SMW-Upload/seduttomachineworks_project/quote_submit.py

130 lines
4.6 KiB
Python

import json
import time
from pathlib import Path
from django.http import StreamingHttpResponse, JsonResponse
from django.conf import settings
from django.core.validators import validate_email
from django.core.exceptions import ValidationError
from django.views.decorators.clickjacking import xframe_options_exempt
from django.views.decorators.csrf import csrf_exempt
def send_progress_update(step, message, progress):
"""Helper to send a progress update as JSON"""
return json.dumps({"step": step, "message": message, "progress": progress}) + "\n"
@xframe_options_exempt
@csrf_exempt
def submit_quote(request):
"""
Handle quote submission with progress updates.
Steps:
1. Upload files
2. Save files
3. Send email
4. Verify email sent
"""
if request.method != "POST":
return JsonResponse({"error": "Method not allowed"}, status=405)
# Read form data first (files need to be read from request)
email = request.POST.get("email", "").strip()
notes = request.POST.get("notes", "").strip()
files = request.FILES.getlist("files")
def process_quote():
try:
# Step 1: Validate email
yield send_progress_update(1, "Validating email address...", 5)
if not email:
raise ValueError("Email is required")
try:
validate_email(email)
except ValidationError:
raise ValueError(f"Invalid email address: {email}")
yield send_progress_update(1, "Email validated successfully", 10)
# Step 2: Create submission & upload files
from quotes.models import Submission, SubmissionFile
# Create a Submission entry
submission = Submission.objects.create(
email=email,
description=notes,
)
yield send_progress_update(2, "Created submission entry...", 15)
# Save each file and register in the model
total_files = len(files)
file_objs = []
for idx, file in enumerate(files, start=1):
# Use the original filename and save to MEDIA_ROOT/submission_<id>_filename
submission_dir = (
Path(settings.MEDIA_ROOT) / f"submission_{submission.id}"
)
submission_dir.mkdir(parents=True, exist_ok=True)
target_path = submission_dir / file.name
with open(target_path, "wb") as f:
for chunk in file.chunks():
f.write(chunk)
# Register file in SubmissionFile model
rel_path = (Path(f"submission_{submission.id}") / file.name).as_posix()
submission_file = SubmissionFile.objects.create(
submission=submission,
original_filename=file.name,
path=rel_path,
file_size=file.size,
)
file_objs.append(submission_file)
yield send_progress_update(
2,
f"Uploaded file {idx} of {total_files}: {file.name}",
15 + int((idx / total_files) * 30),
)
yield send_progress_update(3, "Files saved...", 50)
# Step 4: Send emails
from quotes.email_utils import send_submission_emails
yield send_progress_update(4, "Sending notification email...", 70)
owner_sent, submitter_sent = send_submission_emails(submission)
time.sleep(0.3)
yield send_progress_update(4, "Sending confirmation email...", 75)
time.sleep(0.3)
# Verify emails were sent
if not owner_sent and getattr(settings, "OWNER_EMAIL", ""):
yield send_progress_update(
"warning",
"Warning: Owner notification email may not have been sent",
75,
)
if not submitter_sent:
yield send_progress_update(
"warning", "Warning: Confirmation email may not have been sent", 75
)
# Complete
yield send_progress_update(
5,
"Quote request submitted successfully! Check your email for confirmation.",
100,
)
except Exception as e:
yield send_progress_update("error", f"An error occurred: {str(e)}", 0)
response = StreamingHttpResponse(process_quote(), content_type="text/event-stream")
response["Cache-Control"] = "no-cache"
response["X-Accel-Buffering"] = "no"
return response