diff --git a/internal/database/filter.go b/internal/database/filter.go
index b56999a..9b62bf1 100644
--- a/internal/database/filter.go
+++ b/internal/database/filter.go
@@ -217,6 +217,8 @@ func (r *FilterRepo) FindByID(ctx context.Context, filterID int) (*domain.Filter
"except_categories",
"match_uploaders",
"except_uploaders",
+ "match_language",
+ "except_language",
"tags",
"except_tags",
"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 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")
}
@@ -378,6 +380,8 @@ func (r *FilterRepo) findByIndexerIdentifier(ctx context.Context, tx *Tx, indexe
"f.except_categories",
"f.match_uploaders",
"f.except_uploaders",
+ "f.match_language",
+ "f.except_language",
"f.tags",
"f.except_tags",
"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 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")
}
@@ -513,6 +517,8 @@ func (r *FilterRepo) Store(ctx context.Context, filter domain.Filter) (*domain.F
"except_categories",
"match_uploaders",
"except_uploaders",
+ "match_language",
+ "except_language",
"tags",
"except_tags",
"artists",
@@ -573,6 +579,8 @@ func (r *FilterRepo) Store(ctx context.Context, filter domain.Filter) (*domain.F
filter.ExceptCategories,
filter.MatchUploaders,
filter.ExceptUploaders,
+ pq.Array(filter.MatchLanguage),
+ pq.Array(filter.ExceptLanguage),
filter.Tags,
filter.ExceptTags,
filter.Artists,
@@ -652,6 +660,8 @@ func (r *FilterRepo) Update(ctx context.Context, filter domain.Filter) (*domain.
Set("except_categories", filter.ExceptCategories).
Set("match_uploaders", filter.MatchUploaders).
Set("except_uploaders", filter.ExceptUploaders).
+ Set("match_language", pq.Array(filter.MatchLanguage)).
+ Set("except_language", pq.Array(filter.ExceptLanguage)).
Set("tags", filter.Tags).
Set("except_tags", filter.ExceptTags).
Set("artists", filter.Artists).
@@ -803,6 +813,12 @@ func (r *FilterRepo) UpdatePartial(ctx context.Context, filter domain.FilterUpda
if filter.ExceptUploaders != nil {
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 {
q = q.Set("tags", filter.Tags)
}
diff --git a/internal/database/postgres_migrate.go b/internal/database/postgres_migrate.go
index 407082f..c2cf4f5 100644
--- a/internal/database/postgres_migrate.go
+++ b/internal/database/postgres_migrate.go
@@ -111,6 +111,8 @@ CREATE TABLE filter
except_categories TEXT,
match_uploaders TEXT,
except_uploaders TEXT,
+ match_language TEXT [] DEFAULT '{}',
+ except_language TEXT [] DEFAULT '{}',
tags TEXT,
except_tags TEXT,
origins TEXT [] DEFAULT '{}',
@@ -623,4 +625,10 @@ CREATE INDEX indexer_identifier_index
`ALTER TABLE "filter"
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 '{}';
+ `,
}
diff --git a/internal/database/sqlite_migrate.go b/internal/database/sqlite_migrate.go
index 7850c08..b856836 100644
--- a/internal/database/sqlite_migrate.go
+++ b/internal/database/sqlite_migrate.go
@@ -111,6 +111,8 @@ CREATE TABLE filter
except_categories TEXT,
match_uploaders TEXT,
except_uploaders TEXT,
+ match_language TEXT [] DEFAULT '{}',
+ except_language TEXT [] DEFAULT '{}',
tags TEXT,
except_tags TEXT,
origins TEXT [] DEFAULT '{}',
@@ -967,4 +969,10 @@ ALTER TABLE irc_network_dg_tmp
`ALTER TABLE "filter"
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 '{}';
+ `,
}
diff --git a/internal/domain/filter.go b/internal/domain/filter.go
index 38d86a3..b295d7a 100644
--- a/internal/domain/filter.go
+++ b/internal/domain/filter.go
@@ -109,6 +109,8 @@ type Filter struct {
ExceptCategories string `json:"except_categories,omitempty"`
MatchUploaders string `json:"match_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"`
ExceptTags string `json:"except_tags,omitempty"`
TagsAny string `json:"tags_any,omitempty"`
@@ -182,6 +184,8 @@ type FilterUpdate struct {
ExceptCategories *string `json:"except_categories,omitempty"`
MatchUploaders *string `json:"match_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"`
ExceptTags *string `json:"except_tags,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)
}
+ 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) {
r.addRejectionF("resolution not matching. got: %v want: %v", r.Resolution, f.Resolutions)
}
diff --git a/internal/domain/release.go b/internal/domain/release.go
index ae71445..7b88c30 100644
--- a/internal/domain/release.go
+++ b/internal/domain/release.go
@@ -67,7 +67,7 @@ type Release struct {
AudioChannels string `json:"-"`
Group string `json:"group"`
Region string `json:"-"`
- Language string `json:"-"`
+ Language []string `json:"-"`
Proper bool `json:"proper"`
Repack bool `json:"repack"`
Website string `json:"website"`
@@ -203,6 +203,7 @@ func (r *Release) ParseString(title string) {
r.HDR = rel.HDR
r.Other = rel.Other
r.Artists = rel.Artist
+ r.Language = rel.Language
if r.Season == 0 {
r.Season = rel.Series
diff --git a/internal/domain/release_test.go b/internal/domain/release_test.go
index 38e7d1e..251b61b 100644
--- a/internal/domain/release_test.go
+++ b/internal/domain/release_test.go
@@ -260,6 +260,7 @@ func TestRelease_Parse(t *testing.T) {
Year: 2022,
Group: "GROUP1",
Season: 1,
+ Language: []string{"ENGLiSH"},
},
},
}
@@ -733,7 +734,7 @@ func TestRelease_DownloadTorrentFile(t *testing.T) {
AudioChannels string
Group string
Region string
- Language string
+ Language []string
Proper bool
Repack bool
Website string
diff --git a/internal/feed/rss_test.go b/internal/feed/rss_test.go
index 4e83234..13e9014 100644
--- a/internal/feed/rss_test.go
+++ b/internal/feed/rss_test.go
@@ -64,7 +64,7 @@ func TestRSSJob_processItem(t *testing.T) {
Link: "/details.php?id=00000&hit=1",
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",
@@ -93,7 +93,7 @@ func TestRSSJob_processItem(t *testing.T) {
Link: "https://fake-feed.com/details.php?id=00000&hit=1",
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",
@@ -123,7 +123,7 @@ func TestRSSJob_processItem(t *testing.T) {
GUID: "Some.Release.Title.2022.09.22.720p.WEB.h264-GROUP",
//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",
diff --git a/pkg/torznab/torznab_test.go b/pkg/torznab/torznab_test.go
index 8dbe8af..f3c8d86 100644
--- a/pkg/torznab/torznab_test.go
+++ b/pkg/torznab/torznab_test.go
@@ -1,6 +1,7 @@
package torznab
import (
+ "context"
"encoding/xml"
"net/http"
"net/http/httptest"
@@ -232,7 +233,7 @@ func TestClient_GetCaps(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
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) {
assert.EqualErrorf(t, err, tt.expectedErr, "Error should be: %v, got: %v", tt.wantErr, err)
}
diff --git a/web/src/domain/constants.ts b/web/src/domain/constants.ts
index efab677..16a43f2 100644
--- a/web/src/domain/constants.ts
+++ b/web/src/domain/constants.ts
@@ -154,6 +154,61 @@ export const originOptions = [
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 {
label: string;
description: string;
diff --git a/web/src/screens/filters/details.tsx b/web/src/screens/filters/details.tsx
index b151755..69752ba 100644
--- a/web/src/screens/filters/details.tsx
+++ b/web/src/screens/filters/details.tsx
@@ -11,6 +11,7 @@ import {
downloadsPerUnitOptions,
FORMATS_OPTIONS,
HDR_OPTIONS,
+ LANGUAGE_OPTIONS,
ORIGIN_OPTIONS,
OTHER_OPTIONS,
QUALITY_MUSIC_OPTIONS,
@@ -265,6 +266,8 @@ export default function FilterDetails() {
except_tags: filter.except_tags,
match_uploaders: filter.match_uploaders,
except_uploaders: filter.except_uploaders,
+ match_language: filter.match_language || [],
+ except_language: filter.except_language || [],
freeleech: filter.freeleech,
freeleech_percent: filter.freeleech_percent,
formats: filter.formats || [],
@@ -516,6 +519,11 @@ export function Advanced({ values }: AdvancedProps) {
+
+
+
+
+
diff --git a/web/src/types/Filter.d.ts b/web/src/types/Filter.d.ts
index fbb3c92..5559d3b 100644
--- a/web/src/types/Filter.d.ts
+++ b/web/src/types/Filter.d.ts
@@ -51,6 +51,8 @@ interface Filter {
except_categories: string;
match_uploaders: string;
except_uploaders: string;
+ match_language: string[];
+ except_language: string[];
tags: string;
except_tags: string;
tags_any: string;