""" Topic-based file sharing views. Each topic is accessible via a subdomain (e.g., cofi.rfiles.online). Anyone can view files and upload new ones - no password required. """ from django.shortcuts import render, redirect, get_object_or_404 from django.http import JsonResponse, Http404 from django.views import View from django.views.decorators.csrf import csrf_exempt from django.utils.decorators import method_decorator from files.models import SharedSpace, MediaFile, PublicShare def get_topic_or_404(request): """Get the topic (shared space) from the request's subdomain slug.""" slug = getattr(request, 'shared_space_slug', None) if not slug: raise Http404("Topic not found") return get_object_or_404(SharedSpace, slug=slug, is_active=True) class SharedSpaceLoginView(View): """Redirect login to home - no login needed for topics.""" def get(self, request): return redirect('shared_space_home') def post(self, request): return redirect('shared_space_home') class SharedSpaceLogoutView(View): """Redirect to home - no logout needed.""" def get(self, request): return redirect('shared_space_home') class SharedSpaceHomeView(View): """Main upload page for topic - upload zone + files.""" def get(self, request): space = get_topic_or_404(request) recent_files = space.files.all().order_by('-created_at')[:20] return render(request, 'portal/shared_space/home.html', { 'space': space, 'recent_files': recent_files, }) @method_decorator(csrf_exempt, name='dispatch') class SharedSpaceUploadAPIView(View): """Handle file uploads via AJAX for topic.""" def post(self, request): space = get_topic_or_404(request) if not request.FILES.get('file'): return JsonResponse({'error': 'No file provided'}, status=400) uploaded_file = request.FILES['file'] max_size_bytes = space.max_file_size_mb * 1024 * 1024 if uploaded_file.size > max_size_bytes: return JsonResponse({ 'error': f'File too large. Maximum size is {space.max_file_size_mb}MB' }, status=400) title = request.POST.get('title', '') or uploaded_file.name description = request.POST.get('description', '') media_file = MediaFile.objects.create( file=uploaded_file, original_filename=uploaded_file.name, title=title, description=description, mime_type=uploaded_file.content_type or 'application/octet-stream', uploaded_by=request.user if request.user.is_authenticated else None, shared_space=space, ) share = PublicShare.objects.create( media_file=media_file, created_by=request.user if request.user.is_authenticated else None, note=f'Uploaded to topic: {space.slug}', ) return JsonResponse({ 'success': True, 'file': { 'id': str(media_file.id), 'title': media_file.title, 'filename': media_file.original_filename, 'size': media_file.file_size, 'mime_type': media_file.mime_type, }, 'share': { 'token': share.token, 'url': share.get_public_url(), } }) class SharedSpaceFileListView(View): """List all files in the topic.""" def get(self, request): space = get_topic_or_404(request) files = space.files.all().order_by('-created_at') return render(request, 'portal/shared_space/files.html', { 'space': space, 'files': files, })