[WIP] music platform user data scraper
teal-fm atproto

On time (moved to .utc)

Changed files
+26 -26
db
service
apikey
lastfm
musicbrainz
spotify
session
+3 -3
db/apikey/apikey.go
··· 64 64 } 65 65 apiKeyID := base64.URLEncoding.EncodeToString(b) 66 66 67 - now := time.Now() 67 + now := time.Now().UTC() 68 68 expiresAt := now.AddDate(0, 0, validityDays) // Default to validityDays days validity 69 69 70 70 apiKey := &ApiKey{ ··· 100 100 101 101 if exists { 102 102 // Check if API key is expired 103 - if time.Now().After(apiKey.ExpiresAt) { 103 + if time.Now().UTC().After(apiKey.ExpiresAt) { 104 104 am.DeleteApiKey(apiKeyID) 105 105 return nil, false 106 106 } ··· 118 118 return nil, false 119 119 } 120 120 121 - if time.Now().After(apiKey.ExpiresAt) { 121 + if time.Now().UTC().After(apiKey.ExpiresAt) { 122 122 am.DeleteApiKey(apiKeyID) 123 123 return nil, false 124 124 }
+6 -6
db/atproto.go
··· 80 80 did).Scan(&user.ID, &user.ATProtoDID, &user.CreatedAt, &user.UpdatedAt) 81 81 82 82 if err == sql.ErrNoRows { 83 - now := time.Now() 83 + now := time.Now().UTC() 84 84 // create user! 85 85 result, insertErr := db.Exec(` 86 86 INSERT INTO users (atproto_did, created_at, updated_at) ··· 111 111 // create or update the current user's ATproto session data. 112 112 func (db *DB) SaveATprotoSession(tokenResp *oauth.TokenResponse, authserverIss string, dpopPrivateJWK jwk.Key, pdsUrl string) error { 113 113 fmt.Printf("Saving session with PDS url %s", pdsUrl) 114 - expiryTime := time.Now().Add(time.Second * time.Duration(tokenResp.ExpiresIn)) 115 - now := time.Now() 114 + expiryTime := time.Now().UTC().Add(time.Second * time.Duration(tokenResp.ExpiresIn)) 115 + now := time.Now().UTC() 116 116 117 117 dpopPrivateJWKBytes, err := json.Marshal(dpopPrivateJWK) 118 118 if err != nil { ··· 213 213 } 214 214 215 215 // printout the session details 216 - fmt.Printf("Session details from DB: %+v\n", oauthSession) 216 + fmt.Printf("Getting session details for the did: %+v\n", oauthSession.DID) 217 217 218 218 // if token is expired, refresh it 219 - if time.Now().After(oauthSession.TokenExpiry) { 219 + if time.Now().UTC().After(oauthSession.TokenExpiry) { 220 220 221 221 resp, err := oauthClient.RefreshTokenRequest(ctx, oauthSession.RefreshToken, authserverIss, oauthSession.DpopAuthServerNonce, privateJwk) 222 222 if err != nil { ··· 237 237 DpopPdsNonce: oauthSession.DpopPdsNonce, 238 238 DpopAuthServerNonce: resp.DpopAuthserverNonce, 239 239 DpopPrivateJWK: privateJwk, 240 - TokenExpiry: time.Now().Add(time.Duration(resp.ExpiresIn) * time.Second), 240 + TokenExpiry: time.Now().UTC().Add(time.Duration(resp.ExpiresIn) * time.Second), 241 241 } 242 242 243 243 }
+5 -5
db/db.go
··· 120 120 121 121 // create user without spotify id 122 122 func (db *DB) CreateUser(user *models.User) (int64, error) { 123 - now := time.Now() 123 + now := time.Now().UTC() 124 124 125 125 result, err := db.Exec(` 126 126 INSERT INTO users (username, email, created_at, updated_at) ··· 136 136 137 137 // add spotify session to user, returning the updated user 138 138 func (db *DB) AddSpotifySession(userID int64, username, email, spotifyId, accessToken, refreshToken string, tokenExpiry time.Time) (*models.User, error) { 139 - now := time.Now() 139 + now := time.Now().UTC() 140 140 141 141 _, err := db.Exec(` 142 142 UPDATE users SET username = ?, email = ?, spotify_id = ?, access_token = ?, refresh_token = ?, token_expiry = ?, created_at = ?, updated_at = ? ··· 200 200 } 201 201 202 202 func (db *DB) UpdateUserToken(userID int64, accessToken, refreshToken string, expiry time.Time) error { 203 - now := time.Now() 203 + now := time.Now().UTC() 204 204 205 205 _, err := db.Exec(` 206 206 UPDATE users ··· 326 326 SELECT id, username, email, spotify_id, access_token, refresh_token, token_expiry, created_at, updated_at 327 327 FROM users 328 328 WHERE refresh_token IS NOT NULL AND token_expiry < ? 329 - ORDER BY id`, time.Now()) 329 + ORDER BY id`, time.Now().UTC()) 330 330 331 331 if err != nil { 332 332 return nil, err ··· 355 355 SELECT id, username, email, spotify_id, access_token, refresh_token, token_expiry, created_at, updated_at 356 356 FROM users 357 357 WHERE access_token IS NOT NULL AND token_expiry > ? 358 - ORDER BY id`, time.Now()) 358 + ORDER BY id`, time.Now().UTC()) 359 359 360 360 if err != nil { 361 361 return nil, err
+2 -2
service/apikey/apikey.go
··· 79 79 } 80 80 keyName := reqBody.Name 81 81 if keyName == "" { 82 - keyName = fmt.Sprintf("API Key (via API) - %s", time.Now().Format(time.RFC3339)) 82 + keyName = fmt.Sprintf("API Key (via API) - %s", time.Now().UTC().Format(time.RFC3339)) 83 83 } 84 84 validityDays := 30 // Default, could be made configurable via request body 85 85 ··· 133 133 134 134 keyName := r.FormValue("name") 135 135 if keyName == "" { 136 - keyName = fmt.Sprintf("API Key - %s", time.Now().Format(time.RFC3339)) 136 + keyName = fmt.Sprintf("API Key - %s", time.Now().UTC().Format(time.RFC3339)) 137 137 } 138 138 validityDays := 1024 139 139
+1 -1
service/lastfm/lastfm.go
··· 407 407 } 408 408 409 409 // printout the session details 410 - fmt.Printf("Session details: %+v\n", sess) 410 + fmt.Printf("Submitting track for the did: %+v\n", sess.DID) 411 411 412 412 // horrible no good very bad for now 413 413 artistArr := []string{}
+2 -2
service/musicbrainz/musicbrainz.go
··· 119 119 params.Artist, _ = s.cleaner.CleanArtist(params.Artist) 120 120 121 121 cacheKey := generateCacheKey(params) 122 - now := time.Now() 122 + now := time.Now().UTC() 123 123 124 124 // --- Check Cache (Read Lock) --- 125 125 s.cacheMutex.RLock() ··· 188 188 s.cacheMutex.Lock() 189 189 s.searchCache[cacheKey] = cacheEntry{ 190 190 recordings: result.Recordings, 191 - expiresAt: time.Now().Add(s.cacheTTL), 191 + expiresAt: time.Now().UTC().Add(s.cacheTTL), 192 192 } 193 193 s.cacheMutex.Unlock() 194 194 log.Printf("Cached MusicBrainz search result for key=%s, TTL=%s", cacheKey, s.cacheTTL)
+4 -4
service/spotify/spotify.go
··· 142 142 return 0, err 143 143 } 144 144 145 - tokenExpiryTime := time.Now().Add(1 * time.Hour) // Spotify tokens last ~1 hour 145 + tokenExpiryTime := time.Now().UTC().Add(1 * time.Hour) // Spotify tokens last ~1 hour 146 146 147 147 // We don't intend users to log in via spotify! 148 148 if user == nil { ··· 195 195 count := 0 196 196 for _, user := range users { 197 197 // load users with valid tokens 198 - if user.AccessToken != nil && user.TokenExpiry.After(time.Now()) { 198 + if user.AccessToken != nil && user.TokenExpiry.After(time.Now().UTC()) { 199 199 s.userTokens[user.ID] = *user.AccessToken 200 200 count++ 201 201 } ··· 262 262 delete(s.userTokens, userID) 263 263 s.mu.Unlock() 264 264 // Also clear the bad refresh token from the DB 265 - updateErr := s.DB.UpdateUserToken(userID, "", "", time.Now()) // Clear tokens 265 + updateErr := s.DB.UpdateUserToken(userID, "", "", time.Now().UTC()) // Clear tokens 266 266 if updateErr != nil { 267 267 log.Printf("Failed to clear bad refresh token for user %d: %v", userID, updateErr) 268 268 } ··· 281 281 return "", fmt.Errorf("failed to decode refresh response: %w", err) 282 282 } 283 283 284 - newExpiry := time.Now().Add(time.Duration(tokenResponse.ExpiresIn) * time.Second) 284 + newExpiry := time.Now().UTC().Add(time.Duration(tokenResponse.ExpiresIn) * time.Second) 285 285 newRefreshToken := *user.RefreshToken // Default to old one 286 286 if tokenResponse.RefreshToken != "" { 287 287 newRefreshToken = tokenResponse.RefreshToken // Use new one if provided
+3 -3
session/session.go
··· 67 67 rand.Read(b) 68 68 sessionID := base64.URLEncoding.EncodeToString(b) 69 69 70 - now := time.Now() 70 + now := time.Now().UTC() 71 71 expiresAt := now.Add(24 * time.Hour) // 24-hour session 72 72 73 73 session := &Session{ ··· 104 104 105 105 if exists { 106 106 // Check if session is expired 107 - if time.Now().After(session.ExpiresAt) { 107 + if time.Now().UTC().After(session.ExpiresAt) { 108 108 sm.DeleteSession(sessionID) 109 109 return nil, false 110 110 } ··· 124 124 return nil, false 125 125 } 126 126 127 - if time.Now().After(session.ExpiresAt) { 127 + if time.Now().UTC().After(session.ExpiresAt) { 128 128 sm.DeleteSession(sessionID) 129 129 return nil, false 130 130 }