Files
TermorServer/cmd/server/main.go
benya 46c2c3fb28 feat: import library from media root and stream tracks
Add a filesystem scanner that ingests supported audio files from MEDIA_ROOT into SQLite using embedded tags with filename fallbacks. Wire startup scanning, manual rescan, and authenticated audio streaming into the backend, then connect the web player to the real stream endpoint.
2026-04-02 22:29:04 +03:00

71 lines
1.7 KiB
Go

package main
import (
"context"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"github.com/benya/temporserv/internal/config"
"github.com/benya/temporserv/internal/db"
"github.com/benya/temporserv/internal/httpapi"
"github.com/benya/temporserv/internal/scanner"
)
func main() {
cfg := config.Load()
ctx := context.Background()
database, err := db.Open(ctx, cfg)
if err != nil {
log.Fatalf("database bootstrap failed: %v", err)
}
defer database.Close()
if err := db.Migrate(ctx, database); err != nil {
log.Fatalf("database migrations failed: %v", err)
}
if err := db.Seed(ctx, database, cfg); err != nil {
log.Fatalf("database seed failed: %v", err)
}
scanService := scanner.NewService(database, cfg.MediaRoot)
if scanService.HasMediaFiles() {
if result, err := scanService.Scan(ctx); err != nil {
log.Printf("startup scan failed: %v", err)
} else {
log.Printf("startup scan completed: artists=%d albums=%d tracks=%d", result.Artists, result.Albums, result.Tracks)
}
}
handler := httpapi.NewRouter(cfg, database, scanService)
server := &http.Server{
Addr: cfg.Address(),
Handler: handler,
ReadHeaderTimeout: 10 * time.Second,
}
go func() {
log.Printf("temporserv listening on %s", cfg.Address())
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("server failed: %v", err)
}
}()
stop := make(chan os.Signal, 1)
signal.Notify(stop, os.Interrupt, syscall.SIGTERM)
<-stop
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if err := server.Shutdown(ctx); err != nil {
log.Printf("shutdown error: %v", err)
}
}