mirror of
https://github.com/idanoo/autobrr
synced 2025-07-24 17:29:12 +00:00
refactor: filter and action flow (#225)
* refactor: fitler and action flow * fix: save release before filters * feat: add action client to notifications * feat: improve filter check logging
This commit is contained in:
parent
f32379ae76
commit
a3854ecd59
21 changed files with 654 additions and 313 deletions
132
internal/announce/service.go
Normal file
132
internal/announce/service.go
Normal file
|
@ -0,0 +1,132 @@
|
|||
package announce
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/autobrr/autobrr/internal/action"
|
||||
"github.com/autobrr/autobrr/internal/domain"
|
||||
"github.com/autobrr/autobrr/internal/filter"
|
||||
"github.com/autobrr/autobrr/internal/release"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
type Service interface {
|
||||
Process(release *domain.Release)
|
||||
}
|
||||
|
||||
type service struct {
|
||||
actionSvc action.Service
|
||||
filterSvc filter.Service
|
||||
releaseSvc release.Service
|
||||
}
|
||||
|
||||
type actionClientTypeKey struct {
|
||||
Type domain.ActionType
|
||||
ClientID int32
|
||||
}
|
||||
|
||||
func NewService(actionSvc action.Service, filterSvc filter.Service, releaseSvc release.Service) Service {
|
||||
return &service{
|
||||
actionSvc: actionSvc,
|
||||
filterSvc: filterSvc,
|
||||
releaseSvc: releaseSvc,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *service) Process(release *domain.Release) {
|
||||
// TODO check in config for "Save all releases"
|
||||
// TODO cross-seed check
|
||||
// TODO dupe checks
|
||||
|
||||
// get filters by priority
|
||||
filters, err := s.filterSvc.FindByIndexerIdentifier(release.Indexer)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msgf("announce.Service.Process: error finding filters for indexer: %v", release.Indexer)
|
||||
return
|
||||
}
|
||||
|
||||
// keep track of action clients to avoid sending the same thing all over again
|
||||
// save both client type and client id to potentially try another client of same type
|
||||
triedActionClients := map[actionClientTypeKey]struct{}{}
|
||||
|
||||
// save release
|
||||
//release.FilterStatus = domain.ReleaseStatusFilterApproved
|
||||
err = s.releaseSvc.Store(context.Background(), release)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msgf("announce.Service.Process: error writing release to database: %+v", release)
|
||||
return
|
||||
}
|
||||
|
||||
// loop over and check filters
|
||||
for _, f := range filters {
|
||||
// save filter on release
|
||||
release.Filter = &f
|
||||
release.FilterName = f.Name
|
||||
release.FilterID = f.ID
|
||||
|
||||
// TODO filter limit checks
|
||||
|
||||
// test filter
|
||||
match, err := s.filterSvc.CheckFilter(f, release)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("announce.Service.Process: could not find filter")
|
||||
return
|
||||
}
|
||||
|
||||
if !match {
|
||||
log.Trace().Msgf("announce.Service.Process: indexer: %v, filter: %v release: %v, no match", release.Indexer, release.Filter.Name, release.TorrentName)
|
||||
continue
|
||||
}
|
||||
|
||||
log.Info().Msgf("Matched '%v' (%v) for %v", release.TorrentName, release.Filter.Name, release.Indexer)
|
||||
|
||||
var rejections []string
|
||||
|
||||
// run actions (watchFolder, test, exec, qBittorrent, Deluge, arr etc.)
|
||||
for _, a := range release.Filter.Actions {
|
||||
// only run enabled actions
|
||||
if !a.Enabled {
|
||||
log.Trace().Msgf("announce.Service.Process: indexer: %v, filter: %v release: %v action '%v' not enabled, skip", release.Indexer, release.Filter.Name, release.TorrentName, a.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
log.Trace().Msgf("announce.Service.Process: indexer: %v, filter: %v release: %v , run action: %v", release.Indexer, release.Filter.Name, release.TorrentName, a.Name)
|
||||
|
||||
// keep track of action clients to avoid sending the same thing all over again
|
||||
_, tried := triedActionClients[actionClientTypeKey{Type: a.Type, ClientID: a.ClientID}]
|
||||
if tried {
|
||||
log.Trace().Msgf("announce.Service.Process: indexer: %v, filter: %v release: %v action client already tried, skip", release.Indexer, release.Filter.Name, release.TorrentName)
|
||||
continue
|
||||
}
|
||||
|
||||
rejections, err = s.actionSvc.RunAction(a, *release)
|
||||
if err != nil {
|
||||
log.Error().Stack().Err(err).Msgf("announce.Service.Process: error running actions for filter: %v", release.Filter.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
if len(rejections) > 0 {
|
||||
// if we get a rejection, remember which action client it was from
|
||||
triedActionClients[actionClientTypeKey{Type: a.Type, ClientID: a.ClientID}] = struct{}{}
|
||||
|
||||
// log something and fire events
|
||||
log.Debug().Msgf("announce.Service.Process: indexer: %v, filter: %v release: %v, rejected: %v", release.Indexer, release.Filter.Name, release.TorrentName, strings.Join(rejections, ", "))
|
||||
}
|
||||
|
||||
// if no rejections consider action approved, run next
|
||||
continue
|
||||
}
|
||||
|
||||
// if we have rejections from arr, continue to next filter
|
||||
if len(rejections) > 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// all actions run, decide to stop or continue here
|
||||
break
|
||||
}
|
||||
|
||||
return
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue