149 lines
5.7 KiB
Python
149 lines
5.7 KiB
Python
from background_task import background
|
||
from django.conf import settings
|
||
from celery import shared_task
|
||
from django.core.mail import send_mail
|
||
from django.template.loader import render_to_string
|
||
from django.utils.html import strip_tags
|
||
from django.contrib.auth import get_user_model
|
||
import logging
|
||
|
||
|
||
logger = logging.getLogger(__name__)
|
||
User = get_user_model()
|
||
|
||
@background(schedule=0)
|
||
def send_order_notification_background(order_id):
|
||
"""Асинхронная отправка уведомлений о заказе через background-tasks."""
|
||
from .utils.email_notifications import send_order_notification
|
||
from products.models import Order
|
||
try:
|
||
order = Order.objects.select_related('product', 'configuration').get(id=order_id)
|
||
success = send_order_notification(order)
|
||
if success:
|
||
order.notification_sent = True
|
||
order.save(update_fields=['notification_sent'])
|
||
return success
|
||
except Order.DoesNotExist:
|
||
logger.error(f"Order #{order_id} not found")
|
||
return False
|
||
|
||
@background(schedule=0)
|
||
def send_multiple_order_notifications_background(order_ids):
|
||
"""Отправка уведомлений для нескольких заказов."""
|
||
from .utils.email_notifications import send_multiple_order_notifications
|
||
from products.models import Order
|
||
orders = Order.objects.filter(id__in=order_ids)
|
||
return send_multiple_order_notifications(orders)
|
||
|
||
try:
|
||
from celery import shared_task
|
||
except ImportError:
|
||
shared_task = None
|
||
|
||
if shared_task is not None:
|
||
@shared_task
|
||
def send_order_notification_celery(order_id):
|
||
from .utils.email_notifications import send_order_notification
|
||
from products.models import Order
|
||
try:
|
||
order = Order.objects.select_related('product', 'configuration').get(id=order_id)
|
||
success = send_order_notification(order)
|
||
if success:
|
||
order.notification_sent = True
|
||
order.save(update_fields=['notification_sent'])
|
||
return success
|
||
except Order.DoesNotExist:
|
||
return False
|
||
|
||
@shared_task
|
||
def send_multiple_order_notifications_celery(order_ids):
|
||
from .utils.email_notifications import send_multiple_order_notifications
|
||
from products.models import Order
|
||
orders = Order.objects.filter(id__in=order_ids)
|
||
return send_multiple_order_notifications(orders)
|
||
|
||
|
||
@shared_task
|
||
def send_new_article_notification(article_id):
|
||
"""Отправка уведомлений подписчикам о новой статье."""
|
||
from blog.models import Article
|
||
from programmer.models import Profile
|
||
|
||
try:
|
||
article = Article.objects.select_related('category', 'author').get(id=article_id, is_published=True)
|
||
except Article.DoesNotExist:
|
||
logger.error(f"Article #{article_id} not found or not published")
|
||
return
|
||
|
||
# Получаем email-адреса пользователей, подписанных на новые статьи
|
||
profiles = Profile.objects.filter(notify_new_articles=True, user__is_active=True)
|
||
emails = [p.user.email for p in profiles if p.user.email]
|
||
|
||
if not emails:
|
||
logger.info(f"No subscribers for new articles, skipping notification for article #{article_id}")
|
||
return
|
||
|
||
subject = f'📰 Новая статья: {article.title}'
|
||
context = {
|
||
'article': article,
|
||
'site_url': settings.ALLOWED_HOSTS[0] if settings.ALLOWED_HOSTS else 'localhost',
|
||
'site_name': 'С.Н.А. Технологии',
|
||
}
|
||
html_message = render_to_string('emails/new_article_notification.html', context)
|
||
plain_message = strip_tags(html_message)
|
||
|
||
try:
|
||
send_mail(
|
||
subject=subject,
|
||
message=plain_message,
|
||
from_email=settings.DEFAULT_FROM_EMAIL,
|
||
recipient_list=emails,
|
||
html_message=html_message,
|
||
fail_silently=False,
|
||
)
|
||
logger.info(f"New article notification sent to {len(emails)} subscribers for article #{article_id}")
|
||
except Exception as e:
|
||
logger.error(f"Failed to send new article notification for article #{article_id}: {e}")
|
||
|
||
|
||
@shared_task
|
||
def send_new_product_notification(product_id):
|
||
"""Отправка уведомлений подписчикам о новом продукте."""
|
||
from products.models import Product
|
||
from programmer.models import Profile
|
||
|
||
try:
|
||
product = Product.objects.select_related('category').get(id=product_id, is_published=True)
|
||
except Product.DoesNotExist:
|
||
logger.error(f"Product #{product_id} not found or not published")
|
||
return
|
||
|
||
profiles = Profile.objects.filter(notify_new_products=True, user__is_active=True)
|
||
emails = [p.user.email for p in profiles if p.user.email]
|
||
|
||
if not emails:
|
||
logger.info(f"No subscribers for new products, skipping notification for product #{product_id}")
|
||
return
|
||
|
||
subject = f'🛒 Новый продукт: {product.title}'
|
||
context = {
|
||
'product': product,
|
||
'site_url': settings.ALLOWED_HOSTS[0] if settings.ALLOWED_HOSTS else 'localhost',
|
||
'site_name': 'С.Н.А. Технологии',
|
||
}
|
||
html_message = render_to_string('emails/new_product_notification.html', context)
|
||
plain_message = strip_tags(html_message)
|
||
|
||
try:
|
||
send_mail(
|
||
subject=subject,
|
||
message=plain_message,
|
||
from_email=settings.DEFAULT_FROM_EMAIL,
|
||
recipient_list=emails,
|
||
html_message=html_message,
|
||
fail_silently=False,
|
||
)
|
||
logger.info(f"New product notification sent to {len(emails)} subscribers for product #{product_id}")
|
||
except Exception as e:
|
||
logger.error(f"Failed to send new product notification for product #{product_id}: {e}")
|