55from flask import Response , make_response , redirect
66from src .dataclasses .album import Album
77from src .dataclasses .playback_info import PlaybackInfo , PlaylistProgression
8+ from src .dataclasses .playback_request import StartPlaybackRequest
89from src .dataclasses .playback_state import PlaybackState
910from src .dataclasses .playlist import Playlist
1011from src .dataclasses .playlist_info import CurrentUserPlaylists , SimplifiedPlaylist
1516from src .dataclasses .user import User
1617from src .exceptions .Unauthorized import UnauthorizedException
1718from src .flask_config import Config
18- from src .utils .response_creator import ResponseCreator
19+ from src .utils .response_creator import add_cookies_to_response
1920
2021scope = [
2122 "user-library-read" ,
2829 "playlist-read-collaborative" ,
2930 "playlist-modify-private" ,
3031 "playlist-modify-public" ,
32+ "user-modify-playback-state" ,
3133]
3234
3335
@@ -93,12 +95,9 @@ def refresh_access_token(self, refresh_token):
9395 token_response = TokenResponse .model_validate (api_response )
9496 access_token = token_response .access_token
9597 user_info = self .get_current_user (access_token )
96- resp = (
97- ResponseCreator ()
98- .with_cookies (
99- {"spotify_access_token" : access_token , "user_id" : user_info .id }
100- )
101- .create ()
98+ resp = add_cookies_to_response (
99+ make_response (),
100+ {"spotify_access_token" : access_token , "user_id" : user_info .id },
102101 )
103102 return resp
104103
@@ -119,16 +118,13 @@ def request_access_token(self, code):
119118 token_response = TokenResponse .model_validate (api_response )
120119 access_token = token_response .access_token
121120 user_info = self .get_current_user (access_token )
122- resp = (
123- ResponseCreator (redirect (f"{ Config ().FRONTEND_URL } /" ))
124- .with_cookies (
125- {
126- "spotify_access_token" : access_token ,
127- "spotify_refresh_token" : token_response .refresh_token ,
128- "user_id" : user_info .id ,
129- }
130- )
131- .create ()
121+ resp = add_cookies_to_response (
122+ make_response (redirect (f"{ Config ().FRONTEND_URL } /" )),
123+ {
124+ "spotify_access_token" : access_token ,
125+ "spotify_refresh_token" : token_response .refresh_token ,
126+ "user_id" : user_info .id ,
127+ },
132128 )
133129 return resp
134130
@@ -293,7 +289,7 @@ def get_album(self, access_token, id):
293289 album = Album .model_validate (api_album )
294290 return album
295291
296- def get_current_playback (self , access_token ):
292+ def get_current_playback (self , access_token ) -> PlaybackState | None :
297293 response = requests .get (
298294 f"https://api.spotify.com/v1/me/player" ,
299295 auth = BearerAuth (access_token ),
@@ -345,6 +341,7 @@ def get_my_current_playback(self, access_token) -> PlaybackInfo | None:
345341 "track_duration" : api_playback .item .duration_ms ,
346342 "album_progress" : album_progress ,
347343 "album_duration" : album_duration ,
344+ "is_playing" : api_playback .is_playing ,
348345 }
349346 )
350347
@@ -366,11 +363,13 @@ def get_playlist_progression(self, access_token, api_playback: PlaybackInfo):
366363 }
367364 )
368365
369- def search_albums (self , access_token , search = None , offset = 0 ) -> List [Album ]:
366+ def search_albums (
367+ self , access_token , search = None , offset = 0 , limit = 50
368+ ) -> List [Album ]:
370369 if search :
371370 response = requests .get (
372371 f"https://api.spotify.com/v1/albums/{ id } " ,
373- data = {"q" : search , "type" : "album" , "limit" : 50 , "offset" : offset },
372+ data = {"q" : search , "type" : "album" , "limit" : limit , "offset" : offset },
374373 headers = {
375374 "content-type" : "application/json" ,
376375 },
@@ -456,6 +455,45 @@ def is_album_in_playlist(self, access_token, playlist_id, album: Album) -> bool:
456455 album_track_ids = [track .id for track in album .tracks .items ]
457456 return all (e in playlist_track_ids for e in album_track_ids )
458457
458+ def pause_playback (self , access_token ) -> Response :
459+ response = requests .put (
460+ url = "https://api.spotify.com/v1/me/player/pause" ,
461+ headers = {
462+ "content-type" : "application/json" ,
463+ },
464+ auth = BearerAuth (access_token ),
465+ )
466+ return self .response_handler (
467+ make_response ("" , response .status_code ), jsonify = False
468+ )
469+
470+ def start_playback (
471+ self , access_token , start_playback_request_body : StartPlaybackRequest = None
472+ ) -> Response :
473+ if not start_playback_request_body :
474+ data = None
475+ else :
476+ data = start_playback_request_body .model_dump_json (exclude_none = True )
477+
478+ response = requests .put (
479+ url = "https://api.spotify.com/v1/me/player/play" ,
480+ data = data ,
481+ headers = {
482+ "content-type" : "application/json" ,
483+ },
484+ auth = BearerAuth (access_token ),
485+ )
486+ return self .response_handler (
487+ make_response ("" , response .status_code ), jsonify = False
488+ )
489+
490+ def pause_or_start_playback (self , access_token ) -> Response :
491+ is_playing = self .get_current_playback (access_token ).is_playing
492+ if is_playing :
493+ return self .pause_playback (access_token )
494+ else :
495+ return self .start_playback (access_token )
496+
459497
460498def get_playlist_duration (playlist_info : List [PlaylistTrackObject ]) -> int :
461499 return sum (track .track .duration_ms for track in playlist_info )
0 commit comments