feat(filters): implement AnnounceType (#1837)

* feat(filters): implement AnnounceType

* fix: rss tests
This commit is contained in:
ze0s 2024-12-08 21:08:24 +01:00 committed by GitHub
parent ec85d53d8f
commit f644b3a4d6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 155 additions and 17 deletions

View file

@ -175,6 +175,7 @@ func (r *FilterRepo) FindByID(ctx context.Context, filterID int) (*domain.Filter
"f.max_size",
"f.delay",
"f.priority",
"f.announce_types",
"f.max_downloads",
"f.max_downloads_unit",
"f.match_releases",
@ -267,6 +268,7 @@ func (r *FilterRepo) FindByID(ctx context.Context, filterID int) (*domain.Filter
&maxSize,
&delay,
&f.Priority,
pq.Array(&f.AnnounceTypes),
&maxDownloads,
&maxDownloadsUnit,
&matchReleases,
@ -391,6 +393,7 @@ func (r *FilterRepo) findByIndexerIdentifier(ctx context.Context, indexer string
"f.max_size",
"f.delay",
"f.priority",
"f.announce_types",
"f.max_downloads",
"f.max_downloads_unit",
"f.match_releases",
@ -488,6 +491,7 @@ func (r *FilterRepo) findByIndexerIdentifier(ctx context.Context, indexer string
&maxSize,
&delay,
&f.Priority,
pq.Array(&f.AnnounceTypes),
&maxDownloads,
&maxDownloadsUnit,
&matchReleases,
@ -693,6 +697,7 @@ func (r *FilterRepo) Store(ctx context.Context, filter *domain.Filter) error {
"max_size",
"delay",
"priority",
"announce_types",
"max_downloads",
"max_downloads_unit",
"match_releases",
@ -758,6 +763,7 @@ func (r *FilterRepo) Store(ctx context.Context, filter *domain.Filter) error {
filter.MaxSize,
filter.Delay,
filter.Priority,
pq.Array(filter.AnnounceTypes),
filter.MaxDownloads,
filter.MaxDownloadsUnit,
filter.MatchReleases,
@ -841,6 +847,7 @@ func (r *FilterRepo) Update(ctx context.Context, filter *domain.Filter) error {
Set("max_size", filter.MaxSize).
Set("delay", filter.Delay).
Set("priority", filter.Priority).
Set("announce_types", pq.Array(filter.AnnounceTypes)).
Set("max_downloads", filter.MaxDownloads).
Set("max_downloads_unit", filter.MaxDownloadsUnit).
Set("use_regex", filter.UseRegex).
@ -943,6 +950,9 @@ func (r *FilterRepo) UpdatePartial(ctx context.Context, filter domain.FilterUpda
if filter.Priority != nil {
q = q.Set("priority", filter.Priority)
}
if filter.AnnounceTypes != nil {
q = q.Set("announce_types", pq.Array(filter.AnnounceTypes))
}
if filter.MaxDownloads != nil {
q = q.Set("max_downloads", filter.MaxDownloads)
}

View file

@ -99,6 +99,7 @@ CREATE TABLE filter
priority INTEGER DEFAULT 0 NOT NULL,
max_downloads INTEGER DEFAULT 0,
max_downloads_unit TEXT,
announce_types TEXT [] DEFAULT '{}',
match_releases TEXT,
except_releases TEXT,
use_regex BOOLEAN,
@ -261,6 +262,7 @@ CREATE TABLE "release"
protocol TEXT,
implementation TEXT,
timestamp TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
announce_type TEXT DEFAULT 'NEW',
info_url TEXT,
download_url TEXT,
group_id TEXT,
@ -994,5 +996,11 @@ UPDATE irc_network
`UPDATE irc_network
SET port = '6697', tls = true
WHERE server = 'irc.seedpool.org';
`,
`ALTER TABLE "release"
ADD COLUMN announce_type TEXT DEFAULT 'NEW';
ALTER TABLE filter
ADD COLUMN announce_types TEXT [] DEFAULT '{}';
`,
}

View file

@ -38,8 +38,8 @@ func (repo *ReleaseRepo) Store(ctx context.Context, r *domain.Release) error {
queryBuilder := repo.db.squirrel.
Insert("release").
Columns("filter_status", "rejections", "indexer", "filter", "protocol", "implementation", "timestamp", "group_id", "torrent_id", "info_url", "download_url", "torrent_name", "size", "title", "category", "season", "episode", "year", "month", "day", "resolution", "source", "codec", "container", "hdr", "release_group", "proper", "repack", "website", "type", "origin", "tags", "uploader", "pre_time", "filter_id").
Values(r.FilterStatus, pq.Array(r.Rejections), r.Indexer.Identifier, r.FilterName, r.Protocol, r.Implementation, r.Timestamp.Format(time.RFC3339), r.GroupID, r.TorrentID, r.InfoURL, r.DownloadURL, r.TorrentName, r.Size, r.Title, r.Category, r.Season, r.Episode, r.Year, r.Month, r.Day, r.Resolution, r.Source, codecStr, r.Container, hdrStr, r.Group, r.Proper, r.Repack, r.Website, r.Type, r.Origin, pq.Array(r.Tags), r.Uploader, r.PreTime, r.FilterID).
Columns("filter_status", "rejections", "indexer", "filter", "protocol", "implementation", "timestamp", "announce_type", "group_id", "torrent_id", "info_url", "download_url", "torrent_name", "size", "title", "category", "season", "episode", "year", "month", "day", "resolution", "source", "codec", "container", "hdr", "release_group", "proper", "repack", "website", "type", "origin", "tags", "uploader", "pre_time", "filter_id").
Values(r.FilterStatus, pq.Array(r.Rejections), r.Indexer.Identifier, r.FilterName, r.Protocol, r.Implementation, r.Timestamp.Format(time.RFC3339), r.AnnounceType, r.GroupID, r.TorrentID, r.InfoURL, r.DownloadURL, r.TorrentName, r.Size, r.Title, r.Category, r.Season, r.Episode, r.Year, r.Month, r.Day, r.Resolution, r.Source, codecStr, r.Container, hdrStr, r.Group, r.Proper, r.Repack, r.Website, r.Type, r.Origin, pq.Array(r.Tags), r.Uploader, r.PreTime, r.FilterID).
Suffix("RETURNING id").RunWith(repo.db.handler)
// return values
@ -230,7 +230,7 @@ func (repo *ReleaseRepo) findReleases(ctx context.Context, tx *Tx, params domain
}
queryBuilder := repo.db.squirrel.
Select("r.id", "r.filter_status", "r.rejections", "r.indexer", "i.id", "i.name", "i.identifier_external", "r.filter", "r.protocol", "r.info_url", "r.download_url", "r.title", "r.torrent_name", "r.size", "r.category", "r.season", "r.episode", "r.year", "r.resolution", "r.source", "r.codec", "r.container", "r.release_group", "r.timestamp",
Select("r.id", "r.filter_status", "r.rejections", "r.indexer", "i.id", "i.name", "i.identifier_external", "r.filter", "r.protocol", "r.announce_type", "r.info_url", "r.download_url", "r.title", "r.torrent_name", "r.size", "r.category", "r.season", "r.episode", "r.year", "r.resolution", "r.source", "r.codec", "r.container", "r.release_group", "r.timestamp",
"ras.id", "ras.status", "ras.action", "ras.action_id", "ras.type", "ras.client", "ras.filter", "ras.filter_id", "ras.release_id", "ras.rejections", "ras.timestamp").
Column(sq.Alias(countQuery, "page_total")).
From("release r").
@ -267,7 +267,7 @@ func (repo *ReleaseRepo) findReleases(ctx context.Context, tx *Tx, params domain
var rls domain.Release
var ras domain.ReleaseActionStatus
var rlsIndexer, rlsIndexerName, rlsIndexerExternalName, rlsFilter, infoUrl, downloadUrl, codec sql.NullString
var rlsIndexer, rlsIndexerName, rlsIndexerExternalName, rlsFilter, rlsAnnounceType, infoUrl, downloadUrl, codec sql.NullString
var rlsIndexerID sql.NullInt64
var rasId, rasFilterId, rasReleaseId, rasActionId sql.NullInt64
@ -275,7 +275,7 @@ func (repo *ReleaseRepo) findReleases(ctx context.Context, tx *Tx, params domain
var rasRejections []sql.NullString
var rasTimestamp sql.NullTime
if err := rows.Scan(&rls.ID, &rls.FilterStatus, pq.Array(&rls.Rejections), &rlsIndexer, &rlsIndexerID, &rlsIndexerName, &rlsIndexerExternalName, &rlsFilter, &rls.Protocol, &infoUrl, &downloadUrl, &rls.Title, &rls.TorrentName, &rls.Size, &rls.Category, &rls.Season, &rls.Episode, &rls.Year, &rls.Resolution, &rls.Source, &codec, &rls.Container, &rls.Group, &rls.Timestamp, &rasId, &rasStatus, &rasAction, &rasActionId, &rasType, &rasClient, &rasFilter, &rasFilterId, &rasReleaseId, pq.Array(&rasRejections), &rasTimestamp, &resp.TotalCount); err != nil {
if err := rows.Scan(&rls.ID, &rls.FilterStatus, pq.Array(&rls.Rejections), &rlsIndexer, &rlsIndexerID, &rlsIndexerName, &rlsIndexerExternalName, &rlsFilter, &rls.Protocol, &rlsAnnounceType, &infoUrl, &downloadUrl, &rls.Title, &rls.TorrentName, &rls.Size, &rls.Category, &rls.Season, &rls.Episode, &rls.Year, &rls.Resolution, &rls.Source, &codec, &rls.Container, &rls.Group, &rls.Timestamp, &rasId, &rasStatus, &rasAction, &rasActionId, &rasType, &rasClient, &rasFilter, &rasFilterId, &rasReleaseId, pq.Array(&rasRejections), &rasTimestamp, &resp.TotalCount); err != nil {
return resp, errors.Wrap(err, "error scanning row")
}
@ -320,6 +320,7 @@ func (repo *ReleaseRepo) findReleases(ctx context.Context, tx *Tx, params domain
rls.Indexer.IdentifierExternal = rlsIndexerExternalName.String
rls.FilterName = rlsFilter.String
rls.AnnounceType = domain.AnnounceType(rlsAnnounceType.String)
rls.ActionStatus = make([]domain.ReleaseActionStatus, 0)
rls.InfoURL = infoUrl.String
rls.DownloadURL = downloadUrl.String
@ -419,7 +420,7 @@ func (repo *ReleaseRepo) GetActionStatusByReleaseID(ctx context.Context, release
func (repo *ReleaseRepo) Get(ctx context.Context, req *domain.GetReleaseRequest) (*domain.Release, error) {
queryBuilder := repo.db.squirrel.
Select("r.id", "r.filter_status", "r.rejections", "r.indexer", "r.filter", "r.filter_id", "r.protocol", "r.implementation", "r.info_url", "r.download_url", "r.title", "r.torrent_name", "r.category", "r.size", "r.group_id", "r.torrent_id", "r.uploader", "r.timestamp").
Select("r.id", "r.filter_status", "r.rejections", "r.indexer", "r.filter", "r.filter_id", "r.protocol", "r.implementation", "r.announce_type", "r.info_url", "r.download_url", "r.title", "r.torrent_name", "r.category", "r.size", "r.group_id", "r.torrent_id", "r.uploader", "r.timestamp").
From("release r").
OrderBy("r.id DESC").
Where(sq.Eq{"r.id": req.Id})
@ -438,10 +439,10 @@ func (repo *ReleaseRepo) Get(ctx context.Context, req *domain.GetReleaseRequest)
var rls domain.Release
var indexerName, filterName, infoUrl, downloadUrl, groupId, torrentId, category, uploader sql.NullString
var indexerName, filterName, announceType, infoUrl, downloadUrl, groupId, torrentId, category, uploader sql.NullString
var filterId sql.NullInt64
if err := row.Scan(&rls.ID, &rls.FilterStatus, pq.Array(&rls.Rejections), &indexerName, &filterName, &filterId, &rls.Protocol, &rls.Implementation, &infoUrl, &downloadUrl, &rls.Title, &rls.TorrentName, &category, &rls.Size, &groupId, &torrentId, &uploader, &rls.Timestamp); err != nil {
if err := row.Scan(&rls.ID, &rls.FilterStatus, pq.Array(&rls.Rejections), &indexerName, &filterName, &filterId, &rls.Protocol, &rls.Implementation, &announceType, &infoUrl, &downloadUrl, &rls.Title, &rls.TorrentName, &category, &rls.Size, &groupId, &torrentId, &uploader, &rls.Timestamp); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, domain.ErrRecordNotFound
}
@ -453,6 +454,7 @@ func (repo *ReleaseRepo) Get(ctx context.Context, req *domain.GetReleaseRequest)
rls.FilterName = filterName.String
rls.FilterID = int(filterId.Int64)
rls.ActionStatus = make([]domain.ReleaseActionStatus, 0)
rls.AnnounceType = domain.AnnounceType(announceType.String)
rls.InfoURL = infoUrl.String
rls.DownloadURL = downloadUrl.String
rls.Category = category.String

View file

@ -99,6 +99,7 @@ CREATE TABLE filter
priority INTEGER DEFAULT 0 NOT NULL,
max_downloads INTEGER DEFAULT 0,
max_downloads_unit TEXT,
announce_types TEXT [] DEFAULT '{}',
match_releases TEXT,
except_releases TEXT,
use_regex BOOLEAN,
@ -264,6 +265,7 @@ CREATE TABLE "release"
protocol TEXT,
implementation TEXT,
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
announce_type TEXT DEFAULT 'NEW',
info_url TEXT,
download_url TEXT,
group_id TEXT,
@ -1636,5 +1638,11 @@ UPDATE irc_network
`UPDATE irc_network
SET port = '6697', tls = true
WHERE server = 'irc.seedpool.org';
`,
`ALTER TABLE "release"
ADD COLUMN announce_type TEXT DEFAULT 'NEW';
ALTER TABLE filter
ADD COLUMN announce_types TEXT [] DEFAULT '{}';
`,
}

View file

@ -107,6 +107,7 @@ type Filter struct {
UseRegex bool `json:"use_regex,omitempty"`
MatchReleaseGroups string `json:"match_release_groups,omitempty"`
ExceptReleaseGroups string `json:"except_release_groups,omitempty"`
AnnounceTypes []string `json:"announce_types,omitempty"`
Scene bool `json:"scene,omitempty"`
Origins []string `json:"origins,omitempty"`
ExceptOrigins []string `json:"except_origins,omitempty"`
@ -222,6 +223,7 @@ type FilterUpdate struct {
MaxSize *string `json:"max_size,omitempty"`
Delay *int `json:"delay,omitempty"`
Priority *int32 `json:"priority,omitempty"`
AnnounceTypes *[]string `json:"announce_types,omitempty"`
MaxDownloads *int `json:"max_downloads,omitempty"`
MaxDownloadsUnit *FilterMaxDownloadsUnit `json:"max_downloads_unit,omitempty"`
MatchReleases *string `json:"match_releases,omitempty"`
@ -385,6 +387,10 @@ func (f *Filter) CheckFilter(r *Release) (*RejectionReasons, bool) {
f.RejectReasons.Add("freeleech percent", r.FreeleechPercent, f.FreeleechPercent)
}
if len(f.AnnounceTypes) > 0 && !basicContainsSlice(string(r.AnnounceType), f.AnnounceTypes) {
f.RejectReasons.Add("match announce type", r.AnnounceType, f.AnnounceTypes)
}
if len(f.Origins) > 0 && !containsSlice(r.Origin, f.Origins) {
f.RejectReasons.Add("match origin", r.Origin, f.Origins)
}

View file

@ -53,6 +53,7 @@ type Release struct {
Protocol ReleaseProtocol `json:"protocol"`
Implementation ReleaseImplementation `json:"implementation"` // irc, rss, api
Timestamp time.Time `json:"timestamp"`
AnnounceType AnnounceType `json:"announce_type"`
InfoURL string `json:"info_url"`
DownloadURL string `json:"download_url"`
MagnetURI string `json:"-"`
@ -114,6 +115,56 @@ func (r *Release) Raw(s string) rls.Release {
return rls.ParseString(s)
}
type AnnounceType string
const (
// AnnounceTypeNew Default announce type
AnnounceTypeNew AnnounceType = "NEW"
// AnnounceTypeChecked Checked release
AnnounceTypeChecked AnnounceType = "CHECKED"
// AnnounceTypePromo Marked as promotion (neutral/half/feeeleech etc.)
AnnounceTypePromo AnnounceType = "PROMO"
// AnnounceTypePromoGP Marked Golden Popcorn, PTP specific
AnnounceTypePromoGP AnnounceType = "PROMO_GP"
// AnnounceTypeResurrect Reseeded/revived from dead
AnnounceTypeResurrect AnnounceType = "RESURRECTED"
)
func (a AnnounceType) String() string {
switch a {
case AnnounceTypeNew:
return "NEW"
case AnnounceTypeChecked:
return "CHECKED"
case AnnounceTypePromo:
return "PROMO"
case AnnounceTypePromoGP:
return "PROMO_GP"
case AnnounceTypeResurrect:
return "RESURRECTED"
}
return ""
}
// ParseAnnounceType parse AnnounceType from string
func ParseAnnounceType(s string) (AnnounceType, error) {
switch s {
case string(AnnounceTypeNew):
return AnnounceTypeNew, nil
case string(AnnounceTypeChecked):
return AnnounceTypeChecked, nil
case string(AnnounceTypePromo):
return AnnounceTypePromo, nil
case string(AnnounceTypePromoGP):
return AnnounceTypePromoGP, nil
case string(AnnounceTypeResurrect):
return AnnounceTypeResurrect, nil
default:
return "", fmt.Errorf("invalid AnnounceType: %s", s)
}
}
type ReleaseActionStatus struct {
ID int64 `json:"id"`
Status ReleasePushStatus `json:"status"`
@ -307,6 +358,7 @@ func NewRelease(indexer IndexerMinimal) *Release {
Timestamp: time.Now(),
Tags: []string{},
Size: 0,
AnnounceType: AnnounceTypeNew,
}
return r
@ -667,7 +719,6 @@ const MagnetURIPrefix = "magnet:?"
// MapVars map vars from regex captures to fields on release
func (r *Release) MapVars(def *IndexerDefinition, varMap map[string]string) error {
if torrentName, err := getStringMapValue(varMap, "torrentName"); err != nil {
return errors.Wrap(err, "failed parsing required field")
} else {
@ -682,6 +733,13 @@ func (r *Release) MapVars(def *IndexerDefinition, varMap map[string]string) erro
r.Category = category
}
if announceType, err := getStringMapValue(varMap, "announceTypeEnum"); err == nil {
annType, parseErr := ParseAnnounceType(announceType)
if parseErr == nil {
r.AnnounceType = annType
}
}
if freeleech, err := getStringMapValue(varMap, "freeleech"); err == nil {
fl := StringEqualFoldMulti(freeleech, "1", "free", "freeleech", "freeleech!", "yes", "VIP", "★")
if fl {

View file

@ -73,7 +73,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: domain.IndexerMinimal{0, "Mock Feed", "mock-feed", "Mock Indexer"}, FilterName: "", Protocol: "torrent", Implementation: "RSS", Timestamp: now, GroupID: "", TorrentID: "", DownloadURL: "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: 1490000000, Title: "Some Release Title", Description: "Category: Example\n Size: 1.49 GB\n Status: 27 seeders and 1 leechers\n Speed: 772.16 kB/s\n Added: 2022-09-29 16:06:08\n", Category: "", Season: 0, Episode: 0, Year: 2022, Month: 9, Day: 22, 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: "episode", LogScore: 0, 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: domain.IndexerMinimal{0, "Mock Feed", "mock-feed", "Mock Indexer"}, FilterName: "", Protocol: "torrent", Implementation: "RSS", AnnounceType: domain.AnnounceTypeNew, Timestamp: now, GroupID: "", TorrentID: "", DownloadURL: "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: 1490000000, Title: "Some Release Title", Description: "Category: Example\n Size: 1.49 GB\n Status: 27 seeders and 1 leechers\n Speed: 772.16 kB/s\n Added: 2022-09-29 16:06:08\n", Category: "", Season: 0, Episode: 0, Year: 2022, Month: 9, Day: 22, 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: "episode", LogScore: 0, 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",
@ -107,7 +107,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: domain.IndexerMinimal{0, "Mock Feed", "mock-feed", "Mock Indexer"}, FilterName: "", Protocol: "torrent", Implementation: "RSS", Timestamp: now, GroupID: "", TorrentID: "", DownloadURL: "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: 1490000000, Title: "Some Release Title", Description: "Category: Example\n Size: 1.49 GB\n Status: 27 seeders and 1 leechers\n Speed: 772.16 kB/s\n Added: 2022-09-29 16:06:08\n", Category: "", Season: 0, Episode: 0, Year: 2022, Month: 9, Day: 22, 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: "episode", LogScore: 0, 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: domain.IndexerMinimal{0, "Mock Feed", "mock-feed", "Mock Indexer"}, FilterName: "", Protocol: "torrent", Implementation: "RSS", AnnounceType: domain.AnnounceTypeNew, Timestamp: now, GroupID: "", TorrentID: "", DownloadURL: "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: 1490000000, Title: "Some Release Title", Description: "Category: Example\n Size: 1.49 GB\n Status: 27 seeders and 1 leechers\n Speed: 772.16 kB/s\n Added: 2022-09-29 16:06:08\n", Category: "", Season: 0, Episode: 0, Year: 2022, Month: 9, Day: 22, 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: "episode", LogScore: 0, 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",
@ -142,7 +142,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: domain.IndexerMinimal{0, "Mock Feed", "mock-feed", "Mock Indexer"}, FilterName: "", Protocol: "torrent", Implementation: "RSS", Timestamp: now, GroupID: "", TorrentID: "", DownloadURL: "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: 1490000000, Title: "Some Release Title", Description: "Category: Example\n Size: 1.49 GB\n Status: 27 seeders and 1 leechers\n Speed: 772.16 kB/s\n Added: 2022-09-29 16:06:08\n", Category: "", Season: 0, Episode: 0, Year: 2022, Month: 9, Day: 22, 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: "episode", LogScore: 0, 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: domain.IndexerMinimal{0, "Mock Feed", "mock-feed", "Mock Indexer"}, FilterName: "", Protocol: "torrent", Implementation: "RSS", AnnounceType: domain.AnnounceTypeNew, Timestamp: now, GroupID: "", TorrentID: "", DownloadURL: "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: 1490000000, Title: "Some Release Title", Description: "Category: Example\n Size: 1.49 GB\n Status: 27 seeders and 1 leechers\n Speed: 772.16 kB/s\n Added: 2022-09-29 16:06:08\n", Category: "", Season: 0, Episode: 0, Year: 2022, Month: 9, Day: 22, 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: "episode", LogScore: 0, 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",
@ -208,7 +208,7 @@ func TestRSSJob_processItem(t *testing.T) {
},
},
}},
want: &domain.Release{ID: 0, FilterStatus: "PENDING", Rejections: []string{}, Indexer: domain.IndexerMinimal{0, "Mock Feed", "mock-feed", "Mock Indexer"}, FilterName: "", Protocol: "torrent", Implementation: "RSS", Timestamp: now, MagnetURI: "magnet:?xt=this-not-a-valid-magnet", GroupID: "", TorrentID: "", DownloadURL: "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: 0, Title: "Some Release Title", Description: "Category: Example", Category: "", Season: 0, Episode: 0, Year: 2022, Month: 9, Day: 22, 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: "episode", LogScore: 0, 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: domain.IndexerMinimal{0, "Mock Feed", "mock-feed", "Mock Indexer"}, FilterName: "", Protocol: "torrent", Implementation: "RSS", AnnounceType: domain.AnnounceTypeNew, Timestamp: now, MagnetURI: "magnet:?xt=this-not-a-valid-magnet", GroupID: "", TorrentID: "", DownloadURL: "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: 0, Title: "Some Release Title", Description: "Category: Example", Category: "", Season: 0, Episode: 0, Year: 2022, Month: 9, Day: 22, 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: "episode", LogScore: 0, 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)},
},
}
for _, tt := range tests {

View file

@ -5,6 +5,29 @@
import { MultiSelectOption } from "@components/inputs/select";
export const AnnounceTypeOptions: MultiSelectOption[] = [
{
label: "New",
value: "NEW"
},
{
label: "Checked",
value: "CHECKED"
},
{
label: "Promo",
value: "PROMO"
},
{
label: "Promo GP",
value: "PROMO_GP"
},
{
label: "Resurrected",
value: "RESURRECTED"
}
];
export const resolutions = [
"2160p",
"1080p",

View file

@ -392,6 +392,7 @@ export const FilterDetails = () => {
enabled: filter.enabled,
min_size: filter.min_size,
max_size: filter.max_size,
announce_types: filter.announce_types || [],
delay: filter.delay,
priority: filter.priority,
max_downloads: filter.max_downloads,

View file

@ -10,7 +10,16 @@ import { IndexersOptionsQueryOptions } from "@api/queries";
import { DocsLink } from "@components/ExternalLink";
import { FilterLayout, FilterPage, FilterSection } from "./_components";
import { IndexerMultiSelect, MultiSelectOption, NumberField, Select, SwitchGroup, TextField } from "@components/inputs";
import {
IndexerMultiSelect,
MultiSelect,
MultiSelectOption,
NumberField,
Select,
SwitchGroup,
TextField
} from "@components/inputs";
import * as CONSTS from "@domain/constants.ts";
const MapIndexer = (indexer: Indexer) => (
@ -29,9 +38,20 @@ export const General = () => {
<FilterLayout>
<TextField name="name" label="Filter name" columns={6} placeholder="eg. Filter 1" />
{/*{!isLoading && (*/}
<IndexerMultiSelect name="indexers" options={indexerOptions} label="Indexers" columns={6} />
{/*)}*/}
<MultiSelect
name="announce_types"
options={CONSTS.AnnounceTypeOptions}
label="announce types"
columns={3}
tooltip={
<div>
<p>NEW! Match releases which contain any of the selected announce types.</p>
<DocsLink href="https://autobrr.com/filters#announce-type" />
</div>
}
/>
<IndexerMultiSelect name="indexers" options={indexerOptions} label="Indexers" columns={3} />
</FilterLayout>
</FilterSection>

View file

@ -13,6 +13,7 @@ interface Filter {
max_size: string;
delay: number;
priority: number;
announce_types: string[];
max_downloads: number;
max_downloads_unit: string;
match_releases: string;

View file

@ -11,6 +11,7 @@ interface Release {
filter: string;
protocol: string;
implementation: string;
announce_type: string;
name: string;
title: string;
size: number;