import base64 from django.conf import settings from django.contrib.auth import authenticate, login, get_user_model from django.contrib.auth.decorators import login_required from django.contrib.auth.forms import UserCreationForm, AuthenticationForm from django.http import JsonResponse from django.shortcuts import render, redirect from django.views.decorators.http import require_http_methods from radio import lastfm as lastfm_module User = get_user_model() # --------------------------------------------------------------------------- # Register # --------------------------------------------------------------------------- def register(request): if request.user.is_authenticated: return redirect('index') if request.method == 'POST': form = UserCreationForm(request.POST) if form.is_valid(): user = form.save() login(request, user) return redirect('index') else: form = UserCreationForm() return render(request, 'accounts/register.html', {'form': form}) # --------------------------------------------------------------------------- # Login # --------------------------------------------------------------------------- def login_view(request): if request.user.is_authenticated: return redirect('index') if request.method == 'POST': form = AuthenticationForm(data=request.POST) if form.is_valid(): user = form.get_user() login(request, user) next_url = request.GET.get('next', '/') return redirect(next_url) else: form = AuthenticationForm() return render(request, 'accounts/login.html', {'form': form}) # --------------------------------------------------------------------------- # Settings # --------------------------------------------------------------------------- @login_required def settings_view(request): profile = request.user.profile if request.method == 'POST': profile.lastfm_scrobble = 'lastfm_scrobble' in request.POST profile.save(update_fields=['lastfm_scrobble']) return redirect('settings') context = { 'profile': profile, 'has_lastfm': profile.has_lastfm(), } return render(request, 'accounts/settings.html', context) # --------------------------------------------------------------------------- # Last.fm OAuth # --------------------------------------------------------------------------- @login_required def lastfm_connect(request): callback_url = request.build_absolute_uri('/accounts/lastfm/callback/') try: auth_url, token = lastfm_module.get_auth_url(callback_url) request.session['lastfm_token'] = token return redirect(auth_url) except Exception as exc: return render(request, 'accounts/settings.html', { 'profile': request.user.profile, 'has_lastfm': request.user.profile.has_lastfm(), 'lastfm_error': f"Could not connect to Last.fm: {exc}", }) @login_required def lastfm_callback(request): token = request.session.get('lastfm_token') if not token: return redirect('settings') try: session_key = lastfm_module.get_session_key(token) username = lastfm_module.get_username(session_key) profile = request.user.profile profile.lastfm_session_key = session_key profile.lastfm_username = username profile.save(update_fields=['lastfm_session_key', 'lastfm_username']) # Clean up session del request.session['lastfm_token'] except Exception: pass return redirect('settings') @login_required @require_http_methods(['POST']) def upload_background(request): f = request.FILES.get('file') if not f: return JsonResponse({'error': 'no file'}, status=400) ext = f.name.rsplit('.', 1)[-1].lower() if '.' in f.name else '' mime_map = {'jpg': 'image/jpeg', 'jpeg': 'image/jpeg', 'png': 'image/png', 'webp': 'image/webp'} if ext not in mime_map: return JsonResponse({'error': 'only jpg, png, or webp allowed'}, status=400) if f.size > settings.BG_MAX_BYTES: return JsonResponse({'error': 'file too large (max 5 MB)'}, status=400) data = base64.b64encode(f.read()).decode('ascii') data_url = f"data:{mime_map[ext]};base64,{data}" profile = request.user.profile profile.background_image_data = data_url profile.save(update_fields=['background_image_data']) return JsonResponse({'ok': True, 'url': data_url}) @login_required @require_http_methods(['POST']) def delete_background(request): profile = request.user.profile profile.background_image_data = '' profile.save(update_fields=['background_image_data']) return redirect('settings') @login_required @require_http_methods(['POST']) def lastfm_disconnect(request): profile = request.user.profile profile.lastfm_session_key = '' profile.lastfm_username = '' profile.save(update_fields=['lastfm_session_key', 'lastfm_username']) return redirect('settings')