diff --git a/app/functions.py b/app/functions.py index 7eed5ac..3144ac0 100644 --- a/app/functions.py +++ b/app/functions.py @@ -1,4 +1,7 @@ +import json +from typing import Optional from flask import flash, redirect, session, url_for +import requests from app.models import JellyfinUser, Playlist,Track from app import sp, cache, app, jellyfin ,jellyfin_admin_token, jellyfin_admin_id,device_id, cache from functools import wraps @@ -57,51 +60,57 @@ def prepPlaylistData(data): for playlist_data in data['playlists']['items']: # Fetch the playlist from the database if it exists - db_playlist = Playlist.query.filter_by(spotify_playlist_id=playlist_data['id']).first() + if playlist_data: + db_playlist = Playlist.query.filter_by(provider_playlist_id=playlist_data['id']).first() - if db_playlist: - # If the playlist is in the database, use the stored values - if isinstance(playlist_data['tracks'],list): - track_count = len(playlist_data['tracks'] ) + if db_playlist: + # If the playlist is in the database, use the stored values + if playlist_data.get('tracks'): + if isinstance(playlist_data['tracks'],list): + track_count = len(playlist_data['tracks'] ) + else: + track_count = playlist_data['tracks']['total'] or 0 + else: + track_count = 0 + tracks_available = db_playlist.tracks_available or 0 + tracks_linked = len([track for track in db_playlist.tracks if track.jellyfin_id]) or 0 + percent_available = (tracks_available / track_count * 100) if track_count > 0 else 0 + + # Determine playlist status + if not playlist_data.get('status'): + if tracks_available == track_count and track_count > 0: + playlist_data['status'] = 'green' # Fully available + elif tracks_available > 0: + playlist_data['status'] = 'yellow' # Partially available + else: + playlist_data['status'] = 'red' # Not available + else: - track_count = playlist_data['tracks']['total'] or 0 - tracks_available = db_playlist.tracks_available or 0 - tracks_linked = len([track for track in db_playlist.tracks if track.jellyfin_id]) or 0 - percent_available = (tracks_available / track_count * 100) if track_count > 0 else 0 - - # Determine playlist status - if tracks_available == track_count and track_count > 0: - status = 'green' # Fully available - elif tracks_available > 0: - status = 'yellow' # Partially available - else: - status = 'red' # Not available - else: - # If the playlist is not in the database, initialize with 0 - track_count = 0 - tracks_available = 0 - tracks_linked = 0 - percent_available = 0 - status = 'red' # Not requested yet + # If the playlist is not in the database, initialize with 0 + track_count = 0 + tracks_available = 0 + tracks_linked = 0 + percent_available = 0 + playlist_data['status'] = 'red' # Not requested yet - # Append playlist data to the list - playlists.append({ - 'name': playlist_data['name'], - 'description': playlist_data['description'], - 'image': playlist_data['images'][0]['url'] if playlist_data['images'] else 'default-image.jpg', - 'url': playlist_data['external_urls']['spotify'], - 'id': playlist_data['id'], - 'jellyfin_id': db_playlist.jellyfin_id if db_playlist else '', - 'can_add': (db_playlist not in jellyfin_user.playlists) if db_playlist else True, - 'can_remove' : (db_playlist in jellyfin_user.playlists) if db_playlist else False, - 'last_updated':db_playlist.last_updated if db_playlist else '', - 'last_changed':db_playlist.last_changed if db_playlist else '', - 'tracks_available': tracks_available, - 'track_count': track_count, - 'tracks_linked': tracks_linked, - 'percent_available': percent_available, - 'status': status # Red, yellow, or green based on availability - }) + # Append playlist data to the list + playlists.append({ + 'name': playlist_data['name'], + 'description': playlist_data['description'], + 'image': playlist_data['images'][0]['url'] if playlist_data.get('images') else '/static/images/placeholder.png', + 'url': playlist_data['external_urls']['spotify'] if playlist_data.get('external_urls') else '', + 'id': playlist_data['id'] if playlist_data['id'] else '', + 'jellyfin_id': db_playlist.jellyfin_id if db_playlist else '', + 'can_add': (db_playlist not in jellyfin_user.playlists) if db_playlist else True, + 'can_remove' : (db_playlist in jellyfin_user.playlists) if db_playlist else False, + 'last_updated':db_playlist.last_updated if db_playlist else '', + 'last_changed':db_playlist.last_changed if db_playlist else '', + 'tracks_available': tracks_available, + 'track_count': track_count, + 'tracks_linked': tracks_linked, + 'percent_available': percent_available, + 'status': playlist_data['status'] # Red, yellow, or green based on availability + }) return playlists @@ -115,24 +124,57 @@ def get_cached_spotify_playlists(playlist_ids): spotify_data = {'playlists': {'items': []}} for playlist_id in playlist_ids: - playlist_data = get_cached_spotify_playlist(playlist_id) + playlist_data = None + not_found = False + try: + playlist_data = get_cached_spotify_playlist(playlist_id) + + except SpotifyException as e: + app.logger.error(f"Error Fetching Playlist {playlist_id}: {e}") + not_found = 'http status: 404' in str(e) + if not_found: + playlist_data = { + 'status':'red', + 'description': 'Playlist has most likely been removed. You can keep it, but won´t receive Updates.', + 'id': playlist_id, + 'name' : '' + + } + if playlist_data: spotify_data['playlists']['items'].append(playlist_data) - else: - app.logger.warning(f"Playlist data for ID {playlist_id} could not be retrieved.") return spotify_data -@cache.memoize(timeout=3600) -def get_cached_spotify_playlist(playlist_id): +@cache.memoize(timeout=3600) +def get_cached_playlist(playlist_id): """ Fetches a Spotify playlist by its ID, utilizing caching to minimize API calls. :param playlist_id: The Spotify playlist ID. :return: Playlist data as a dictionary, or None if an error occurs. """ - playlist_data = sp.playlist(playlist_id) # Fetch data from Spotify API - return playlist_data + # When the playlist_id starts with 37i9dQZF1, we need to use the new function + # as the standard Spotify API endpoints are deprecated for these playlists. + # Reference: https://github.com/kamilkosek/jellyplist/issues/25 + + if playlist_id.startswith("37i9dQZF1"): + app.logger.warning(f"Algorithmic or Spotify-owned editorial playlist, using custom Implementation to fetch details") + # Use the custom implementation for these playlists + try: + data = fetch_spotify_playlist(playlist_id) + return transform_playlist_response(data) + except Exception as e: + print(f"Error fetching playlist with custom method: {e}") + return None + + # Otherwise, use the standard Spotipy API + try: + playlist_data = sp.playlist(playlist_id) # Fetch data using Spotipy + return playlist_data + except Exception as e: + print(f"Error fetching playlist with Spotipy: {e}") + return None @cache.memoize(timeout=3600*24*10) def get_cached_spotify_track(track_id): @@ -189,7 +231,7 @@ def getFeaturedPlaylists(country: str, offset: int): def getCategoryPlaylists(category: str, offset: int): try: - playlists_data = sp.category_playlists(category_id=category, limit=16, offset=offset) + playlists_data = sp.category_playlists(category_id=category, country=app.config['SPOTIFY_COUNTRY_CODE'], limit=16, offset=offset) return prepPlaylistData(playlists_data), playlists_data['playlists']['total'], f"Category {playlists_data['message']}" except SpotifyException as e: app.logger.error(f"Spotify API error in getCategoryPlaylists: {e}") @@ -215,14 +257,14 @@ def get_tracks_for_playlist(data): tracks = [] is_admin = session.get('is_admin', False) - for idx, item in enumerate(results['tracks']): + for idx, item in enumerate(results['tracks']['items']): track_data = item['track'] if track_data: duration_ms = track_data['duration_ms'] minutes = duration_ms // 60000 seconds = (duration_ms % 60000) // 1000 - track_db = Track.query.filter_by(spotify_track_id=track_data['id']).first() + track_db = Track.query.filter_by(provider_track_id=track_data['id']).first() if track_db: downloaded = track_db.downloaded diff --git a/app/jellyfin_routes.py b/app/jellyfin_routes.py index 2190c53..74c3ba5 100644 --- a/app/jellyfin_routes.py +++ b/app/jellyfin_routes.py @@ -16,25 +16,37 @@ def jellyfin_playlists(): try: # Fetch playlists from Jellyfin playlists = jellyfin.get_playlists(session_token=functions._get_token_from_sessioncookie()) - + spotify_data = {'playlists': {'items': []}} + # Extract Spotify playlist IDs from the database - spotify_playlist_ids = [] for pl in playlists: # Retrieve the playlist from the database using Jellyfin ID from_db = Playlist.query.filter_by(jellyfin_id=pl['Id']).first() - if from_db and from_db.spotify_playlist_id: - spotify_playlist_ids.append(from_db.spotify_playlist_id) + playlist_data = None + not_found = False + if from_db and from_db.provider_playlist_id: + pl_id = from_db.provider_playlist_id + try: + playlist_data = functions.get_cached_spotify_playlist(pl_id) + + except SpotifyException as e: + app.logger.error(f"Error Fetching Playlist {pl_id}: {e}") + not_found = 'http status: 404' in str(e) + if not_found: + playlist_data = { + 'status':'red', + 'description': 'Playlist has most likely been removed. You can keep it, but won´t receive Updates.', + 'id': from_db.provider_playlist_id, + 'name' : from_db.name + + } + + if playlist_data: + spotify_data['playlists']['items'].append(playlist_data) + else: app.logger.warning(f"No database entry found for Jellyfin playlist ID: {pl['Id']}") - if not spotify_playlist_ids: - flash('No Spotify playlists found to display.', 'warning') - return render_template('jellyfin_playlists.html', playlists=functions.prepPlaylistData({'playlists': {'items': []}})) - - # Use the cached function to fetch Spotify playlists - spotify_data = functions.get_cached_spotify_playlists(spotify_playlist_ids) - - # Prepare the data for the template prepared_data = functions.prepPlaylistData(spotify_data) return render_template('jellyfin_playlists.html', playlists=prepared_data) @@ -63,13 +75,13 @@ def add_playlist(): playlist_data = functions.get_cached_spotify_playlist(playlist_id) # Check if playlist already exists in the database - playlist = Playlist.query.filter_by(spotify_playlist_id=playlist_id).first() + playlist = Playlist.query.filter_by(provider_playlist_id=playlist_id).first() if not playlist: # Add new playlist if it doesn't exist # create the playlist via api key, with the first admin as 'owner' fromJellyfin = jellyfin.create_music_playlist(functions._get_api_token(),playlist_data['name'],[],functions._get_admin_id())['Id'] - playlist = Playlist(name=playlist_data['name'], spotify_playlist_id=playlist_id,spotify_uri=playlist_data['uri'],track_count = playlist_data['tracks']['total'], tracks_available=0, jellyfin_id = fromJellyfin) + playlist = Playlist(name=playlist_data['name'], provider_playlist_id=playlist_id,provider_uri=playlist_data['uri'],track_count = playlist_data['tracks']['total'], tracks_available=0, jellyfin_id = fromJellyfin) db.session.add(playlist) db.session.commit() if app.config['START_DOWNLOAD_AFTER_PLAYLIST_ADD']: @@ -83,7 +95,7 @@ def add_playlist(): spotify_tracks = {} offset = 0 while True: - playlist_items = sp.playlist_items(playlist.spotify_playlist_id, offset=offset, limit=100) + playlist_items = sp.playlist_items(playlist.provider_playlist_id, offset=offset, limit=100) items = playlist_items['items'] spotify_tracks.update({offset + idx: track['track'] for idx, track in enumerate(items) if track['track']}) @@ -94,11 +106,11 @@ def add_playlist(): track_info = track_data if not track_info: continue - track = Track.query.filter_by(spotify_track_id=track_info['id']).first() + track = Track.query.filter_by(provider_track_id=track_info['id']).first() if not track: # Add new track if it doesn't exist - track = Track(name=track_info['name'], spotify_track_id=track_info['id'], spotify_uri=track_info['uri'], downloaded=False) + track = Track(name=track_info['name'], provider_track_id=track_info['id'], provider_uri=track_info['uri'], downloaded=False) db.session.add(track) db.session.commit() elif track.downloaded: @@ -158,7 +170,7 @@ def delete_playlist(playlist_id): flash('Playlist removed') item = { "name" : playlist.name, - "id" : playlist.spotify_playlist_id, + "id" : playlist.provider_playlist_id, "can_add":True, "can_remove":False, "jellyfin_id" : playlist.jellyfin_id @@ -182,7 +194,7 @@ def wipe_playlist(playlist_id): if playlist: # Delete the playlist name = playlist.name - id = playlist.spotify_playlist_id + id = playlist.provider_playlist_id jf_id = playlist.jellyfin_id db.session.delete(playlist) db.session.commit() diff --git a/app/models.py b/app/models.py index 12d76db..76bac0f 100644 --- a/app/models.py +++ b/app/models.py @@ -22,8 +22,8 @@ user_playlists = db.Table('user_playlists', class Playlist(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(150), nullable=False) - spotify_playlist_id = db.Column(db.String(120), unique=True, nullable=False) - spotify_uri = db.Column(db.String(120), unique=True, nullable=False) + provider_playlist_id = db.Column(db.String(120), unique=True, nullable=False) + provider_uri = db.Column(db.String(120), unique=True, nullable=False) # Relationship with Tracks tracks = db.relationship('Track', secondary='playlist_tracks', back_populates='playlists') @@ -37,7 +37,7 @@ class Playlist(db.Model): users = db.relationship('JellyfinUser', secondary=user_playlists, back_populates='playlists') def __repr__(self): - return f'' + return f'' # Association table between Playlists and Tracks playlist_tracks = db.Table('playlist_tracks', @@ -50,8 +50,8 @@ playlist_tracks = db.Table('playlist_tracks', class Track(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(150), nullable=False) - spotify_track_id = db.Column(db.String(120), unique=True, nullable=False) - spotify_uri = db.Column(db.String(120), unique=True, nullable=False) + provider_track_id = db.Column(db.String(120), unique=True, nullable=False) + provider_uri = db.Column(db.String(120), unique=True, nullable=False) downloaded = db.Column(db.Boolean()) filesystem_path = db.Column(db.String(), nullable=True) jellyfin_id = db.Column(db.String(120), nullable=True) # Add Jellyfin track ID field @@ -60,4 +60,4 @@ class Track(db.Model): # Many-to-Many relationship with Playlists playlists = db.relationship('Playlist', secondary=playlist_tracks, back_populates='tracks') def __repr__(self): - return f'' + return f'' diff --git a/app/routes.py b/app/routes.py index a346f7d..fcf0cb1 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,10 +1,29 @@ -from flask import Flask, Response, jsonify, render_template, request, redirect, url_for, session, flash +import json +import re +from flask import Flask, Response, jsonify, render_template, request, redirect, url_for, session, flash, Blueprint, g from app import app, db, functions, sp, jellyfin, celery, jellyfin_admin_token, jellyfin_admin_id,device_id, cache, read_dev_build_file, tasks from app.models import JellyfinUser,Playlist,Track from celery.result import AsyncResult + +from app.providers import base +from app.providers.base import MusicProviderClient +from app.providers.spotify import SpotifyClient +from app.registry.music_provider_registry import MusicProviderRegistry from .version import __version__ from spotipy.exceptions import SpotifyException +pl_bp = Blueprint('playlist', __name__) +@pl_bp.before_request +def set_active_provider(): + """ + Middleware to select the active provider based on request parameters. + """ + provider_id = request.args.get('provider', 'Spotify') # Default to Spotify + try: + g.music_provider = MusicProviderRegistry.get_provider(provider_id) + except ValueError as e: + return {"error": str(e)}, 400 + @app.context_processor def add_context(): unlinked_track_count = len(Track.query.filter_by(downloaded=True,jellyfin_id=None).all()) @@ -45,7 +64,7 @@ def link_issues(): unlinked_tracks = Track.query.filter_by(downloaded=True,jellyfin_id=None).all() tracks = [] for ult in unlinked_tracks: - sp_track = functions.get_cached_spotify_track(ult.spotify_track_id) + sp_track = functions.get_cached_spotify_track(ult.provider_track_id) duration_ms = sp_track['duration_ms'] minutes = duration_ms // 60000 seconds = (duration_ms % 60000) // 1000 @@ -117,7 +136,7 @@ def login(): db.session.add(new_user) db.session.commit() - return redirect('/playlists') + return redirect('/') except: flash('Login failed. Please check your Jellyfin credentials and try again.', 'error') return redirect(url_for('login')) @@ -130,6 +149,32 @@ def logout(): session.pop('jellyfin_access_token', None) return redirect(url_for('login')) +@app.route('/add_single',methods=['GET']) +@functions.jellyfin_login_required +def add_single(): + playlist = request.args.get('playlist') + error = None + errdata= None + if playlist: + parsed = sp._get_id(type='playlist',id=playlist) + if parsed: + try: + functions.get_cached_spotify_playlist(parsed) + + return redirect(f'/playlist/view/{parsed}') + except SpotifyException as e: + url_match = re.search(sp._regex_spotify_url, playlist) + if url_match is not None: + resp = functions.fetch_spotify_playlist(playlist,None) + parsed_data = functions.parse_spotify_playlist_html(resp) + error = (f'Playlist can´t be fetched') + + errdata = str(e) + + return render_template('index.html',error_message = error, error_data = errdata) + + + @app.route('/playlists') @app.route('/categories') @@ -147,8 +192,13 @@ def loaditems(): try: db_playlists = db.session.query(Playlist).offset(offset).limit(limit).all() max_items = db.session.query(Playlist).count() - spotify_playlist_ids = [playlist.spotify_playlist_id for playlist in db_playlists] - spotify_data = functions.get_cached_spotify_playlists(tuple(spotify_playlist_ids)) + + provider_playlist_ids = [playlist.provider_playlist_id for playlist in db_playlists] + spotify_data = functions.get_cached_spotify_playlists(tuple(provider_playlist_ids)) + for x in spotify_data['playlists']['items']: + for from_db in db_playlists: + if x['id'] == from_db.provider_playlist_id: + x['name'] = from_db.name data = functions.prepPlaylistData(spotify_data) items_title = "Monitored Playlists" items_subtitle = "These playlists are already monitored by the Server. If you add one to your Jellyfin account, they will be available immediately." @@ -209,11 +259,11 @@ def searchResults(): context = {} if query: # Add your logic here to perform the search on Spotify (or Jellyfin) - search_result = sp.search(q = query, type= 'track,album,artist,playlist') + search_result = sp.search(q = query, type= 'playlist',limit= 50, market=app.config['SPOTIFY_COUNTRY_CODE']) context = { - 'artists' : functions.prepArtistData(search_result ), + #'artists' : functions.prepArtistData(search_result ), 'playlists' : functions.prepPlaylistData(search_result ), - 'albums' : functions.prepAlbumData(search_result ), + #'albums' : functions.prepAlbumData(search_result ), 'query' : query } return render_template('search.html', **context) @@ -221,14 +271,14 @@ def searchResults(): return render_template('search.html', query=None, results={}) -@app.route('/playlist/view/') +@pl_bp.route('/playlist/view/') @functions.jellyfin_login_required def get_playlist_tracks(playlist_id): - # Hol dir alle Tracks für die Playlist - data = functions.get_full_playlist_data(playlist_id) # Diese neue Funktion holt alle Tracks der Playlist - tracks = functions.get_tracks_for_playlist(data) # Deine Funktion, um Tracks zu holen + provider: MusicProviderClient = g.music_provider # Explicit type hint for g.music_provider + playlist: base.Playlist = provider.get_playlist(playlist_id) + tracks = functions.get_tracks_for_playlist(playlist.tracks) # Deine Funktion, um Tracks zu holen # Berechne die gesamte Dauer der Playlist - total_duration_ms = sum([track['track']['duration_ms'] for track in data['tracks'] if track['track']]) + total_duration_ms = sum([track['track']['duration_ms'] for track in data['tracks']['items'] if track['track']]) # Konvertiere die Gesamtdauer in ein lesbares Format hours, remainder = divmod(total_duration_ms // 1000, 3600) @@ -263,7 +313,7 @@ def associate_track(): flash('Missing Jellyfin or Spotify ID') # Retrieve the track by Spotify ID - track = Track.query.filter_by(spotify_track_id=spotify_id).first() + track = Track.query.filter_by(provider_track_id=spotify_id).first() if not track: flash('Track not found') @@ -296,4 +346,10 @@ def unlock_key(): @app.route('/test') def test(): + playlist_id = "37i9dQZF1DX12qgyzUprB6" + client = SpotifyClient(cookie_file='/jellyplist/open.spotify.com_cookies.txt') + client.authenticate() + pl = client.get_playlist(playlist_id=playlist_id) + browse = client.browse_all() + page = client.browse_page(browse[0].items[12]) return '' \ No newline at end of file diff --git a/app/tasks.py b/app/tasks.py index 815b399..a8084d6 100644 --- a/app/tasks.py +++ b/app/tasks.py @@ -49,7 +49,7 @@ def update_all_playlists_track_status(self): for playlist in playlists: total_tracks = 0 available_tracks = 0 - app.logger.debug(f"Current Playlist: {playlist.name} [{playlist.id}:{playlist.spotify_playlist_id}]" ) + app.logger.debug(f"Current Playlist: {playlist.name} [{playlist.id}:{playlist.provider_playlist_id}]" ) for track in playlist.tracks: total_tracks += 1 if track.filesystem_path and os.path.exists(track.filesystem_path): @@ -106,21 +106,21 @@ def download_missing_tracks(self): processed_tracks = 0 failed_downloads = 0 for track in undownloaded_tracks: - app.logger.info(f"Processing track: {track.name} [{track.spotify_track_id}]") + app.logger.info(f"Processing track: {track.name} [{track.provider_track_id}]") # Check if the track already exists in the output directory - file_path = f"{output_dir.replace('{track-id}', track.spotify_track_id)}.mp3" + file_path = f"{output_dir.replace('{track-id}', track.provider_track_id)}.mp3" # region search before download if search_before_download: app.logger.info(f"Searching for track in Jellyfin: {track.name}") - spotify_track = functions.get_cached_spotify_track(track.spotify_track_id) + spotify_track = functions.get_cached_spotify_track(track.provider_track_id) # at first try to find the track without fingerprinting it best_match = find_best_match_from_jellyfin(track) if best_match: track.downloaded = True if track.jellyfin_id != best_match['Id']: track.jellyfin_id = best_match['Id'] - app.logger.info(f"Updated Jellyfin ID for track: {track.name} ({track.spotify_track_id})") + app.logger.info(f"Updated Jellyfin ID for track: {track.name} ({track.provider_track_id})") if track.filesystem_path != best_match['Path']: track.filesystem_path = best_match['Path'] @@ -171,8 +171,8 @@ def download_missing_tracks(self): # Attempt to download the track using spotdl try: - app.logger.info(f"Trying to download track: {track.name} ({track.spotify_track_id}), spotdl timeout = 90") - s_url = f"https://open.spotify.com/track/{track.spotify_track_id}" + app.logger.info(f"Trying to download track: {track.name} ({track.provider_track_id}), spotdl timeout = 90") + s_url = f"https://open.spotify.com/track/{track.provider_track_id}" command = [ "spotdl", "download", s_url, @@ -251,7 +251,7 @@ def check_for_playlist_updates(self): for playlist in playlists: playlist.last_updated = datetime.now( timezone.utc) - sp_playlist = sp.playlist(playlist.spotify_playlist_id) + sp_playlist = sp.playlist(playlist.provider_playlist_id) full_update = True app.logger.info(f'Checking updates for playlist: {playlist.name}, s_snapshot = {sp_playlist['snapshot_id']}') db.session.commit() @@ -266,7 +266,7 @@ def check_for_playlist_updates(self): offset = 0 playlist.snapshot_id = sp_playlist['snapshot_id'] while True: - playlist_data = sp.playlist_items(playlist.spotify_playlist_id, offset=offset, limit=100) + playlist_data = sp.playlist_items(playlist.provider_playlist_id, offset=offset, limit=100) items = playlist_data['items'] spotify_tracks.update({offset + idx: track['track'] for idx, track in enumerate(items) if track['track']}) @@ -274,7 +274,7 @@ def check_for_playlist_updates(self): break offset += 100 # Move to the next batch - existing_tracks = {track.spotify_track_id: track for track in playlist.tracks} + existing_tracks = {track.provider_track_id: track for track in playlist.tracks} # Determine tracks to add and remove tracks_to_add = [] @@ -282,9 +282,9 @@ def check_for_playlist_updates(self): if track_info: track_id = track_info['id'] if track_id not in existing_tracks: - track = Track.query.filter_by(spotify_track_id=track_id).first() + track = Track.query.filter_by(provider_track_id=track_id).first() if not track: - track = Track(name=track_info['name'], spotify_track_id=track_id, spotify_uri=track_info['uri'], downloaded=False) + track = Track(name=track_info['name'], provider_track_id=track_id, provider_uri=track_info['uri'], downloaded=False) db.session.add(track) db.session.commit() app.logger.info(f'Added new track: {track.name}') @@ -382,10 +382,10 @@ def update_jellyfin_id_for_downloaded_tracks(self): track.downloaded = True if track.jellyfin_id != best_match['Id']: track.jellyfin_id = best_match['Id'] - app.logger.info(f"Updated Jellyfin ID for track: {track.name} ({track.spotify_track_id})") + app.logger.info(f"Updated Jellyfin ID for track: {track.name} ({track.provider_track_id})") if track.filesystem_path != best_match['Path']: track.filesystem_path = best_match['Path'] - app.logger.info(f"Updated filesystem_path for track: {track.name} ({track.spotify_track_id})") + app.logger.info(f"Updated filesystem_path for track: {track.name} ({track.provider_track_id})") @@ -422,10 +422,10 @@ def find_best_match_from_jellyfin(track: Track): for result in search_results: - app.logger.debug(f"Processing search result: {result['Id']}") + app.logger.debug(f"Processing search result: {result['Id']}, Path = {result['Path']}") quality_score = compute_quality_score(result, app.config['FIND_BEST_MATCH_USE_FFPROBE']) try: - spotify_track = functions.get_cached_spotify_track(track.spotify_track_id) + spotify_track = functions.get_cached_spotify_track(track.provider_track_id) spotify_track_name = spotify_track['name'].lower() spotify_artists = [artist['name'].lower() for artist in spotify_track['artists']] except Exception as e: