@@ -5,6 +5,8 @@ from functools import wraps
|
||||
from celery.result import AsyncResult
|
||||
from app.tasks import download_missing_tracks,check_for_playlist_updates, update_all_playlists_track_status, update_jellyfin_id_for_downloaded_tracks
|
||||
from jellyfin.objects import PlaylistMetadata
|
||||
from spotipy.exceptions import SpotifyException
|
||||
|
||||
import re
|
||||
|
||||
TASK_STATUS = {
|
||||
@@ -129,12 +131,9 @@ def get_cached_spotify_playlist(playlist_id):
|
||||
:param playlist_id: The Spotify playlist ID.
|
||||
:return: Playlist data as a dictionary, or None if an error occurs.
|
||||
"""
|
||||
try:
|
||||
playlist_data = sp.playlist(playlist_id) # Fetch data from Spotify API
|
||||
return playlist_data
|
||||
except Exception as e:
|
||||
app.logger.error(f"Error fetching playlist {playlist_id} from Spotify: {str(e)}")
|
||||
return None
|
||||
playlist_data = sp.playlist(playlist_id) # Fetch data from Spotify API
|
||||
return playlist_data
|
||||
|
||||
@cache.memoize(timeout=3600*24*10)
|
||||
def get_cached_spotify_track(track_id):
|
||||
"""
|
||||
@@ -180,15 +179,21 @@ def prepArtistData(data):
|
||||
|
||||
|
||||
|
||||
def getFeaturedPlaylists(country,offset):
|
||||
playlists_data = sp.featured_playlists(country=country, limit=16, offset=offset)
|
||||
|
||||
return prepPlaylistData(playlists_data), playlists_data['playlists']['total'],'Featured Playlists'
|
||||
def getFeaturedPlaylists(country: str, offset: int):
|
||||
try:
|
||||
playlists_data = sp.featured_playlists(country=country, limit=16, offset=offset)
|
||||
return prepPlaylistData(playlists_data), playlists_data['playlists']['total'], 'Featured Playlists'
|
||||
except SpotifyException as e:
|
||||
app.logger.error(f"Spotify API error in getFeaturedPlaylists: {e}")
|
||||
return [], e, f'Error: Could not load featured playlists. Please try again later. This is most likely due to an Error in the Spotify API or an rate limit has been reached.'
|
||||
|
||||
def getCategoryPlaylists(category,offset):
|
||||
playlists_data = sp.category_playlists(category_id=category, limit=16, offset=offset)
|
||||
|
||||
return prepPlaylistData(playlists_data), playlists_data['playlists']['total'],f"Category {playlists_data['message']}"
|
||||
def getCategoryPlaylists(category: str, offset: int):
|
||||
try:
|
||||
playlists_data = sp.category_playlists(category_id=category, 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}")
|
||||
return [], e, 'Error: Could not load category playlists. Please try again later. This is most likely due to an Error in the Spotify API or an rate limit has been reached.'
|
||||
|
||||
def getCategories(country,offset):
|
||||
categories_data = sp.categories(limit=16, offset= offset)
|
||||
|
||||
@@ -3,7 +3,7 @@ from flask import Flask, jsonify, render_template, request, redirect, url_for, s
|
||||
from sqlalchemy import insert
|
||||
from app import app, db, jellyfin, functions, device_id,sp
|
||||
from app.models import Playlist,Track, playlist_tracks
|
||||
|
||||
from spotipy.exceptions import SpotifyException
|
||||
|
||||
|
||||
from jellyfin.objects import PlaylistMetadata
|
||||
@@ -38,11 +38,15 @@ def jellyfin_playlists():
|
||||
prepared_data = functions.prepPlaylistData(spotify_data)
|
||||
|
||||
return render_template('jellyfin_playlists.html', playlists=prepared_data)
|
||||
|
||||
except SpotifyException as e:
|
||||
app.logger.error(f"Error fetching monitored playlists: {e}")
|
||||
error_data, error_message = e, f'Could not retrieve monitored Playlists. Please try again later. This is most likely due to an Error in the Spotify API or an rate limit has been reached.'
|
||||
return render_template('jellyfin_playlists.html', playlists=functions.prepPlaylistData({'playlists': {'items': []}}), error_message=error_message,error_data = error_data)
|
||||
|
||||
except Exception as e:
|
||||
app.logger.error(f"Error in /jellyfin_playlists route: {str(e)}")
|
||||
flash('An error occurred while fetching playlists.', 'danger')
|
||||
return render_template('jellyfin_playlists.html', playlists=functions.prepPlaylistData({'playlists': {'items': []}}))
|
||||
return render_template('jellyfin_playlists.html', playlists=functions.prepPlaylistData({'playlists': {'items': []}}), error_message='An error occurred while fetching playlists.',error_data = e)
|
||||
|
||||
|
||||
@app.route('/addplaylist', methods=['POST'])
|
||||
|
||||
@@ -3,6 +3,7 @@ from app import app, db, functions, sp, jellyfin, celery, jellyfin_admin_token,
|
||||
from app.models import JellyfinUser,Playlist,Track
|
||||
from celery.result import AsyncResult
|
||||
from .version import __version__
|
||||
from spotipy.exceptions import SpotifyException
|
||||
|
||||
@app.context_processor
|
||||
def add_context():
|
||||
@@ -140,32 +141,46 @@ def loaditems():
|
||||
limit = 20 # Define a limit for pagination
|
||||
additional_query = ''
|
||||
items_subtitle = ''
|
||||
|
||||
error_message = None # Placeholder for error messages
|
||||
error_data = ''
|
||||
if request.path == '/playlists/monitored':
|
||||
# Step 1: Query the database for monitored playlists
|
||||
db_playlists = db.session.query(Playlist).offset(offset).limit(limit).all()
|
||||
max_items = db.session.query(Playlist).count()
|
||||
|
||||
# Collect Spotify Playlist IDs from the database
|
||||
spotify_playlist_ids = [playlist.spotify_playlist_id for playlist in db_playlists]
|
||||
|
||||
spotify_data = functions.get_cached_spotify_playlists(tuple(spotify_playlist_ids))
|
||||
|
||||
# Step 3: Pass the Spotify data to prepPlaylistData for processing
|
||||
data = functions.prepPlaylistData(spotify_data)
|
||||
items_title = "Monitored Playlists"
|
||||
items_subtitle = "This playlists are already monitored by the Server, if you add one of these to your Jellyfin account, they will be available immediately."
|
||||
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))
|
||||
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."
|
||||
except SpotifyException as e:
|
||||
app.logger.error(f"Error fetching monitored playlists: {e}")
|
||||
data, max_items, items_title = [], e, f'Could not retrieve monitored Playlists. Please try again later. This is most likely due to an Error in the Spotify API or an rate limit has been reached.'
|
||||
error_message = items_title
|
||||
error_data = max_items
|
||||
|
||||
elif request.path == '/playlists':
|
||||
cat = request.args.get('cat', None)
|
||||
if cat is not None:
|
||||
data, max_items, items_title = functions.getCategoryPlaylists(category=cat, offset=offset)
|
||||
if not data: # Check if data is empty
|
||||
error_message = items_title # Set the error message from the function
|
||||
error_data = max_items
|
||||
additional_query += f"&cat={cat}"
|
||||
else:
|
||||
data, max_items, items_title = functions.getFeaturedPlaylists(country=country, offset=offset)
|
||||
if not data: # Check if data is empty
|
||||
error_message = items_title # Set the error message from the function
|
||||
error_data = max_items
|
||||
|
||||
elif request.path == '/categories':
|
||||
data, max_items, items_title = functions.getCategories(country=country, offset=offset)
|
||||
try:
|
||||
data, max_items, items_title = functions.getCategories(country=country, offset=offset)
|
||||
except Exception as e:
|
||||
app.logger.error(f"Error fetching categories: {e}")
|
||||
data, max_items, items_title = [], e, f'Error: Could not load categories. Please try again later. '
|
||||
error_message = items_title
|
||||
error_data = max_items
|
||||
|
||||
|
||||
next_offset = offset + len(data)
|
||||
total_items = max_items
|
||||
@@ -175,8 +190,10 @@ def loaditems():
|
||||
'total_items': total_items,
|
||||
'endpoint': request.path,
|
||||
'items_title': items_title,
|
||||
'items_subtitle' : items_subtitle,
|
||||
'additional_query': additional_query
|
||||
'items_subtitle': items_subtitle,
|
||||
'additional_query': additional_query,
|
||||
'error_message': error_message, # Pass error message to the template
|
||||
'error_data': error_data, # Pass error message to the template
|
||||
}
|
||||
|
||||
if request.headers.get('HX-Request'): # Check if the request is from HTMX
|
||||
|
||||
51
app/tasks.py
51
app/tasks.py
@@ -127,31 +127,34 @@ def download_missing_tracks(self):
|
||||
processed_tracks+=1
|
||||
continue
|
||||
|
||||
# region search with fingerprinting
|
||||
preview_url = spotify_track.get('preview_url')
|
||||
if not preview_url:
|
||||
app.logger.error(f"Preview URL not found for track {track.name}.")
|
||||
# Decide whether to skip or proceed to download
|
||||
# For now, we'll proceed to download
|
||||
else:
|
||||
# Get the list of Spotify artist names
|
||||
spotify_artists = [artist['name'] for artist in spotify_track['artists']]
|
||||
|
||||
# Perform the search in Jellyfin
|
||||
match_found, jellyfin_file_path = jellyfin.search_track_in_jellyfin(
|
||||
session_token=jellyfin_admin_token,
|
||||
preview_url=preview_url,
|
||||
song_name=track.name,
|
||||
artist_names=spotify_artists
|
||||
)
|
||||
if match_found:
|
||||
app.logger.info(f"Match found in Jellyfin for track {track.name}. Skipping download.")
|
||||
track.downloaded = True
|
||||
track.filesystem_path = jellyfin_file_path
|
||||
db.session.commit()
|
||||
continue
|
||||
# region search with fingerprinting
|
||||
if spotify_track:
|
||||
preview_url = spotify_track.get('preview_url')
|
||||
if not preview_url:
|
||||
app.logger.error(f"Preview URL not found for track {track.name}.")
|
||||
# Decide whether to skip or proceed to download
|
||||
# For now, we'll proceed to download
|
||||
else:
|
||||
app.logger.info(f"No match found in Jellyfin for track {track.name}. Proceeding to download.")
|
||||
# Get the list of Spotify artist names
|
||||
spotify_artists = [artist['name'] for artist in spotify_track['artists']]
|
||||
|
||||
# Perform the search in Jellyfin
|
||||
match_found, jellyfin_file_path = jellyfin.search_track_in_jellyfin(
|
||||
session_token=jellyfin_admin_token,
|
||||
preview_url=preview_url,
|
||||
song_name=track.name,
|
||||
artist_names=spotify_artists
|
||||
)
|
||||
if match_found:
|
||||
app.logger.info(f"Match found in Jellyfin for track {track.name}. Skipping download.")
|
||||
track.downloaded = True
|
||||
track.filesystem_path = jellyfin_file_path
|
||||
db.session.commit()
|
||||
continue
|
||||
else:
|
||||
app.logger.info(f"No match found in Jellyfin for track {track.name}. Proceeding to download.")
|
||||
else:
|
||||
app.logger.warning(f"spotify_track not set, see previous log messages")
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
Reference in New Issue
Block a user