Skip to content

Commit 2552a6c

Browse files
committed
Add min and max duration filter
1 parent eb79ef0 commit 2552a6c

File tree

5 files changed

+31
-5
lines changed

5 files changed

+31
-5
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ any device in podcast client.
2323
- Supports feeds configuration: video/audio, high/low quality, max video height, etc.
2424
- mp3 encoding
2525
- Update scheduler supports cron expressions
26-
- Episodes filtering (match by title).
26+
- Episodes filtering (match by title, duration).
2727
- Feeds customizations (custom artwork, category, language, etc).
2828
- OPML export.
2929
- Supports episodes cleanup (keep last X episodes).

cmd/podsync/config_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ timeout = 15
3737
update_period = "5h"
3838
format = "audio"
3939
quality = "low"
40-
filters = { title = "regex for title here" }
40+
filters = { title = "regex for title here", min_duration = 0, max_duration = 86400}
4141
playlist_sort = "desc"
4242
clean = { keep_last = 10 }
4343
[feeds.XYZ.custom]
@@ -78,6 +78,8 @@ timeout = 15
7878
assert.EqualValues(t, "audio", feed.Format)
7979
assert.EqualValues(t, "low", feed.Quality)
8080
assert.EqualValues(t, "regex for title here", feed.Filters.Title)
81+
assert.EqualValues(t, 0, feed.Filters.MinDuration)
82+
assert.EqualValues(t, 86400, feed.Filters.MaxDuration)
8183
assert.EqualValues(t, 10, feed.Clean.KeepLast)
8284
assert.EqualValues(t, model.SortingDesc, feed.PlaylistSort)
8385

config.toml.example

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ vimeo = [ # Multiple keys will be rotated.
7070

7171
# Optional Golang regexp format.
7272
# If set, then only download matching episodes.
73-
filters = { title = "regex for title here", not_title = "regex for negative title match", description = "...", not_description = "..." }
73+
# Duration filters are in seconds.
74+
filters = { title = "regex for title here", not_title = "regex for negative title match", description = "...", not_description = "...", min_duration = 0, max_duration = 86400 }
7475

7576
# Optional extra arguments passed to youtube-dl when downloading videos from this feed.
7677
# This example would embed available English closed captions in the videos.

pkg/feed/config.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ type Config struct {
2828
MaxHeight int `toml:"max_height"`
2929
// Format to use for this feed
3030
Format model.Format `toml:"format"`
31-
// Only download episodes that match this regexp (defaults to matching anything)
31+
// Only download episodes that match the filters (defaults to matching anything)
3232
Filters Filters `toml:"filters"`
3333
// Clean is a cleanup policy to use for this feed
3434
Clean Cleanup `toml:"clean"`
@@ -49,6 +49,8 @@ type Filters struct {
4949
NotTitle string `toml:"not_title"`
5050
Description string `toml:"description"`
5151
NotDescription string `toml:"not_description"`
52+
MinDuration int64 `toml:"min_duration"`
53+
MaxDuration int64 `toml:"max_duration"`
5254
// More filters to be added here
5355
}
5456

services/update/matcher.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,27 @@ import (
88
log "github.com/sirupsen/logrus"
99
)
1010

11+
func matchDurationFilter(duration_limit int64, episode_duration int64, operator string, logger log.FieldLogger) bool {
12+
if duration_limit != 0 {
13+
if operator == "min" && episode_duration < duration_limit {
14+
logger.Info("skipping due to duration filter")
15+
return false
16+
} else if operator == "max" && episode_duration > duration_limit {
17+
logger.Info("skipping due to duration filter")
18+
return false
19+
}
20+
}
21+
return true
22+
}
23+
1124
func matchRegexpFilter(pattern, str string, negative bool, logger log.FieldLogger) bool {
1225
if pattern != "" {
1326
matched, err := regexp.MatchString(pattern, str)
1427
if err != nil {
1528
logger.Warnf("pattern %q is not a valid")
1629
} else {
1730
if matched == negative {
18-
logger.Infof("skipping due to mismatch")
31+
logger.Infof("skipping due to regexp mismatch")
1932
return false
2033
}
2134
}
@@ -40,6 +53,14 @@ func matchFilters(episode *model.Episode, filters *feed.Filters) bool {
4053
if !matchRegexpFilter(filters.NotDescription, episode.Description, true, logger.WithField("filter", "not_description")) {
4154
return false
4255
}
56+
57+
if !matchDurationFilter(filters.MinDuration, episode.Duration, "min", logger.WithField("filter", "min_duration")) {
58+
return false
59+
}
60+
61+
if !matchDurationFilter(filters.MaxDuration, episode.Duration, "max", logger.WithField("filter", "max_duration")) {
62+
return false
63+
}
4364

4465
return true
4566
}

0 commit comments

Comments
 (0)