feat(server/m7-353): config + main.go wiring for coverart enricher

This commit is contained in:
2026-05-04 15:06:28 -04:00
parent 64475d45dc
commit 6c33acf062
2 changed files with 46 additions and 2 deletions
+24
View File
@@ -13,6 +13,7 @@ import (
"git.fabledsword.com/bvandeusen/minstrel/internal/auth" "git.fabledsword.com/bvandeusen/minstrel/internal/auth"
"git.fabledsword.com/bvandeusen/minstrel/internal/config" "git.fabledsword.com/bvandeusen/minstrel/internal/config"
"git.fabledsword.com/bvandeusen/minstrel/internal/coverart"
"git.fabledsword.com/bvandeusen/minstrel/internal/db" "git.fabledsword.com/bvandeusen/minstrel/internal/db"
"git.fabledsword.com/bvandeusen/minstrel/internal/library" "git.fabledsword.com/bvandeusen/minstrel/internal/library"
"git.fabledsword.com/bvandeusen/minstrel/internal/lidarrconfig" "git.fabledsword.com/bvandeusen/minstrel/internal/lidarrconfig"
@@ -71,11 +72,34 @@ func run() error {
} }
scanner := library.New(pool, logger, cfg.Library.ScanPaths) scanner := library.New(pool, logger, cfg.Library.ScanPaths)
contact := cfg.Library.ContactEmail
if contact == "" {
contact = "https://git.fabledsword.com/bvandeusen/minstrel"
}
coverFetcher := coverart.NewFetcher(coverart.FetcherConfig{
UserAgent: fmt.Sprintf("Minstrel/dev (%s)", contact),
MinPeriod: time.Second,
})
coverEnricher := coverart.NewEnricher(pool, logger.With("component", "coverart"), coverFetcher, cfg.Library.CoverArtFromMBCAA)
if cfg.Library.ScanOnStartup && len(cfg.Library.ScanPaths) > 0 { if cfg.Library.ScanOnStartup && len(cfg.Library.ScanPaths) > 0 {
go func() { go func() {
if _, err := scanner.Scan(ctx); err != nil { if _, err := scanner.Scan(ctx); err != nil {
logger.Error("startup scan failed", "err", err) logger.Error("startup scan failed", "err", err)
} }
// Enrich any newly-imported albums (and resume any partial backlog).
if _, err := coverEnricher.EnrichBatch(ctx, cfg.Library.CoverArtBackfillCap); err != nil {
logger.Warn("post-scan cover enrichment failed", "err", err)
}
}()
} else {
// No startup scan — still run the boot backfill once for any rows
// the previous run didn't get to.
go func() {
if _, err := coverEnricher.EnrichBatch(ctx, cfg.Library.CoverArtBackfillCap); err != nil {
logger.Warn("boot cover enrichment failed", "err", err)
}
}() }()
} }
+22 -2
View File
@@ -69,8 +69,11 @@ type AdminBootstrapConfig struct {
} }
type LibraryConfig struct { type LibraryConfig struct {
ScanPaths []string `yaml:"scan_paths"` ScanPaths []string `yaml:"scan_paths"`
ScanOnStartup bool `yaml:"scan_on_startup"` ScanOnStartup bool `yaml:"scan_on_startup"`
CoverArtFromMBCAA bool `yaml:"coverart_from_mbcaa"` // default true
CoverArtBackfillCap int `yaml:"coverart_backfill_cap"` // default 500
ContactEmail string `yaml:"contact_email"` // optional override for MBCAA UA
} }
// SubsonicConfig controls wire-format concessions on the /rest/* surface. // SubsonicConfig controls wire-format concessions on the /rest/* surface.
@@ -134,6 +137,10 @@ func Default() Config {
RadioSize: 50, RadioSize: 50,
RadioSizeMax: 200, RadioSizeMax: 200,
}, },
Library: LibraryConfig{
CoverArtFromMBCAA: true,
CoverArtBackfillCap: 500,
},
} }
} }
@@ -189,6 +196,19 @@ func applyEnv(cfg *Config) {
cfg.Library.ScanOnStartup = b cfg.Library.ScanOnStartup = b
} }
} }
if v, ok := os.LookupEnv("MINSTREL_LIBRARY_COVERART_FROM_MBCAA"); ok {
if b, err := strconv.ParseBool(v); err == nil {
cfg.Library.CoverArtFromMBCAA = b
}
}
if v, ok := os.LookupEnv("MINSTREL_LIBRARY_COVERART_BACKFILL_CAP"); ok {
if n, err := strconv.Atoi(v); err == nil {
cfg.Library.CoverArtBackfillCap = n
}
}
if v, ok := os.LookupEnv("MINSTREL_CONTACT_EMAIL"); ok {
cfg.Library.ContactEmail = v
}
if v, ok := os.LookupEnv("MINSTREL_SUBSONIC_ALLOW_PLAINTEXT_PASSWORD"); ok { if v, ok := os.LookupEnv("MINSTREL_SUBSONIC_ALLOW_PLAINTEXT_PASSWORD"); ok {
if b, err := strconv.ParseBool(v); err == nil { if b, err := strconv.ParseBool(v); err == nil {
cfg.Subsonic.AllowPlaintextPassword = b cfg.Subsonic.AllowPlaintextPassword = b