Removed engine.Scrobbler
This commit is contained in:
+1
-2
@@ -46,13 +46,12 @@ func CreateSubsonicAPIRouter() (*subsonic.Router, error) {
|
|||||||
listGenerator := engine.NewListGenerator(dataStore, nowPlayingRepository)
|
listGenerator := engine.NewListGenerator(dataStore, nowPlayingRepository)
|
||||||
users := engine.NewUsers(dataStore)
|
users := engine.NewUsers(dataStore)
|
||||||
playlists := engine.NewPlaylists(dataStore)
|
playlists := engine.NewPlaylists(dataStore)
|
||||||
scrobbler := engine.NewScrobbler(dataStore, nowPlayingRepository)
|
|
||||||
transcoderTranscoder := transcoder.New()
|
transcoderTranscoder := transcoder.New()
|
||||||
transcodingCache := core.NewTranscodingCache()
|
transcodingCache := core.NewTranscodingCache()
|
||||||
mediaStreamer := core.NewMediaStreamer(dataStore, transcoderTranscoder, transcodingCache)
|
mediaStreamer := core.NewMediaStreamer(dataStore, transcoderTranscoder, transcodingCache)
|
||||||
archiver := core.NewArchiver(dataStore)
|
archiver := core.NewArchiver(dataStore)
|
||||||
players := engine.NewPlayers(dataStore)
|
players := engine.NewPlayers(dataStore)
|
||||||
router := subsonic.New(artwork, listGenerator, users, playlists, scrobbler, mediaStreamer, archiver, players, dataStore)
|
router := subsonic.New(artwork, listGenerator, users, playlists, mediaStreamer, archiver, players, dataStore)
|
||||||
return router, nil
|
return router, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ type Router struct {
|
|||||||
Artwork core.Artwork
|
Artwork core.Artwork
|
||||||
ListGenerator engine.ListGenerator
|
ListGenerator engine.ListGenerator
|
||||||
Playlists engine.Playlists
|
Playlists engine.Playlists
|
||||||
Scrobbler engine.Scrobbler
|
|
||||||
Users engine.Users
|
Users engine.Users
|
||||||
Streamer core.MediaStreamer
|
Streamer core.MediaStreamer
|
||||||
Archiver core.Archiver
|
Archiver core.Archiver
|
||||||
@@ -37,11 +36,10 @@ type Router struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func New(artwork core.Artwork, listGenerator engine.ListGenerator, users engine.Users,
|
func New(artwork core.Artwork, listGenerator engine.ListGenerator, users engine.Users,
|
||||||
playlists engine.Playlists, scrobbler engine.Scrobbler, streamer core.MediaStreamer,
|
playlists engine.Playlists, streamer core.MediaStreamer,
|
||||||
archiver core.Archiver, players engine.Players, ds model.DataStore) *Router {
|
archiver core.Archiver, players engine.Players, ds model.DataStore) *Router {
|
||||||
r := &Router{Artwork: artwork, ListGenerator: listGenerator, Playlists: playlists,
|
r := &Router{Artwork: artwork, ListGenerator: listGenerator, Playlists: playlists,
|
||||||
Scrobbler: scrobbler, Users: users, Streamer: streamer, Archiver: archiver,
|
Users: users, Streamer: streamer, Archiver: archiver, Players: players, DataStore: ds}
|
||||||
Players: players, DataStore: ds}
|
|
||||||
r.mux = r.routes()
|
r.mux = r.routes()
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,70 +0,0 @@
|
|||||||
package engine
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/deluan/navidrome/log"
|
|
||||||
"github.com/deluan/navidrome/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Scrobbler interface {
|
|
||||||
Register(ctx context.Context, playerId int, trackId string, playDate time.Time) (*model.MediaFile, error)
|
|
||||||
NowPlaying(ctx context.Context, playerId int, playerName, trackId, username string) (*model.MediaFile, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewScrobbler(ds model.DataStore, npr NowPlayingRepository) Scrobbler {
|
|
||||||
return &scrobbler{ds: ds, npRepo: npr}
|
|
||||||
}
|
|
||||||
|
|
||||||
type scrobbler struct {
|
|
||||||
ds model.DataStore
|
|
||||||
npRepo NowPlayingRepository
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *scrobbler) Register(ctx context.Context, playerId int, trackId string, playTime time.Time) (*model.MediaFile, error) {
|
|
||||||
var mf *model.MediaFile
|
|
||||||
var err error
|
|
||||||
err = s.ds.WithTx(func(tx model.DataStore) error {
|
|
||||||
mf, err = s.ds.MediaFile(ctx).Get(trackId)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = s.ds.MediaFile(ctx).IncPlayCount(trackId, playTime)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = s.ds.Album(ctx).IncPlayCount(mf.AlbumID, playTime)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = s.ds.Artist(ctx).IncPlayCount(mf.ArtistID, playTime)
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Error while scrobbling", "trackId", trackId, err)
|
|
||||||
} else {
|
|
||||||
log.Info("Scrobbled", "title", mf.Title, "artist", mf.Artist, "user", userName(ctx))
|
|
||||||
}
|
|
||||||
|
|
||||||
return mf, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO Validate if NowPlaying still works after all refactorings
|
|
||||||
func (s *scrobbler) NowPlaying(ctx context.Context, playerId int, playerName, trackId, username string) (*model.MediaFile, error) {
|
|
||||||
mf, err := s.ds.MediaFile(ctx).Get(trackId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if mf == nil {
|
|
||||||
return nil, fmt.Errorf(`ID "%s" not found`, trackId)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Info("Now Playing", "title", mf.Title, "artist", mf.Artist, "user", userName(ctx))
|
|
||||||
|
|
||||||
info := &NowPlayingInfo{TrackID: trackId, Username: username, Start: time.Now(), PlayerId: playerId, PlayerName: playerName}
|
|
||||||
return mf, s.npRepo.Enqueue(info)
|
|
||||||
}
|
|
||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
var Set = wire.NewSet(
|
var Set = wire.NewSet(
|
||||||
NewListGenerator,
|
NewListGenerator,
|
||||||
NewPlaylists,
|
NewPlaylists,
|
||||||
NewScrobbler,
|
|
||||||
NewNowPlayingRepository,
|
NewNowPlayingRepository,
|
||||||
NewUsers,
|
NewUsers,
|
||||||
NewPlayers,
|
NewPlayers,
|
||||||
|
|||||||
@@ -2,23 +2,25 @@ package subsonic
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/deluan/navidrome/log"
|
"github.com/deluan/navidrome/log"
|
||||||
"github.com/deluan/navidrome/model"
|
"github.com/deluan/navidrome/model"
|
||||||
|
"github.com/deluan/navidrome/model/request"
|
||||||
"github.com/deluan/navidrome/server/subsonic/engine"
|
"github.com/deluan/navidrome/server/subsonic/engine"
|
||||||
"github.com/deluan/navidrome/server/subsonic/responses"
|
"github.com/deluan/navidrome/server/subsonic/responses"
|
||||||
"github.com/deluan/navidrome/utils"
|
"github.com/deluan/navidrome/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MediaAnnotationController struct {
|
type MediaAnnotationController struct {
|
||||||
scrobbler engine.Scrobbler
|
|
||||||
ds model.DataStore
|
ds model.DataStore
|
||||||
|
npRepo engine.NowPlayingRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMediaAnnotationController(scrobbler engine.Scrobbler, ds model.DataStore) *MediaAnnotationController {
|
func NewMediaAnnotationController(ds model.DataStore, npr engine.NowPlayingRepository) *MediaAnnotationController {
|
||||||
return &MediaAnnotationController{scrobbler: scrobbler, ds: ds}
|
return &MediaAnnotationController{ds: ds, npRepo: npr}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *MediaAnnotationController) SetRating(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
|
func (c *MediaAnnotationController) SetRating(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
|
||||||
@@ -116,13 +118,13 @@ func (c *MediaAnnotationController) Scrobble(w http.ResponseWriter, r *http.Requ
|
|||||||
t = time.Now()
|
t = time.Now()
|
||||||
}
|
}
|
||||||
if submission {
|
if submission {
|
||||||
_, err := c.scrobbler.Register(r.Context(), playerId, id, t)
|
_, err := c.scrobblerRegister(r.Context(), playerId, id, t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(r, "Error scrobbling track", "id", id, err)
|
log.Error(r, "Error scrobbling track", "id", id, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_, err := c.scrobbler.NowPlaying(r.Context(), playerId, playerName, id, username)
|
_, err := c.scrobblerNowPlaying(r.Context(), playerId, playerName, id, username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(r, "Error setting current song", "id", id, err)
|
log.Error(r, "Error setting current song", "id", id, err)
|
||||||
continue
|
continue
|
||||||
@@ -132,6 +134,52 @@ func (c *MediaAnnotationController) Scrobble(w http.ResponseWriter, r *http.Requ
|
|||||||
return newResponse(), nil
|
return newResponse(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *MediaAnnotationController) scrobblerRegister(ctx context.Context, playerId int, trackId string, playTime time.Time) (*model.MediaFile, error) {
|
||||||
|
var mf *model.MediaFile
|
||||||
|
var err error
|
||||||
|
err = c.ds.WithTx(func(tx model.DataStore) error {
|
||||||
|
mf, err = c.ds.MediaFile(ctx).Get(trackId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = c.ds.MediaFile(ctx).IncPlayCount(trackId, playTime)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = c.ds.Album(ctx).IncPlayCount(mf.AlbumID, playTime)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = c.ds.Artist(ctx).IncPlayCount(mf.ArtistID, playTime)
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
|
||||||
|
username, _ := request.UsernameFrom(ctx)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Error while scrobbling", "trackId", trackId, "user", username, err)
|
||||||
|
} else {
|
||||||
|
log.Info("Scrobbled", "title", mf.Title, "artist", mf.Artist, "user", username)
|
||||||
|
}
|
||||||
|
|
||||||
|
return mf, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *MediaAnnotationController) scrobblerNowPlaying(ctx context.Context, playerId int, playerName, trackId, username string) (*model.MediaFile, error) {
|
||||||
|
mf, err := c.ds.MediaFile(ctx).Get(trackId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if mf == nil {
|
||||||
|
return nil, fmt.Errorf(`ID "%s" not found`, trackId)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info("Now Playing", "title", mf.Title, "artist", mf.Artist, "user", username)
|
||||||
|
|
||||||
|
info := &engine.NowPlayingInfo{TrackID: trackId, Username: username, Start: time.Now(), PlayerId: playerId, PlayerName: playerName}
|
||||||
|
return mf, c.npRepo.Enqueue(info)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *MediaAnnotationController) setStar(ctx context.Context, star bool, ids ...string) error {
|
func (c *MediaAnnotationController) setStar(ctx context.Context, star bool, ids ...string) error {
|
||||||
if len(ids) == 0 {
|
if len(ids) == 0 {
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package subsonic
|
package subsonic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/deluan/navidrome/server/subsonic/engine"
|
||||||
"github.com/google/wire"
|
"github.com/google/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -29,9 +30,9 @@ func initAlbumListController(router *Router) *AlbumListController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func initMediaAnnotationController(router *Router) *MediaAnnotationController {
|
func initMediaAnnotationController(router *Router) *MediaAnnotationController {
|
||||||
scrobbler := router.Scrobbler
|
|
||||||
dataStore := router.DataStore
|
dataStore := router.DataStore
|
||||||
mediaAnnotationController := NewMediaAnnotationController(scrobbler, dataStore)
|
nowPlayingRepository := engine.NewNowPlayingRepository()
|
||||||
|
mediaAnnotationController := NewMediaAnnotationController(dataStore, nowPlayingRepository)
|
||||||
return mediaAnnotationController
|
return mediaAnnotationController
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,5 +85,5 @@ var allProviders = wire.NewSet(
|
|||||||
NewUsersController,
|
NewUsersController,
|
||||||
NewMediaRetrievalController,
|
NewMediaRetrievalController,
|
||||||
NewStreamController,
|
NewStreamController,
|
||||||
NewBookmarksController, wire.FieldsOf(new(*Router), "Artwork", "ListGenerator", "Playlists", "Scrobbler", "Streamer", "Archiver", "DataStore"),
|
NewBookmarksController, engine.NewNowPlayingRepository, wire.FieldsOf(new(*Router), "Artwork", "ListGenerator", "Playlists", "Streamer", "Archiver", "DataStore"),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
package subsonic
|
package subsonic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/deluan/navidrome/server/subsonic/engine"
|
||||||
"github.com/google/wire"
|
"github.com/google/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -17,7 +18,8 @@ var allProviders = wire.NewSet(
|
|||||||
NewMediaRetrievalController,
|
NewMediaRetrievalController,
|
||||||
NewStreamController,
|
NewStreamController,
|
||||||
NewBookmarksController,
|
NewBookmarksController,
|
||||||
wire.FieldsOf(new(*Router), "Artwork", "ListGenerator", "Playlists", "Scrobbler", "Streamer", "Archiver", "DataStore"),
|
engine.NewNowPlayingRepository,
|
||||||
|
wire.FieldsOf(new(*Router), "Artwork", "ListGenerator", "Playlists", "Streamer", "Archiver", "DataStore"),
|
||||||
)
|
)
|
||||||
|
|
||||||
func initSystemController(router *Router) *SystemController {
|
func initSystemController(router *Router) *SystemController {
|
||||||
|
|||||||
Reference in New Issue
Block a user