ability to pause individual podcast

pull/142/head
Akhil Gupta 3 years ago
parent accd7fe166
commit 96d589886e

@ -14,7 +14,7 @@
</a> --> </a> -->
<h1 align="center" style="margin-bottom:0px">Podgrab</h1> <h1 align="center" style="margin-bottom:0px">Podgrab</h1>
<p align="center">Current Version - 2021.07.28</p> <p align="center">Current Version - 2021.07.30</p>
<p align="center"> <p align="center">
A self-hosted podcast manager to download episodes as soon as they become live A self-hosted podcast manager to download episodes as soon as they become live

@ -115,6 +115,10 @@
.list .u-full-width{ .list .u-full-width{
width: 80%; width: 80%;
} }
.paused{
opacity: 50%;
}
</style> </style>
</head> </head>
<body> <body>
@ -172,11 +176,12 @@
/> />
</a> </a>
</div> </div>
<div class="columns" v-bind:class="{ten:layout=='list', twelve:layout=='grid'}"> <div class="columns" v-bind:class="{ten:layout=='list', twelve:layout=='grid',paused:podcast.IsPaused}">
<div class="titleContainer"> <div class="titleContainer">
<a style="text-decoration: none" :href="'/podcasts/'+podcast.ID+'/view'"> <a style="text-decoration: none" :href="'/podcasts/'+podcast.ID+'/view'">
<h3 v-if="layout=='list'">${podcast.Title}</h3> <h3 v-if="layout=='list'">${podcast.Title}</h3>
<h5 v-if="layout=='grid'">${podcast.Title}</h5> <h5 v-if="layout=='grid'">${podcast.Title} </h5>
</a> </a>
</div> </div>
<div class="contentContainer"> <div class="contentContainer">
@ -250,6 +255,22 @@
> >
<i class="fas fa-plus"></i> <i class="fas fa-plus"></i>
</button> </button>
<button
class="button"
title="New episodes for this podcast are not being downloaded automatially. Click to resume download."
v-if="podcast.IsPaused"
@click="togglePause(podcast,false)"
>
<i style="color: greenyellow;" class="fas fa-dot-circle"></i>
</button>
<button
class="button"
title="Click to pause automatic downloading for this podcast."
v-if="!podcast.IsPaused"
@click="togglePause(podcast,true)"
>
<i style="color: red;" class="fas fa-dot-circle"></i>
</button>
</div> </div>
</div> </div>
</div> </div>
@ -469,6 +490,27 @@
} }
this.socket.send(getWebsocketMessage("Enqueue",`{"podcastId":"${id}"}`)) this.socket.send(getWebsocketMessage("Enqueue",`{"podcastId":"${id}"}`))
}, },
togglePause(item,isPaused){
var self=this;
var url= isPaused?`/podcasts/${item.ID}/pause`:`/podcasts/${item.ID}/unpause`;
axios
.get(url)
.then(function (response) {
item.IsPaused=isPaused;
})
.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,
});
}
})
},
filterPodcasts(){ filterPodcasts(){
if(this.filterTag===""){ if(this.filterTag===""){
this.podcasts=this.allPodcasts; this.podcasts=this.allPodcasts;

@ -128,7 +128,7 @@
<table> <table>
<tr> <tr>
<td>Current Version</td> <td>Current Version</td>
<td> 2021.07.28</td> <td> 2021.07.30</td>
</tr> </tr>
<tr> <tr>
<td>Website</td> <td>Website</td>

@ -95,6 +95,35 @@ func GetPodcastById(c *gin.Context) {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"}) c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"})
} }
} }
func PausePodcastById(c *gin.Context) {
var searchByIdQuery SearchByIdQuery
if c.ShouldBindUri(&searchByIdQuery) == nil {
err := service.TogglePodcastPause(searchByIdQuery.Id, true)
if err != nil {
c.JSON(http.StatusBadRequest, err)
return
}
c.JSON(200, gin.H{})
} else {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"})
}
}
func UnpausePodcastById(c *gin.Context) {
var searchByIdQuery SearchByIdQuery
if c.ShouldBindUri(&searchByIdQuery) == nil {
err := service.TogglePodcastPause(searchByIdQuery.Id, false)
if err != nil {
c.JSON(http.StatusBadRequest, err)
return
}
c.JSON(200, gin.H{})
} else {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"})
}
}
func DeletePodcastById(c *gin.Context) { func DeletePodcastById(c *gin.Context) {
var searchByIdQuery SearchByIdQuery var searchByIdQuery SearchByIdQuery

@ -272,6 +272,12 @@ func ForceSetLastEpisodeDate(podcastId string) {
DB.Exec("update podcasts set last_episode = (select max(pi.pub_date) from podcast_items pi where pi.podcast_id = @id) where id = @id", sql.Named("id", podcastId)) DB.Exec("update podcasts set last_episode = (select max(pi.pub_date) from podcast_items pi where pi.podcast_id = @id) where id = @id", sql.Named("id", podcastId))
} }
func TogglePodcastPauseStatus(podcastId string, isPaused bool) error {
tx := DB.Debug().Exec("update podcasts set is_paused = @isPaused where id = @id", sql.Named("id", podcastId), sql.Named("isPaused", isPaused))
return tx.Error
}
func GetPodcastItemsByPodcastIdAndGUIDs(podcastId string, guids []string) (*[]PodcastItem, error) { func GetPodcastItemsByPodcastIdAndGUIDs(podcastId string, guids []string) (*[]PodcastItem, error) {
var podcastItems []PodcastItem var podcastItems []PodcastItem
result := DB.Preload(clause.Associations).Where(&PodcastItem{PodcastID: podcastId}).Where("guid IN ?", guids).Find(&podcastItems) result := DB.Preload(clause.Associations).Where(&PodcastItem{PodcastID: podcastId}).Where("guid IN ?", guids).Find(&podcastItems)
@ -297,6 +303,11 @@ func CreatePodcastItem(podcastItem *PodcastItem) error {
tx := DB.Omit("Podcast").Create(&podcastItem) tx := DB.Omit("Podcast").Create(&podcastItem)
return tx.Error return tx.Error
} }
func UpdatePodcast(podcast *Podcast) error {
tx := DB.Save(&podcast)
return tx.Error
}
func UpdatePodcastItem(podcastItem *PodcastItem) error { func UpdatePodcastItem(podcastItem *PodcastItem) error {
tx := DB.Omit("Podcast").Save(&podcastItem) tx := DB.Omit("Podcast").Save(&podcastItem)
return tx.Error return tx.Error

@ -30,6 +30,8 @@ type Podcast struct {
DownloadedEpisodesSize int64 `gorm:"-"` DownloadedEpisodesSize int64 `gorm:"-"`
DownloadingEpisodesSize int64 `gorm:"-"` DownloadingEpisodesSize int64 `gorm:"-"`
AllEpisodesSize int64 `gorm:"-"` AllEpisodesSize int64 `gorm:"-"`
IsPaused bool `gorm:"default:false"`
} }
//PodcastItem is //PodcastItem is

@ -157,6 +157,8 @@ func main() {
router.GET("/podcasts/:id/download", controllers.DownloadAllEpisodesByPodcastId) router.GET("/podcasts/:id/download", controllers.DownloadAllEpisodesByPodcastId)
router.DELETE("/podcasts/:id/items", controllers.DeletePodcastEpisodesById) router.DELETE("/podcasts/:id/items", controllers.DeletePodcastEpisodesById)
router.DELETE("/podcasts/:id/podcast", controllers.DeleteOnlyPodcastById) router.DELETE("/podcasts/:id/podcast", controllers.DeleteOnlyPodcastById)
router.GET("/podcasts/:id/pause", controllers.PausePodcastById)
router.GET("/podcasts/:id/unpause", controllers.UnpausePodcastById)
router.GET("/podcastitems", controllers.GetAllPodcastItems) router.GET("/podcastitems", controllers.GetAllPodcastItems)
router.GET("/podcastitems/:id", controllers.GetPodcastItemById) router.GET("/podcastitems/:id", controllers.GetPodcastItemById)

@ -312,6 +312,10 @@ func AddPodcastItems(podcast *db.Podcast, newPodcast bool) error {
downloadStatus = db.Deleted downloadStatus = db.Deleted
} }
if podcast.IsPaused {
downloadStatus = db.Deleted
}
summary := strip.StripTags(obj.Summary) summary := strip.StripTags(obj.Summary)
if summary == "" { if summary == "" {
summary = strip.StripTags(obj.Description) summary = strip.StripTags(obj.Description)
@ -779,3 +783,13 @@ func AddTag(label, description string) (db.Tag, error) {
return *tag, &model.TagAlreadyExistsError{Label: label} return *tag, &model.TagAlreadyExistsError{Label: label}
} }
func TogglePodcastPause(id string, isPaused bool) error {
var podcast db.Podcast
err := db.GetPodcastById(id, &podcast)
if err != nil {
return err
}
return db.TogglePodcastPauseStatus(id, isPaused)
}

Loading…
Cancel
Save