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

Spotify improvements

authored by baileytownsend.dev and committed by Kyle Loveless 9117c91a cc18db49

Changed files
+61 -26
db
service
spotify
+2 -1
db/atproto.go
··· 246 246 } 247 247 248 248 func AtpSessionToAuthArgs(sess *models.ATprotoAuthSession) *oauth.XrpcAuthedRequestArgs { 249 - fmt.Printf("DID: %s\nPDS URL: %s\nISS: %s\nAccess Token: %s\nNonce: %s\nPrivate JWK: %s\n", sess.DID, sess.PDSUrl, sess.AuthServerIssuer, sess.AccessToken, sess.DpopPdsNonce, sess.DpopPrivateJWK) 249 + //Commenting out so jwts and tokens are not in logs 250 + //fmt.Printf("DID: %s\nPDS URL: %s\nISS: %s\nAccess Token: %s\nNonce: %s\nPrivate JWK: %s\n", sess.DID, sess.PDSUrl, sess.AuthServerIssuer, sess.AccessToken, sess.DpopPdsNonce, sess.DpopPrivateJWK) 250 251 return &oauth.XrpcAuthedRequestArgs{ 251 252 Did: sess.DID, 252 253 PdsUrl: sess.PDSUrl,
+33 -25
db/db.go
··· 321 321 return tracks, nil 322 322 } 323 323 324 - func (db *DB) GetUsersWithExpiredTokens() ([]*models.User, error) { 325 - rows, err := db.Query(` 326 - SELECT id, username, email, spotify_id, access_token, refresh_token, token_expiry, created_at, updated_at 327 - FROM users 328 - WHERE refresh_token IS NOT NULL AND token_expiry < ? 329 - ORDER BY id`, time.Now().UTC()) 330 - 331 - if err != nil { 332 - return nil, err 333 - } 334 - defer rows.Close() 324 + // SpotifyQueryMapping maps Spotify sql query results to user structs 325 + func SpotifyQueryMapping(rows *sql.Rows) ([]*models.User, error) { 335 326 336 327 var users []*models.User 337 328 ··· 350 341 return users, nil 351 342 } 352 343 353 - func (db *DB) GetAllActiveUsers() ([]*models.User, error) { 344 + func (db *DB) GetUsersWithExpiredTokens() ([]*models.User, error) { 354 345 rows, err := db.Query(` 355 346 SELECT id, username, email, spotify_id, access_token, refresh_token, token_expiry, created_at, updated_at 356 347 FROM users 357 - WHERE access_token IS NOT NULL AND token_expiry > ? 348 + WHERE refresh_token IS NOT NULL AND token_expiry < ? 358 349 ORDER BY id`, time.Now().UTC()) 359 350 360 351 if err != nil { ··· 362 353 } 363 354 defer rows.Close() 364 355 365 - var users []*models.User 356 + return SpotifyQueryMapping(rows) 366 357 367 - for rows.Next() { 368 - user := &models.User{} 369 - err := rows.Scan( 370 - &user.ID, &user.Username, &user.Email, &user.SpotifyID, 371 - &user.AccessToken, &user.RefreshToken, &user.TokenExpiry, 372 - &user.CreatedAt, &user.UpdatedAt) 373 - if err != nil { 374 - return nil, err 375 - } 376 - users = append(users, user) 358 + } 359 + 360 + func (db *DB) GetAllActiveUsers() ([]*models.User, error) { 361 + rows, err := db.Query(` 362 + SELECT id, username, email, spotify_id, access_token, refresh_token, token_expiry, created_at, updated_at 363 + FROM users 364 + WHERE access_token IS NOT NULL 365 + ORDER BY id`) 366 + 367 + if err != nil { 368 + return nil, err 377 369 } 370 + defer rows.Close() 371 + 372 + return SpotifyQueryMapping(rows) 373 + } 378 374 379 - return users, nil 375 + func (db *DB) GetAllActiveUsersWithUnExpiredTokens() ([]*models.User, error) { 376 + rows, err := db.Query(` 377 + SELECT id, username, email, spotify_id, access_token, refresh_token, token_expiry, created_at, updated_at 378 + FROM users 379 + WHERE access_token IS NOT NULL AND token_expiry > ? 380 + ORDER BY id`, time.Now().UTC()) 381 + 382 + if err != nil { 383 + return nil, err 384 + } 385 + defer rows.Close() 386 + 387 + return SpotifyQueryMapping(rows) 380 388 } 381 389 382 390 // debug to view current user's information
+26
service/spotify/spotify.go
··· 198 198 if user.AccessToken != nil && user.TokenExpiry.After(time.Now().UTC()) { 199 199 s.userTokens[user.ID] = *user.AccessToken 200 200 count++ 201 + } else { 202 + token, err := s.refreshTokenInner(user.ID) 203 + if err != nil { 204 + //Probably should remove the access token and refresh in long run? 205 + log.Printf("Error refreshing token for user %d: %v", user.ID, err) 206 + continue 207 + } 208 + s.userTokens[user.ID] = token 201 209 } 202 210 } 203 211 204 212 log.Printf("Loaded %d active users with valid tokens", count) 213 + return nil 214 + } 215 + 216 + func (s *SpotifyService) UnloadAllUsers() error { 217 + s.mu.Lock() 218 + defer s.mu.Unlock() 219 + s.userTokens = make(map[int64]string) 205 220 return nil 206 221 } 207 222 ··· 537 552 defer ticker.Stop() 538 553 539 554 for range ticker.C { 555 + err := s.LoadAllUsers() 556 + if err != nil { 557 + log.Printf("Error loading spotify users: %v", err) 558 + continue 559 + } 540 560 // copy userIDs to avoid holding the lock too long 541 561 s.mu.RLock() 542 562 userIDs := make([]int64, 0, len(s.userTokens)) ··· 663 683 664 684 log.Printf("User %d is listening to: %s by %s", userID, track.Name, track.Artist) 665 685 } 686 + } 687 + 688 + //unloading users to save memory and make sure we get new signups 689 + err = s.LoadAllUsers() 690 + if err != nil { 691 + log.Printf("Error loading spotify users: %v", err) 666 692 } 667 693 } 668 694 }