fix(actions): reject if client is disabled (#1626)

* fix(actions): error on disabled client

* fix(actions): sql scan args

* refactor: download client cache for actions

* fix: tests client store

* fix: tests client store and int conversion

* fix: tests revert findbyid ctx timeout

* fix: tests row.err

* feat: add logging to download client cache
This commit is contained in:
ze0s 2024-08-27 19:45:06 +02:00 committed by GitHub
parent 77e1c2c305
commit 861f30c144
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 928 additions and 680 deletions

View file

@ -7,7 +7,6 @@ import (
"context"
"encoding/base64"
"os"
"time"
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/pkg/errors"
@ -20,20 +19,18 @@ func (s *service) deluge(ctx context.Context, action *domain.Action, release dom
var err error
// get client for action
client, err := s.clientSvc.FindByID(ctx, action.ClientID)
client, err := s.clientSvc.GetClient(ctx, action.ClientID)
if err != nil {
s.log.Error().Stack().Err(err).Msgf("error finding client: %d", action.ClientID)
return nil, err
return nil, errors.Wrap(err, "could not get client with id %d", action.ClientID)
}
if client == nil {
return nil, errors.New("could not find client by id: %d", action.ClientID)
if !client.Enabled {
return nil, errors.New("client %s %s not enabled", client.Type, client.Name)
}
var rejections []string
switch client.Type {
switch action.Client.Type {
case "DELUGE_V1":
rejections, err = s.delugeV1(ctx, client, action, release)
@ -90,27 +87,18 @@ func (s *service) delugeCheckRulesCanDownload(ctx context.Context, del deluge.De
}
func (s *service) delugeV1(ctx context.Context, client *domain.DownloadClient, action *domain.Action, release domain.Release) ([]string, error) {
settings := deluge.Settings{
Hostname: client.Host,
Port: uint(client.Port),
Login: client.Username,
Password: client.Password,
DebugServerResponses: true,
ReadWriteTimeout: time.Second * 30,
}
del := deluge.NewV1(settings)
downloadClient := client.Client.(*deluge.Client)
// perform connection to Deluge server
err := del.Connect(ctx)
err := downloadClient.Connect(ctx)
if err != nil {
return nil, errors.Wrap(err, "could not connect to client %s at %s", client.Name, client.Host)
}
defer del.Close()
defer downloadClient.Close()
// perform connection to Deluge server
rejections, err := s.delugeCheckRulesCanDownload(ctx, del, client, action)
rejections, err := s.delugeCheckRulesCanDownload(ctx, downloadClient, client, action)
if err != nil {
s.log.Error().Err(err).Msgf("error checking client rules: %s", action.Name)
return nil, err
@ -127,13 +115,13 @@ func (s *service) delugeV1(ctx context.Context, client *domain.DownloadClient, a
s.log.Trace().Msgf("action Deluge options: %+v", options)
torrentHash, err := del.AddTorrentMagnet(ctx, release.MagnetURI, &options)
torrentHash, err := downloadClient.AddTorrentMagnet(ctx, release.MagnetURI, &options)
if err != nil {
return nil, errors.Wrap(err, "could not add torrent magnet %s to client: %s", release.MagnetURI, client.Name)
}
if action.Label != "" {
labelPluginActive, err := del.LabelPlugin(ctx)
labelPluginActive, err := downloadClient.LabelPlugin(ctx)
if err != nil {
return nil, errors.Wrap(err, "could not load label plugin for client: %s", client.Name)
}
@ -176,13 +164,13 @@ func (s *service) delugeV1(ctx context.Context, client *domain.DownloadClient, a
s.log.Trace().Msgf("action Deluge options: %+v", options)
torrentHash, err := del.AddTorrentFile(ctx, release.TorrentTmpFile, encodedFile, &options)
torrentHash, err := downloadClient.AddTorrentFile(ctx, release.TorrentTmpFile, encodedFile, &options)
if err != nil {
return nil, errors.Wrap(err, "could not add torrent %v to client: %v", release.TorrentTmpFile, client.Name)
}
if action.Label != "" {
labelPluginActive, err := del.LabelPlugin(ctx)
labelPluginActive, err := downloadClient.LabelPlugin(ctx)
if err != nil {
return nil, errors.Wrap(err, "could not load label plugin for client: %s", client.Name)
}
@ -203,27 +191,18 @@ func (s *service) delugeV1(ctx context.Context, client *domain.DownloadClient, a
}
func (s *service) delugeV2(ctx context.Context, client *domain.DownloadClient, action *domain.Action, release domain.Release) ([]string, error) {
settings := deluge.Settings{
Hostname: client.Host,
Port: uint(client.Port),
Login: client.Username,
Password: client.Password,
DebugServerResponses: true,
ReadWriteTimeout: time.Second * 30,
}
del := deluge.NewV2(settings)
downloadClient := client.Client.(*deluge.ClientV2)
// perform connection to Deluge server
err := del.Connect(ctx)
err := downloadClient.Connect(ctx)
if err != nil {
return nil, errors.Wrap(err, "could not connect to client %s at %s", client.Name, client.Host)
}
defer del.Close()
defer downloadClient.Close()
// perform connection to Deluge server
rejections, err := s.delugeCheckRulesCanDownload(ctx, del, client, action)
rejections, err := s.delugeCheckRulesCanDownload(ctx, downloadClient, client, action)
if err != nil {
s.log.Error().Err(err).Msgf("error checking client rules: %s", action.Name)
return nil, err
@ -240,13 +219,13 @@ func (s *service) delugeV2(ctx context.Context, client *domain.DownloadClient, a
s.log.Trace().Msgf("action Deluge options: %+v", options)
torrentHash, err := del.AddTorrentMagnet(ctx, release.MagnetURI, &options)
torrentHash, err := downloadClient.AddTorrentMagnet(ctx, release.MagnetURI, &options)
if err != nil {
return nil, errors.Wrap(err, "could not add torrent magnet %s to client: %s", release.MagnetURI, client.Name)
}
if action.Label != "" {
labelPluginActive, err := del.LabelPlugin(ctx)
labelPluginActive, err := downloadClient.LabelPlugin(ctx)
if err != nil {
return nil, errors.Wrap(err, "could not load label plugin for client: %s", client.Name)
}
@ -290,13 +269,13 @@ func (s *service) delugeV2(ctx context.Context, client *domain.DownloadClient, a
s.log.Trace().Msgf("action Deluge options: %+v", options)
torrentHash, err := del.AddTorrentFile(ctx, release.TorrentTmpFile, encodedFile, &options)
torrentHash, err := downloadClient.AddTorrentFile(ctx, release.TorrentTmpFile, encodedFile, &options)
if err != nil {
return nil, errors.Wrap(err, "could not add torrent %s to client: %s", release.TorrentTmpFile, client.Name)
}
if action.Label != "" {
labelPluginActive, err := del.LabelPlugin(ctx)
labelPluginActive, err := downloadClient.LabelPlugin(ctx)
if err != nil {
return nil, errors.Wrap(err, "could not load label plugin for client: %s", client.Name)
}

View file

@ -17,41 +17,16 @@ func (s *service) lidarr(ctx context.Context, action *domain.Action, release dom
// TODO validate data
// get client for action
client, err := s.clientSvc.FindByID(ctx, action.ClientID)
client, err := s.clientSvc.GetClient(ctx, action.ClientID)
if err != nil {
s.log.Error().Err(err).Msgf("lidarr: error finding client: %v", action.ClientID)
return nil, err
return nil, errors.Wrap(err, "could not get client with id %d", action.ClientID)
}
// return early if no client found
if client == nil {
return nil, errors.New("could not find client by id: %v", action.ClientID)
if !client.Enabled {
return nil, errors.New("client %s %s not enabled", client.Type, client.Name)
}
// initial config
cfg := lidarr.Config{
Hostname: client.Host,
APIKey: client.Settings.APIKey,
Log: s.subLogger,
}
// only set basic auth if enabled
if client.Settings.Basic.Auth {
cfg.BasicAuth = client.Settings.Basic.Auth
cfg.Username = client.Settings.Basic.Username
cfg.Password = client.Settings.Basic.Password
}
externalClientId := client.Settings.ExternalDownloadClientId
if action.ExternalDownloadClientID > 0 {
externalClientId = int(action.ExternalDownloadClientID)
}
externalClient := client.Settings.ExternalDownloadClient
if action.ExternalDownloadClient != "" {
externalClient = action.ExternalDownloadClient
}
arr := client.Client.(lidarr.Client)
r := lidarr.Release{
Title: release.TorrentName,
@ -60,14 +35,20 @@ func (s *service) lidarr(ctx context.Context, action *domain.Action, release dom
MagnetUrl: release.MagnetURI,
Size: int64(release.Size),
Indexer: release.Indexer.GetExternalIdentifier(),
DownloadClientId: externalClientId,
DownloadClient: externalClient,
DownloadClientId: client.Settings.ExternalDownloadClientId,
DownloadClient: client.Settings.ExternalDownloadClient,
DownloadProtocol: release.Protocol.String(),
Protocol: release.Protocol.String(),
PublishDate: time.Now().Format(time.RFC3339),
}
arr := lidarr.New(cfg)
if action.ExternalDownloadClientID > 0 {
r.DownloadClientId = int(action.ExternalDownloadClientID)
}
if action.ExternalDownloadClient != "" {
r.DownloadClient = action.ExternalDownloadClient
}
rejections, err := arr.Push(ctx, r)
if err != nil {

View file

@ -13,34 +13,21 @@ import (
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/pkg/errors"
"github.com/autobrr/autobrr/pkg/porla"
"github.com/dcarbone/zadapters/zstdlog"
"github.com/rs/zerolog"
)
func (s *service) porla(ctx context.Context, action *domain.Action, release domain.Release) ([]string, error) {
s.log.Debug().Msgf("action Porla: %s", action.Name)
client, err := s.clientSvc.FindByID(ctx, action.ClientID)
client, err := s.clientSvc.GetClient(ctx, action.ClientID)
if err != nil {
return nil, errors.Wrap(err, "error finding client: %d", action.ClientID)
return nil, errors.Wrap(err, "could not get client with id %d", action.ClientID)
}
if client == nil {
return nil, errors.New("could not find client by id: %d", action.ClientID)
if !client.Enabled {
return nil, errors.New("client %s %s not enabled", client.Type, client.Name)
}
porlaSettings := porla.Config{
Hostname: client.Host,
AuthToken: client.Settings.APIKey,
TLSSkipVerify: client.TLSSkipVerify,
BasicUser: client.Settings.Basic.Username,
BasicPass: client.Settings.Basic.Password,
}
porlaSettings.Log = zstdlog.NewStdLoggerWithLevel(s.log.With().Str("type", "Porla").Str("client", client.Name).Logger(), zerolog.TraceLevel)
prl := porla.NewClient(porlaSettings)
prl := client.Client.(*porla.Client)
rejections, err := s.porlaCheckRulesCanDownload(ctx, action, client, prl)
if err != nil {

View file

@ -17,11 +17,20 @@ import (
func (s *service) qbittorrent(ctx context.Context, action *domain.Action, release domain.Release) ([]string, error) {
s.log.Debug().Msgf("action qBittorrent: %s", action.Name)
c := s.clientSvc.GetCachedClient(ctx, action.ClientID)
client, err := s.clientSvc.GetClient(ctx, action.ClientID)
if err != nil {
return nil, errors.Wrap(err, "could not get client with id %d", action.ClientID)
}
if c.Dc.Settings.Rules.Enabled && !action.IgnoreRules {
if !client.Enabled {
return nil, errors.New("client %s %s not enabled", client.Type, client.Name)
}
qbtClient := client.Client.(*qbittorrent.Client)
if client.Settings.Rules.Enabled && !action.IgnoreRules {
// check for active downloads and other rules
rejections, err := s.qbittorrentCheckRulesCanDownload(ctx, action, c.Dc.Settings.Rules, c.Qbt)
rejections, err := s.qbittorrentCheckRulesCanDownload(ctx, action, client.Settings.Rules, qbtClient)
if err != nil {
return nil, errors.Wrap(err, "error checking client rules: %s", action.Name)
}
@ -39,11 +48,11 @@ func (s *service) qbittorrent(ctx context.Context, action *domain.Action, releas
s.log.Trace().Msgf("action qBittorrent options: %+v", options)
if err = c.Qbt.AddTorrentFromUrlCtx(ctx, release.MagnetURI, options); err != nil {
return nil, errors.Wrap(err, "could not add torrent %s to client: %s", release.MagnetURI, c.Dc.Name)
if err = qbtClient.AddTorrentFromUrlCtx(ctx, release.MagnetURI, options); err != nil {
return nil, errors.Wrap(err, "could not add torrent %s to client: %s", release.MagnetURI, client.Name)
}
s.log.Info().Msgf("torrent from magnet successfully added to client: '%s'", c.Dc.Name)
s.log.Info().Msgf("torrent from magnet successfully added to client: '%s'", client.Name)
return nil, nil
}
@ -61,37 +70,37 @@ func (s *service) qbittorrent(ctx context.Context, action *domain.Action, releas
s.log.Trace().Msgf("action qBittorrent options: %+v", options)
if err = c.Qbt.AddTorrentFromFileCtx(ctx, release.TorrentTmpFile, options); err != nil {
return nil, errors.Wrap(err, "could not add torrent %s to client: %s", release.TorrentTmpFile, c.Dc.Name)
if err = qbtClient.AddTorrentFromFileCtx(ctx, release.TorrentTmpFile, options); err != nil {
return nil, errors.Wrap(err, "could not add torrent %s to client: %s", release.TorrentTmpFile, client.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)
prefs, err := qbtClient.GetAppPreferencesCtx(ctx)
if err != nil {
return nil, errors.Wrap(err, "could not get application preferences from client: '%s'", c.Dc.Name)
return nil, errors.Wrap(err, "could not get application preferences from client: '%s'", client.Name)
}
// enable queueing if it's disabled
if !prefs.QueueingEnabled {
if err := c.Qbt.SetPreferencesQueueingEnabled(true); err != nil {
if err := qbtClient.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)
s.log.Trace().Msgf("torrent queueing was disabled, now enabled in client: '%s'", client.Name)
}
// set priority if queueing is enabled
if action.PriorityLayout == domain.PriorityLayoutMax {
if err := c.Qbt.SetMaxPriorityCtx(ctx, []string{release.TorrentHash}); err != nil {
if err := qbtClient.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)
s.log.Debug().Msgf("torrent with hash %s set to max priority in client: '%s'", release.TorrentHash, client.Name)
} else { // domain.PriorityLayoutMin
if err := c.Qbt.SetMinPriorityCtx(ctx, []string{release.TorrentHash}); err != nil {
if err := qbtClient.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)
s.log.Debug().Msgf("torrent with hash %s set to min priority in client: '%s'", release.TorrentHash, client.Name)
}
case domain.PriorityLayoutDefault:
@ -111,7 +120,7 @@ func (s *service) qbittorrent(ctx context.Context, action *domain.Action, releas
DeleteOnFailure: action.ReAnnounceDelete,
}
if err := c.Qbt.ReannounceTorrentWithRetry(ctx, release.TorrentHash, &opts); err != nil {
if err := qbtClient.ReannounceTorrentWithRetry(ctx, release.TorrentHash, &opts); err != nil {
if errors.Is(err, qbittorrent.ErrReannounceTookTooLong) {
return []string{fmt.Sprintf("re-announce took too long for hash: %s", release.TorrentHash)}, nil
}
@ -120,7 +129,7 @@ func (s *service) qbittorrent(ctx context.Context, action *domain.Action, releas
}
}
s.log.Info().Msgf("torrent with hash %s successfully added to client: '%s'", release.TorrentHash, c.Dc.Name)
s.log.Info().Msgf("torrent with hash %s successfully added to client: '%s'", release.TorrentHash, client.Name)
return nil, nil
}

View file

@ -17,40 +17,16 @@ func (s *service) radarr(ctx context.Context, action *domain.Action, release dom
// TODO validate data
// get client for action
client, err := s.clientSvc.FindByID(ctx, action.ClientID)
client, err := s.clientSvc.GetClient(ctx, action.ClientID)
if err != nil {
return nil, errors.Wrap(err, "error finding client: %v", action.ClientID)
return nil, errors.Wrap(err, "could not get client with id %d", action.ClientID)
}
// return early if no client found
if client == nil {
return nil, errors.New("could not find client by id: %v", action.ClientID)
if !client.Enabled {
return nil, errors.New("client %s %s not enabled", client.Type, client.Name)
}
// initial config
cfg := radarr.Config{
Hostname: client.Host,
APIKey: client.Settings.APIKey,
Log: s.subLogger,
}
// only set basic auth if enabled
if client.Settings.Basic.Auth {
cfg.BasicAuth = client.Settings.Basic.Auth
cfg.Username = client.Settings.Basic.Username
cfg.Password = client.Settings.Basic.Password
}
externalClientId := client.Settings.ExternalDownloadClientId
if action.ExternalDownloadClientID > 0 {
externalClientId = int(action.ExternalDownloadClientID)
}
externalClient := client.Settings.ExternalDownloadClient
if action.ExternalDownloadClient != "" {
externalClient = action.ExternalDownloadClient
}
arr := client.Client.(radarr.Client)
r := radarr.Release{
Title: release.TorrentName,
@ -59,14 +35,20 @@ func (s *service) radarr(ctx context.Context, action *domain.Action, release dom
MagnetUrl: release.MagnetURI,
Size: int64(release.Size),
Indexer: release.Indexer.GetExternalIdentifier(),
DownloadClientId: externalClientId,
DownloadClient: externalClient,
DownloadClientId: client.Settings.ExternalDownloadClientId,
DownloadClient: client.Settings.ExternalDownloadClient,
DownloadProtocol: release.Protocol.String(),
Protocol: release.Protocol.String(),
PublishDate: time.Now().Format(time.RFC3339),
}
arr := radarr.New(cfg)
if action.ExternalDownloadClientID > 0 {
r.DownloadClientId = int(action.ExternalDownloadClientID)
}
if action.ExternalDownloadClient != "" {
r.DownloadClient = action.ExternalDownloadClient
}
rejections, err := arr.Push(ctx, r)
if err != nil {

View file

@ -17,40 +17,16 @@ func (s *service) readarr(ctx context.Context, action *domain.Action, release do
// TODO validate data
// get client for action
client, err := s.clientSvc.FindByID(ctx, action.ClientID)
client, err := s.clientSvc.GetClient(ctx, action.ClientID)
if err != nil {
return nil, errors.Wrap(err, "readarr could not find client: %v", action.ClientID)
return nil, errors.Wrap(err, "could not get client with id %d", action.ClientID)
}
// return early if no client found
if client == nil {
return nil, errors.New("no client found")
if !client.Enabled {
return nil, errors.New("client %s %s not enabled", client.Type, client.Name)
}
// initial config
cfg := readarr.Config{
Hostname: client.Host,
APIKey: client.Settings.APIKey,
Log: s.subLogger,
}
// only set basic auth if enabled
if client.Settings.Basic.Auth {
cfg.BasicAuth = client.Settings.Basic.Auth
cfg.Username = client.Settings.Basic.Username
cfg.Password = client.Settings.Basic.Password
}
externalClientId := client.Settings.ExternalDownloadClientId
if action.ExternalDownloadClientID > 0 {
externalClientId = int(action.ExternalDownloadClientID)
}
externalClient := client.Settings.ExternalDownloadClient
if action.ExternalDownloadClient != "" {
externalClient = action.ExternalDownloadClient
}
arr := client.Client.(readarr.Client)
r := readarr.Release{
Title: release.TorrentName,
@ -59,14 +35,20 @@ func (s *service) readarr(ctx context.Context, action *domain.Action, release do
MagnetUrl: release.MagnetURI,
Size: int64(release.Size),
Indexer: release.Indexer.GetExternalIdentifier(),
DownloadClientId: externalClientId,
DownloadClient: externalClient,
DownloadClientId: client.Settings.ExternalDownloadClientId,
DownloadClient: client.Settings.ExternalDownloadClient,
DownloadProtocol: release.Protocol.String(),
Protocol: release.Protocol.String(),
PublishDate: time.Now().Format(time.RFC3339),
}
arr := readarr.New(cfg)
if action.ExternalDownloadClientID > 0 {
r.DownloadClientId = int(action.ExternalDownloadClientID)
}
if action.ExternalDownloadClient != "" {
r.DownloadClient = action.ExternalDownloadClient
}
rejections, err := arr.Push(ctx, r)
if err != nil {

View file

@ -16,32 +16,19 @@ import (
func (s *service) rtorrent(ctx context.Context, action *domain.Action, release domain.Release) ([]string, error) {
s.log.Debug().Msgf("action rTorrent: %s", action.Name)
var err error
// get client for action
client, err := s.clientSvc.FindByID(ctx, action.ClientID)
client, err := s.clientSvc.GetClient(ctx, action.ClientID)
if err != nil {
s.log.Error().Stack().Err(err).Msgf("error finding client: %d", action.ClientID)
return nil, err
return nil, errors.Wrap(err, "could not get client with id %d", action.ClientID)
}
if client == nil {
return nil, errors.New("could not find client by id: %d", action.ClientID)
if !client.Enabled {
return nil, errors.New("client %s %s not enabled", client.Type, client.Name)
}
rt := client.Client.(*rtorrent.Client)
var rejections []string
// create config
cfg := rtorrent.Config{
Addr: client.Host,
TLSSkipVerify: client.TLSSkipVerify,
BasicUser: client.Settings.Basic.Username,
BasicPass: client.Settings.Basic.Password,
}
// create client
rt := rtorrent.NewClient(cfg)
if release.HasMagnetUri() {
var args []*rtorrent.FieldValue
@ -79,55 +66,54 @@ func (s *service) rtorrent(ctx context.Context, action *domain.Action, release d
s.log.Info().Msgf("torrent from magnet successfully added to client: '%s'", client.Name)
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
}
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
}
}
tmpFile, err := os.ReadFile(release.TorrentTmpFile)
if err != nil {
return nil, errors.Wrap(err, "could not read torrent file: %s", release.TorrentTmpFile)
}
tmpFile, err := os.ReadFile(release.TorrentTmpFile)
if err != nil {
return nil, errors.Wrap(err, "could not read torrent file: %s", release.TorrentTmpFile)
}
var args []*rtorrent.FieldValue
var args []*rtorrent.FieldValue
if action.Label != "" {
if action.Label != "" {
args = append(args, &rtorrent.FieldValue{
Field: rtorrent.DLabel,
Value: action.Label,
})
}
if action.SavePath != "" {
if action.ContentLayout == domain.ActionContentLayoutSubfolderNone {
args = append(args, &rtorrent.FieldValue{
Field: rtorrent.DLabel,
Value: action.Label,
Field: "d.directory_base",
Value: action.SavePath,
})
} else {
args = append(args, &rtorrent.FieldValue{
Field: rtorrent.DDirectory,
Value: action.SavePath,
})
}
if action.SavePath != "" {
if action.ContentLayout == domain.ActionContentLayoutSubfolderNone {
args = append(args, &rtorrent.FieldValue{
Field: "d.directory_base",
Value: action.SavePath,
})
} else {
args = append(args, &rtorrent.FieldValue{
Field: rtorrent.DDirectory,
Value: action.SavePath,
})
}
}
var addTorrentFile func(context.Context, []byte, ...*rtorrent.FieldValue) error
if action.Paused {
addTorrentFile = rt.AddTorrentStopped
} else {
addTorrentFile = rt.AddTorrent
}
if err := addTorrentFile(ctx, tmpFile, args...); err != nil {
return nil, errors.Wrap(err, "could not add torrent file: %s", release.TorrentTmpFile)
}
s.log.Info().Msgf("torrent successfully added to client: '%s'", client.Name)
}
var addTorrentFile func(context.Context, []byte, ...*rtorrent.FieldValue) error
if action.Paused {
addTorrentFile = rt.AddTorrentStopped
} else {
addTorrentFile = rt.AddTorrent
}
if err := addTorrentFile(ctx, tmpFile, args...); err != nil {
return nil, errors.Wrap(err, "could not add torrent file: %s", release.TorrentTmpFile)
}
s.log.Info().Msgf("torrent successfully added to client: '%s'", client.Name)
return rejections, nil
}

View file

@ -19,7 +19,6 @@ import (
)
func (s *service) RunAction(ctx context.Context, action *domain.Action, release *domain.Release) ([]string, error) {
var (
err error
rejections []string
@ -33,6 +32,10 @@ func (s *service) RunAction(ctx context.Context, action *domain.Action, release
}
}()
if action.ClientID > 0 && action.Client != nil && !action.Client.Enabled {
return nil, errors.New("action %s client %s %s not enabled, skipping", action.Name, action.Client.Type, action.Client.Name)
}
// if set, try to resolve MagnetURI before parsing macros
// to allow webhook and exec to get the magnet_uri
if err := release.ResolveMagnetUri(ctx); err != nil {

View file

@ -18,29 +18,16 @@ func (s *service) sabnzbd(ctx context.Context, action *domain.Action, release do
return nil, errors.New("action type: %s invalid protocol: %s", action.Type, release.Protocol)
}
// get client for action
client, err := s.clientSvc.FindByID(ctx, action.ClientID)
client, err := s.clientSvc.GetClient(ctx, action.ClientID)
if err != nil {
return nil, errors.Wrap(err, "sonarr could not find client: %d", action.ClientID)
return nil, errors.Wrap(err, "could not get client with id %d", action.ClientID)
}
// return early if no client found
if client == nil {
return nil, errors.New("no sabnzbd client found by id: %d", action.ClientID)
if !client.Enabled {
return nil, errors.New("client %s %s not enabled", client.Type, client.Name)
}
opts := sabnzbd.Options{
Addr: client.Host,
ApiKey: client.Settings.APIKey,
Log: nil,
}
if client.Settings.Basic.Auth {
opts.BasicUser = client.Settings.Basic.Username
opts.BasicPass = client.Settings.Basic.Password
}
sab := sabnzbd.New(opts)
sab := client.Client.(*sabnzbd.Client)
ids, err := sab.AddFromUrl(ctx, sabnzbd.AddNzbRequest{Url: release.DownloadURL, Category: action.Category})
if err != nil {

View file

@ -21,9 +21,10 @@ import (
type Service interface {
Store(ctx context.Context, action domain.Action) (*domain.Action, error)
StoreFilterActions(ctx context.Context, filterID int64, actions []*domain.Action) ([]*domain.Action, error)
List(ctx context.Context) ([]domain.Action, error)
Get(ctx context.Context, req *domain.GetActionRequest) (*domain.Action, error)
FindByFilterID(ctx context.Context, filterID int, active *bool) ([]*domain.Action, error)
FindByFilterID(ctx context.Context, filterID int, active *bool, withClient bool) ([]*domain.Action, error)
Delete(ctx context.Context, req *domain.DeleteActionRequest) error
DeleteByFilterID(ctx context.Context, filterID int) error
ToggleEnabled(actionID int) error
@ -63,6 +64,10 @@ func (s *service) Store(ctx context.Context, action domain.Action) (*domain.Acti
return s.repo.Store(ctx, action)
}
func (s *service) StoreFilterActions(ctx context.Context, filterID int64, actions []*domain.Action) ([]*domain.Action, error) {
return s.repo.StoreFilterActions(ctx, filterID, actions)
}
func (s *service) List(ctx context.Context) ([]domain.Action, error) {
return s.repo.List(ctx)
}
@ -86,8 +91,8 @@ func (s *service) Get(ctx context.Context, req *domain.GetActionRequest) (*domai
return a, nil
}
func (s *service) FindByFilterID(ctx context.Context, filterID int, active *bool) ([]*domain.Action, error) {
return s.repo.FindByFilterID(ctx, filterID, active)
func (s *service) FindByFilterID(ctx context.Context, filterID int, active *bool, withClient bool) ([]*domain.Action, error) {
return s.repo.FindByFilterID(ctx, filterID, active, withClient)
}
func (s *service) Delete(ctx context.Context, req *domain.DeleteActionRequest) error {

View file

@ -17,40 +17,16 @@ func (s *service) sonarr(ctx context.Context, action *domain.Action, release dom
// TODO validate data
// get client for action
client, err := s.clientSvc.FindByID(ctx, action.ClientID)
client, err := s.clientSvc.GetClient(ctx, action.ClientID)
if err != nil {
return nil, errors.Wrap(err, "sonarr could not find client: %v", action.ClientID)
return nil, errors.Wrap(err, "could not get client with id %d", action.ClientID)
}
// return early if no client found
if client == nil {
return nil, errors.New("no client found")
if !client.Enabled {
return nil, errors.New("client %s %s not enabled", client.Type, client.Name)
}
// initial config
cfg := sonarr.Config{
Hostname: client.Host,
APIKey: client.Settings.APIKey,
Log: s.subLogger,
}
// only set basic auth if enabled
if client.Settings.Basic.Auth {
cfg.BasicAuth = client.Settings.Basic.Auth
cfg.Username = client.Settings.Basic.Username
cfg.Password = client.Settings.Basic.Password
}
externalClientId := client.Settings.ExternalDownloadClientId
if action.ExternalDownloadClientID > 0 {
externalClientId = int(action.ExternalDownloadClientID)
}
externalClient := client.Settings.ExternalDownloadClient
if action.ExternalDownloadClient != "" {
externalClient = action.ExternalDownloadClient
}
arr := client.Client.(sonarr.Client)
r := sonarr.Release{
Title: release.TorrentName,
@ -59,14 +35,20 @@ func (s *service) sonarr(ctx context.Context, action *domain.Action, release dom
MagnetUrl: release.MagnetURI,
Size: int64(release.Size),
Indexer: release.Indexer.GetExternalIdentifier(),
DownloadClientId: externalClientId,
DownloadClient: externalClient,
DownloadClientId: client.Settings.ExternalDownloadClientId,
DownloadClient: client.Settings.ExternalDownloadClient,
DownloadProtocol: release.Protocol.String(),
Protocol: release.Protocol.String(),
PublishDate: time.Now().Format(time.RFC3339),
}
arr := sonarr.New(cfg)
if action.ExternalDownloadClientID > 0 {
r.DownloadClientId = int(action.ExternalDownloadClientID)
}
if action.ExternalDownloadClient != "" {
r.DownloadClient = action.ExternalDownloadClient
}
rejections, err := arr.Push(ctx, r)
if err != nil {

View file

@ -6,14 +6,11 @@ package action
import (
"context"
"fmt"
"net/url"
"strings"
"time"
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/pkg/errors"
"github.com/autobrr/autobrr/pkg/transmission"
"github.com/hekmon/transmissionrpc/v3"
)
@ -28,38 +25,16 @@ var TrTrue = true
func (s *service) transmission(ctx context.Context, action *domain.Action, release domain.Release) ([]string, error) {
s.log.Debug().Msgf("action Transmission: %s", action.Name)
var err error
// get client for action
client, err := s.clientSvc.FindByID(ctx, action.ClientID)
client, err := s.clientSvc.GetClient(ctx, action.ClientID)
if err != nil {
s.log.Error().Stack().Err(err).Msgf("error finding client: %d", action.ClientID)
return nil, err
return nil, errors.Wrap(err, "could not get client with id %d", action.ClientID)
}
if client == nil {
return nil, errors.New("could not find client by id: %d", action.ClientID)
if !client.Enabled {
return nil, errors.New("client %s %s not enabled", client.Type, client.Name)
}
scheme := "http"
if client.TLS {
scheme = "https"
}
u, err := url.Parse(fmt.Sprintf("%s://%s:%d/transmission/rpc", scheme, client.Host, client.Port))
if err != nil {
return nil, err
}
tbt, err := transmission.New(u, &transmission.Config{
UserAgent: "autobrr",
Username: client.Username,
Password: client.Password,
TLSSkipVerify: client.TLSSkipVerify,
})
if err != nil {
return nil, errors.Wrap(err, "error logging into client: %s", client.Host)
}
tbt := client.Client.(*transmissionrpc.Client)
rejections, err := s.transmissionCheckRulesCanDownload(ctx, action, client, tbt)
if err != nil {

View file

@ -17,40 +17,16 @@ func (s *service) whisparr(ctx context.Context, action *domain.Action, release d
// TODO validate data
// get client for action
client, err := s.clientSvc.FindByID(ctx, action.ClientID)
client, err := s.clientSvc.GetClient(ctx, action.ClientID)
if err != nil {
return nil, errors.Wrap(err, "sonarr could not find client: %v", action.ClientID)
return nil, errors.Wrap(err, "could not get client with id %d", action.ClientID)
}
// return early if no client found
if client == nil {
return nil, errors.New("could not find client by id: %v", action.ClientID)
if !client.Enabled {
return nil, errors.New("client %s %s not enabled", client.Type, client.Name)
}
// initial config
cfg := whisparr.Config{
Hostname: client.Host,
APIKey: client.Settings.APIKey,
Log: s.subLogger,
}
// only set basic auth if enabled
if client.Settings.Basic.Auth {
cfg.BasicAuth = client.Settings.Basic.Auth
cfg.Username = client.Settings.Basic.Username
cfg.Password = client.Settings.Basic.Password
}
externalClientId := client.Settings.ExternalDownloadClientId
if action.ExternalDownloadClientID > 0 {
externalClientId = int(action.ExternalDownloadClientID)
}
externalClient := client.Settings.ExternalDownloadClient
if action.ExternalDownloadClient != "" {
externalClient = action.ExternalDownloadClient
}
arr := client.Client.(whisparr.Client)
r := whisparr.Release{
Title: release.TorrentName,
@ -59,14 +35,20 @@ func (s *service) whisparr(ctx context.Context, action *domain.Action, release d
MagnetUrl: release.MagnetURI,
Size: int64(release.Size),
Indexer: release.Indexer.GetExternalIdentifier(),
DownloadClientId: externalClientId,
DownloadClient: externalClient,
DownloadClientId: client.Settings.ExternalDownloadClientId,
DownloadClient: client.Settings.ExternalDownloadClient,
DownloadProtocol: release.Protocol.String(),
Protocol: release.Protocol.String(),
PublishDate: time.Now().Format(time.RFC3339),
}
arr := whisparr.New(cfg)
if action.ExternalDownloadClientID > 0 {
r.DownloadClientId = int(action.ExternalDownloadClientID)
}
if action.ExternalDownloadClient != "" {
r.DownloadClient = action.ExternalDownloadClient
}
rejections, err := arr.Push(ctx, r)
if err != nil {