from notify.notification import Notification from notify.service import NotificationService from sqlalchemy import asc from tasks import Session from tasks.decorators import background from tasks.Models import NotificationEmailData import os @background def notify(execute_flag): # If True mails are sent normaly # If False mails are not sent. Used to avoid sending mails for jobs that # have been completed a long time ago. Use this if you implement notify # into an already existing nopaque instance. Change it to True after the # daemon has run one time with the flag set to False. # Initialize notification service notification_service = NotificationService(execute_flag) notification_service.get_smtp_configs() notification_service.set_server() # create notifications (content, recipient etc.) notifications = __create_mail_notifications(notification_service) # only login and send mails if there are any notifications if (len(notifications) > 0): try: notification_service.login() # combine new and unsent notifications notifications.update(notification_service.not_sent) # send all notifications __send_mail_notifications(notifications, notification_service) # remove unsent notifications because they have been sent now # but only if mail limit has not been exceeded if (notification_service.mail_limit_exceeded is not True): notification_service.not_sent = {} notification_service.quit() except Exception as e: notification_service.not_sent.update(notifications) notification_service.quit() # Email notification functions def __create_mail_notifications(notification_service): mn_session = Session() notification_email_data = mn_session.query(NotificationEmailData).order_by(asc(NotificationEmailData.creation_date)).all() notifications = {} for data in notification_email_data: notification = Notification() notification.set_addresses(notification_service.email_address, data.job.user.email) subject_template = '[nopaque] Status update for your Job/Corpora: {title}!' subject_template_values_dict = {'title': data.job.title} protocol = os.environ.get('NOPAQUE_PROTOCOL') domain = os.environ.get('NOPAQUE_DOMAIN') url = '{protocol}://{domain}/{jobs}/{id}'.format( protocol=protocol, domain=domain, jobs='jobs', id=data.job.id) body_template_values_dict = {'username': data.job.user.username, 'id': data.job.id, 'title': data.job.title, 'status': data.notify_status, 'time': data.creation_date, 'url': url} txt_tmplt = 'notify/templates/notification_messages/notification.txt' html_tmplt = 'notify/templates/notification_messages/notification.html' notification.set_notification_content(subject_template, subject_template_values_dict, txt_tmplt, html_tmplt, body_template_values_dict) notifications[data.job.id] = notification # Using a dictionary for notifications avoids sending multiple mails # if the status of a job changes in a few seconds. The user will not # get swamped with mails for queued, running and complete if those # happen in in a few seconds. Only the last update will be sent. # This depends on the sleep time interval though. mn_session.delete(data) mn_session.commit() Session.remove() return notifications def __send_mail_notifications(notifications, notification_service): for key, notification in notifications.items(): try: notification_service.send(notification) notification_service.mail_limit_exceeded = False except Exception as e: # Adds notifications to unsent if mail server exceded limit for # consecutive mail sending notification_service.not_sent[key] = notification notification_service.mail_limit_exceeded = True