package services import ( "context" "fmt" "strings" "github.com/fujin/music-agregator/internal/config" "github.com/fujin/music-agregator/internal/indexer" ) type IndexerService struct { indexers []*indexer.TorznabIndexer } type IndexerInfo struct { Name string `json:"name"` URL string `json:"url"` Healthy bool `json:"healthy"` } func NewIndexerService(configs []config.IndexerConfig) (*IndexerService, error) { var indexers []*indexer.TorznabIndexer for _, cfg := range configs { url := buildTorznabURL(cfg) idx, err := indexer.NewTorznabIndexer(cfg.Name, url, cfg.APIKey) if err != nil { return nil, fmt.Errorf("failed to create indexer %s: %w", cfg.Name, err) } indexers = append(indexers, idx) } return &IndexerService{indexers: indexers}, nil } func buildTorznabURL(cfg config.IndexerConfig) string { url := strings.TrimRight(cfg.URL, "/") switch cfg.IndexerType { case config.IndexerTypeJackett: if !strings.Contains(url, "/api/") { url = fmt.Sprintf("%s/api/v2.0/indexers/all/results/torznab", url) } case config.IndexerTypeProwlarr: if !strings.Contains(url, "/api/") { url = fmt.Sprintf("%s/api/v1/indexer/all/newznab", url) } } return url } func (s *IndexerService) Search(ctx context.Context, criteria *indexer.MusicSearchCriteria, indexerName *string) ([]indexer.SearchResult, error) { var results []indexer.SearchResult for _, idx := range s.indexers { if indexerName != nil && idx.Name() != *indexerName { continue } r, err := idx.Search(ctx, criteria) if err != nil { continue } results = append(results, r...) } return results, nil } func (s *IndexerService) GetIndexers(ctx context.Context) []IndexerInfo { var infos []IndexerInfo for _, idx := range s.indexers { healthy := idx.TestConnection(ctx) == nil infos = append(infos, IndexerInfo{ Name: idx.Name(), Healthy: healthy, }) } return infos }