0.0.32 Flesh out track page

This commit is contained in:
Daniel Mason 2021-08-13 21:37:53 +12:00
parent d7b7ceb122
commit 9074149925
Signed by: idanoo
GPG key ID: 387387CDBC02F132
17 changed files with 216 additions and 48 deletions

View file

@ -71,12 +71,16 @@ func HandleRequests(port string) {
// No Auth
v1.HandleFunc("/stats", limitMiddleware(handleStats, lightLimiter)).Methods("GET")
v1.HandleFunc("/profile/{username}", limitMiddleware(getProfile, lightLimiter)).Methods("GET")
v1.HandleFunc("/artists/top/{uuid}", limitMiddleware(getArtists, lightLimiter)).Methods("GET")
v1.HandleFunc("/artists/{uuid}", limitMiddleware(getArtist, lightLimiter)).Methods("GET")
v1.HandleFunc("/albums/top/{uuid}", limitMiddleware(getArtists, lightLimiter)).Methods("GET")
v1.HandleFunc("/albums/{uuid}", limitMiddleware(getAlbum, lightLimiter)).Methods("GET")
v1.HandleFunc("/tracks/top/{uuid}", limitMiddleware(getTracks, lightLimiter)).Methods("GET")
v1.HandleFunc("/tracks/{uuid}", limitMiddleware(getTrack, lightLimiter)).Methods("GET")
v1.HandleFunc("/tracks/top/{uuid}", limitMiddleware(getTracks, lightLimiter)).Methods("GET") // User UUID - Top Tracks
v1.HandleFunc("/tracks/{uuid}", limitMiddleware(getTrack, lightLimiter)).Methods("GET") // Track UUID
v1.HandleFunc("/tracks/{uuid}/top", limitMiddleware(getTopUsersForTrack, lightLimiter)).Methods("GET") // TrackUUID - Top Listeners
v1.HandleFunc("/register", limitMiddleware(handleRegister, heavyLimiter)).Methods("POST")
v1.HandleFunc("/login", limitMiddleware(handleLogin, standardLimiter)).Methods("POST")
@ -648,6 +652,31 @@ func getTracks(w http.ResponseWriter, r *http.Request) {
w.Write(json)
}
// getTopUsersForTrack - I suck at naming. Returns top users that have scrobbled this track.
func getTopUsersForTrack(w http.ResponseWriter, r *http.Request) {
var uuid string
for k, v := range mux.Vars(r) {
if k == "uuid" {
uuid = v
}
}
if uuid == "" {
throwOkError(w, "Invalid UUID")
return
}
userList, err := getTopUsersForTrackUUID(uuid, 10, 1)
if err != nil {
throwOkError(w, err.Error())
return
}
json, _ := json.Marshal(&userList)
w.WriteHeader(http.StatusOK)
w.Write(json)
}
// postSpotifyResponse - Oauth Response from Spotify
func postSpotifyReponse(w http.ResponseWriter, r *http.Request) {
err := connectSpotifyResponse(r)
@ -748,7 +777,7 @@ func getServerInfo(w http.ResponseWriter, r *http.Request) {
}
info := ServerInfo{
Version: "0.0.31",
Version: "0.0.32",
RegistrationEnabled: cachedRegistrationEnabled,
}

View file

@ -30,6 +30,23 @@ type TopTracks struct {
Tracks map[int]TopTrack `json:"tracks"`
}
type TopUserTrackResponse struct {
Meta TopUserTrackResponseMeta `json:"meta"`
Items []TopUserTrackResponseItem `json:"items"`
}
type TopUserTrackResponseMeta struct {
Count int `json:"count"`
Total int `json:"total"`
Page int `json:"page"`
}
type TopUserTrackResponseItem struct {
UserUUID string `json:"user_uuid"`
Count int `json:"count"`
UserName string `json:"user_name"`
}
// insertTrack - This will return if it exists or create it based on MBID > Name
func insertTrack(name string, legnth int, mbid string, spotifyId string, album string, artists []string, tx *sql.Tx) (Track, error) {
track := Track{}
@ -294,3 +311,57 @@ func (track *Track) getAlbumsForTrack() error {
track.Albums = albums
return nil
}
// getTopUsersForTrackUUID - Returns list of top users for a track
func getTopUsersForTrackUUID(trackUUID string, limit int, page int) (TopUserTrackResponse, error) {
response := TopUserTrackResponse{}
var count int
// Yeah this isn't great. But for now.. it works! Cache later
// TODO: This is counting total scrobbles, not unique users
total, err := getDbCount(
"SELECT COUNT(*) FROM `scrobbles` WHERE `track` = UUID_TO_BIN(?, true) GROUP BY `user`", trackUUID)
if err != nil {
log.Printf("Failed to fetch scrobble count: %+v", err)
return response, errors.New("Failed to fetch combined scrobbles")
}
rows, err := db.Query(
"SELECT BIN_TO_UUID(`scrobbles`.`user`, true), `users`.`username`, COUNT(*) "+
"FROM `scrobbles` "+
"JOIN `users` ON `scrobbles`.`user` = `users`.`uuid` "+
"WHERE `track` = UUID_TO_BIN(?, true) "+
"GROUP BY `scrobbles`.`user` "+
"ORDER BY COUNT(*) DESC LIMIT ?",
trackUUID, limit)
if err != nil {
log.Printf("Failed to fetch scrobbles: %+v", err)
return response, errors.New("Failed to fetch combined scrobbles")
}
defer rows.Close()
for rows.Next() {
item := TopUserTrackResponseItem{}
err := rows.Scan(&item.UserUUID, &item.UserName, &item.Count)
if err != nil {
log.Printf("Failed to fetch scrobbles: %+v", err)
return response, errors.New("Failed to fetch combined scrobbles")
}
count++
response.Items = append(response.Items, item)
}
err = rows.Err()
if err != nil {
log.Printf("Failed to fetch scrobbles: %+v", err)
return response, errors.New("Failed to fetch scrobbles")
}
response.Meta.Count = count
response.Meta.Total = total
response.Meta.Page = page
return response, nil
}

View file

@ -16,6 +16,9 @@ import (
"github.com/google/uuid"
)
// DevMode - Controls background workers and probably more
var DevMode bool
var emailRegex = regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")
var usernameRegex = regexp.MustCompile("^[a-zA-Z0-9_\\.]+$")