aboutsummaryrefslogtreecommitdiffstats
path: root/src/notifier/manager.py
diff options
context:
space:
mode:
authorParker Berberian <pberberian@iol.unh.edu>2018-10-24 15:12:32 -0400
committerParker Berberian <pberberian@iol.unh.edu>2018-11-07 10:32:56 -0500
commit7b15aed77c6675286fd75b8832af58c992717ef9 (patch)
treef4597f72433ce75ab46a1fd80f3635c987b38205 /src/notifier/manager.py
parentebc42347105caa2be52a8337372ae4793fe9182c (diff)
Rewrite Notification subsystem
In this commit: - delete a lot of really bad and / or unused code - redesign a much simpler Notification model - create and send notifications to the user's inbox on booking start & end - migrations - emails user when booking is ready and when it ends Not in this commit: - Creating notifications from lab messages - warning messages when a booking is about to end - creating "summary" notifications when e.g. a booking has been fulfilled by a lab Change-Id: I69b4dc36c3f2bce76d810106baadeef5a562cc7d Signed-off-by: Parker Berberian <pberberian@iol.unh.edu>
Diffstat (limited to 'src/notifier/manager.py')
-rw-r--r--src/notifier/manager.py181
1 files changed, 104 insertions, 77 deletions
diff --git a/src/notifier/manager.py b/src/notifier/manager.py
index a705d00..cc1aa16 100644
--- a/src/notifier/manager.py
+++ b/src/notifier/manager.py
@@ -1,98 +1,125 @@
##############################################################################
-# Copyright (c) 2018 Sawyer Bergeron and others.
+# Copyright (c) 2018 Parker Berberian, Sawyer Bergeron and others.
#
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Apache License, Version 2.0
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
+import os
+from notifier.models import Notification
-from booking.models import *
-from notifier.models import Notifier, MetaBooking, LabMessage
-from django.utils import timezone
-from datetime import timedelta
-from django.template import Template, Context
-from account.models import UserProfile
+from django.core.mail import send_mail
+from django.template.loader import render_to_string
-from django.db import models
-class NotifyPeriodic(object):
- def task():
- bookings_new = Booking.objects.filter(metabooking__isnull=True)
- bookings_old = Booking.objects.filter(end__lte=timezone.now() + timedelta(hours=24)).filter(metabooking__ended_notified=False)
+class NotificationHandler(object):
- for booking in bookings_old:
- metabooking = booking.metabooking
- if booking.end <= timezone.now() + timedelta(hours=24):
- if not metabooking.ending_notified:
- Notify().notify(Notify.TOCLEAN, booking)
- metabooking.ending_notified = True
- metabooking.save()
- if booking.end <= timezone.now():
- metabooking = booking.metabooking
- if not metabooking.ended_notified:
- Notify().notify(Notify.CLEANED, booking)
- metabooking.ended_notified = True
- metabooking.save()
+ @classmethod
+ def notify_new_booking(cls, booking):
+ template = "notifier/new_booking.html"
+ titles = ["You have a new Booking", "You have been added to a Booking"]
+ cls.booking_notify(booking, template, titles)
- for booking in bookings_new:
- metabooking = MetaBooking()
- metabooking.booking = booking
- metabooking.created_notified = True
- metabooking.save()
+ @classmethod
+ def notify_booking_end(cls, booking):
+ template = "notifier/end_booking.html"
+ titles = ["Your booking has ended", "A booking you collaborate on has ended"]
+ cls.booking_notify(booking, template, titles)
- Notify().notify(Notify.CREATED, booking)
+ @classmethod
+ def booking_notify(cls, booking, template, titles):
+ """
+ Creates a notification for a booking owner and collaborators
+ using the template.
+ titles is a list - the first is the title for the owner's notification,
+ the last is the title for the collaborators'
+ """
+ owner_notif = Notification.objects.create(
+ title=titles[0],
+ content=render_to_string(template, context={
+ "booking": booking,
+ "owner": True
+ })
+ )
+ owner_notif.recipients.add(booking.owner)
+ if not booking.collaborators.all().exists():
+ return # no collaborators - were done
+ collab_notif = Notification.objects.create(
+ title=titles[-1],
+ content=render_to_string(template, context={
+ "booking": booking,
+ "owner": False
+ })
+ )
+ for c in booking.collaborators.all():
+ collab_notif.recipients.add(c)
-class Notify(object):
+ @classmethod
+ def email_job_fulfilled(cls, job):
+ template_name = "notifier/email_fulfilled.txt"
+ all_tasks = job.get_tasklist()
+ users = list(job.booking.collaborators.all())
+ users.append(job.booking.owner)
+ for user in users:
+ user_tasklist = []
+ # gather up all the relevant messages from the lab
+ for task in all_tasks:
+ if (not hasattr(task, "user")) or task.user == user:
+ user_tasklist.append({
+ "title": task.type_str + " Message: ",
+ "content": task.message
+ })
+ # gather up all the other needed info
+ context = {
+ "user_name": user.userprofile.full_name,
+ "messages": user_tasklist,
+ "booking_url": os.environ.get("DASHBOARD_URL", "<Dashboard url>") + "/booking/detail/" + str(job.booking.id) + "/"
+ }
- CREATED = "created"
- TOCLEAN = "toclean"
- CLEANED = "cleaned"
+ # render email template
+ message = render_to_string(template_name, context)
- TITLES = {}
- TITLES["created"] = "Your booking has been confirmed"
- TITLES["toclean"] = "Your booking is ending soon"
- TITLES["cleaned"] = "Your booking has ended"
+ # finally, send the email
+ send_mail(
+ "Your Booking is Ready",
+ message,
+ os.environ.get("DEFAULT_FROM_EMAIL", "opnfv@pharos-dashboard"),
+ user.userprofile.email_addr,
+ fail_silently=False
+ )
- """
- Lab message is provided with the following context elements:
- * if is for owner or for collaborator (if owner)
- * recipient username (<owner, collaborator>.username)
- * recipient full name (<owner, collaborator>.userprofile.full_name)
- * booking it pertains to (booking)
- * status message should convey (currently "created", "toclean" and "cleaned" as strings)
- It should be a django template that can be rendered with these context elements
- and should generally use all of them in one way or another.
- It should be applicable to email, the web based general view, and should be scalable for
- all device formats across those mediums.
- """
- def notify(self, notifier_type, booking):
- template = Template(LabMessage.objects.filter(lab=booking.lab).first().msg)
+ @classmethod
+ def email_booking_over(cls, booking):
+ template_name = "notifier/email_ended.txt"
+ hostnames = [host.template.resource.name for host in booking.resource.hosts.all()]
+ users = list(booking.collaborators.all())
+ users.append(booking.owner)
+ for user in users:
+ context = {
+ "user_name": user.userprofile.full_name,
+ "booking": booking,
+ "hosts": hostnames,
+ "booking_url": os.environ.get("DASHBOARD_URL", "<Dashboard url>") + "/booking/detail/" + str(booking.id) + "/"
+ }
- context = {}
- context["owner"] = booking.owner
- context["notify_type"] = notifier_type
- context["booking"] = booking
- message = template.render(Context(context))
- notifier = Notifier()
- notifier.title = self.TITLES[notifier_type]
- notifier.content = message
- notifier.user = booking.owner.userprofile
- notifier.sender = str(booking.lab)
- notifier.save()
- notifier.send()
+ message = render_to_string(template_name, context)
+ send_mail(
+ "Your Booking has Expired",
+ message,
+ os.environ.get("DEFAULT_FROM_EMAIL", "opnfv@pharos-dashboard"),
+ user.userprofile.email_addr,
+ fail_silently=False
+ )
- context["owner"] = False
-
- for user in booking.collaborators.all():
- context["collaborator"] = user
- message = template.render(Context(context))
- notifier = Notifier()
- notifier.title = self.TITLES[notifier_type]
- notifier.content = message
- notifier.user = UserProfile.objects.get(user=user)
- notifier.sender = str(booking.lab)
- notifier.save()
- notifier.send()
+ @classmethod
+ def task_updated(cls, task):
+ """
+ called every time a lab updated info about a task.
+ currently only checks if the job is now done so I can send an email,
+ may add more functionality later
+ """
+ if task.job.is_fulfilled():
+ cls.email_job_fulfilled(task.job)