mirror of
https://github.com/mxpv/podsync.git
synced 2024-05-11 05:55:04 +00:00
Support episodes cleanup #44
This commit is contained in:
@ -58,6 +58,7 @@ vimeo = "{VIMEO_API_TOKEN}"
|
||||
# max_height = "720" # Optional maximal height of video, example: 720, 1080, 1440, 2160, ...
|
||||
# cron_schedule = "@every 12h" # Optional cron expression format. If set then overwrite 'update_period'. See details below
|
||||
# filters = { title = "regex for title here" } # Optional Golang regexp format. If set, then only download episodes with matching titles.
|
||||
# clean = { keep_last = 10 } # Keep last 10 episodes (order desc by PubDate)
|
||||
```
|
||||
|
||||
Episodes files will be kept at: `/path/to/data/directory/ID1`, feed will be accessible from: `http://localhost/ID1.xml`
|
||||
|
@ -7,8 +7,10 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"regexp"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/pkg/errors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
@ -61,6 +63,10 @@ func (u *Updater) Update(ctx context.Context, feedConfig *config.Feed) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := u.cleanup(ctx, feedConfig); err != nil {
|
||||
log.WithError(err).Error("cleanup failed")
|
||||
}
|
||||
|
||||
elapsed := time.Since(started)
|
||||
nextUpdate := time.Now().Add(feedConfig.UpdatePeriod.Duration)
|
||||
log.Infof("successfully updated feed in %s, next update at %s", elapsed, nextUpdate.Format(time.Kitchen))
|
||||
@ -241,3 +247,58 @@ func (u *Updater) buildXML(ctx context.Context, feedConfig *config.Feed) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *Updater) cleanup(ctx context.Context, feedConfig *config.Feed) error {
|
||||
var (
|
||||
feedID = feedConfig.ID
|
||||
logger = log.WithField("feed_id", feedID)
|
||||
count = feedConfig.Clean.KeepLast
|
||||
list []*model.Episode
|
||||
result *multierror.Error
|
||||
)
|
||||
|
||||
if count < 1 {
|
||||
logger.Info("nothing to clean")
|
||||
return nil
|
||||
}
|
||||
|
||||
logger.WithField("count", count).Info("running cleaner")
|
||||
if err := u.db.WalkEpisodes(ctx, feedConfig.ID, func(episode *model.Episode) error {
|
||||
switch episode.Status {
|
||||
case model.EpisodeError, model.EpisodeCleaned:
|
||||
// Skip
|
||||
default:
|
||||
list = append(list, episode)
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if count > len(list) {
|
||||
return nil
|
||||
}
|
||||
|
||||
sort.Slice(list, func(i, j int) bool {
|
||||
return list[i].PubDate.After(list[j].PubDate)
|
||||
})
|
||||
|
||||
for _, episode := range list[count:] {
|
||||
logger.WithField("episode_id", episode.ID).Infof("deleting %q", episode.Title)
|
||||
|
||||
if err := u.fs.Delete(ctx, feedConfig.ID, feed.EpisodeName(feedConfig, episode)); err != nil {
|
||||
result = multierror.Append(result, errors.Wrapf(err, "failed to delete episode: %s", episode.ID))
|
||||
continue
|
||||
}
|
||||
|
||||
if err := u.db.UpdateEpisode(feedID, episode.ID, func(episode *model.Episode) error {
|
||||
episode.Status = model.EpisodeCleaned
|
||||
return nil
|
||||
}); err != nil {
|
||||
result = multierror.Append(result, errors.Wrapf(err, "failed to set state for cleaned episode: %s", episode.ID))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
@ -38,6 +38,8 @@ type Feed struct {
|
||||
CoverArt string `toml:"cover_art"`
|
||||
// Only download episodes that match this regexp (defaults to matching anything)
|
||||
Filters Filters `toml:"filters"`
|
||||
// Clean is a cleanup policy to use for this feed
|
||||
Clean Cleanup `toml:"clean"`
|
||||
}
|
||||
|
||||
type Tokens struct {
|
||||
@ -64,6 +66,11 @@ type Database struct {
|
||||
Dir string `toml:"dir"`
|
||||
}
|
||||
|
||||
type Cleanup struct {
|
||||
// KeepLast defines how many episodes to keep
|
||||
KeepLast int `toml:"keep_last"`
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
// Server is the web server configuration
|
||||
Server Server `toml:"server"`
|
||||
|
@ -32,6 +32,8 @@ dir = "/home/user/db/"
|
||||
update_period = "5h"
|
||||
format = "audio"
|
||||
quality = "low"
|
||||
filters = { title = "regex for title here" }
|
||||
clean = { keep_last = 10 }
|
||||
`
|
||||
|
||||
f, err := ioutil.TempFile("", "")
|
||||
@ -62,6 +64,8 @@ dir = "/home/user/db/"
|
||||
assert.EqualValues(t, Duration{5 * time.Hour}, feed.UpdatePeriod)
|
||||
assert.EqualValues(t, "audio", feed.Format)
|
||||
assert.EqualValues(t, "low", feed.Quality)
|
||||
assert.EqualValues(t, "regex for title here", feed.Filters.Title)
|
||||
assert.EqualValues(t, 10, feed.Clean.KeepLast)
|
||||
}
|
||||
|
||||
func TestApplyDefaults(t *testing.T) {
|
||||
|
Reference in New Issue
Block a user