|
|
|
@@ -33,6 +33,7 @@ type Options struct {
|
|
|
|
ProxyPrefix string
|
|
|
|
ProxyPrefix string
|
|
|
|
GenreSplit string
|
|
|
|
GenreSplit string
|
|
|
|
HTTPLog bool
|
|
|
|
HTTPLog bool
|
|
|
|
|
|
|
|
JukeboxEnabled bool
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type Server struct {
|
|
|
|
type Server struct {
|
|
|
|
@@ -44,58 +45,61 @@ type Server struct {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func New(opts Options) *Server {
|
|
|
|
func New(opts Options) *Server {
|
|
|
|
// ** begin sanitation
|
|
|
|
|
|
|
|
opts.MusicPath = filepath.Clean(opts.MusicPath)
|
|
|
|
opts.MusicPath = filepath.Clean(opts.MusicPath)
|
|
|
|
opts.CachePath = filepath.Clean(opts.CachePath)
|
|
|
|
opts.CachePath = filepath.Clean(opts.CachePath)
|
|
|
|
opts.PodcastPath = filepath.Clean(opts.PodcastPath)
|
|
|
|
opts.PodcastPath = filepath.Clean(opts.PodcastPath)
|
|
|
|
// ** begin controllers
|
|
|
|
|
|
|
|
scanner := scanner.New(opts.MusicPath, opts.DB, opts.GenreSplit)
|
|
|
|
scanner := scanner.New(opts.MusicPath, opts.DB, opts.GenreSplit)
|
|
|
|
jukebox := jukebox.New(opts.MusicPath)
|
|
|
|
|
|
|
|
// the base controller, it's fields/middlewares are embedded/used by the
|
|
|
|
|
|
|
|
// other two admin ui and subsonic controllers
|
|
|
|
|
|
|
|
base := &ctrlbase.Controller{
|
|
|
|
base := &ctrlbase.Controller{
|
|
|
|
DB: opts.DB,
|
|
|
|
DB: opts.DB,
|
|
|
|
MusicPath: opts.MusicPath,
|
|
|
|
MusicPath: opts.MusicPath,
|
|
|
|
ProxyPrefix: opts.ProxyPrefix,
|
|
|
|
ProxyPrefix: opts.ProxyPrefix,
|
|
|
|
Scanner: scanner,
|
|
|
|
Scanner: scanner,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// router with common wares for admin / subsonic
|
|
|
|
// router with common wares for admin / subsonic
|
|
|
|
r := mux.NewRouter()
|
|
|
|
r := mux.NewRouter()
|
|
|
|
if opts.HTTPLog {
|
|
|
|
if opts.HTTPLog {
|
|
|
|
r.Use(base.WithLogging)
|
|
|
|
r.Use(base.WithLogging)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
r.Use(base.WithCORS)
|
|
|
|
r.Use(base.WithCORS)
|
|
|
|
//
|
|
|
|
|
|
|
|
sessKey := opts.DB.GetOrCreateKey("session_key")
|
|
|
|
sessKey := opts.DB.GetOrCreateKey("session_key")
|
|
|
|
sessDB := gormstore.New(opts.DB.DB, []byte(sessKey))
|
|
|
|
sessDB := gormstore.New(opts.DB.DB, []byte(sessKey))
|
|
|
|
sessDB.SessionOpts.HttpOnly = true
|
|
|
|
sessDB.SessionOpts.HttpOnly = true
|
|
|
|
sessDB.SessionOpts.SameSite = http.SameSiteLaxMode
|
|
|
|
sessDB.SessionOpts.SameSite = http.SameSiteLaxMode
|
|
|
|
//
|
|
|
|
|
|
|
|
pcInit := &podcasts.Podcasts{DB: opts.DB, PodcastBasePath: opts.PodcastPath}
|
|
|
|
podcast := &podcasts.Podcasts{DB: opts.DB, PodcastBasePath: opts.PodcastPath}
|
|
|
|
ctrlAdmin := ctrladmin.New(base, sessDB, pcInit)
|
|
|
|
ctrlAdmin := ctrladmin.New(base, sessDB, podcast)
|
|
|
|
scrobblers := []scrobble.Scrobbler{
|
|
|
|
|
|
|
|
&lastfm.Scrobbler{DB: opts.DB},
|
|
|
|
|
|
|
|
&listenbrainz.Scrobbler{},
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
ctrlSubsonic := &ctrlsubsonic.Controller{
|
|
|
|
ctrlSubsonic := &ctrlsubsonic.Controller{
|
|
|
|
Controller: base,
|
|
|
|
Controller: base,
|
|
|
|
CachePath: opts.CachePath,
|
|
|
|
CachePath: opts.CachePath,
|
|
|
|
CoverCachePath: opts.CoverCachePath,
|
|
|
|
CoverCachePath: opts.CoverCachePath,
|
|
|
|
Jukebox: jukebox,
|
|
|
|
Scrobblers: []scrobble.Scrobbler{
|
|
|
|
Scrobblers: scrobblers,
|
|
|
|
&lastfm.Scrobbler{DB: opts.DB},
|
|
|
|
Podcasts: pcInit,
|
|
|
|
&listenbrainz.Scrobbler{},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
Podcasts: podcast,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
setupMisc(r, base)
|
|
|
|
setupMisc(r, base)
|
|
|
|
setupAdmin(r.PathPrefix("/admin").Subrouter(), ctrlAdmin)
|
|
|
|
setupAdmin(r.PathPrefix("/admin").Subrouter(), ctrlAdmin)
|
|
|
|
setupSubsonic(r.PathPrefix("/rest").Subrouter(), ctrlSubsonic)
|
|
|
|
setupSubsonic(r.PathPrefix("/rest").Subrouter(), ctrlSubsonic)
|
|
|
|
//
|
|
|
|
|
|
|
|
return &Server{
|
|
|
|
server := &Server{
|
|
|
|
scanner: scanner,
|
|
|
|
scanner: scanner,
|
|
|
|
jukebox: jukebox,
|
|
|
|
|
|
|
|
router: r,
|
|
|
|
router: r,
|
|
|
|
sessDB: sessDB,
|
|
|
|
sessDB: sessDB,
|
|
|
|
podcast: &podcasts.Podcasts{DB: opts.DB, PodcastBasePath: opts.PodcastPath},
|
|
|
|
podcast: podcast,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if opts.JukeboxEnabled {
|
|
|
|
|
|
|
|
jukebox := jukebox.New(opts.MusicPath)
|
|
|
|
|
|
|
|
ctrlSubsonic.Jukebox = jukebox
|
|
|
|
|
|
|
|
server.jukebox = jukebox
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return server
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func setupMisc(r *mux.Router, ctrl *ctrlbase.Controller) {
|
|
|
|
func setupMisc(r *mux.Router, ctrl *ctrlbase.Controller) {
|
|
|
|
|