mirror of
https://github.com/idanoo/autobrr
synced 2025-07-22 08:19:12 +00:00
Add support for using freeleech tokens if available
This commit is contained in:
parent
74f777340e
commit
3656a68a27
28 changed files with 199 additions and 39 deletions
|
@ -447,6 +447,7 @@ type FilterExport struct {
|
|||
// Media-specific fields
|
||||
Freeleech bool `json:"freeleech,omitempty"`
|
||||
FreeleechPercent string `json:"freeleech_percent,omitempty"`
|
||||
FreeleechToken bool `json:"freeleech_token,omitempty"`
|
||||
Shows string `json:"shows,omitempty"`
|
||||
Seasons string `json:"seasons,omitempty"`
|
||||
Episodes string `json:"episodes,omitempty"`
|
||||
|
@ -543,6 +544,7 @@ func prepareFilterForExport(filter domain.Filter, externalFilters []domain.Filte
|
|||
AnnounceTypes: filter.AnnounceTypes,
|
||||
Freeleech: filter.Freeleech,
|
||||
FreeleechPercent: filter.FreeleechPercent,
|
||||
FreeleechToken: filter.FreeleechToken,
|
||||
Shows: filter.Shows,
|
||||
Seasons: filter.Seasons,
|
||||
Episodes: filter.Episodes,
|
||||
|
|
|
@ -210,6 +210,7 @@ func (r *FilterRepo) FindByID(ctx context.Context, filterID int) (*domain.Filter
|
|||
"f.scene",
|
||||
"f.freeleech",
|
||||
"f.freeleech_percent",
|
||||
"f.freeleech_token",
|
||||
"f.smart_episode",
|
||||
"f.shows",
|
||||
"f.seasons",
|
||||
|
@ -278,7 +279,7 @@ func (r *FilterRepo) FindByID(ctx context.Context, filterID int) (*domain.Filter
|
|||
|
||||
// filter
|
||||
var minSize, maxSize, maxDownloadsUnit, matchReleases, exceptReleases, matchReleaseGroups, exceptReleaseGroups, matchReleaseTags, exceptReleaseTags, matchDescription, exceptDescription, freeleechPercent, shows, seasons, episodes, years, months, days, artists, albums, matchCategories, exceptCategories, matchUploaders, exceptUploaders, matchRecordLabels, exceptRecordLabels, tags, exceptTags, tagsMatchLogic, exceptTagsMatchLogic sql.NullString
|
||||
var useRegex, scene, freeleech, hasLog, hasCue, perfectFlac sql.NullBool
|
||||
var useRegex, scene, freeleech, freeleechToken, hasLog, hasCue, perfectFlac sql.NullBool
|
||||
var delay, maxDownloads, logScore sql.NullInt32
|
||||
var releaseProfileDuplicateId sql.NullInt64
|
||||
|
||||
|
@ -307,6 +308,7 @@ func (r *FilterRepo) FindByID(ctx context.Context, filterID int) (*domain.Filter
|
|||
&scene,
|
||||
&freeleech,
|
||||
&freeleechPercent,
|
||||
&freeleechToken,
|
||||
&f.SmartEpisode,
|
||||
&shows,
|
||||
&seasons,
|
||||
|
@ -375,7 +377,9 @@ func (r *FilterRepo) FindByID(ctx context.Context, filterID int) (*domain.Filter
|
|||
f.ExceptReleaseTags = exceptReleaseTags.String
|
||||
f.MatchDescription = matchDescription.String
|
||||
f.ExceptDescription = exceptDescription.String
|
||||
f.Freeleech = freeleech.Bool
|
||||
f.FreeleechPercent = freeleechPercent.String
|
||||
f.FreeleechToken = freeleechToken.Bool
|
||||
f.Shows = shows.String
|
||||
f.Seasons = seasons.String
|
||||
f.Episodes = episodes.String
|
||||
|
@ -400,7 +404,6 @@ func (r *FilterRepo) FindByID(ctx context.Context, filterID int) (*domain.Filter
|
|||
f.ExceptTagsMatchLogic = exceptTagsMatchLogic.String
|
||||
f.UseRegex = useRegex.Bool
|
||||
f.Scene = scene.Bool
|
||||
f.Freeleech = freeleech.Bool
|
||||
f.ReleaseProfileDuplicateID = releaseProfileDuplicateId.Int64
|
||||
|
||||
return &f, nil
|
||||
|
@ -438,6 +441,7 @@ func (r *FilterRepo) findByIndexerIdentifier(ctx context.Context, indexer string
|
|||
"f.scene",
|
||||
"f.freeleech",
|
||||
"f.freeleech_percent",
|
||||
"f.freeleech_token",
|
||||
"f.smart_episode",
|
||||
"f.shows",
|
||||
"f.seasons",
|
||||
|
@ -535,7 +539,7 @@ func (r *FilterRepo) findByIndexerIdentifier(ctx context.Context, indexer string
|
|||
var f domain.Filter
|
||||
|
||||
var minSize, maxSize, maxDownloadsUnit, matchReleases, exceptReleases, matchReleaseGroups, exceptReleaseGroups, matchReleaseTags, exceptReleaseTags, matchDescription, exceptDescription, freeleechPercent, shows, seasons, episodes, years, months, days, artists, albums, matchCategories, exceptCategories, matchUploaders, exceptUploaders, matchRecordLabels, exceptRecordLabels, tags, exceptTags, tagsMatchLogic, exceptTagsMatchLogic sql.NullString
|
||||
var useRegex, scene, freeleech, hasLog, hasCue, perfectFlac sql.NullBool
|
||||
var useRegex, scene, freeleech, freeleechToken, hasLog, hasCue, perfectFlac sql.NullBool
|
||||
var delay, maxDownloads, logScore sql.NullInt32
|
||||
var releaseProfileDuplicateID, rdpId sql.NullInt64
|
||||
|
||||
|
@ -567,6 +571,7 @@ func (r *FilterRepo) findByIndexerIdentifier(ctx context.Context, indexer string
|
|||
&scene,
|
||||
&freeleech,
|
||||
&freeleechPercent,
|
||||
&freeleechToken,
|
||||
&f.SmartEpisode,
|
||||
&shows,
|
||||
&seasons,
|
||||
|
@ -680,6 +685,7 @@ func (r *FilterRepo) findByIndexerIdentifier(ctx context.Context, indexer string
|
|||
f.UseRegex = useRegex.Bool
|
||||
f.Scene = scene.Bool
|
||||
f.Freeleech = freeleech.Bool
|
||||
f.FreeleechToken = freeleechToken.Bool
|
||||
f.ReleaseProfileDuplicateID = releaseProfileDuplicateID.Int64
|
||||
|
||||
f.Rejections = []string{}
|
||||
|
@ -832,6 +838,7 @@ func (r *FilterRepo) Store(ctx context.Context, filter *domain.Filter) error {
|
|||
"scene",
|
||||
"freeleech",
|
||||
"freeleech_percent",
|
||||
"freeleech_token",
|
||||
"smart_episode",
|
||||
"shows",
|
||||
"seasons",
|
||||
|
@ -901,6 +908,7 @@ func (r *FilterRepo) Store(ctx context.Context, filter *domain.Filter) error {
|
|||
filter.Scene,
|
||||
filter.Freeleech,
|
||||
filter.FreeleechPercent,
|
||||
filter.FreeleechToken,
|
||||
filter.SmartEpisode,
|
||||
filter.Shows,
|
||||
filter.Seasons,
|
||||
|
@ -988,6 +996,7 @@ func (r *FilterRepo) Update(ctx context.Context, filter *domain.Filter) error {
|
|||
Set("scene", filter.Scene).
|
||||
Set("freeleech", filter.Freeleech).
|
||||
Set("freeleech_percent", filter.FreeleechPercent).
|
||||
Set("freeleech_token", filter.FreeleechToken).
|
||||
Set("smart_episode", filter.SmartEpisode).
|
||||
Set("shows", filter.Shows).
|
||||
Set("seasons", filter.Seasons).
|
||||
|
@ -1128,6 +1137,9 @@ func (r *FilterRepo) UpdatePartial(ctx context.Context, filter domain.FilterUpda
|
|||
if filter.FreeleechPercent != nil {
|
||||
q = q.Set("freeleech_percent", filter.FreeleechPercent)
|
||||
}
|
||||
if filter.FreeleechToken != nil {
|
||||
q = q.Set("freeleech_token", filter.FreeleechToken)
|
||||
}
|
||||
if filter.SmartEpisode != nil {
|
||||
q = q.Set("smart_episode", filter.SmartEpisode)
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ func getMockFilter() *domain.Filter {
|
|||
Bonus: nil,
|
||||
Freeleech: false,
|
||||
FreeleechPercent: "100%",
|
||||
FreeleechToken: false,
|
||||
SmartEpisode: false,
|
||||
Shows: "Is It Wrong to Try to Pick Up Girls in a Dungeon?",
|
||||
Seasons: "4",
|
||||
|
|
|
@ -1373,5 +1373,8 @@ CREATE INDEX release_hybrid_index
|
|||
FROM irc_network
|
||||
WHERE server = 'irc.rocket-hd.cc'
|
||||
);
|
||||
`,
|
||||
`ALTER TABLE filter
|
||||
ADD freeleech_token BOOLEAN DEFAULT FALSE AFTER freeleech_percent;
|
||||
`,
|
||||
}
|
||||
|
|
|
@ -742,6 +742,7 @@ func getMockFilterDuplicates() *domain.Filter {
|
|||
Bonus: nil,
|
||||
Freeleech: false,
|
||||
FreeleechPercent: "100%",
|
||||
FreeleechToken: false,
|
||||
SmartEpisode: false,
|
||||
Shows: "Is It Wrong to Try to Pick Up Girls in a Dungeon?",
|
||||
Seasons: "4",
|
||||
|
|
|
@ -2018,5 +2018,101 @@ CREATE INDEX release_hybrid_index
|
|||
FROM irc_network
|
||||
WHERE server = 'irc.rocket-hd.cc'
|
||||
);
|
||||
`, ``,
|
||||
`ALTER TABLE filter RENAME TO filter_add_col;
|
||||
DROP INDEX filter_enabled_index;
|
||||
DROP INDEX filter_priority_index;
|
||||
|
||||
CREATE TABLE filter
|
||||
(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
enabled BOOLEAN,
|
||||
name TEXT NOT NULL,
|
||||
min_size TEXT,
|
||||
max_size TEXT,
|
||||
delay INTEGER,
|
||||
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,
|
||||
match_release_groups TEXT,
|
||||
except_release_groups TEXT,
|
||||
match_release_tags TEXT,
|
||||
except_release_tags TEXT,
|
||||
use_regex_release_tags BOOLEAN DEFAULT FALSE,
|
||||
match_description TEXT,
|
||||
except_description TEXT,
|
||||
use_regex_description BOOLEAN DEFAULT FALSE,
|
||||
scene BOOLEAN,
|
||||
freeleech BOOLEAN,
|
||||
freeleech_percent TEXT,
|
||||
freeleech_token BOOLEAN DEFAULT FALSE,
|
||||
smart_episode BOOLEAN DEFAULT FALSE,
|
||||
shows TEXT,
|
||||
seasons TEXT,
|
||||
episodes TEXT,
|
||||
resolutions TEXT [] DEFAULT '{}' NOT NULL,
|
||||
codecs TEXT [] DEFAULT '{}' NOT NULL,
|
||||
sources TEXT [] DEFAULT '{}' NOT NULL,
|
||||
containers TEXT [] DEFAULT '{}' NOT NULL,
|
||||
match_hdr TEXT [] DEFAULT '{}',
|
||||
except_hdr TEXT [] DEFAULT '{}',
|
||||
match_other TEXT [] DEFAULT '{}',
|
||||
except_other TEXT [] DEFAULT '{}',
|
||||
years TEXT,
|
||||
months TEXT,
|
||||
days TEXT,
|
||||
artists TEXT,
|
||||
albums TEXT,
|
||||
release_types_match TEXT [] DEFAULT '{}',
|
||||
release_types_ignore TEXT [] DEFAULT '{}',
|
||||
formats TEXT [] DEFAULT '{}',
|
||||
quality TEXT [] DEFAULT '{}',
|
||||
media TEXT [] DEFAULT '{}',
|
||||
log_score INTEGER,
|
||||
has_log BOOLEAN,
|
||||
has_cue BOOLEAN,
|
||||
perfect_flac BOOLEAN,
|
||||
match_categories TEXT,
|
||||
except_categories TEXT,
|
||||
match_uploaders TEXT,
|
||||
except_uploaders TEXT,
|
||||
match_record_labels TEXT,
|
||||
except_record_labels TEXT,
|
||||
match_language TEXT [] DEFAULT '{}',
|
||||
except_language TEXT [] DEFAULT '{}',
|
||||
tags TEXT,
|
||||
except_tags TEXT,
|
||||
tags_match_logic TEXT,
|
||||
except_tags_match_logic TEXT,
|
||||
origins TEXT [] DEFAULT '{}',
|
||||
except_origins TEXT [] DEFAULT '{}',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
min_seeders INTEGER DEFAULT 0,
|
||||
max_seeders INTEGER DEFAULT 0,
|
||||
min_leechers INTEGER DEFAULT 0,
|
||||
max_leechers INTEGER DEFAULT 0,
|
||||
release_profile_duplicate_id INTEGER,
|
||||
FOREIGN KEY (release_profile_duplicate_id) REFERENCES release_profile_duplicate(id) ON DELETE SET NULL
|
||||
);
|
||||
|
||||
CREATE INDEX filter_enabled_index
|
||||
ON filter (enabled);
|
||||
CREATE INDEX filter_priority_index
|
||||
ON filter (priority);
|
||||
|
||||
INSERT INTO filter SELECT id, enabled, name, min_size, max_size, delay, priority, max_downloads, max_downloads_unit, announce_types,
|
||||
match_releases, except_releases, use_regex, match_release_groups, except_release_groups, match_release_tags, except_release_tags,
|
||||
use_regex_release_tags, match_description, except_description, use_regex_description, scene, freeleech, freeleech_percent,
|
||||
false,
|
||||
smart_episode, shows, seasons, episodes, resolutions, codecs, sources, containers, match_hdr, except_hdr, match_other, except_other,
|
||||
years, months, days, artists, albums, release_types_match, release_types_ignore, formats, quality, media, log_score, has_log, has_cue, perfect_flac, match_categories, except_categories, match_uploaders, except_uploaders, match_record_labels, except_record_labels, match_language, except_language, tags, except_tags, tags_match_logic, except_tags_match_logic, origins, except_origins, created_at, updated_at, min_seeders, max_seeders, min_leechers, max_leechers, release_profile_duplicate_id
|
||||
FROM filter_add_col;
|
||||
|
||||
DROP TABLE filter_add_col;
|
||||
`,
|
||||
}
|
||||
|
|
|
@ -114,6 +114,7 @@ type Filter struct {
|
|||
Bonus []string `json:"bonus,omitempty"`
|
||||
Freeleech bool `json:"freeleech,omitempty"`
|
||||
FreeleechPercent string `json:"freeleech_percent,omitempty"`
|
||||
FreeleechToken bool `json:"freeleech_token,omitempty"`
|
||||
SmartEpisode bool `json:"smart_episode"`
|
||||
Shows string `json:"shows,omitempty"`
|
||||
Seasons string `json:"seasons,omitempty"`
|
||||
|
@ -248,6 +249,7 @@ type FilterUpdate struct {
|
|||
Bonus *[]string `json:"bonus,omitempty"`
|
||||
Freeleech *bool `json:"freeleech,omitempty"`
|
||||
FreeleechPercent *string `json:"freeleech_percent,omitempty"`
|
||||
FreeleechToken *bool `json:"freeleech_token,omitempty"`
|
||||
SmartEpisode *bool `json:"smart_episode,omitempty"`
|
||||
Shows *string `json:"shows,omitempty"`
|
||||
Seasons *string `json:"seasons,omitempty"`
|
||||
|
|
|
@ -2087,6 +2087,7 @@ func TestFilter_CheckFilter1(t *testing.T) {
|
|||
ExceptOrigins: tt.fields.ExceptOrigins,
|
||||
Freeleech: tt.fields.Freeleech,
|
||||
FreeleechPercent: tt.fields.FreeleechPercent,
|
||||
FreeleechToken: tt.fields.FreeleechToken,
|
||||
Shows: tt.fields.Shows,
|
||||
Seasons: tt.fields.Seasons,
|
||||
Episodes: tt.fields.Episodes,
|
||||
|
|
|
@ -47,6 +47,7 @@ type Macro struct {
|
|||
FilterName string
|
||||
Freeleech bool
|
||||
FreeleechPercent int
|
||||
FreeleechToken bool
|
||||
Group string
|
||||
GroupID string
|
||||
HDR string
|
||||
|
|
|
@ -282,6 +282,7 @@ func TestRelease_DownloadTorrentFile(t *testing.T) {
|
|||
ReleaseTags: tt.fields.ReleaseTags,
|
||||
Freeleech: tt.fields.Freeleech,
|
||||
FreeleechPercent: tt.fields.FreeleechPercent,
|
||||
FreeleechToken: tt.fields.FreeleechToken,
|
||||
Bonus: tt.fields.Bonus,
|
||||
Uploader: tt.fields.Uploader,
|
||||
PreTime: tt.fields.PreTime,
|
||||
|
|
|
@ -558,7 +558,7 @@ func (s *service) AdditionalSizeCheck(ctx context.Context, f *domain.Filter, rel
|
|||
if (release.Size == 0 && release.AdditionalSizeCheckRequired) || (release.Uploader == "" && release.AdditionalUploaderCheckRequired) || (release.RecordLabel == "" && release.AdditionalRecordLabelCheckRequired) {
|
||||
l.Trace().Msgf("(%s) preparing to check size via api", f.Name)
|
||||
|
||||
torrentInfo, err := s.apiService.GetTorrentByID(ctx, release.Indexer.Identifier, release.TorrentID)
|
||||
torrentInfo, err := s.apiService.GetTorrentByID(ctx, release.Indexer.Identifier, release.TorrentID, f.FreeleechToken)
|
||||
if err != nil || torrentInfo == nil {
|
||||
l.Error().Err(err).Msgf("(%s) could not get torrent info from api: '%s' from: %s", f.Name, release.TorrentID, release.Indexer.Identifier)
|
||||
return false, err
|
||||
|
@ -643,7 +643,7 @@ func (s *service) AdditionalUploaderCheck(ctx context.Context, f *domain.Filter,
|
|||
case "redacted", "ops", "mock":
|
||||
l.Trace().Msgf("(%s) preparing to check via api", f.Name)
|
||||
|
||||
torrentInfo, err := s.apiService.GetTorrentByID(ctx, release.Indexer.Identifier, release.TorrentID)
|
||||
torrentInfo, err := s.apiService.GetTorrentByID(ctx, release.Indexer.Identifier, release.TorrentID, f.FreeleechToken)
|
||||
if err != nil || torrentInfo == nil {
|
||||
l.Error().Err(err).Msgf("(%s) could not get torrent info from api: '%s' from: %s", f.Name, release.TorrentID, release.Indexer.Identifier)
|
||||
return false, err
|
||||
|
@ -722,7 +722,7 @@ func (s *service) AdditionalRecordLabelCheck(ctx context.Context, f *domain.Filt
|
|||
case "redacted", "ops", "mock":
|
||||
l.Trace().Msgf("(%s) preparing to check via api", f.Name)
|
||||
|
||||
torrentInfo, err := s.apiService.GetTorrentByID(ctx, release.Indexer.Identifier, release.TorrentID)
|
||||
torrentInfo, err := s.apiService.GetTorrentByID(ctx, release.Indexer.Identifier, release.TorrentID, f.FreeleechToken)
|
||||
if err != nil || torrentInfo == nil {
|
||||
l.Error().Err(err).Msgf("(%s) could not get torrent info from api: '%s' from: %s", f.Name, release.TorrentID, release.Indexer.Identifier)
|
||||
return false, err
|
||||
|
|
|
@ -20,13 +20,13 @@ import (
|
|||
|
||||
type APIService interface {
|
||||
TestConnection(ctx context.Context, req domain.IndexerTestApiRequest) (bool, error)
|
||||
GetTorrentByID(ctx context.Context, indexer string, torrentID string) (*domain.TorrentBasic, error)
|
||||
GetTorrentByID(ctx context.Context, indexer string, torrentID string, freeleechToken bool) (*domain.TorrentBasic, error)
|
||||
AddClient(indexer string, settings map[string]string) error
|
||||
RemoveClient(indexer string) error
|
||||
}
|
||||
|
||||
type apiClient interface {
|
||||
GetTorrentByID(ctx context.Context, torrentID string) (*domain.TorrentBasic, error)
|
||||
GetTorrentByID(ctx context.Context, torrentID string, freeleechToken bool) (*domain.TorrentBasic, error)
|
||||
TestAPI(ctx context.Context) (bool, error)
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ func NewAPIService(log logger.Logger) APIService {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *apiService) GetTorrentByID(ctx context.Context, indexer string, torrentID string) (*domain.TorrentBasic, error) {
|
||||
func (s *apiService) GetTorrentByID(ctx context.Context, indexer string, torrentID string, freeleechToken bool) (*domain.TorrentBasic, error) {
|
||||
client, err := s.getApiClient(indexer)
|
||||
if err != nil {
|
||||
s.log.Error().Stack().Err(err).Msgf("could not get api client for: %s", indexer)
|
||||
|
@ -51,7 +51,7 @@ func (s *apiService) GetTorrentByID(ctx context.Context, indexer string, torrent
|
|||
|
||||
s.log.Trace().Str("method", "GetTorrentByID").Msgf("%s fetching torrent from api...", indexer)
|
||||
|
||||
torrent, err := client.GetTorrentByID(ctx, torrentID)
|
||||
torrent, err := client.GetTorrentByID(ctx, torrentID, freeleechToken)
|
||||
if err != nil {
|
||||
s.log.Error().Stack().Err(err).Msgf("could not get torrent: %s from: %s", torrentID, indexer)
|
||||
return nil, err
|
||||
|
|
|
@ -120,4 +120,4 @@ irc:
|
|||
|
||||
match:
|
||||
infourl: "/torrents.php?torrentid={{ .torrentId }}"
|
||||
torrenturl: "/torrents.php?action=download&id={{ .torrentId }}&torrent_pass={{ .torrent_pass }}"
|
||||
torrenturl: "/torrents.php?action=download&id={{ .torrentId }}&torrent_pass={{ .torrent_pass }}{{ .freeleech_token }}"
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
)
|
||||
|
||||
type IndexerApiClient interface {
|
||||
GetTorrentByID(ctx context.Context, torrentID string) (*domain.TorrentBasic, error)
|
||||
GetTorrentByID(ctx context.Context, torrentID string, freeleechToken bool) (*domain.TorrentBasic, error)
|
||||
TestAPI(ctx context.Context) (bool, error)
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@ func NewMockClient(apiKey string, opts ...OptFunc) IndexerApiClient {
|
|||
return c
|
||||
}
|
||||
|
||||
func (c *IndexerClient) GetTorrentByID(ctx context.Context, torrentID string) (*domain.TorrentBasic, error) {
|
||||
func (c *IndexerClient) GetTorrentByID(ctx context.Context, torrentID string, freeleechToken bool) (*domain.TorrentBasic, error) {
|
||||
if torrentID == "" {
|
||||
return nil, errors.New("mock client: must have torrentID")
|
||||
}
|
||||
|
|
|
@ -32,12 +32,12 @@ func (c *Client) TestAPI(ctx context.Context) (bool, error) {
|
|||
return false, nil
|
||||
}
|
||||
|
||||
func (c *Client) GetTorrentByID(ctx context.Context, torrentID string) (*domain.TorrentBasic, error) {
|
||||
func (c *Client) GetTorrentByID(ctx context.Context, torrentID string, freeleechToken bool) (*domain.TorrentBasic, error) {
|
||||
if torrentID == "" {
|
||||
return nil, errors.New("btn client: must have torrentID")
|
||||
}
|
||||
|
||||
res, err := c.rpcClient.CallCtx(ctx, "getTorrentById", [2]string{c.APIKey, torrentID})
|
||||
res, err := c.rpcClient.CallCtx(ctx, "getTorrentById", [3]interface{}{c.APIKey, torrentID, freeleechToken})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "call getTorrentById failed")
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
const DefaultURL = "https://api.broadcasthe.net/"
|
||||
|
||||
type ApiClient interface {
|
||||
GetTorrentByID(ctx context.Context, torrentID string) (*domain.TorrentBasic, error)
|
||||
GetTorrentByID(ctx context.Context, torrentID string, freeleechToken bool) (*domain.TorrentBasic, error)
|
||||
TestAPI(ctx context.Context) (bool, error)
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ var ErrForbidden = errors.New("forbidden")
|
|||
var ErrTooManyRequests = errors.New("too many requests: rate-limit reached")
|
||||
|
||||
type ApiClient interface {
|
||||
GetTorrentByID(ctx context.Context, torrentID string) (*domain.TorrentBasic, error)
|
||||
GetTorrentByID(ctx context.Context, torrentID string, freelechToken bool) (*domain.TorrentBasic, error)
|
||||
TestAPI(ctx context.Context) (bool, error)
|
||||
}
|
||||
|
||||
|
@ -243,7 +243,7 @@ func (c *Client) getJSON(ctx context.Context, params url.Values, data any) error
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) GetTorrentByID(ctx context.Context, torrentID string) (*domain.TorrentBasic, error) {
|
||||
func (c *Client) GetTorrentByID(ctx context.Context, torrentID string, freeleechToken bool) (*domain.TorrentBasic, error) {
|
||||
if torrentID == "" {
|
||||
return nil, errors.New("ggn client: must have torrentID")
|
||||
}
|
||||
|
@ -253,6 +253,9 @@ func (c *Client) GetTorrentByID(ctx context.Context, torrentID string) (*domain.
|
|||
params := url.Values{}
|
||||
params.Add("request", "torrent")
|
||||
params.Add("id", torrentID)
|
||||
if freeleechToken {
|
||||
params.Add("usetoken", "1")
|
||||
}
|
||||
|
||||
err := c.getJSON(ctx, params, &response)
|
||||
if err != nil {
|
||||
|
|
|
@ -86,7 +86,7 @@ func Test_client_GetTorrentByID(t *testing.T) {
|
|||
Url: ts.URL,
|
||||
APIKey: key,
|
||||
},
|
||||
args: args{torrentID: "422368"},
|
||||
args: args{torrentID: "422368", freeleechToken: false},
|
||||
want: &domain.TorrentBasic{
|
||||
Id: "422368",
|
||||
InfoHash: "78DA2811E6732012B8224198D4DC2FD49A5E950F",
|
||||
|
@ -100,7 +100,7 @@ func Test_client_GetTorrentByID(t *testing.T) {
|
|||
Url: ts.URL,
|
||||
APIKey: key,
|
||||
},
|
||||
args: args{torrentID: "100002"},
|
||||
args: args{torrentID: "100002", freeleechToken: true},
|
||||
want: nil,
|
||||
wantErr: false,
|
||||
},
|
||||
|
@ -109,7 +109,7 @@ func Test_client_GetTorrentByID(t *testing.T) {
|
|||
t.Run(tt.name, func(t *testing.T) {
|
||||
c := NewClient(tt.fields.APIKey, WithUrl(ts.URL))
|
||||
|
||||
got, err := c.GetTorrentByID(context.Background(), tt.args.torrentID)
|
||||
got, err := c.GetTorrentByID(context.Background(), tt.args.torrentID, tt.args.freeleechToken)
|
||||
if tt.wantErr && assert.Error(t, err) {
|
||||
t.Logf("got err: %v", err)
|
||||
assert.Equal(t, tt.wantErr, err)
|
||||
|
|
|
@ -23,7 +23,7 @@ import (
|
|||
const DefaultURL = "https://orpheus.network/ajax.php"
|
||||
|
||||
type ApiClient interface {
|
||||
GetTorrentByID(ctx context.Context, torrentID string) (*domain.TorrentBasic, error)
|
||||
GetTorrentByID(ctx context.Context, torrentID string, freeleechToken bool) (*domain.TorrentBasic, error)
|
||||
TestAPI(ctx context.Context) (bool, error)
|
||||
}
|
||||
|
||||
|
@ -226,7 +226,7 @@ func (c *Client) getJSON(ctx context.Context, params url.Values, data any) error
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) GetTorrentByID(ctx context.Context, torrentID string) (*domain.TorrentBasic, error) {
|
||||
func (c *Client) GetTorrentByID(ctx context.Context, torrentID string, freeleechToken bool) (*domain.TorrentBasic, error) {
|
||||
if torrentID == "" {
|
||||
return nil, errors.New("orpheus client: must have torrentID")
|
||||
}
|
||||
|
@ -236,6 +236,9 @@ func (c *Client) GetTorrentByID(ctx context.Context, torrentID string) (*domain.
|
|||
params := url.Values{}
|
||||
params.Add("action", "torrent")
|
||||
params.Add("id", torrentID)
|
||||
if freeleechToken {
|
||||
params.Add("usetoken", "1")
|
||||
}
|
||||
|
||||
err := c.getJSON(ctx, params, &response)
|
||||
if err != nil {
|
||||
|
|
|
@ -70,7 +70,7 @@ func TestOrpheusClient_GetTorrentByID(t *testing.T) {
|
|||
Url: ts.URL,
|
||||
APIKey: key,
|
||||
},
|
||||
args: args{torrentID: "2156788"},
|
||||
args: args{torrentID: "2156788", freeleechToken: false},
|
||||
want: &domain.TorrentBasic{
|
||||
Id: "2156788",
|
||||
InfoHash: "",
|
||||
|
@ -86,7 +86,7 @@ func TestOrpheusClient_GetTorrentByID(t *testing.T) {
|
|||
Url: ts.URL,
|
||||
APIKey: key,
|
||||
},
|
||||
args: args{torrentID: "100002"},
|
||||
args: args{torrentID: "100002", freeleechToken: false},
|
||||
want: nil,
|
||||
wantErr: "could not get torrent by id: 100002: status code: 400 status: failure error: bad id parameter",
|
||||
},
|
||||
|
@ -96,16 +96,26 @@ func TestOrpheusClient_GetTorrentByID(t *testing.T) {
|
|||
Url: ts.URL,
|
||||
APIKey: "",
|
||||
},
|
||||
args: args{torrentID: "100002"},
|
||||
args: args{torrentID: "100002", freeleechToken: false},
|
||||
want: nil,
|
||||
wantErr: "could not get torrent by id: 100002: orpheus client missing API key!",
|
||||
},
|
||||
{
|
||||
name: "get_by_id_1_freeleech_token",
|
||||
fields: fields{
|
||||
Url: ts.URL,
|
||||
APIKey: "",
|
||||
},
|
||||
args: args{torrentID: "100002", freeleechToken: true},
|
||||
want: nil,
|
||||
wantErr: "could not get torrent by id: 1. freeleech token not supported or no tokens available",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
c := NewClient(tt.fields.APIKey, WithUrl(ts.URL))
|
||||
|
||||
got, err := c.GetTorrentByID(context.Background(), tt.args.torrentID)
|
||||
got, err := c.GetTorrentByID(context.Background(), tt.args.torrentID, tt.args.freeleechToken)
|
||||
if tt.wantErr != "" && assert.Error(t, err) {
|
||||
assert.EqualErrorf(t, err, tt.wantErr, "Error should be: %v, got: %v", tt.wantErr, err)
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ var ErrForbidden = errors.New("forbidden")
|
|||
var ErrTooManyRequests = errors.New("too many requests: rate-limit reached")
|
||||
|
||||
type ApiClient interface {
|
||||
GetTorrentByID(ctx context.Context, torrentID string) (*domain.TorrentBasic, error)
|
||||
GetTorrentByID(ctx context.Context, torrentID string, freeleechToken bool) (*domain.TorrentBasic, error)
|
||||
TestAPI(ctx context.Context) (bool, error)
|
||||
}
|
||||
|
||||
|
@ -180,7 +180,7 @@ func (c *Client) getJSON(ctx context.Context, params url.Values, data any) error
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) GetTorrentByID(ctx context.Context, torrentID string) (*domain.TorrentBasic, error) {
|
||||
func (c *Client) GetTorrentByID(ctx context.Context, torrentID string, freeleechToken bool) (*domain.TorrentBasic, error) {
|
||||
if torrentID == "" {
|
||||
return nil, errors.New("ptp client: must have torrentID")
|
||||
}
|
||||
|
@ -189,6 +189,9 @@ func (c *Client) GetTorrentByID(ctx context.Context, torrentID string) (*domain.
|
|||
|
||||
params := url.Values{}
|
||||
params.Add("torrentid", torrentID)
|
||||
if freeleechToken {
|
||||
params.Add("usetoken", "1")
|
||||
}
|
||||
|
||||
err := c.getJSON(ctx, params, &response)
|
||||
if err != nil {
|
||||
|
|
|
@ -72,7 +72,7 @@ func TestPTPClient_GetTorrentByID(t *testing.T) {
|
|||
APIUser: user,
|
||||
APIKey: key,
|
||||
},
|
||||
args: args{torrentID: "1"},
|
||||
args: args{torrentID: "1", freeleechToken: false},
|
||||
want: &domain.TorrentBasic{
|
||||
Id: "1",
|
||||
InfoHash: "F57AA86DFB03F87FCC7636E310D35918442EAE5C",
|
||||
|
@ -87,7 +87,7 @@ func TestPTPClient_GetTorrentByID(t *testing.T) {
|
|||
APIUser: user,
|
||||
APIKey: key,
|
||||
},
|
||||
args: args{torrentID: "100002"},
|
||||
args: args{torrentID: "100002", freeleechToken: false},
|
||||
want: nil,
|
||||
wantErr: true,
|
||||
},
|
||||
|
@ -96,7 +96,7 @@ func TestPTPClient_GetTorrentByID(t *testing.T) {
|
|||
t.Run(tt.name, func(t *testing.T) {
|
||||
c := NewClient(tt.fields.APIUser, tt.fields.APIKey, WithUrl(ts.URL))
|
||||
|
||||
got, err := c.GetTorrentByID(context.Background(), tt.args.torrentID)
|
||||
got, err := c.GetTorrentByID(context.Background(), tt.args.torrentID, tt.args.freeleechToken)
|
||||
if tt.wantErr {
|
||||
assert.Error(t, err)
|
||||
} else {
|
||||
|
|
|
@ -23,7 +23,7 @@ import (
|
|||
const DefaultURL = "https://redacted.sh/ajax.php"
|
||||
|
||||
type ApiClient interface {
|
||||
GetTorrentByID(ctx context.Context, torrentID string) (*domain.TorrentBasic, error)
|
||||
GetTorrentByID(ctx context.Context, torrentID string, freeleechToken bool) (*domain.TorrentBasic, error)
|
||||
TestAPI(ctx context.Context) (bool, error)
|
||||
}
|
||||
|
||||
|
@ -214,7 +214,7 @@ func (c *Client) getJSON(ctx context.Context, params url.Values, data any) error
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) GetTorrentByID(ctx context.Context, torrentID string) (*domain.TorrentBasic, error) {
|
||||
func (c *Client) GetTorrentByID(ctx context.Context, torrentID string, freeleechToken bool) (*domain.TorrentBasic, error) {
|
||||
if torrentID == "" {
|
||||
return nil, errors.New("red client: must have torrentID")
|
||||
}
|
||||
|
@ -224,6 +224,9 @@ func (c *Client) GetTorrentByID(ctx context.Context, torrentID string) (*domain.
|
|||
params := url.Values{}
|
||||
params.Add("action", "torrent")
|
||||
params.Add("id", torrentID)
|
||||
if freeleechToken {
|
||||
params.Add("usetoken", "1")
|
||||
}
|
||||
|
||||
err := c.getJSON(ctx, params, &response)
|
||||
if err != nil {
|
||||
|
|
|
@ -70,7 +70,7 @@ func TestREDClient_GetTorrentByID(t *testing.T) {
|
|||
Url: ts.URL,
|
||||
APIKey: key,
|
||||
},
|
||||
args: args{torrentID: "29991962"},
|
||||
args: args{torrentID: "29991962", freeleechToken: false},
|
||||
want: &domain.TorrentBasic{
|
||||
Id: "29991962",
|
||||
InfoHash: "B2BABD3A361EAFC6C4E9142C422DF7DDF5D7E163",
|
||||
|
@ -86,7 +86,7 @@ func TestREDClient_GetTorrentByID(t *testing.T) {
|
|||
Url: ts.URL,
|
||||
APIKey: key,
|
||||
},
|
||||
args: args{torrentID: "100002"},
|
||||
args: args{torrentID: "100002", freeleechToken: false},
|
||||
want: nil,
|
||||
wantErr: "could not get torrent by id: 100002: status code: 400 status: failure error: bad id parameter",
|
||||
},
|
||||
|
@ -96,7 +96,7 @@ func TestREDClient_GetTorrentByID(t *testing.T) {
|
|||
Url: ts.URL,
|
||||
APIKey: "",
|
||||
},
|
||||
args: args{torrentID: "100002"},
|
||||
args: args{torrentID: "100002", freeleechToken: false},
|
||||
want: nil,
|
||||
wantErr: "could not get torrent by id: 100002: RED client missing API key!",
|
||||
},
|
||||
|
@ -105,7 +105,7 @@ func TestREDClient_GetTorrentByID(t *testing.T) {
|
|||
t.Run(tt.name, func(t *testing.T) {
|
||||
c := NewClient(tt.fields.APIKey, WithUrl(ts.URL))
|
||||
|
||||
got, err := c.GetTorrentByID(context.Background(), tt.args.torrentID)
|
||||
got, err := c.GetTorrentByID(context.Background(), tt.args.torrentID, tt.args.freeleechToken)
|
||||
if tt.wantErr != "" && assert.Error(t, err) {
|
||||
assert.EqualErrorf(t, err, tt.wantErr, "Error should be: %v, got: %v", tt.wantErr, err)
|
||||
}
|
||||
|
|
|
@ -437,6 +437,7 @@ export const FilterDetails = () => {
|
|||
except_language: filter.except_language || [],
|
||||
freeleech: filter.freeleech,
|
||||
freeleech_percent: filter.freeleech_percent,
|
||||
freeleech_token: filter.freeleech_token,
|
||||
formats: filter.formats || [],
|
||||
quality: filter.quality || [],
|
||||
media: filter.media || [],
|
||||
|
|
|
@ -14,6 +14,7 @@ export const FILTER_FIELDS: Record<string, string> = {
|
|||
"scene": "boolean",
|
||||
"smart_episode": "boolean",
|
||||
"freeleech": "boolean",
|
||||
"freeleech_token": "boolean",
|
||||
"perfect_flac": "boolean",
|
||||
"download_duplicates": "boolean",
|
||||
"cue": "boolean",
|
||||
|
|
|
@ -354,7 +354,7 @@ const Freeleech = () => {
|
|||
|
||||
return (
|
||||
<CollapsibleSection
|
||||
defaultOpen={values.freeleech || values.freeleech_percent !== undefined}
|
||||
defaultOpen={values.freeleech || values.freeleech_token || values.freeleech_percent !== undefined}
|
||||
title="Freeleech"
|
||||
subtitle="Match based off freeleech (if announced)"
|
||||
>
|
||||
|
@ -401,6 +401,21 @@ const Freeleech = () => {
|
|||
}
|
||||
/>
|
||||
</FilterHalfRow>
|
||||
<FilterHalfRow>
|
||||
<SwitchGroup
|
||||
name="freeleech_token"
|
||||
label="Freeleech Tokens"
|
||||
className="py-0"
|
||||
description="Use freeleech tokens if available."
|
||||
tooltip={
|
||||
<div>
|
||||
<p>
|
||||
Use freelech tokens for downloads if supported bt the tracker.
|
||||
</p>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
</FilterHalfRow>
|
||||
</CollapsibleSection>
|
||||
);
|
||||
}
|
||||
|
|
1
web/src/types/Filter.d.ts
vendored
1
web/src/types/Filter.d.ts
vendored
|
@ -32,6 +32,7 @@ interface Filter {
|
|||
except_origins: string[];
|
||||
freeleech: boolean;
|
||||
freeleech_percent: string;
|
||||
freeleech_token: boolean;
|
||||
shows: string;
|
||||
seasons: string;
|
||||
episodes: string;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue