feat(subsonic): wire /rest/scrobble into playevents.Writer
submission=false → play_started (replaces in-memory nowPlayingMap). submission=true (default) → synthetic completed play. The nowPlayingMap struct + factory + the nowPlaying field on mediaHandlers are deleted; play_events WHERE ended_at IS NULL is now the source of truth for 'currently playing,' reachable from M3+ work. api.Mount now takes the shared *playevents.Writer instead of cfg so the same writer instance feeds both surfaces.
This commit is contained in:
@@ -11,10 +11,13 @@ import (
|
||||
"github.com/go-chi/chi/v5/middleware"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
|
||||
"time"
|
||||
|
||||
"git.fabledsword.com/bvandeusen/minstrel/internal/api"
|
||||
"git.fabledsword.com/bvandeusen/minstrel/internal/auth"
|
||||
"git.fabledsword.com/bvandeusen/minstrel/internal/config"
|
||||
"git.fabledsword.com/bvandeusen/minstrel/internal/library"
|
||||
"git.fabledsword.com/bvandeusen/minstrel/internal/playevents"
|
||||
"git.fabledsword.com/bvandeusen/minstrel/internal/subsonic"
|
||||
"git.fabledsword.com/bvandeusen/minstrel/web"
|
||||
)
|
||||
@@ -45,14 +48,20 @@ func (s *Server) Router() http.Handler {
|
||||
r.Get("/healthz", s.handleHealthz)
|
||||
|
||||
if s.Pool != nil {
|
||||
api.Mount(r, s.Pool, s.Logger, s.EventsCfg)
|
||||
writer := playevents.NewWriter(
|
||||
s.Pool, s.Logger,
|
||||
time.Duration(s.EventsCfg.SessionTimeoutMinutes)*time.Minute,
|
||||
s.EventsCfg.SkipMaxCompletionRatio,
|
||||
s.EventsCfg.SkipMaxDurationPlayedMs,
|
||||
)
|
||||
api.Mount(r, s.Pool, s.Logger, writer)
|
||||
r.Route("/api/admin", func(admin chi.Router) {
|
||||
admin.Use(auth.RequireAdmin(s.Pool))
|
||||
if s.Scanner != nil {
|
||||
admin.Post("/scan", s.handleAdminScan)
|
||||
}
|
||||
})
|
||||
subsonic.Mount(r, s.Pool, s.Logger, s.SubsonicCfg)
|
||||
subsonic.Mount(r, s.Pool, s.Logger, s.SubsonicCfg, writer)
|
||||
}
|
||||
|
||||
spa := web.Handler()
|
||||
|
||||
Reference in New Issue
Block a user