feat(actions): qbit add options content layout and skip hash check (#393)

* feat(actions): qbit content layout and skip hash check

* feat(actions): qbit options
This commit is contained in:
ze0s 2022-08-02 18:06:45 +02:00 committed by GitHub
parent db9d048f5d
commit 9508cbb46c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 394 additions and 50 deletions

View file

@ -2,7 +2,6 @@ package action
import (
"context"
"strconv"
"strings"
"time"
@ -102,10 +101,23 @@ func (s *service) qbittorrent(action domain.Action, release domain.Release) ([]s
func (s *service) prepareQbitOptions(action domain.Action, m domain.Macro) (map[string]string, error) {
options := map[string]string{}
opts := &qbittorrent.TorrentAddOptions{}
if action.Paused {
options["paused"] = "true"
opts.Paused = BoolPointer(true)
}
if action.SkipHashCheck {
opts.SkipHashCheck = BoolPointer(true)
}
if action.ContentLayout != "" {
if action.ContentLayout == domain.ActionContentLayoutSubfolderCreate {
layout := qbittorrent.ContentLayoutSubfolderCreate
opts.ContentLayout = &layout
} else if action.ContentLayout == domain.ActionContentLayoutSubfolderNone {
layout := qbittorrent.ContentLayoutSubfolderNone
opts.ContentLayout = &layout
}
// if ORIGINAL then leave empty
}
if action.SavePath != "" {
// parse and replace values in argument string before continuing
@ -114,8 +126,8 @@ func (s *service) prepareQbitOptions(action domain.Action, m domain.Macro) (map[
return nil, errors.Wrap(err, "could not parse savepath macro: %v", action.SavePath)
}
options["savepath"] = actionArgs
options["autoTMM"] = "false"
opts.SavePath = &actionArgs
opts.AutoTMM = BoolPointer(false)
}
if action.Category != "" {
// parse and replace values in argument string before continuing
@ -124,7 +136,7 @@ func (s *service) prepareQbitOptions(action domain.Action, m domain.Macro) (map[
return nil, errors.Wrap(err, "could not parse category macro: %v", action.Category)
}
options["category"] = categoryArgs
opts.Category = &categoryArgs
}
if action.Tags != "" {
// parse and replace values in argument string before continuing
@ -133,22 +145,26 @@ func (s *service) prepareQbitOptions(action domain.Action, m domain.Macro) (map[
return nil, errors.Wrap(err, "could not parse tags macro: %v", action.Tags)
}
options["tags"] = tagsArgs
opts.Tags = &tagsArgs
}
if action.LimitUploadSpeed > 0 {
options["upLimit"] = strconv.FormatInt(action.LimitUploadSpeed*1000, 10)
opts.LimitUploadSpeed = &action.LimitUploadSpeed
}
if action.LimitDownloadSpeed > 0 {
options["dlLimit"] = strconv.FormatInt(action.LimitDownloadSpeed*1000, 10)
opts.LimitDownloadSpeed = &action.LimitDownloadSpeed
}
if action.LimitRatio > 0 {
options["ratioLimit"] = strconv.FormatFloat(action.LimitRatio, 'r', 2, 64)
opts.LimitRatio = &action.LimitRatio
}
if action.LimitSeedTime > 0 {
options["seedingTimeLimit"] = strconv.FormatInt(action.LimitSeedTime, 10)
opts.LimitSeedTime = &action.LimitSeedTime
}
return options, nil
return opts.Prepare(), nil
}
func BoolPointer(b bool) *bool {
return &b
}
func (s *service) qbittorrentCheckRulesCanDownload(action domain.Action, client *domain.DownloadClient, qbt *qbittorrent.Client) ([]string, error) {

View file

@ -70,6 +70,8 @@ func (r *ActionRepo) findByFilterID(ctx context.Context, tx *Tx, filterID int) (
"save_path",
"paused",
"ignore_rules",
"skip_hash_check",
"content_layout",
"limit_download_speed",
"limit_upload_speed",
"limit_ratio",
@ -103,7 +105,7 @@ func (r *ActionRepo) findByFilterID(ctx context.Context, tx *Tx, filterID int) (
for rows.Next() {
var a domain.Action
var execCmd, execArgs, watchFolder, category, tags, label, savePath, webhookHost, webhookType, webhookMethod, webhookData sql.NullString
var execCmd, execArgs, watchFolder, category, tags, label, savePath, contentLayout, webhookHost, webhookType, webhookMethod, webhookData sql.NullString
var limitUl, limitDl, limitSeedTime sql.NullInt64
var limitRatio sql.NullFloat64
@ -111,7 +113,7 @@ func (r *ActionRepo) findByFilterID(ctx context.Context, tx *Tx, filterID int) (
// filterID
var paused, ignoreRules sql.NullBool
if err := rows.Scan(&a.ID, &a.Name, &a.Type, &a.Enabled, &execCmd, &execArgs, &watchFolder, &category, &tags, &label, &savePath, &paused, &ignoreRules, &limitDl, &limitUl, &limitRatio, &limitSeedTime, &a.ReAnnounceSkip, &a.ReAnnounceDelete, &a.ReAnnounceInterval, &a.ReAnnounceMaxAttempts, &webhookHost, &webhookType, &webhookMethod, &webhookData, &clientID); err != nil {
if err := rows.Scan(&a.ID, &a.Name, &a.Type, &a.Enabled, &execCmd, &execArgs, &watchFolder, &category, &tags, &label, &savePath, &paused, &ignoreRules, &a.SkipHashCheck, &contentLayout, &limitDl, &limitUl, &limitRatio, &limitSeedTime, &a.ReAnnounceSkip, &a.ReAnnounceDelete, &a.ReAnnounceInterval, &a.ReAnnounceMaxAttempts, &webhookHost, &webhookType, &webhookMethod, &webhookData, &clientID); err != nil {
return nil, errors.Wrap(err, "error scanning row")
}
@ -124,6 +126,7 @@ func (r *ActionRepo) findByFilterID(ctx context.Context, tx *Tx, filterID int) (
a.SavePath = savePath.String
a.Paused = paused.Bool
a.IgnoreRules = ignoreRules.Bool
a.ContentLayout = domain.ActionContentLayout(contentLayout.String)
a.LimitDownloadSpeed = limitDl.Int64
a.LimitUploadSpeed = limitUl.Int64
@ -324,6 +327,7 @@ func (r *ActionRepo) Store(ctx context.Context, action domain.Action) (*domain.A
tags := toNullString(action.Tags)
label := toNullString(action.Label)
savePath := toNullString(action.SavePath)
contentLayout := toNullString(string(action.ContentLayout))
webhookHost := toNullString(action.WebhookHost)
webhookData := toNullString(action.WebhookData)
webhookType := toNullString(action.WebhookType)
@ -351,6 +355,8 @@ func (r *ActionRepo) Store(ctx context.Context, action domain.Action) (*domain.A
"save_path",
"paused",
"ignore_rules",
"skip_hash_check",
"content_layout",
"limit_upload_speed",
"limit_download_speed",
"limit_ratio",
@ -379,6 +385,8 @@ func (r *ActionRepo) Store(ctx context.Context, action domain.Action) (*domain.A
savePath,
action.Paused,
action.IgnoreRules,
action.SkipHashCheck,
contentLayout,
limitUL,
limitDL,
limitRatio,
@ -418,6 +426,7 @@ func (r *ActionRepo) Update(ctx context.Context, action domain.Action) (*domain.
tags := toNullString(action.Tags)
label := toNullString(action.Label)
savePath := toNullString(action.SavePath)
contentLayout := toNullString(string(action.ContentLayout))
webhookHost := toNullString(action.WebhookHost)
webhookType := toNullString(action.WebhookType)
webhookMethod := toNullString(action.WebhookMethod)
@ -447,6 +456,8 @@ func (r *ActionRepo) Update(ctx context.Context, action domain.Action) (*domain.
Set("save_path", savePath).
Set("paused", action.Paused).
Set("ignore_rules", action.IgnoreRules).
Set("skip_hash_check", action.SkipHashCheck).
Set("content_layout", contentLayout).
Set("limit_upload_speed", limitUL).
Set("limit_download_speed", limitDL).
Set("limit_ratio", limitRatio).
@ -507,6 +518,7 @@ func (r *ActionRepo) StoreFilterActions(ctx context.Context, actions []*domain.A
tags := toNullString(action.Tags)
label := toNullString(action.Label)
savePath := toNullString(action.SavePath)
contentLayout := toNullString(string(action.ContentLayout))
webhookHost := toNullString(action.WebhookHost)
webhookType := toNullString(action.WebhookType)
webhookMethod := toNullString(action.WebhookMethod)
@ -533,6 +545,8 @@ func (r *ActionRepo) StoreFilterActions(ctx context.Context, actions []*domain.A
"save_path",
"paused",
"ignore_rules",
"skip_hash_check",
"content_layout",
"limit_upload_speed",
"limit_download_speed",
"limit_ratio",
@ -561,6 +575,8 @@ func (r *ActionRepo) StoreFilterActions(ctx context.Context, actions []*domain.A
savePath,
action.Paused,
action.IgnoreRules,
action.SkipHashCheck,
contentLayout,
limitUL,
limitDL,
limitRatio,

View file

@ -78,5 +78,7 @@ func (db *DB) migratePostgres() error {
return errors.Wrap(err, "failed to bump schema version")
}
db.log.Info().Msgf("Database schema upgraded to version: %v", len(postgresMigrations))
return tx.Commit()
}

View file

@ -158,6 +158,8 @@ CREATE TABLE action
save_path TEXT,
paused BOOLEAN,
ignore_rules BOOLEAN,
skip_hash_check BOOLEAN DEFAULT false,
content_layout TEXT,
limit_upload_speed INT,
limit_download_speed INT,
limit_ratio REAL,
@ -527,4 +529,11 @@ CREATE INDEX indexer_identifier_index
ALTER TABLE filter
ADD COLUMN external_webhook_expect_status INTEGER;
`,
`
ALTER TABLE action
ADD COLUMN skip_hash_check BOOLEAN DEFAULT FALSE;
ALTER TABLE action
ADD COLUMN content_layout TEXT;
`,
}

View file

@ -98,6 +98,8 @@ func (db *DB) migrateSQLite() error {
return errors.Wrap(err, "failed to bump schema version")
}
db.log.Info().Msgf("Database schema upgraded to version: %v", len(sqliteMigrations))
return tx.Commit()
}

View file

@ -158,6 +158,8 @@ CREATE TABLE action
save_path TEXT,
paused BOOLEAN,
ignore_rules BOOLEAN,
skip_hash_check BOOLEAN DEFAULT false,
content_layout TEXT,
limit_upload_speed INT,
limit_download_speed INT,
limit_ratio REAL,
@ -847,4 +849,11 @@ CREATE INDEX indexer_identifier_index
ALTER TABLE filter
ADD COLUMN external_webhook_expect_status INTEGER;
`,
`
ALTER TABLE action
ADD COLUMN skip_hash_check BOOLEAN DEFAULT FALSE;
ALTER TABLE action
ADD COLUMN content_layout TEXT;
`,
}

View file

@ -13,35 +13,37 @@ type ActionRepo interface {
}
type Action struct {
ID int `json:"id"`
Name string `json:"name"`
Type ActionType `json:"type"`
Enabled bool `json:"enabled"`
ExecCmd string `json:"exec_cmd,omitempty"`
ExecArgs string `json:"exec_args,omitempty"`
WatchFolder string `json:"watch_folder,omitempty"`
Category string `json:"category,omitempty"`
Tags string `json:"tags,omitempty"`
Label string `json:"label,omitempty"`
SavePath string `json:"save_path,omitempty"`
Paused bool `json:"paused,omitempty"`
IgnoreRules bool `json:"ignore_rules,omitempty"`
LimitUploadSpeed int64 `json:"limit_upload_speed,omitempty"`
LimitDownloadSpeed int64 `json:"limit_download_speed,omitempty"`
LimitRatio float64 `json:"limit_ratio,omitempty"`
LimitSeedTime int64 `json:"limit_seed_time,omitempty"`
ReAnnounceSkip bool `json:"reannounce_skip,omitempty"`
ReAnnounceDelete bool `json:"reannounce_delete,omitempty"`
ReAnnounceInterval int64 `json:"reannounce_interval,omitempty"`
ReAnnounceMaxAttempts int64 `json:"reannounce_max_attempts,omitempty"`
WebhookHost string `json:"webhook_host,omitempty"`
WebhookType string `json:"webhook_type,omitempty"`
WebhookMethod string `json:"webhook_method,omitempty"`
WebhookData string `json:"webhook_data,omitempty"`
WebhookHeaders []string `json:"webhook_headers,omitempty"`
FilterID int `json:"filter_id,omitempty"`
ClientID int32 `json:"client_id,omitempty"`
Client DownloadClient `json:"client,omitempty"`
ID int `json:"id"`
Name string `json:"name"`
Type ActionType `json:"type"`
Enabled bool `json:"enabled"`
ExecCmd string `json:"exec_cmd,omitempty"`
ExecArgs string `json:"exec_args,omitempty"`
WatchFolder string `json:"watch_folder,omitempty"`
Category string `json:"category,omitempty"`
Tags string `json:"tags,omitempty"`
Label string `json:"label,omitempty"`
SavePath string `json:"save_path,omitempty"`
Paused bool `json:"paused,omitempty"`
IgnoreRules bool `json:"ignore_rules,omitempty"`
SkipHashCheck bool `json:"skip_hash_check,omitempty"`
ContentLayout ActionContentLayout `json:"content_layout,omitempty"`
LimitUploadSpeed int64 `json:"limit_upload_speed,omitempty"`
LimitDownloadSpeed int64 `json:"limit_download_speed,omitempty"`
LimitRatio float64 `json:"limit_ratio,omitempty"`
LimitSeedTime int64 `json:"limit_seed_time,omitempty"`
ReAnnounceSkip bool `json:"reannounce_skip,omitempty"`
ReAnnounceDelete bool `json:"reannounce_delete,omitempty"`
ReAnnounceInterval int64 `json:"reannounce_interval,omitempty"`
ReAnnounceMaxAttempts int64 `json:"reannounce_max_attempts,omitempty"`
WebhookHost string `json:"webhook_host,omitempty"`
WebhookType string `json:"webhook_type,omitempty"`
WebhookMethod string `json:"webhook_method,omitempty"`
WebhookData string `json:"webhook_data,omitempty"`
WebhookHeaders []string `json:"webhook_headers,omitempty"`
FilterID int `json:"filter_id,omitempty"`
ClientID int32 `json:"client_id,omitempty"`
Client DownloadClient `json:"client,omitempty"`
}
type ActionType string
@ -60,3 +62,11 @@ const (
ActionTypeLidarr ActionType = "LIDARR"
ActionTypeWhisparr ActionType = "WHISPARR"
)
type ActionContentLayout string
const (
ActionContentLayoutOriginal ActionContentLayout = "ORIGINAL"
ActionContentLayoutSubfolderNone ActionContentLayout = "SUBFOLDER_NONE"
ActionContentLayoutSubfolderCreate ActionContentLayout = "SUBFOLDER_CREATE"
)

View file

@ -83,14 +83,14 @@ func (s *service) FindByID(ctx context.Context, filterID int) (*domain.Filter, e
// find actions and attach
actions, err := s.actionRepo.FindByFilterID(ctx, filter.ID)
if err != nil {
s.log.Error().Msgf("could not find filter actions: %+v", &filter.ID)
s.log.Error().Msgf("could not find filter actions for filter id: %v", filter.ID)
}
filter.Actions = actions
// find indexers and attach
indexers, err := s.indexerSvc.FindByFilterID(ctx, filter.ID)
if err != nil {
s.log.Error().Err(err).Msgf("could not find indexers for filter: %+v", &filter.Name)
s.log.Error().Err(err).Msgf("could not find indexers for filter: %v", filter.Name)
return nil, err
}
filter.Indexers = indexers