mirror of
https://github.com/idanoo/autobrr
synced 2025-07-23 00:39:13 +00:00
Feature: Get size by api for ptp btn and ggn (#66)
* chore: add package * feat: get size by api for ptp and btn * feat: download and parse torrent if not api * feat: bypass tls check and load meta from file * fix: no invite command needed for btn * feat: add ggn api * feat: imrpove logging * feat: build request url * feat: improve err logging
This commit is contained in:
parent
d2aa7c1e7e
commit
2ea2293745
32 changed files with 2181 additions and 99 deletions
|
@ -4,6 +4,8 @@ import (
|
|||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/anacrolix/torrent/metainfo"
|
||||
"github.com/dustin/go-humanize"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"github.com/autobrr/autobrr/internal/domain"
|
||||
|
@ -25,12 +27,14 @@ type service struct {
|
|||
repo domain.FilterRepo
|
||||
actionRepo domain.ActionRepo
|
||||
indexerSvc indexer.Service
|
||||
apiService indexer.APIService
|
||||
}
|
||||
|
||||
func NewService(repo domain.FilterRepo, actionRepo domain.ActionRepo, indexerSvc indexer.Service) Service {
|
||||
func NewService(repo domain.FilterRepo, actionRepo domain.ActionRepo, apiService indexer.APIService, indexerSvc indexer.Service) Service {
|
||||
return &service{
|
||||
repo: repo,
|
||||
actionRepo: actionRepo,
|
||||
apiService: apiService,
|
||||
indexerSvc: indexerSvc,
|
||||
}
|
||||
}
|
||||
|
@ -175,44 +179,113 @@ func (s *service) Delete(ctx context.Context, filterID int) error {
|
|||
}
|
||||
|
||||
func (s *service) FindAndCheckFilters(release *domain.Release) (bool, *domain.Filter, error) {
|
||||
|
||||
// find all enabled filters for indexer
|
||||
filters, err := s.repo.FindByIndexerIdentifier(release.Indexer)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msgf("could not find filters for indexer: %v", release.Indexer)
|
||||
log.Error().Err(err).Msgf("filter-service.find_and_check_filters: could not find filters for indexer: %v", release.Indexer)
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
log.Trace().Msgf("filter-service.find_and_check_filters: found (%d) active filters to check for indexer '%v'", len(filters), release.Indexer)
|
||||
|
||||
// save outside of loop to check multiple filters with only one fetch
|
||||
var torrentInfo *domain.TorrentBasic
|
||||
var torrentFileRes *domain.DownloadTorrentFileResponse
|
||||
var torrentMetaInfo metainfo.Info
|
||||
|
||||
// loop and check release to filter until match
|
||||
for _, f := range filters {
|
||||
log.Trace().Msgf("checking filter: %+v", f.Name)
|
||||
log.Trace().Msgf("filter-service.find_and_check_filters: checking filter: %+v", f.Name)
|
||||
|
||||
matchedFilter := release.CheckFilter(f)
|
||||
// if matched, attach actions and return the f
|
||||
if matchedFilter {
|
||||
//release.Filter = &f
|
||||
//release.FilterID = f.ID
|
||||
//release.FilterName = f.Name
|
||||
// if matched, do additional size check if needed, attach actions and return the filter
|
||||
|
||||
log.Debug().Msgf("found and matched filter: %+v", f.Name)
|
||||
log.Debug().Msgf("filter-service.find_and_check_filters: found and matched filter: %+v", f.Name)
|
||||
|
||||
// TODO do additional size check against indexer api or torrent for size
|
||||
// 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.
|
||||
|
||||
// do additional size check against indexer api or torrent for size
|
||||
if release.AdditionalSizeCheckRequired {
|
||||
log.Debug().Msgf("additional size check required for: %+v", f.Name)
|
||||
// check if indexer = btn,ptp,ggn,red
|
||||
// fetch api for data
|
||||
// else download torrent and add to tmpPath
|
||||
// if size != response.size
|
||||
// r.RecheckSizeFilter(f)
|
||||
//continue
|
||||
log.Debug().Msgf("filter-service.find_and_check_filters: (%v) additional size check required", f.Name)
|
||||
|
||||
// check if indexer = btn,ptp (ggn,red later)
|
||||
if release.Indexer == "ptp" || release.Indexer == "btn" || release.Indexer == "ggn" {
|
||||
// fetch torrent info from api
|
||||
// save outside of loop to check multiple filters with only one fetch
|
||||
if torrentInfo == nil {
|
||||
torrentInfo, err = s.apiService.GetTorrentByID(release.Indexer, release.TorrentID)
|
||||
if err != nil || torrentInfo == nil {
|
||||
log.Error().Stack().Err(err).Msgf("filter-service.find_and_check_filters: (%v) could not get torrent: '%v' from: %v", f.Name, release.TorrentID, release.Indexer)
|
||||
continue
|
||||
}
|
||||
|
||||
log.Debug().Msgf("filter-service.find_and_check_filters: (%v) got torrent info: %+v", f.Name, torrentInfo)
|
||||
}
|
||||
|
||||
// compare size against filters
|
||||
match, err := checkSizeFilter(f.MinSize, f.MaxSize, torrentInfo.ReleaseSizeBytes())
|
||||
if err != nil {
|
||||
log.Error().Stack().Err(err).Msgf("filter-service.find_and_check_filters: (%v) could not check size filter", f.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
// no match, lets continue to next filter
|
||||
if !match {
|
||||
log.Debug().Msgf("filter-service.find_and_check_filters: (%v) filter did not match after additional size check, trying next", f.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
// store size on the release
|
||||
release.Size = torrentInfo.ReleaseSizeBytes()
|
||||
} else {
|
||||
log.Trace().Msgf("filter-service.find_and_check_filters: (%v) additional size check required: preparing to download metafile", f.Name)
|
||||
|
||||
// if indexer doesn't have api, download torrent and add to tmpPath
|
||||
torrentFileRes, err = release.DownloadTorrentFile(nil)
|
||||
if err != nil {
|
||||
log.Error().Stack().Err(err).Msgf("filter-service.find_and_check_filters: (%v) could not download torrent file with id: '%v' from: %v", f.Name, release.TorrentID, release.Indexer)
|
||||
continue
|
||||
}
|
||||
|
||||
// parse torrent metainfo
|
||||
torrentMetaInfo, err = torrentFileRes.MetaInfo.UnmarshalInfo()
|
||||
if err != nil {
|
||||
log.Error().Stack().Err(err).Msgf("filter-service.find_and_check_filters: could not download torrent file: '%v' from: %v", release.TorrentID, release.Indexer)
|
||||
continue
|
||||
}
|
||||
|
||||
// compare size against filter
|
||||
match, err := checkSizeFilter(f.MinSize, f.MaxSize, uint64(torrentMetaInfo.TotalLength()))
|
||||
if err != nil {
|
||||
log.Error().Stack().Err(err).Msgf("filter-service.find_and_check_filters: (%v) could not check size filter", f.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
// no match, lets continue to next filter
|
||||
if !match {
|
||||
log.Debug().Msgf("filter-service.find_and_check_filters: (%v) filter did not match after additional size check, trying next", f.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
// store size on the release
|
||||
release.Size = uint64(torrentMetaInfo.TotalLength())
|
||||
}
|
||||
}
|
||||
|
||||
// find actions and attach
|
||||
// found matching filter, lets find the filter actions and attach
|
||||
actions, err := s.actionRepo.FindByFilterID(f.ID)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msgf("could not find actions for filter: %+v", f.Name)
|
||||
}
|
||||
|
||||
// if no actions, continue to next filter
|
||||
if len(actions) == 0 {
|
||||
log.Trace().Msgf("filter-service.find_and_check_filters: no actions found for filter '%v', trying next one..", f.Name)
|
||||
continue
|
||||
}
|
||||
f.Actions = actions
|
||||
|
||||
return true, &f, nil
|
||||
|
@ -222,3 +295,35 @@ func (s *service) FindAndCheckFilters(release *domain.Release) (bool, *domain.Fi
|
|||
// if no match, return nil
|
||||
return false, nil, nil
|
||||
}
|
||||
|
||||
func checkSizeFilter(minSize string, maxSize string, releaseSize uint64) (bool, error) {
|
||||
// handle both min and max
|
||||
if minSize != "" {
|
||||
// string to bytes
|
||||
minSizeBytes, err := humanize.ParseBytes(minSize)
|
||||
if err != nil {
|
||||
// log could not parse into bytes
|
||||
}
|
||||
|
||||
if releaseSize <= minSizeBytes {
|
||||
//r.addRejection("size: smaller than min size")
|
||||
return false, nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if maxSize != "" {
|
||||
// string to bytes
|
||||
maxSizeBytes, err := humanize.ParseBytes(maxSize)
|
||||
if err != nil {
|
||||
// log could not parse into bytes
|
||||
}
|
||||
|
||||
if releaseSize >= maxSizeBytes {
|
||||
//r.addRejection("size: larger than max size")
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue