mirror of
https://github.com/idanoo/autobrr
synced 2025-07-22 16:29:12 +00:00
feat(actions): qBittorrent add priority handling (#1315)
* feat(qbittorrent): add priority handling * fix: check if torrent queueing is enabled * fix: only check for torrent queueing if priority is set * fix: improve tooltip message * feat: enable torrent queueing if disabled * change to SetPreferencesQueueingEnabled * feat(actions): rename field * chore: bump pkg go-qbittorrent to v1.8.0 * chore(deps): update go-qbittorrent to v1.8.1 * chore(deps): go mod tidy --------- Co-authored-by: ze0s <ze0s@riseup.net>
This commit is contained in:
parent
0ab404f81a
commit
c6122dbc41
11 changed files with 115 additions and 30 deletions
4
go.mod
4
go.mod
|
@ -10,7 +10,7 @@ require (
|
|||
github.com/anacrolix/torrent v1.53.1
|
||||
github.com/asaskevich/EventBus v0.0.0-20200907212545-49d423059eef
|
||||
github.com/autobrr/go-deluge v1.1.0
|
||||
github.com/autobrr/go-qbittorrent v1.7.2-0.20231029234932-67580aa0e42a
|
||||
github.com/autobrr/go-qbittorrent v1.8.1
|
||||
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
|
||||
|
@ -18,6 +18,7 @@ require (
|
|||
github.com/dustin/go-humanize v1.0.1
|
||||
github.com/ergochat/irc-go v0.4.0
|
||||
github.com/fsnotify/fsnotify v1.7.0
|
||||
github.com/go-andiamo/splitter v1.2.5
|
||||
github.com/go-chi/chi/v5 v5.0.10
|
||||
github.com/go-chi/render v1.0.3
|
||||
github.com/gorilla/sessions v1.2.2
|
||||
|
@ -61,7 +62,6 @@ require (
|
|||
github.com/bradfitz/iter v0.0.0-20191230175014-e8f45d346db8 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/gdm85/go-rencode v0.1.8 // indirect
|
||||
github.com/go-andiamo/splitter v1.2.5 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/gorilla/securecookie v1.1.2 // indirect
|
||||
github.com/gosimple/unidecode v1.0.1 // indirect
|
||||
|
|
10
go.sum
10
go.sum
|
@ -94,8 +94,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.1.0 h1:wT+FUxjNrYnUhOcZmZSIApCz4tT2n0FzXVfuvOBtcIM=
|
||||
github.com/autobrr/go-deluge v1.1.0/go.mod h1:ndiXT1eHWv/ATNk9TpE8GHIs8OSSUnsImt4Syk+y5LM=
|
||||
github.com/autobrr/go-qbittorrent v1.7.2-0.20231029234932-67580aa0e42a h1:oMPFpu0QXbkpeJu1LhcO2+pu5pff2cQLWQx/Fv5z8AM=
|
||||
github.com/autobrr/go-qbittorrent v1.7.2-0.20231029234932-67580aa0e42a/go.mod h1:z88B3+O/1/3doQABErvIOOxE4hjpmIpulu6XzDG/q78=
|
||||
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-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=
|
||||
|
@ -475,8 +475,6 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
|
|||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
|
||||
golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No=
|
||||
golang.org/x/exp v0.0.0-20231127185646-65229373498e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
|
@ -504,8 +502,6 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
|
||||
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
@ -702,8 +698,6 @@ golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4f
|
|||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
|
||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||
golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM=
|
||||
golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
|
|
@ -65,6 +65,45 @@ func (s *service) qbittorrent(ctx context.Context, action *domain.Action, releas
|
|||
return nil, errors.Wrap(err, "could not add torrent %s to client: %s", release.TorrentTmpFile, c.Dc.Name)
|
||||
}
|
||||
|
||||
if release.TorrentHash != "" {
|
||||
// check if torrent queueing is enabled if priority is set
|
||||
switch action.PriorityLayout {
|
||||
case domain.PriorityLayoutMax, domain.PriorityLayoutMin:
|
||||
prefs, err := c.Qbt.GetAppPreferencesCtx(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get application preferences from client: '%s'", c.Dc.Name)
|
||||
}
|
||||
// enable queueing if it's disabled
|
||||
if !prefs.QueueingEnabled {
|
||||
if err := c.Qbt.SetPreferencesQueueingEnabled(true); err != nil {
|
||||
return nil, errors.Wrap(err, "could not enable torrent queueing")
|
||||
}
|
||||
s.log.Trace().Msgf("torrent queueing was disabled, now enabled in client: '%s'", c.Dc.Name)
|
||||
}
|
||||
// set priority if queueing is enabled
|
||||
if action.PriorityLayout == domain.PriorityLayoutMax {
|
||||
if err := c.Qbt.SetMaxPriorityCtx(ctx, []string{release.TorrentHash}); err != nil {
|
||||
return nil, errors.Wrap(err, "could not set torrent %s to max priority", release.TorrentHash)
|
||||
}
|
||||
s.log.Debug().Msgf("torrent with hash %s set to max priority in client: '%s'", release.TorrentHash, c.Dc.Name)
|
||||
|
||||
} else { // domain.PriorityLayoutMin
|
||||
if err := c.Qbt.SetMinPriorityCtx(ctx, []string{release.TorrentHash}); err != nil {
|
||||
return nil, errors.Wrap(err, "could not set torrent %s to min priority", release.TorrentHash)
|
||||
}
|
||||
s.log.Debug().Msgf("torrent with hash %s set to min priority in client: '%s'", release.TorrentHash, c.Dc.Name)
|
||||
}
|
||||
|
||||
case domain.PriorityLayoutDefault:
|
||||
// do nothing as it's disabled or unset
|
||||
default:
|
||||
s.log.Warn().Msgf("unknown priority setting: '%v', no priority changes made", action.PriorityLayout)
|
||||
}
|
||||
} else {
|
||||
// add anyway if no hash
|
||||
s.log.Trace().Msg("no torrent hash provided, skipping priority setting")
|
||||
}
|
||||
|
||||
if !action.Paused && !action.ReAnnounceSkip && release.TorrentHash != "" {
|
||||
opts := qbittorrent.ReannounceOptions{
|
||||
Interval: int(action.ReAnnounceInterval),
|
||||
|
|
|
@ -77,6 +77,7 @@ func (r *ActionRepo) findByFilterID(ctx context.Context, tx *Tx, filterID int, a
|
|||
"ignore_rules",
|
||||
"skip_hash_check",
|
||||
"content_layout",
|
||||
"priority",
|
||||
"limit_download_speed",
|
||||
"limit_upload_speed",
|
||||
"limit_ratio",
|
||||
|
@ -115,14 +116,14 @@ func (r *ActionRepo) findByFilterID(ctx context.Context, tx *Tx, filterID int, a
|
|||
for rows.Next() {
|
||||
var a domain.Action
|
||||
|
||||
var execCmd, execArgs, watchFolder, category, tags, label, savePath, contentLayout, webhookHost, webhookType, webhookMethod, webhookData sql.NullString
|
||||
var execCmd, execArgs, watchFolder, category, tags, label, savePath, contentLayout, priorityLayout, webhookHost, webhookType, webhookMethod, webhookData sql.NullString
|
||||
var limitUl, limitDl, limitSeedTime sql.NullInt64
|
||||
var limitRatio sql.NullFloat64
|
||||
|
||||
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, &limitDl, &limitUl, &limitRatio, &limitSeedTime, &a.ReAnnounceSkip, &a.ReAnnounceDelete, &a.ReAnnounceInterval, &a.ReAnnounceMaxAttempts, &webhookHost, &webhookType, &webhookMethod, &webhookData, &externalClientID, &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, &priorityLayout, &limitDl, &limitUl, &limitRatio, &limitSeedTime, &a.ReAnnounceSkip, &a.ReAnnounceDelete, &a.ReAnnounceInterval, &a.ReAnnounceMaxAttempts, &webhookHost, &webhookType, &webhookMethod, &webhookData, &externalClientID, &clientID); err != nil {
|
||||
return nil, errors.Wrap(err, "error scanning row")
|
||||
}
|
||||
|
||||
|
@ -136,6 +137,7 @@ func (r *ActionRepo) findByFilterID(ctx context.Context, tx *Tx, filterID int, a
|
|||
a.Paused = paused.Bool
|
||||
a.IgnoreRules = ignoreRules.Bool
|
||||
a.ContentLayout = domain.ActionContentLayout(contentLayout.String)
|
||||
a.PriorityLayout = domain.PriorityLayout(priorityLayout.String)
|
||||
|
||||
a.LimitDownloadSpeed = limitDl.Int64
|
||||
a.LimitUploadSpeed = limitUl.Int64
|
||||
|
@ -227,6 +229,7 @@ func (r *ActionRepo) List(ctx context.Context) ([]domain.Action, error) {
|
|||
"ignore_rules",
|
||||
"skip_hash_check",
|
||||
"content_layout",
|
||||
"priority",
|
||||
"limit_download_speed",
|
||||
"limit_upload_speed",
|
||||
"limit_ratio",
|
||||
|
@ -260,13 +263,13 @@ func (r *ActionRepo) List(ctx context.Context) ([]domain.Action, error) {
|
|||
for rows.Next() {
|
||||
var a domain.Action
|
||||
|
||||
var execCmd, execArgs, watchFolder, category, tags, label, savePath, contentLayout, webhookHost, webhookType, webhookMethod, webhookData sql.NullString
|
||||
var execCmd, execArgs, watchFolder, category, tags, label, savePath, contentLayout, priorityLayout, webhookHost, webhookType, webhookMethod, webhookData sql.NullString
|
||||
var limitUl, limitDl, limitSeedTime sql.NullInt64
|
||||
var limitRatio sql.NullFloat64
|
||||
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, &limitDl, &limitUl, &limitRatio, &limitSeedTime, &a.ReAnnounceSkip, &a.ReAnnounceDelete, &a.ReAnnounceInterval, &a.ReAnnounceMaxAttempts, &webhookHost, &webhookType, &webhookMethod, &webhookData, &externalClientID, &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, &priorityLayout, &limitDl, &limitUl, &limitRatio, &limitSeedTime, &a.ReAnnounceSkip, &a.ReAnnounceDelete, &a.ReAnnounceInterval, &a.ReAnnounceMaxAttempts, &webhookHost, &webhookType, &webhookMethod, &webhookData, &externalClientID, &clientID); err != nil {
|
||||
return nil, errors.Wrap(err, "error scanning row")
|
||||
}
|
||||
|
||||
|
@ -277,6 +280,7 @@ func (r *ActionRepo) List(ctx context.Context) ([]domain.Action, error) {
|
|||
a.Paused = paused.Bool
|
||||
a.IgnoreRules = ignoreRules.Bool
|
||||
a.ContentLayout = domain.ActionContentLayout(contentLayout.String)
|
||||
a.PriorityLayout = domain.PriorityLayout(priorityLayout.String)
|
||||
|
||||
a.LimitDownloadSpeed = limitDl.Int64
|
||||
a.LimitUploadSpeed = limitUl.Int64
|
||||
|
@ -319,6 +323,7 @@ func (r *ActionRepo) Get(ctx context.Context, req *domain.GetActionRequest) (*do
|
|||
"ignore_rules",
|
||||
"skip_hash_check",
|
||||
"content_layout",
|
||||
"priority",
|
||||
"limit_download_speed",
|
||||
"limit_upload_speed",
|
||||
"limit_ratio",
|
||||
|
@ -354,13 +359,13 @@ func (r *ActionRepo) Get(ctx context.Context, req *domain.GetActionRequest) (*do
|
|||
|
||||
var a domain.Action
|
||||
|
||||
var execCmd, execArgs, watchFolder, category, tags, label, savePath, contentLayout, webhookHost, webhookType, webhookMethod, webhookData sql.NullString
|
||||
var execCmd, execArgs, watchFolder, category, tags, label, savePath, contentLayout, priorityLayout, webhookHost, webhookType, webhookMethod, webhookData sql.NullString
|
||||
var limitUl, limitDl, limitSeedTime sql.NullInt64
|
||||
var limitRatio sql.NullFloat64
|
||||
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, &limitDl, &limitUl, &limitRatio, &limitSeedTime, &a.ReAnnounceSkip, &a.ReAnnounceDelete, &a.ReAnnounceInterval, &a.ReAnnounceMaxAttempts, &webhookHost, &webhookType, &webhookMethod, &webhookData, &externalClientID, &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.SkipHashCheck, &contentLayout, &priorityLayout, &limitDl, &limitUl, &limitRatio, &limitSeedTime, &a.ReAnnounceSkip, &a.ReAnnounceDelete, &a.ReAnnounceInterval, &a.ReAnnounceMaxAttempts, &webhookHost, &webhookType, &webhookMethod, &webhookData, &externalClientID, &clientID, &filterID); err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return nil, domain.ErrRecordNotFound
|
||||
}
|
||||
|
@ -378,6 +383,7 @@ func (r *ActionRepo) Get(ctx context.Context, req *domain.GetActionRequest) (*do
|
|||
a.Paused = paused.Bool
|
||||
a.IgnoreRules = ignoreRules.Bool
|
||||
a.ContentLayout = domain.ActionContentLayout(contentLayout.String)
|
||||
a.PriorityLayout = domain.PriorityLayout(priorityLayout.String)
|
||||
|
||||
a.LimitDownloadSpeed = limitDl.Int64
|
||||
a.LimitUploadSpeed = limitUl.Int64
|
||||
|
@ -454,6 +460,7 @@ func (r *ActionRepo) Store(ctx context.Context, action domain.Action) (*domain.A
|
|||
"ignore_rules",
|
||||
"skip_hash_check",
|
||||
"content_layout",
|
||||
"priority",
|
||||
"limit_upload_speed",
|
||||
"limit_download_speed",
|
||||
"limit_ratio",
|
||||
|
@ -485,6 +492,7 @@ func (r *ActionRepo) Store(ctx context.Context, action domain.Action) (*domain.A
|
|||
action.IgnoreRules,
|
||||
action.SkipHashCheck,
|
||||
toNullString(string(action.ContentLayout)),
|
||||
toNullString(string(action.PriorityLayout)),
|
||||
toNullInt64(action.LimitUploadSpeed),
|
||||
toNullInt64(action.LimitDownloadSpeed),
|
||||
toNullFloat64(action.LimitRatio),
|
||||
|
@ -534,6 +542,7 @@ func (r *ActionRepo) Update(ctx context.Context, action domain.Action) (*domain.
|
|||
Set("ignore_rules", action.IgnoreRules).
|
||||
Set("skip_hash_check", action.SkipHashCheck).
|
||||
Set("content_layout", toNullString(string(action.ContentLayout))).
|
||||
Set("priority", toNullString(string(action.PriorityLayout))).
|
||||
Set("limit_upload_speed", toNullInt64(action.LimitUploadSpeed)).
|
||||
Set("limit_download_speed", toNullInt64(action.LimitDownloadSpeed)).
|
||||
Set("limit_ratio", toNullFloat64(action.LimitRatio)).
|
||||
|
@ -593,6 +602,7 @@ func (r *ActionRepo) StoreFilterActions(ctx context.Context, filterID int64, act
|
|||
Set("ignore_rules", action.IgnoreRules).
|
||||
Set("skip_hash_check", action.SkipHashCheck).
|
||||
Set("content_layout", toNullString(string(action.ContentLayout))).
|
||||
Set("priority", toNullString(string(action.PriorityLayout))).
|
||||
Set("limit_upload_speed", toNullInt64(action.LimitUploadSpeed)).
|
||||
Set("limit_download_speed", toNullInt64(action.LimitDownloadSpeed)).
|
||||
Set("limit_ratio", toNullFloat64(action.LimitRatio)).
|
||||
|
@ -639,6 +649,7 @@ func (r *ActionRepo) StoreFilterActions(ctx context.Context, filterID int64, act
|
|||
"ignore_rules",
|
||||
"skip_hash_check",
|
||||
"content_layout",
|
||||
"priority",
|
||||
"limit_upload_speed",
|
||||
"limit_download_speed",
|
||||
"limit_ratio",
|
||||
|
@ -670,6 +681,7 @@ func (r *ActionRepo) StoreFilterActions(ctx context.Context, filterID int64, act
|
|||
action.IgnoreRules,
|
||||
action.SkipHashCheck,
|
||||
toNullString(string(action.ContentLayout)),
|
||||
toNullString(string(action.PriorityLayout)),
|
||||
toNullInt64(action.LimitUploadSpeed),
|
||||
toNullInt64(action.LimitDownloadSpeed),
|
||||
toNullFloat64(action.LimitRatio),
|
||||
|
|
|
@ -199,6 +199,7 @@ CREATE TABLE action
|
|||
limit_download_speed INT,
|
||||
limit_ratio REAL,
|
||||
limit_seed_time INT,
|
||||
priority TEXT,
|
||||
reannounce_skip BOOLEAN DEFAULT false,
|
||||
reannounce_delete BOOLEAN DEFAULT false,
|
||||
reannounce_interval INTEGER DEFAULT 7,
|
||||
|
@ -507,20 +508,20 @@ var postgresMigrations = []string{
|
|||
`
|
||||
ALTER TABLE "action"
|
||||
ADD COLUMN reannounce_skip BOOLEAN DEFAULT false;
|
||||
|
||||
|
||||
ALTER TABLE "action"
|
||||
ADD COLUMN reannounce_delete BOOLEAN DEFAULT false;
|
||||
|
||||
|
||||
ALTER TABLE "action"
|
||||
ADD COLUMN reannounce_interval INTEGER DEFAULT 7;
|
||||
|
||||
|
||||
ALTER TABLE "action"
|
||||
ADD COLUMN reannounce_max_attempts INTEGER DEFAULT 50;
|
||||
`,
|
||||
`
|
||||
ALTER TABLE "action"
|
||||
ADD COLUMN limit_ratio REAL DEFAULT 0;
|
||||
|
||||
|
||||
ALTER TABLE "action"
|
||||
ADD COLUMN limit_seed_time INTEGER DEFAULT 0;
|
||||
`,
|
||||
|
@ -685,7 +686,7 @@ FROM filter f WHERE f.name = release_action_status.filter);
|
|||
`,
|
||||
`ALTER TABLE "release"
|
||||
ADD COLUMN info_url TEXT;
|
||||
|
||||
|
||||
ALTER TABLE "release"
|
||||
ADD COLUMN download_url TEXT;
|
||||
`,
|
||||
|
@ -728,7 +729,7 @@ ALTER TABLE irc_network
|
|||
ADD COLUMN bouncer_addr TEXT;`,
|
||||
`ALTER TABLE release_action_status
|
||||
DROP CONSTRAINT IF EXISTS release_action_status_action_id_fkey;
|
||||
|
||||
|
||||
ALTER TABLE release_action_status
|
||||
DROP CONSTRAINT IF EXISTS release_action_status_action_id_fk;
|
||||
|
||||
|
@ -834,5 +835,8 @@ ALTER TABLE filter_external
|
|||
`,
|
||||
`ALTER TABLE feed
|
||||
ALTER COLUMN max_age SET DEFAULT 0;
|
||||
`,
|
||||
`ALTER TABLE action
|
||||
ADD COLUMN priority TEXT;
|
||||
`,
|
||||
}
|
||||
|
|
|
@ -199,6 +199,7 @@ CREATE TABLE action
|
|||
limit_download_speed INT,
|
||||
limit_ratio REAL,
|
||||
limit_seed_time INT,
|
||||
priority TEXT,
|
||||
reannounce_skip BOOLEAN DEFAULT false,
|
||||
reannounce_delete BOOLEAN DEFAULT false,
|
||||
reannounce_interval INTEGER DEFAULT 7,
|
||||
|
@ -763,20 +764,20 @@ ALTER TABLE release_action_status_dg_tmp
|
|||
`
|
||||
ALTER TABLE "action"
|
||||
ADD COLUMN reannounce_skip BOOLEAN DEFAULT false;
|
||||
|
||||
|
||||
ALTER TABLE "action"
|
||||
ADD COLUMN reannounce_delete BOOLEAN DEFAULT false;
|
||||
|
||||
|
||||
ALTER TABLE "action"
|
||||
ADD COLUMN reannounce_interval INTEGER DEFAULT 7;
|
||||
|
||||
|
||||
ALTER TABLE "action"
|
||||
ADD COLUMN reannounce_max_attempts INTEGER DEFAULT 50;
|
||||
`,
|
||||
`
|
||||
ALTER TABLE "action"
|
||||
ADD COLUMN limit_ratio REAL DEFAULT 0;
|
||||
|
||||
|
||||
ALTER TABLE "action"
|
||||
ADD COLUMN limit_seed_time INTEGER DEFAULT 0;
|
||||
`,
|
||||
|
@ -986,7 +987,7 @@ CREATE TABLE irc_network_dg_tmp
|
|||
unique (server, port, nick)
|
||||
);
|
||||
|
||||
INSERT INTO irc_network_dg_tmp(id, enabled, name, server, port, tls, pass, nick, auth_mechanism, auth_account, auth_password, invite_command,
|
||||
INSERT INTO irc_network_dg_tmp(id, enabled, name, server, port, tls, pass, nick, auth_mechanism, auth_account, auth_password, invite_command,
|
||||
connected, connected_since, created_at, updated_at)
|
||||
SELECT id,
|
||||
enabled,
|
||||
|
@ -1079,7 +1080,7 @@ FROM filter f WHERE f.name = release_action_status.filter);
|
|||
`,
|
||||
`ALTER TABLE "release"
|
||||
ADD COLUMN info_url TEXT;
|
||||
|
||||
|
||||
ALTER TABLE "release"
|
||||
ADD COLUMN download_url TEXT;
|
||||
`,
|
||||
|
@ -1088,7 +1089,7 @@ ADD COLUMN download_url TEXT;
|
|||
|
||||
ALTER TABLE filter
|
||||
ADD COLUMN except_tags_match_logic TEXT;
|
||||
|
||||
|
||||
UPDATE filter
|
||||
SET tags_match_logic = 'ANY'
|
||||
WHERE tags IS NOT NULL;
|
||||
|
@ -1475,5 +1476,8 @@ DROP TABLE feed;
|
|||
|
||||
ALTER TABLE feed_dg_tmp
|
||||
RENAME TO feed;
|
||||
`,
|
||||
`ALTER TABLE action
|
||||
ADD COLUMN priority TEXT;
|
||||
`,
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ type Action struct {
|
|||
LimitDownloadSpeed int64 `json:"limit_download_speed,omitempty"`
|
||||
LimitRatio float64 `json:"limit_ratio,omitempty"`
|
||||
LimitSeedTime int64 `json:"limit_seed_time,omitempty"`
|
||||
PriorityLayout PriorityLayout `json:"priority,omitempty"`
|
||||
ReAnnounceSkip bool `json:"reannounce_skip,omitempty"`
|
||||
ReAnnounceDelete bool `json:"reannounce_delete,omitempty"`
|
||||
ReAnnounceInterval int64 `json:"reannounce_interval,omitempty"`
|
||||
|
@ -128,6 +129,14 @@ const (
|
|||
ActionContentLayoutSubfolderCreate ActionContentLayout = "SUBFOLDER_CREATE"
|
||||
)
|
||||
|
||||
type PriorityLayout string
|
||||
|
||||
const (
|
||||
PriorityLayoutMax PriorityLayout = "MAX"
|
||||
PriorityLayoutMin PriorityLayout = "MIN"
|
||||
PriorityLayoutDefault PriorityLayout = ""
|
||||
)
|
||||
|
||||
type GetActionRequest struct {
|
||||
Id int
|
||||
}
|
||||
|
|
|
@ -349,6 +349,12 @@ export const ActionContentLayoutOptions: SelectGenericOption<ActionContentLayout
|
|||
{ label: "Don't create subfolder", description: "Don't create subfolder", value: "SUBFOLDER_NONE" }
|
||||
];
|
||||
|
||||
export const ActionPriorityOptions: SelectGenericOption<ActionPriorityLayout>[] = [
|
||||
{ label: "Top of queue", description: "Top of queue", value: "MAX" },
|
||||
{ label: "Bottom of queue", description: "Bottom of queue", value: "MIN" },
|
||||
{ label: "Disabled", description: "Disabled", value: "" }
|
||||
];
|
||||
|
||||
export const ActionRtorrentRenameOptions: SelectGenericOption<ActionContentLayout>[] = [
|
||||
{ label: "No", description: "No", value: "ORIGINAL" },
|
||||
{ label: "Yes", description: "Yes", value: "SUBFOLDER_NONE" }
|
||||
|
|
|
@ -54,6 +54,7 @@ export function Actions({ filter, values }: FilterActionsProps) {
|
|||
ignore_rules: false,
|
||||
skip_hash_check: false,
|
||||
content_layout: "" || undefined,
|
||||
priority: "" || undefined,
|
||||
limit_upload_speed: 0,
|
||||
limit_download_speed: 0,
|
||||
limit_ratio: 0,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Link } from "react-router-dom";
|
||||
|
||||
import { DocsLink } from "@components/ExternalLink";
|
||||
import { ActionContentLayoutOptions } from "@domain/constants";
|
||||
import { ActionContentLayoutOptions, ActionPriorityOptions } from "@domain/constants";
|
||||
import * as Input from "@components/inputs";
|
||||
|
||||
import { CollapsibleSection } from "../_components";
|
||||
|
@ -105,6 +105,19 @@ export const QBittorrent = ({ idx, action, clients }: ClientActionProps) => (
|
|||
description="Add torrent and skip hash check"
|
||||
/>
|
||||
</FilterSection.HalfRow>
|
||||
<FilterSection.HalfRow>
|
||||
<Input.Select
|
||||
name={`actions.${idx}.priority`}
|
||||
label="Priority"
|
||||
optionDefaultText="Disabled"
|
||||
options={ActionPriorityOptions}
|
||||
tooltip={
|
||||
<div>
|
||||
<p>Torrent Queueing will be enabled for you if it is disabled. Ensure you set your preferred limits for it in your client.</p>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
</FilterSection.HalfRow>
|
||||
</CollapsibleSection>
|
||||
|
||||
<CollapsibleSection
|
||||
|
|
3
web/src/types/Filter.d.ts
vendored
3
web/src/types/Filter.d.ts
vendored
|
@ -90,6 +90,7 @@ interface Action {
|
|||
ignore_rules?: boolean;
|
||||
skip_hash_check: boolean;
|
||||
content_layout?: ActionContentLayout;
|
||||
priority?: ActionPriorityLayout;
|
||||
limit_upload_speed?: number;
|
||||
limit_download_speed?: number;
|
||||
limit_ratio?: number;
|
||||
|
@ -110,6 +111,8 @@ interface Action {
|
|||
|
||||
type ActionContentLayout = "ORIGINAL" | "SUBFOLDER_CREATE" | "SUBFOLDER_NONE";
|
||||
|
||||
type ActionPriorityLayout = "MAX" | "MIN" | "";
|
||||
|
||||
type ActionType = "TEST" | "EXEC" | "WATCH_FOLDER" | "WEBHOOK" | DownloadClientType;
|
||||
|
||||
type ExternalType = "EXEC" | "WEBHOOK";
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue