cmsmanage/tasks/management/commands/sendNotifications.py

63 lines
2.4 KiB
Python

from itertools import groupby
from django.core.mail import send_mail
from django.core.management.base import BaseCommand, CommandError
from django.template import loader
from tasks.models import Tool, Task, Event, GroupToolSubscription, GroupTaskSubscription
class Command(BaseCommand):
help = 'Sends any notifications for upcoming and overdue tasks'
def _active_task_subscriptions(self):
for subscription in GroupTaskSubscription.objects.all():
if subscription.should_remind:
yield subscription
for tool_subscription in GroupToolSubscription.objects.all():
for subscription in tool_subscription.get_task_subscriptions():
if subscription.should_remind:
yield subscription
def _expand_group_subscriptions_to_users(self, subscriptions):
out = {}
for subscription in subscriptions:
for user in subscription.group.user_set.all():
if user not in out:
out[user] = []
out[user].append(subscription)
return {
user: sorted(subscriptions, key=lambda r: r.task.next_recurrence)
for user, subscriptions in out.items()
}
def handle(self, *args, **options):
template = loader.get_template('tasks/notificationEmail.txt.dtl')
group_subscriptions = self._active_task_subscriptions()
subscriptions_per_user = self._expand_group_subscriptions_to_users(group_subscriptions)
for user, subscriptions in subscriptions_per_user.items():
if not user.email:
self.stdout.write(self.style.ERROR(
f"Can't send email, user '{user}' is missing an email address"))
continue
self.stdout.write(self.style.SUCCESS(
f'Sending notification for {len(subscriptions)} task(s) to {user}'))
try:
send_mail(
subject=f'[CMS Tool Maintenance] {len(subscriptions)} tasks are upcoming or overdue!',
message=template.render({'subscriptions': subscriptions}).strip(),
from_email='adam@adamgoldsmith.name',
recipient_list=[user.email],
fail_silently=False
)
except Exception as e:
self.stdout.write(self.style.ERROR(
f"Failed to send mail for user '{user}': {type(e).__name__}: {e}"))