diff --git a/Readme.md b/Readme.md
index edc5f2b..bb86acd 100644
--- a/Readme.md
+++ b/Readme.md
@@ -148,13 +148,14 @@ Distributed under the MIT License. See `LICENSE` for more information.
- [x] Append Date to filename
- [x] iTunes Search
- [x] Existing episodes detection (Will not redownload if files exist even with a fresh install)
-- [x] Rudimentary downloading/downloaded indicator
+- [x] Downloading/downloaded indicator
- [x] Played/Unplayed Flag
- [x] OPML import
- [x] OPML export
- [x] In built podcast player
- [ ] Set ID3 tags if not set
- [ ] Filtering and Sorting options
+- [ ] Native installer for Windows/Linux/MacOS
diff --git a/client/episodes.html b/client/episodes.html
index 9487bb2..2f0423f 100644
--- a/client/episodes.html
+++ b/client/episodes.html
@@ -65,7 +65,7 @@
diff --git a/client/player.html b/client/player.html
index 8c81fe0..95925ed 100644
--- a/client/player.html
+++ b/client/player.html
@@ -867,11 +867,15 @@ div#large-visualization{
},
getSongsFromItems(items){
return items.map(x=>{
+ var image = x.LocalImage;
+ if(!image){
+ image=x.Image;
+ }
var toReturn= {
id:x.ID,
name:x.Title,
url:x.DownloadPath,
- cover_art_url:x.Image,
+ cover_art_url:image,
artist:x.Podcast.Title,
album: new Date(x.PubDate.substr(0,10)).toDateString()
}
diff --git a/client/settings.html b/client/settings.html
index 7bd937c..d4fc67a 100644
--- a/client/settings.html
+++ b/client/settings.html
@@ -82,6 +82,11 @@
Use Dark Mode
+
+
@@ -135,7 +140,8 @@ var app = new Vue({
autoDownload:self.autoDownload,
appendDateToFileName:self.appendDateToFileName,
appendEpisodeNumberToFileName:self.appendEpisodeNumberToFileName,
- darkMode:self.darkMode
+ darkMode:self.darkMode,
+ downloadEpisodeImages:self.downloadEpisodeImages
})
.then(function(response){
@@ -176,7 +182,8 @@ var app = new Vue({
appendDateToFileName: {{ .setting.AppendDateToFileName }},
appendEpisodeNumberToFileName:{{ .setting.AppendEpisodeNumberToFileName }},
darkMode:{{ .setting.DarkMode }},
- originalThemeSetting:{{ .setting.DarkMode }}
+ originalThemeSetting:{{ .setting.DarkMode }},
+ downloadEpisodeImages:{{.setting.DownloadEpisodeImages }},
},
})
diff --git a/controllers/pages.go b/controllers/pages.go
index 650edfd..ced4524 100644
--- a/controllers/pages.go
+++ b/controllers/pages.go
@@ -26,6 +26,7 @@ type SettingModel struct {
AppendDateToFileName bool `form:"appendDateToFileName" json:"appendDateToFileName" query:"appendDateToFileName"`
AppendEpisodeNumberToFileName bool `form:"appendEpisodeNumberToFileName" json:"appendEpisodeNumberToFileName" query:"appendEpisodeNumberToFileName"`
DarkMode bool `form:"darkMode" json:"darkMode" query:"darkMode"`
+ DownloadEpisodeImages bool `form:"downloadEpisodeImages" json:"downloadEpisodeImages" query:"downloadEpisodeImages"`
}
func AddPage(c *gin.Context) {
diff --git a/controllers/podcast.go b/controllers/podcast.go
index c737b40..850ece4 100644
--- a/controllers/podcast.go
+++ b/controllers/podcast.go
@@ -305,7 +305,9 @@ func UpdateSetting(c *gin.Context) {
if err == nil {
- err = service.UpdateSettings(model.DownloadOnAdd, model.InitialDownloadCount, model.AutoDownload, model.AppendDateToFileName, model.AppendEpisodeNumberToFileName, model.DarkMode)
+ err = service.UpdateSettings(model.DownloadOnAdd, model.InitialDownloadCount,
+ model.AutoDownload, model.AppendDateToFileName, model.AppendEpisodeNumberToFileName,
+ model.DarkMode, model.DownloadEpisodeImages)
if err == nil {
c.JSON(200, gin.H{"message": "Success"})
diff --git a/db/dbfunctions.go b/db/dbfunctions.go
index 6d92eaf..81b30d5 100644
--- a/db/dbfunctions.go
+++ b/db/dbfunctions.go
@@ -96,6 +96,13 @@ func UpdateLastEpisodeDateForPodcast(podcastId string, lastEpisode time.Time) er
return result.Error
}
+func GetAllPodcastItemsWithoutImage() (*[]PodcastItem, error) {
+ var podcastItems []PodcastItem
+ result := DB.Debug().Preload(clause.Associations).Where("local_image is ?", nil).Where("image != ?", "").Where("download_status=?", Downloaded).Order("created_at desc").Find(&podcastItems)
+ //fmt.Println("To be downloaded : " + string(len(podcastItems)))
+ return &podcastItems, result.Error
+}
+
func GetAllPodcastItemsToBeDownloaded() (*[]PodcastItem, error) {
var podcastItems []PodcastItem
result := DB.Debug().Preload(clause.Associations).Where("download_status=?", NotDownloaded).Find(&podcastItems)
diff --git a/db/podcast.go b/db/podcast.go
index 54bc557..53275eb 100644
--- a/db/podcast.go
+++ b/db/podcast.go
@@ -52,6 +52,8 @@ type PodcastItem struct {
IsPlayed bool `gorm:"default:false"`
BookmarkDate time.Time
+
+ LocalImage string
}
type DownloadStatus int
@@ -71,6 +73,7 @@ type Setting struct {
AppendDateToFileName bool `gorm:"default:false"`
AppendEpisodeNumberToFileName bool `gorm:"default:false"`
DarkMode bool `gorm:"default:false"`
+ DownloadEpisodeImages bool `gorm:"default:false"`
}
type Migration struct {
Base
diff --git a/main.go b/main.go
index afe428f..c2e7de6 100644
--- a/main.go
+++ b/main.go
@@ -168,6 +168,7 @@ func intiCron() {
gocron.Every(uint64(checkFrequency)).Minutes().Do(service.RefreshEpisodes)
gocron.Every(uint64(checkFrequency)).Minutes().Do(service.CheckMissingFiles)
gocron.Every(uint64(checkFrequency) * 2).Minutes().Do(service.UnlockMissedJobs)
+ gocron.Every(uint64(checkFrequency)).Minutes().Do(service.DownloadMissingImages)
gocron.Every(2).Days().Do(service.CreateBackup)
<-gocron.Start()
}
diff --git a/service/fileService.go b/service/fileService.go
index aa2e7f0..ea25a9c 100644
--- a/service/fileService.go
+++ b/service/fileService.go
@@ -58,6 +58,45 @@ func Download(link string, episodeTitle string, podcastName string, prefix strin
changeOwnership(finalPath)
return finalPath, nil
+}
+
+func DownloadImage(link string, episodeId string, podcastName string) (string, error) {
+ if link == "" {
+ return "", errors.New("Download path empty")
+ }
+ client := httpClient()
+ resp, err := client.Get(link)
+ if err != nil {
+ Logger.Errorw("Error getting response: "+link, err)
+ return "", err
+ }
+
+ fileName := getFileName(link, episodeId, ".jpg")
+ folder := createDataFolderIfNotExists(podcastName)
+ imageFolder := createFolder("images", folder)
+ finalPath := path.Join(imageFolder, fileName)
+
+ if _, err := os.Stat(finalPath); !os.IsNotExist(err) {
+ changeOwnership(finalPath)
+ return finalPath, nil
+ }
+
+ file, err := os.Create(finalPath)
+ if err != nil {
+ Logger.Errorw("Error creating file"+link, err)
+ return "", err
+ }
+ defer resp.Body.Close()
+ _, erra := io.Copy(file, resp.Body)
+ //fmt.Println(size)
+ defer file.Close()
+ if erra != nil {
+ Logger.Errorw("Error saving file"+link, err)
+ return "", erra
+ }
+ changeOwnership(finalPath)
+ return finalPath, nil
+
}
func changeOwnership(path string) {
uid, err1 := strconv.Atoi(os.Getenv("PUID"))
diff --git a/service/podcastService.go b/service/podcastService.go
index 68f189b..655880b 100644
--- a/service/podcastService.go
+++ b/service/podcastService.go
@@ -306,6 +306,33 @@ func SetPodcastItemAsQueuedForDownload(id string) error {
return db.UpdatePodcastItem(&podcastItem)
}
+func DownloadMissingImages() error {
+ setting := db.GetOrCreateSetting()
+ if !setting.DownloadEpisodeImages {
+ fmt.Println("No Need To Download Images")
+ return nil
+ }
+ items, err := db.GetAllPodcastItemsWithoutImage()
+ if err != nil {
+ return err
+ }
+ for _, item := range *items {
+ downloadImageLocally(item)
+ }
+ return nil
+}
+
+func downloadImageLocally(podcastItem db.PodcastItem) error {
+ path, err := DownloadImage(podcastItem.Image, podcastItem.ID, podcastItem.Podcast.Title)
+ if err != nil {
+ return err
+ }
+
+ podcastItem.LocalImage = path
+
+ return db.UpdatePodcastItem(&podcastItem)
+}
+
func SetPodcastItemBookmarkStatus(id string, bookmark bool) error {
var podcastItem db.PodcastItem
err := db.GetPodcastItemById(id, &podcastItem)
@@ -447,6 +474,10 @@ func DeleteEpisodeFile(podcastItemId string) error {
return err
}
+ if podcastItem.LocalImage != "" {
+ go DeleteFile(podcastItem.LocalImage)
+ }
+
return SetPodcastItemAsNotDownloaded(podcastItem.ID, db.Deleted)
}
func DownloadSingleEpisode(podcastItemId string) error {
@@ -465,6 +496,9 @@ func DownloadSingleEpisode(podcastItemId string) error {
if err != nil {
return err
}
+ if setting.DownloadEpisodeImages {
+ go downloadImageLocally(podcastItem)
+ }
return SetPodcastItemAsDownloaded(podcastItem.ID, url)
}
@@ -527,6 +561,10 @@ func DeletePodcast(id string, deleteFiles bool) error {
for _, item := range podcastItems {
if deleteFiles {
DeleteFile(item.DownloadPath)
+ if item.LocalImage != "" {
+ DeleteFile(item.LocalImage)
+ }
+
}
db.DeletePodcastItemById(item.ID)
@@ -577,7 +615,7 @@ func GetSearchFromItunes(pod model.ItunesSingleResult) *model.CommonSearchResult
return p
}
-func UpdateSettings(downloadOnAdd bool, initialDownloadCount int, autoDownload bool, appendDateToFileName bool, appendEpisodeNumberToFileName bool, darkMode bool) error {
+func UpdateSettings(downloadOnAdd bool, initialDownloadCount int, autoDownload bool, appendDateToFileName bool, appendEpisodeNumberToFileName bool, darkMode bool, downloadEpisodeImages bool) error {
setting := db.GetOrCreateSetting()
setting.AutoDownload = autoDownload
@@ -586,6 +624,7 @@ func UpdateSettings(downloadOnAdd bool, initialDownloadCount int, autoDownload b
setting.AppendDateToFileName = appendDateToFileName
setting.AppendEpisodeNumberToFileName = appendEpisodeNumberToFileName
setting.DarkMode = darkMode
+ setting.DownloadEpisodeImages = downloadEpisodeImages
return db.UpdateSettings(setting)
}