# Create your views here. from django.contrib.auth.decorators import login_required from django.http import FileResponse, HttpResponse, HttpResponseRedirect from django.shortcuts import get_object_or_404, render import os from blake3 import blake3 from .forms import UploadFileForm from .models import User_Banner_Images, User_Profile_Images, Metadata_Files, Submission_File MODEL_MAP = { 'user_profile': User_Profile_Images, 'user_banner': User_Banner_Images, 'submission': Submission_File, 'metadata': Metadata_Files, } def compute_file_hash(file): ''' Compute BLAKE3 hash of the file ''' try: hasher = blake3() for chunk in file.chunks(chunk_size=65536): hasher.update(chunk) return hasher.hexdigest() except Exception as e: print(f"Error computing file hash: {e}") return None @login_required(login_url="/login/") def serve_content_file(request, folder, file_hash): ''' View function to serve content files for download or inline viewing ''' ModelClass = MODEL_MAP.get(folder) if ModelClass is None: return HttpResponse("Invalid folder", status=404) download = request.GET.get('d') try: obj_file = get_object_or_404(ModelClass, file_hash=file_hash) file = obj_file.file.file file_name = obj_file.file_name response = FileResponse(file) if download == "1": response['Content-Disposition'] = f'attachment; filename="{file_name}"' else: response['Content-Disposition'] = f'inline; filename="{file_name}"' return response except Exception as e: print(f"Error serving file: {e}") return HttpResponse("File not found", status=404) @login_required(login_url="/login/") def fileUpload(request): ''' View function for handling file uploads ''' if request.method == 'POST': form = UploadFileForm(request.POST, request.FILES) if form.is_valid(): if 'file' in request.FILES: # Check if a file has been uploaded file = form.cleaned_data['file'] file_name = file.name file_hash = compute_file_hash(file) Null, file_ext = os.path.splitext(file_name) hash_file_name = file_hash + file_ext new_submission_file, created = Submission_File.objects.get_or_create(file_hash=file_hash) new_submission_file.file_hash = file_hash new_submission_file.file_name = file_name new_submission_file.file.save(hash_file_name, file) new_submission_file.save return HttpResponseRedirect(f"/files/submission/{file_hash}") else: # No file was uploaded, add an error message to the context error_message = 'No file was uploaded.' return render(request, 'files/upload.html', {'form': form, 'error_message': error_message}) else: # Form is not valid, add an error message to the context error_message = 'There was an error with the form.' return render(request, 'files/upload.html', {'form': form, 'error_message': error_message}) else: form = UploadFileForm() return render(request, 'files/upload.html', {'form': form})