mirror of
https://github.com/idanoo/autobrr
synced 2025-07-23 00:39:13 +00:00
feat(filters): RED and OPS fetch uploader from API (#1348)
* feat: added uploader when fetching torrent details on RED indexer * revert * tests * refactor(filters): size and uploader api checks * refactor(filters): fix test * refactor(filters): add mutex to rejections --------- Co-authored-by: Kyle Sanderson <kyle.leet@gmail.com> Co-authored-by: ze0s <ze0s@riseup.net>
This commit is contained in:
parent
04c4bd482f
commit
acef4ac624
8 changed files with 251 additions and 88 deletions
|
@ -42,6 +42,7 @@ type Service interface {
|
|||
ToggleEnabled(ctx context.Context, filterID int, enabled bool) error
|
||||
Delete(ctx context.Context, filterID int) error
|
||||
AdditionalSizeCheck(ctx context.Context, f *domain.Filter, release *domain.Release) (bool, error)
|
||||
AdditionalUploaderCheck(ctx context.Context, f *domain.Filter, release *domain.Release) (bool, error)
|
||||
CheckSmartEpisodeCanDownload(ctx context.Context, params *domain.SmartEpisodeParams) (bool, error)
|
||||
GetDownloadsByFilterId(ctx context.Context, filterID int) (*domain.FilterDownloads, error)
|
||||
}
|
||||
|
@ -429,8 +430,7 @@ func (s *service) CheckFilter(ctx context.Context, f *domain.Filter, release *do
|
|||
l.Debug().Msgf("found and matched filter: %s", f.Name)
|
||||
|
||||
// If size constraints are set in a filter and the indexer did not
|
||||
// announce the size, we need to do an additional out of band size
|
||||
// check.
|
||||
// announce the size, we need to do an additional out of band size check.
|
||||
if release.AdditionalSizeCheckRequired {
|
||||
l.Debug().Msgf("(%s) additional size check required", f.Name)
|
||||
|
||||
|
@ -446,6 +446,22 @@ func (s *service) CheckFilter(ctx context.Context, f *domain.Filter, release *do
|
|||
}
|
||||
}
|
||||
|
||||
// check uploader if the indexer supports check via api
|
||||
if release.AdditionalUploaderCheckRequired {
|
||||
l.Debug().Msgf("(%s) additional uploader check required", f.Name)
|
||||
|
||||
ok, err := s.AdditionalUploaderCheck(ctx, f, release)
|
||||
if err != nil {
|
||||
l.Error().Err(err).Msgf("(%s) additional uploader check error", f.Name)
|
||||
return false, err
|
||||
}
|
||||
|
||||
if !ok {
|
||||
l.Trace().Msgf("(%s) additional uploader check not matching what filter wanted", f.Name)
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
// run external filters
|
||||
if f.External != nil {
|
||||
externalOk, err := s.RunExternalFilters(ctx, f, f.External, release)
|
||||
|
@ -467,8 +483,8 @@ func (s *service) CheckFilter(ctx context.Context, f *domain.Filter, release *do
|
|||
return false, nil
|
||||
}
|
||||
|
||||
// AdditionalSizeCheck performs additional out of band checks to determine the
|
||||
// size of a torrent. Some indexers do not announce torrent size, so it is
|
||||
// AdditionalSizeCheck performs additional out-of-band checks to determine the
|
||||
// values of a torrent. Some indexers do not announce torrent size, so it is
|
||||
// necessary to determine the size of the torrent in some other way. Some
|
||||
// indexers have an API implemented to fetch this data. For those which don't,
|
||||
// it is necessary to download the torrent file and parse it to make the size
|
||||
|
@ -484,12 +500,12 @@ func (s *service) AdditionalSizeCheck(ctx context.Context, f *domain.Filter, rel
|
|||
// do additional size check against indexer api or torrent for size
|
||||
l := s.log.With().Str("method", "AdditionalSizeCheck").Logger()
|
||||
|
||||
l.Debug().Msgf("(%s) additional size check required", f.Name)
|
||||
l.Debug().Msgf("(%s) additional api size check required", f.Name)
|
||||
|
||||
switch release.Indexer.Identifier {
|
||||
case "ptp", "btn", "ggn", "redacted", "ops", "mock":
|
||||
if release.Size == 0 {
|
||||
l.Trace().Msgf("(%s) preparing to check via api", f.Name)
|
||||
case "btn", "ggn", "redacted", "ops", "mock":
|
||||
if (release.Size == 0 && release.AdditionalSizeCheckRequired) || (release.Uploader == "" && release.AdditionalUploaderCheckRequired) {
|
||||
l.Trace().Msgf("(%s) preparing to check size via api", f.Name)
|
||||
|
||||
torrentInfo, err := s.apiService.GetTorrentByID(ctx, release.Indexer.Identifier, release.TorrentID)
|
||||
if err != nil || torrentInfo == nil {
|
||||
|
@ -499,16 +515,25 @@ func (s *service) AdditionalSizeCheck(ctx context.Context, f *domain.Filter, rel
|
|||
|
||||
l.Debug().Msgf("(%s) got torrent info from api: %+v", f.Name, torrentInfo)
|
||||
|
||||
release.Size = torrentInfo.ReleaseSizeBytes()
|
||||
torrentSize := torrentInfo.ReleaseSizeBytes()
|
||||
if release.Size == 0 && torrentSize > 0 {
|
||||
release.Size = torrentSize
|
||||
}
|
||||
|
||||
if release.Uploader == "" {
|
||||
release.Uploader = torrentInfo.Uploader
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
l.Trace().Msgf("(%s) preparing to download torrent metafile", f.Name)
|
||||
if release.Size == 0 && release.AdditionalSizeCheckRequired {
|
||||
l.Trace().Msgf("(%s) preparing to download torrent metafile", f.Name)
|
||||
|
||||
// if indexer doesn't have api, download torrent and add to tmpPath
|
||||
if err := s.downloadSvc.DownloadRelease(ctx, release); err != nil {
|
||||
l.Error().Err(err).Msgf("(%s) could not download torrent file with id: '%s' from: %s", f.Name, release.TorrentID, release.Indexer.Identifier)
|
||||
return false, errors.Wrap(err, "could not download torrent file for release: %s", release.TorrentName)
|
||||
// if indexer doesn't have api, download torrent and add to tmpPath
|
||||
if err := s.downloadSvc.DownloadRelease(ctx, release); err != nil {
|
||||
l.Error().Err(err).Msgf("(%s) could not download torrent file with id: '%s' from: %s", f.Name, release.TorrentID, release.Indexer.Identifier)
|
||||
return false, errors.Wrap(err, "could not download torrent file for release: %s", release.TorrentName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -518,6 +543,9 @@ func (s *service) AdditionalSizeCheck(ctx context.Context, f *domain.Filter, rel
|
|||
return false, err
|
||||
}
|
||||
|
||||
// reset AdditionalSizeCheckRequired to not re-trigger check
|
||||
release.AdditionalSizeCheckRequired = false
|
||||
|
||||
if !sizeOk {
|
||||
l.Debug().Msgf("(%s) filter did not match after additional size check, trying next", f.Name)
|
||||
return false, err
|
||||
|
@ -526,6 +554,82 @@ func (s *service) AdditionalSizeCheck(ctx context.Context, f *domain.Filter, rel
|
|||
return true, nil
|
||||
}
|
||||
|
||||
func (s *service) AdditionalUploaderCheck(ctx context.Context, f *domain.Filter, release *domain.Release) (bool, error) {
|
||||
var err error
|
||||
defer func() {
|
||||
// try recover panic if anything went wrong with API or size checks
|
||||
errors.RecoverPanic(recover(), &err)
|
||||
}()
|
||||
|
||||
// do additional check against indexer api
|
||||
l := s.log.With().Str("method", "AdditionalUploaderCheck").Logger()
|
||||
|
||||
// if uploader was fetched before during size check we check it and return early
|
||||
if release.Uploader != "" {
|
||||
uploaderOk, err := f.CheckUploader(release.Uploader)
|
||||
if err != nil {
|
||||
l.Error().Err(err).Msgf("(%s) error comparing release and uploaders", f.Name)
|
||||
return false, err
|
||||
}
|
||||
|
||||
// reset AdditionalUploaderCheckRequired to not re-trigger check
|
||||
release.AdditionalUploaderCheckRequired = false
|
||||
|
||||
if !uploaderOk {
|
||||
l.Debug().Msgf("(%s) filter did not match after additional uploaders check, trying next", f.Name)
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
l.Debug().Msgf("(%s) additional api size check required", f.Name)
|
||||
|
||||
switch release.Indexer.Identifier {
|
||||
case "redacted", "ops", "mock":
|
||||
l.Trace().Msgf("(%s) preparing to check via api", f.Name)
|
||||
|
||||
torrentInfo, err := s.apiService.GetTorrentByID(ctx, release.Indexer.Identifier, release.TorrentID)
|
||||
if err != nil || torrentInfo == nil {
|
||||
l.Error().Err(err).Msgf("(%s) could not get torrent info from api: '%s' from: %s", f.Name, release.TorrentID, release.Indexer.Identifier)
|
||||
return false, err
|
||||
}
|
||||
|
||||
l.Debug().Msgf("(%s) got torrent info from api: %+v", f.Name, torrentInfo)
|
||||
|
||||
torrentSize := torrentInfo.ReleaseSizeBytes()
|
||||
if release.Size == 0 && torrentSize > 0 {
|
||||
release.Size = torrentSize
|
||||
|
||||
// reset AdditionalSizeCheckRequired to not re-trigger check
|
||||
release.AdditionalSizeCheckRequired = false
|
||||
}
|
||||
|
||||
if release.Uploader == "" {
|
||||
release.Uploader = torrentInfo.Uploader
|
||||
}
|
||||
|
||||
default:
|
||||
return false, errors.New("additional uploader check not supported for this indexer: %s", release.Indexer.Identifier)
|
||||
}
|
||||
|
||||
uploaderOk, err := f.CheckUploader(release.Uploader)
|
||||
if err != nil {
|
||||
l.Error().Err(err).Msgf("(%s) error comparing release and uploaders", f.Name)
|
||||
return false, err
|
||||
}
|
||||
|
||||
// reset AdditionalUploaderCheckRequired to not re-trigger check
|
||||
release.AdditionalUploaderCheckRequired = false
|
||||
|
||||
if !uploaderOk {
|
||||
l.Debug().Msgf("(%s) filter did not match after additional uploaders check, trying next", f.Name)
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (s *service) CheckSmartEpisodeCanDownload(ctx context.Context, params *domain.SmartEpisodeParams) (bool, error) {
|
||||
return s.releaseRepo.CheckSmartEpisodeCanDownload(ctx, params)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue