mirror of
https://github.com/idanoo/autobrr
synced 2025-07-23 08:49:13 +00:00
feat(clients): Transmission set label (#1204)
* feat(clients): Transmission set label * fix(clients): Transmission fmt * fix(clients): Transmission set label before reannounce
This commit is contained in:
parent
d602b1e868
commit
522f22db46
2 changed files with 80 additions and 40 deletions
|
@ -5,6 +5,7 @@ package action
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -16,9 +17,11 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ReannounceMaxAttempts = 50
|
ReannounceMaxAttempts = 50
|
||||||
ReannounceInterval = 7000
|
ReannounceInterval = 7 // interval in seconds
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var ErrReannounceTookTooLong = errors.New("ErrReannounceTookTooLong")
|
||||||
|
|
||||||
func (s *service) transmission(ctx context.Context, action *domain.Action, release domain.Release) ([]string, error) {
|
func (s *service) transmission(ctx context.Context, action *domain.Action, release domain.Release) ([]string, error) {
|
||||||
s.log.Debug().Msgf("action Transmission: %s", action.Name)
|
s.log.Debug().Msgf("action Transmission: %s", action.Name)
|
||||||
|
|
||||||
|
@ -36,8 +39,9 @@ func (s *service) transmission(ctx context.Context, action *domain.Action, relea
|
||||||
}
|
}
|
||||||
|
|
||||||
tbt, err := transmissionrpc.New(client.Host, client.Username, client.Password, &transmissionrpc.AdvancedConfig{
|
tbt, err := transmissionrpc.New(client.Host, client.Username, client.Password, &transmissionrpc.AdvancedConfig{
|
||||||
HTTPS: client.TLS,
|
HTTPS: client.TLS,
|
||||||
Port: uint16(client.Port),
|
Port: uint16(client.Port),
|
||||||
|
UserAgent: "autobrr",
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "error logging into client: %s", client.Host)
|
return nil, errors.Wrap(err, "error logging into client: %s", client.Host)
|
||||||
|
@ -70,42 +74,71 @@ func (s *service) transmission(ctx context.Context, action *domain.Action, relea
|
||||||
return nil, errors.Wrap(err, "could not add torrent from magnet %s to client: %s", release.MagnetURI, client.Host)
|
return nil, errors.Wrap(err, "could not add torrent from magnet %s to client: %s", release.MagnetURI, client.Host)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if action.Label != "" {
|
||||||
|
p := transmissionrpc.TorrentSetPayload{
|
||||||
|
IDs: []int64{*torrent.ID},
|
||||||
|
Labels: []string{action.Label},
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := tbt.TorrentSet(ctx, p); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not set label for hash %s to client: %s", *torrent.HashString, client.Host)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.log.Debug().Msgf("set label for torrent hash %s successful to client: '%s'", *torrent.HashString, client.Name)
|
||||||
|
}
|
||||||
|
|
||||||
s.log.Info().Msgf("torrent from magnet with hash %v successfully added to client: '%s'", torrent.HashString, client.Name)
|
s.log.Info().Msgf("torrent from magnet with hash %v successfully added to client: '%s'", torrent.HashString, client.Name)
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
|
||||||
} else {
|
|
||||||
if release.TorrentTmpFile == "" {
|
|
||||||
if err := release.DownloadTorrentFileCtx(ctx); err != nil {
|
|
||||||
s.log.Error().Err(err).Msgf("could not download torrent file for release: %s", release.TorrentName)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
b64, err := transmissionrpc.File2Base64(release.TorrentTmpFile)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "cant encode file %s into base64", release.TorrentTmpFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
payload.MetaInfo = &b64
|
|
||||||
|
|
||||||
// Prepare and send payload
|
|
||||||
torrent, err := tbt.TorrentAdd(ctx, payload)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "could not add torrent %v to client: %v", release.TorrentTmpFile, client.Host)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !action.Paused && !action.ReAnnounceSkip {
|
|
||||||
if err := s.transmissionReannounce(ctx, action, tbt, *torrent.ID); err != nil {
|
|
||||||
return nil, errors.Wrap(err, "could not reannounce torrent: %s", *torrent.HashString)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
s.log.Info().Msgf("torrent with hash %s successfully added to client: '%s'", *torrent.HashString, client.Name)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if release.TorrentTmpFile == "" {
|
||||||
|
if err := release.DownloadTorrentFileCtx(ctx); err != nil {
|
||||||
|
s.log.Error().Err(err).Msgf("could not download torrent file for release: %s", release.TorrentName)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
b64, err := transmissionrpc.File2Base64(release.TorrentTmpFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "cant encode file %s into base64", release.TorrentTmpFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
payload.MetaInfo = &b64
|
||||||
|
|
||||||
|
// Prepare and send payload
|
||||||
|
torrent, err := tbt.TorrentAdd(ctx, payload)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not add torrent %s to client: %s", release.TorrentTmpFile, client.Host)
|
||||||
|
}
|
||||||
|
|
||||||
|
if action.Label != "" {
|
||||||
|
p := transmissionrpc.TorrentSetPayload{
|
||||||
|
IDs: []int64{*torrent.ID},
|
||||||
|
Labels: []string{action.Label},
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := tbt.TorrentSet(ctx, p); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not set label for hash %s to client: %s", *torrent.HashString, client.Host)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.log.Debug().Msgf("set label for torrent hash %s successful to client: '%s'", *torrent.HashString, client.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !action.Paused && !action.ReAnnounceSkip {
|
||||||
|
if err := s.transmissionReannounce(ctx, action, tbt, *torrent.ID); err != nil {
|
||||||
|
if errors.Is(err, ErrReannounceTookTooLong) {
|
||||||
|
return []string{fmt.Sprintf("reannounce took too long for torrent: %s, deleted", *torrent.HashString)}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, errors.Wrap(err, "could not reannounce torrent: %s", *torrent.HashString)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
s.log.Info().Msgf("torrent with hash %s successfully added to client: '%s'", *torrent.HashString, client.Name)
|
||||||
|
|
||||||
return rejections, nil
|
return rejections, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +156,7 @@ func (s *service) transmissionReannounce(ctx context.Context, action *domain.Act
|
||||||
attempts := 0
|
attempts := 0
|
||||||
|
|
||||||
for attempts <= maxAttempts {
|
for attempts <= maxAttempts {
|
||||||
s.log.Debug().Msgf("re-announce %v attempt: %d/%d", torrentId, attempts, maxAttempts)
|
s.log.Debug().Msgf("re-announce %d attempt: %d/%d", torrentId, attempts, maxAttempts)
|
||||||
|
|
||||||
// add delay for next run
|
// add delay for next run
|
||||||
time.Sleep(time.Duration(interval) * time.Second)
|
time.Sleep(time.Duration(interval) * time.Second)
|
||||||
|
@ -157,7 +190,7 @@ func (s *service) transmissionReannounce(ctx context.Context, action *domain.Act
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s.log.Debug().Msgf("transmission re-announce not working yet, lets re-announce %v again attempt: %d/%d", torrentId, attempts, maxAttempts)
|
s.log.Debug().Msgf("transmission re-announce not working yet, lets re-announce %d again attempt: %d/%d", torrentId, attempts, maxAttempts)
|
||||||
|
|
||||||
if err := tbt.TorrentReannounceIDs(ctx, []int64{torrentId}); err != nil {
|
if err := tbt.TorrentReannounceIDs(ctx, []int64{torrentId}); err != nil {
|
||||||
return errors.Wrap(err, "failed to reannounce")
|
return errors.Wrap(err, "failed to reannounce")
|
||||||
|
@ -173,7 +206,7 @@ func (s *service) transmissionReannounce(ctx context.Context, action *domain.Act
|
||||||
return errors.Wrap(err, "could not delete torrent: %v from client after max re-announce attempts reached", torrentId)
|
return errors.Wrap(err, "could not delete torrent: %v from client after max re-announce attempts reached", torrentId)
|
||||||
}
|
}
|
||||||
|
|
||||||
return errors.New("transmission re-announce took too long, deleted torrent %v", torrentId)
|
return errors.Wrap(ErrReannounceTookTooLong, "transmission re-announce took too long, deleted torrent %v", torrentId)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -346,8 +346,8 @@ const TypeForm = ({ action, idx, clients }: TypeFormProps) => {
|
||||||
<div className="col-span-6">
|
<div className="col-span-6">
|
||||||
<SwitchGroup
|
<SwitchGroup
|
||||||
name={`actions.${idx}.reannounce_skip`}
|
name={`actions.${idx}.reannounce_skip`}
|
||||||
label="Skip reannounce"
|
label="Disable reannounce"
|
||||||
description="If reannounce is not needed, skip"
|
description="Reannounce is enabled by default. Disable if not needed."
|
||||||
/>
|
/>
|
||||||
<SwitchGroup
|
<SwitchGroup
|
||||||
name={`actions.${idx}.reannounce_delete`}
|
name={`actions.${idx}.reannounce_delete`}
|
||||||
|
@ -484,6 +484,13 @@ const TypeForm = ({ action, idx, clients }: TypeFormProps) => {
|
||||||
label="Add paused"
|
label="Add paused"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<TextField
|
||||||
|
name={`actions.${idx}.label`}
|
||||||
|
label="Label"
|
||||||
|
columns={6}
|
||||||
|
placeholder="eg. label1"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<CollapsableSection title="Re-announce" subtitle="Re-announce options">
|
<CollapsableSection title="Re-announce" subtitle="Re-announce options">
|
||||||
|
@ -504,7 +511,7 @@ const TypeForm = ({ action, idx, clients }: TypeFormProps) => {
|
||||||
<SwitchGroup
|
<SwitchGroup
|
||||||
name={`actions.${idx}.reannounce_skip`}
|
name={`actions.${idx}.reannounce_skip`}
|
||||||
label="Disable reannounce"
|
label="Disable reannounce"
|
||||||
description="Reannounce is enabled by default. Disable if needed."
|
description="Reannounce is enabled by default. Disable if not needed."
|
||||||
/>
|
/>
|
||||||
<SwitchGroup
|
<SwitchGroup
|
||||||
name={`actions.${idx}.reannounce_delete`}
|
name={`actions.${idx}.reannounce_delete`}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue