feat: add support for proxies to use with IRC and Indexers (#1421)

* feat: add support for proxies

* fix(http): release handler

* fix(migrations): define proxy early

* fix(migrations): pg proxy

* fix(proxy): list update delete

* fix(proxy): remove log and imports

* feat(irc): use proxy

* feat(irc): tests

* fix(web): update imports for ProxyForms.tsx

* fix(database): migration

* feat(proxy): test

* feat(proxy): validate proxy type

* feat(proxy): validate and test

* feat(proxy): improve validate and test

* feat(proxy): fix db schema

* feat(proxy): add db tests

* feat(proxy): handle http errors

* fix(http): imports

* feat(proxy): use proxy for indexer downloads

* feat(proxy): indexerforms select proxy

* feat(proxy): handle torrent download

* feat(proxy): skip if disabled

* feat(proxy): imports

* feat(proxy): implement in Feeds

* feat(proxy): update helper text indexer proxy

* feat(proxy): add internal cache
This commit is contained in:
ze0s 2024-09-02 11:10:45 +02:00 committed by GitHub
parent 472d327308
commit bc0f4cc055
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
59 changed files with 2533 additions and 371 deletions

View file

@ -140,9 +140,8 @@ func (s *service) delugeV1(ctx context.Context, client *domain.DownloadClient, a
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 err := s.downloadSvc.DownloadRelease(ctx, &release); err != nil {
return nil, errors.Wrap(err, "could not download torrent file for release: %s", release.TorrentName)
}
}
@ -243,11 +242,8 @@ func (s *service) delugeV2(ctx context.Context, client *domain.DownloadClient, a
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 err := s.downloadSvc.DownloadRelease(ctx, &release); err != nil {
return nil, errors.Wrap(err, "could not download torrent file for release: %s", release.TorrentName)
}
t, err := os.ReadFile(release.TorrentTmpFile)

View file

@ -74,10 +74,8 @@ func (s *service) porla(ctx context.Context, action *domain.Action, release doma
return nil, nil
} else {
if release.TorrentTmpFile == "" {
if err := release.DownloadTorrentFileCtx(ctx); err != nil {
return nil, errors.Wrap(err, "error downloading torrent file for release: %s", release.TorrentName)
}
if err := s.downloadSvc.DownloadRelease(ctx, &release); err != nil {
return nil, errors.Wrap(err, "could not download torrent file for release: %s", release.TorrentName)
}
file, err := os.Open(release.TorrentTmpFile)

View file

@ -57,10 +57,8 @@ func (s *service) qbittorrent(ctx context.Context, action *domain.Action, releas
return nil, nil
}
if release.TorrentTmpFile == "" {
if err := release.DownloadTorrentFileCtx(ctx); err != nil {
return nil, errors.Wrap(err, "error downloading torrent file for release: %s", release.TorrentName)
}
if err := s.downloadSvc.DownloadRelease(ctx, &release); err != nil {
return nil, errors.Wrap(err, "could not download torrent file for release: %s", release.TorrentName)
}
options, err := s.prepareQbitOptions(action)

View file

@ -68,11 +68,8 @@ func (s *service) rtorrent(ctx context.Context, action *domain.Action, release d
return nil, nil
}
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 err := s.downloadSvc.DownloadRelease(ctx, &release); err != nil {
return nil, errors.Wrap(err, "could not download torrent file for release: %s", release.TorrentName)
}
tmpFile, err := os.ReadFile(release.TorrentTmpFile)

View file

@ -36,9 +36,8 @@ func (s *service) RunAction(ctx context.Context, action *domain.Action, release
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 {
// Check preconditions: download torrent file if needed
if err := s.CheckActionPreconditions(ctx, action, release); err != nil {
return nil, err
}
@ -137,6 +136,30 @@ func (s *service) RunAction(ctx context.Context, action *domain.Action, release
return rejections, err
}
func (s *service) CheckActionPreconditions(ctx context.Context, action *domain.Action, release *domain.Release) error {
if err := s.downloadSvc.ResolveMagnetURI(ctx, release); err != nil {
return errors.Wrap(err, "could not resolve magnet uri: %s", release.MagnetURI)
}
// parse all macros in one go
if action.CheckMacrosNeedTorrentTmpFile(release) {
if err := s.downloadSvc.DownloadRelease(ctx, release); err != nil {
return errors.Wrap(err, "could not download torrent file for release: %s", release.TorrentName)
}
}
if action.CheckMacrosNeedRawDataBytes(release) {
tmpFile, err := os.ReadFile(release.TorrentTmpFile)
if err != nil {
return errors.Wrap(err, "could not read torrent file: %v", release.TorrentTmpFile)
}
release.TorrentDataRawBytes = tmpFile
}
return nil
}
func (s *service) test(name string) {
s.log.Info().Msgf("action TEST: %v", name)
}

View file

@ -12,6 +12,7 @@ import (
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/internal/download_client"
"github.com/autobrr/autobrr/internal/logger"
"github.com/autobrr/autobrr/internal/releasedownload"
"github.com/autobrr/autobrr/pkg/sharedhttp"
"github.com/asaskevich/EventBus"
@ -33,21 +34,23 @@ type Service interface {
}
type service struct {
log zerolog.Logger
subLogger *log.Logger
repo domain.ActionRepo
clientSvc download_client.Service
bus EventBus.Bus
log zerolog.Logger
subLogger *log.Logger
repo domain.ActionRepo
clientSvc download_client.Service
downloadSvc *releasedownload.DownloadService
bus EventBus.Bus
httpClient *http.Client
}
func NewService(log logger.Logger, repo domain.ActionRepo, clientSvc download_client.Service, bus EventBus.Bus) Service {
func NewService(log logger.Logger, repo domain.ActionRepo, clientSvc download_client.Service, downloadSvc *releasedownload.DownloadService, bus EventBus.Bus) Service {
s := &service{
log: log.With().Str("module", "action").Logger(),
repo: repo,
clientSvc: clientSvc,
bus: bus,
log: log.With().Str("module", "action").Logger(),
repo: repo,
clientSvc: clientSvc,
downloadSvc: downloadSvc,
bus: bus,
httpClient: &http.Client{
Timeout: time.Second * 120,

View file

@ -107,11 +107,8 @@ func (s *service) transmission(ctx context.Context, action *domain.Action, relea
return nil, nil
}
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 err := s.downloadSvc.DownloadRelease(ctx, &release); err != nil {
return nil, errors.Wrap(err, "could not download torrent file for release: %s", release.TorrentName)
}
b64, err := transmissionrpc.File2Base64(release.TorrentTmpFile)