mirror of
https://github.com/idanoo/autobrr
synced 2025-07-23 00:39:13 +00:00
252 lines
5.2 KiB
Go
252 lines
5.2 KiB
Go
package indexer
|
|
|
|
import (
|
|
"fmt"
|
|
"io/fs"
|
|
"strings"
|
|
|
|
"gopkg.in/yaml.v2"
|
|
|
|
"github.com/rs/zerolog/log"
|
|
|
|
"github.com/autobrr/autobrr/internal/domain"
|
|
)
|
|
|
|
type Service interface {
|
|
Store(indexer domain.Indexer) (*domain.Indexer, error)
|
|
Update(indexer domain.Indexer) (*domain.Indexer, error)
|
|
Delete(id int) error
|
|
FindByFilterID(id int) ([]domain.Indexer, error)
|
|
List() ([]domain.Indexer, error)
|
|
GetAll() ([]*domain.IndexerDefinition, error)
|
|
GetTemplates() ([]domain.IndexerDefinition, error)
|
|
LoadIndexerDefinitions() error
|
|
GetIndexerByAnnounce(name string) *domain.IndexerDefinition
|
|
Start() error
|
|
}
|
|
|
|
type service struct {
|
|
repo domain.IndexerRepo
|
|
indexerDefinitions map[string]domain.IndexerDefinition
|
|
indexerInstances map[string]domain.IndexerDefinition
|
|
mapIndexerIRCToName map[string]string
|
|
}
|
|
|
|
func NewService(repo domain.IndexerRepo) Service {
|
|
return &service{
|
|
repo: repo,
|
|
indexerDefinitions: make(map[string]domain.IndexerDefinition),
|
|
indexerInstances: make(map[string]domain.IndexerDefinition),
|
|
mapIndexerIRCToName: make(map[string]string),
|
|
}
|
|
}
|
|
|
|
func (s *service) Store(indexer domain.Indexer) (*domain.Indexer, error) {
|
|
i, err := s.repo.Store(indexer)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return i, nil
|
|
}
|
|
|
|
func (s *service) Update(indexer domain.Indexer) (*domain.Indexer, error) {
|
|
i, err := s.repo.Update(indexer)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return i, nil
|
|
}
|
|
|
|
func (s *service) Delete(id int) error {
|
|
if err := s.repo.Delete(id); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *service) FindByFilterID(id int) ([]domain.Indexer, error) {
|
|
filters, err := s.repo.FindByFilterID(id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return filters, nil
|
|
}
|
|
|
|
func (s *service) List() ([]domain.Indexer, error) {
|
|
i, err := s.repo.List()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return i, nil
|
|
}
|
|
|
|
func (s *service) GetAll() ([]*domain.IndexerDefinition, error) {
|
|
indexers, err := s.repo.List()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var res = make([]*domain.IndexerDefinition, 0)
|
|
|
|
for _, indexer := range indexers {
|
|
in := s.getDefinitionByName(indexer.Identifier)
|
|
if in == nil {
|
|
// if no indexerDefinition found, continue
|
|
continue
|
|
}
|
|
|
|
temp := domain.IndexerDefinition{
|
|
ID: indexer.ID,
|
|
Name: in.Name,
|
|
Identifier: in.Identifier,
|
|
Enabled: indexer.Enabled,
|
|
Description: in.Description,
|
|
Language: in.Language,
|
|
Privacy: in.Privacy,
|
|
Protocol: in.Protocol,
|
|
URLS: in.URLS,
|
|
Settings: nil,
|
|
SettingsMap: make(map[string]string),
|
|
IRC: in.IRC,
|
|
Parse: in.Parse,
|
|
}
|
|
|
|
// map settings
|
|
// add value to settings objects
|
|
for _, setting := range in.Settings {
|
|
if v, ok := indexer.Settings[setting.Name]; ok {
|
|
setting.Value = v
|
|
|
|
temp.SettingsMap[setting.Name] = v
|
|
}
|
|
|
|
temp.Settings = append(temp.Settings, setting)
|
|
}
|
|
|
|
res = append(res, &temp)
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
func (s *service) GetTemplates() ([]domain.IndexerDefinition, error) {
|
|
|
|
definitions := s.indexerDefinitions
|
|
|
|
var ret []domain.IndexerDefinition
|
|
for _, definition := range definitions {
|
|
ret = append(ret, definition)
|
|
}
|
|
|
|
return ret, nil
|
|
}
|
|
|
|
func (s *service) Start() error {
|
|
err := s.LoadIndexerDefinitions()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
indexers, err := s.GetAll()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, indexer := range indexers {
|
|
if !indexer.Enabled {
|
|
continue
|
|
}
|
|
|
|
s.indexerInstances[indexer.Identifier] = *indexer
|
|
|
|
// map irc stuff to indexer.name
|
|
if indexer.IRC != nil {
|
|
server := indexer.IRC.Server
|
|
|
|
for _, channel := range indexer.IRC.Channels {
|
|
for _, announcer := range indexer.IRC.Announcers {
|
|
val := fmt.Sprintf("%v:%v:%v", server, channel, announcer)
|
|
s.mapIndexerIRCToName[val] = indexer.Identifier
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// LoadIndexerDefinitions load definitions from golang embed fs
|
|
func (s *service) LoadIndexerDefinitions() error {
|
|
|
|
entries, err := fs.ReadDir(Definitions, "definitions")
|
|
if err != nil {
|
|
log.Fatal().Msgf("failed reading directory: %s", err)
|
|
}
|
|
|
|
if len(entries) == 0 {
|
|
log.Fatal().Msgf("failed reading directory: %s", err)
|
|
return err
|
|
}
|
|
|
|
for _, f := range entries {
|
|
filePath := "definitions/" + f.Name()
|
|
|
|
if strings.Contains(f.Name(), ".yaml") {
|
|
log.Debug().Msgf("parsing: %v", filePath)
|
|
|
|
var d domain.IndexerDefinition
|
|
|
|
data, err := fs.ReadFile(Definitions, filePath)
|
|
if err != nil {
|
|
log.Debug().Err(err).Msgf("failed reading file: %v", filePath)
|
|
return err
|
|
}
|
|
|
|
err = yaml.Unmarshal(data, &d)
|
|
if err != nil {
|
|
log.Error().Err(err).Msgf("failed unmarshal file: %v", filePath)
|
|
return err
|
|
}
|
|
|
|
s.indexerDefinitions[d.Identifier] = d
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *service) GetIndexerByAnnounce(name string) *domain.IndexerDefinition {
|
|
|
|
if identifier, idOk := s.mapIndexerIRCToName[name]; idOk {
|
|
if indexer, ok := s.indexerInstances[identifier]; ok {
|
|
return &indexer
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *service) getDefinitionByName(name string) *domain.IndexerDefinition {
|
|
|
|
if v, ok := s.indexerDefinitions[name]; ok {
|
|
return &v
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *service) getDefinitionForAnnounce(name string) *domain.IndexerDefinition {
|
|
|
|
// map[network:channel:announcer] = indexer01
|
|
|
|
if v, ok := s.indexerDefinitions[name]; ok {
|
|
return &v
|
|
}
|
|
|
|
return nil
|
|
}
|