import calendar import sys from email.utils import formatdate from apscheduler.schedulers.background import BackgroundScheduler from datetime import datetime, timedelta from data import model class ExpirationScheduler(object): def __init__(self, utc_create_notifications_date, utc_terminate_processes_date): self._scheduler = BackgroundScheduler() self._termination_date = utc_terminate_processes_date soon = datetime.now() + timedelta(seconds=1) if utc_create_notifications_date > datetime.utcnow(): self._scheduler.add_job(model.delete_all_notifications_by_kind, 'date', run_date=soon, args=['expiring_license']) local_notifications_date = self._utc_to_local(utc_create_notifications_date) self._scheduler.add_job(self._generate_notifications, 'date', run_date=local_notifications_date) else: self._scheduler.add_job(self._generate_notifications, 'date', run_date=soon) local_termination_date = self._utc_to_local(utc_terminate_processes_date) self._scheduler.add_job(self._terminate, 'date', run_date=local_termination_date) @staticmethod def _format_date(date): """ Output an RFC822 date format. """ if date is None: return None return formatdate(calendar.timegm(date.utctimetuple())) @staticmethod def _utc_to_local(utc_dt): # get integer timestamp to avoid precision lost timestamp = calendar.timegm(utc_dt.timetuple()) local_dt = datetime.fromtimestamp(timestamp) return local_dt.replace(microsecond=utc_dt.microsecond) def _generate_notifications(self): for user in model.get_active_users(): model.create_unique_notification('expiring_license', user, {'expires_at': self._format_date(self._termination_date)}) @staticmethod def _terminate(): sys.exit(1) def start(self): self._scheduler.start()