def create_run(job_uid, user=None): """ This will create a new Run based on the provided job uid. :param job_uid: The UID to reference the Job model. :return: An ExportRun object. """ # start the run try: # https://docs.djangoproject.com/en/1.10/topics/db/transactions/#django.db.transaction.atomic # enforce max runs with transaction.atomic(): max_runs = settings.EXPORT_MAX_RUNS # get the number of existing runs for this job job = Job.objects.get(uid=job_uid) if not job.provider_tasks.all(): raise Error( "This job does not have any data sources or formats associated with it, " "try cloning the job or submitting a new request.") invalid_licenses = get_invalid_licenses(job) if invalid_licenses: raise InvalidLicense("The user: {0} has not agreed to the following licenses: {1}.\n" \ "Please use the user account page, or the user api to agree to the " \ "licenses prior to exporting the data.".format(job.user.username, invalid_licenses)) if not user: user = job.user perms, job_ids = JobPermission.userjobs( user, JobPermissionLevel.ADMIN.value) if not job.id in job_ids: raise Unauthorized( "The user: {0} is not authorized to create a run based on the job: {1}." .format(job.user.username, job.name)) run_count = job.runs.filter(deleted=False).count() if run_count > 0: while run_count > max_runs - 1: # delete the earliest runs job.runs.filter(deleted=False).earliest( field_name='started_at').soft_delete(user=user) run_count -= 1 # add the export run to the database run = ExportRun.objects.create( job=job, user=user, status='SUBMITTED', expiration=(timezone.now() + timezone.timedelta(days=14))) # persist the run job.last_export_run = run job.save() sendnotification(run, run.user, NotificationVerb.RUN_STARTED.value, None, None, NotificationLevel.INFO.value, '') run_uid = run.uid logger.debug('Saved run with id: {0}'.format(str(run_uid))) return run_uid except DatabaseError as e: logger.error('Error saving export run: {0}'.format(e)) raise e
def soft_delete_notifications(self, *args, **kwargs): permissions = kwargs.get('permissions') if permissions: users = get_all_users_by_permissions(permissions) logger.error("users: {0}".format(users)) for user in users: logger.error("Sending notification to {0}".format(user)) sendnotification(self, user, NotificationVerb.RUN_DELETED.value, None, None, NotificationLevel.WARNING.value, getattr(self, "status", "DELETED"))
def create_run(job_uid, user=None): """ This will create a new Run based on the provided job uid. :param job_uid: The UID to reference the Job model. :return: An ExportRun object. """ # start the run try: # https://docs.djangoproject.com/en/1.10/topics/db/transactions/#django.db.transaction.atomic # enforce max runs with transaction.atomic(): max_runs = settings.EXPORT_MAX_RUNS # get the number of existing runs for this job job = Job.objects.get(uid=job_uid) if not job.provider_tasks.all(): raise Error("This job does not have any data sources or formats associated with it, " "try cloning the job or submitting a new request.") invalid_licenses = get_invalid_licenses(job) if invalid_licenses: raise InvalidLicense("The user: {0} has not agreed to the following licenses: {1}.\n" \ "Please use the user account page, or the user api to agree to the " \ "licenses prior to exporting the data.".format(job.user.username, invalid_licenses)) if not user: user = job.user perms, job_ids = JobPermission.userjobs(user, JobPermissionLevel.ADMIN.value) if not job.id in job_ids: raise Unauthorized("The user: {0} is not authorized to create a run based on the job: {1}.".format( job.user.username, job.name )) run_count = job.runs.filter(deleted=False).count() if run_count > 0: while run_count > max_runs - 1: # delete the earliest runs job.runs.filter(deleted=False).earliest(field_name='started_at').soft_delete(user=user) run_count -= 1 # add the export run to the database run = ExportRun.objects.create(job=job, user=user, status='SUBMITTED', expiration=(timezone.now() + timezone.timedelta(days=14))) # persist the run job.last_export_run = run job.save() sendnotification(run, run.user, NotificationVerb.RUN_STARTED.value, None, None, NotificationLevel.INFO.value, '') run_uid = run.uid logger.debug('Saved run with id: {0}'.format(str(run_uid))) return run_uid except DatabaseError as e: logger.error('Error saving export run: {0}'.format(e)) raise e
def test_send(self, ): memo = "Note to myself" level = NotificationLevel.SUCCESS.value verb = NotificationVerb.REMOVED_FROM_GROUP.value sendnotification(self.user1, self.user1, verb, None, None, level, memo) url = '/api/notifications' response = self.client.get(url, content_type='application/json; version=1.0') self.assertEqual(status.HTTP_200_OK, response.status_code) self.assertEqual(len(response.data),1) self.assertEqual(response.data[0]["description"],memo) self.assertEqual(response.data[0]["level"],level) self.assertEqual(response.data[0]["verb"],verb)
def test_send(self): memo = "Note to myself" level = NotificationLevel.SUCCESS.value verb = NotificationVerb.REMOVED_FROM_GROUP.value sendnotification(self.user1, self.user1, verb, None, None, level, memo) url = "/api/notifications" response = self.client.get( url, content_type="application/json; version=1.0") self.assertEqual(status.HTTP_200_OK, response.status_code) self.assertEqual(len(response.data), 1) self.assertEqual(response.data[0]["description"], memo) self.assertEqual(response.data[0]["level"], level) self.assertEqual(response.data[0]["verb"], verb)
def create_run(job: Job, user: User = None, clone: ExportRun = None, download_data=True): """ This will create a new Run based on the provided job. :param job: The Job model on which to create a new run. :param user: The user creating the run. :param clone: The run to clone, 'None' if not cloning. :param download_data: boolean value to indicate whether or not to download data. :return: An ExportRun object. """ # start the run try: # https://docs.djangoproject.com/en/1.10/topics/db/transactions/#django.db.transaction.atomic # enforce max runs with transaction.atomic(): job, user = check_job_permissions(job, user) if clone: run = clone.clone(download_data=download_data) run.status = TaskState.SUBMITTED.value run.save() job.last_export_run = run job.save() else: # add the export run to the database run = ExportRun.objects.create( job=job, user=user, status=TaskState.SUBMITTED.value, expiration=(timezone.now() + timezone.timedelta(days=14)), ) # persist the run job.last_export_run = run job.save() sendnotification( run, run.user, NotificationVerb.RUN_STARTED.value, None, None, NotificationLevel.INFO.value, "" ) logger.debug("Saved run with id: {0}".format(str(run.uid))) return run.uid except DatabaseError as e: logger.error("Error saving export run: {0}".format(e)) raise e
def expire_runs_task(): """ Checks all runs. Expires all runs older than 2 weeks, Emails users one week before scheduled expiration time and 2 days before schedule expiration time. """ from eventkit_cloud.tasks.models import ExportRun site_url = getattr(settings, "SITE_URL") runs = ExportRun.objects.filter(deleted=False) for run in runs: expiration = run.expiration email = run.user.email uid = run.job.uid url = "{0}/status/{1}".format(site_url.rstrip("/"), uid) notified = run.notified now = timezone.now() # if expired delete the run: if expiration <= now: run.soft_delete() # if two days left and most recent notification was at the 7 day mark email user elif expiration - now <= timezone.timedelta(days=2): if not notified or (notified and notified < expiration - timezone.timedelta(days=2)): sendnotification( run, run.job.user, NotificationVerb.RUN_EXPIRING.value, None, None, NotificationLevel.WARNING.value, run.status, ) if email: send_warning_email(date=expiration, url=url, addr=email, job_name=run.job.name) run.notified = now run.save() # if one week left and no notification yet email the user elif expiration - now <= timezone.timedelta(days=7) and not notified: sendnotification( run, run.job.user, NotificationVerb.RUN_EXPIRING.value, None, None, NotificationLevel.WARNING.value, run.status, ) if email: send_warning_email(date=expiration, url=url, addr=email, job_name=run.job.name) run.notified = now run.save()