215 lines
8.5 KiB
Python
215 lines
8.5 KiB
Python
"""
|
||
Celery задачи для пользователей.
|
||
"""
|
||
from celery import shared_task
|
||
from django.core.mail import send_mail, EmailMultiAlternatives
|
||
from django.conf import settings
|
||
from django.template.loader import render_to_string
|
||
from django.utils.html import strip_tags
|
||
import logging
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
@shared_task
|
||
def send_welcome_email_task(user_id):
|
||
"""Отправка приветственного письма новому пользователю."""
|
||
from .models import User
|
||
|
||
try:
|
||
user = User.objects.get(id=user_id)
|
||
|
||
subject = 'Добро пожаловать на платформу!'
|
||
|
||
# Контекст для шаблона
|
||
context = {
|
||
'user_full_name': user.get_full_name() or user.email,
|
||
'user_email': user.email,
|
||
'login_url': f"{settings.FRONTEND_URL}/auth/jwt/sign-in",
|
||
}
|
||
|
||
# Загружаем HTML и текстовые шаблоны
|
||
html_message = render_to_string('emails/welcome.html', context)
|
||
plain_message = render_to_string('emails/welcome.txt', context)
|
||
|
||
# Используем EmailMultiAlternatives для HTML писем
|
||
msg = EmailMultiAlternatives(
|
||
subject=subject,
|
||
body=plain_message,
|
||
from_email=settings.DEFAULT_FROM_EMAIL,
|
||
to=[user.email]
|
||
)
|
||
msg.attach_alternative(html_message, "text/html")
|
||
msg.send()
|
||
|
||
logger.info(f'Welcome email sent to {user.email}')
|
||
return f'Welcome email sent to {user.email}'
|
||
except User.DoesNotExist:
|
||
logger.error(f'User {user_id} not found')
|
||
return f'User {user_id} not found'
|
||
except Exception as e:
|
||
logger.error(f'Error sending welcome email: {str(e)}', exc_info=True)
|
||
return f'Error sending welcome email: {str(e)}'
|
||
|
||
|
||
@shared_task
|
||
def send_verification_email_task(user_id, verification_token):
|
||
"""Отправка письма с подтверждением email."""
|
||
from .models import User
|
||
|
||
try:
|
||
user = User.objects.get(id=user_id)
|
||
|
||
# URL для подтверждения
|
||
verification_url = f"{settings.FRONTEND_URL}/auth/jwt/verify-email?token={verification_token}"
|
||
|
||
subject = 'Подтвердите ваш email'
|
||
|
||
# Контекст для шаблона
|
||
context = {
|
||
'user_full_name': user.get_full_name() or user.email,
|
||
'verification_url': verification_url,
|
||
}
|
||
|
||
# Загружаем HTML и текстовые шаблоны
|
||
html_message = render_to_string('emails/verification.html', context)
|
||
plain_message = render_to_string('emails/verification.txt', context)
|
||
|
||
msg = EmailMultiAlternatives(
|
||
subject=subject,
|
||
body=plain_message,
|
||
from_email=settings.DEFAULT_FROM_EMAIL,
|
||
to=[user.email]
|
||
)
|
||
msg.attach_alternative(html_message, "text/html")
|
||
msg.send()
|
||
|
||
logger.info(f'Verification email sent to {user.email}')
|
||
return f'Verification email sent to {user.email}'
|
||
except User.DoesNotExist:
|
||
logger.error(f'User {user_id} not found')
|
||
return f'User {user_id} not found'
|
||
except Exception as e:
|
||
logger.error(f'Error sending verification email: {str(e)}', exc_info=True)
|
||
return f'Error sending verification email: {str(e)}'
|
||
|
||
|
||
@shared_task
|
||
def send_password_reset_email_task(user_id, reset_token):
|
||
"""Отправка письма для восстановления пароля."""
|
||
from .models import User
|
||
|
||
try:
|
||
user = User.objects.get(id=user_id)
|
||
|
||
# URL для сброса пароля
|
||
reset_url = f"{settings.FRONTEND_URL}/auth/jwt/reset-password?token={reset_token}"
|
||
|
||
subject = 'Восстановление пароля'
|
||
|
||
# Контекст для шаблона
|
||
context = {
|
||
'user_full_name': user.get_full_name() or user.email,
|
||
'reset_url': reset_url,
|
||
}
|
||
|
||
# Загружаем HTML и текстовые шаблоны
|
||
html_message = render_to_string('emails/password_reset.html', context)
|
||
plain_message = render_to_string('emails/password_reset.txt', context)
|
||
|
||
msg = EmailMultiAlternatives(
|
||
subject=subject,
|
||
body=plain_message,
|
||
from_email=settings.DEFAULT_FROM_EMAIL,
|
||
to=[user.email]
|
||
)
|
||
msg.attach_alternative(html_message, "text/html")
|
||
msg.send()
|
||
|
||
logger.info(f'Password reset email sent to {user.email}')
|
||
return f'Password reset email sent to {user.email}'
|
||
except User.DoesNotExist:
|
||
logger.error(f'User {user_id} not found')
|
||
return f'User {user_id} not found'
|
||
except Exception as e:
|
||
logger.error(f'Error sending password reset email: {str(e)}', exc_info=True)
|
||
return f'Error sending password reset email: {str(e)}'
|
||
|
||
|
||
@shared_task
|
||
def send_student_welcome_email_task(user_id, reset_token):
|
||
"""Отправка приветственного письма новому студенту с ссылкой на установку пароля."""
|
||
from .models import User
|
||
|
||
try:
|
||
user = User.objects.get(id=user_id)
|
||
|
||
# URL для установки пароля
|
||
set_password_url = f"{settings.FRONTEND_URL}/auth/jwt/reset-password?token={reset_token}"
|
||
|
||
subject = 'Добро пожаловать на платформу!'
|
||
|
||
# Контекст для шаблона
|
||
context = {
|
||
'user_full_name': user.get_full_name() or user.email,
|
||
'user_email': user.email,
|
||
'set_password_url': set_password_url,
|
||
}
|
||
|
||
# Загружаем HTML и текстовые шаблоны
|
||
html_message = render_to_string('emails/student_welcome.html', context)
|
||
plain_message = render_to_string('emails/student_welcome.txt', context)
|
||
|
||
msg = EmailMultiAlternatives(
|
||
subject=subject,
|
||
body=plain_message,
|
||
from_email=settings.DEFAULT_FROM_EMAIL,
|
||
to=[user.email]
|
||
)
|
||
msg.attach_alternative(html_message, "text/html")
|
||
msg.send()
|
||
|
||
logger.info(f'Student welcome email sent to {user.email}')
|
||
return f'Student welcome email sent to {user.email}'
|
||
except User.DoesNotExist:
|
||
logger.error(f'User {user_id} not found')
|
||
return f'User {user_id} not found'
|
||
except Exception as e:
|
||
logger.error(f'Error sending student welcome email: {str(e)}', exc_info=True)
|
||
return f'Error sending student welcome email: {str(e)}'
|
||
|
||
|
||
@shared_task
|
||
def send_mentor_invitation_email_task(connection_id, set_password_url=None):
|
||
"""Отправка письма приглашения от ментора: подтвердить приглашение (и при необходимости установить пароль)."""
|
||
from .models import MentorStudentConnection
|
||
|
||
try:
|
||
conn = MentorStudentConnection.objects.select_related('mentor', 'student').get(id=connection_id)
|
||
confirm_url = (f"{settings.FRONTEND_URL}/invitation/confirm?token={conn.confirm_token}" if conn.confirm_token else None)
|
||
subject = 'Вас пригласили в качестве ученика'
|
||
context = {
|
||
'mentor_name': conn.mentor.get_full_name() or conn.mentor.email,
|
||
'student_email': conn.student.email,
|
||
'confirm_url': confirm_url,
|
||
'set_password_url': set_password_url or None,
|
||
}
|
||
html_message = render_to_string('emails/mentor_invitation.html', context)
|
||
plain_message = render_to_string('emails/mentor_invitation.txt', context)
|
||
msg = EmailMultiAlternatives(
|
||
subject=subject,
|
||
body=plain_message,
|
||
from_email=settings.DEFAULT_FROM_EMAIL,
|
||
to=[conn.student.email],
|
||
)
|
||
msg.attach_alternative(html_message, "text/html")
|
||
msg.send()
|
||
logger.info(f'Mentor invitation email sent to {conn.student.email}')
|
||
return f'Mentor invitation email sent to {conn.student.email}'
|
||
except MentorStudentConnection.DoesNotExist:
|
||
logger.error(f'Connection {connection_id} not found')
|
||
return f'Connection {connection_id} not found'
|
||
except Exception as e:
|
||
logger.error(f'Error sending mentor invitation email: {str(e)}', exc_info=True)
|
||
return f'Error sending mentor invitation email: {str(e)}'
|