import os import mimetypes from pathlib import Path from django.http import JsonResponse from django.views.decorators.http import require_http_methods from file.models import File @require_http_methods(["POST"]) def upload_files_api(request): """Handle file/folder uploads and create File model instances""" uploaded_files = request.FILES.getlist('files') if not uploaded_files: return JsonResponse({'error': 'No files uploaded'}, status=400) created_files = [] folder_cache = {} # Cache for created folder objects for idx, uploaded_file in enumerate(uploaded_files): # Get the relative path if it exists (from webkitRelativePath) relative_path = request.POST.get(f'path_{idx}', '') if relative_path: # This is from a folder upload path_obj = Path(relative_path) parts = path_obj.parts # Create parent folders if needed parent = None for i, part in enumerate(parts[:-1]): # Exclude the file itself folder_path = os.path.join(*parts[:i+1]) if folder_path not in folder_cache: # Create or get folder folder, created = File.objects.get_or_create( user=request.quiz_user, path=folder_path, defaults={ 'name': part, 'mime_type': 'application/x-folder', 'parent': parent } ) folder_cache[folder_path] = folder parent = folder_cache[folder_path] file_path = relative_path file_name = parts[-1] else: # Single file upload file_path = uploaded_file.name file_name = uploaded_file.name parent = None # Determine MIME type mime_type, _ = mimetypes.guess_type(file_name) if not mime_type: mime_type = 'application/octet-stream' # Read file content (for text files, store in text field) text_content = '' if mime_type.startswith('text/'): try: content_bytes = uploaded_file.read() text_content = content_bytes.decode('utf-8') uploaded_file.seek(0) # Reset for saving to disk except (UnicodeDecodeError, AttributeError): uploaded_file.seek(0) # Generate unique filename with 8-digit hash import hashlib file_hash = hashlib.md5(f"{file_path}{uploaded_file.name}".encode()).hexdigest()[:8] name_parts = os.path.splitext(file_name) unique_filename = f"{name_parts[0]}_{file_hash}{name_parts[1]}" # Create File instance file_obj = File.objects.create( user=request.quiz_user, name=file_name, path=file_path, mime_type=mime_type, parent=parent, text=text_content ) # Save the uploaded file to disk (not for folders) if mime_type != 'application/x-folder': file_obj.file_content.save(unique_filename, uploaded_file, save=True) created_files.append(file_obj) return JsonResponse({ 'success': True, 'count': len(created_files), 'files': [{'name': f.name, 'path': f.path} for f in created_files] })