mirror of
https://github.com/idanoo/autobrr
synced 2025-07-23 16:59:12 +00:00
feat(filters): add regex support (#258)
This commit is contained in:
parent
e6c151a029
commit
5d032dd075
3 changed files with 101 additions and 6 deletions
|
@ -2,6 +2,7 @@ package domain
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -113,13 +114,24 @@ func (f Filter) CheckFilter(r *Release) ([]string, bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// matchRelease
|
// matchRelease
|
||||||
// TODO allow to match against regex
|
// match against regex
|
||||||
if f.MatchReleases != "" && !containsFuzzy(r.TorrentName, f.MatchReleases) {
|
if f.UseRegex {
|
||||||
r.addRejectionF("match release not matching. got: %v want: %v", r.TorrentName, f.MatchReleases)
|
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) {
|
if f.ExceptReleases != "" && matchRegex(r.TorrentName, f.ExceptReleases) {
|
||||||
r.addRejectionF("except releases: unwanted release. got: %v want: %v", 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) {
|
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
|
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"
|
// checkFilterIntStrings "1,2,3-20"
|
||||||
func containsIntStrings(value int, filterList string) bool {
|
func containsIntStrings(value int, filterList string) bool {
|
||||||
filters := strings.Split(filterList, ",")
|
filters := strings.Split(filterList, ",")
|
||||||
|
|
|
@ -1361,6 +1361,56 @@ func TestFilter_CheckFilter1(t *testing.T) {
|
||||||
wantRejections: []string{"origin not matching. got: want: [SCENE]"},
|
wantRejections: []string{"origin not matching. got: want: [SCENE]"},
|
||||||
wantMatch: false,
|
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 {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
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)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -256,6 +256,7 @@ export default function FilterDetails() {
|
||||||
max_size: filter.max_size,
|
max_size: filter.max_size,
|
||||||
delay: filter.delay,
|
delay: filter.delay,
|
||||||
priority: filter.priority,
|
priority: filter.priority,
|
||||||
|
use_regex: filter.use_regex || false,
|
||||||
shows: filter.shows,
|
shows: filter.shows,
|
||||||
years: filter.years,
|
years: filter.years,
|
||||||
resolutions: filter.resolutions || [],
|
resolutions: filter.resolutions || [],
|
||||||
|
@ -487,6 +488,9 @@ function Advanced() {
|
||||||
<CollapsableSection title="Releases" subtitle="Match only certain release names and/or ignore other release names">
|
<CollapsableSection title="Releases" subtitle="Match only certain release names and/or ignore other release names">
|
||||||
<TextField name="match_releases" label="Match releases" columns={6} placeholder="eg. *some?movie*,*some?show*s01*" />
|
<TextField name="match_releases" label="Match releases" columns={6} placeholder="eg. *some?movie*,*some?show*s01*" />
|
||||||
<TextField name="except_releases" label="Except releases" columns={6} placeholder="" />
|
<TextField name="except_releases" label="Except releases" columns={6} placeholder="" />
|
||||||
|
<div className="col-span-6">
|
||||||
|
<SwitchGroup name="use_regex" label="Use Regex" />
|
||||||
|
</div>
|
||||||
</CollapsableSection>
|
</CollapsableSection>
|
||||||
|
|
||||||
<CollapsableSection title="Groups" subtitle="Match only certain groups and/or ignore other groups">
|
<CollapsableSection title="Groups" subtitle="Match only certain groups and/or ignore other groups">
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue