feat(actions): qBittorrent add first-last piece priority (#1517)

* feat(actions): qBittorrent add first/last piece priority

* removed accidental change

* fix: scanrow order

* fix: spaces vs tabs

* bump(deps): upgrade go-qbittorrent to v1.9.0

* fix(test): add missing colon

* fix(database): sqlite remove duplicate
This commit is contained in:
s0up4200 2024-04-18 14:47:36 +02:00 committed by GitHub
parent 7b9993b296
commit 56ef3a5402
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 36 additions and 7 deletions

2
go.mod
View file

@ -10,7 +10,7 @@ require (
github.com/anacrolix/torrent v1.55.0
github.com/asaskevich/EventBus v0.0.0-20200907212545-49d423059eef
github.com/autobrr/go-deluge v1.2.0
github.com/autobrr/go-qbittorrent v1.8.1
github.com/autobrr/go-qbittorrent v1.9.0
github.com/autobrr/go-rtorrent v1.10.0
github.com/avast/retry-go v3.0.0+incompatible
github.com/avast/retry-go/v4 v4.5.1

4
go.sum
View file

@ -58,8 +58,8 @@ github.com/asaskevich/EventBus v0.0.0-20200907212545-49d423059eef h1:2JGTg6JapxP
github.com/asaskevich/EventBus v0.0.0-20200907212545-49d423059eef/go.mod h1:JS7hed4L1fj0hXcyEejnW57/7LCetXggd+vwrRnYeII=
github.com/autobrr/go-deluge v1.2.0 h1:psqHrH3nhriRAuxEiN8HpjH/2IW4DsNUxVavoqfi2xI=
github.com/autobrr/go-deluge v1.2.0/go.mod h1:ndiXT1eHWv/ATNk9TpE8GHIs8OSSUnsImt4Syk+y5LM=
github.com/autobrr/go-qbittorrent v1.8.1 h1:QQxuEaCKThTmV0LhU6tHZQvYv+eCrKmiCRY0G1RiJG4=
github.com/autobrr/go-qbittorrent v1.8.1/go.mod h1:z88B3+O/1/3doQABErvIOOxE4hjpmIpulu6XzDG/q78=
github.com/autobrr/go-qbittorrent v1.9.0 h1:HaLueJ99D3G1cQ2r5ADVbtfwyEhekt2eQoEZ7yhAwYs=
github.com/autobrr/go-qbittorrent v1.9.0/go.mod h1:z88B3+O/1/3doQABErvIOOxE4hjpmIpulu6XzDG/q78=
github.com/autobrr/go-rtorrent v1.10.0 h1:SCs7Rdi1BZ3MxNoVIdWK0qTUHQyhSj9rEU8KUTRi4Ug=
github.com/autobrr/go-rtorrent v1.10.0/go.mod h1:1CyQ2tcLOGP+p9drOqFiVPb/+QvfExMPCHnEGQd0BmM=
github.com/autobrr/sse/v2 v2.0.0-20230520125637-530e06346d7d h1:9EGCYgeugAVWLBAtjHC7AFnXSwUdYfCB98WaOgdDREE=

View file

@ -135,6 +135,9 @@ func (s *service) prepareQbitOptions(action *domain.Action) (map[string]string,
if action.SkipHashCheck {
opts.SkipHashCheck = true
}
if action.FirstLastPiecePrio {
opts.FirstLastPiecePrio = true
}
if action.ContentLayout != "" {
if action.ContentLayout == domain.ActionContentLayoutSubfolderCreate {
opts.ContentLayout = qbittorrent.ContentLayoutSubfolderCreate

View file

@ -75,6 +75,7 @@ func (r *ActionRepo) findByFilterID(ctx context.Context, tx *Tx, filterID int, a
"save_path",
"paused",
"ignore_rules",
"first_last_piece_prio",
"skip_hash_check",
"content_layout",
"priority",
@ -124,7 +125,7 @@ func (r *ActionRepo) findByFilterID(ctx context.Context, tx *Tx, filterID int, a
var externalClientID, clientID sql.NullInt32
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, &a.SkipHashCheck, &contentLayout, &priorityLayout, &limitDl, &limitUl, &limitRatio, &limitSeedTime, &a.ReAnnounceSkip, &a.ReAnnounceDelete, &a.ReAnnounceInterval, &a.ReAnnounceMaxAttempts, &webhookHost, &webhookType, &webhookMethod, &webhookData, &externalClientID, &externalClient, &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.FirstLastPiecePrio, &a.SkipHashCheck, &contentLayout, &priorityLayout, &limitDl, &limitUl, &limitRatio, &limitSeedTime, &a.ReAnnounceSkip, &a.ReAnnounceDelete, &a.ReAnnounceInterval, &a.ReAnnounceMaxAttempts, &webhookHost, &webhookType, &webhookMethod, &webhookData, &externalClientID, &externalClient, &clientID); err != nil {
return nil, errors.Wrap(err, "error scanning row")
}
@ -229,6 +230,7 @@ func (r *ActionRepo) List(ctx context.Context) ([]domain.Action, error) {
"save_path",
"paused",
"ignore_rules",
"first_last_piece_prio",
"skip_hash_check",
"content_layout",
"priority",
@ -272,7 +274,7 @@ func (r *ActionRepo) List(ctx context.Context) ([]domain.Action, error) {
var externalClientID, clientID sql.NullInt32
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, &a.SkipHashCheck, &contentLayout, &priorityLayout, &limitDl, &limitUl, &limitRatio, &limitSeedTime, &a.ReAnnounceSkip, &a.ReAnnounceDelete, &a.ReAnnounceInterval, &a.ReAnnounceMaxAttempts, &webhookHost, &webhookType, &webhookMethod, &webhookData, &externalClientID, &externalClient, &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.FirstLastPiecePrio, &a.SkipHashCheck, &contentLayout, &priorityLayout, &limitDl, &limitUl, &limitRatio, &limitSeedTime, &a.ReAnnounceSkip, &a.ReAnnounceDelete, &a.ReAnnounceInterval, &a.ReAnnounceMaxAttempts, &webhookHost, &webhookType, &webhookMethod, &webhookData, &externalClientID, &externalClient, &clientID); err != nil {
return nil, errors.Wrap(err, "error scanning row")
}
@ -325,6 +327,7 @@ func (r *ActionRepo) Get(ctx context.Context, req *domain.GetActionRequest) (*do
"save_path",
"paused",
"ignore_rules",
"first_last_piece_prio",
"skip_hash_check",
"content_layout",
"priority",
@ -370,7 +373,7 @@ func (r *ActionRepo) Get(ctx context.Context, req *domain.GetActionRequest) (*do
var externalClientID, clientID, filterID sql.NullInt32
var paused, ignoreRules sql.NullBool
if err := row.Scan(&a.ID, &a.Name, &a.Type, &a.Enabled, &execCmd, &execArgs, &watchFolder, &category, &tags, &label, &savePath, &paused, &ignoreRules, &a.SkipHashCheck, &contentLayout, &priorityLayout, &limitDl, &limitUl, &limitRatio, &limitSeedTime, &a.ReAnnounceSkip, &a.ReAnnounceDelete, &a.ReAnnounceInterval, &a.ReAnnounceMaxAttempts, &webhookHost, &webhookType, &webhookMethod, &webhookData, &externalClientID, &externalClient, &clientID, &filterID); err != nil {
if err := row.Scan(&a.ID, &a.Name, &a.Type, &a.Enabled, &execCmd, &execArgs, &watchFolder, &category, &tags, &label, &savePath, &paused, &ignoreRules, &a.FirstLastPiecePrio, &a.SkipHashCheck, &contentLayout, &priorityLayout, &limitDl, &limitUl, &limitRatio, &limitSeedTime, &a.ReAnnounceSkip, &a.ReAnnounceDelete, &a.ReAnnounceInterval, &a.ReAnnounceMaxAttempts, &webhookHost, &webhookType, &webhookMethod, &webhookData, &externalClientID, &externalClient, &clientID, &filterID); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, domain.ErrRecordNotFound
}
@ -464,6 +467,7 @@ func (r *ActionRepo) Store(ctx context.Context, action domain.Action) (*domain.A
"save_path",
"paused",
"ignore_rules",
"first_last_piece_prio",
"skip_hash_check",
"content_layout",
"priority",
@ -497,6 +501,7 @@ func (r *ActionRepo) Store(ctx context.Context, action domain.Action) (*domain.A
toNullString(action.SavePath),
action.Paused,
action.IgnoreRules,
action.FirstLastPiecePrio,
action.SkipHashCheck,
toNullString(string(action.ContentLayout)),
toNullString(string(action.PriorityLayout)),
@ -548,6 +553,7 @@ func (r *ActionRepo) Update(ctx context.Context, action domain.Action) (*domain.
Set("save_path", toNullString(action.SavePath)).
Set("paused", action.Paused).
Set("ignore_rules", action.IgnoreRules).
Set("first_last_piece_prio", action.FirstLastPiecePrio).
Set("skip_hash_check", action.SkipHashCheck).
Set("content_layout", toNullString(string(action.ContentLayout))).
Set("priority", toNullString(string(action.PriorityLayout))).
@ -609,6 +615,7 @@ func (r *ActionRepo) StoreFilterActions(ctx context.Context, filterID int64, act
Set("save_path", toNullString(action.SavePath)).
Set("paused", action.Paused).
Set("ignore_rules", action.IgnoreRules).
Set("first_last_piece_prio", action.FirstLastPiecePrio).
Set("skip_hash_check", action.SkipHashCheck).
Set("content_layout", toNullString(string(action.ContentLayout))).
Set("priority", toNullString(string(action.PriorityLayout))).
@ -657,6 +664,7 @@ func (r *ActionRepo) StoreFilterActions(ctx context.Context, filterID int64, act
"save_path",
"paused",
"ignore_rules",
"first_last_piece_prio",
"skip_hash_check",
"content_layout",
"priority",
@ -690,6 +698,7 @@ func (r *ActionRepo) StoreFilterActions(ctx context.Context, filterID int64, act
toNullString(action.SavePath),
action.Paused,
action.IgnoreRules,
action.FirstLastPiecePrio,
action.SkipHashCheck,
toNullString(string(action.ContentLayout)),
toNullString(string(action.PriorityLayout)),

View file

@ -31,6 +31,7 @@ func getMockAction() domain.Action {
Paused: false,
IgnoreRules: false,
SkipHashCheck: false,
FirstLastPiecePrio: false,
ContentLayout: domain.ActionContentLayoutOriginal,
LimitUploadSpeed: 0,
LimitDownloadSpeed: 0,

View file

@ -197,6 +197,7 @@ CREATE TABLE action
save_path TEXT,
paused BOOLEAN,
ignore_rules BOOLEAN,
first_last_piece_prio BOOLEAN DEFAULT false,
skip_hash_check BOOLEAN DEFAULT false,
content_layout TEXT,
limit_upload_speed INT,
@ -873,5 +874,8 @@ ALTER TABLE filter
ELSE name
END
WHERE server = 'irc.animebytes.tv';
`,
`ALTER TABLE action
ADD COLUMN first_last_piece_prio BOOLEAN DEFAULT false;
`,
}

View file

@ -197,6 +197,7 @@ CREATE TABLE action
save_path TEXT,
paused BOOLEAN,
ignore_rules BOOLEAN,
first_last_piece_prio BOOLEAN DEFAULT false,
skip_hash_check BOOLEAN DEFAULT false,
content_layout TEXT,
limit_upload_speed INT,
@ -1511,5 +1512,8 @@ ALTER TABLE filter
ELSE name
END
WHERE server = 'irc.animebytes.tv';
`,
`ALTER TABLE action
ADD COLUMN first_last_piece_prio BOOLEAN DEFAULT false;
`,
}

View file

@ -36,6 +36,7 @@ type Action struct {
SavePath string `json:"save_path,omitempty"`
Paused bool `json:"paused,omitempty"`
IgnoreRules bool `json:"ignore_rules,omitempty"`
FirstLastPiecePrio bool `json:"first_last_piece_prio,omitempty"`
SkipHashCheck bool `json:"skip_hash_check,omitempty"`
ContentLayout ActionContentLayout `json:"content_layout,omitempty"`
LimitUploadSpeed int64 `json:"limit_upload_speed,omitempty"`

View file

@ -51,6 +51,7 @@ export function Actions() {
save_path: "",
paused: false,
ignore_rules: false,
first_last_piece_prio: false,
skip_hash_check: false,
content_layout: "" || undefined,
priority: "" || undefined,

View file

@ -109,6 +109,11 @@ export const QBittorrent = ({ idx, action, clients }: ClientActionProps) => (
label="Skip hash check"
description="Add torrent and skip hash check"
/>
<Input.SwitchGroup
name={`actions.${idx}.first_last_piece_prio`}
label="Download first and last pieces first"
description="Add torrent and download first and last pieces first"
/>
</FilterSection.HalfRow>
<FilterSection.HalfRow>
<Input.Select

View file

@ -92,7 +92,8 @@ interface Action {
save_path?: string;
paused?: boolean;
ignore_rules?: boolean;
skip_hash_check: boolean;
first_last_piece_prio?: boolean;
skip_hash_check?: boolean;
content_layout?: ActionContentLayout;
priority?: ActionPriorityLayout;
limit_upload_speed?: number;