refactor: rewrite project from Rust to Go

- Replace Axum with Chi router
- Replace sqlx with pgx for PostgreSQL
- Replace tonic/prost with grpc-go
- Replace tracing with zerolog
- Update flake.nix for Go build with protoc generation
- Preserve all existing endpoints and functionality

Stack: Chi, pgx, grpc-go, zerolog, yaml.v3
This commit is contained in:
Alexander
2026-04-29 10:45:05 +02:00
parent f24543f401
commit 41fb033d30
48 changed files with 2306 additions and 6652 deletions
+84
View File
@@ -0,0 +1,84 @@
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
}