diff --git a/internal/domain/filter.go b/internal/domain/filter.go index 3ec98b0..edba9ad 100644 --- a/internal/domain/filter.go +++ b/internal/domain/filter.go @@ -2,6 +2,7 @@ package domain import ( "context" + "regexp" "strconv" "strings" "time" @@ -113,13 +114,24 @@ func (f Filter) CheckFilter(r *Release) ([]string, bool) { } // matchRelease - // TODO allow to match against regex - if f.MatchReleases != "" && !containsFuzzy(r.TorrentName, f.MatchReleases) { - r.addRejectionF("match release not matching. got: %v want: %v", r.TorrentName, f.MatchReleases) - } + // match against regex + if f.UseRegex { + if f.MatchReleases != "" && !matchRegex(r.TorrentName, f.MatchReleases) { + r.addRejectionF("match release regex not matching. got: %v want: %v", r.TorrentName, f.MatchReleases) + } - if f.ExceptReleases != "" && containsFuzzy(r.TorrentName, f.ExceptReleases) { - r.addRejectionF("except releases: unwanted release. got: %v want: %v", r.TorrentName, f.ExceptReleases) + if f.ExceptReleases != "" && matchRegex(r.TorrentName, f.ExceptReleases) { + r.addRejectionF("except releases regex: unwanted release. got: %v want: %v", r.TorrentName, f.ExceptReleases) + } + + } else { + if f.MatchReleases != "" && !containsFuzzy(r.TorrentName, f.MatchReleases) { + r.addRejectionF("match release not matching. got: %v want: %v", r.TorrentName, f.MatchReleases) + } + + if f.ExceptReleases != "" && containsFuzzy(r.TorrentName, f.ExceptReleases) { + r.addRejectionF("except releases: unwanted release. got: %v want: %v", r.TorrentName, f.ExceptReleases) + } } if f.MatchReleaseGroups != "" && !contains(r.Group, f.MatchReleaseGroups) { @@ -307,6 +319,15 @@ func (f Filter) checkSizeFilter(r *Release, minSize string, maxSize string) bool return true } +func matchRegex(tag string, filter string) bool { + re, err := regexp.Compile(`(?i)(?:` + filter + `)`) + if err != nil { + return false + } + + return re.MatchString(tag) +} + // checkFilterIntStrings "1,2,3-20" func containsIntStrings(value int, filterList string) bool { filters := strings.Split(filterList, ",") diff --git a/internal/domain/filter_test.go b/internal/domain/filter_test.go index 1b63313..f5994b1 100644 --- a/internal/domain/filter_test.go +++ b/internal/domain/filter_test.go @@ -1361,6 +1361,56 @@ func TestFilter_CheckFilter1(t *testing.T) { wantRejections: []string{"origin not matching. got: want: [SCENE]"}, wantMatch: false, }, + { + name: "test_27", + fields: fields{ + UseRegex: true, + MatchReleases: ".*1080p.+(group1|group3)", + }, + args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2"}}, + wantRejections: []string{"match release regex not matching. got: Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2 want: .*1080p.+(group1|group3)"}, + wantMatch: false, + }, + { + name: "test_28", + fields: fields{ + UseRegex: true, + MatchReleases: ".*2160p.+(group1|group2)", + }, + args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2"}}, + wantRejections: nil, + wantMatch: true, + }, + { + name: "test_29", + fields: fields{ + UseRegex: true, + MatchReleases: "*2160p*", + }, + args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2"}}, + wantRejections: []string{"match release regex not matching. got: Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2 want: *2160p*"}, + wantMatch: false, + }, + { + name: "test_30", + fields: fields{ + UseRegex: true, + MatchReleases: "2160p", + }, + args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2"}}, + wantRejections: nil, + wantMatch: true, + }, + { + name: "test_31", + fields: fields{ + UseRegex: false, + MatchReleases: "*2160p*", + }, + args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2"}}, + wantRejections: nil, + wantMatch: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -1535,3 +1585,23 @@ func Test_containsIntStrings(t *testing.T) { }) } } + +func Test_matchRegex(t *testing.T) { + type args struct { + tag string + filter string + } + tests := []struct { + name string + args args + want bool + }{ + {name: "test_1", args: args{tag: "Some.show.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP1", filter: ".*2160p.+(group1|group2)"}, want: true}, + {name: "test_2", args: args{tag: "Some.show.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2", filter: ".*1080p.+(group1|group3)"}, want: false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equalf(t, tt.want, matchRegex(tt.args.tag, tt.args.filter), "matchRegex(%v, %v)", tt.args.tag, tt.args.filter) + }) + } +} diff --git a/web/src/screens/filters/details.tsx b/web/src/screens/filters/details.tsx index 6742d00..4fc7889 100644 --- a/web/src/screens/filters/details.tsx +++ b/web/src/screens/filters/details.tsx @@ -256,6 +256,7 @@ export default function FilterDetails() { max_size: filter.max_size, delay: filter.delay, priority: filter.priority, + use_regex: filter.use_regex || false, shows: filter.shows, years: filter.years, resolutions: filter.resolutions || [], @@ -487,6 +488,9 @@ function Advanced() { +
+ +