mirror of
https://github.com/idanoo/autobrr
synced 2025-07-23 08:49:13 +00:00
feat(filters): support Language filtering (#632)
* feat(filters): add support for language * feat(filters): add db migrations and repo * feat(filters): fix failing tests * feat(filters): fix failing tests
This commit is contained in:
parent
3c4711efa0
commit
5c402b6d6c
11 changed files with 120 additions and 8 deletions
|
@ -217,6 +217,8 @@ func (r *FilterRepo) FindByID(ctx context.Context, filterID int) (*domain.Filter
|
||||||
"except_categories",
|
"except_categories",
|
||||||
"match_uploaders",
|
"match_uploaders",
|
||||||
"except_uploaders",
|
"except_uploaders",
|
||||||
|
"match_language",
|
||||||
|
"except_language",
|
||||||
"tags",
|
"tags",
|
||||||
"except_tags",
|
"except_tags",
|
||||||
"origins",
|
"origins",
|
||||||
|
@ -250,7 +252,7 @@ func (r *FilterRepo) FindByID(ctx context.Context, filterID int) (*domain.Filter
|
||||||
var useRegex, scene, freeleech, hasLog, hasCue, perfectFlac, extScriptEnabled, extWebhookEnabled sql.NullBool
|
var useRegex, scene, freeleech, hasLog, hasCue, perfectFlac, extScriptEnabled, extWebhookEnabled sql.NullBool
|
||||||
var delay, maxDownloads, logScore, extWebhookStatus, extScriptStatus sql.NullInt32
|
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, &matchReleaseTags, &exceptReleaseTags, &f.UseRegexReleaseTags, &scene, &freeleech, &freeleechPercent, &f.SmartEpisode, &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 {
|
if err := row.Scan(&f.ID, &f.Enabled, &f.Name, &minSize, &maxSize, &delay, &f.Priority, &maxDownloads, &maxDownloadsUnit, &matchReleases, &exceptReleases, &useRegex, &matchReleaseGroups, &exceptReleaseGroups, &matchReleaseTags, &exceptReleaseTags, &f.UseRegexReleaseTags, &scene, &freeleech, &freeleechPercent, &f.SmartEpisode, &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, pq.Array(&f.MatchLanguage), pq.Array(&f.ExceptLanguage), &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")
|
return nil, errors.Wrap(err, "error scanning row")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,6 +380,8 @@ func (r *FilterRepo) findByIndexerIdentifier(ctx context.Context, tx *Tx, indexe
|
||||||
"f.except_categories",
|
"f.except_categories",
|
||||||
"f.match_uploaders",
|
"f.match_uploaders",
|
||||||
"f.except_uploaders",
|
"f.except_uploaders",
|
||||||
|
"f.match_language",
|
||||||
|
"f.except_language",
|
||||||
"f.tags",
|
"f.tags",
|
||||||
"f.except_tags",
|
"f.except_tags",
|
||||||
"f.origins",
|
"f.origins",
|
||||||
|
@ -421,7 +425,7 @@ func (r *FilterRepo) findByIndexerIdentifier(ctx context.Context, tx *Tx, indexe
|
||||||
var useRegex, scene, freeleech, hasLog, hasCue, perfectFlac, extScriptEnabled, extWebhookEnabled sql.NullBool
|
var useRegex, scene, freeleech, hasLog, hasCue, perfectFlac, extScriptEnabled, extWebhookEnabled sql.NullBool
|
||||||
var delay, maxDownloads, logScore, extWebhookStatus, extScriptStatus sql.NullInt32
|
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, &matchReleaseTags, &exceptReleaseTags, &f.UseRegexReleaseTags, &scene, &freeleech, &freeleechPercent, &f.SmartEpisode, &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 {
|
if err := rows.Scan(&f.ID, &f.Enabled, &f.Name, &minSize, &maxSize, &delay, &f.Priority, &maxDownloads, &maxDownloadsUnit, &matchReleases, &exceptReleases, &useRegex, &matchReleaseGroups, &exceptReleaseGroups, &matchReleaseTags, &exceptReleaseTags, &f.UseRegexReleaseTags, &scene, &freeleech, &freeleechPercent, &f.SmartEpisode, &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, pq.Array(&f.MatchLanguage), pq.Array(&f.ExceptLanguage), &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")
|
return nil, errors.Wrap(err, "error scanning row")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -513,6 +517,8 @@ func (r *FilterRepo) Store(ctx context.Context, filter domain.Filter) (*domain.F
|
||||||
"except_categories",
|
"except_categories",
|
||||||
"match_uploaders",
|
"match_uploaders",
|
||||||
"except_uploaders",
|
"except_uploaders",
|
||||||
|
"match_language",
|
||||||
|
"except_language",
|
||||||
"tags",
|
"tags",
|
||||||
"except_tags",
|
"except_tags",
|
||||||
"artists",
|
"artists",
|
||||||
|
@ -573,6 +579,8 @@ func (r *FilterRepo) Store(ctx context.Context, filter domain.Filter) (*domain.F
|
||||||
filter.ExceptCategories,
|
filter.ExceptCategories,
|
||||||
filter.MatchUploaders,
|
filter.MatchUploaders,
|
||||||
filter.ExceptUploaders,
|
filter.ExceptUploaders,
|
||||||
|
pq.Array(filter.MatchLanguage),
|
||||||
|
pq.Array(filter.ExceptLanguage),
|
||||||
filter.Tags,
|
filter.Tags,
|
||||||
filter.ExceptTags,
|
filter.ExceptTags,
|
||||||
filter.Artists,
|
filter.Artists,
|
||||||
|
@ -652,6 +660,8 @@ func (r *FilterRepo) Update(ctx context.Context, filter domain.Filter) (*domain.
|
||||||
Set("except_categories", filter.ExceptCategories).
|
Set("except_categories", filter.ExceptCategories).
|
||||||
Set("match_uploaders", filter.MatchUploaders).
|
Set("match_uploaders", filter.MatchUploaders).
|
||||||
Set("except_uploaders", filter.ExceptUploaders).
|
Set("except_uploaders", filter.ExceptUploaders).
|
||||||
|
Set("match_language", pq.Array(filter.MatchLanguage)).
|
||||||
|
Set("except_language", pq.Array(filter.ExceptLanguage)).
|
||||||
Set("tags", filter.Tags).
|
Set("tags", filter.Tags).
|
||||||
Set("except_tags", filter.ExceptTags).
|
Set("except_tags", filter.ExceptTags).
|
||||||
Set("artists", filter.Artists).
|
Set("artists", filter.Artists).
|
||||||
|
@ -803,6 +813,12 @@ func (r *FilterRepo) UpdatePartial(ctx context.Context, filter domain.FilterUpda
|
||||||
if filter.ExceptUploaders != nil {
|
if filter.ExceptUploaders != nil {
|
||||||
q = q.Set("except_uploaders", filter.ExceptUploaders)
|
q = q.Set("except_uploaders", filter.ExceptUploaders)
|
||||||
}
|
}
|
||||||
|
if filter.MatchLanguage != nil {
|
||||||
|
q = q.Set("match_language", pq.Array(filter.MatchLanguage))
|
||||||
|
}
|
||||||
|
if filter.ExceptLanguage != nil {
|
||||||
|
q = q.Set("except_language", pq.Array(filter.ExceptLanguage))
|
||||||
|
}
|
||||||
if filter.Tags != nil {
|
if filter.Tags != nil {
|
||||||
q = q.Set("tags", filter.Tags)
|
q = q.Set("tags", filter.Tags)
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,6 +111,8 @@ CREATE TABLE filter
|
||||||
except_categories TEXT,
|
except_categories TEXT,
|
||||||
match_uploaders TEXT,
|
match_uploaders TEXT,
|
||||||
except_uploaders TEXT,
|
except_uploaders TEXT,
|
||||||
|
match_language TEXT [] DEFAULT '{}',
|
||||||
|
except_language TEXT [] DEFAULT '{}',
|
||||||
tags TEXT,
|
tags TEXT,
|
||||||
except_tags TEXT,
|
except_tags TEXT,
|
||||||
origins TEXT [] DEFAULT '{}',
|
origins TEXT [] DEFAULT '{}',
|
||||||
|
@ -623,4 +625,10 @@ CREATE INDEX indexer_identifier_index
|
||||||
`ALTER TABLE "filter"
|
`ALTER TABLE "filter"
|
||||||
ADD COLUMN smart_episode BOOLEAN DEFAULT false;
|
ADD COLUMN smart_episode BOOLEAN DEFAULT false;
|
||||||
`,
|
`,
|
||||||
|
`ALTER TABLE "filter"
|
||||||
|
ADD COLUMN match_language TEXT [] DEFAULT '{}';
|
||||||
|
|
||||||
|
ALTER TABLE "filter"
|
||||||
|
ADD COLUMN except_language TEXT [] DEFAULT '{}';
|
||||||
|
`,
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,6 +111,8 @@ CREATE TABLE filter
|
||||||
except_categories TEXT,
|
except_categories TEXT,
|
||||||
match_uploaders TEXT,
|
match_uploaders TEXT,
|
||||||
except_uploaders TEXT,
|
except_uploaders TEXT,
|
||||||
|
match_language TEXT [] DEFAULT '{}',
|
||||||
|
except_language TEXT [] DEFAULT '{}',
|
||||||
tags TEXT,
|
tags TEXT,
|
||||||
except_tags TEXT,
|
except_tags TEXT,
|
||||||
origins TEXT [] DEFAULT '{}',
|
origins TEXT [] DEFAULT '{}',
|
||||||
|
@ -967,4 +969,10 @@ ALTER TABLE irc_network_dg_tmp
|
||||||
`ALTER TABLE "filter"
|
`ALTER TABLE "filter"
|
||||||
ADD COLUMN smart_episode BOOLEAN DEFAULT false;
|
ADD COLUMN smart_episode BOOLEAN DEFAULT false;
|
||||||
`,
|
`,
|
||||||
|
`ALTER TABLE "filter"
|
||||||
|
ADD COLUMN match_language TEXT [] DEFAULT '{}';
|
||||||
|
|
||||||
|
ALTER TABLE "filter"
|
||||||
|
ADD COLUMN except_language TEXT [] DEFAULT '{}';
|
||||||
|
`,
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,6 +109,8 @@ type Filter struct {
|
||||||
ExceptCategories string `json:"except_categories,omitempty"`
|
ExceptCategories string `json:"except_categories,omitempty"`
|
||||||
MatchUploaders string `json:"match_uploaders,omitempty"`
|
MatchUploaders string `json:"match_uploaders,omitempty"`
|
||||||
ExceptUploaders string `json:"except_uploaders,omitempty"`
|
ExceptUploaders string `json:"except_uploaders,omitempty"`
|
||||||
|
MatchLanguage []string `json:"match_language,omitempty"`
|
||||||
|
ExceptLanguage []string `json:"except_language,omitempty"`
|
||||||
Tags string `json:"tags,omitempty"`
|
Tags string `json:"tags,omitempty"`
|
||||||
ExceptTags string `json:"except_tags,omitempty"`
|
ExceptTags string `json:"except_tags,omitempty"`
|
||||||
TagsAny string `json:"tags_any,omitempty"`
|
TagsAny string `json:"tags_any,omitempty"`
|
||||||
|
@ -182,6 +184,8 @@ type FilterUpdate struct {
|
||||||
ExceptCategories *string `json:"except_categories,omitempty"`
|
ExceptCategories *string `json:"except_categories,omitempty"`
|
||||||
MatchUploaders *string `json:"match_uploaders,omitempty"`
|
MatchUploaders *string `json:"match_uploaders,omitempty"`
|
||||||
ExceptUploaders *string `json:"except_uploaders,omitempty"`
|
ExceptUploaders *string `json:"except_uploaders,omitempty"`
|
||||||
|
MatchLanguage *[]string `json:"match_language,omitempty"`
|
||||||
|
ExceptLanguage *[]string `json:"except_language,omitempty"`
|
||||||
Tags *string `json:"tags,omitempty"`
|
Tags *string `json:"tags,omitempty"`
|
||||||
ExceptTags *string `json:"except_tags,omitempty"`
|
ExceptTags *string `json:"except_tags,omitempty"`
|
||||||
TagsAny *string `json:"tags_any,omitempty"`
|
TagsAny *string `json:"tags_any,omitempty"`
|
||||||
|
@ -297,6 +301,14 @@ func (f Filter) CheckFilter(r *Release) ([]string, bool) {
|
||||||
r.addRejectionF("unwanted uploaders. got: %v unwanted: %v", r.Uploader, f.ExceptUploaders)
|
r.addRejectionF("unwanted uploaders. got: %v unwanted: %v", r.Uploader, f.ExceptUploaders)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(f.MatchLanguage) > 0 && !sliceContainsSlice(r.Language, f.MatchLanguage) {
|
||||||
|
r.addRejectionF("language not matching. got: %v want: %v", r.Language, f.MatchLanguage)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(f.ExceptLanguage) > 0 && sliceContainsSlice(r.Language, f.ExceptLanguage) {
|
||||||
|
r.addRejectionF("language unwanted. got: %v want: %v", r.Language, f.ExceptLanguage)
|
||||||
|
}
|
||||||
|
|
||||||
if len(f.Resolutions) > 0 && !containsSlice(r.Resolution, f.Resolutions) {
|
if len(f.Resolutions) > 0 && !containsSlice(r.Resolution, f.Resolutions) {
|
||||||
r.addRejectionF("resolution not matching. got: %v want: %v", r.Resolution, f.Resolutions)
|
r.addRejectionF("resolution not matching. got: %v want: %v", r.Resolution, f.Resolutions)
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ type Release struct {
|
||||||
AudioChannels string `json:"-"`
|
AudioChannels string `json:"-"`
|
||||||
Group string `json:"group"`
|
Group string `json:"group"`
|
||||||
Region string `json:"-"`
|
Region string `json:"-"`
|
||||||
Language string `json:"-"`
|
Language []string `json:"-"`
|
||||||
Proper bool `json:"proper"`
|
Proper bool `json:"proper"`
|
||||||
Repack bool `json:"repack"`
|
Repack bool `json:"repack"`
|
||||||
Website string `json:"website"`
|
Website string `json:"website"`
|
||||||
|
@ -203,6 +203,7 @@ func (r *Release) ParseString(title string) {
|
||||||
r.HDR = rel.HDR
|
r.HDR = rel.HDR
|
||||||
r.Other = rel.Other
|
r.Other = rel.Other
|
||||||
r.Artists = rel.Artist
|
r.Artists = rel.Artist
|
||||||
|
r.Language = rel.Language
|
||||||
|
|
||||||
if r.Season == 0 {
|
if r.Season == 0 {
|
||||||
r.Season = rel.Series
|
r.Season = rel.Series
|
||||||
|
|
|
@ -260,6 +260,7 @@ func TestRelease_Parse(t *testing.T) {
|
||||||
Year: 2022,
|
Year: 2022,
|
||||||
Group: "GROUP1",
|
Group: "GROUP1",
|
||||||
Season: 1,
|
Season: 1,
|
||||||
|
Language: []string{"ENGLiSH"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -733,7 +734,7 @@ func TestRelease_DownloadTorrentFile(t *testing.T) {
|
||||||
AudioChannels string
|
AudioChannels string
|
||||||
Group string
|
Group string
|
||||||
Region string
|
Region string
|
||||||
Language string
|
Language []string
|
||||||
Proper bool
|
Proper bool
|
||||||
Repack bool
|
Repack bool
|
||||||
Website string
|
Website string
|
||||||
|
|
|
@ -64,7 +64,7 @@ func TestRSSJob_processItem(t *testing.T) {
|
||||||
Link: "/details.php?id=00000&hit=1",
|
Link: "/details.php?id=00000&hit=1",
|
||||||
GUID: "Some.Release.Title.2022.09.22.720p.WEB.h264-GROUP",
|
GUID: "Some.Release.Title.2022.09.22.720p.WEB.h264-GROUP",
|
||||||
}},
|
}},
|
||||||
want: &domain.Release{ID: 0, FilterStatus: "PENDING", Rejections: []string{}, Indexer: "mock-feed", FilterName: "", Protocol: "torrent", Implementation: "RSS", Timestamp: now, GroupID: "", TorrentID: "", TorrentURL: "https://fake-feed.com/details.php?id=00000&hit=1", TorrentTmpFile: "", TorrentDataRawBytes: []uint8(nil), TorrentHash: "", TorrentName: "Some.Release.Title.2022.09.22.720p.WEB.h264-GROUP", Size: 0x0, Title: "Some Release Title", Category: "", Season: 0, Episode: 0, Year: 2022, Resolution: "720p", Source: "WEB", Codec: []string{"H.264"}, Container: "", HDR: []string(nil), Audio: []string(nil), AudioChannels: "", Group: "GROUP", Region: "", Language: "", Proper: false, Repack: false, Website: "", Artists: "", Type: "", LogScore: 0, IsScene: false, Origin: "", Tags: []string{}, ReleaseTags: "", Freeleech: false, FreeleechPercent: 0, Bonus: []string(nil), Uploader: "", PreTime: "", Other: []string(nil), RawCookie: "", AdditionalSizeCheckRequired: false, FilterID: 0, Filter: (*domain.Filter)(nil), ActionStatus: []domain.ReleaseActionStatus(nil)},
|
want: &domain.Release{ID: 0, FilterStatus: "PENDING", Rejections: []string{}, Indexer: "mock-feed", FilterName: "", Protocol: "torrent", Implementation: "RSS", Timestamp: now, GroupID: "", TorrentID: "", TorrentURL: "https://fake-feed.com/details.php?id=00000&hit=1", TorrentTmpFile: "", TorrentDataRawBytes: []uint8(nil), TorrentHash: "", TorrentName: "Some.Release.Title.2022.09.22.720p.WEB.h264-GROUP", Size: 0x0, Title: "Some Release Title", Category: "", Season: 0, Episode: 0, Year: 2022, Resolution: "720p", Source: "WEB", Codec: []string{"H.264"}, Container: "", HDR: []string(nil), Audio: []string(nil), AudioChannels: "", Group: "GROUP", Region: "", Language: nil, Proper: false, Repack: false, Website: "", Artists: "", Type: "", LogScore: 0, IsScene: false, Origin: "", Tags: []string{}, ReleaseTags: "", Freeleech: false, FreeleechPercent: 0, Bonus: []string(nil), Uploader: "", PreTime: "", Other: []string(nil), RawCookie: "", AdditionalSizeCheckRequired: false, FilterID: 0, Filter: (*domain.Filter)(nil), ActionStatus: []domain.ReleaseActionStatus(nil)},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "with_baseurl",
|
name: "with_baseurl",
|
||||||
|
@ -93,7 +93,7 @@ func TestRSSJob_processItem(t *testing.T) {
|
||||||
Link: "https://fake-feed.com/details.php?id=00000&hit=1",
|
Link: "https://fake-feed.com/details.php?id=00000&hit=1",
|
||||||
GUID: "Some.Release.Title.2022.09.22.720p.WEB.h264-GROUP",
|
GUID: "Some.Release.Title.2022.09.22.720p.WEB.h264-GROUP",
|
||||||
}},
|
}},
|
||||||
want: &domain.Release{ID: 0, FilterStatus: "PENDING", Rejections: []string{}, Indexer: "mock-feed", FilterName: "", Protocol: "torrent", Implementation: "RSS", Timestamp: now, GroupID: "", TorrentID: "", TorrentURL: "https://fake-feed.com/details.php?id=00000&hit=1", TorrentTmpFile: "", TorrentDataRawBytes: []uint8(nil), TorrentHash: "", TorrentName: "Some.Release.Title.2022.09.22.720p.WEB.h264-GROUP", Size: 0x0, Title: "Some Release Title", Category: "", Season: 0, Episode: 0, Year: 2022, Resolution: "720p", Source: "WEB", Codec: []string{"H.264"}, Container: "", HDR: []string(nil), Audio: []string(nil), AudioChannels: "", Group: "GROUP", Region: "", Language: "", Proper: false, Repack: false, Website: "", Artists: "", Type: "", LogScore: 0, IsScene: false, Origin: "", Tags: []string{}, ReleaseTags: "", Freeleech: false, FreeleechPercent: 0, Bonus: []string(nil), Uploader: "", PreTime: "", Other: []string(nil), RawCookie: "", AdditionalSizeCheckRequired: false, FilterID: 0, Filter: (*domain.Filter)(nil), ActionStatus: []domain.ReleaseActionStatus(nil)},
|
want: &domain.Release{ID: 0, FilterStatus: "PENDING", Rejections: []string{}, Indexer: "mock-feed", FilterName: "", Protocol: "torrent", Implementation: "RSS", Timestamp: now, GroupID: "", TorrentID: "", TorrentURL: "https://fake-feed.com/details.php?id=00000&hit=1", TorrentTmpFile: "", TorrentDataRawBytes: []uint8(nil), TorrentHash: "", TorrentName: "Some.Release.Title.2022.09.22.720p.WEB.h264-GROUP", Size: 0x0, Title: "Some Release Title", Category: "", Season: 0, Episode: 0, Year: 2022, Resolution: "720p", Source: "WEB", Codec: []string{"H.264"}, Container: "", HDR: []string(nil), Audio: []string(nil), AudioChannels: "", Group: "GROUP", Region: "", Language: nil, Proper: false, Repack: false, Website: "", Artists: "", Type: "", LogScore: 0, IsScene: false, Origin: "", Tags: []string{}, ReleaseTags: "", Freeleech: false, FreeleechPercent: 0, Bonus: []string(nil), Uploader: "", PreTime: "", Other: []string(nil), RawCookie: "", AdditionalSizeCheckRequired: false, FilterID: 0, Filter: (*domain.Filter)(nil), ActionStatus: []domain.ReleaseActionStatus(nil)},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "time_parse",
|
name: "time_parse",
|
||||||
|
@ -123,7 +123,7 @@ func TestRSSJob_processItem(t *testing.T) {
|
||||||
GUID: "Some.Release.Title.2022.09.22.720p.WEB.h264-GROUP",
|
GUID: "Some.Release.Title.2022.09.22.720p.WEB.h264-GROUP",
|
||||||
//PublishedParsed: &nowMinusTime,
|
//PublishedParsed: &nowMinusTime,
|
||||||
}},
|
}},
|
||||||
want: &domain.Release{ID: 0, FilterStatus: "PENDING", Rejections: []string{}, Indexer: "mock-feed", FilterName: "", Protocol: "torrent", Implementation: "RSS", Timestamp: now, GroupID: "", TorrentID: "", TorrentURL: "https://fake-feed.com/details.php?id=00000&hit=1", TorrentTmpFile: "", TorrentDataRawBytes: []uint8(nil), TorrentHash: "", TorrentName: "Some.Release.Title.2022.09.22.720p.WEB.h264-GROUP", Size: 0x0, Title: "Some Release Title", Category: "", Season: 0, Episode: 0, Year: 2022, Resolution: "720p", Source: "WEB", Codec: []string{"H.264"}, Container: "", HDR: []string(nil), Audio: []string(nil), AudioChannels: "", Group: "GROUP", Region: "", Language: "", Proper: false, Repack: false, Website: "", Artists: "", Type: "", LogScore: 0, IsScene: false, Origin: "", Tags: []string{}, ReleaseTags: "", Freeleech: false, FreeleechPercent: 0, Bonus: []string(nil), Uploader: "", PreTime: "", Other: []string(nil), RawCookie: "", AdditionalSizeCheckRequired: false, FilterID: 0, Filter: (*domain.Filter)(nil), ActionStatus: []domain.ReleaseActionStatus(nil)},
|
want: &domain.Release{ID: 0, FilterStatus: "PENDING", Rejections: []string{}, Indexer: "mock-feed", FilterName: "", Protocol: "torrent", Implementation: "RSS", Timestamp: now, GroupID: "", TorrentID: "", TorrentURL: "https://fake-feed.com/details.php?id=00000&hit=1", TorrentTmpFile: "", TorrentDataRawBytes: []uint8(nil), TorrentHash: "", TorrentName: "Some.Release.Title.2022.09.22.720p.WEB.h264-GROUP", Size: 0x0, Title: "Some Release Title", Category: "", Season: 0, Episode: 0, Year: 2022, Resolution: "720p", Source: "WEB", Codec: []string{"H.264"}, Container: "", HDR: []string(nil), Audio: []string(nil), AudioChannels: "", Group: "GROUP", Region: "", Language: nil, Proper: false, Repack: false, Website: "", Artists: "", Type: "", LogScore: 0, IsScene: false, Origin: "", Tags: []string{}, ReleaseTags: "", Freeleech: false, FreeleechPercent: 0, Bonus: []string(nil), Uploader: "", PreTime: "", Other: []string(nil), RawCookie: "", AdditionalSizeCheckRequired: false, FilterID: 0, Filter: (*domain.Filter)(nil), ActionStatus: []domain.ReleaseActionStatus(nil)},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "time_parse",
|
name: "time_parse",
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package torznab
|
package torznab
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
@ -232,7 +233,7 @@ func TestClient_GetCaps(t *testing.T) {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
c := NewClient(Config{Host: tt.fields.Host, ApiKey: tt.fields.ApiKey})
|
c := NewClient(Config{Host: tt.fields.Host, ApiKey: tt.fields.ApiKey})
|
||||||
|
|
||||||
got, err := c.FetchCaps()
|
got, err := c.FetchCaps(context.TODO())
|
||||||
if tt.wantErr && assert.Error(t, err) {
|
if tt.wantErr && assert.Error(t, err) {
|
||||||
assert.EqualErrorf(t, err, tt.expectedErr, "Error should be: %v, got: %v", tt.wantErr, err)
|
assert.EqualErrorf(t, err, tt.expectedErr, "Error should be: %v, got: %v", tt.wantErr, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,6 +154,61 @@ export const originOptions = [
|
||||||
|
|
||||||
export const ORIGIN_OPTIONS = originOptions.map(v => ({ value: v, label: v, key: v }));
|
export const ORIGIN_OPTIONS = originOptions.map(v => ({ value: v, label: v, key: v }));
|
||||||
|
|
||||||
|
export const languageOptions = [
|
||||||
|
"BALTIC",
|
||||||
|
"BRAZiLiAN",
|
||||||
|
"BULGARiAN",
|
||||||
|
"CHiNESE",
|
||||||
|
"CHS",
|
||||||
|
"CHT",
|
||||||
|
"CZECH",
|
||||||
|
"DANiSH",
|
||||||
|
"DUBBED",
|
||||||
|
"DKSUBS",
|
||||||
|
"DUTCH",
|
||||||
|
"ENGLiSH",
|
||||||
|
"ESTONiAN",
|
||||||
|
"FLEMiSH",
|
||||||
|
"FiNNiSH",
|
||||||
|
"FRENCH",
|
||||||
|
"GERMAN",
|
||||||
|
"GREEK",
|
||||||
|
"HAiTiAN",
|
||||||
|
"HARDSUB",
|
||||||
|
"Hardcoded",
|
||||||
|
"HEBREW",
|
||||||
|
"HebSub",
|
||||||
|
"HiNDi",
|
||||||
|
"HUNGARiAN",
|
||||||
|
"iCELANDiC",
|
||||||
|
"iTALiAN",
|
||||||
|
"JAPANESE",
|
||||||
|
"KOREAN",
|
||||||
|
"LATiN",
|
||||||
|
"MANDARiN",
|
||||||
|
"MULTi",
|
||||||
|
"MULTILANG",
|
||||||
|
"MULTiSUB",
|
||||||
|
"MULTiSUBS",
|
||||||
|
"NORDiC",
|
||||||
|
"NORWEGiAN",
|
||||||
|
"POLiSH",
|
||||||
|
"PORTUGUESE",
|
||||||
|
"ROMANiAN",
|
||||||
|
"RUSSiAN",
|
||||||
|
"SPANiSH",
|
||||||
|
"SUBBED",
|
||||||
|
"SUBFORCED",
|
||||||
|
"SUBPACK",
|
||||||
|
"SWEDiSH",
|
||||||
|
"SYNCED",
|
||||||
|
"TURKiSH",
|
||||||
|
"UKRAiNiAN",
|
||||||
|
"UNSUBBED"
|
||||||
|
];
|
||||||
|
|
||||||
|
export const LANGUAGE_OPTIONS = languageOptions.map(v => ({ value: v, label: v, key: v }));
|
||||||
|
|
||||||
export interface RadioFieldsetOption {
|
export interface RadioFieldsetOption {
|
||||||
label: string;
|
label: string;
|
||||||
description: string;
|
description: string;
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
downloadsPerUnitOptions,
|
downloadsPerUnitOptions,
|
||||||
FORMATS_OPTIONS,
|
FORMATS_OPTIONS,
|
||||||
HDR_OPTIONS,
|
HDR_OPTIONS,
|
||||||
|
LANGUAGE_OPTIONS,
|
||||||
ORIGIN_OPTIONS,
|
ORIGIN_OPTIONS,
|
||||||
OTHER_OPTIONS,
|
OTHER_OPTIONS,
|
||||||
QUALITY_MUSIC_OPTIONS,
|
QUALITY_MUSIC_OPTIONS,
|
||||||
|
@ -265,6 +266,8 @@ export default function FilterDetails() {
|
||||||
except_tags: filter.except_tags,
|
except_tags: filter.except_tags,
|
||||||
match_uploaders: filter.match_uploaders,
|
match_uploaders: filter.match_uploaders,
|
||||||
except_uploaders: filter.except_uploaders,
|
except_uploaders: filter.except_uploaders,
|
||||||
|
match_language: filter.match_language || [],
|
||||||
|
except_language: filter.except_language || [],
|
||||||
freeleech: filter.freeleech,
|
freeleech: filter.freeleech,
|
||||||
freeleech_percent: filter.freeleech_percent,
|
freeleech_percent: filter.freeleech_percent,
|
||||||
formats: filter.formats || [],
|
formats: filter.formats || [],
|
||||||
|
@ -516,6 +519,11 @@ export function Advanced({ values }: AdvancedProps) {
|
||||||
<TextField name="except_uploaders" label="Except uploaders" columns={6} placeholder="eg. anonymous" />
|
<TextField name="except_uploaders" label="Except uploaders" columns={6} placeholder="eg. anonymous" />
|
||||||
</CollapsableSection>
|
</CollapsableSection>
|
||||||
|
|
||||||
|
<CollapsableSection defaultOpen={true} title="Language" subtitle="Match or ignore languages.">
|
||||||
|
<MultiSelect name="match_language" options={LANGUAGE_OPTIONS} label="Match Language" columns={6} creatable={true} />
|
||||||
|
<MultiSelect name="except_language" options={LANGUAGE_OPTIONS} label="Except Language" columns={6} creatable={true} />
|
||||||
|
</CollapsableSection>
|
||||||
|
|
||||||
<CollapsableSection defaultOpen={true} title="Origins" subtitle="Match Internals, scene, p2p etc. if announced.">
|
<CollapsableSection defaultOpen={true} title="Origins" subtitle="Match Internals, scene, p2p etc. if announced.">
|
||||||
<MultiSelect name="origins" options={ORIGIN_OPTIONS} label="Match Origins" columns={6} creatable={true} />
|
<MultiSelect name="origins" options={ORIGIN_OPTIONS} label="Match Origins" columns={6} creatable={true} />
|
||||||
<MultiSelect name="except_origins" options={ORIGIN_OPTIONS} label="Except Origins" columns={6} creatable={true} />
|
<MultiSelect name="except_origins" options={ORIGIN_OPTIONS} label="Except Origins" columns={6} creatable={true} />
|
||||||
|
|
2
web/src/types/Filter.d.ts
vendored
2
web/src/types/Filter.d.ts
vendored
|
@ -51,6 +51,8 @@ interface Filter {
|
||||||
except_categories: string;
|
except_categories: string;
|
||||||
match_uploaders: string;
|
match_uploaders: string;
|
||||||
except_uploaders: string;
|
except_uploaders: string;
|
||||||
|
match_language: string[];
|
||||||
|
except_language: string[];
|
||||||
tags: string;
|
tags: string;
|
||||||
except_tags: string;
|
except_tags: string;
|
||||||
tags_any: string;
|
tags_any: string;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue