add getAlbumList2

This commit is contained in:
sentriz
2019-05-15 16:03:31 +01:00
parent 4a5b36ccee
commit 5fae510958
7 changed files with 62 additions and 29 deletions

View File

@@ -61,7 +61,7 @@ func readTags(fullPath string) (tag.Metadata, error) {
return tags, nil return tags, nil
} }
func updateAlbum(fullPath string, albumArtistID int, title string) { func updateAlbum(fullPath string, album *db.Album) {
if currentAlbum.ID != 0 { if currentAlbum.ID != 0 {
return return
} }
@@ -76,8 +76,9 @@ func updateAlbum(fullPath string, albumArtistID int, title string) {
} }
currentAlbum = &db.Album{ currentAlbum = &db.Album{
Path: directory, Path: directory,
AlbumArtistID: albumArtistID, Title: album.Title,
Title: title, AlbumArtistID: album.AlbumArtistID,
Year: album.Year,
} }
tx.Save(currentAlbum) tx.Save(currentAlbum)
} }
@@ -182,7 +183,11 @@ func handleTrack(fullPath string, stat os.FileInfo, mime, exten string) error {
// //
// set temporary album's basics - will be updated with // set temporary album's basics - will be updated with
// cover after the tracks inserted when we exit the folder // cover after the tracks inserted when we exit the folder
updateAlbum(fullPath, albumArtist.ID, tags.Album()) updateAlbum(fullPath, &db.Album{
AlbumArtistID: albumArtist.ID,
Title: tags.Album(),
Year: tags.Year(),
})
// //
// update the track with our new album and finally save // update the track with our new album and finally save
track.AlbumID = currentAlbum.ID track.AlbumID = currentAlbum.ID

View File

@@ -70,8 +70,8 @@ func setSubsonicRoutes(cont handler.Controller, mux *http.ServeMux) {
// browse by tag // browse by tag
mux.HandleFunc("/rest/getAlbum", withWare(cont.GetAlbum)) mux.HandleFunc("/rest/getAlbum", withWare(cont.GetAlbum))
mux.HandleFunc("/rest/getAlbum.view", withWare(cont.GetAlbum)) mux.HandleFunc("/rest/getAlbum.view", withWare(cont.GetAlbum))
mux.HandleFunc("/rest/getAlbumList2", withWare(cont.GetAlbumList)) mux.HandleFunc("/rest/getAlbumList2", withWare(cont.GetAlbumListTwo))
mux.HandleFunc("/rest/getAlbumList2.view", withWare(cont.GetAlbumList)) mux.HandleFunc("/rest/getAlbumList2.view", withWare(cont.GetAlbumListTwo))
mux.HandleFunc("/rest/getArtist", withWare(cont.GetArtist)) mux.HandleFunc("/rest/getArtist", withWare(cont.GetArtist))
mux.HandleFunc("/rest/getArtist.view", withWare(cont.GetArtist)) mux.HandleFunc("/rest/getArtist.view", withWare(cont.GetArtist))
mux.HandleFunc("/rest/getArtists", withWare(cont.GetArtists)) mux.HandleFunc("/rest/getArtists", withWare(cont.GetArtists))

View File

@@ -16,6 +16,7 @@ type Album struct {
Path string `gorm:"not null;unique_index"` Path string `gorm:"not null;unique_index"`
CoverID int CoverID int
Cover Cover Cover Cover
Year int
Tracks []Track Tracks []Track
} }
@@ -82,10 +83,11 @@ type Setting struct {
type Play struct { type Play struct {
IDBase IDBase
User User User User
UserID int UserID int `gorm:"not null;index"`
Track Track Album Album
TrackID int AlbumID int `gorm:"not null;index"`
Time time.Time Time time.Time
Count int
} }
// Folder represents the settings table // Folder represents the settings table

View File

@@ -10,12 +10,6 @@ import (
"github.com/sentriz/gonic/subsonic" "github.com/sentriz/gonic/subsonic"
) )
var orderExpr = map[string]interface{}{
"random": gorm.Expr("random()"),
"newest": "updated_at desc",
"alphabeticalByName": "title",
}
func (c *Controller) GetArtists(w http.ResponseWriter, r *http.Request) { func (c *Controller) GetArtists(w http.ResponseWriter, r *http.Request) {
var artists []*db.AlbumArtist var artists []*db.AlbumArtist
c.DB.Find(&artists) c.DB.Find(&artists)
@@ -110,14 +104,37 @@ func (c *Controller) GetAlbum(w http.ResponseWriter, r *http.Request) {
respond(w, r, sub) respond(w, r, sub)
} }
func (c *Controller) GetAlbumList(w http.ResponseWriter, r *http.Request) { func (c *Controller) GetAlbumListTwo(w http.ResponseWriter, r *http.Request) {
listType := getStrParam(r, "type") listType := getStrParam(r, "type")
if listType == "" { if listType == "" {
respondError(w, r, 10, "please provide a `type` parameter") respondError(w, r, 10, "please provide a `type` parameter")
return return
} }
orderType, ok := orderExpr[listType] query := c.DB
if !ok { switch listType {
case "alphabeticalByArtist":
query = query.
Joins("JOIN album_artists ON albums.album_artist_id=album_artists.id").
Order("album_artists.name")
case "alphabeticalByName":
query = query.Order("title")
case "byYear":
query = query.Order("year")
case "frequent":
user := r.Context().Value(contextUserKey).(*db.User)
query = query.
Joins("JOIN plays ON albums.id=plays.album_id AND plays.user_id=?", user.ID).
Order("plays.count desc")
case "newest":
query = query.Order("updated_at desc")
case "random":
query = query.Order(gorm.Expr("random()"))
case "recent":
user := r.Context().Value(contextUserKey).(*db.User)
query = query.
Joins("JOIN plays ON albums.id=plays.album_id AND plays.user_id=?", user.ID).
Order("plays.time desc")
default:
respondError(w, r, 10, fmt.Sprintf( respondError(w, r, 10, fmt.Sprintf(
"unknown value `%s` for parameter 'type'", listType, "unknown value `%s` for parameter 'type'", listType,
)) ))
@@ -125,10 +142,9 @@ func (c *Controller) GetAlbumList(w http.ResponseWriter, r *http.Request) {
} }
size := getIntParamOr(r, "size", 10) size := getIntParamOr(r, "size", 10)
var albums []*db.Album var albums []*db.Album
c.DB. query.
Preload("AlbumArtist").
Order(orderType).
Limit(size). Limit(size).
Preload("AlbumArtist").
Find(&albums) Find(&albums)
sub := subsonic.NewResponse() sub := subsonic.NewResponse()
for _, album := range albums { for _, album := range albums {

View File

@@ -30,7 +30,9 @@ func (c *Controller) Stream(w http.ResponseWriter, r *http.Request) {
return return
} }
var track db.Track var track db.Track
c.DB.First(&track, id) c.DB.
Preload("Album").
First(&track, id)
if track.Path == "" { if track.Path == "" {
respondError(w, r, 70, fmt.Sprintf("media with id `%d` was not found", id)) respondError(w, r, 70, fmt.Sprintf("media with id `%d` was not found", id))
return return
@@ -42,6 +44,17 @@ func (c *Controller) Stream(w http.ResponseWriter, r *http.Request) {
} }
stat, _ := file.Stat() stat, _ := file.Stat()
http.ServeContent(w, r, track.Path, stat.ModTime(), file) http.ServeContent(w, r, track.Path, stat.ModTime(), file)
//
// after we've served the file, mark the album as played
user := r.Context().Value(contextUserKey).(*db.User)
play := db.Play{
AlbumID: track.Album.ID,
UserID: user.ID,
}
c.DB.Where(play).First(&play)
play.Time = time.Now() // for getAlbumList?type=recent
play.Count++ // for getAlbumList?type=frequent
c.DB.Save(&play)
} }
func (c *Controller) GetCoverArt(w http.ResponseWriter, r *http.Request) { func (c *Controller) GetCoverArt(w http.ResponseWriter, r *http.Request) {
@@ -75,12 +88,7 @@ func (c *Controller) Scrobble(w http.ResponseWriter, r *http.Request) {
return return
} }
// fetch user to get lastfm session // fetch user to get lastfm session
username := getStrParam(r, "u") user := r.Context().Value(contextUserKey).(*db.User)
user := c.GetUserFromName(username)
if user == nil {
respondError(w, r, 10, "could not find a user with that name")
return
}
if user.LastFMSession == "" { if user.LastFMSession == "" {
respondError(w, r, 0, fmt.Sprintf("no last.fm session for this user: %v", err)) respondError(w, r, 0, fmt.Sprintf("no last.fm session for this user: %v", err))
return return

View File

@@ -1,6 +1,7 @@
package handler package handler
import ( import (
"context"
"crypto/md5" "crypto/md5"
"encoding/hex" "encoding/hex"
"fmt" "fmt"
@@ -75,7 +76,8 @@ func (c *Controller) WithValidSubsonicArgs(next http.HandlerFunc) http.HandlerFu
respondError(w, r, 40, "invalid password") respondError(w, r, 40, "invalid password")
return return
} }
next.ServeHTTP(w, r) withUser := context.WithValue(r.Context(), contextUserKey, user)
next.ServeHTTP(w, r.WithContext(withUser))
} }
} }