diff --git a/cmd/podsync/updater.go b/cmd/podsync/updater.go index 2aa4f71f..a548ea28 100644 --- a/cmd/podsync/updater.go +++ b/cmd/podsync/updater.go @@ -116,10 +116,33 @@ func (u *Updater) updateFeed(ctx context.Context, feedConfig *config.Feed) error log.Debugf("received %d episode(s) for %q", len(result.Episodes), result.Title) + episodeSet := make(map[string]struct{}) + if err := u.db.WalkEpisodes(ctx, feedConfig.ID, func(episode *model.Episode) error { + if episode.Status != model.EpisodeDownloaded && episode.Status != model.EpisodeCleaned { + episodeSet[episode.ID] = struct{}{} + } + return nil + }); err != nil { + return err + } + if err := u.db.AddFeed(ctx, feedConfig.ID, result); err != nil { return err } + for _, episode := range result.Episodes { + delete(episodeSet, episode.ID) + } + + // removing episodes that are no longer available in the feed and not downloaded or cleaned + for id := range episodeSet { + log.Infof("removing episode %q", id) + err := u.db.DeleteEpisode(feedConfig.ID, id) + if err != nil { + return err + } + } + log.Debug("successfully saved updates to storage") return nil } @@ -372,6 +395,8 @@ func (u *Updater) cleanup(ctx context.Context, feedConfig *config.Feed) error { if err := u.db.UpdateEpisode(feedID, episode.ID, func(episode *model.Episode) error { episode.Status = model.EpisodeCleaned + episode.Title = "" + episode.Description = "" return nil }); err != nil { result = multierror.Append(result, errors.Wrapf(err, "failed to set state for cleaned episode: %s", episode.ID)) diff --git a/pkg/db/badger.go b/pkg/db/badger.go index daef6d43..41e6ad5b 100644 --- a/pkg/db/badger.go +++ b/pkg/db/badger.go @@ -214,6 +214,13 @@ func (b *Badger) UpdateEpisode(feedID string, episodeID string, cb func(episode }) } +func (b *Badger) DeleteEpisode(feedID, episodeID string) error { + key := b.getKey(episodePath, feedID, episodeID) + return b.db.Update(func(txn *badger.Txn) error { + return txn.Delete(key) + }) +} + func (b *Badger) WalkEpisodes(ctx context.Context, feedID string, cb func(episode *model.Episode) error) error { return b.db.View(func(txn *badger.Txn) error { return b.walkEpisodes(txn, feedID, cb) diff --git a/pkg/db/storage.go b/pkg/db/storage.go index 3da4dc85..9b518cdd 100644 --- a/pkg/db/storage.go +++ b/pkg/db/storage.go @@ -36,6 +36,9 @@ type Storage interface { // UpdateEpisode updates episode fields UpdateEpisode(feedID string, episodeID string, cb func(episode *model.Episode) error) error + // DeleteEpisode deletes an episode + DeleteEpisode(feedID string, episodeID string) error + // WalkEpisodes iterates over episodes that belong to the given feed ID WalkEpisodes(ctx context.Context, feedID string, cb func(episode *model.Episode) error) error }