Skip to content

Commit

Permalink
Add min and max duration filter
Browse files Browse the repository at this point in the history
  • Loading branch information
Th0masL committed Nov 19, 2022
1 parent eb79ef0 commit 2552a6c
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 5 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down
4 changes: 3 additions & 1 deletion cmd/podsync/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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)

Expand Down
3 changes: 2 additions & 1 deletion config.toml.example
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 3 additions & 1 deletion pkg/feed/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
Expand All @@ -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
}

Expand Down
23 changes: 22 additions & 1 deletion services/update/matcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,27 @@ 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)
if err != nil {
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
}
}
Expand All @@ -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
}

0 comments on commit 2552a6c

Please sign in to comment.