0.1.1 Reworked Spotify, Cache values, Update package name

This commit is contained in:
Daniel Mason 2022-01-05 22:32:20 +13:00
parent 3394816606
commit 8c38eca4bc
12 changed files with 105 additions and 71 deletions

View file

@ -59,19 +59,36 @@ func updateConfigValue(key string, value string) error {
return errors.New("Failed to update config value.")
}
// Set cached config
redisKey := "config:" + key
setRedisVal(redisKey, value)
return nil
}
func getConfigValue(key string) (string, error) {
var value string
err := db.QueryRow("SELECT `value` FROM `config` "+
"WHERE `key` = ?",
key).Scan(&value)
// Check if cached first
redisKey := "config:" + key
if err == sql.ErrNoRows {
return value, errors.New("Config key doesn't exist")
// TODO: Handle unset vals in DB to prevent excess calls if not using spotify/etc.
configKey := getRedisVal(redisKey)
if configKey == "" {
err := db.QueryRow("SELECT `value` FROM `config` "+
"WHERE `key` = ?",
key).Scan(&value)
if err == sql.ErrNoRows {
return value, errors.New("Config key doesn't exist")
}
if value != "" {
setRedisVal(redisKey, value)
}
return value, nil
}
return value, nil
return configKey, nil
}

View file

@ -47,10 +47,10 @@ func ParseJellyfinInput(userUUID string, jf JellyfinRequest, ip net.IP, tx *sql.
// Debugging
// fmt.Printf("%+v", jf)
// Prevents scrobbling same song twice!
cacheKey := jf.UserID + ":" + jf.Name + ":" + jf.Artist + ":" + jf.Album + ":" + jf.ServerID
redisKey := getMd5(cacheKey + userUUID)
if getRedisKeyExists(redisKey) {
// Custom cache key - never log the same song twice in a row for now... (:
lastPlayedTitle := getUserLastPlayed(userUUID)
if lastPlayedTitle == jf.Name+":"+jf.Album {
// If it matches last played song, skip it
return nil
}
@ -103,8 +103,7 @@ func ParseJellyfinInput(userUUID string, jf JellyfinRequest, ip net.IP, tx *sql.
}
// Add cache key!
ttl := time.Duration(timestampToSeconds(jf.RunTime)) * time.Second
setRedisValTtl(redisKey, "1", ttl)
setUserLastPlayed(userUUID, jf.Name+":"+jf.Album)
return nil
}

View file

@ -3,7 +3,6 @@ package goscrobble
import (
"database/sql"
"errors"
"fmt"
"log"
"net"
"time"
@ -19,10 +18,10 @@ type MultiScrobblerRequest struct {
// ParseMultiScrobblerInput - Transform API data
func ParseMultiScrobblerInput(userUUID string, data MultiScrobblerRequest, ip net.IP, tx *sql.Tx) error {
// Cache key
json := fmt.Sprintf("%s:%s:%s", data.PlayedAt, data.Track, userUUID)
redisKey := getMd5(json)
if getRedisKeyExists(redisKey) {
// Custom cache key - never log the same song twice in a row for now... (:
lastPlayedTitle := getUserLastPlayed(userUUID)
if lastPlayedTitle == data.Track+":"+data.Album {
// If it matches last played song, skip it
return nil
}
@ -61,8 +60,7 @@ func ParseMultiScrobblerInput(userUUID string, data MultiScrobblerRequest, ip ne
return errors.New("Failed to map track")
}
ttl := time.Duration(24) * time.Hour
setRedisValTtl(redisKey, "1", ttl)
setUserLastPlayed(userUUID, data.Track+":"+data.Album)
return nil
}

View file

@ -138,10 +138,10 @@ func validateNavidromeConnection(url string, username string, hash string, salt
// ParseNavidromeInput - Transform API data
func ParseNavidromeInput(userUUID string, data NavidromeNowPlaying, ip net.IP, tx *sql.Tx) error {
// Cache key
json := fmt.Sprintf("%s:%s:%s", data.ID, data.Parent, userUUID)
redisKey := getMd5(json)
if getRedisKeyExists(redisKey) {
// Custom cache key - never log the same song twice in a row for now... (:
lastPlayedTitle := getUserLastPlayed(userUUID)
if lastPlayedTitle == data.Title+":"+data.Album {
// If it matches last played song, skip it
return nil
}
@ -177,9 +177,7 @@ func ParseNavidromeInput(userUUID string, data NavidromeNowPlaying, ip net.IP, t
return errors.New("Failed to map track")
}
// Todo: Find a better way to check dupes
ttl := time.Duration(data.Duration*2) * time.Second
setRedisValTtl(redisKey, "1", ttl)
setUserLastPlayed(userUUID, data.Title+":"+data.Album)
return nil
}

View file

@ -64,11 +64,15 @@ func getSpotifyAuthHandler() spotifyauth.Authenticator {
func connectSpotifyResponse(r *http.Request) error {
urlParams := r.URL.Query()
userUuid := urlParams["state"][0]
userUUID := urlParams["state"][0]
_, err := getUserByUUID(userUUID)
if err != nil {
return err
}
// TODO: Add validation user exists here
auth := getSpotifyAuthHandler()
token, err := auth.Token(r.Context(), userUuid, r)
token, err := auth.Token(r.Context(), userUUID, r)
if err != nil {
return err
}
@ -79,7 +83,7 @@ func connectSpotifyResponse(r *http.Request) error {
// Lets pull in last 30 minutes
time := time.Now().UTC().Add(-(time.Duration(30) * time.Minute))
err = insertOauthToken(userUuid, "spotify", token.AccessToken, token.RefreshToken, token.Expiry, spotifyUser.DisplayName, time, "")
err = insertOauthToken(userUUID, "spotify", token.AccessToken, token.RefreshToken, token.Expiry, spotifyUser.DisplayName, time, "")
if err != nil {
return err
}

View file

@ -133,24 +133,21 @@ func HandleRequests(port string) {
// API ENDPOINT HANDLING
// handleRegister - Does as it says!
func handleRegister(w http.ResponseWriter, r *http.Request) {
cachedRegistrationEnabled := getRedisVal("REGISTRATION_ENABLED")
if cachedRegistrationEnabled == "" {
registrationEnabled, err := getConfigValue("REGISTRATION_ENABLED")
if err != nil {
throwOkError(w, "Error checking if registration is enabled")
}
setRedisVal("REGISTRATION_ENABLED", registrationEnabled)
cachedRegistrationEnabled = registrationEnabled
registrationEnabled, err := getConfigValue("REGISTRATION_ENABLED")
if err != nil {
log.Printf("%+v", err)
throwOkError(w, "Registration is currently disabled")
return
}
if cachedRegistrationEnabled == "0" {
if registrationEnabled == "0" {
throwOkError(w, "Registration is currently disabled")
return
}
regReq := RequestRequest{}
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&regReq)
err = decoder.Decode(&regReq)
if err != nil {
throwBadReq(w, err.Error())
return
@ -778,19 +775,15 @@ func deleteNavidrome(w http.ResponseWriter, r *http.Request, claims CustomClaims
}
func getServerInfo(w http.ResponseWriter, r *http.Request) {
cachedRegistrationEnabled := getRedisVal("REGISTRATION_ENABLED")
if cachedRegistrationEnabled == "" {
registrationEnabled, err := getConfigValue("REGISTRATION_ENABLED")
if err != nil {
throwOkError(w, "Error fetching serverinfo")
}
setRedisVal("REGISTRATION_ENABLED", registrationEnabled)
cachedRegistrationEnabled = registrationEnabled
registrationEnabled, err := getConfigValue("REGISTRATION_ENABLED")
if err != nil {
log.Printf("%+v", err)
registrationEnabled = "0"
}
info := ServerInfo{
Version: "0.1.0",
RegistrationEnabled: cachedRegistrationEnabled,
Version: "0.1.1",
RegistrationEnabled: registrationEnabled,
}
js, _ := json.Marshal(&info)

View file

@ -317,8 +317,6 @@ func getTopUsersForTrackUUID(trackUUID string, limit int, page int) (TopUserTrac
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 `track`, `user`", trackUUID)

View file

@ -201,7 +201,7 @@ func getUserByUUID(uuid string) (User, error) {
uuid).Scan(&user.UUID, &user.CreatedAt, &user.CreatedIp, &user.ModifiedAt, &user.ModifiedIP, &user.Username, &user.Email, &user.Password, &user.Verified, &user.Admin, &user.Mod, &user.Timezone, &user.Token)
if err == sql.ErrNoRows {
return user, errors.New("Invalid JWT Token")
return user, errors.New("Invalid user UUID")
}
return user, nil
@ -378,3 +378,11 @@ func getAllNavidromeUsers() ([]User, error) {
return users, nil
}
func getUserLastPlayed(userUUID string) string {
return getRedisVal("lastPlayed:" + userUUID)
}
func setUserLastPlayed(userUUID string, val string) {
setRedisVal("lastPlayed:"+userUUID, val)
}