All checks were successful
Deploy Quartz site to GitHub Pages / build (push) Successful in 2m29s
102 lines
3.4 KiB
Python
102 lines
3.4 KiB
Python
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]
|
|
})
|
|
|