From 5d80e48b5443a9dc8ade11ff647b5b86414f3965 Mon Sep 17 00:00:00 2001 From: ze0s <43699394+zze0s@users.noreply.github.com> Date: Wed, 3 Aug 2022 12:47:32 +0200 Subject: [PATCH] feat(filters): add except origins (#396) * feat(filters): add except origins * feat(filters): add user origin --- internal/database/filter.go | 9 +++++++-- internal/database/postgres_migrate.go | 5 +++++ internal/database/sqlite_migrate.go | 5 +++++ internal/domain/filter.go | 4 ++++ internal/domain/filter_test.go | 20 ++++++++++++++++++++ internal/domain/releasetags.go | 1 + web/src/screens/filters/details.tsx | 9 ++++++--- web/src/types/Filter.d.ts | 1 + 8 files changed, 49 insertions(+), 5 deletions(-) diff --git a/internal/database/filter.go b/internal/database/filter.go index d18b6ac..ce56a09 100644 --- a/internal/database/filter.go +++ b/internal/database/filter.go @@ -122,6 +122,7 @@ func (r *FilterRepo) FindByID(ctx context.Context, filterID int) (*domain.Filter "tags", "except_tags", "origins", + "except_origins", "external_script_enabled", "external_script_cmd", "external_script_args", @@ -151,7 +152,7 @@ func (r *FilterRepo) FindByID(ctx context.Context, filterID int) (*domain.Filter var useRegex, scene, freeleech, hasLog, hasCue, perfectFlac, extScriptEnabled, extWebhookEnabled sql.NullBool var delay, maxDownloads, logScore, extWebhookStatus, extScriptStatus sql.NullInt32 - if err := row.Scan(&f.ID, &f.Enabled, &f.Name, &minSize, &maxSize, &delay, &f.Priority, &maxDownloads, &maxDownloadsUnit, &matchReleases, &exceptReleases, &useRegex, &matchReleaseGroups, &exceptReleaseGroups, &scene, &freeleech, &freeleechPercent, &shows, &seasons, &episodes, pq.Array(&f.Resolutions), pq.Array(&f.Codecs), pq.Array(&f.Sources), pq.Array(&f.Containers), pq.Array(&f.MatchHDR), pq.Array(&f.ExceptHDR), pq.Array(&f.MatchOther), pq.Array(&f.ExceptOther), &years, &artists, &albums, pq.Array(&f.MatchReleaseTypes), pq.Array(&f.Formats), pq.Array(&f.Quality), pq.Array(&f.Media), &logScore, &hasLog, &hasCue, &perfectFlac, &matchCategories, &exceptCategories, &matchUploaders, &exceptUploaders, &tags, &exceptTags, pq.Array(&f.Origins), &extScriptEnabled, &extScriptCmd, &extScriptArgs, &extScriptStatus, &extWebhookEnabled, &extWebhookHost, &extWebhookData, &extWebhookStatus, &f.CreatedAt, &f.UpdatedAt); err != nil { + if err := row.Scan(&f.ID, &f.Enabled, &f.Name, &minSize, &maxSize, &delay, &f.Priority, &maxDownloads, &maxDownloadsUnit, &matchReleases, &exceptReleases, &useRegex, &matchReleaseGroups, &exceptReleaseGroups, &scene, &freeleech, &freeleechPercent, &shows, &seasons, &episodes, pq.Array(&f.Resolutions), pq.Array(&f.Codecs), pq.Array(&f.Sources), pq.Array(&f.Containers), pq.Array(&f.MatchHDR), pq.Array(&f.ExceptHDR), pq.Array(&f.MatchOther), pq.Array(&f.ExceptOther), &years, &artists, &albums, pq.Array(&f.MatchReleaseTypes), pq.Array(&f.Formats), pq.Array(&f.Quality), pq.Array(&f.Media), &logScore, &hasLog, &hasCue, &perfectFlac, &matchCategories, &exceptCategories, &matchUploaders, &exceptUploaders, &tags, &exceptTags, pq.Array(&f.Origins), pq.Array(&f.ExceptOrigins), &extScriptEnabled, &extScriptCmd, &extScriptArgs, &extScriptStatus, &extWebhookEnabled, &extWebhookHost, &extWebhookData, &extWebhookStatus, &f.CreatedAt, &f.UpdatedAt); err != nil { return nil, errors.Wrap(err, "error scanning row") } @@ -272,6 +273,7 @@ func (r *FilterRepo) findByIndexerIdentifier(ctx context.Context, tx *Tx, indexe "f.tags", "f.except_tags", "f.origins", + "f.except_origins", "f.external_script_enabled", "f.external_script_cmd", "f.external_script_args", @@ -311,7 +313,7 @@ func (r *FilterRepo) findByIndexerIdentifier(ctx context.Context, tx *Tx, indexe var useRegex, scene, freeleech, hasLog, hasCue, perfectFlac, extScriptEnabled, extWebhookEnabled sql.NullBool var delay, maxDownloads, logScore, extWebhookStatus, extScriptStatus sql.NullInt32 - if err := rows.Scan(&f.ID, &f.Enabled, &f.Name, &minSize, &maxSize, &delay, &f.Priority, &maxDownloads, &maxDownloadsUnit, &matchReleases, &exceptReleases, &useRegex, &matchReleaseGroups, &exceptReleaseGroups, &scene, &freeleech, &freeleechPercent, &shows, &seasons, &episodes, pq.Array(&f.Resolutions), pq.Array(&f.Codecs), pq.Array(&f.Sources), pq.Array(&f.Containers), pq.Array(&f.MatchHDR), pq.Array(&f.ExceptHDR), pq.Array(&f.MatchOther), pq.Array(&f.ExceptOther), &years, &artists, &albums, pq.Array(&f.MatchReleaseTypes), pq.Array(&f.Formats), pq.Array(&f.Quality), pq.Array(&f.Media), &logScore, &hasLog, &hasCue, &perfectFlac, &matchCategories, &exceptCategories, &matchUploaders, &exceptUploaders, &tags, &exceptTags, pq.Array(&f.Origins), &extScriptEnabled, &extScriptCmd, &extScriptArgs, &extScriptStatus, &extWebhookEnabled, &extWebhookHost, &extWebhookData, &extWebhookStatus, &f.CreatedAt, &f.UpdatedAt); err != nil { + if err := rows.Scan(&f.ID, &f.Enabled, &f.Name, &minSize, &maxSize, &delay, &f.Priority, &maxDownloads, &maxDownloadsUnit, &matchReleases, &exceptReleases, &useRegex, &matchReleaseGroups, &exceptReleaseGroups, &scene, &freeleech, &freeleechPercent, &shows, &seasons, &episodes, pq.Array(&f.Resolutions), pq.Array(&f.Codecs), pq.Array(&f.Sources), pq.Array(&f.Containers), pq.Array(&f.MatchHDR), pq.Array(&f.ExceptHDR), pq.Array(&f.MatchOther), pq.Array(&f.ExceptOther), &years, &artists, &albums, pq.Array(&f.MatchReleaseTypes), pq.Array(&f.Formats), pq.Array(&f.Quality), pq.Array(&f.Media), &logScore, &hasLog, &hasCue, &perfectFlac, &matchCategories, &exceptCategories, &matchUploaders, &exceptUploaders, &tags, &exceptTags, pq.Array(&f.Origins), pq.Array(&f.ExceptOrigins), &extScriptEnabled, &extScriptCmd, &extScriptArgs, &extScriptStatus, &extWebhookEnabled, &extWebhookHost, &extWebhookData, &extWebhookStatus, &f.CreatedAt, &f.UpdatedAt); err != nil { return nil, errors.Wrap(err, "error scanning row") } @@ -410,6 +412,7 @@ func (r *FilterRepo) Store(ctx context.Context, filter domain.Filter) (*domain.F "has_cue", "perfect_flac", "origins", + "except_origins", "external_script_enabled", "external_script_cmd", "external_script_args", @@ -465,6 +468,7 @@ func (r *FilterRepo) Store(ctx context.Context, filter domain.Filter) (*domain.F filter.Cue, filter.PerfectFlac, pq.Array(filter.Origins), + pq.Array(filter.ExceptOrigins), filter.ExternalScriptEnabled, filter.ExternalScriptCmd, filter.ExternalScriptArgs, @@ -539,6 +543,7 @@ func (r *FilterRepo) Update(ctx context.Context, filter domain.Filter) (*domain. Set("has_cue", filter.Cue). Set("perfect_flac", filter.PerfectFlac). Set("origins", pq.Array(filter.Origins)). + Set("except_origins", pq.Array(filter.ExceptOrigins)). Set("external_script_enabled", filter.ExternalScriptEnabled). Set("external_script_cmd", filter.ExternalScriptCmd). Set("external_script_args", filter.ExternalScriptArgs). diff --git a/internal/database/postgres_migrate.go b/internal/database/postgres_migrate.go index 1244ec5..537cb33 100644 --- a/internal/database/postgres_migrate.go +++ b/internal/database/postgres_migrate.go @@ -107,6 +107,7 @@ CREATE TABLE filter tags TEXT, except_tags TEXT, origins TEXT [] DEFAULT '{}', + except_origins TEXT [] DEFAULT '{}', external_script_enabled BOOLEAN DEFAULT FALSE, external_script_cmd TEXT, external_script_args TEXT, @@ -536,4 +537,8 @@ CREATE INDEX indexer_identifier_index ALTER TABLE action ADD COLUMN content_layout TEXT; `, + ` + ALTER TABLE filter + ADD COLUMN except_origins TEXT [] DEFAULT '{}'; + `, } diff --git a/internal/database/sqlite_migrate.go b/internal/database/sqlite_migrate.go index c4444bc..a639c94 100644 --- a/internal/database/sqlite_migrate.go +++ b/internal/database/sqlite_migrate.go @@ -107,6 +107,7 @@ CREATE TABLE filter tags TEXT, except_tags TEXT, origins TEXT [] DEFAULT '{}', + except_origins TEXT [] DEFAULT '{}', external_script_enabled BOOLEAN DEFAULT FALSE, external_script_cmd TEXT, external_script_args TEXT, @@ -856,4 +857,8 @@ CREATE INDEX indexer_identifier_index ALTER TABLE action ADD COLUMN content_layout TEXT; `, + ` + ALTER TABLE filter + ADD COLUMN except_origins TEXT [] DEFAULT '{}'; + `, } diff --git a/internal/domain/filter.go b/internal/domain/filter.go index ffc7977..4eb8d8f 100644 --- a/internal/domain/filter.go +++ b/internal/domain/filter.go @@ -67,6 +67,7 @@ type Filter struct { ExceptReleaseGroups string `json:"except_release_groups,omitempty"` Scene bool `json:"scene,omitempty"` Origins []string `json:"origins,omitempty"` + ExceptOrigins []string `json:"except_origins,omitempty"` Bonus []string `json:"bonus,omitempty"` Freeleech bool `json:"freeleech,omitempty"` FreeleechPercent string `json:"freeleech_percent,omitempty"` @@ -140,6 +141,9 @@ func (f Filter) CheckFilter(r *Release) ([]string, bool) { if len(f.Origins) > 0 && !containsSlice(r.Origin, f.Origins) { r.addRejectionF("origin not matching. got: %v want: %v", r.Origin, f.Origins) } + if len(f.ExceptOrigins) > 0 && containsSlice(r.Origin, f.ExceptOrigins) { + r.addRejectionF("except origin not matching. got: %v unwanted: %v", r.Origin, f.ExceptOrigins) + } // title is the parsed title if f.Shows != "" && !contains(r.Title, f.Shows) { diff --git a/internal/domain/filter_test.go b/internal/domain/filter_test.go index 8902f6e..6d43972 100644 --- a/internal/domain/filter_test.go +++ b/internal/domain/filter_test.go @@ -1017,6 +1017,7 @@ func TestFilter_CheckFilter1(t *testing.T) { ExceptReleaseGroups string Scene bool Origins []string + ExceptOrigins []string Freeleech bool FreeleechPercent string Shows string @@ -1510,6 +1511,24 @@ func TestFilter_CheckFilter1(t *testing.T) { wantRejections: nil, 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, + }, + { + name: "test_38", + fields: fields{ + ExceptOrigins: []string{"Internal"}, + }, + args: args{&Release{TorrentName: "Gillan - Future Shock", Origin: "Scene"}}, + wantRejections: nil, + wantMatch: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -1532,6 +1551,7 @@ func TestFilter_CheckFilter1(t *testing.T) { ExceptReleaseGroups: tt.fields.ExceptReleaseGroups, Scene: tt.fields.Scene, Origins: tt.fields.Origins, + ExceptOrigins: tt.fields.ExceptOrigins, Freeleech: tt.fields.Freeleech, FreeleechPercent: tt.fields.FreeleechPercent, Shows: tt.fields.Shows, diff --git a/internal/domain/releasetags.go b/internal/domain/releasetags.go index 6b7623c..fce17d5 100644 --- a/internal/domain/releasetags.go +++ b/internal/domain/releasetags.go @@ -133,6 +133,7 @@ func init() { {tag: "Scene", title: "Scene", regexp: "", re: nil}, {tag: "O-Scene", title: "O-Scene", regexp: "", re: nil}, {tag: "Internal", title: "Internal", regexp: "", re: nil}, + {tag: "User", title: "User", regexp: "", re: nil}, } types["origin"] = origin diff --git a/web/src/screens/filters/details.tsx b/web/src/screens/filters/details.tsx index bb003eb..4511f57 100644 --- a/web/src/screens/filters/details.tsx +++ b/web/src/screens/filters/details.tsx @@ -282,6 +282,7 @@ export default function FilterDetails() { artists: filter.artists, albums: filter.albums, origins: filter.origins || [], + except_origins: filter.except_origins || [], indexers: filter.indexers || [], actions: filter.actions || [], external_script_enabled: filter.external_script_enabled || false, @@ -491,7 +492,8 @@ export function Advanced() { - + + @@ -509,10 +511,11 @@ interface CollapsableSectionProps { title: string; subtitle: string; children: React.ReactNode; + defaultOpen?: boolean; } -function CollapsableSection({ title, subtitle, children }: CollapsableSectionProps) { - const [isOpen, toggleOpen] = useToggle(false); +function CollapsableSection({ title, subtitle, children, defaultOpen }: CollapsableSectionProps) { + const [isOpen, toggleOpen] = useToggle(defaultOpen ?? false); return (
diff --git a/web/src/types/Filter.d.ts b/web/src/types/Filter.d.ts index f437303..8e4705c 100644 --- a/web/src/types/Filter.d.ts +++ b/web/src/types/Filter.d.ts @@ -17,6 +17,7 @@ interface Filter { except_release_groups: string; scene: boolean; origins: string[]; + except_origins: string[]; freeleech: boolean; freeleech_percent: string; shows: string;