From f029de233fa2489948d2b76d2db8fc0dfea8ea7f Mon Sep 17 00:00:00 2001 From: ze0s <43699394+zze0s@users.noreply.github.com> Date: Sun, 20 Oct 2024 22:58:55 +0200 Subject: [PATCH] feat(filters): improve rejection handling (#1776) * feat(filters): improve rejection handling * fix(filters): rejection tests * fix(filters): size check error rejection --- internal/domain/filter.go | 179 ++++++------- internal/domain/filter_test.go | 416 +++++++++++++++++------------ internal/domain/rejections.go | 140 ++++++++++ internal/domain/rejections_test.go | 115 ++++++++ internal/domain/release.go | 29 -- internal/filter/service.go | 12 +- internal/indexer/indexer_test.go | 2 +- internal/release/service.go | 4 +- 8 files changed, 586 insertions(+), 311 deletions(-) create mode 100644 internal/domain/rejections.go create mode 100644 internal/domain/rejections_test.go diff --git a/internal/domain/filter.go b/internal/domain/filter.go index 22ea4e8..2755da8 100644 --- a/internal/domain/filter.go +++ b/internal/domain/filter.go @@ -52,6 +52,10 @@ type FilterDownloads struct { TotalCount int } +func (f *FilterDownloads) String() string { + return fmt.Sprintf("Hour: %d, Day: %d, Week: %d, Month: %d, Total: %d", f.HourCount, f.DayCount, f.WeekCount, f.MonthCount, f.TotalCount) +} + type FilterMaxDownloadsUnit string const ( @@ -164,6 +168,7 @@ type Filter struct { Indexers []Indexer `json:"indexers"` Downloads *FilterDownloads `json:"-"` Rejections []string `json:"-"` + RejectReasons *RejectionReasons `json:"-"` } type FilterExternal struct { @@ -354,156 +359,156 @@ func (f *Filter) Sanitize() error { return nil } -func (f *Filter) CheckFilter(r *Release) ([]string, bool) { +func (f *Filter) CheckFilter(r *Release) (*RejectionReasons, bool) { + f.RejectReasons = NewRejectionReasons() + // max downloads check. If reached return early so other filters can be checked as quick as possible. if f.MaxDownloads > 0 && !f.checkMaxDownloads() { - f.addRejectionF("max downloads (%d) this (%v) reached", f.MaxDownloads, f.MaxDownloadsUnit) - return f.Rejections, false + f.RejectReasons.Addf("max downloads", fmt.Sprintf("[max downloads] reached %d per %s", f.MaxDownloads, f.MaxDownloadsUnit), f.Downloads.String(), fmt.Sprintf("reached %d per %s", f.MaxDownloads, f.MaxDownloadsUnit)) + return f.RejectReasons, false } if len(f.Bonus) > 0 && !sliceContainsSlice(r.Bonus, f.Bonus) { - r.addRejectionF("bonus not matching. got: %v want: %v", r.Bonus, f.Bonus) + f.RejectReasons.Add("bonus", r.Bonus, f.Bonus) } if f.Freeleech && r.Freeleech != f.Freeleech { - f.addRejection("wanted: freeleech") + f.RejectReasons.Add("freeleech", r.Freeleech, f.Freeleech) } if f.FreeleechPercent != "" && !checkFreeleechPercent(r.FreeleechPercent, f.FreeleechPercent) { - f.addRejectionF("freeleech percent not matching. got: %v want: %v", r.FreeleechPercent, f.FreeleechPercent) + f.RejectReasons.Add("freeleech percent", r.FreeleechPercent, f.FreeleechPercent) } if len(f.Origins) > 0 && !containsSlice(r.Origin, f.Origins) { - f.addRejectionF("origin not matching. got: %v want: %v", r.Origin, f.Origins) + f.RejectReasons.Add("match origin", r.Origin, f.Origins) } if len(f.ExceptOrigins) > 0 && containsSlice(r.Origin, f.ExceptOrigins) { - f.addRejectionF("except origin not matching. got: %v unwanted: %v", r.Origin, f.ExceptOrigins) + f.RejectReasons.Add("except origin", r.Origin, f.ExceptOrigins) } // title is the parsed title if f.Shows != "" && !contains(r.Title, f.Shows) { - f.addRejectionF("shows not matching. got: %v want: %v", r.Title, f.Shows) + f.RejectReasons.Add("shows", r.Title, f.Shows) } if f.Seasons != "" && !containsIntStrings(r.Season, f.Seasons) { - f.addRejectionF("season not matching. got: %d want: %v", r.Season, f.Seasons) + f.RejectReasons.Add("season", r.Season, f.Seasons) } if f.Episodes != "" && !containsIntStrings(r.Episode, f.Episodes) { - f.addRejectionF("episodes not matching. got: %d want: %v", r.Episode, f.Episodes) + f.RejectReasons.Add("episodes", r.Episode, f.Episodes) } // matchRelease // match against regex if f.UseRegex { if f.MatchReleases != "" && !matchRegex(r.TorrentName, f.MatchReleases) { - f.addRejectionF("match release regex not matching. got: %v want: %v", r.TorrentName, f.MatchReleases) + f.RejectReasons.Add("match releases: REGEX", r.TorrentName, f.MatchReleases) } if f.ExceptReleases != "" && matchRegex(r.TorrentName, f.ExceptReleases) { - f.addRejectionF("except releases regex: unwanted release. got: %v want: %v", r.TorrentName, f.ExceptReleases) + f.RejectReasons.Add("except releases: REGEX", r.TorrentName, f.ExceptReleases) } } else { if f.MatchReleases != "" && !containsFuzzy(r.TorrentName, f.MatchReleases) { - f.addRejectionF("match release not matching. got: %v want: %v", r.TorrentName, f.MatchReleases) + f.RejectReasons.Add("match releases", r.TorrentName, f.MatchReleases) } if f.ExceptReleases != "" && containsFuzzy(r.TorrentName, f.ExceptReleases) { - f.addRejectionF("except releases: unwanted release. got: %v want: %v", r.TorrentName, f.ExceptReleases) + f.RejectReasons.Add("except releases", r.TorrentName, f.ExceptReleases) } } if f.MatchReleaseGroups != "" && !contains(r.Group, f.MatchReleaseGroups) { - f.addRejectionF("release groups not matching. got: %v want: %v", r.Group, f.MatchReleaseGroups) + f.RejectReasons.Add("match release groups", r.Group, f.MatchReleaseGroups) } if f.ExceptReleaseGroups != "" && contains(r.Group, f.ExceptReleaseGroups) { - f.addRejectionF("unwanted release group. got: %v unwanted: %v", r.Group, f.ExceptReleaseGroups) + f.RejectReasons.Add("except release groups", r.Group, f.ExceptReleaseGroups) } // check raw releaseTags string if f.UseRegexReleaseTags { if f.MatchReleaseTags != "" && !matchRegex(r.ReleaseTags, f.MatchReleaseTags) { - f.addRejectionF("match release tags regex not matching. got: %v want: %v", r.ReleaseTags, f.MatchReleaseTags) + f.RejectReasons.Add("match release tags: REGEX", r.ReleaseTags, f.MatchReleaseTags) } if f.ExceptReleaseTags != "" && matchRegex(r.ReleaseTags, f.ExceptReleaseTags) { - f.addRejectionF("except release tags regex: unwanted release. got: %v want: %v", r.ReleaseTags, f.ExceptReleaseTags) + f.RejectReasons.Add("except release tags: REGEX", r.ReleaseTags, f.ExceptReleaseTags) } } else { if f.MatchReleaseTags != "" && !containsFuzzy(r.ReleaseTags, f.MatchReleaseTags) { - f.addRejectionF("match release tags not matching. got: %v want: %v", r.ReleaseTags, f.MatchReleaseTags) + f.RejectReasons.Add("match release tags", r.ReleaseTags, f.MatchReleaseTags) } if f.ExceptReleaseTags != "" && containsFuzzy(r.ReleaseTags, f.ExceptReleaseTags) { - f.addRejectionF("except release tags: unwanted release. got: %v want: %v", r.ReleaseTags, f.ExceptReleaseTags) + f.RejectReasons.Add("except release tags", r.ReleaseTags, f.ExceptReleaseTags) } } if f.MatchUploaders != "" && !contains(r.Uploader, f.MatchUploaders) { - f.addRejectionF("uploaders not matching. got: %v want: %v", r.Uploader, f.MatchUploaders) + f.RejectReasons.Add("match uploaders", r.Uploader, f.MatchUploaders) } if f.ExceptUploaders != "" && contains(r.Uploader, f.ExceptUploaders) { - f.addRejectionF("unwanted uploaders. got: %v unwanted: %v", r.Uploader, f.ExceptUploaders) + f.RejectReasons.Add("except uploaders", r.Uploader, f.ExceptUploaders) } if len(f.MatchLanguage) > 0 && !sliceContainsSlice(r.Language, f.MatchLanguage) { - f.addRejectionF("language not matching. got: %v want: %v", r.Language, f.MatchLanguage) + f.RejectReasons.Add("match language", r.Language, f.MatchLanguage) } if len(f.ExceptLanguage) > 0 && sliceContainsSlice(r.Language, f.ExceptLanguage) { - f.addRejectionF("language unwanted. got: %v want: %v", r.Language, f.ExceptLanguage) + f.RejectReasons.Add("except language", r.Language, f.ExceptLanguage) } if len(f.Resolutions) > 0 && !containsSlice(r.Resolution, f.Resolutions) { - f.addRejectionF("resolution not matching. got: %v want: %v", r.Resolution, f.Resolutions) + f.RejectReasons.Add("resolution", r.Resolution, f.Resolutions) } if len(f.Codecs) > 0 && !sliceContainsSlice(r.Codec, f.Codecs) { - f.addRejectionF("codec not matching. got: %v want: %v", r.Codec, f.Codecs) + f.RejectReasons.Add("codec", r.Codec, f.Codecs) } if len(f.Sources) > 0 && !containsSlice(r.Source, f.Sources) { - f.addRejectionF("source not matching. got: %v want: %v", r.Source, f.Sources) + f.RejectReasons.Add("source", r.Source, f.Sources) } if len(f.Containers) > 0 && !containsSlice(r.Container, f.Containers) { - f.addRejectionF("container not matching. got: %v want: %v", r.Container, f.Containers) + f.RejectReasons.Add("container", r.Container, f.Containers) } - // HDR is parsed into the Codec slice from rls if len(f.MatchHDR) > 0 && !matchHDR(r.HDR, f.MatchHDR) { - f.addRejectionF("hdr not matching. got: %v want: %v", r.HDR, f.MatchHDR) + f.RejectReasons.Add("match hdr", r.HDR, f.MatchHDR) } - // HDR is parsed into the Codec slice from rls if len(f.ExceptHDR) > 0 && matchHDR(r.HDR, f.ExceptHDR) { - f.addRejectionF("hdr unwanted. got: %v want: %v", r.HDR, f.ExceptHDR) + f.RejectReasons.Add("except hdr", r.HDR, f.ExceptHDR) } // Other is parsed into the Other slice from rls if len(f.MatchOther) > 0 && !sliceContainsSlice(r.Other, f.MatchOther) { - f.addRejectionF("match other not matching. got: %v want: %v", r.Other, f.MatchOther) + f.RejectReasons.Add("match other", r.Other, f.MatchOther) } // Other is parsed into the Other slice from rls if len(f.ExceptOther) > 0 && sliceContainsSlice(r.Other, f.ExceptOther) { - f.addRejectionF("except other unwanted. got: %v unwanted: %v", r.Other, f.ExceptOther) + f.RejectReasons.Add("except other", r.Other, f.ExceptOther) } if f.Years != "" && !containsIntStrings(r.Year, f.Years) { - f.addRejectionF("year not matching. got: %d want: %v", r.Year, f.Years) + f.RejectReasons.Add("year", r.Year, f.Years) } if f.Months != "" && !containsIntStrings(r.Month, f.Months) { - f.addRejectionF("month not matching. got: %d want: %v", r.Month, f.Months) + f.RejectReasons.Add("month", r.Month, f.Months) } if f.Days != "" && !containsIntStrings(r.Day, f.Days) { - f.addRejectionF("day not matching. got: %d want: %v", r.Day, f.Days) + f.RejectReasons.Add("day", r.Day, f.Days) } if f.MatchCategories != "" { @@ -513,7 +518,7 @@ func (f *Filter) CheckFilter(r *Release) ([]string, bool) { categories = append(categories, r.Category) } if !contains(r.Category, f.MatchCategories) && !containsAny(categories, f.MatchCategories) { - f.addRejectionF("category not matching. got: %v want: %v", strings.Join(categories, ","), f.MatchCategories) + f.RejectReasons.Add("match category", strings.Join(categories, ","), f.MatchCategories) } } @@ -524,121 +529,126 @@ func (f *Filter) CheckFilter(r *Release) ([]string, bool) { categories = append(categories, r.Category) } if contains(r.Category, f.ExceptCategories) && containsAny(categories, f.ExceptCategories) { - f.addRejectionF("category unwanted. got: %v unwanted: %v", strings.Join(categories, ","), f.ExceptCategories) + f.RejectReasons.Add("except category", strings.Join(categories, ","), f.ExceptCategories) } } + // music related if len(f.MatchReleaseTypes) > 0 && !containsSlice(r.Category, f.MatchReleaseTypes) { - f.addRejectionF("release type not matching. got: %v want: %v", r.Category, f.MatchReleaseTypes) + f.RejectReasons.Add("release type", r.Category, f.MatchReleaseTypes) } - if (f.MinSize != "" || f.MaxSize != "") && !f.checkSizeFilter(r) { - f.addRejectionF("size not matching. got: %v want min: %v max: %v", r.Size, f.MinSize, f.MaxSize) + if f.MinSize != "" && !f.checkSizeFilter(r) { + f.RejectReasons.Add("min size", r.Size, f.MinSize) + } + + if f.MaxSize != "" && !f.checkSizeFilter(r) { + f.RejectReasons.Add("max size", r.Size, f.MaxSize) } if f.Tags != "" { if f.TagsMatchLogic == "ALL" && !containsAll(r.Tags, f.Tags) { - f.addRejectionF("tags not matching. got: %v want(all): %v", r.Tags, f.Tags) + f.RejectReasons.Add("match tags: ALL", r.Tags, f.Tags) } else if !containsAny(r.Tags, f.Tags) { // TagsMatchLogic is set to "" by default, this makes sure that "" and "ANY" are treated the same way. - f.addRejectionF("tags not matching. got: %v want: %v", r.Tags, f.Tags) + f.RejectReasons.Add("match tags: ANY", r.Tags, f.Tags) } } if f.ExceptTags != "" { if f.ExceptTagsMatchLogic == "ALL" && containsAll(r.Tags, f.ExceptTags) { - f.addRejectionF("tags unwanted. got: %v don't want: %v", r.Tags, f.ExceptTags) + f.RejectReasons.Add("except tags: ALL", r.Tags, f.ExceptTags) } else if containsAny(r.Tags, f.ExceptTags) { // ExceptTagsMatchLogic is set to "" by default, this makes sure that "" and "ANY" are treated the same way. - f.addRejectionF("tags unwanted. got: %v don't want: %v", r.Tags, f.ExceptTags) + f.RejectReasons.Add("except tags: ANY", r.Tags, f.ExceptTags) } } if len(f.Artists) > 0 && !contains(r.Artists, f.Artists) { - f.addRejectionF("artists not matching. got: %v want: %v", r.Artists, f.Artists) + f.RejectReasons.Add("artists", r.Artists, f.Artists) } if len(f.Albums) > 0 && !contains(r.Title, f.Albums) { - f.addRejectionF("albums not matching. got: %v want: %v", r.Title, f.Albums) + f.RejectReasons.Add("albums", r.Title, f.Albums) } // Perfect flac requires Cue, Log, Log Score 100, FLAC and 24bit Lossless if f.PerfectFlac && !f.isPerfectFLAC(r) { - f.addRejectionF("wanted: perfect flac. got: %v", r.Audio) + f.RejectReasons.Add("perfect flac", r.Audio, "Cue, Log, Log Score 100, FLAC and 24bit Lossless") } if len(f.Formats) > 0 && !sliceContainsSlice(r.Audio, f.Formats) { - f.addRejectionF("formats not matching. got: %v want: %v", r.Audio, f.Formats) + f.RejectReasons.Add("formats", r.Audio, f.Formats) } if len(f.Quality) > 0 && !containsMatchBasic(r.Audio, f.Quality) { - f.addRejectionF("quality not matching. got: %v want: %v", r.Audio, f.Quality) + f.RejectReasons.Add("quality", r.Audio, f.Quality) } if len(f.Media) > 0 && !containsSlice(r.Source, f.Media) { - f.addRejectionF("media not matching. got: %v want: %v", r.Source, f.Media) + f.RejectReasons.Add("media", r.Source, f.Media) } if f.Cue && !containsAny(r.Audio, "Cue") { - f.addRejection("wanted: cue") + f.RejectReasons.Add("cue", r.Audio, "Cue") } if f.Log && !containsAny(r.Audio, "Log") { - f.addRejection("wanted: log") + f.RejectReasons.Add("log", r.Audio, "Log") } if f.Log && f.LogScore != 0 && r.LogScore != f.LogScore { - f.addRejectionF("log score. got: %v want: %v", r.LogScore, f.LogScore) + f.RejectReasons.Add("log score", r.LogScore, f.LogScore) } // check description string if f.UseRegexDescription { if f.MatchDescription != "" && !matchRegex(r.Description, f.MatchDescription) { - f.addRejectionF("match description regex not matching. got: %v want: %v", r.Description, f.MatchDescription) + f.RejectReasons.Add("match description: REGEX", r.Description, f.MatchDescription) } if f.ExceptDescription != "" && matchRegex(r.Description, f.ExceptDescription) { - f.addRejectionF("except description regex: unwanted release. got: %v want: %v", r.Description, f.ExceptDescription) + f.RejectReasons.Add("except description: REGEX", r.Description, f.ExceptDescription) } } else { if f.MatchDescription != "" && !containsFuzzy(r.Description, f.MatchDescription) { - f.addRejectionF("match description not matching. got: %v want: %v", r.Description, f.MatchDescription) + f.RejectReasons.Add("match description", r.Description, f.MatchDescription) } if f.ExceptDescription != "" && containsFuzzy(r.Description, f.ExceptDescription) { - f.addRejectionF("except description: unwanted release. got: %v want: %v", r.Description, f.ExceptDescription) + f.RejectReasons.Add("except description", r.Description, f.ExceptDescription) } } // Min and Max Seeders/Leechers is only for Torznab feeds if f.MinSeeders > 0 { if f.MinSeeders > r.Seeders { - f.addRejectionF("min seeders not matcing. got: %d want %d", r.Seeders, f.MinSeeders) + f.RejectReasons.Add("min seeders", r.Seeders, f.MinSeeders) } } if f.MaxSeeders > 0 { if f.MaxSeeders < r.Seeders { - f.addRejectionF("max seeders not matcing. got: %d want %d", r.Seeders, f.MaxSeeders) + f.RejectReasons.Add("max seeders", r.Seeders, f.MaxSeeders) } } if f.MinLeechers > 0 { if f.MinLeechers > r.Leechers { - f.addRejectionF("min leechers not matcing. got: %d want %d", r.Leechers, f.MinLeechers) + f.RejectReasons.Add("min leechers", r.Leechers, f.MinLeechers) } } if f.MaxLeechers > 0 { if f.MaxLeechers < r.Leechers { - f.addRejectionF("max leechers not matcing. got: %d want %d", r.Leechers, f.MaxLeechers) + f.RejectReasons.Add("max leechers", r.Leechers, f.MaxLeechers) } } - if len(f.Rejections) > 0 { - return f.Rejections, false + if f.RejectReasons.Len() > 0 { + return f.RejectReasons, false } - return nil, true + return f.RejectReasons, true } func (f *Filter) checkMaxDownloads() bool { @@ -699,7 +709,7 @@ func (f *Filter) checkSizeFilter(r *Release) bool { sizeOK, err := f.CheckReleaseSize(r.Size) if err != nil { - f.addRejectionF("size: error checking release size against filter: %+v", err) + f.RejectReasons.Add("size: ERROR", fmt.Sprintf("error checking release size against filter: %v", err), f.MinSize) return false } @@ -736,35 +746,6 @@ func (f *Filter) IsPerfectFLAC(r *Release) ([]string, bool) { return rejections, len(rejections) == 0 } -func (f *Filter) addRejection(reason string) { - f.Rejections = append(f.Rejections, reason) -} - -func (f *Filter) AddRejectionF(format string, v ...interface{}) { - f.addRejectionF(format, v...) -} - -func (f *Filter) addRejectionF(format string, v ...interface{}) { - f.Rejections = append(f.Rejections, fmt.Sprintf(format, v...)) -} - -// ResetRejections reset rejections -func (f *Filter) resetRejections() { - f.Rejections = []string{} -} - -func (f *Filter) RejectionsString(trim bool) string { - if len(f.Rejections) > 0 { - out := strings.Join(f.Rejections, ", ") - if trim && len(out) > 1024 { - out = out[:1024] - } - - return out - } - return "" -} - func matchRegex(tag string, filterList string) bool { if tag == "" { return false @@ -1121,12 +1102,12 @@ func (f *Filter) CheckReleaseSize(releaseSize uint64) (bool, error) { } if minBytes != nil && releaseSize <= *minBytes { - f.addRejectionF("release size %d bytes smaller than filter min size %d bytes", releaseSize, *minBytes) + f.RejectReasons.Addf("release size", "release size %d bytes is smaller than filter min size %d bytes", releaseSize, *minBytes) return false, nil } if maxBytes != nil && releaseSize >= *maxBytes { - f.addRejectionF("release size %d bytes is larger than filter max size %d bytes", releaseSize, *maxBytes) + f.RejectReasons.Addf("release size", "release size %d bytes is larger than filter max size %d bytes", releaseSize, *maxBytes) return false, nil } diff --git a/internal/domain/filter_test.go b/internal/domain/filter_test.go index c0ad357..eda4004 100644 --- a/internal/domain/filter_test.go +++ b/internal/domain/filter_test.go @@ -11,8 +11,8 @@ import ( func TestFilter_CheckFilter(t *testing.T) { type args struct { - filter Filter - rejections []string + filter Filter + rejectionReasons *RejectionReasons } tests := []struct { name string @@ -52,6 +52,7 @@ func TestFilter_CheckFilter(t *testing.T) { Years: "2020", MatchReleaseGroups: "GROUP1", }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -77,6 +78,7 @@ func TestFilter_CheckFilter(t *testing.T) { Years: "2020", MatchReleaseGroups: "GROUP1", }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -101,6 +103,7 @@ func TestFilter_CheckFilter(t *testing.T) { Years: "2020", MatchReleaseGroups: "GROUP1", }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -126,6 +129,7 @@ func TestFilter_CheckFilter(t *testing.T) { MatchReleaseGroups: "GROUP1", Shows: "That Movie", }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -151,6 +155,7 @@ func TestFilter_CheckFilter(t *testing.T) { MatchReleaseGroups: "GROUP1", Shows: "That Movie", }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -176,6 +181,7 @@ func TestFilter_CheckFilter(t *testing.T) { MatchReleaseGroups: "GROUP1", Shows: "That Movie, good story, bad movie", }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -201,6 +207,7 @@ func TestFilter_CheckFilter(t *testing.T) { MatchReleaseGroups: "GROUP1", Shows: "That Movie, good story, bad movie", }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -226,6 +233,7 @@ func TestFilter_CheckFilter(t *testing.T) { MatchReleaseGroups: "GROUP1,BADGROUP", Shows: "*Movie*, good story, bad movie", }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -251,7 +259,7 @@ func TestFilter_CheckFilter(t *testing.T) { MatchReleaseGroups: "GROUP1,BADGROUP", Shows: "*Movie*, good story, bad movie", }, - rejections: []string{"category unwanted. got: Movies unwanted: *movies*"}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "except category", got: "Movies", want: "*movies*"}}}, }, want: false, }, @@ -277,7 +285,7 @@ func TestFilter_CheckFilter(t *testing.T) { MatchReleaseGroups: "GROUP1,BADGROUP", Shows: "*Movie*, good story, bad movie", }, - rejections: nil, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -303,7 +311,7 @@ func TestFilter_CheckFilter(t *testing.T) { MatchReleaseGroups: "GROUP1,BADGROUP", Shows: "*Movie*, good story, bad movie", }, - rejections: []string{"category not matching. got: Movies want: *tv*"}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "match category", got: "Movies", want: "*tv*"}}}, }, want: false, }, @@ -330,7 +338,7 @@ func TestFilter_CheckFilter(t *testing.T) { MatchReleaseGroups: "GROUP1,BADGROUP", Shows: "*Movie*, good story, bad movie", }, - rejections: []string{"category not matching. got: Movies/HD,2040 want: *tv*"}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "match category", got: "Movies/HD,2040", want: "*tv*"}}}, }, want: false, }, @@ -357,6 +365,7 @@ func TestFilter_CheckFilter(t *testing.T) { MatchReleaseGroups: "GROUP1,BADGROUP", Shows: "*Movie*, good story, bad movie", }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -383,6 +392,7 @@ func TestFilter_CheckFilter(t *testing.T) { MatchReleaseGroups: "GROUP1,BADGROUP", Shows: "*Movie*, good story, bad movie", }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -409,6 +419,7 @@ func TestFilter_CheckFilter(t *testing.T) { MatchReleaseGroups: "GROUP1,BADGROUP", Shows: "*Movie*, good story, bad movie", }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -429,6 +440,7 @@ func TestFilter_CheckFilter(t *testing.T) { Seasons: "1,2", Episodes: "1", }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -448,6 +460,7 @@ func TestFilter_CheckFilter(t *testing.T) { MatchReleaseGroups: "GROUP1,GROUP2", Seasons: "1,2", }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -467,7 +480,7 @@ func TestFilter_CheckFilter(t *testing.T) { MatchReleaseGroups: "GROUP1,GROUP2", Seasons: "1", }, - rejections: []string{"season not matching. got: 2 want: 1"}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "season", got: 2, want: "1"}}}, }, want: false, }, @@ -484,6 +497,7 @@ func TestFilter_CheckFilter(t *testing.T) { MatchCategories: "*tv*", MatchUploaders: "Uploader1", }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -500,7 +514,7 @@ func TestFilter_CheckFilter(t *testing.T) { MatchCategories: "*tv*", ExceptUploaders: "Anonymous", }, - rejections: []string{"unwanted uploaders. got: Anonymous unwanted: Anonymous"}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "except uploaders", got: "Anonymous", want: "Anonymous"}}}, }, want: false, }, @@ -519,6 +533,7 @@ func TestFilter_CheckFilter(t *testing.T) { ExceptUploaders: "Anonymous", Shows: "Good show", }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -540,6 +555,7 @@ func TestFilter_CheckFilter(t *testing.T) { Tags: "tv", TagsMatchLogic: "", }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -561,6 +577,7 @@ func TestFilter_CheckFilter(t *testing.T) { Tags: "tv", TagsMatchLogic: "ANY", }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -582,6 +599,7 @@ func TestFilter_CheckFilter(t *testing.T) { Tags: "tv,foreign", TagsMatchLogic: "ALL", }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -603,7 +621,7 @@ func TestFilter_CheckFilter(t *testing.T) { Tags: "tv", TagsMatchLogic: "ANY", }, - rejections: []string{"tags not matching. got: [foreign] want: tv"}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "match tags: ANY", got: []string{"foreign"}, want: "tv"}}}, }, want: false, }, @@ -625,7 +643,7 @@ func TestFilter_CheckFilter(t *testing.T) { Tags: "tv,foreign", TagsMatchLogic: "ALL", }, - rejections: []string{"tags not matching. got: [foreign] want(all): tv,foreign"}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "match tags: ALL", got: []string{"foreign"}, want: "tv,foreign"}}}, }, want: false, }, @@ -647,6 +665,7 @@ func TestFilter_CheckFilter(t *testing.T) { ExceptTags: "tv", TagsMatchLogic: "ANY", }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -668,7 +687,7 @@ func TestFilter_CheckFilter(t *testing.T) { ExceptTags: "tv,foreign", TagsMatchLogic: "ALL", }, - rejections: []string{"tags unwanted. got: [foreign] don't want: tv,foreign"}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "except tags: ANY", got: []string{"foreign"}, want: "tv,foreign"}}}, }, want: false, }, @@ -690,7 +709,7 @@ func TestFilter_CheckFilter(t *testing.T) { ExceptTags: "foreign", ExceptTagsMatchLogic: "ANY", }, - rejections: []string{"tags unwanted. got: [foreign] don't want: foreign"}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "except tags: ANY", got: []string{"foreign"}, want: "foreign"}}}, }, want: false, }, @@ -712,7 +731,7 @@ func TestFilter_CheckFilter(t *testing.T) { ExceptTags: "foreign,tv", ExceptTagsMatchLogic: "ALL", }, - rejections: []string{"tags unwanted. got: [tv foreign] don't want: foreign,tv"}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "except tags: ALL", got: []string{"tv", "foreign"}, want: "foreign,tv"}}}, }, want: false, }, @@ -732,6 +751,7 @@ func TestFilter_CheckFilter(t *testing.T) { Shows: "Good show", MatchReleaseGroups: "GROUP", }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -751,6 +771,7 @@ func TestFilter_CheckFilter(t *testing.T) { Shows: "Good show shift", MatchReleaseGroups: "ift", }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -770,7 +791,7 @@ func TestFilter_CheckFilter(t *testing.T) { Shows: "Good show shift", MatchReleaseGroups: "ift", }, - rejections: []string{"release groups not matching. got: GROUP want: ift"}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "match release groups", got: "GROUP", want: "ift"}}}, }, want: false, }, @@ -810,7 +831,7 @@ func TestFilter_CheckFilter(t *testing.T) { MatchReleaseGroups: "GROUP", ExceptReleases: "Good show shift", }, - rejections: []string{"except releases: unwanted release. got: Good show shift S02 NORDiC 2160p ATVP WEB-DL DDP 5.1 Atmos DV HEVC-GROUP want: Good show shift"}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "except releases", got: "Good show shift S02 NORDiC 2160p ATVP WEB-DL DDP 5.1 Atmos DV HEVC-GROUP", want: "Good show shift"}}}, }, want: false, }, @@ -831,7 +852,7 @@ func TestFilter_CheckFilter(t *testing.T) { MatchReleaseGroups: "GROUP", ExceptReleases: "NORDiC", }, - rejections: []string{"except releases: unwanted release. got: Good show shift S02 NORDiC 2160p ATVP WEB-DL DDP 5.1 Atmos DV HEVC-GROUP want: NORDiC"}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "except releases", got: "Good show shift S02 NORDiC 2160p ATVP WEB-DL DDP 5.1 Atmos DV HEVC-GROUP", want: "NORDiC"}}}, }, want: false, }, @@ -852,6 +873,7 @@ func TestFilter_CheckFilter(t *testing.T) { MatchReleaseGroups: "GROUP", ExceptReleases: "NORDiC", }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -872,7 +894,7 @@ func TestFilter_CheckFilter(t *testing.T) { MatchReleaseGroups: "GROUP", ExceptReleases: "NORDiC,*shift*", }, - rejections: []string{"except releases: unwanted release. got: Good show shift S02 2160p ATVP WEB-DL DDP 5.1 Atmos DV HEVC-GROUP want: NORDiC,*shift*"}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "except releases", got: "Good show shift S02 2160p ATVP WEB-DL DDP 5.1 Atmos DV HEVC-GROUP", want: "NORDiC,*shift*"}}}, }, want: false, }, @@ -894,6 +916,7 @@ func TestFilter_CheckFilter(t *testing.T) { ExceptReleases: "NORDiC", MatchHDR: []string{"DV", "HDR"}, }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -915,6 +938,7 @@ func TestFilter_CheckFilter(t *testing.T) { ExceptReleases: "NORDiC", MatchHDR: []string{"DV", "HDR"}, }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -936,7 +960,7 @@ func TestFilter_CheckFilter(t *testing.T) { ExceptReleases: "NORDiC", ExceptHDR: []string{"DV", "HDR", "DoVi"}, }, - rejections: []string{"hdr unwanted. got: [DV] want: [DV HDR DoVi]"}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "except hdr", got: []string{"DV"}, want: []string{"DV", "HDR", "DoVi"}}}}, }, want: false, }, @@ -958,7 +982,7 @@ func TestFilter_CheckFilter(t *testing.T) { ExceptReleases: "NORDiC", MatchHDR: []string{"DV", "HDR", "DoVi"}, }, - rejections: []string{"hdr not matching. got: [] want: [DV HDR DoVi]"}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "match hdr", got: []string(nil), want: []string{"DV", "HDR", "DoVi"}}}}, }, want: false, }, @@ -980,6 +1004,7 @@ func TestFilter_CheckFilter(t *testing.T) { ExceptReleases: "NORDiC", ExceptHDR: []string{"DV", "HDR", "DoVi"}, }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -1001,6 +1026,7 @@ func TestFilter_CheckFilter(t *testing.T) { ExceptReleases: "NORDiC", ExceptHDR: []string{"DV", "DoVi"}, }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -1022,6 +1048,7 @@ func TestFilter_CheckFilter(t *testing.T) { ExceptReleases: "NORDiC", ExceptHDR: []string{"DV", "DoVi"}, }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -1043,6 +1070,7 @@ func TestFilter_CheckFilter(t *testing.T) { ExceptReleases: "NORDiC", MatchHDR: []string{"DV", "DoVi", "HDR10+"}, }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -1056,6 +1084,7 @@ func TestFilter_CheckFilter(t *testing.T) { Enabled: true, MatchHDR: []string{"DV HDR"}, }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -1069,7 +1098,7 @@ func TestFilter_CheckFilter(t *testing.T) { Enabled: true, MatchHDR: []string{"DV HDR"}, }, - rejections: []string{"hdr not matching. got: [DV HDR10] want: [DV HDR]"}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "match hdr", got: []string{"DV", "HDR10"}, want: []string{"DV HDR"}}}}, }, want: false, }, @@ -1083,7 +1112,7 @@ func TestFilter_CheckFilter(t *testing.T) { Enabled: true, MatchHDR: []string{"DV", "HDR"}, }, - rejections: []string{"hdr not matching. got: [HDR10] want: [DV HDR]"}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "match hdr", got: []string{"HDR10"}, want: []string{"DV", "HDR"}}}}, }, want: false, }, @@ -1106,6 +1135,7 @@ func TestFilter_CheckFilter(t *testing.T) { Cue: true, //LogScore: 100, }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -1123,7 +1153,7 @@ func TestFilter_CheckFilter(t *testing.T) { Artists: "Artist", PerfectFlac: true, }, - rejections: []string{"wanted: perfect flac. got: [320 MP3]"}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "perfect flac", got: []string{"320", "MP3"}, want: "Cue, Log, Log Score 100, FLAC and 24bit Lossless"}}}, }, want: false, }, @@ -1141,7 +1171,7 @@ func TestFilter_CheckFilter(t *testing.T) { Artists: "Artist", PerfectFlac: true, }, - rejections: []string{"wanted: perfect flac. got: [FLAC Lossless Log100 Log]"}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "perfect flac", got: []string{"FLAC", "Lossless", "Log100", "Log"}, want: "Cue, Log, Log Score 100, FLAC and 24bit Lossless"}}}, }, want: false, }, @@ -1165,7 +1195,7 @@ func TestFilter_CheckFilter(t *testing.T) { LogScore: 100, Cue: true, }, - rejections: []string{"quality not matching. got: [FLAC Lossless Log100 Log] want: [24bit Lossless]", "wanted: cue"}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "quality", got: []string{"FLAC", "Lossless", "Log100", "Log"}, want: []string{"24bit Lossless"}}, {key: "cue", got: []string{"FLAC", "Lossless", "Log100", "Log"}, want: "Cue"}}}, }, want: false, }, @@ -1193,6 +1223,7 @@ func TestFilter_CheckFilter(t *testing.T) { Cue: true, //Cue: true, }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -1216,7 +1247,7 @@ func TestFilter_CheckFilter(t *testing.T) { LogScore: 100, Cue: true, }, - rejections: []string{"release type not matching. got: Album want: [Single]"}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "release type", got: "Album", want: []string{"Single"}}}}, }, want: false, }, @@ -1240,7 +1271,7 @@ func TestFilter_CheckFilter(t *testing.T) { LogScore: 100, Cue: true, }, - rejections: []string{"artists not matching. got: Artist want: Artiiiist"}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "artists", got: "Artist", want: "Artiiiist"}}}, }, want: false, }, @@ -1265,6 +1296,7 @@ func TestFilter_CheckFilter(t *testing.T) { //LogScore: 100, Cue: true, }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -1286,7 +1318,7 @@ func TestFilter_CheckFilter(t *testing.T) { Formats: []string{"FLAC"}, Quality: []string{"Lossless"}, }, - rejections: []string{"quality not matching. got: [24BIT Lossless Cue FLAC Log100 Log] want: [Lossless]"}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "quality", got: []string{"24BIT Lossless", "Cue", "FLAC", "Log100", "Log"}, want: []string{"Lossless"}}}}, }, want: false, }, @@ -1301,6 +1333,7 @@ func TestFilter_CheckFilter(t *testing.T) { Enabled: true, Freeleech: true, }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -1315,7 +1348,7 @@ func TestFilter_CheckFilter(t *testing.T) { Enabled: true, Freeleech: true, }, - rejections: []string{"wanted: freeleech"}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "freeleech", got: false, want: true}}}, }, want: false, }, @@ -1337,6 +1370,7 @@ func TestFilter_CheckFilter(t *testing.T) { MatchCategories: "Light Novel", MatchReleaseTags: "*EPUB*", }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -1356,6 +1390,7 @@ func TestFilter_CheckFilter(t *testing.T) { Months: "04", Days: "20", }, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, }, want: true, }, @@ -1370,11 +1405,11 @@ func TestFilter_CheckFilter(t *testing.T) { filter: Filter{ Enabled: true, MatchCategories: "*tv*", - Shows: "Daily talk show", + Shows: "Daaaaaily talk show", Years: "2022", - Months: "05", + //Months: "05", }, - rejections: []string{"month not matching. got: 4 want: 05"}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "shows", got: "Daily talk show", want: "Daaaaaily talk show"}}}, }, want: false, }, @@ -1387,7 +1422,7 @@ func TestFilter_CheckFilter(t *testing.T) { rejections, got := tt.args.filter.CheckFilter(r) assert.Equal(t, tt.want, got) - assert.Equal(t, tt.args.rejections, rejections) + assert.Equal(t, tt.args.rejectionReasons, rejections) }) } } @@ -1398,11 +1433,11 @@ func TestFilter_CheckFilter1(t *testing.T) { r *Release } tests := []struct { - name string - fields fields - args args - wantRejections []string - wantMatch bool + name string + fields fields + args args + rejectionReasons *RejectionReasons + wantMatch bool }{ { name: "test_1", @@ -1415,9 +1450,9 @@ func TestFilter_CheckFilter1(t *testing.T) { MatchReleaseGroups: "NOSiViD", MatchHDR: []string{"DV", "HDR"}, }, - args: args{&Release{TorrentName: "WeCrashed.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-NOSiViD"}}, - wantRejections: nil, - wantMatch: true, + args: args{&Release{TorrentName: "WeCrashed.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-NOSiViD"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, + wantMatch: true, }, { name: "test_2", @@ -1430,9 +1465,9 @@ func TestFilter_CheckFilter1(t *testing.T) { Codecs: []string{"x265"}, MatchReleaseGroups: "NOSiViD", }, - args: args{&Release{TorrentName: "WeCrashed.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-NOSiViD"}}, - wantRejections: []string{"episodes not matching. got: 0 want: 2-8"}, - wantMatch: false, + args: args{&Release{TorrentName: "WeCrashed.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-NOSiViD"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "episodes", got: 0, want: "2-8"}}}, + wantMatch: false, }, { name: "test_3", @@ -1445,9 +1480,9 @@ func TestFilter_CheckFilter1(t *testing.T) { MatchReleaseGroups: "NOSiViD", MatchHDR: []string{"HDR"}, }, - args: args{&Release{TorrentName: "WeCrashed.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-NOSiViD"}}, - wantRejections: []string{"hdr not matching. got: [DV] want: [HDR]"}, - wantMatch: false, + args: args{&Release{TorrentName: "WeCrashed.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-NOSiViD"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "match hdr", got: []string{"DV"}, want: []string{"HDR"}}}}, + wantMatch: false, }, { name: "test_4", @@ -1460,9 +1495,9 @@ func TestFilter_CheckFilter1(t *testing.T) { MatchReleaseGroups: "NOSiViD", ExceptHDR: []string{"DV", "HDR"}, }, - args: args{&Release{TorrentName: "WeCrashed.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-NOSiViD"}}, - wantRejections: []string{"hdr unwanted. got: [DV] want: [DV HDR]"}, - wantMatch: false, + args: args{&Release{TorrentName: "WeCrashed.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-NOSiViD"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "except hdr", got: []string{"DV"}, want: []string{"DV", "HDR"}}}}, + wantMatch: false, }, { name: "test_5", @@ -1475,9 +1510,9 @@ func TestFilter_CheckFilter1(t *testing.T) { MatchReleaseGroups: "NOSiViD", ExceptHDR: []string{"DV", "HDR"}, }, - args: args{&Release{TorrentName: "WeCrashed.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-NOSiViD"}}, - wantRejections: []string{"shows not matching. got: WeCrashed want: WeWork", "hdr unwanted. got: [DV] want: [DV HDR]"}, - wantMatch: false, + args: args{&Release{TorrentName: "WeCrashed.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-NOSiViD"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "shows", got: "WeCrashed", want: "WeWork"}, {key: "except hdr", got: []string{"DV"}, want: []string{"DV", "HDR"}}}}, + wantMatch: false, }, { name: "test_6", @@ -1490,9 +1525,9 @@ func TestFilter_CheckFilter1(t *testing.T) { ExceptReleaseGroups: "NOSiViD", ExceptHDR: []string{"DV", "HDR"}, }, - args: args{&Release{TorrentName: "WeCrashed.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-NOSiViD"}}, - wantRejections: []string{"shows not matching. got: WeCrashed want: WeWork", "unwanted release group. got: NOSiViD unwanted: NOSiViD", "hdr unwanted. got: [DV] want: [DV HDR]"}, - wantMatch: false, + args: args{&Release{TorrentName: "WeCrashed.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-NOSiViD"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "shows", got: "WeCrashed", want: "WeWork"}, {key: "except release groups", got: "NOSiViD", want: "NOSiViD"}, {key: "except hdr", got: []string{"DV"}, want: []string{"DV", "HDR"}}}}, + wantMatch: false, }, { name: "test_7", @@ -1505,9 +1540,9 @@ func TestFilter_CheckFilter1(t *testing.T) { ExceptReleaseGroups: "NOSiViD", ExceptHDR: []string{"DV", "HDR"}, }, - args: args{&Release{TorrentName: "WeCrashed.S01.DV.2160p.ATVP.WEB.DDPA5.1.x265-NOSiViD"}}, - wantRejections: []string{"shows not matching. got: WeCrashed want: WeWork", "unwanted release group. got: NOSiViD unwanted: NOSiViD", "source not matching. got: WEB want: [WEB-DL]", "hdr unwanted. got: [DV] want: [DV HDR]"}, - wantMatch: false, + args: args{&Release{TorrentName: "WeCrashed.S01.DV.2160p.ATVP.WEB.DDPA5.1.x265-NOSiViD"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "shows", got: "WeCrashed", want: "WeWork"}, {key: "except release groups", got: "NOSiViD", want: "NOSiViD"}, {key: "source", got: "WEB", want: []string{"WEB-DL"}}, {key: "except hdr", got: []string{"DV"}, want: []string{"DV", "HDR"}}}}, + wantMatch: false, }, { name: "test_8", @@ -1520,9 +1555,9 @@ func TestFilter_CheckFilter1(t *testing.T) { MatchReleaseGroups: "NOSiViD", MatchHDR: []string{"DV", "HDR"}, }, - args: args{&Release{TorrentName: "WeCrashed.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-NOSiViD"}}, - wantRejections: []string{"source not matching. got: WEB-DL want: [WEB]"}, - wantMatch: false, + args: args{&Release{TorrentName: "WeCrashed.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-NOSiViD"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "source", got: "WEB-DL", want: []string{"WEB"}}}}, + wantMatch: false, }, { name: "test_9", @@ -1535,9 +1570,9 @@ func TestFilter_CheckFilter1(t *testing.T) { MatchReleaseGroups: "NOSiViD", MatchHDR: []string{"DV", "HDR"}, }, - args: args{&Release{TorrentName: "WeCrashed.S01.DV.2160p.Blu-ray.DDPA5.1.x265-NOSiViD"}}, - wantRejections: []string{"source not matching. got: BluRay want: [WEB]"}, - wantMatch: false, + args: args{&Release{TorrentName: "WeCrashed.S01.DV.2160p.Blu-ray.DDPA5.1.x265-NOSiViD"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "source", got: "BluRay", want: []string{"WEB"}}}}, + wantMatch: false, }, { name: "test_10", @@ -1548,9 +1583,9 @@ func TestFilter_CheckFilter1(t *testing.T) { MatchHDR: []string{"DV", "HDR"}, ExceptOther: []string{"REMUX", "HYBRID"}, }, - args: args{&Release{TorrentName: "Stranger Things S02 UHD BluRay 2160p DTS-HD MA 5.1 DV HEVC HYBRID REMUX-FraMeSToR"}}, - wantRejections: []string{"source not matching. got: UHD.BluRay want: [BluRay]", "except other unwanted. got: [HYBRiD REMUX] unwanted: [REMUX HYBRID]"}, - wantMatch: false, + args: args{&Release{TorrentName: "Stranger Things S02 UHD BluRay 2160p DTS-HD MA 5.1 DV HEVC HYBRID REMUX-FraMeSToR"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "source", got: "UHD.BluRay", want: []string{"BluRay"}}, {key: "except other", got: []string{"HYBRiD", "REMUX"}, want: []string{"REMUX", "HYBRID"}}}}, + wantMatch: false, }, { name: "test_10", @@ -1561,9 +1596,9 @@ func TestFilter_CheckFilter1(t *testing.T) { MatchHDR: []string{"DV", "HDR"}, MatchOther: []string{"REMUX", "HYBRID"}, }, - args: args{&Release{TorrentName: "Stranger Things S02 UHD BluRay 2160p DTS-HD MA 5.1 DV HEVC HYBRID REMUX-FraMeSToR"}}, - wantRejections: nil, - wantMatch: true, + args: args{&Release{TorrentName: "Stranger Things S02 UHD BluRay 2160p DTS-HD MA 5.1 DV HEVC HYBRID REMUX-FraMeSToR"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, + wantMatch: true, }, { name: "test_11", @@ -1573,9 +1608,9 @@ func TestFilter_CheckFilter1(t *testing.T) { Codecs: []string{"HEVC"}, //MatchHDR: []string{"DV", "HDR"}, }, - args: args{&Release{TorrentName: "Food Wars!: Shokugeki no Soma S05 2020 1080p BluRay HEVC 10-Bit DD2.0 Dual Audio -ZR-"}}, - wantRejections: nil, - wantMatch: true, + args: args{&Release{TorrentName: "Food Wars!: Shokugeki no Soma S05 2020 1080p BluRay HEVC 10-Bit DD2.0 Dual Audio -ZR-"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, + wantMatch: true, }, { name: "test_12", @@ -1583,9 +1618,9 @@ func TestFilter_CheckFilter1(t *testing.T) { Resolutions: []string{"2160p"}, Codecs: []string{"h.265"}, }, - args: args{&Release{TorrentName: "The.First.Lady.S01E01.DV.2160p.WEB-DL.DD5.1.H265-GLHF"}}, - wantRejections: nil, - wantMatch: true, + args: args{&Release{TorrentName: "The.First.Lady.S01E01.DV.2160p.WEB-DL.DD5.1.H265-GLHF"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, + wantMatch: true, }, { @@ -1594,36 +1629,36 @@ func TestFilter_CheckFilter1(t *testing.T) { Resolutions: []string{"2160p"}, Codecs: []string{"h.265"}, }, - args: args{&Release{TorrentName: "The First Lady S01E01 DV 2160p WEB-DL DD5.1 H 265-GLHF"}}, - wantRejections: nil, - wantMatch: true, + args: args{&Release{TorrentName: "The First Lady S01E01 DV 2160p WEB-DL DD5.1 H 265-GLHF"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, + wantMatch: true, }, { name: "test_14", fields: fields{ Sources: []string{"WEBRip"}, }, - args: args{&Release{TorrentName: "Halt and Catch Fire S04 1080p WEBRip x265-HiQVE"}}, - wantRejections: nil, - wantMatch: true, + args: args{&Release{TorrentName: "Halt and Catch Fire S04 1080p WEBRip x265-HiQVE"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, + wantMatch: true, }, { name: "test_15", fields: fields{ Sources: []string{"WEB"}, }, - args: args{&Release{TorrentName: "Dominik Walter-Cocktail Girl-(NS1083)-WEB-2022-AFO"}}, - wantRejections: nil, - wantMatch: true, + args: args{&Release{TorrentName: "Dominik Walter-Cocktail Girl-(NS1083)-WEB-2022-AFO"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, + wantMatch: true, }, { name: "test_16", fields: fields{ Sources: []string{"ViNYL"}, }, - args: args{&Release{TorrentName: "Love Unlimited - Under the Influence of Love Unlimited [1973] [Album] - MP3 / V0 (VBR) / Vinyl"}}, - wantRejections: nil, - wantMatch: true, + args: args{&Release{TorrentName: "Love Unlimited - Under the Influence of Love Unlimited [1973] [Album] - MP3 / V0 (VBR) / Vinyl"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, + wantMatch: true, }, { name: "test_17", @@ -1631,18 +1666,18 @@ func TestFilter_CheckFilter1(t *testing.T) { Resolutions: []string{"1080p"}, Sources: []string{"BluRay"}, }, - args: args{&Release{TorrentName: "A Movie [2015] - GROUP", ReleaseTags: "Type: Movie / 1080p / Encode / Freeleech: 100 Size: 7.00GB"}}, - wantRejections: []string{"source not matching. got: want: [BluRay]"}, - wantMatch: false, + args: args{&Release{TorrentName: "A Movie [2015] - GROUP", ReleaseTags: "Type: Movie / 1080p / Encode / Freeleech: 100 Size: 7.00GB"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "source", got: "", want: []string{"BluRay"}}}}, + wantMatch: false, }, { name: "test_18", fields: fields{ Resolutions: []string{"2160p"}, }, - args: args{&Release{TorrentName: "The Green Mile [1999] - playBD", ReleaseTags: "Type: Movie / 2160p / Remux / Freeleech: 100 Size: 72.78GB"}}, - wantRejections: nil, - wantMatch: true, + args: args{&Release{TorrentName: "The Green Mile [1999] - playBD", ReleaseTags: "Type: Movie / 2160p / Remux / Freeleech: 100 Size: 72.78GB"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, + wantMatch: true, }, { name: "test_19", @@ -1654,9 +1689,9 @@ func TestFilter_CheckFilter1(t *testing.T) { Sources: []string{"WEB-DL"}, Codecs: []string{"x265"}, }, - args: args{&Release{TorrentName: "Preacher.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-NOSiViD"}}, - wantRejections: []string{"shows not matching. got: Preacher want: Reacher"}, - wantMatch: false, + args: args{&Release{TorrentName: "Preacher.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-NOSiViD"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "shows", got: "Preacher", want: "Reacher"}}}, + wantMatch: false, }, { name: "test_20", @@ -1665,9 +1700,9 @@ func TestFilter_CheckFilter1(t *testing.T) { Resolutions: []string{"1080p"}, Sources: []string{"WEB-DL", "WEB"}, }, - args: args{&Release{TorrentName: "NBA.2022.04.19.Atlanta.Hawks.vs.Miami.Heat.1080p.WEB.H264-SPLASH"}}, - wantRejections: []string{"shows not matching. got: NBA want: Atlanta"}, - wantMatch: false, + args: args{&Release{TorrentName: "NBA.2022.04.19.Atlanta.Hawks.vs.Miami.Heat.1080p.WEB.H264-SPLASH"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "shows", got: "NBA", want: "Atlanta"}}}, + wantMatch: false, }, { name: "test_21", @@ -1679,63 +1714,63 @@ func TestFilter_CheckFilter1(t *testing.T) { //LogScore: 100, Cue: true, }, - args: args{&Release{TorrentName: "Gillan - Future Shock", ReleaseTags: "FLAC / Lossless / Log / 100% / Cue / CD / Scene"}}, - wantRejections: nil, - wantMatch: true, + args: args{&Release{TorrentName: "Gillan - Future Shock", ReleaseTags: "FLAC / Lossless / Log / 100% / Cue / CD / Scene"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, + wantMatch: true, }, { name: "test_22", fields: fields{ PerfectFlac: true, }, - args: args{&Release{TorrentName: "Gillan - Future Shock", ReleaseTags: "FLAC / Lossless / Log / 100% / Cue / CD / Scene"}}, - wantRejections: nil, - wantMatch: true, + args: args{&Release{TorrentName: "Gillan - Future Shock", ReleaseTags: "FLAC / Lossless / Log / 100% / Cue / CD / Scene"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, + wantMatch: true, }, { name: "test_23", fields: fields{ Origins: []string{"Internal"}, }, - args: args{&Release{TorrentName: "Gillan - Future Shock", ReleaseTags: "FLAC / Lossless / Log / 100% / Cue / CD / Scene", Origin: "Internal"}}, - wantRejections: nil, - wantMatch: true, + args: args{&Release{TorrentName: "Gillan - Future Shock", ReleaseTags: "FLAC / Lossless / Log / 100% / Cue / CD / Scene", Origin: "Internal"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, + wantMatch: true, }, { name: "test_24", fields: fields{ Origins: []string{"P2P"}, }, - args: args{&Release{TorrentName: "Gillan - Future Shock", ReleaseTags: "FLAC / Lossless / Log / 100% / Cue / CD / Scene", Origin: "Internal"}}, - wantRejections: []string{"origin not matching. got: Internal want: [P2P]"}, - wantMatch: false, + args: args{&Release{TorrentName: "Gillan - Future Shock", ReleaseTags: "FLAC / Lossless / Log / 100% / Cue / CD / Scene", Origin: "Internal"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "match origin", got: "Internal", want: []string{"P2P"}}}}, + wantMatch: false, }, { name: "test_25", fields: fields{ Origins: []string{"O-SCENE"}, }, - args: args{&Release{TorrentName: "Gillan - Future Shock", ReleaseTags: "FLAC / Lossless / Log / 100% / Cue / CD / Scene", Origin: "SCENE"}}, - wantRejections: []string{"origin not matching. got: SCENE want: [O-SCENE]"}, - wantMatch: false, + args: args{&Release{TorrentName: "Gillan - Future Shock", ReleaseTags: "FLAC / Lossless / Log / 100% / Cue / CD / Scene", Origin: "SCENE"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "match origin", got: "SCENE", want: []string{"O-SCENE"}}}}, + wantMatch: false, }, { name: "test_26", fields: fields{ Origins: []string{"SCENE"}, }, - args: args{&Release{TorrentName: "Gillan - Future Shock", ReleaseTags: "FLAC / Lossless / Log / 100% / Cue / CD / Scene", Origin: "O-SCENE"}}, - wantRejections: []string{"origin not matching. got: O-SCENE want: [SCENE]"}, - wantMatch: false, + args: args{&Release{TorrentName: "Gillan - Future Shock", ReleaseTags: "FLAC / Lossless / Log / 100% / Cue / CD / Scene", Origin: "O-SCENE"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "match origin", got: "O-SCENE", want: []string{"SCENE"}}}}, + wantMatch: false, }, { name: "test_26", fields: fields{ Origins: []string{"SCENE"}, }, - args: args{&Release{TorrentName: "Gillan - Future Shock", ReleaseTags: "FLAC / Lossless / Log / 100% / Cue / CD / Scene"}}, - wantRejections: nil, - wantMatch: true, + args: args{&Release{TorrentName: "Gillan - Future Shock", ReleaseTags: "FLAC / Lossless / Log / 100% / Cue / CD / Scene"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, + wantMatch: true, }, { name: "test_27", @@ -1743,9 +1778,9 @@ func TestFilter_CheckFilter1(t *testing.T) { 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, + args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "match releases: REGEX", got: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2", want: ".*1080p.+(group1|group3)"}}}, + wantMatch: false, }, { name: "test_28", @@ -1753,9 +1788,9 @@ func TestFilter_CheckFilter1(t *testing.T) { 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, + args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, + wantMatch: true, }, { name: "test_29", @@ -1763,9 +1798,9 @@ func TestFilter_CheckFilter1(t *testing.T) { 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, + args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "match releases: REGEX", got: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2", want: "*2160p*"}}}, + wantMatch: false, }, { name: "test_30", @@ -1773,9 +1808,9 @@ func TestFilter_CheckFilter1(t *testing.T) { UseRegex: true, MatchReleases: "2160p", }, - args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2"}}, - wantRejections: nil, - wantMatch: true, + args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, + wantMatch: true, }, { name: "test_31", @@ -1783,9 +1818,9 @@ func TestFilter_CheckFilter1(t *testing.T) { UseRegex: false, MatchReleases: "*2160p*", }, - args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2"}}, - wantRejections: nil, - wantMatch: true, + args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, + wantMatch: true, }, { name: "test_32", @@ -1796,9 +1831,9 @@ func TestFilter_CheckFilter1(t *testing.T) { MonthCount: 0, }, }, - args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2"}}, - wantRejections: nil, - wantMatch: true, + args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, + wantMatch: true, }, { name: "test_33", @@ -1806,12 +1841,13 @@ func TestFilter_CheckFilter1(t *testing.T) { MaxDownloads: 10, MaxDownloadsUnit: FilterMaxDownloadsMonth, Downloads: &FilterDownloads{ + TotalCount: 10, MonthCount: 10, }, }, - args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2"}}, - wantRejections: []string{"max downloads (10) this (MONTH) reached"}, - wantMatch: false, + args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "max downloads", got: "Hour: 0, Day: 0, Week: 0, Month: 10, Total: 10", want: "reached 10 per MONTH", format: "[max downloads] reached 10 per MONTH"}}}, + wantMatch: false, }, { name: "test_34", @@ -1819,12 +1855,13 @@ func TestFilter_CheckFilter1(t *testing.T) { MaxDownloads: 10, MaxDownloadsUnit: FilterMaxDownloadsMonth, Downloads: &FilterDownloads{ + TotalCount: 50, MonthCount: 50, }, }, - args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2"}}, - wantRejections: []string{"max downloads (10) this (MONTH) reached"}, - wantMatch: false, + args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "max downloads", got: "Hour: 0, Day: 0, Week: 0, Month: 50, Total: 50", want: "reached 10 per MONTH", format: "[max downloads] reached 10 per MONTH"}}}, + wantMatch: false, }, { name: "test_35", @@ -1832,13 +1869,16 @@ func TestFilter_CheckFilter1(t *testing.T) { MaxDownloads: 15, MaxDownloadsUnit: FilterMaxDownloadsHour, Downloads: &FilterDownloads{ - HourCount: 20, + TotalCount: 50, MonthCount: 50, + WeekCount: 50, + DayCount: 25, + HourCount: 20, }, }, - args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2"}}, - wantRejections: []string{"max downloads (15) this (HOUR) reached"}, - wantMatch: false, + args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "max downloads", got: "Hour: 20, Day: 25, Week: 50, Month: 50, Total: 50", want: "reached 15 per HOUR", format: "[max downloads] reached 15 per HOUR"}}}, + wantMatch: false, }, { name: "test_36", @@ -1850,27 +1890,27 @@ func TestFilter_CheckFilter1(t *testing.T) { MonthCount: 50, }, }, - args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2"}}, - wantRejections: nil, - wantMatch: true, + args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, + wantMatch: true, }, { name: "test_37", fields: fields{ ExceptOrigins: []string{"Internal"}, }, - args: args{&Release{TorrentName: "Gillan - Future Shock", Origin: "Internal"}}, - wantRejections: []string{"except origin not matching. got: Internal unwanted: [Internal]"}, - wantMatch: false, + args: args{&Release{TorrentName: "Gillan - Future Shock", Origin: "Internal"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "except origin", got: "Internal", want: []string{"Internal"}}}}, + wantMatch: false, }, { name: "test_38", fields: fields{ ExceptOrigins: []string{"Internal"}, }, - args: args{&Release{TorrentName: "Gillan - Future Shock", Origin: "Scene"}}, - wantRejections: nil, - wantMatch: true, + args: args{&Release{TorrentName: "Gillan - Future Shock", Origin: "Scene"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, + wantMatch: true, }, { name: "test_39", @@ -1878,9 +1918,9 @@ func TestFilter_CheckFilter1(t *testing.T) { UseRegexReleaseTags: true, MatchReleaseTags: ".*1080p.+(group1|group3)", }, - args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2", ReleaseTags: "MKV | x264 | WEB | P2P"}}, - wantRejections: []string{"match release tags regex not matching. got: MKV | x264 | WEB | P2P want: .*1080p.+(group1|group3)"}, - wantMatch: false, + args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2", ReleaseTags: "MKV | x264 | WEB | P2P"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "match release tags: REGEX", got: "MKV | x264 | WEB | P2P", want: ".*1080p.+(group1|group3)"}}}, + wantMatch: false, }, { name: "test_40", @@ -1888,9 +1928,9 @@ func TestFilter_CheckFilter1(t *testing.T) { UseRegexReleaseTags: true, MatchReleaseTags: "foreign - 16", }, - args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2", ReleaseTags: "MKV | x264 | WEB | P2P | Foreign - 17"}}, - wantRejections: []string{"match release tags regex not matching. got: MKV | x264 | WEB | P2P | Foreign - 17 want: foreign - 16"}, - wantMatch: false, + args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2", ReleaseTags: "MKV | x264 | WEB | P2P | Foreign - 17"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "match release tags: REGEX", got: "MKV | x264 | WEB | P2P | Foreign - 17", want: "foreign - 16"}}}, + wantMatch: false, }, { name: "test_41", @@ -1898,8 +1938,9 @@ func TestFilter_CheckFilter1(t *testing.T) { UseRegexReleaseTags: true, MatchReleaseTags: "foreign - 17", }, - args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2", ReleaseTags: "MKV | x264 | WEB | P2P | Foreign - 17"}}, - wantMatch: true, + args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2", ReleaseTags: "MKV | x264 | WEB | P2P | Foreign - 17"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, + wantMatch: true, }, { name: "test_42", @@ -1907,9 +1948,9 @@ func TestFilter_CheckFilter1(t *testing.T) { UseRegexReleaseTags: true, MatchReleaseTags: "foreign - 17", }, - args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2", ReleaseTags: ""}}, - wantRejections: []string{"match release tags regex not matching. got: want: foreign - 17"}, - wantMatch: false, + args: args{&Release{TorrentName: "Show.Name.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-GROUP2", ReleaseTags: ""}}, + rejectionReasons: &RejectionReasons{data: []Rejection{{key: "match release tags: REGEX", got: "", want: "foreign - 17"}}}, + wantMatch: false, }, { name: "test_43", @@ -1921,9 +1962,9 @@ func TestFilter_CheckFilter1(t *testing.T) { Sources: []string{"WEB-DL"}, Codecs: []string{"x265"}, }, - args: args{&Release{TorrentName: "Preacher.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-NOSiViD"}}, - wantRejections: nil, - wantMatch: true, + args: args{&Release{TorrentName: "Preacher.S01.DV.2160p.ATVP.WEB-DL.DDPA5.1.x265-NOSiViD"}}, + rejectionReasons: &RejectionReasons{data: []Rejection{}}, + wantMatch: true, }, } for _, tt := range tests { @@ -1994,7 +2035,7 @@ func TestFilter_CheckFilter1(t *testing.T) { f.Sanitize() tt.args.r.ParseString(tt.args.r.TorrentName) rejections, match := f.CheckFilter(tt.args.r) - assert.Equalf(t, tt.wantRejections, rejections, "CheckFilter(%v)", tt.args.r) + assert.Equalf(t, tt.rejectionReasons, rejections, "CheckFilter(%v)", tt.args.r) assert.Equalf(t, tt.wantMatch, match, "CheckFilter(%v)", tt.args.r) }) } @@ -2258,8 +2299,8 @@ func Test_checkSizeFilter(t *testing.T) { {name: "test_9", filter: Filter{MinSize: "unparseable", MaxSize: "20GB"}, releaseSize: 2500000000, want: false, wantErr: "could not parse filter min size: strconv.ParseFloat: parsing \"\": invalid syntax"}, } for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { + tt.filter.RejectReasons = NewRejectionReasons() got, err := tt.filter.CheckReleaseSize(tt.releaseSize) if tt.wantErr != "" && assert.Error(t, err) { assert.EqualErrorf(t, err, tt.wantErr, "Error should be: %v, got: %v", tt.wantErr, err) @@ -2268,3 +2309,30 @@ func Test_checkSizeFilter(t *testing.T) { }) } } + +func Test_containsFuzzy(t *testing.T) { + type args struct { + tag string + filter string + } + tests := []struct { + name string + args args + want bool + }{ + {name: "", args: args{tag: "this is a long text that should contain some random data one of them being black metal which should be in the middle of everything.", filter: "*black?metal*"}, want: true}, + { + name: "", + args: args{ + tag: "Kategori: Music \\n Storlek: 132.78 MiB\\n ? ?? ?? ????????? ?? ?? ?? ?? ?? ???? ?? ?? ?? ???? ??? ? ?? ?? ?? ? ??? ? ? ?? ? ?? ? ??? ? ?? ?? ??? ?? ?? ???? ???? ?? ???? ????? ????? ? ?? ?? ???? ?? ???? ?? ?? ? ?????? ????????????? ???????????? ????????????? ?????? ???? ?????? ? ?? ??? ? ?? ? ?? ?? ??? ?? ? ? ?????? ?? ?? ?? ?? ?? ????? ? ?? ?? ?? ?? ?? ????????? ? ?????? ?? ????????? ??? ? ?????? ? ?? ? ?? ?? ??? ? ? ? ?? ?? ? ??? ? ?? ? ? ?? ????? ? ?? ? ? ?? ?? ??? ??? ??? ?? ??? ?? ??? ??? ? ????????? ???? ?? ????? ? ?? ????????????? ??????????? ??? ???? ??? ?? ?????????? ?? ?? ??? ?? ??? ??? ???? ??? ? ?? ??? ? ?? ?????????? ?? ??????????????? ????????????? ???? ???? ????? ??? ??????? ???????? ????? ???????? ????? ????? ?? ??? ??? ? ? ???? ???? ???? ???? ???? ???? ???? ?? ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?? ?? ??? ??? ?? ??? ??? ??? ??? ??? ???????? ? ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?????? ??? ??? ???? ??? ? ??? ??? ??? ??? ? ??? ???? ? ? ??? ???? ???? ?? ?? ?? ?? ?? ?? ?? ??????? ???? ???? ? ?? ? ? ? ? ? ? ?????? ??????? ????? ?? ? ? ? ? ? ? ?? ?????? ????? ?? ? ? ? ? ? ? sM!iMPURE ??? ???? ? ? ? ? ? ? ./\\\\\\\\//\\\\\\\\. ???? ?? ? ? ? ?? ? ? ? ? ?????????????????????????????????????? ?????????????????? ?????????????????? ??? ?? ?? ??? ??? RELEASE INFORMATION for: ??? ?? Portae_Obscuritas-Sapientia_Occulta-WEB-2024-ENTiTLED ?? ?? ?? ? artist........ | Portae Obscuritas ? title......... | Sapientia Occulta label......... | 6868317 Records DK genre......... | Black Metal url............| https://www.deezer.com/album/568832371 rip date...... | 2024-10-17 retail date... | 2024-04-03 runtime....... | 55:41 tracks........ | 7 size.......... | 132.14MB source........ | WEB quality....... | CBR 320kbps 44.1kHz Stereo ? codec......... | MP3 (MPEG-1 Audio Layer 3) ? ?? encoder....... | LAME ?? ?? ?? ?? ?? ???? ???? ?????????????????? ?????????????????? ??? ? ?????????????????????????????????????? ? ?? ?? ?? ???? ------------------------------------------- ???? ??? ? ?\\u003c t r a c k . l i s t \\u003e? ? ??? ?? ------------------------------------------- ??? ?? ?? ?? ?? 01 \\u003e Intro \\u003c 05:12 02 \\u003e In a Twilight Obscurity \\u003c 09:15 03 \\u003e Manifestation of Acheronian Trinity \\u003c 09:14 04 \\u003e Imperious Reverent Transcendence \\u003c 08:59 05 \\u003e Enslaved Spirit of Forgotten Kingdoms \\u003c 11:48 06 \\u003e Sapientia Occulta \\u003c 08:24 07 \\u003e Outro \\u003c 02:49 ? ? ?? ?? ?? ?? ?? ?? ???? ???? ? ?????????????????? ?????????????????? ? ??? ?????????????????????????????????????? ??? ??? ??? ? ? ?\\u003c GREETINGS \\u003e? ? ? ?% %? ?? ?? ?% %? ?? Shout out to all of those who keep the dream of the scene alive. ?? ?% %? ?? Special thanks to those who have paved the way and parted. ?? ?% %? ?? We miss you! ?? ?% %? ?? ?? ?% %? ?? ?? ?% %? ?? ?? ?% %? ?? ?? ?% ??????????? %? ??? ?????? ????????? ?????? ??? ??? ? ?????????????? ? ??????????????? ? ??? ? ???????????????? ?????????????? ????? ???????????? ????????????????? ? ??????? ??????? ????? ??? ? ??? ?????? ??????? ??????? ?? ???????? ? ?????? ???? ? ???? ?????? ? ??????? ?? ?? ??????????? ??? ??????????? ?? ?? ?? + ? + ?? ?? ? ???? o ????? ? ????????????? ? ? ? ? ??? ??? ? ? ? ? ? ? ? ? ???? ????", + filter: "dark?metal,*black?metal*,gray?metal", + }, + want: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equalf(t, tt.want, containsFuzzy(tt.args.tag, tt.args.filter), "containsFuzzy(%v, %v)", tt.args.tag, tt.args.filter) + }) + } +} diff --git a/internal/domain/rejections.go b/internal/domain/rejections.go new file mode 100644 index 0000000..cdeea5d --- /dev/null +++ b/internal/domain/rejections.go @@ -0,0 +1,140 @@ +package domain + +import ( + "encoding/json" + "fmt" + "strings" +) + +type Rejection struct { + key string + got any + want any + format string +} + +type RejectionReasons struct { + data []Rejection +} + +func (r *RejectionReasons) Len() int { + return len(r.data) +} + +func NewRejectionReasons() *RejectionReasons { + return &RejectionReasons{ + data: make([]Rejection, 0), + } +} + +func (r *RejectionReasons) String() string { + if len(r.data) == 0 { + return "" + } + + builder := strings.Builder{} + for i, rejection := range r.data { + if i > 0 { + builder.WriteString(", ") + } + + if rejection.format != "" { + fmt.Fprintf(&builder, rejection.format, rejection.key, rejection.got, rejection.want) + continue + } + + fmt.Fprintf(&builder, "[%s] not matching: got %v want: %v", rejection.key, rejection.got, rejection.want) + } + + return builder.String() +} + +func (r *RejectionReasons) StringTruncated() string { + if len(r.data) == 0 { + return "" + } + + builder := strings.Builder{} + for i, rejection := range r.data { + got := rejection.got + switch v := rejection.got.(type) { + case string: + if len(v) > 1024 { + got = v[:1024] + } + } + + want := rejection.want + switch v := rejection.want.(type) { + case string: + if len(v) > 1024 { + want = v[:1024] + } + } + + if i > 0 { + builder.WriteString(", ") + } + fmt.Fprintf(&builder, "[%s] not matching: got %v want: %v", rejection.key, got, want) + } + + return builder.String() +} + +func (r *RejectionReasons) WriteString() string { + var output []string + for _, rejection := range r.data { + output = append(output, fmt.Sprintf("[%s] not matching: got %v want: %v", rejection.key, rejection.got, rejection.want)) + } + + return strings.Join(output, ", ") +} + +func (r *RejectionReasons) WriteJSON() ([]byte, error) { + var output map[string]string + for _, rejection := range r.data { + output[rejection.key] = fmt.Sprintf("[%s] not matching: got %v want: %v", rejection.key, rejection.got, rejection.want) + } + + return json.Marshal(output) +} + +func (r *RejectionReasons) Add(key string, got any, want any) { + r.data = append(r.data, Rejection{ + key: key, + got: got, + want: want, + }) +} + +func (r *RejectionReasons) Addf(key string, format string, got any, want any) { + r.data = append(r.data, Rejection{ + key: key, + format: format, + got: got, + want: want, + }) +} + +func (r *RejectionReasons) AddTruncated(key string, got any, want any) { + switch wanted := want.(type) { + case string: + if len(wanted) > 1024 { + want = wanted[:1024] + } + + case []string: + for i, s := range wanted { + if len(s) > 1024 { + wanted[i] = s[:1024] + } + } + + } + r.Add(key, got, want) +} + +// Clear rejections +func (r *RejectionReasons) Clear() { + r.data = make([]Rejection, 0) +} diff --git a/internal/domain/rejections_test.go b/internal/domain/rejections_test.go new file mode 100644 index 0000000..2612fe1 --- /dev/null +++ b/internal/domain/rejections_test.go @@ -0,0 +1,115 @@ +package domain + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestRejectionReasons_String(t *testing.T) { + type fields struct { + data []Rejection + } + tests := []struct { + name string + fields fields + want string + }{ + { + name: "empty", + fields: fields{ + data: []Rejection{}, + }, + want: "", + }, + { + name: "non_empty", + fields: fields{ + data: []Rejection{ + { + key: "resolution", + got: "1080p", + want: "2160p", + }, + { + key: "match hdr", + got: []string{"HDR10"}, + want: []string{"DV"}, + }, + }, + }, + want: "[resolution] not matching: got 1080p want: 2160p, [match hdr] not matching: got [HDR10] want: [DV]", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + r := &RejectionReasons{ + data: tt.fields.data, + } + assert.Equalf(t, tt.want, r.String(), "String()") + }) + } +} + +func TestRejectionReasons_StringTruncated(t *testing.T) { + type fields struct { + data []Rejection + } + tests := []struct { + name string + fields fields + want string + }{ + { + name: "empty", + fields: fields{ + data: []Rejection{}, + }, + want: "", + }, + { + name: "non_empty", + fields: fields{ + data: []Rejection{ + { + key: "resolution", + got: "1080p", + want: "2160p", + }, + { + key: "match hdr", + got: []string{"HDR10"}, + want: []string{"DV"}, + }, + }, + }, + want: "[resolution] not matching: got 1080p want: 2160p, [match hdr] not matching: got [HDR10] want: [DV]", + }, + { + name: "truncated", + fields: fields{ + data: []Rejection{ + { + key: "resolution", + got: "1080p", + want: "2160p", + }, + { + key: "match description", + got: "Kategori: Music \\n Storlek: 132.78 MiB\\n ? ?? ?? ????????? ?? ?? ?? ?? ?? ???? ?? ?? ?? ???? ??? ? ?? ?? ?? ? ??? ? ? ?? ? ?? ? ??? ? ?? ?? ??? ?? ?? ???? ???? ?? ???? ????? ????? ? ?? ?? ???? ?? ???? ?? ?? ? ?????? ????????????? ???????????? ????????????? ?????? ???? ?????? ? ?? ??? ? ?? ? ?? ?? ??? ?? ? ? ?????? ?? ?? ?? ?? ?? ????? ? ?? ?? ?? ?? ?? ????????? ? ?????? ?? ????????? ??? ? ?????? ? ?? ? ?? ?? ??? ? ? ? ?? ?? ? ??? ? ?? ? ? ?? ????? ? ?? ? ? ?? ?? ??? ??? ??? ?? ??? ?? ??? ??? ? ????????? ???? ?? ????? ? ?? ????????????? ??????????? ??? ???? ??? ?? ?????????? ?? ?? ??? ?? ??? ??? ???? ??? ? ?? ??? ? ?? ?????????? ?? ??????????????? ????????????? ???? ???? ????? ??? ??????? ???????? ????? ???????? ????? ????? ?? ??? ??? ? ? ???? ???? ???? ???? ???? ???? ???? ?? ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?? ?? ??? ??? ?? ??? ??? ??? ??? ??? ???????? ? ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?????? ??? ??? ???? ??? ? ??? ??? ??? ??? ? ??? ???? ? ? ??? ???? ???? ?? ?? ?? ?? ?? ?? ?? ??????? ???? ???? ? ?? ? ? ? ? ? ? ?????? ??????? ????? ?? ? ? ? ? ? ? ?? ?????? ????? ?? ? ? ? ? ? ? sM!iMPURE ??? ???? ? ? ? ? ? ? ./\\\\\\\\//\\\\\\\\. ???? ?? ? ? ? ?? ? ? ? ? ?????????????????????????????????????? ?????????????????? ?????????????????? ??? ?? ?? ??? ??? RELEASE INFORMATION for: ??? ?? Portae_Obscuritas-Sapientia_Occulta-WEB-2024-ENTiTLED ?? ?? ?? ? artist........ | Portae Obscuritas ? title......... | Sapientia Occulta label......... | 6868317 Records DK genre......... | Black Metal url............| https://www.deezer.com/album/568832371 rip date...... | 2024-10-17 retail date... | 2024-04-03 runtime....... | 55:41 tracks........ | 7 size.......... | 132.14MB source........ | WEB quality....... | CBR 320kbps 44.1kHz Stereo ? codec......... | MP3 (MPEG-1 Audio Layer 3) ? ?? encoder....... | LAME ?? ?? ?? ?? ?? ???? ???? ?????????????????? ?????????????????? ??? ? ?????????????????????????????????????? ? ?? ?? ?? ???? ------------------------------------------- ???? ??? ? ?\\u003c t r a c k . l i s t \\u003e? ? ??? ?? ------------------------------------------- ??? ?? ?? ?? ?? 01 \\u003e Intro \\u003c 05:12 02 \\u003e In a Twilight Obscurity \\u003c 09:15 03 \\u003e Manifestation of Acheronian Trinity \\u003c 09:14 04 \\u003e Imperious Reverent Transcendence \\u003c 08:59 05 \\u003e Enslaved Spirit of Forgotten Kingdoms \\u003c 11:48 06 \\u003e Sapientia Occulta \\u003c 08:24 07 \\u003e Outro \\u003c 02:49 ? ? ?? ?? ?? ?? ?? ?? ???? ???? ? ?????????????????? ?????????????????? ? ??? ?????????????????????????????????????? ??? ??? ??? ? ? ?\\u003c GREETINGS \\u003e? ? ? ?% %? ?? ?? ?% %? ?? Shout out to all of those who keep the dream of the scene alive. ?? ?% %? ?? Special thanks to those who have paved the way and parted. ?? ?% %? ?? We miss you! ?? ?% %? ?? ?? ?% %? ?? ?? ?% %? ?? ?? ?% %? ?? ?? ?% ??????????? %? ??? ?????? ????????? ?????? ??? ??? ? ?????????????? ? ??????????????? ? ??? ? ???????????????? ?????????????? ????? ???????????? ????????????????? ? ??????? ??????? ????? ??? ? ??? ?????? ??????? ??????? ?? ???????? ? ?????? ???? ? ???? ?????? ? ??????? ?? ?? ??????????? ??? ??????????? ?? ?? ?? + ? + ?? ?? ? ???? o ????? ? ????????????? ? ? ? ? ??? ??? ? ? ? ? ? ? ? ? ???? ????", + want: "*black?metal*", + }, + }, + }, + want: "[resolution] not matching: got 1080p want: 2160p, [match description] not matching: got Kategori: Music \\n Storlek: 132.78 MiB\\n ? ?? ?? ????????? ?? ?? ?? ?? ?? ???? ?? ?? ?? ???? ??? ? ?? ?? ?? ? ??? ? ? ?? ? ?? ? ??? ? ?? ?? ??? ?? ?? ???? ???? ?? ???? ????? ????? ? ?? ?? ???? ?? ???? ?? ?? ? ?????? ????????????? ???????????? ????????????? ?????? ???? ?????? ? ?? ??? ? ?? ? ?? ?? ??? ?? ? ? ?????? ?? ?? ?? ?? ?? ????? ? ?? want: *black?metal*", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + r := &RejectionReasons{ + data: tt.fields.data, + } + assert.Equalf(t, tt.want, r.StringTruncated(), "StringTruncated()") + }) + } +} diff --git a/internal/domain/release.go b/internal/domain/release.go index 92de407..5a14c0e 100644 --- a/internal/domain/release.go +++ b/internal/domain/release.go @@ -620,35 +620,6 @@ func (r *Release) HasMagnetUri() bool { const MagnetURIPrefix = "magnet:?" -func (r *Release) addRejection(reason string) { - r.Rejections = append(r.Rejections, reason) -} - -func (r *Release) AddRejectionF(format string, v ...interface{}) { - r.addRejectionF(format, v...) -} - -func (r *Release) addRejectionF(format string, v ...interface{}) { - r.Rejections = append(r.Rejections, fmt.Sprintf(format, v...)) -} - -// ResetRejections reset rejections between filter checks -func (r *Release) resetRejections() { - r.Rejections = []string{} -} - -func (r *Release) RejectionsString(trim bool) string { - if len(r.Rejections) > 0 { - out := strings.Join(r.Rejections, ", ") - if trim && len(out) > 1024 { - out = out[:1024] - } - - return out - } - return "" -} - // MapVars map vars from regex captures to fields on release func (r *Release) MapVars(def *IndexerDefinition, varMap map[string]string) error { diff --git a/internal/filter/service.go b/internal/filter/service.go index ab6f558..300d7b5 100644 --- a/internal/filter/service.go +++ b/internal/filter/service.go @@ -386,8 +386,8 @@ func (s *service) CheckFilter(ctx context.Context, f *domain.Filter, release *do } rejections, matchedFilter := f.CheckFilter(release) - if len(rejections) > 0 { - l.Debug().Msgf("(%s) for release: %v rejections: (%s)", f.Name, release.TorrentName, f.RejectionsString(true)) + if rejections.Len() > 0 { + l.Debug().Msgf("(%s) for release: %v rejections: (%s)", f.Name, release.TorrentName, rejections.StringTruncated()) return false, nil } @@ -415,9 +415,9 @@ func (s *service) CheckFilter(ctx context.Context, f *domain.Filter, release *do l.Trace().Msgf("failed smart episode check: %s", f.Name) if params.IsDailyEpisode() { - f.AddRejectionF("smart episode check: not new: (%s) Daily: %d-%d-%d", release.Title, release.Year, release.Month, release.Day) + f.RejectReasons.Add("smart episode", fmt.Sprintf("not new (%s) daily: %d-%d-%d", release.Title, release.Year, release.Month, release.Day), fmt.Sprintf("expected newer than (%s) daily: %d-%d-%d", release.Title, release.Year, release.Month, release.Day)) } else { - f.AddRejectionF("smart episode check: not new: (%s) season: %d ep: %d", release.Title, release.Season, release.Episode) + f.RejectReasons.Add("smart episode", fmt.Sprintf("not new (%s) season: %d ep: %d", release.Title, release.Season, release.Episode), fmt.Sprintf("expected newer than (%s) season: %d ep: %d", release.Title, release.Season, release.Episode)) } return false, nil @@ -566,7 +566,7 @@ func (s *service) RunExternalFilters(ctx context.Context, f *domain.Filter, exte if exitCode != external.ExecExpectStatus { s.log.Trace().Msgf("filter.Service.CheckFilter: external script unexpected exit code. got: %d want: %d", exitCode, external.ExecExpectStatus) - f.AddRejectionF("external script unexpected exit code. got: %d want: %d", exitCode, external.ExecExpectStatus) + f.RejectReasons.Add("external script exit code", exitCode, external.ExecExpectStatus) return false, nil } @@ -579,7 +579,7 @@ func (s *service) RunExternalFilters(ctx context.Context, f *domain.Filter, exte if statusCode != external.WebhookExpectStatus { s.log.Trace().Msgf("filter.Service.CheckFilter: external webhook unexpected status code. got: %d want: %d", statusCode, external.WebhookExpectStatus) - f.AddRejectionF("external webhook unexpected status code. got: %d want: %d", statusCode, external.WebhookExpectStatus) + f.RejectReasons.Add("external webhook status code", statusCode, external.WebhookExpectStatus) return false, nil } } diff --git a/internal/indexer/indexer_test.go b/internal/indexer/indexer_test.go index 5fc4f36..e5c9f3d 100644 --- a/internal/indexer/indexer_test.go +++ b/internal/indexer/indexer_test.go @@ -398,7 +398,7 @@ func TestIndexersParseAndFilter(t *testing.T) { //match, err := filterSvc.CheckFilter(ctx, filter, rls) rejections, matchedFilter := filter.CheckFilter(rls) - assert.Len(t, rejections, len(filterT.rejections)) + assert.Equal(t, rejections.Len(), len(filterT.rejections)) assert.Equal(t, filterT.match, matchedFilter) }) } diff --git a/internal/release/service.go b/internal/release/service.go index 7c47ed1..8246293 100644 --- a/internal/release/service.go +++ b/internal/release/service.go @@ -206,9 +206,9 @@ func (s *service) processFilters(ctx context.Context, filters []*domain.Filter, } if !match { - l.Trace().Msgf("release.Process: indexer: %s, filter: %s release: %s, no match. rejections: %s", release.Indexer.Name, release.FilterName, release.TorrentName, f.RejectionsString(false)) + l.Trace().Msgf("release.Process: indexer: %s, filter: %s release: %s, no match. rejections: %s", release.Indexer.Name, release.FilterName, release.TorrentName, f.RejectReasons.String()) - l.Debug().Msgf("filter %s rejected release: %s", f.Name, f.RejectionsString(true)) + l.Debug().Msgf("filter %s rejected release: %s", f.Name, release.TorrentName) continue }