feat: enhance song search with login requirement and error handling
This commit is contained in:
@@ -8,7 +8,7 @@ from flask_wtf.csrf import CSRFProtect
|
|||||||
import traceback # Add import at the top
|
import traceback # Add import at the top
|
||||||
import logging
|
import logging
|
||||||
from sqlalchemy import or_
|
from sqlalchemy import or_
|
||||||
from flask_login import login_required # Add import for login_required
|
from flask_login import login_required, current_user
|
||||||
import requests # Import requests for direct API calls
|
import requests # Import requests for direct API calls
|
||||||
|
|
||||||
api_bp = Blueprint('api', __name__, url_prefix='/api')
|
api_bp = Blueprint('api', __name__, url_prefix='/api')
|
||||||
@@ -658,15 +658,15 @@ def get_deezer_playlist(playlist_id):
|
|||||||
return jsonify({'error': 'Unable to fetch playlist details'}), 500
|
return jsonify({'error': 'Unable to fetch playlist details'}), 500
|
||||||
|
|
||||||
@api_bp.route('/songs/search')
|
@api_bp.route('/songs/search')
|
||||||
|
@login_required
|
||||||
def search_songs():
|
def search_songs():
|
||||||
"""Search for songs by title or artist"""
|
"""Search for songs by title or artist"""
|
||||||
if 'access_token' not in session:
|
|
||||||
return jsonify({'error': 'Authentication required'}), 401
|
|
||||||
|
|
||||||
query = request.args.get('q', '')
|
query = request.args.get('q', '')
|
||||||
if not query or len(query) < 2:
|
if not query or len(query) < 2:
|
||||||
return jsonify([])
|
return jsonify([])
|
||||||
|
|
||||||
|
current_app.logger.info(f"User {current_user.username} searching for songs with query: {query}")
|
||||||
|
|
||||||
# Search for songs by title or artist
|
# Search for songs by title or artist
|
||||||
songs = Song.query.filter(
|
songs = Song.query.filter(
|
||||||
or_(
|
or_(
|
||||||
|
|||||||
@@ -606,9 +606,16 @@
|
|||||||
|
|
||||||
searchTimeout = setTimeout(function() {
|
searchTimeout = setTimeout(function() {
|
||||||
searchResults.innerHTML = '<p class="text-center p-4"><i class="fas fa-spinner fa-spin"></i> Searching...</p>';
|
searchResults.innerHTML = '<p class="text-center p-4"><i class="fas fa-spinner fa-spin"></i> Searching...</p>';
|
||||||
|
fetch(`/api/songs/search?q=${encodeURIComponent(query)}`)
|
||||||
fetch(`/api/songs/search?q=${encodeURIComponent(query)}`)
|
.then(response => {
|
||||||
.then(response => response.json())
|
if (!response.ok) {
|
||||||
|
if (response.status === 401) {
|
||||||
|
throw new Error('You need to log in to search for songs');
|
||||||
|
}
|
||||||
|
throw new Error('Error searching for songs');
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
.then(data => {
|
.then(data => {
|
||||||
if (data.length === 0) {
|
if (data.length === 0) {
|
||||||
searchResults.innerHTML = '<p class="text-gray-500 text-center p-4">No songs found</p>';
|
searchResults.innerHTML = '<p class="text-gray-500 text-center p-4">No songs found</p>';
|
||||||
@@ -649,11 +656,21 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
}) .catch(error => {
|
||||||
.catch(error => {
|
|
||||||
console.error('Error searching songs:', error);
|
console.error('Error searching songs:', error);
|
||||||
searchResults.innerHTML = '<p class="text-red-500 text-center p-4">Error searching songs</p>';
|
searchResults.innerHTML = `<p class="text-red-500 text-center p-4">${error.message}</p>`;
|
||||||
showToast('Error searching for songs', 'error');
|
showToast(error.message, 'error');
|
||||||
|
|
||||||
|
// If unauthorized, suggest logging in again
|
||||||
|
if (error.message.includes('log in')) {
|
||||||
|
searchResults.innerHTML += `
|
||||||
|
<div class="text-center p-4">
|
||||||
|
<a href="{{ url_for('users.login') }}" class="text-blue-500 hover:underline">
|
||||||
|
Click here to log in again
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}, 500);
|
}, 500);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user