mirror of
https://github.com/idanoo/autobrr
synced 2025-07-23 16:59:12 +00:00
feat(filters): add external script and webhook checks
This commit is contained in:
parent
16dd8c5419
commit
d56693cd33
17 changed files with 635 additions and 200 deletions
|
@ -135,7 +135,7 @@ func (s *service) delugeV1(client *domain.DownloadClient, action domain.Action,
|
|||
}
|
||||
|
||||
// macros handle args and replace vars
|
||||
m := NewMacro(release)
|
||||
m := domain.NewMacro(release)
|
||||
|
||||
options, err := s.prepareDelugeOptions(action, m)
|
||||
if err != nil {
|
||||
|
@ -224,7 +224,7 @@ func (s *service) delugeV2(client *domain.DownloadClient, action domain.Action,
|
|||
}
|
||||
|
||||
// macros handle args and replace vars
|
||||
m := NewMacro(release)
|
||||
m := domain.NewMacro(release)
|
||||
|
||||
// set options
|
||||
options, err := s.prepareDelugeOptions(action, m)
|
||||
|
@ -265,7 +265,7 @@ func (s *service) delugeV2(client *domain.DownloadClient, action domain.Action,
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func (s *service) prepareDelugeOptions(action domain.Action, m Macro) (delugeClient.Options, error) {
|
||||
func (s *service) prepareDelugeOptions(action domain.Action, m domain.Macro) (delugeClient.Options, error) {
|
||||
|
||||
// set options
|
||||
options := delugeClient.Options{}
|
||||
|
|
|
@ -56,7 +56,7 @@ func (s *service) execCmd(action domain.Action, release domain.Release) error {
|
|||
|
||||
func (s *service) parseExecArgs(release domain.Release, execArgs string) ([]string, error) {
|
||||
// handle args and replace vars
|
||||
m := NewMacro(release)
|
||||
m := domain.NewMacro(release)
|
||||
|
||||
// parse and replace values in argument string before continuing
|
||||
parsedArgs, err := m.Parse(execArgs)
|
||||
|
|
|
@ -76,7 +76,7 @@ func (s *service) qbittorrent(action domain.Action, release domain.Release) ([]s
|
|||
}
|
||||
|
||||
// macros handle args and replace vars
|
||||
m := NewMacro(release)
|
||||
m := domain.NewMacro(release)
|
||||
|
||||
options, err := s.prepareQbitOptions(action, m)
|
||||
if err != nil {
|
||||
|
@ -100,7 +100,7 @@ func (s *service) qbittorrent(action domain.Action, release domain.Release) ([]s
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func (s *service) prepareQbitOptions(action domain.Action, m Macro) (map[string]string, error) {
|
||||
func (s *service) prepareQbitOptions(action domain.Action, m domain.Macro) (map[string]string, error) {
|
||||
|
||||
options := map[string]string{}
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ func (s *service) watchFolder(action domain.Action, release domain.Release) erro
|
|||
}
|
||||
}
|
||||
|
||||
m := NewMacro(release)
|
||||
m := domain.NewMacro(release)
|
||||
|
||||
// parse and replace values in argument string before continuing
|
||||
watchFolderArgs, err := m.Parse(action.WatchFolder)
|
||||
|
@ -187,7 +187,7 @@ func (s *service) webhook(action domain.Action, release domain.Release) error {
|
|||
}
|
||||
}
|
||||
|
||||
m := NewMacro(release)
|
||||
m := domain.NewMacro(release)
|
||||
|
||||
// parse and replace values in argument string before continuing
|
||||
dataArgs, err := m.Parse(action.WebhookData)
|
||||
|
|
|
@ -123,6 +123,14 @@ func (r *FilterRepo) FindByID(ctx context.Context, filterID int) (*domain.Filter
|
|||
"tags",
|
||||
"except_tags",
|
||||
"origins",
|
||||
"external_script_enabled",
|
||||
"external_script_cmd",
|
||||
"external_script_args",
|
||||
"external_script_expect_status",
|
||||
"external_webhook_enabled",
|
||||
"external_webhook_host",
|
||||
"external_webhook_data",
|
||||
"external_webhook_expect_status",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
).
|
||||
|
@ -140,11 +148,11 @@ func (r *FilterRepo) FindByID(ctx context.Context, filterID int) (*domain.Filter
|
|||
}
|
||||
|
||||
var f domain.Filter
|
||||
var minSize, maxSize, maxDownloadsUnit, matchReleases, exceptReleases, matchReleaseGroups, exceptReleaseGroups, freeleechPercent, shows, seasons, episodes, years, artists, albums, matchCategories, exceptCategories, matchUploaders, exceptUploaders, tags, exceptTags sql.NullString
|
||||
var useRegex, scene, freeleech, hasLog, hasCue, perfectFlac sql.NullBool
|
||||
var delay, maxDownloads, logScore sql.NullInt32
|
||||
var minSize, maxSize, maxDownloadsUnit, matchReleases, exceptReleases, matchReleaseGroups, exceptReleaseGroups, freeleechPercent, shows, seasons, episodes, years, artists, albums, matchCategories, exceptCategories, matchUploaders, exceptUploaders, tags, exceptTags, extScriptCmd, extScriptArgs, extWebhookHost, extWebhookData sql.NullString
|
||||
var useRegex, scene, freeleech, hasLog, hasCue, perfectFlac, extScriptEnabled, extWebhookEnabled sql.NullBool
|
||||
var delay, maxDownloads, logScore, extWebhookStatus, extScriptStatus sql.NullInt32
|
||||
|
||||
if err := row.Scan(&f.ID, &f.Enabled, &f.Name, &minSize, &maxSize, &delay, &f.Priority, &maxDownloads, &maxDownloadsUnit, &matchReleases, &exceptReleases, &useRegex, &matchReleaseGroups, &exceptReleaseGroups, &scene, &freeleech, &freeleechPercent, &shows, &seasons, &episodes, pq.Array(&f.Resolutions), pq.Array(&f.Codecs), pq.Array(&f.Sources), pq.Array(&f.Containers), pq.Array(&f.MatchHDR), pq.Array(&f.ExceptHDR), pq.Array(&f.MatchOther), pq.Array(&f.ExceptOther), &years, &artists, &albums, pq.Array(&f.MatchReleaseTypes), pq.Array(&f.Formats), pq.Array(&f.Quality), pq.Array(&f.Media), &logScore, &hasLog, &hasCue, &perfectFlac, &matchCategories, &exceptCategories, &matchUploaders, &exceptUploaders, &tags, &exceptTags, pq.Array(&f.Origins), &f.CreatedAt, &f.UpdatedAt); err != nil {
|
||||
if err := row.Scan(&f.ID, &f.Enabled, &f.Name, &minSize, &maxSize, &delay, &f.Priority, &maxDownloads, &maxDownloadsUnit, &matchReleases, &exceptReleases, &useRegex, &matchReleaseGroups, &exceptReleaseGroups, &scene, &freeleech, &freeleechPercent, &shows, &seasons, &episodes, pq.Array(&f.Resolutions), pq.Array(&f.Codecs), pq.Array(&f.Sources), pq.Array(&f.Containers), pq.Array(&f.MatchHDR), pq.Array(&f.ExceptHDR), pq.Array(&f.MatchOther), pq.Array(&f.ExceptOther), &years, &artists, &albums, pq.Array(&f.MatchReleaseTypes), pq.Array(&f.Formats), pq.Array(&f.Quality), pq.Array(&f.Media), &logScore, &hasLog, &hasCue, &perfectFlac, &matchCategories, &exceptCategories, &matchUploaders, &exceptUploaders, &tags, &exceptTags, pq.Array(&f.Origins), &extScriptEnabled, &extScriptCmd, &extScriptArgs, &extScriptStatus, &extWebhookEnabled, &extWebhookHost, &extWebhookData, &extWebhookStatus, &f.CreatedAt, &f.UpdatedAt); err != nil {
|
||||
return nil, errors.Wrap(err, "error scanning row")
|
||||
}
|
||||
|
||||
|
@ -178,6 +186,16 @@ func (r *FilterRepo) FindByID(ctx context.Context, filterID int) (*domain.Filter
|
|||
f.Scene = scene.Bool
|
||||
f.Freeleech = freeleech.Bool
|
||||
|
||||
f.ExternalScriptEnabled = extScriptEnabled.Bool
|
||||
f.ExternalScriptCmd = extScriptCmd.String
|
||||
f.ExternalScriptArgs = extScriptArgs.String
|
||||
f.ExternalScriptExpectStatus = int(extScriptStatus.Int32)
|
||||
|
||||
f.ExternalWebhookEnabled = extWebhookEnabled.Bool
|
||||
f.ExternalWebhookHost = extWebhookHost.String
|
||||
f.ExternalWebhookData = extWebhookData.String
|
||||
f.ExternalWebhookExpectStatus = int(extWebhookStatus.Int32)
|
||||
|
||||
return &f, nil
|
||||
}
|
||||
|
||||
|
@ -255,6 +273,14 @@ func (r *FilterRepo) findByIndexerIdentifier(ctx context.Context, tx *Tx, indexe
|
|||
"f.tags",
|
||||
"f.except_tags",
|
||||
"f.origins",
|
||||
"f.external_script_enabled",
|
||||
"f.external_script_cmd",
|
||||
"f.external_script_args",
|
||||
"f.external_script_expect_status",
|
||||
"f.external_webhook_enabled",
|
||||
"f.external_webhook_host",
|
||||
"f.external_webhook_data",
|
||||
"f.external_webhook_expect_status",
|
||||
"f.created_at",
|
||||
"f.updated_at",
|
||||
).
|
||||
|
@ -282,11 +308,11 @@ func (r *FilterRepo) findByIndexerIdentifier(ctx context.Context, tx *Tx, indexe
|
|||
for rows.Next() {
|
||||
var f domain.Filter
|
||||
|
||||
var minSize, maxSize, maxDownloadsUnit, matchReleases, exceptReleases, matchReleaseGroups, exceptReleaseGroups, freeleechPercent, shows, seasons, episodes, years, artists, albums, matchCategories, exceptCategories, matchUploaders, exceptUploaders, tags, exceptTags sql.NullString
|
||||
var useRegex, scene, freeleech, hasLog, hasCue, perfectFlac sql.NullBool
|
||||
var delay, maxDownloads, logScore sql.NullInt32
|
||||
var minSize, maxSize, maxDownloadsUnit, matchReleases, exceptReleases, matchReleaseGroups, exceptReleaseGroups, freeleechPercent, shows, seasons, episodes, years, artists, albums, matchCategories, exceptCategories, matchUploaders, exceptUploaders, tags, exceptTags, extScriptCmd, extScriptArgs, extWebhookHost, extWebhookData sql.NullString
|
||||
var useRegex, scene, freeleech, hasLog, hasCue, perfectFlac, extScriptEnabled, extWebhookEnabled sql.NullBool
|
||||
var delay, maxDownloads, logScore, extWebhookStatus, extScriptStatus sql.NullInt32
|
||||
|
||||
if err := rows.Scan(&f.ID, &f.Enabled, &f.Name, &minSize, &maxSize, &delay, &f.Priority, &maxDownloads, &maxDownloadsUnit, &matchReleases, &exceptReleases, &useRegex, &matchReleaseGroups, &exceptReleaseGroups, &scene, &freeleech, &freeleechPercent, &shows, &seasons, &episodes, pq.Array(&f.Resolutions), pq.Array(&f.Codecs), pq.Array(&f.Sources), pq.Array(&f.Containers), pq.Array(&f.MatchHDR), pq.Array(&f.ExceptHDR), pq.Array(&f.MatchOther), pq.Array(&f.ExceptOther), &years, &artists, &albums, pq.Array(&f.MatchReleaseTypes), pq.Array(&f.Formats), pq.Array(&f.Quality), pq.Array(&f.Media), &logScore, &hasLog, &hasCue, &perfectFlac, &matchCategories, &exceptCategories, &matchUploaders, &exceptUploaders, &tags, &exceptTags, pq.Array(&f.Origins), &f.CreatedAt, &f.UpdatedAt); err != nil {
|
||||
if err := rows.Scan(&f.ID, &f.Enabled, &f.Name, &minSize, &maxSize, &delay, &f.Priority, &maxDownloads, &maxDownloadsUnit, &matchReleases, &exceptReleases, &useRegex, &matchReleaseGroups, &exceptReleaseGroups, &scene, &freeleech, &freeleechPercent, &shows, &seasons, &episodes, pq.Array(&f.Resolutions), pq.Array(&f.Codecs), pq.Array(&f.Sources), pq.Array(&f.Containers), pq.Array(&f.MatchHDR), pq.Array(&f.ExceptHDR), pq.Array(&f.MatchOther), pq.Array(&f.ExceptOther), &years, &artists, &albums, pq.Array(&f.MatchReleaseTypes), pq.Array(&f.Formats), pq.Array(&f.Quality), pq.Array(&f.Media), &logScore, &hasLog, &hasCue, &perfectFlac, &matchCategories, &exceptCategories, &matchUploaders, &exceptUploaders, &tags, &exceptTags, pq.Array(&f.Origins), &extScriptEnabled, &extScriptCmd, &extScriptArgs, &extScriptStatus, &extWebhookEnabled, &extWebhookHost, &extWebhookData, &extWebhookStatus, &f.CreatedAt, &f.UpdatedAt); err != nil {
|
||||
return nil, errors.Wrap(err, "error scanning row")
|
||||
}
|
||||
|
||||
|
@ -320,6 +346,16 @@ func (r *FilterRepo) findByIndexerIdentifier(ctx context.Context, tx *Tx, indexe
|
|||
f.Scene = scene.Bool
|
||||
f.Freeleech = freeleech.Bool
|
||||
|
||||
f.ExternalScriptEnabled = extScriptEnabled.Bool
|
||||
f.ExternalScriptCmd = extScriptCmd.String
|
||||
f.ExternalScriptArgs = extScriptArgs.String
|
||||
f.ExternalScriptExpectStatus = int(extScriptStatus.Int32)
|
||||
|
||||
f.ExternalWebhookEnabled = extWebhookEnabled.Bool
|
||||
f.ExternalWebhookHost = extWebhookHost.String
|
||||
f.ExternalWebhookData = extWebhookData.String
|
||||
f.ExternalWebhookExpectStatus = int(extWebhookStatus.Int32)
|
||||
|
||||
filters = append(filters, f)
|
||||
}
|
||||
|
||||
|
@ -375,6 +411,14 @@ func (r *FilterRepo) Store(ctx context.Context, filter domain.Filter) (*domain.F
|
|||
"has_cue",
|
||||
"perfect_flac",
|
||||
"origins",
|
||||
"external_script_enabled",
|
||||
"external_script_cmd",
|
||||
"external_script_args",
|
||||
"external_script_expect_status",
|
||||
"external_webhook_enabled",
|
||||
"external_webhook_host",
|
||||
"external_webhook_data",
|
||||
"external_webhook_expect_status",
|
||||
).
|
||||
Values(
|
||||
filter.Name,
|
||||
|
@ -422,6 +466,14 @@ func (r *FilterRepo) Store(ctx context.Context, filter domain.Filter) (*domain.F
|
|||
filter.Cue,
|
||||
filter.PerfectFlac,
|
||||
pq.Array(filter.Origins),
|
||||
filter.ExternalScriptEnabled,
|
||||
filter.ExternalScriptCmd,
|
||||
filter.ExternalScriptArgs,
|
||||
filter.ExternalScriptExpectStatus,
|
||||
filter.ExternalWebhookEnabled,
|
||||
filter.ExternalWebhookHost,
|
||||
filter.ExternalWebhookData,
|
||||
filter.ExternalWebhookExpectStatus,
|
||||
).
|
||||
Suffix("RETURNING id").RunWith(r.db.handler)
|
||||
|
||||
|
@ -488,6 +540,14 @@ func (r *FilterRepo) Update(ctx context.Context, filter domain.Filter) (*domain.
|
|||
Set("has_cue", filter.Cue).
|
||||
Set("perfect_flac", filter.PerfectFlac).
|
||||
Set("origins", pq.Array(filter.Origins)).
|
||||
Set("external_script_enabled", filter.ExternalScriptEnabled).
|
||||
Set("external_script_cmd", filter.ExternalScriptCmd).
|
||||
Set("external_script_args", filter.ExternalScriptArgs).
|
||||
Set("external_script_expect_status", filter.ExternalScriptExpectStatus).
|
||||
Set("external_webhook_enabled", filter.ExternalWebhookEnabled).
|
||||
Set("external_webhook_host", filter.ExternalWebhookHost).
|
||||
Set("external_webhook_data", filter.ExternalWebhookData).
|
||||
Set("external_webhook_expect_status", filter.ExternalWebhookExpectStatus).
|
||||
Set("updated_at", time.Now().Format(time.RFC3339)).
|
||||
Where("id = ?", filter.ID)
|
||||
|
||||
|
|
|
@ -60,55 +60,63 @@ CREATE TABLE irc_channel
|
|||
|
||||
CREATE TABLE filter
|
||||
(
|
||||
id SERIAL PRIMARY KEY,
|
||||
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,
|
||||
match_releases TEXT,
|
||||
except_releases TEXT,
|
||||
use_regex BOOLEAN,
|
||||
match_release_groups TEXT,
|
||||
except_release_groups TEXT,
|
||||
scene BOOLEAN,
|
||||
freeleech BOOLEAN,
|
||||
freeleech_percent TEXT,
|
||||
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,
|
||||
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,
|
||||
tags TEXT,
|
||||
except_tags TEXT,
|
||||
origins TEXT [] DEFAULT '{}',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
id SERIAL PRIMARY KEY,
|
||||
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,
|
||||
match_releases TEXT,
|
||||
except_releases TEXT,
|
||||
use_regex BOOLEAN,
|
||||
match_release_groups TEXT,
|
||||
except_release_groups TEXT,
|
||||
scene BOOLEAN,
|
||||
freeleech BOOLEAN,
|
||||
freeleech_percent TEXT,
|
||||
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,
|
||||
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,
|
||||
tags TEXT,
|
||||
except_tags TEXT,
|
||||
origins TEXT [] DEFAULT '{}',
|
||||
external_script_enabled BOOLEAN DEFAULT FALSE,
|
||||
external_script_cmd TEXT,
|
||||
external_script_args TEXT,
|
||||
external_script_expect_status INTEGER,
|
||||
external_webhook_enabled BOOLEAN DEFAULT FALSE,
|
||||
external_webhook_host TEXT,
|
||||
external_webhook_data TEXT,
|
||||
external_webhook_expect_status INTEGER,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE filter_indexer
|
||||
|
@ -494,4 +502,29 @@ CREATE INDEX indexer_identifier_index
|
|||
ALTER TABLE release_action_status
|
||||
ADD COLUMN filter TEXT;
|
||||
`,
|
||||
`
|
||||
ALTER TABLE filter
|
||||
ADD COLUMN external_script_enabled BOOLEAN DEFAULT FALSE;
|
||||
|
||||
ALTER TABLE filter
|
||||
ADD COLUMN external_script_cmd TEXT;
|
||||
|
||||
ALTER TABLE filter
|
||||
ADD COLUMN external_script_args TEXT;
|
||||
|
||||
ALTER TABLE filter
|
||||
ADD COLUMN external_script_expect_status INTEGER;
|
||||
|
||||
ALTER TABLE filter
|
||||
ADD COLUMN external_webhook_enabled BOOLEAN DEFAULT FALSE;
|
||||
|
||||
ALTER TABLE filter
|
||||
ADD COLUMN external_webhook_host TEXT;
|
||||
|
||||
ALTER TABLE filter
|
||||
ADD COLUMN external_webhook_data TEXT;
|
||||
|
||||
ALTER TABLE filter
|
||||
ADD COLUMN external_webhook_expect_status INTEGER;
|
||||
`,
|
||||
}
|
||||
|
|
|
@ -60,55 +60,63 @@ CREATE TABLE irc_channel
|
|||
|
||||
CREATE TABLE filter
|
||||
(
|
||||
id INTEGER PRIMARY KEY,
|
||||
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,
|
||||
match_releases TEXT,
|
||||
except_releases TEXT,
|
||||
use_regex BOOLEAN,
|
||||
match_release_groups TEXT,
|
||||
except_release_groups TEXT,
|
||||
scene BOOLEAN,
|
||||
freeleech BOOLEAN,
|
||||
freeleech_percent TEXT,
|
||||
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,
|
||||
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,
|
||||
tags TEXT,
|
||||
except_tags TEXT,
|
||||
origins TEXT [] DEFAULT '{}',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
id INTEGER PRIMARY KEY,
|
||||
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,
|
||||
match_releases TEXT,
|
||||
except_releases TEXT,
|
||||
use_regex BOOLEAN,
|
||||
match_release_groups TEXT,
|
||||
except_release_groups TEXT,
|
||||
scene BOOLEAN,
|
||||
freeleech BOOLEAN,
|
||||
freeleech_percent TEXT,
|
||||
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,
|
||||
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,
|
||||
tags TEXT,
|
||||
except_tags TEXT,
|
||||
origins TEXT [] DEFAULT '{}',
|
||||
external_script_enabled BOOLEAN DEFAULT FALSE,
|
||||
external_script_cmd TEXT,
|
||||
external_script_args TEXT,
|
||||
external_script_expect_status INTEGER,
|
||||
external_webhook_enabled BOOLEAN DEFAULT FALSE,
|
||||
external_webhook_host TEXT,
|
||||
external_webhook_data TEXT,
|
||||
external_webhook_expect_status INTEGER,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE filter_indexer
|
||||
|
@ -814,4 +822,29 @@ CREATE INDEX indexer_identifier_index
|
|||
ALTER TABLE release_action_status
|
||||
ADD COLUMN filter TEXT;
|
||||
`,
|
||||
`
|
||||
ALTER TABLE filter
|
||||
ADD COLUMN external_script_enabled BOOLEAN DEFAULT FALSE;
|
||||
|
||||
ALTER TABLE filter
|
||||
ADD COLUMN external_script_cmd TEXT;
|
||||
|
||||
ALTER TABLE filter
|
||||
ADD COLUMN external_script_args TEXT;
|
||||
|
||||
ALTER TABLE filter
|
||||
ADD COLUMN external_script_expect_status INTEGER;
|
||||
|
||||
ALTER TABLE filter
|
||||
ADD COLUMN external_webhook_enabled BOOLEAN DEFAULT FALSE;
|
||||
|
||||
ALTER TABLE filter
|
||||
ADD COLUMN external_webhook_host TEXT;
|
||||
|
||||
ALTER TABLE filter
|
||||
ADD COLUMN external_webhook_data TEXT;
|
||||
|
||||
ALTER TABLE filter
|
||||
ADD COLUMN external_webhook_expect_status INTEGER;
|
||||
`,
|
||||
}
|
||||
|
|
|
@ -49,61 +49,69 @@ const (
|
|||
)
|
||||
|
||||
type Filter struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Enabled bool `json:"enabled"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
MinSize string `json:"min_size"`
|
||||
MaxSize string `json:"max_size"`
|
||||
Delay int `json:"delay"`
|
||||
Priority int32 `json:"priority"`
|
||||
MaxDownloads int `json:"max_downloads"`
|
||||
MaxDownloadsUnit FilterMaxDownloadsUnit `json:"max_downloads_unit"`
|
||||
MatchReleases string `json:"match_releases"`
|
||||
ExceptReleases string `json:"except_releases"`
|
||||
UseRegex bool `json:"use_regex"`
|
||||
MatchReleaseGroups string `json:"match_release_groups"`
|
||||
ExceptReleaseGroups string `json:"except_release_groups"`
|
||||
Scene bool `json:"scene"`
|
||||
Origins []string `json:"origins"`
|
||||
Bonus []string `json:"bonus"`
|
||||
Freeleech bool `json:"freeleech"`
|
||||
FreeleechPercent string `json:"freeleech_percent"`
|
||||
Shows string `json:"shows"`
|
||||
Seasons string `json:"seasons"`
|
||||
Episodes string `json:"episodes"`
|
||||
Resolutions []string `json:"resolutions"` // SD, 480i, 480p, 576p, 720p, 810p, 1080i, 1080p.
|
||||
Codecs []string `json:"codecs"` // XviD, DivX, x264, h.264 (or h264), mpeg2 (or mpeg-2), VC-1 (or VC1), WMV, Remux, h.264 Remux (or h264 Remux), VC-1 Remux (or VC1 Remux).
|
||||
Sources []string `json:"sources"` // DSR, PDTV, HDTV, HR.PDTV, HR.HDTV, DVDRip, DVDScr, BDr, BD5, BD9, BDRip, BRRip, DVDR, MDVDR, HDDVD, HDDVDRip, BluRay, WEB-DL, TVRip, CAM, R5, TELESYNC, TS, TELECINE, TC. TELESYNC and TS are synonyms (you don't need both). Same for TELECINE and TC
|
||||
Containers []string `json:"containers"`
|
||||
MatchHDR []string `json:"match_hdr"`
|
||||
ExceptHDR []string `json:"except_hdr"`
|
||||
MatchOther []string `json:"match_other"`
|
||||
ExceptOther []string `json:"except_other"`
|
||||
Years string `json:"years"`
|
||||
Artists string `json:"artists"`
|
||||
Albums string `json:"albums"`
|
||||
MatchReleaseTypes []string `json:"match_release_types"` // Album,Single,EP
|
||||
ExceptReleaseTypes string `json:"except_release_types"`
|
||||
Formats []string `json:"formats"` // MP3, FLAC, Ogg, AAC, AC3, DTS
|
||||
Quality []string `json:"quality"` // 192, 320, APS (VBR), V2 (VBR), V1 (VBR), APX (VBR), V0 (VBR), q8.x (VBR), Lossless, 24bit Lossless, Other
|
||||
Media []string `json:"media"` // CD, DVD, Vinyl, Soundboard, SACD, DAT, Cassette, WEB, Other
|
||||
PerfectFlac bool `json:"perfect_flac"`
|
||||
Cue bool `json:"cue"`
|
||||
Log bool `json:"log"`
|
||||
LogScore int `json:"log_score"`
|
||||
MatchCategories string `json:"match_categories"`
|
||||
ExceptCategories string `json:"except_categories"`
|
||||
MatchUploaders string `json:"match_uploaders"`
|
||||
ExceptUploaders string `json:"except_uploaders"`
|
||||
Tags string `json:"tags"`
|
||||
ExceptTags string `json:"except_tags"`
|
||||
TagsAny string `json:"tags_any"`
|
||||
ExceptTagsAny string `json:"except_tags_any"`
|
||||
Actions []*Action `json:"actions"`
|
||||
Indexers []Indexer `json:"indexers"`
|
||||
Downloads *FilterDownloads `json:"-"`
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Enabled bool `json:"enabled"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
MinSize string `json:"min_size"`
|
||||
MaxSize string `json:"max_size"`
|
||||
Delay int `json:"delay"`
|
||||
Priority int32 `json:"priority"`
|
||||
MaxDownloads int `json:"max_downloads"`
|
||||
MaxDownloadsUnit FilterMaxDownloadsUnit `json:"max_downloads_unit"`
|
||||
MatchReleases string `json:"match_releases"`
|
||||
ExceptReleases string `json:"except_releases"`
|
||||
UseRegex bool `json:"use_regex"`
|
||||
MatchReleaseGroups string `json:"match_release_groups"`
|
||||
ExceptReleaseGroups string `json:"except_release_groups"`
|
||||
Scene bool `json:"scene"`
|
||||
Origins []string `json:"origins"`
|
||||
Bonus []string `json:"bonus"`
|
||||
Freeleech bool `json:"freeleech"`
|
||||
FreeleechPercent string `json:"freeleech_percent"`
|
||||
Shows string `json:"shows"`
|
||||
Seasons string `json:"seasons"`
|
||||
Episodes string `json:"episodes"`
|
||||
Resolutions []string `json:"resolutions"` // SD, 480i, 480p, 576p, 720p, 810p, 1080i, 1080p.
|
||||
Codecs []string `json:"codecs"` // XviD, DivX, x264, h.264 (or h264), mpeg2 (or mpeg-2), VC-1 (or VC1), WMV, Remux, h.264 Remux (or h264 Remux), VC-1 Remux (or VC1 Remux).
|
||||
Sources []string `json:"sources"` // DSR, PDTV, HDTV, HR.PDTV, HR.HDTV, DVDRip, DVDScr, BDr, BD5, BD9, BDRip, BRRip, DVDR, MDVDR, HDDVD, HDDVDRip, BluRay, WEB-DL, TVRip, CAM, R5, TELESYNC, TS, TELECINE, TC. TELESYNC and TS are synonyms (you don't need both). Same for TELECINE and TC
|
||||
Containers []string `json:"containers"`
|
||||
MatchHDR []string `json:"match_hdr"`
|
||||
ExceptHDR []string `json:"except_hdr"`
|
||||
MatchOther []string `json:"match_other"`
|
||||
ExceptOther []string `json:"except_other"`
|
||||
Years string `json:"years"`
|
||||
Artists string `json:"artists"`
|
||||
Albums string `json:"albums"`
|
||||
MatchReleaseTypes []string `json:"match_release_types"` // Album,Single,EP
|
||||
ExceptReleaseTypes string `json:"except_release_types"`
|
||||
Formats []string `json:"formats"` // MP3, FLAC, Ogg, AAC, AC3, DTS
|
||||
Quality []string `json:"quality"` // 192, 320, APS (VBR), V2 (VBR), V1 (VBR), APX (VBR), V0 (VBR), q8.x (VBR), Lossless, 24bit Lossless, Other
|
||||
Media []string `json:"media"` // CD, DVD, Vinyl, Soundboard, SACD, DAT, Cassette, WEB, Other
|
||||
PerfectFlac bool `json:"perfect_flac"`
|
||||
Cue bool `json:"cue"`
|
||||
Log bool `json:"log"`
|
||||
LogScore int `json:"log_score"`
|
||||
MatchCategories string `json:"match_categories"`
|
||||
ExceptCategories string `json:"except_categories"`
|
||||
MatchUploaders string `json:"match_uploaders"`
|
||||
ExceptUploaders string `json:"except_uploaders"`
|
||||
Tags string `json:"tags"`
|
||||
ExceptTags string `json:"except_tags"`
|
||||
TagsAny string `json:"tags_any"`
|
||||
ExceptTagsAny string `json:"except_tags_any"`
|
||||
ExternalScriptEnabled bool `json:"external_script_enabled"`
|
||||
ExternalScriptCmd string `json:"external_script_cmd"`
|
||||
ExternalScriptArgs string `json:"external_script_args"`
|
||||
ExternalScriptExpectStatus int `json:"external_script_expect_status"`
|
||||
ExternalWebhookEnabled bool `json:"external_webhook_enabled"`
|
||||
ExternalWebhookHost string `json:"external_webhook_host"`
|
||||
ExternalWebhookData string `json:"external_webhook_data"`
|
||||
ExternalWebhookExpectStatus int `json:"external_webhook_expect_status"`
|
||||
Actions []*Action `json:"actions"`
|
||||
Indexers []Indexer `json:"indexers"`
|
||||
Downloads *FilterDownloads `json:"-"`
|
||||
}
|
||||
|
||||
func (f Filter) CheckFilter(r *Release) ([]string, bool) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package action
|
||||
package domain
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
@ -6,7 +6,6 @@ import (
|
|||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/autobrr/autobrr/internal/domain"
|
||||
"github.com/autobrr/autobrr/pkg/errors"
|
||||
)
|
||||
|
||||
|
@ -32,7 +31,7 @@ type Macro struct {
|
|||
CurrentSecond int
|
||||
}
|
||||
|
||||
func NewMacro(release domain.Release) Macro {
|
||||
func NewMacro(release Release) Macro {
|
||||
currentTime := time.Now()
|
||||
|
||||
ma := Macro{
|
|
@ -1,12 +1,10 @@
|
|||
package action
|
||||
package domain
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/autobrr/autobrr/internal/domain"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
@ -25,14 +23,14 @@ func TestMacros_Parse(t *testing.T) {
|
|||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
release domain.Release
|
||||
release Release
|
||||
args args
|
||||
want string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "test_ok",
|
||||
release: domain.Release{
|
||||
release: Release{
|
||||
TorrentName: "This movie 2021",
|
||||
TorrentTmpFile: "/tmp/a-temporary-file.torrent",
|
||||
Indexer: "mock1",
|
||||
|
@ -43,7 +41,7 @@ func TestMacros_Parse(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "test_bad",
|
||||
release: domain.Release{
|
||||
release: Release{
|
||||
TorrentName: "This movie 2021",
|
||||
TorrentTmpFile: "/tmp/a-temporary-file.torrent",
|
||||
Indexer: "mock1",
|
||||
|
@ -54,7 +52,7 @@ func TestMacros_Parse(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "test_program_arg",
|
||||
release: domain.Release{
|
||||
release: Release{
|
||||
TorrentName: "This movie 2021",
|
||||
TorrentTmpFile: "/tmp/a-temporary-file.torrent",
|
||||
Indexer: "mock1",
|
||||
|
@ -65,7 +63,7 @@ func TestMacros_Parse(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "test_program_arg_bad",
|
||||
release: domain.Release{
|
||||
release: Release{
|
||||
TorrentTmpFile: "/tmp/a-temporary-file.torrent",
|
||||
Indexer: "mock1",
|
||||
},
|
||||
|
@ -75,7 +73,7 @@ func TestMacros_Parse(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "test_program_arg",
|
||||
release: domain.Release{
|
||||
release: Release{
|
||||
TorrentName: "This movie 2021",
|
||||
TorrentTmpFile: "/tmp/a-temporary-file.torrent",
|
||||
Indexer: "mock1",
|
||||
|
@ -86,7 +84,7 @@ func TestMacros_Parse(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "test_args_long",
|
||||
release: domain.Release{
|
||||
release: Release{
|
||||
TorrentName: "This movie 2021",
|
||||
TorrentURL: "https://some.site/download/fakeid",
|
||||
Indexer: "mock1",
|
||||
|
@ -97,7 +95,7 @@ func TestMacros_Parse(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "test_args_long_1",
|
||||
release: domain.Release{
|
||||
release: Release{
|
||||
TorrentName: "This movie 2021",
|
||||
TorrentURL: "https://some.site/download/fakeid",
|
||||
Indexer: "mock1",
|
||||
|
@ -108,7 +106,7 @@ func TestMacros_Parse(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "test_args_category",
|
||||
release: domain.Release{
|
||||
release: Release{
|
||||
TorrentName: "This movie 2021",
|
||||
TorrentURL: "https://some.site/download/fakeid",
|
||||
Indexer: "mock1",
|
||||
|
@ -119,7 +117,7 @@ func TestMacros_Parse(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "test_args_category_year",
|
||||
release: domain.Release{
|
||||
release: Release{
|
||||
TorrentName: "This movie 2021",
|
||||
TorrentURL: "https://some.site/download/fakeid",
|
||||
Indexer: "mock1",
|
||||
|
@ -130,7 +128,7 @@ func TestMacros_Parse(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "test_args_category_year",
|
||||
release: domain.Release{
|
||||
release: Release{
|
||||
TorrentName: "This movie 2021",
|
||||
TorrentURL: "https://some.site/download/fakeid",
|
||||
Indexer: "mock1",
|
||||
|
@ -143,7 +141,7 @@ func TestMacros_Parse(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "test_args_category_and_if",
|
||||
release: domain.Release{
|
||||
release: Release{
|
||||
TorrentName: "This movie 2021",
|
||||
TorrentURL: "https://some.site/download/fakeid",
|
||||
Indexer: "mock1",
|
||||
|
@ -156,7 +154,7 @@ func TestMacros_Parse(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "test_release_year_1",
|
||||
release: domain.Release{
|
||||
release: Release{
|
||||
TorrentName: "This movie 2021",
|
||||
TorrentURL: "https://some.site/download/fakeid",
|
||||
Indexer: "mock1",
|
|
@ -344,6 +344,10 @@ func (r *Release) addRejection(reason string) {
|
|||
r.Rejections = append(r.Rejections, reason)
|
||||
}
|
||||
|
||||
func (r *Release) AddRejectionF(format string, v ...interface{}) {
|
||||
r.addRejectionF(format, v...)
|
||||
}
|
||||
|
||||
func (r *Release) addRejectionF(format string, v ...interface{}) {
|
||||
r.Rejections = append(r.Rejections, fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
|
|
@ -1,15 +1,22 @@
|
|||
package filter
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/autobrr/autobrr/internal/domain"
|
||||
"github.com/autobrr/autobrr/internal/indexer"
|
||||
"github.com/autobrr/autobrr/internal/logger"
|
||||
"github.com/autobrr/autobrr/pkg/errors"
|
||||
|
||||
"github.com/dustin/go-humanize"
|
||||
"github.com/mattn/go-shellwords"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
|
@ -269,6 +276,37 @@ func (s *service) CheckFilter(f domain.Filter, release *domain.Release) (bool, e
|
|||
}
|
||||
}
|
||||
|
||||
// run external script
|
||||
if f.ExternalScriptEnabled && f.ExternalScriptCmd != "" {
|
||||
exitCode, err := s.execCmd(release, f.ExternalScriptCmd, f.ExternalScriptArgs)
|
||||
if err != nil {
|
||||
s.log.Error().Err(err).Msgf("filter.Service.CheckFilter: error executing external command for filter: %+v", f.Name)
|
||||
return false, err
|
||||
}
|
||||
|
||||
if exitCode != f.ExternalScriptExpectStatus {
|
||||
s.log.Trace().Msgf("filter.Service.CheckFilter: external script unexpected exit code. got: %v want: %v", exitCode, f.ExternalScriptExpectStatus)
|
||||
release.AddRejectionF("external script unexpected exit code. got: %v want: %v", exitCode, f.ExternalScriptExpectStatus)
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
// run external webhook
|
||||
if f.ExternalWebhookEnabled && f.ExternalWebhookHost != "" && f.ExternalWebhookData != "" {
|
||||
// run external scripts
|
||||
statusCode, err := s.webhook(release, f.ExternalWebhookHost, f.ExternalWebhookData)
|
||||
if err != nil {
|
||||
s.log.Error().Err(err).Msgf("filter.Service.CheckFilter: error executing external webhook for filter: %v", f.Name)
|
||||
return false, err
|
||||
}
|
||||
|
||||
if statusCode != f.ExternalWebhookExpectStatus {
|
||||
s.log.Trace().Msgf("filter.Service.CheckFilter: external webhook unexpected status code. got: %v want: %v", statusCode, f.ExternalWebhookExpectStatus)
|
||||
release.AddRejectionF("external webhook unexpected status code. got: %v want: %v", statusCode, f.ExternalWebhookExpectStatus)
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
// found matching filter, lets find the filter actions and attach
|
||||
actions, err := s.actionRepo.FindByFilterID(context.TODO(), f.ID)
|
||||
if err != nil {
|
||||
|
@ -279,7 +317,7 @@ func (s *service) CheckFilter(f domain.Filter, release *domain.Release) (bool, e
|
|||
// if no actions, continue to next filter
|
||||
if len(actions) == 0 {
|
||||
s.log.Trace().Msgf("filter.Service.CheckFilter: no actions found for filter '%v', trying next one..", f.Name)
|
||||
return false, err
|
||||
return false, nil
|
||||
}
|
||||
release.Filter.Actions = actions
|
||||
|
||||
|
@ -371,3 +409,102 @@ func checkSizeFilter(minSize string, maxSize string, releaseSize uint64) (bool,
|
|||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (s *service) execCmd(release *domain.Release, cmd string, args string) (int, error) {
|
||||
s.log.Debug().Msgf("filter exec release: %v", release.TorrentName)
|
||||
|
||||
if release.TorrentTmpFile == "" && strings.Contains(args, "TorrentPathName") {
|
||||
if err := release.DownloadTorrentFile(); err != nil {
|
||||
return 0, errors.Wrap(err, "error downloading torrent file for release: %v", release.TorrentName)
|
||||
}
|
||||
}
|
||||
|
||||
// check if program exists
|
||||
cmd, err := exec.LookPath(cmd)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "exec failed, could not find program: %v", cmd)
|
||||
}
|
||||
|
||||
// handle args and replace vars
|
||||
m := domain.NewMacro(*release)
|
||||
|
||||
// parse and replace values in argument string before continuing
|
||||
parsedArgs, err := m.Parse(args)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "could not parse macro")
|
||||
}
|
||||
|
||||
// we need to split on space into a string slice, so we can spread the args into exec
|
||||
p := shellwords.NewParser()
|
||||
p.ParseBacktick = true
|
||||
commandArgs, err := p.Parse(parsedArgs)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "could not parse into shell-words")
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
|
||||
// setup command and args
|
||||
command := exec.Command(cmd, commandArgs...)
|
||||
|
||||
err = command.Run()
|
||||
var exitErr *exec.ExitError
|
||||
if errors.As(err, &exitErr) {
|
||||
s.log.Debug().Msgf("filter script command exited with non zero code: %v", exitErr.ExitCode())
|
||||
return exitErr.ExitCode(), nil
|
||||
}
|
||||
|
||||
duration := time.Since(start)
|
||||
|
||||
s.log.Debug().Msgf("executed external script: (%v), args: (%v) for release: (%v) indexer: (%v) total time (%v)", cmd, args, release.TorrentName, release.Indexer, duration)
|
||||
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (s *service) webhook(release *domain.Release, url string, data string) (int, error) {
|
||||
|
||||
if release.TorrentTmpFile == "" && strings.Contains(data, "TorrentPathName") {
|
||||
if err := release.DownloadTorrentFile(); err != nil {
|
||||
return 0, errors.Wrap(err, "webhook: could not download torrent file for release: %v", release.TorrentName)
|
||||
}
|
||||
}
|
||||
|
||||
m := domain.NewMacro(*release)
|
||||
|
||||
// parse and replace values in argument string before continuing
|
||||
dataArgs, err := m.Parse(data)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "could not parse webhook data macro: %v", data)
|
||||
}
|
||||
|
||||
t := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
},
|
||||
}
|
||||
|
||||
client := http.Client{Transport: t, Timeout: 15 * time.Second}
|
||||
|
||||
req, err := http.NewRequest(http.MethodPost, url, bytes.NewBufferString(dataArgs))
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "could not build request for webhook")
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("User-Agent", "autobrr")
|
||||
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "could not make request for webhook")
|
||||
}
|
||||
|
||||
defer res.Body.Close()
|
||||
|
||||
if res.StatusCode > 299 {
|
||||
return res.StatusCode, nil
|
||||
}
|
||||
|
||||
s.log.Debug().Msgf("successfully ran external webhook filter to: (%v) payload: (%v)", url, dataArgs)
|
||||
|
||||
return res.StatusCode, nil
|
||||
}
|
||||
|
|
|
@ -114,8 +114,6 @@ func (s *service) Process(release *domain.Release) {
|
|||
release.FilterName = f.Name
|
||||
release.FilterID = f.ID
|
||||
|
||||
// TODO filter limit checks
|
||||
|
||||
// test filter
|
||||
match, err := s.filterSvc.CheckFilter(f, release)
|
||||
if err != nil {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue