Refactored email sending to use a single HTML template with a base layout, removed plain text email templates, and updated all related backend logic. Introduced a new ContactMe model, serializer, Celery task, and API endpoints for handling contact form submissions, including email notifications. Renamed ShopConfiguration to SiteConfiguration throughout the backend for consistency. Updated frontend to remove unused components, add a new Services section, and adjust navigation and contact form integration.
121 lines
3.9 KiB
Python
121 lines
3.9 KiB
Python
from celery import shared_task
|
||
from celery.utils.log import get_task_logger
|
||
from django.core.mail import send_mail
|
||
from django.conf import settings
|
||
from django.utils.http import urlsafe_base64_encode
|
||
from django.utils.encoding import force_bytes
|
||
from django.template.loader import render_to_string
|
||
from .tokens import *
|
||
from .models import CustomUser
|
||
|
||
logger = get_task_logger(__name__)
|
||
|
||
def send_email_with_context(recipients, subject, template_path=None, context=None, message: str | None = None):
|
||
"""
|
||
Send emails rendering a single HTML template.
|
||
- `template_name` is a simple base name without extension, e.g. "email/test".
|
||
- Renders only HTML (".html"), no ".txt" support.
|
||
- Converts `user` in context to a plain dict to avoid passing models to templates.
|
||
"""
|
||
if isinstance(recipients, str):
|
||
recipients = [recipients]
|
||
|
||
html_message = None
|
||
if template_path:
|
||
ctx = dict(context or {})
|
||
# Render base layout and include the provided template as the main content.
|
||
# The included template receives the same context as the base.
|
||
html_message = render_to_string(
|
||
"email/components/base.html",
|
||
{"content_template": template_path, **ctx},
|
||
)
|
||
|
||
try:
|
||
send_mail(
|
||
subject=subject,
|
||
message=message or "",
|
||
from_email=None,
|
||
recipient_list=recipients,
|
||
fail_silently=False,
|
||
html_message=html_message,
|
||
)
|
||
if settings.EMAIL_BACKEND == 'django.core.mail.backends.console.EmailBackend' and message:
|
||
logger.debug(f"\nEMAIL OBSAH:\n{message}\nKONEC OBSAHU")
|
||
return True
|
||
except Exception as e:
|
||
logger.error(f"E-mail se neodeslal: {e}")
|
||
return False
|
||
|
||
|
||
#----------------------------------------------------------------------------------------------------
|
||
|
||
# This function sends an email to the user for email verification after registration.
|
||
@shared_task
|
||
def send_email_verification_task(user_id):
|
||
try:
|
||
user = CustomUser.objects.get(pk=user_id)
|
||
except CustomUser.DoesNotExist:
|
||
logger.info(f"Task send_email_verification has failed. Invalid User ID was sent.")
|
||
return 0
|
||
|
||
uid = urlsafe_base64_encode(force_bytes(user.pk))
|
||
# {changed} generate and store a per-user token
|
||
token = user.generate_email_verification_token()
|
||
verify_url = f"{settings.FRONTEND_URL}/email-verification/?uidb64={uid}&token={token}"
|
||
|
||
context = {
|
||
"user": user,
|
||
"action_url": verify_url,
|
||
"frontend_url": settings.FRONTEND_URL,
|
||
"cta_label": "Ověřit e‑mail",
|
||
}
|
||
|
||
send_email_with_context(
|
||
recipients=user.email,
|
||
subject="Ověření e‑mailu",
|
||
template_path="email/email_verification.html",
|
||
context=context,
|
||
)
|
||
|
||
|
||
|
||
@shared_task
|
||
def send_email_test_task(email):
|
||
context = {
|
||
"action_url": settings.FRONTEND_URL,
|
||
"frontend_url": settings.FRONTEND_URL,
|
||
"cta_label": "Otevřít aplikaci",
|
||
}
|
||
send_email_with_context(
|
||
recipients=email,
|
||
subject="Testovací e‑mail",
|
||
template_path="email/test.html",
|
||
context=context,
|
||
)
|
||
|
||
|
||
@shared_task
|
||
def send_password_reset_email_task(user_id):
|
||
try:
|
||
user = CustomUser.objects.get(pk=user_id)
|
||
except CustomUser.DoesNotExist:
|
||
logger.info(f"Task send_password_reset_email has failed. Invalid User ID was sent.")
|
||
return 0
|
||
|
||
uid = urlsafe_base64_encode(force_bytes(user.pk))
|
||
token = password_reset_token.make_token(user)
|
||
reset_url = f"{settings.FRONTEND_URL}/reset-password/{uid}/{token}"
|
||
|
||
context = {
|
||
"user": user,
|
||
"action_url": reset_url,
|
||
"frontend_url": settings.FRONTEND_URL,
|
||
"cta_label": "Obnovit heslo",
|
||
}
|
||
|
||
send_email_with_context(
|
||
recipients=user.email,
|
||
subject="Obnova hesla",
|
||
template_path="email/password_reset.html",
|
||
context=context,
|
||
) |