1
0
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:
Maksym Pavlenko
2020-03-07 18:01:00 -08:00
parent e0290afa11
commit 35dc6043bc
4 changed files with 73 additions and 0 deletions

View File

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

View File

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

View File

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

View File

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