From c2b537e39f53269a08563c0e2ed0e59724d1c5ec Mon Sep 17 00:00:00 2001 From: aj Date: Mon, 22 Jun 2020 20:21:54 +0100 Subject: [PATCH] updated spotframework network actions to be tried and caught --- music/api/api.py | 13 ++-- music/api/player.py | 10 ++-- music/api/spotfm.py | 25 ++++---- music/api/spotify.py | 2 +- music/db/database.py | 16 +++-- music/tasks/create_playlist.py | 11 ++-- music/tasks/refresh_lastfm_stats.py | 19 +++++- music/tasks/run_user_playlist.py | 92 ++++++++++++++++++----------- 8 files changed, 115 insertions(+), 73 deletions(-) diff --git a/music/api/api.py b/music/api/api.py index 3c33856..d1e600f 100644 --- a/music/api/api.py +++ b/music/api/api.py @@ -16,6 +16,8 @@ from music.model.playlist import Playlist import music.db.database as database +from spotframework.net.network import SpotifyNetworkException + blueprint = Blueprint('api', __name__) db = firestore.Client() logger = logging.getLogger(__name__) @@ -352,7 +354,6 @@ def run_users_cron(): @blueprint.route('/playlist/image', methods=['GET']) @login_or_basic_auth def image(user=None): - name = request.args.get('name', None) if name is None: @@ -364,9 +365,7 @@ def image(user=None): net = database.get_authed_spotify_network(user) - spotify_playlist = net.get_playlist(uri_string=_playlist.uri) - - if spotify_playlist is None: - return jsonify({'error': "no spotify playlist returned"}), 404 - - return jsonify({'images': spotify_playlist.images, 'status': 'success'}), 200 + try: + return jsonify({'images': net.get_playlist(uri_string=_playlist.uri).images, 'status': 'success'}), 200 + except SpotifyNetworkException as e: + return jsonify({'error': f"spotify error occured: {e.http_code}"}), 404 diff --git a/music/api/player.py b/music/api/player.py index 744c6db..25e55d5 100644 --- a/music/api/player.py +++ b/music/api/player.py @@ -5,7 +5,8 @@ import logging from music.api.decorators import login_or_basic_auth, spotify_link_required import music.db.database as database -from spotframework.model.track import TrackFull, Context +from spotframework.net.network import SpotifyNetworkException +from spotframework.model.track import Context from spotframework.model.uri import Uri from spotframework.player.player import Player @@ -39,8 +40,8 @@ def play(user=None): return jsonify({'error': "malformed uri provided"}), 400 elif 'playlist_name' in request_json: net = database.get_authed_spotify_network(user) - playlists = net.get_playlists() - if playlists is not None: + try: + playlists = net.get_playlists() playlist_to_play = next((i for i in playlists if i.name == request_json['playlist_name']), None) if playlist_to_play is not None: @@ -51,8 +52,9 @@ def play(user=None): return jsonify({'message': 'played', 'status': 'success'}), 200 else: return jsonify({'error': f"playlist {request_json['playlist_name']} not found"}), 404 - else: + except SpotifyNetworkException: return jsonify({'error': "playlists not returned"}), 400 + elif 'tracks' in request_json: try: uris = [Uri(i) for i in request_json['tracks']] diff --git a/music/api/spotfm.py b/music/api/spotfm.py index ca9d06c..3a8e34c 100644 --- a/music/api/spotfm.py +++ b/music/api/spotfm.py @@ -12,6 +12,7 @@ from music.tasks.refresh_lastfm_stats import refresh_lastfm_track_stats, \ from spotfm.maths.counter import Counter from spotframework.model.uri import Uri +from spotframework.net.network import SpotifyNetworkException blueprint = Blueprint('spotfm-api', __name__) logger = logging.getLogger(__name__) @@ -48,18 +49,20 @@ def count(user=None): 'last.fm_username': fmnet.username }), 200 elif playlist_name: + try: + playlists = spotnet.get_playlists() + playlist = next((i for i in playlists if i.name == playlist_name), None) - playlists = spotnet.get_playlists() - playlist = next((i for i in playlists if i.name == playlist_name), None) - - if playlist is not None: - playlist_count = counter.count_playlist(playlist=playlist) - return jsonify({ - "count": playlist_count, - 'playlist_name': playlist_name, - 'last.fm_username': fmnet.username - }), 200 - else: + if playlist is not None: + playlist_count = counter.count_playlist(playlist=playlist) + return jsonify({ + "count": playlist_count, + 'playlist_name': playlist_name, + 'last.fm_username': fmnet.username + }), 200 + else: + return jsonify({'error': f'playlist {playlist_name} not found'}), 404 + except SpotifyNetworkException: return jsonify({'error': f'playlist {playlist_name} not found'}), 404 diff --git a/music/api/spotify.py b/music/api/spotify.py index faba954..11083da 100644 --- a/music/api/spotify.py +++ b/music/api/spotify.py @@ -14,7 +14,7 @@ logger = logging.getLogger(__name__) @blueprint.route('/sort', methods=['POST']) @login_or_basic_auth @spotify_link_required -def play(user=None): +def sort(user=None): request_json = request.get_json() net = database.get_authed_spotify_network(user) diff --git a/music/db/database.py b/music/db/database.py index e43b050..58eb7c7 100644 --- a/music/db/database.py +++ b/music/db/database.py @@ -2,7 +2,7 @@ from google.cloud import firestore import logging from datetime import timedelta, datetime, timezone -from spotframework.net.network import Network as SpotifyNetwork +from spotframework.net.network import Network as SpotifyNetwork, SpotifyNetworkException from fmframework.net.network import Network as FmNetwork from music.db.user import DatabaseUser from music.model.user import User @@ -42,15 +42,21 @@ def get_authed_spotify_network(user): access_token=user.access_token) user_obj.on_refresh.append(refresh_token_database_callback) + net = SpotifyNetwork(user_obj) + if user.last_refreshed is not None and user.token_expiry is not None: if user.last_refreshed + timedelta(seconds=user.token_expiry - 1) \ < datetime.now(timezone.utc): - user_obj.refresh_access_token() + net.refresh_access_token() else: - user_obj.refresh_access_token() + net.refresh_access_token() - user_obj.refresh_info() - return SpotifyNetwork(user_obj) + try: + net.refresh_user_info() + except SpotifyNetworkException as e: + logger.error(f'error refreshing user info for {user.username} = {e}') + + return net else: logger.error('user spotify not linked') else: diff --git a/music/tasks/create_playlist.py b/music/tasks/create_playlist.py index bee11b2..001d5bc 100644 --- a/music/tasks/create_playlist.py +++ b/music/tasks/create_playlist.py @@ -3,6 +3,7 @@ from google.cloud import firestore import logging import music.db.database as database +from spotframework.net.network import SpotifyNetworkException db = firestore.Client() @@ -18,10 +19,8 @@ def create_playlist(user, name): logger.info(f'creating spotify playlist for {user.username} / {name}') net = database.get_authed_spotify_network(user) - playlist = net.create_playlist(net.user.username, name) - - if playlist is not None: - return playlist - else: - logger.error(f'no response received {user.username} / {name}') + try: + return net.create_playlist(net.user.user.display_name, name) + except SpotifyNetworkException as e: + logger.error(f'error ocurred {user.username} / {name} - {e}') return diff --git a/music/tasks/refresh_lastfm_stats.py b/music/tasks/refresh_lastfm_stats.py index c3f5bfd..53304ad 100644 --- a/music/tasks/refresh_lastfm_stats.py +++ b/music/tasks/refresh_lastfm_stats.py @@ -9,6 +9,7 @@ from music.model.playlist import Playlist from spotfm.maths.counter import Counter from spotframework.model.uri import Uri +from spotframework.net.network import SpotifyNetworkException db = firestore.Client() @@ -37,7 +38,11 @@ def refresh_lastfm_track_stats(username, playlist_name): logger.critical(f'playlist {playlist_name} for {username} has no spotify uri') return - spotify_playlist = spotnet.get_playlist(uri=Uri(playlist.uri)) + try: + spotify_playlist = spotnet.get_playlist(uri=Uri(playlist.uri)) + except SpotifyNetworkException as e: + logger.error(f'error retrieving spotify playlist {username} / {playlist_name} - {e}') + return track_count = counter.count_playlist(playlist=spotify_playlist) user_count = fmnet.get_user_scrobble_count() @@ -75,7 +80,11 @@ def refresh_lastfm_album_stats(username, playlist_name): logger.critical(f'playlist {playlist_name} for {username} has no spotify uri') return - spotify_playlist = spotnet.get_playlist(uri=Uri(playlist.uri)) + try: + spotify_playlist = spotnet.get_playlist(uri=Uri(playlist.uri)) + except SpotifyNetworkException as e: + logger.error(f'error retrieving spotify playlist {username} / {playlist_name} - {e}') + return album_count = counter.count_playlist(playlist=spotify_playlist, query_album=True) user_count = fmnet.get_user_scrobble_count() @@ -113,7 +122,11 @@ def refresh_lastfm_artist_stats(username, playlist_name): logger.critical(f'playlist {playlist_name} for {username} has no spotify uri') return - spotify_playlist = spotnet.get_playlist(uri=Uri(playlist.uri)) + try: + spotify_playlist = spotnet.get_playlist(uri=Uri(playlist.uri)) + except SpotifyNetworkException as e: + logger.error(f'error retrieving spotify playlist {username} / {playlist_name} - {e}') + return artist_count = counter.count_playlist(playlist=spotify_playlist, query_artist=True) user_count = fmnet.get_user_scrobble_count() diff --git a/music/tasks/run_user_playlist.py b/music/tasks/run_user_playlist.py index 567b9e7..7f6ec6e 100644 --- a/music/tasks/run_user_playlist.py +++ b/music/tasks/run_user_playlist.py @@ -8,6 +8,7 @@ from spotframework.filter import remove_local, get_track_objects from spotframework.filter.added import added_after from spotframework.filter.sort import sort_by_release_date from spotframework.filter.deduplicate import deduplicate_by_name +from spotframework.net.network import SpotifyNetworkException from fmframework.net.network import Network from spotfm.charts.chart import get_chart_of_spotify_tracks @@ -49,7 +50,11 @@ def run_user_playlist(username, playlist_name): logger.error(f'no spotify network returned for {username} / {playlist_name}') return - user_playlists = net.get_user_playlists() + try: + user_playlists = net.get_user_playlists() + except SpotifyNetworkException as e: + logger.error(f'error occured while retrieving playlists {username} / {playlist_name} - {e}') + return part_generator = PartGenerator(user=user) part_names = part_generator.get_recursive_parts(playlist.name) @@ -66,11 +71,14 @@ def run_user_playlist(username, playlist_name): try: # attempt to cast to uri uri = Uri(part_name) - _tracks = net.get_playlist_tracks(uri=uri) - if _tracks and len(_tracks) > 0: - playlist_tracks += _tracks - else: - logger.warning(f'no tracks returned for {uri} {username} / {playlist_name}') + try: + _tracks = net.get_playlist_tracks(uri=uri) + if _tracks and len(_tracks) > 0: + playlist_tracks += _tracks + else: + logger.warning(f'no tracks returned for {uri} {username} / {playlist_name}') + except SpotifyNetworkException as e: + logger.error(f'error occured while retrieving {uri} {username} / {playlist_name} - {e}') except ValueError: # is a playlist name part_playlist = next((i for i in user_playlists if i.name == part_name), None) @@ -78,21 +86,27 @@ def run_user_playlist(username, playlist_name): logger.warning(f'playlist {part_name} not found {username} / {playlist_name}') continue - part_playlist_tracks = net.get_playlist_tracks(uri=part_playlist.uri) - if part_playlist_tracks and len(part_playlist_tracks) > 0: - playlist_tracks += part_playlist_tracks - else: - logger.warning(f'no tracks returned for {part_playlist.name} {username} / {playlist_name}') + try: + part_playlist_tracks = net.get_playlist_tracks(uri=part_playlist.uri) + if part_playlist_tracks and len(part_playlist_tracks) > 0: + playlist_tracks += part_playlist_tracks + else: + logger.warning(f'no tracks returned for {part_playlist.name} {username} / {playlist_name}') + except SpotifyNetworkException as e: + logger.error(f'error occured while retrieving {part_name} {username} / {playlist_name} - {e}') playlist_tracks = remove_local(playlist_tracks) # LIBRARY if playlist.include_library_tracks: - library_tracks = net.get_library_tracks() - if library_tracks and len(library_tracks) > 0: - playlist_tracks += library_tracks - else: - logger.error(f'error getting library tracks {username} / {playlist_name}') + try: + library_tracks = net.get_library_tracks() + if library_tracks and len(library_tracks) > 0: + playlist_tracks += library_tracks + else: + logger.error(f'error getting library tracks {username} / {playlist_name}') + except SpotifyNetworkException as e: + logger.error(f'error occured while retrieving library tracks {username} / {playlist_name} - {e}') # PLAYLIST TYPE SPECIFIC if playlist.type == 'recents': @@ -132,26 +146,30 @@ def run_user_playlist(username, playlist_name): # RECOMMENDATIONS if playlist.include_recommendations: - recommendations = net.get_recommendations(tracks=[i.uri.object_id for i, j - in zip(*get_track_objects( - random.sample(playlist_tracks, - k=min(5, len(playlist_tracks)) - ) - )) - if i.uri.object_type == Uri.ObjectType.track], - response_limit=playlist.recommendation_sample) - if recommendations and len(recommendations.tracks) > 0: - playlist_tracks += recommendations.tracks - else: - logger.error(f'error getting recommendations {username} / {playlist_name}') + try: + recommendations = net.get_recommendations(tracks=[i.uri.object_id for i, j + in zip(*get_track_objects( + random.sample(playlist_tracks, + k=min(5, len(playlist_tracks)) + ) + )) + if i.uri.object_type == Uri.ObjectType.track], + response_limit=playlist.recommendation_sample) + if recommendations and len(recommendations.tracks) > 0: + playlist_tracks += recommendations.tracks + else: + logger.error(f'error getting recommendations {username} / {playlist_name}') + except SpotifyNetworkException as e: + logger.error(f'error occured while generating recommendations {username} / {playlist_name} - {e}') # DEDUPLICATE playlist_tracks = deduplicate_by_name(playlist_tracks) # EXECUTE - resp = net.replace_playlist_tracks(uri_string=playlist.uri, uris=[i.uri for i, j - in zip(*get_track_objects(playlist_tracks))]) - if resp: + try: + net.replace_playlist_tracks(uri_string=playlist.uri, uris=[i.uri for i, j + in zip(*get_track_objects(playlist_tracks))]) + if playlist.description_overwrite: string = playlist.description_overwrite else: @@ -164,11 +182,13 @@ def run_user_playlist(username, playlist_name): logger.error(f'no string generated {username} / {playlist_name}') return None - resp = net.change_playlist_details(Uri(playlist.uri), description=string) - if resp is None: - logger.error(f'error changing description {username} / {playlist_name}') - else: - logger.error(f'error executing {username} / {playlist_name}') + try: + net.change_playlist_details(Uri(playlist.uri), description=string) + except SpotifyNetworkException as e: + logger.error(f'error changing description for {username} / {playlist_name} - {e}') + + except SpotifyNetworkException as e: + logger.error(f'error executing {username} / {playlist_name} - {e}') playlist.last_updated = datetime.datetime.utcnow() playlist.update()