mirror of
https://github.com/idanoo/autobrr
synced 2025-07-23 16:59:12 +00:00
fix(macros): torrentdata parsing (#757)
* fix(macros): Fix torrentdata parsing in macros. * fix action test * more dead code * hunting demons * limit success output
This commit is contained in:
parent
92f2b0ebe3
commit
29bedc532d
6 changed files with 54 additions and 83 deletions
|
@ -2,9 +2,7 @@ package action
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"os"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/autobrr/autobrr/internal/domain"
|
"github.com/autobrr/autobrr/internal/domain"
|
||||||
|
@ -16,22 +14,6 @@ import (
|
||||||
func (s *service) execCmd(ctx context.Context, action *domain.Action, release domain.Release) error {
|
func (s *service) execCmd(ctx context.Context, action *domain.Action, release domain.Release) error {
|
||||||
s.log.Debug().Msgf("action exec: %s release: %s", action.Name, release.TorrentName)
|
s.log.Debug().Msgf("action exec: %s release: %s", action.Name, release.TorrentName)
|
||||||
|
|
||||||
if release.TorrentTmpFile == "" && strings.Contains(action.ExecArgs, "TorrentPathName") {
|
|
||||||
if err := release.DownloadTorrentFileCtx(ctx); err != nil {
|
|
||||||
return errors.Wrap(err, "error downloading torrent file for release: %s", release.TorrentName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// read the file into bytes we can then use in the macro
|
|
||||||
if len(release.TorrentDataRawBytes) == 0 && release.TorrentTmpFile != "" {
|
|
||||||
t, err := os.ReadFile(release.TorrentTmpFile)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "could not read torrent file: %s", release.TorrentTmpFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
release.TorrentDataRawBytes = t
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if program exists
|
// check if program exists
|
||||||
cmd, err := exec.LookPath(action.ExecCmd)
|
cmd, err := exec.LookPath(action.ExecCmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package action
|
package action
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/autobrr/autobrr/internal/domain"
|
"github.com/autobrr/autobrr/internal/domain"
|
||||||
|
@ -56,13 +57,7 @@ func Test_service_parseMacros(t *testing.T) {
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
s := &service{
|
_ = tt.args.action.ParseMacros(&tt.args.release)
|
||||||
log: logger.Mock().With().Logger(),
|
|
||||||
repo: nil,
|
|
||||||
clientSvc: nil,
|
|
||||||
bus: nil,
|
|
||||||
}
|
|
||||||
_ = s.parseMacros(tt.args.action, tt.args.release)
|
|
||||||
assert.Equalf(t, tt.want, tt.args.action.ExecArgs, "parseMacros(%v, %v)", tt.args.action, tt.args.release)
|
assert.Equalf(t, tt.want, tt.args.action.ExecArgs, "parseMacros(%v, %v)", tt.args.action, tt.args.release)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -101,7 +96,7 @@ func Test_service_execCmd(t *testing.T) {
|
||||||
clientSvc: nil,
|
clientSvc: nil,
|
||||||
bus: nil,
|
bus: nil,
|
||||||
}
|
}
|
||||||
s.execCmd(nil, tt.args.action, tt.args.release)
|
s.execCmd(context.TODO(), tt.args.action, tt.args.release)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ import (
|
||||||
"github.com/autobrr/autobrr/pkg/errors"
|
"github.com/autobrr/autobrr/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *service) RunAction(ctx context.Context, action *domain.Action, release domain.Release) ([]string, error) {
|
func (s *service) RunAction(ctx context.Context, action *domain.Action, release *domain.Release) ([]string, error) {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
|
@ -47,46 +47,46 @@ func (s *service) RunAction(ctx context.Context, action *domain.Action, release
|
||||||
s.test(action.Name)
|
s.test(action.Name)
|
||||||
|
|
||||||
case domain.ActionTypeExec:
|
case domain.ActionTypeExec:
|
||||||
err = s.execCmd(ctx, action, release)
|
err = s.execCmd(ctx, action, *release)
|
||||||
|
|
||||||
case domain.ActionTypeWatchFolder:
|
case domain.ActionTypeWatchFolder:
|
||||||
err = s.watchFolder(ctx, action, release)
|
err = s.watchFolder(ctx, action, *release)
|
||||||
|
|
||||||
case domain.ActionTypeWebhook:
|
case domain.ActionTypeWebhook:
|
||||||
err = s.webhook(ctx, action, release)
|
err = s.webhook(ctx, action, *release)
|
||||||
|
|
||||||
case domain.ActionTypeDelugeV1, domain.ActionTypeDelugeV2:
|
case domain.ActionTypeDelugeV1, domain.ActionTypeDelugeV2:
|
||||||
rejections, err = s.deluge(ctx, action, release)
|
rejections, err = s.deluge(ctx, action, *release)
|
||||||
|
|
||||||
case domain.ActionTypeQbittorrent:
|
case domain.ActionTypeQbittorrent:
|
||||||
rejections, err = s.qbittorrent(ctx, action, release)
|
rejections, err = s.qbittorrent(ctx, action, *release)
|
||||||
|
|
||||||
case domain.ActionTypeRTorrent:
|
case domain.ActionTypeRTorrent:
|
||||||
rejections, err = s.rtorrent(ctx, action, release)
|
rejections, err = s.rtorrent(ctx, action, *release)
|
||||||
|
|
||||||
case domain.ActionTypeTransmission:
|
case domain.ActionTypeTransmission:
|
||||||
rejections, err = s.transmission(ctx, action, release)
|
rejections, err = s.transmission(ctx, action, *release)
|
||||||
|
|
||||||
case domain.ActionTypePorla:
|
case domain.ActionTypePorla:
|
||||||
rejections, err = s.porla(ctx, action, release)
|
rejections, err = s.porla(ctx, action, *release)
|
||||||
|
|
||||||
case domain.ActionTypeRadarr:
|
case domain.ActionTypeRadarr:
|
||||||
rejections, err = s.radarr(ctx, action, release)
|
rejections, err = s.radarr(ctx, action, *release)
|
||||||
|
|
||||||
case domain.ActionTypeSonarr:
|
case domain.ActionTypeSonarr:
|
||||||
rejections, err = s.sonarr(ctx, action, release)
|
rejections, err = s.sonarr(ctx, action, *release)
|
||||||
|
|
||||||
case domain.ActionTypeLidarr:
|
case domain.ActionTypeLidarr:
|
||||||
rejections, err = s.lidarr(ctx, action, release)
|
rejections, err = s.lidarr(ctx, action, *release)
|
||||||
|
|
||||||
case domain.ActionTypeWhisparr:
|
case domain.ActionTypeWhisparr:
|
||||||
rejections, err = s.whisparr(ctx, action, release)
|
rejections, err = s.whisparr(ctx, action, *release)
|
||||||
|
|
||||||
case domain.ActionTypeReadarr:
|
case domain.ActionTypeReadarr:
|
||||||
rejections, err = s.readarr(ctx, action, release)
|
rejections, err = s.readarr(ctx, action, *release)
|
||||||
|
|
||||||
case domain.ActionTypeSabnzbd:
|
case domain.ActionTypeSabnzbd:
|
||||||
rejections, err = s.sabnzbd(ctx, action, release)
|
rejections, err = s.sabnzbd(ctx, action, *release)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
s.log.Warn().Msgf("unsupported action type: %v", action.Type)
|
s.log.Warn().Msgf("unsupported action type: %v", action.Type)
|
||||||
|
@ -161,21 +161,6 @@ func (s *service) watchFolder(ctx context.Context, action *domain.Action, releas
|
||||||
return fmt.Errorf("action watch folder does not support magnet links: %s", release.TorrentName)
|
return fmt.Errorf("action watch folder does not support magnet links: %s", release.TorrentName)
|
||||||
}
|
}
|
||||||
|
|
||||||
if release.TorrentTmpFile == "" {
|
|
||||||
if err := release.DownloadTorrentFileCtx(ctx); err != nil {
|
|
||||||
return errors.Wrap(err, "watch folder: could not download torrent file for release: %v", release.TorrentName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(release.TorrentDataRawBytes) == 0 {
|
|
||||||
t, err := os.ReadFile(release.TorrentTmpFile)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "could not read torrent file: %v", release.TorrentTmpFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
release.TorrentDataRawBytes = t
|
|
||||||
}
|
|
||||||
|
|
||||||
s.log.Trace().Msgf("action WATCH_FOLDER: %v file: %v", action.WatchFolder, release.TorrentTmpFile)
|
s.log.Trace().Msgf("action WATCH_FOLDER: %v file: %v", action.WatchFolder, release.TorrentTmpFile)
|
||||||
|
|
||||||
// Open original file
|
// Open original file
|
||||||
|
@ -225,25 +210,12 @@ func (s *service) watchFolder(ctx context.Context, action *domain.Action, releas
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) webhook(ctx context.Context, action *domain.Action, release domain.Release) error {
|
func (s *service) webhook(ctx context.Context, action *domain.Action, release domain.Release) error {
|
||||||
// if webhook data contains TorrentPathName or TorrentDataRawBytes, lets download the torrent file
|
|
||||||
if release.TorrentTmpFile == "" && (strings.Contains(action.WebhookData, "TorrentPathName") || strings.Contains(action.WebhookData, "TorrentDataRawBytes")) {
|
|
||||||
if err := release.DownloadTorrentFileCtx(ctx); err != nil {
|
|
||||||
return errors.Wrap(err, "webhook: could not download torrent file for release: %v", release.TorrentName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if webhook data contains TorrentDataRawBytes, lets read the file into bytes we can then use in the macro
|
|
||||||
if len(release.TorrentDataRawBytes) == 0 && strings.Contains(action.WebhookData, "TorrentDataRawBytes") {
|
|
||||||
t, err := os.ReadFile(release.TorrentTmpFile)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "could not read torrent file: %v", release.TorrentTmpFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
release.TorrentDataRawBytes = t
|
|
||||||
}
|
|
||||||
|
|
||||||
s.log.Trace().Msgf("action WEBHOOK: '%v' file: %v", action.Name, release.TorrentName)
|
s.log.Trace().Msgf("action WEBHOOK: '%v' file: %v", action.Name, release.TorrentName)
|
||||||
|
if len(action.WebhookData) > 1024 {
|
||||||
|
s.log.Trace().Msgf("webhook action '%v' - host: %v data: %v", action.Name, action.WebhookHost, action.WebhookData[:1024])
|
||||||
|
} else {
|
||||||
s.log.Trace().Msgf("webhook action '%v' - host: %v data: %v", action.Name, action.WebhookHost, action.WebhookData)
|
s.log.Trace().Msgf("webhook action '%v' - host: %v data: %v", action.Name, action.WebhookHost, action.WebhookData)
|
||||||
|
}
|
||||||
|
|
||||||
t := &http.Transport{
|
t := &http.Transport{
|
||||||
TLSClientConfig: &tls.Config{
|
TLSClientConfig: &tls.Config{
|
||||||
|
@ -268,11 +240,11 @@ func (s *service) webhook(ctx context.Context, action *domain.Action, release do
|
||||||
|
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
if len(action.WebhookData) > 256 {
|
||||||
|
s.log.Info().Msgf("successfully ran webhook action: '%v' to: %v payload: %v", action.Name, action.WebhookHost, action.WebhookData[:256])
|
||||||
|
} else {
|
||||||
s.log.Info().Msgf("successfully ran webhook action: '%v' to: %v payload: %v", action.Name, action.WebhookHost, action.WebhookData)
|
s.log.Info().Msgf("successfully ran webhook action: '%v' to: %v payload: %v", action.Name, action.WebhookHost, action.WebhookData)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func (s *service) parseMacros(action *domain.Action, release domain.Release) error {
|
|
||||||
// parse all macros in one go
|
|
||||||
return action.ParseMacros(release)
|
|
||||||
}
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ type Service interface {
|
||||||
DeleteByFilterID(ctx context.Context, filterID int) error
|
DeleteByFilterID(ctx context.Context, filterID int) error
|
||||||
ToggleEnabled(actionID int) error
|
ToggleEnabled(actionID int) error
|
||||||
|
|
||||||
RunAction(ctx context.Context, action *domain.Action, release domain.Release) ([]string, error)
|
RunAction(ctx context.Context, action *domain.Action, release *domain.Release) ([]string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type service struct {
|
type service struct {
|
||||||
|
|
|
@ -2,6 +2,8 @@ package domain
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/autobrr/autobrr/pkg/errors"
|
"github.com/autobrr/autobrr/pkg/errors"
|
||||||
)
|
)
|
||||||
|
@ -51,10 +53,30 @@ type Action struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseMacros parse all macros on action
|
// ParseMacros parse all macros on action
|
||||||
func (a *Action) ParseMacros(release Release) error {
|
func (a *Action) ParseMacros(release *Release) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
m := NewMacro(release)
|
if release.TorrentTmpFile == "" &&
|
||||||
|
(strings.Contains(a.ExecArgs, "TorrentPathName") || strings.Contains(a.ExecArgs, "TorrentDataRawBytes") ||
|
||||||
|
strings.Contains(a.WebhookData, "TorrentPathName") || strings.Contains(a.WebhookData, "TorrentDataRawBytes") ||
|
||||||
|
strings.Contains(a.SavePath, "TorrentPathName")) {
|
||||||
|
if err := release.DownloadTorrentFile(); err != nil {
|
||||||
|
return errors.Wrap(err, "webhook: could not download torrent file for release: %v", release.TorrentName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if webhook data contains TorrentDataRawBytes, lets read the file into bytes we can then use in the macro
|
||||||
|
if len(release.TorrentDataRawBytes) == 0 &&
|
||||||
|
(strings.Contains(a.ExecArgs, "TorrentDataRawBytes") || strings.Contains(a.WebhookData, "TorrentDataRawBytes")) {
|
||||||
|
t, err := os.ReadFile(release.TorrentTmpFile)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "could not read torrent file: %v", release.TorrentTmpFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
release.TorrentDataRawBytes = t
|
||||||
|
}
|
||||||
|
|
||||||
|
m := NewMacro(*release)
|
||||||
|
|
||||||
a.ExecArgs, err = m.Parse(a.ExecArgs)
|
a.ExecArgs, err = m.Parse(a.ExecArgs)
|
||||||
a.WatchFolder, err = m.Parse(a.WatchFolder)
|
a.WatchFolder, err = m.Parse(a.WatchFolder)
|
||||||
|
|
|
@ -167,7 +167,7 @@ func (s *service) Process(release *domain.Release) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
rejections, err = s.actionSvc.RunAction(ctx, a, *release)
|
rejections, err = s.actionSvc.RunAction(ctx, a, release)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Error().Stack().Err(err).Msgf("release.Process: error running actions for filter: %v", release.Filter.Name)
|
l.Error().Stack().Err(err).Msgf("release.Process: error running actions for filter: %v", release.Filter.Name)
|
||||||
continue
|
continue
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue