From 659b68f11d4e0ea7a6cabcd6d792740239c9f3dd Mon Sep 17 00:00:00 2001 From: riwiwa Date: Sat, 28 Feb 2026 00:13:37 -0800 Subject: [PATCH] fix spotify connection --- scrobble/scrobble.go | 21 ++++++++++++++++++++- scrobble/spotify.go | 11 ++++++++--- static/style.css | 20 ++++++++++++++++++++ templates/settings.gohtml | 5 +++++ web/settings.go | 31 +++++++++++++++++++++++++++++++ web/web.go | 1 + 6 files changed, 85 insertions(+), 4 deletions(-) diff --git a/scrobble/scrobble.go b/scrobble/scrobble.go index 1d402dd..aa5e34e 100644 --- a/scrobble/scrobble.go +++ b/scrobble/scrobble.go @@ -180,14 +180,33 @@ func ClearNowPlaying(userId int) { } func GetUserSpotifyCredentials(userId int) (clientId, clientSecret, accessToken, refreshToken string, expiresAt time.Time, err error) { + var clientIdPg, clientSecretPg, accessTokenPg, refreshTokenPg pgtype.Text + var expiresAtPg pgtype.Timestamptz err = db.Pool.QueryRow(context.Background(), `SELECT spotify_client_id, spotify_client_secret, spotify_access_token, spotify_refresh_token, spotify_token_expires FROM users WHERE pk = $1`, - userId).Scan(&clientId, &clientSecret, &accessToken, &refreshToken, &expiresAt) + userId).Scan(&clientIdPg, &clientSecretPg, &accessTokenPg, &refreshTokenPg, &expiresAtPg) if err != nil { return "", "", "", "", time.Time{}, err } + + if clientIdPg.Status == pgtype.Present { + clientId = clientIdPg.String + } + if clientSecretPg.Status == pgtype.Present { + clientSecret = clientSecretPg.String + } + if accessTokenPg.Status == pgtype.Present { + accessToken = accessTokenPg.String + } + if refreshTokenPg.Status == pgtype.Present { + refreshToken = refreshTokenPg.String + } + if expiresAtPg.Status == pgtype.Present { + expiresAt = expiresAtPg.Time + } + return clientId, clientSecret, accessToken, refreshToken, expiresAt, nil } diff --git a/scrobble/spotify.go b/scrobble/spotify.go index b95f007..f2fec22 100644 --- a/scrobble/spotify.go +++ b/scrobble/spotify.go @@ -77,9 +77,9 @@ type SpotifyCursors struct { func (h *SpotifyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { path := r.URL.Path - if path == "/authorize" { + if path == "/scrobble/spotify/authorize" { h.handleAuthorize(w, r) - } else if path == "/callback" { + } else if path == "/scrobble/spotify/callback" { h.handleCallback(w, r) } else { http.Error(w, "Not found", http.StatusNotFound) @@ -94,6 +94,7 @@ func (h *SpotifyHandler) handleAuthorize(w http.ResponseWriter, r *http.Request) } clientId, _, _, _, _, err := GetUserSpotifyCredentials(userIdToInt(userId)) + fmt.Fprintf(os.Stderr, "handleAuthorize: userId=%s, clientId='%s', err=%v\n", userId, clientId, err) if err != nil || clientId == "" { http.Error(w, "Spotify credentials not configured", http.StatusBadRequest) return @@ -389,7 +390,11 @@ func getBaseURL(r *http.Request) string { if r.TLS != nil { scheme = "https" } - return scheme + "://" + r.Host + host := r.Host + if host == "localhost:1234" || host == "localhost" { + host = "127.0.0.1:1234" + } + return scheme + "://" + host } func GetSpotifyAuthURL(userId int, baseURL string) (string, error) { diff --git a/static/style.css b/static/style.css index 8413e78..f7997c2 100644 --- a/static/style.css +++ b/static/style.css @@ -434,3 +434,23 @@ color: #8F8; margin-top: 10px; } + +.info { + color: #888; + font-size: 14px; + margin-top: 10px; +} + +a.button { + display: inline-block; + padding: 10px 20px; + background: #1DB954; + color: #fff; + text-decoration: none; + border-radius: 25px; + font-weight: bold; +} + +a.button:hover { + background: #1ed760; +} diff --git a/templates/settings.gohtml b/templates/settings.gohtml index 6811582..40f3551 100644 --- a/templates/settings.gohtml +++ b/templates/settings.gohtml @@ -98,6 +98,11 @@ + {{if and .SpotifyClientId (not .SpotifyConnected)}} +

Connect Spotify

+

Click to authorize Muzi to access your Spotify account.

+ {{end}} + {{if .SpotifyConnected}}

Spotify is connected and importing!

{{end}} diff --git a/web/settings.go b/web/settings.go index f15e387..f3b6925 100644 --- a/web/settings.go +++ b/web/settings.go @@ -134,3 +134,34 @@ func updateSpotifyCredentialsHandler(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "/settings", http.StatusSeeOther) } + +func spotifyConnectHandler(w http.ResponseWriter, r *http.Request) { + username := getLoggedInUsername(r) + if username == "" { + http.Redirect(w, r, "/login", http.StatusSeeOther) + return + } + + userId, err := getUserIdByUsername(r.Context(), username) + if err != nil { + http.Error(w, "User not found", http.StatusInternalServerError) + return + } + + user, err := scrobble.GetUserById(userId) + if err != nil { + fmt.Fprintf(os.Stderr, "spotifyConnectHandler: GetUserById error: %v\n", err) + http.Redirect(w, r, "/settings", http.StatusSeeOther) + return + } + + fmt.Fprintf(os.Stderr, "spotifyConnectHandler: userId=%d, SpotifyClientId=%v\n", userId, user.SpotifyClientId) + + if user.SpotifyClientId == nil || *user.SpotifyClientId == "" { + fmt.Fprintf(os.Stderr, "spotifyConnectHandler: SpotifyClientId is nil or empty, redirecting to settings\n") + http.Redirect(w, r, "/settings", http.StatusSeeOther) + return + } + + http.Redirect(w, r, fmt.Sprintf("/scrobble/spotify/authorize?user_id=%d", userId), http.StatusSeeOther) +} diff --git a/web/web.go b/web/web.go index ed95948..5d65eae 100644 --- a/web/web.go +++ b/web/web.go @@ -91,6 +91,7 @@ func Start() { r.Get("/callback", http.HandlerFunc(scrobble.NewSpotifyHandler().ServeHTTP)) }) + r.Get("/settings/spotify-connect", spotifyConnectHandler) r.Get("/settings", settingsPageHandler()) r.Post("/settings/generate-apikey", generateAPIKeyHandler) r.Post("/settings/update-spotify", updateSpotifyCredentialsHandler)