add support for subsonic podcast api
This commit is contained in:
committed by
Senan Kelly
parent
ce96b9f6fa
commit
9c4286b0e2
@@ -17,6 +17,7 @@ import (
|
||||
"go.senan.xyz/gonic/server/ctrlsubsonic"
|
||||
"go.senan.xyz/gonic/server/db"
|
||||
"go.senan.xyz/gonic/server/jukebox"
|
||||
"go.senan.xyz/gonic/server/podcasts"
|
||||
"go.senan.xyz/gonic/server/scanner"
|
||||
"go.senan.xyz/gonic/server/scrobble"
|
||||
"go.senan.xyz/gonic/server/scrobble/lastfm"
|
||||
@@ -26,6 +27,7 @@ import (
|
||||
type Options struct {
|
||||
DB *db.DB
|
||||
MusicPath string
|
||||
PodcastPath string
|
||||
CachePath string
|
||||
CoverCachePath string
|
||||
ProxyPrefix string
|
||||
@@ -37,12 +39,14 @@ type Server struct {
|
||||
jukebox *jukebox.Jukebox
|
||||
router *mux.Router
|
||||
sessDB *gormstore.Store
|
||||
podcast *podcasts.Podcasts
|
||||
}
|
||||
|
||||
func New(opts Options) *Server {
|
||||
// ** begin sanitation
|
||||
opts.MusicPath = filepath.Clean(opts.MusicPath)
|
||||
opts.CachePath = filepath.Clean(opts.CachePath)
|
||||
opts.PodcastPath = filepath.Clean(opts.PodcastPath)
|
||||
// ** begin controllers
|
||||
scanner := scanner.New(opts.MusicPath, opts.DB, opts.GenreSplit)
|
||||
jukebox := jukebox.New(opts.MusicPath)
|
||||
@@ -64,7 +68,8 @@ func New(opts Options) *Server {
|
||||
sessDB.SessionOpts.HttpOnly = true
|
||||
sessDB.SessionOpts.SameSite = http.SameSiteLaxMode
|
||||
//
|
||||
ctrlAdmin := ctrladmin.New(base, sessDB)
|
||||
pcInit := &podcasts.Podcasts{DB: opts.DB, PodcastBasePath: opts.PodcastPath}
|
||||
ctrlAdmin := ctrladmin.New(base, sessDB, pcInit)
|
||||
scrobblers := []scrobble.Scrobbler{
|
||||
&lastfm.Scrobbler{DB: opts.DB},
|
||||
&listenbrainz.Scrobbler{},
|
||||
@@ -75,6 +80,7 @@ func New(opts Options) *Server {
|
||||
CoverCachePath: opts.CoverCachePath,
|
||||
Jukebox: jukebox,
|
||||
Scrobblers: scrobblers,
|
||||
Podcasts: pcInit,
|
||||
}
|
||||
setupMisc(r, base)
|
||||
setupAdmin(r.PathPrefix("/admin").Subrouter(), ctrlAdmin)
|
||||
@@ -85,6 +91,7 @@ func New(opts Options) *Server {
|
||||
jukebox: jukebox,
|
||||
router: r,
|
||||
sessDB: sessDB,
|
||||
podcast: &podcasts.Podcasts{DB: opts.DB, PodcastBasePath: opts.PodcastPath},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,6 +142,10 @@ func setupAdmin(r *mux.Router, ctrl *ctrladmin.Controller) {
|
||||
routUser.Handle("/delete_playlist_do", ctrl.H(ctrl.ServeDeletePlaylistDo))
|
||||
routUser.Handle("/create_transcode_pref_do", ctrl.H(ctrl.ServeCreateTranscodePrefDo))
|
||||
routUser.Handle("/delete_transcode_pref_do", ctrl.H(ctrl.ServeDeleteTranscodePrefDo))
|
||||
if ctrl.Podcasts.PodcastBasePath != "" {
|
||||
routUser.Handle("/add_podcast_do", ctrl.H(ctrl.ServePodcastAddDo))
|
||||
routUser.Handle("/delete_podcast_do", ctrl.H(ctrl.ServePodcastDeleteDo))
|
||||
}
|
||||
// ** begin admin routes (if session is valid, and is admin)
|
||||
routAdmin := routUser.NewRoute().Subrouter()
|
||||
routAdmin.Use(ctrl.WithAdminSession)
|
||||
@@ -198,8 +209,15 @@ func setupSubsonic(r *mux.Router, ctrl *ctrlsubsonic.Controller) {
|
||||
r.Handle("/search2{_:(?:\\.view)?}", ctrl.H(ctrl.ServeSearchTwo))
|
||||
r.Handle("/getGenres{_:(?:\\.view)?}", ctrl.H(ctrl.ServeGetGenres))
|
||||
r.Handle("/getArtistInfo{_:(?:\\.view)?}", ctrl.H(ctrl.ServeGetArtistInfo))
|
||||
// ** begin unimplemented
|
||||
r.Handle("/getPodcasts{_:(?:\\.view)?}", ctrl.H(ctrl.ServeGetPodcasts))
|
||||
// ** begin podcasts
|
||||
if ctrl.Podcasts.PodcastBasePath != "" {
|
||||
r.Handle("/getPodcasts{_:(?:\\.view)?}", ctrl.H(ctrl.ServeGetPodcasts))
|
||||
r.Handle("/downloadPodcastEpisode{_:(?:\\.view)?}", ctrl.H(ctrl.ServeDownloadPodcastEpisode))
|
||||
r.Handle("/createPodcastChannel{_:(?:\\.view)?}", ctrl.H(ctrl.ServeCreatePodcastChannel))
|
||||
r.Handle("/refreshPodcasts{_:(?:\\.view)?}", ctrl.H(ctrl.ServeRefreshPodcasts))
|
||||
r.Handle("/deletePodcastChannel{_:(?:\\.view)?}", ctrl.H(ctrl.ServeDeletePodcastChannel))
|
||||
r.Handle("/deletePodcastEpisode{_:(?:\\.view)?}", ctrl.H(ctrl.ServeDeletePodcastEpisode))
|
||||
}
|
||||
// middlewares should be run for not found handler
|
||||
// https://github.com/gorilla/mux/issues/416
|
||||
notFoundHandler := ctrl.H(ctrl.ServeNotFound)
|
||||
@@ -264,6 +282,31 @@ func (s *Server) StartJukebox() (FuncExecute, FuncInterrupt) {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) StartPodcastRefresher(dur time.Duration) (FuncExecute, FuncInterrupt) {
|
||||
ticker := time.NewTicker(dur)
|
||||
done := make(chan struct{})
|
||||
waitFor := func() error {
|
||||
for {
|
||||
select {
|
||||
case <-done:
|
||||
return nil
|
||||
case <-ticker.C:
|
||||
if err := s.podcast.RefreshPodcasts(0, true); err != nil {
|
||||
log.Printf("failed to refresh some feeds: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return func() error {
|
||||
log.Printf("starting job 'podcast refresher'\n")
|
||||
return waitFor()
|
||||
}, func(_ error) {
|
||||
// stop job
|
||||
ticker.Stop()
|
||||
done <- struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) StartSessionClean(dur time.Duration) (FuncExecute, FuncInterrupt) {
|
||||
ticker := time.NewTicker(dur)
|
||||
done := make(chan struct{})
|
||||
|
||||
Reference in New Issue
Block a user