Merge branch 'master' into ta

pull/53/head
Akhil Gupta 4 years ago
commit e3884bf1cb

@ -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

@ -170,7 +170,7 @@
}
var self = this;
self.searching = true;
let formData = new FormData();
var formData = new FormData();
formData.append("file", currentFile);
axios
@ -189,8 +189,8 @@
item.already_saved = true;
})
.catch(function (error) {
if (error.response) {
Vue.toasted.show(error.response.data?.message, {
if (error.response && error.response.data && error.response.data.message) {
Vue.toasted.show(error.response.data.message, {
theme: "bubble",
type: "error",
position: "top-right",
@ -246,8 +246,8 @@
item.already_saved = true;
})
.catch(function (error) {
if (error.response) {
Vue.toasted.show(error.response.data?.message, {
if (error.response && error.response.data && error.response.data.message) {
Vue.toasted.show(error.response.data.message, {
theme: "bubble",
type: "error",
position: "top-right",

@ -65,7 +65,7 @@
<img
onerror="onImageError(this)"
class="u-full-width"
src="{{ .Image }}"
{{if .LocalImage }} src="/{{ .LocalImage }}" {{ else }} src="{{ .Image }}" {{end}}
alt="{{ .Title }}"
lazy="lazy"
/>
@ -221,8 +221,8 @@
row.remove();
})
.catch(function (error) {
if (error.response) {
Vue.toasted.show(error.response.data?.message, {
if (error.response && error.response.data && error.response.data.message) {
Vue.toasted.show(error.response.data.message, {
theme: "bubble",
type: "error",
position: "top-right",
@ -247,8 +247,8 @@
row.remove();
})
.catch(function (error) {
if (error.response) {
Vue.toasted.show(error.response.data?.message, {
if (error.response && error.response.data && error.response.data.message) {
Vue.toasted.show(error.response.data.message, {
theme: "bubble",
type: "error",
position: "top-right",
@ -260,7 +260,7 @@
return false;
}
function changePlayedStatus(id, status) {
let endpoint = status ? "markPlayed" : "markUnplayed";
var endpoint = status ? "markPlayed" : "markUnplayed";
axios
.get("/podcastitems/" + id + "/" + endpoint, {
isPlayed: status,
@ -276,8 +276,9 @@
row.remove();
})
.catch(function (error) {
if (error.response) {
Vue.toasted.show(error.response.data?.message, {
if (error.response && error.response.data && error.response.data.message) {
Vue.toasted.show(error.response.data.message, {
theme: "bubble",
type: "error",
position: "top-right",
@ -289,7 +290,7 @@
return false;
}
function changeBookmarkStatus(id, status) {
let endpoint = status ? "bookmark" : "unbookmark";
var endpoint = status ? "bookmark" : "unbookmark";
axios
.get("/podcastitems/" + id + "/" + endpoint, {
isPlayed: status,
@ -306,8 +307,8 @@
row.remove();
})
.catch(function (error) {
if (error.response) {
Vue.toasted.show(error.response.data?.message, {
if (error.response && error.response.data && error.response.data.message) {
Vue.toasted.show(error.response.data.message, {
theme: "bubble",
type: "error",
position: "top-right",
@ -339,6 +340,15 @@
}
socket.send(getWebsocketMessage("Enqueue",`{"itemId":"${id}"}`))
}
function enquePodcast(id){
if(!socket){
return
}
socket.send(getWebsocketMessage("Enqueue",`{"podcastId":"${id}"}`))
}
function playPodcast(id){
openPlayer("",id)
}
</script>
</body>
</html>

@ -261,7 +261,7 @@
this.socket.send(getWebsocketMessage("Enqueue",`{"podcastId":"${id}"}`))
},
sortPodcasts(order){
let compareFunction;
var compareFunction;
switch(order){
case "dateAdded-asc":compareFunction=(a,b)=>Date.parse(a.CreatedAt)-Date.parse(b.CreatedAt);break;
case "dateAdded-desc":compareFunction=(a,b)=>Date.parse(b.CreatedAt)-Date.parse(a.CreatedAt);break;
@ -298,7 +298,7 @@
this.podcasts.sort(compareFunction)
},
getEpisodeCountTooltip(podcast){
let title=`${podcast.DownloadedEpisodesCount} episodes downloaded out of total ${podcast.AllEpisodesCount} episodes`
var title=`${podcast.DownloadedEpisodesCount} episodes downloaded out of total ${podcast.AllEpisodesCount} episodes`
if(podcast.DownloadingEpisodesCount){
title+= '\n'+podcast.DownloadingEpisodesCount+' episodes in the queue.'
@ -308,7 +308,7 @@
getFormattedLastEpisodeDate(podcast){
const options={month:"short", day:"numeric", year:"numeric"}
//todo: this is a really dirty hack which needs to be fixed when we work on the episode page
let dt=new Date(Date.parse(podcast.LastEpisode.substr(0,10)));
var dt=new Date(Date.parse(podcast.LastEpisode.substr(0,10)));
return dt.toDateString()
},
downloadAllEpisodes(id) { downloadAllEpisodes(id);},
@ -321,11 +321,11 @@
playPodcast(id){openPlayer("",id)},
},
mounted(){
if(localStorage?.sortOrder){
if(localStorage && localStorage.sortOrder){
this.sortOrder=localStorage.sortOrder;
this.sortPodcasts(this.sortOrder);
}
if(localStorage?.layout){
if(localStorage && localStorage.layout){
this.layout=localStorage.layout;
}else{
this.layout='list';
@ -415,145 +415,7 @@
{{ $len := len .podcasts}}
podcasts: {{if gt $len 0}} {{ .podcasts }} {{else}} [] {{end}},
}})
function downloadAllEpisodes(id) {
var confirmed = confirm(
"Are you sure you want to download all episodes of this podcast?"
);
if (!confirmed) {
return false;
}
axios
.get("/podcasts/" + id + "/download")
.then(function (response) {
Vue.toasted.show(
"All episodes of this podcast have been enqueued to download.",
{
theme: "bubble",
type: "info",
position: "top-right",
duration: 5000,
}
);
})
.catch(function (error) {
if (error.response) {
Vue.toasted.show(error.response.data?.message, {
theme: "bubble",
type: "error",
position: "top-right",
duration: 5000,
});
}
})
.then(function () {});
return false;
}
function deletePodcast(id,onSuccess) {
if (typeof id !== 'string'){
id= id.getAttribute('data-id')
}
console.log(id)
var confirmed = confirm(
"Are you sure you want to delete this podcast and all files?"
);
if (!confirmed) {
return false;
}
axios
.delete("/podcasts/" + id)
.then(function (response) {
Vue.toasted.show("Podcast deleted successfully.", {
theme: "bubble",
type: "success",
position: "top-right",
duration: 5000,
});
app.removePodcast(id)
})
.catch(function (error) {
if (error.response) {
Vue.toasted.show(error.response.data?.message, {
theme: "bubble",
type: "error",
position: "top-right",
duration: 5000,
});
}
})
.then(function () {});
return false;
}
function deletePodcastEpisodes(id) {
if (typeof id !== 'string'){
id= id.getAttribute('data-id')
}
console.log(id);
var confirmed = confirm(
"Are you sure you want to delete all episodes of this podcast?"
);
if (!confirmed) {
return false;
}
axios
.delete("/podcasts/" + id + "/items")
.then(function (response) {
Vue.toasted.show("Podcast Episodes deleted successfully.", {
theme: "bubble",
type: "success",
position: "top-right",
duration: 5000,
});
})
.catch(function (error) {
if (error.response) {
Vue.toasted.show(error.response.data?.message, {
theme: "bubble",
type: "error",
position: "top-right",
duration: 5000,
});
}
})
.then(function () {});
return false;
}
function deleteOnlyPodcast(id) {
if (typeof id !== 'string'){
id= id.getAttribute('data-id')
}
console.log(id);
var confirmed = confirm(
"Are you sure you want to delete this podcast (without deleting the files)?"
);
if (!confirmed) {
return false;
}
axios
.delete("/podcasts/" + id + "/podcast")
.then(function (response) {
Vue.toasted.show("Podcast deleted successfully.", {
theme: "bubble",
type: "success",
position: "top-right",
duration: 5000,
});
app.removePodcast(id)
})
.catch(function (error) {
if (error.response) {
Vue.toasted.show(error.response.data?.message, {
theme: "bubble",
type: "error",
position: "top-right",
duration: 5000,
});
}
})
.then(function () {});
return false;
}
</script>
<script>

@ -142,6 +142,31 @@ div#overlay{
<div></div>
</a>
<h1>{{ .title }}</h1>
{{if .podcastId }}
<button
class="button"
title="Download all episode files"
onclick="downloadAllEpisodes({{ .podcastId }})"
>
<i class="fas fa-download"></i>
</button>
<button
class="button"
title="Play all episodes"
onclick="playPodcast({{ .podcastId }})"
>
<i class="fas fa-play"></i>
</button>
<button
class="button button-enqueue"
title="Add all episodes to existing player playlist"
onclick="enquePodcast({{ .podcastId }})"
>
<i class="fas fa-plus"></i>
</button>
{{end}}
</section>
<nav class="navbar">
<div class="container">
@ -174,8 +199,8 @@ div#overlay{
<script>
function toggleMenu(){
let sideDrawer= document.getElementById('sideDrawer')
let overlay= document.getElementById('overlay')
var sideDrawer= document.getElementById('sideDrawer')
var overlay= document.getElementById('overlay')
if(overlay.style.display==="block"){
sideDrawer.style.left="-160px"
overlay.style.display="none"

@ -809,7 +809,7 @@ div#large-visualization{
removeSongTime(songId){
if(localStorage){
let songTimes=localStorage.songTimes;
var songTimes=localStorage.songTimes;
if(!songTimes){
songTimes={};
}else{
@ -825,7 +825,7 @@ div#large-visualization{
,saveSongTime(songId,time){
if(localStorage){
let songTimes=localStorage.songTimes;
var songTimes=localStorage.songTimes;
if(!songTimes){
songTimes={};
}else{
@ -840,8 +840,8 @@ div#large-visualization{
getSavedSongTime(){
if(localStorage){
let song=Amplitude.getActiveSongMetadata();
let songTimes=localStorage.songTimes;
var song=Amplitude.getActiveSongMetadata();
var songTimes=localStorage.songTimes;
if(!songTimes){
songTimes={};
}else{
@ -855,8 +855,8 @@ div#large-visualization{
return 0;
},
changeSpeed(){
let currentSpeedIndex= this.speedOptions.indexOf(this.speed);
let nextIndex=0;
var currentSpeedIndex= this.speedOptions.indexOf(this.speed);
var nextIndex=0;
if(currentSpeedIndex===-1 || currentSpeedIndex===this.speedOptions.length-1){
nextIndex=0;
}else{
@ -867,11 +867,15 @@ div#large-visualization{
},
getSongsFromItems(items){
return items.map(x=>{
let toReturn= {
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()
}
@ -882,7 +886,7 @@ div#large-visualization{
});
},
getFormattedLastEpisodeDate(item){
let dt=new Date(Date.parse(item.PubDate.substr(0,10)));
var dt=new Date(Date.parse(item.PubDate.substr(0,10)));
return dt.toDateString()
},
formatDuration(total) {
@ -933,8 +937,8 @@ div#large-visualization{
});
},
mounted(){
let volume=50;
if(localStorage?.playerVolume){
var volume=50;
if(localStorage && localStorage.playerVolume){
volume=parseInt(localStorage.playerVolume)
}
const self=this;
@ -961,7 +965,7 @@ div#large-visualization{
// },
'timeupdate':function(){
let secs=Math.floor(Amplitude.getSongPlayedSeconds());
var secs=Math.floor(Amplitude.getSongPlayedSeconds());
if(secs%10===0){
song=Amplitude.getActiveSongMetadata();
if(Amplitude.getSongPlayedPercentage()>20){
@ -1025,7 +1029,7 @@ div#large-visualization{
let songElements = document.getElementsByClassName('song');
var songElements = document.getElementsByClassName('song');
for( var i = 0; i < songElements.length; i++ ){
songElements[i].addEventListener('click', function(){
@ -1033,11 +1037,11 @@ for( var i = 0; i < songElements.length; i++ ){
});
}
let markedAsPlayed=[];
var markedAsPlayed=[];
function markSongAsPlayed(id) {
let endpoint = "markPlayed";
var endpoint = "markPlayed";
if(markedAsPlayed.indexOf(id)!==-1){
return;
}

@ -177,9 +177,10 @@ function downloadToDisk(id){
row.remove();
})
.catch(function(error){
if(error.response){
if (error.response && error.response.data && error.response.data.message) {
Vue.toasted.show(error.response.data?.message, {
Vue.toasted.show(error.response.data.message, {
theme: "bubble",
position: "top-right",
type: "error",

@ -10,24 +10,24 @@
};
const limit = 300;
function checkUseMore() {
let elements = document.getElementsByClassName("useMore");
var elements = document.getElementsByClassName("useMore");
for (let index = 0; index < elements.length; index++) {
for (var index = 0; index < elements.length; index++) {
const element = elements[index];
let display = element.style.display;
let originalText = element.textContent;
var display = element.style.display;
var originalText = element.textContent;
if (originalText.length <= limit) {
continue;
}
let newText = originalText.substr(0, limit);
var newText = originalText.substr(0, limit);
let newElement = document.createElement(element.tagName);
var newElement = document.createElement(element.tagName);
newElement.textContent = newText;
newElement.classList.add("short-version");
element.classList.add("long-version");
let more = document.createElement("a");
var more = document.createElement("a");
more.textContent = " show more";
more.style.cursor = "pointer";
more.onclick = function () {
@ -35,7 +35,7 @@
newElement.style.display = "none";
};
let less = document.createElement("a");
var less = document.createElement("a");
less.textContent = " show less";
less.style.cursor = "pointer";
less.onclick = function () {
@ -53,7 +53,7 @@
checkUseMore();
function openPlayer(itemId, podcastId) {
let url = "/player?";
var url = "/player?";
if (itemId) {
url += "&itemId=" + itemId;
}
@ -66,7 +66,7 @@
function getIdentifier() {
if(localStorage){
if (localStorage.identifier) {
return localStorage?.identifier;
return localStorage.identifier;
}
var id = +new Date();
localStorage.identifier = id;
@ -103,5 +103,148 @@
// console.log('Message from server ', event.data);
// });
}
function downloadAllEpisodes(id) {
var confirmed = confirm(
"Are you sure you want to download all episodes of this podcast?"
);
if (!confirmed) {
return false;
}
axios
.get("/podcasts/" + id + "/download")
.then(function (response) {
Vue.toasted.show(
"All episodes of this podcast have been enqueued to download.",
{
theme: "bubble",
type: "info",
position: "top-right",
duration: 5000,
}
);
})
.catch(function (error) {
if (error.response && error.response.data && error.response.data.message) {
Vue.toasted.show(error.response.data.message, {
theme: "bubble",
type: "error",
position: "top-right",
duration: 5000,
});
}
})
.then(function () {});
return false;
}
function deletePodcast(id,onSuccess) {
if (typeof id !== 'string'){
id= id.getAttribute('data-id')
}
console.log(id)
var confirmed = confirm(
"Are you sure you want to delete this podcast and all files?"
);
if (!confirmed) {
return false;
}
axios
.delete("/podcasts/" + id)
.then(function (response) {
Vue.toasted.show("Podcast deleted successfully.", {
theme: "bubble",
type: "success",
position: "top-right",
duration: 5000,
});
app.removePodcast(id)
})
.catch(function (error) {
if (error.response && error.response.data && error.response.data.message) {
Vue.toasted.show(error.response.data.message, {
theme: "bubble",
type: "error",
position: "top-right",
duration: 5000,
});
}
})
.then(function () {});
return false;
}
function deletePodcastEpisodes(id) {
if (typeof id !== 'string'){
id= id.getAttribute('data-id')
}
console.log(id);
var confirmed = confirm(
"Are you sure you want to delete all episodes of this podcast?"
);
if (!confirmed) {
return false;
}
axios
.delete("/podcasts/" + id + "/items")
.then(function (response) {
Vue.toasted.show("Podcast Episodes deleted successfully.", {
theme: "bubble",
type: "success",
position: "top-right",
duration: 5000,
});
})
.catch(function (error) {
if (error.response && error.response.data && error.response.data.message) {
Vue.toasted.show(error.response.data.message, {
theme: "bubble",
type: "error",
position: "top-right",
duration: 5000,
});
}
})
.then(function () {});
return false;
}
function deleteOnlyPodcast(id) {
if (typeof id !== 'string'){
id= id.getAttribute('data-id')
}
console.log(id);
var confirmed = confirm(
"Are you sure you want to delete this podcast (without deleting the files)?"
);
if (!confirmed) {
return false;
}
axios
.delete("/podcasts/" + id + "/podcast")
.then(function (response) {
Vue.toasted.show("Podcast deleted successfully.", {
theme: "bubble",
type: "success",
position: "top-right",
duration: 5000,
});
app.removePodcast(id)
})
.catch(function (error) {
if (error.response && error.response.data && error.response.data.message) {
Vue.toasted.show(error.response.data.message, {
theme: "bubble",
type: "error",
position: "top-right",
duration: 5000,
});
}
})
.then(function () {});
return false;
}
</script>
{{end}}

@ -82,6 +82,11 @@
<input type="checkbox" name="darkMode" v-model="darkMode">
<span class="label-body">Use Dark Mode</span>
</label>
<label for="downloadEpisodeImages">
<input type="checkbox" name="downloadEpisodeImages" v-model="downloadEpisodeImages">
<span class="label-body">Download Episode Images with files</span>
</label>
<input type="submit" value="Save" class="button">
</form>
@ -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){
@ -151,9 +157,10 @@ var app = new Vue({
}
})
.catch(function(error){
if(error.response){
if (error.response && error.response.data && error.response.data.message) {
Vue.toasted.show(error.response.data?.message, {
Vue.toasted.show(error.response.data.message, {
theme: "bubble",
type: "error",
position: "top-right",
@ -175,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 }},
},
})

@ -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) {
@ -81,6 +82,7 @@ func PodcastPage(c *gin.Context) {
"nextPage": nextPage,
"previousPage": previousPage,
"downloadedOnly": false,
"podcastId": searchByIdQuery.Id,
})
} else {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"})

@ -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"})

@ -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)

@ -54,6 +54,8 @@ type PodcastItem struct {
IsPlayed bool `gorm:"default:false"`
BookmarkDate time.Time
LocalImage string
}
type DownloadStatus int
@ -73,6 +75,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

@ -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()
}

@ -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"))

@ -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)
}

Loading…
Cancel
Save