From 2552a6c6b36ecd52e170ba11924aa282d5302900 Mon Sep 17 00:00:00 2001 From: Th0masL Date: Sat, 19 Nov 2022 21:51:14 +0200 Subject: [PATCH 1/4] Add min and max duration filter --- README.md | 2 +- cmd/podsync/config_test.go | 4 +++- config.toml.example | 3 ++- pkg/feed/config.go | 4 +++- services/update/matcher.go | 23 ++++++++++++++++++++++- 5 files changed, 31 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index fdc1be3..74372e0 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ any device in podcast client. - Supports feeds configuration: video/audio, high/low quality, max video height, etc. - mp3 encoding - Update scheduler supports cron expressions -- Episodes filtering (match by title). +- Episodes filtering (match by title, duration). - Feeds customizations (custom artwork, category, language, etc). - OPML export. - Supports episodes cleanup (keep last X episodes). diff --git a/cmd/podsync/config_test.go b/cmd/podsync/config_test.go index ef5e5ff..9a79a97 100644 --- a/cmd/podsync/config_test.go +++ b/cmd/podsync/config_test.go @@ -37,7 +37,7 @@ timeout = 15 update_period = "5h" format = "audio" quality = "low" - filters = { title = "regex for title here" } + filters = { title = "regex for title here", min_duration = 0, max_duration = 86400} playlist_sort = "desc" clean = { keep_last = 10 } [feeds.XYZ.custom] @@ -78,6 +78,8 @@ timeout = 15 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, 0, feed.Filters.MinDuration) + assert.EqualValues(t, 86400, feed.Filters.MaxDuration) assert.EqualValues(t, 10, feed.Clean.KeepLast) assert.EqualValues(t, model.SortingDesc, feed.PlaylistSort) diff --git a/config.toml.example b/config.toml.example index 094f744..886fe39 100644 --- a/config.toml.example +++ b/config.toml.example @@ -70,7 +70,8 @@ vimeo = [ # Multiple keys will be rotated. # Optional Golang regexp format. # If set, then only download matching episodes. - filters = { title = "regex for title here", not_title = "regex for negative title match", description = "...", not_description = "..." } + # Duration filters are in seconds. + filters = { title = "regex for title here", not_title = "regex for negative title match", description = "...", not_description = "...", min_duration = 0, max_duration = 86400 } # Optional extra arguments passed to youtube-dl when downloading videos from this feed. # This example would embed available English closed captions in the videos. diff --git a/pkg/feed/config.go b/pkg/feed/config.go index 2a7a741..8aa5a4a 100644 --- a/pkg/feed/config.go +++ b/pkg/feed/config.go @@ -28,7 +28,7 @@ type Config struct { MaxHeight int `toml:"max_height"` // Format to use for this feed Format model.Format `toml:"format"` - // Only download episodes that match this regexp (defaults to matching anything) + // Only download episodes that match the filters (defaults to matching anything) Filters Filters `toml:"filters"` // Clean is a cleanup policy to use for this feed Clean Cleanup `toml:"clean"` @@ -49,6 +49,8 @@ type Filters struct { NotTitle string `toml:"not_title"` Description string `toml:"description"` NotDescription string `toml:"not_description"` + MinDuration int64 `toml:"min_duration"` + MaxDuration int64 `toml:"max_duration"` // More filters to be added here } diff --git a/services/update/matcher.go b/services/update/matcher.go index f28753d..47fa7a4 100644 --- a/services/update/matcher.go +++ b/services/update/matcher.go @@ -8,6 +8,19 @@ import ( log "github.com/sirupsen/logrus" ) +func matchDurationFilter(duration_limit int64, episode_duration int64, operator string, logger log.FieldLogger) bool { + if duration_limit != 0 { + if operator == "min" && episode_duration < duration_limit { + logger.Info("skipping due to duration filter") + return false + } else if operator == "max" && episode_duration > duration_limit { + logger.Info("skipping due to duration filter") + return false + } + } + return true +} + func matchRegexpFilter(pattern, str string, negative bool, logger log.FieldLogger) bool { if pattern != "" { matched, err := regexp.MatchString(pattern, str) @@ -15,7 +28,7 @@ func matchRegexpFilter(pattern, str string, negative bool, logger log.FieldLogge logger.Warnf("pattern %q is not a valid") } else { if matched == negative { - logger.Infof("skipping due to mismatch") + logger.Infof("skipping due to regexp mismatch") return false } } @@ -40,6 +53,14 @@ func matchFilters(episode *model.Episode, filters *feed.Filters) bool { if !matchRegexpFilter(filters.NotDescription, episode.Description, true, logger.WithField("filter", "not_description")) { return false } + + if !matchDurationFilter(filters.MinDuration, episode.Duration, "min", logger.WithField("filter", "min_duration")) { + return false + } + + if !matchDurationFilter(filters.MaxDuration, episode.Duration, "max", logger.WithField("filter", "max_duration")) { + return false + } return true } From a546bbf25f6877459b42803a4e7c4516bb2ee793 Mon Sep 17 00:00:00 2001 From: Th0masL Date: Sat, 19 Nov 2022 22:22:12 +0200 Subject: [PATCH 2/4] Rename vars --- services/update/matcher.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/services/update/matcher.go b/services/update/matcher.go index 47fa7a4..447f7de 100644 --- a/services/update/matcher.go +++ b/services/update/matcher.go @@ -8,12 +8,12 @@ import ( log "github.com/sirupsen/logrus" ) -func matchDurationFilter(duration_limit int64, episode_duration int64, operator string, logger log.FieldLogger) bool { - if duration_limit != 0 { - if operator == "min" && episode_duration < duration_limit { +func matchDurationFilter(durationLimit int64, episodeDuration int64, operator string, logger log.FieldLogger) bool { + if durationLimit != 0 { + if operator == "min" && episodeDuration < durationLimit { logger.Info("skipping due to duration filter") return false - } else if operator == "max" && episode_duration > duration_limit { + } else if operator == "max" && episodeDuration > durationLimit { logger.Info("skipping due to duration filter") return false } From c8b4aa27183c6fa111b9a01f81eac0ab38abaace Mon Sep 17 00:00:00 2001 From: Th0masL Date: Sat, 19 Nov 2022 22:36:57 +0200 Subject: [PATCH 3/4] run gofmt --- services/update/matcher.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/update/matcher.go b/services/update/matcher.go index 447f7de..93bf37f 100644 --- a/services/update/matcher.go +++ b/services/update/matcher.go @@ -53,7 +53,7 @@ func matchFilters(episode *model.Episode, filters *feed.Filters) bool { if !matchRegexpFilter(filters.NotDescription, episode.Description, true, logger.WithField("filter", "not_description")) { return false } - + if !matchDurationFilter(filters.MinDuration, episode.Duration, "min", logger.WithField("filter", "min_duration")) { return false } From 4ebdc47aa9a98ae9b07987bfeae6054f7a20df4b Mon Sep 17 00:00:00 2001 From: Th0masL Date: Wed, 23 Nov 2022 20:04:07 +0200 Subject: [PATCH 4/4] Remove helper --- .gitignore | 1 + services/update/matcher.go | 19 ++++--------------- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index 6d89f1a..0955eba 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,7 @@ venv/ .DS_Store /podsync +podsync.log db config.toml \ No newline at end of file diff --git a/services/update/matcher.go b/services/update/matcher.go index 93bf37f..b432fcb 100644 --- a/services/update/matcher.go +++ b/services/update/matcher.go @@ -8,19 +8,6 @@ import ( log "github.com/sirupsen/logrus" ) -func matchDurationFilter(durationLimit int64, episodeDuration int64, operator string, logger log.FieldLogger) bool { - if durationLimit != 0 { - if operator == "min" && episodeDuration < durationLimit { - logger.Info("skipping due to duration filter") - return false - } else if operator == "max" && episodeDuration > durationLimit { - logger.Info("skipping due to duration filter") - return false - } - } - return true -} - func matchRegexpFilter(pattern, str string, negative bool, logger log.FieldLogger) bool { if pattern != "" { matched, err := regexp.MatchString(pattern, str) @@ -54,11 +41,13 @@ func matchFilters(episode *model.Episode, filters *feed.Filters) bool { return false } - if !matchDurationFilter(filters.MinDuration, episode.Duration, "min", logger.WithField("filter", "min_duration")) { + if filters.MaxDuration > 0 && episode.Duration > filters.MaxDuration { + logger.WithField("filter", "max_duration").Infof("skipping due to duration filter (%ds)", episode.Duration) return false } - if !matchDurationFilter(filters.MaxDuration, episode.Duration, "max", logger.WithField("filter", "max_duration")) { + if filters.MinDuration > 0 && episode.Duration < filters.MinDuration { + logger.WithField("filter", "min_duration").Infof("skipping due to duration filter (%ds)", episode.Duration) return false }