feat(releases): support magnet links (#730)

* feat(releases): support magnet links

* feat(feeds): support magnet links

* feat(actions): log messages

* fix: component warning

* fix: check hasprefix instead of hassuffix for magnet

* feat(release): resolve magnet uri from link

* fix(actions): deluge use magnet uri

* fix(macros): add `MagnetURI` var

* fix(actions): run magnet resolving before macros

* feat(feeds): set download type on creation
This commit is contained in:
ze0s 2023-02-28 22:16:10 +01:00 committed by GitHub
parent c6101cc765
commit ca196f0bf1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 770 additions and 260 deletions

View file

@ -33,7 +33,7 @@ type Service interface {
Duplicate(ctx context.Context, filterID int) (*domain.Filter, error)
ToggleEnabled(ctx context.Context, filterID int, enabled bool) error
Delete(ctx context.Context, filterID int) error
AdditionalSizeCheck(f domain.Filter, release *domain.Release) (bool, error)
AdditionalSizeCheck(ctx context.Context, f domain.Filter, release *domain.Release) (bool, error)
CanDownloadShow(ctx context.Context, release *domain.Release) (bool, error)
}
@ -336,7 +336,7 @@ func (s *service) CheckFilter(ctx context.Context, f domain.Filter, release *dom
if release.AdditionalSizeCheckRequired {
s.log.Debug().Msgf("filter.Service.CheckFilter: (%v) additional size check required", f.Name)
ok, err := s.AdditionalSizeCheck(f, release)
ok, err := s.AdditionalSizeCheck(ctx, f, release)
if err != nil {
s.log.Error().Stack().Err(err).Msgf("filter.Service.CheckFilter: (%v) additional size check error", f.Name)
return false, err
@ -350,7 +350,7 @@ func (s *service) CheckFilter(ctx context.Context, f domain.Filter, release *dom
// run external script
if f.ExternalScriptEnabled && f.ExternalScriptCmd != "" {
exitCode, err := s.execCmd(release, f.ExternalScriptCmd, f.ExternalScriptArgs)
exitCode, err := s.execCmd(ctx, release, f.ExternalScriptCmd, f.ExternalScriptArgs)
if err != nil {
s.log.Error().Err(err).Msgf("filter.Service.CheckFilter: error executing external command for filter: %+v", f.Name)
return false, err
@ -366,7 +366,7 @@ func (s *service) CheckFilter(ctx context.Context, f domain.Filter, release *dom
// run external webhook
if f.ExternalWebhookEnabled && f.ExternalWebhookHost != "" && f.ExternalWebhookData != "" {
// run external scripts
statusCode, err := s.webhook(release, f.ExternalWebhookHost, f.ExternalWebhookData)
statusCode, err := s.webhook(ctx, release, f.ExternalWebhookHost, f.ExternalWebhookData)
if err != nil {
s.log.Error().Err(err).Msgf("filter.Service.CheckFilter: error executing external webhook for filter: %v", f.Name)
return false, err
@ -404,7 +404,7 @@ func (s *service) CheckFilter(ctx context.Context, f domain.Filter, release *dom
// Some indexers do not announce the size and if size (min,max) is set in a filter then it will need
// additional size check. Some indexers have api implemented to fetch this data and for the others
// it will download the torrent file to parse and make the size check. This is all to minimize the amount of downloads.
func (s *service) AdditionalSizeCheck(f domain.Filter, release *domain.Release) (bool, error) {
func (s *service) AdditionalSizeCheck(ctx context.Context, f domain.Filter, release *domain.Release) (bool, error) {
// do additional size check against indexer api or torrent for size
s.log.Debug().Msgf("filter.Service.AdditionalSizeCheck: (%v) additional size check required", f.Name)
@ -428,7 +428,7 @@ func (s *service) AdditionalSizeCheck(f domain.Filter, release *domain.Release)
s.log.Trace().Msgf("filter.Service.AdditionalSizeCheck: (%v) preparing to download torrent metafile", f.Name)
// if indexer doesn't have api, download torrent and add to tmpPath
if err := release.DownloadTorrentFile(); err != nil {
if err := release.DownloadTorrentFileCtx(ctx); err != nil {
s.log.Error().Stack().Err(err).Msgf("filter.Service.AdditionalSizeCheck: (%v) could not download torrent file with id: '%v' from: %v", f.Name, release.TorrentID, release.Indexer)
return false, err
}
@ -485,11 +485,11 @@ func (s *service) CanDownloadShow(ctx context.Context, release *domain.Release)
return s.releaseRepo.CanDownloadShow(ctx, release.Title, release.Season, release.Episode)
}
func (s *service) execCmd(release *domain.Release, cmd string, args string) (int, error) {
func (s *service) execCmd(ctx context.Context, release *domain.Release, cmd string, args string) (int, error) {
s.log.Debug().Msgf("filter exec release: %v", release.TorrentName)
if release.TorrentTmpFile == "" && strings.Contains(args, "TorrentPathName") {
if err := release.DownloadTorrentFile(); err != nil {
if err := release.DownloadTorrentFileCtx(ctx); err != nil {
return 0, errors.Wrap(err, "error downloading torrent file for release: %v", release.TorrentName)
}
}
@ -546,10 +546,10 @@ func (s *service) execCmd(release *domain.Release, cmd string, args string) (int
return 0, nil
}
func (s *service) webhook(release *domain.Release, url string, data string) (int, error) {
func (s *service) webhook(ctx context.Context, release *domain.Release, url string, data string) (int, error) {
// if webhook data contains TorrentPathName or TorrentDataRawBytes, lets download the torrent file
if release.TorrentTmpFile == "" && (strings.Contains(data, "TorrentPathName") || strings.Contains(data, "TorrentDataRawBytes")) {
if err := release.DownloadTorrentFile(); err != nil {
if err := release.DownloadTorrentFileCtx(ctx); err != nil {
return 0, errors.Wrap(err, "webhook: could not download torrent file for release: %v", release.TorrentName)
}
}
@ -580,7 +580,7 @@ func (s *service) webhook(release *domain.Release, url string, data string) (int
client := http.Client{Transport: t, Timeout: 15 * time.Second}
req, err := http.NewRequest(http.MethodPost, url, bytes.NewBufferString(dataArgs))
req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewBufferString(dataArgs))
if err != nil {
return 0, errors.Wrap(err, "could not build request for webhook")
}