def on_failure(self, exc, task_id, args, kwargs, einfo): if isinstance(exc, SkipException): return None doc_id = args[0] print("Document {} failed.".format(doc_id)) document = Document.objects.get(id=doc_id) document.state = "ERROR" document.save() # Notify the uploader Notification.direct( user=document.user, text="Une erreur c'est produite pendant la conversion de : {}".format( document.name), node=document.parent, url=reverse('node_canonic', args=[document.parent.id]), icon="x", ) # Warn the admins DocumentError.objects.create( document=document, task_id=task_id, exception=exc, traceback=einfo.traceback, )
def pre_document_save(**kwargs): assert kwargs['sender'] == models.Document document = kwargs['instance'] try: old_doc = models.Document.objects.get(pk=document.pk) except models.Document.DoesNotExist: # New Document => do nothing pass else: if not old_doc.state == document.state: # State changed if document.state == 'DONE': Notification.direct(user=document.user, text='Conversion de "{}" terminée'.format( document.name), node=document, url=reverse('document_show', args=[document.id]), icon="check") PreNotification.objects.create( node=document, text="Nouveau document : {} dans {}".format( document.name, document.parent.slug), url=reverse('document_show', args=[document.id]), user=document.user, sender_type="Document", icon="page-copy") else: # State not changed => do nothing pass
def on_failure(self, exc, task_id, args, kwargs, einfo): if isinstance(exc, SkipException): return None doc_id = args[0] print("Document {} failed.".format(doc_id)) document = Document.objects.get(id=doc_id) document.state = "ERROR" document.save() # Notify the uploader Notification.direct( user=document.user, text="Une erreur c'est produite pendant la conversion de : {}".format(document.name), node=document.parent, url=reverse('node_canonic', args=[document.parent.id]), icon="x", ) # Warn the admins DocumentError.objects.create( document=document, task_id=task_id, exception=exc, traceback=einfo.traceback, )
def checksum(self, document_id): document = Document.objects.get(pk=document_id) contents = document.original.read() hashed = hashlib.md5(contents).hexdigest() query = Document.objects.filter(md5=hashed).exclude(md5='') if query.count() != 0: dup = query.first() Notification.direct( user=document.user, text= 'Votre document "{}" a été refusé car c\'est une copie conforme de {}' .format(document.name, dup.name), node=document.parent, url=reverse('node_canonic', args=[dup.id]), icon="x", ) did = document.id document.delete() raise ExisingChecksum("Document {} has the same checksum as {}".format( did, dup.id)) else: document.md5 = hashed document.save() return document_id
def pre_document_save(**kwargs): assert kwargs['sender'] == models.Document document = kwargs['instance'] try: old_doc = models.Document.objects.get(pk=document.pk) except models.Document.DoesNotExist: # New Document => do nothing pass else: if not old_doc.state == document.state: # State changed if document.state == 'DONE': Notification.direct( user=document.user, text='Conversion de "{}" terminée'.format(document.name), node=document, url=reverse('document_show', args=[document.id]), icon="check" ) PreNotification.objects.create( node=document, text="Nouveau document : {} dans {}".format(document.name, document.parent.slug), url=reverse('document_show', args=[document.id]), user=document.user, sender_type="Document", icon="page-copy" ) else: # State not changed => do nothing pass
def user_rent_item(sender, instance, *args, **kwargs): Rent = instance recv = Rent.item sender = Rent.hirer notify = Notification(sender=sender, user=recv.owner, notification_type=1) notify.save()
def test_incoming_notification_query(self): """Test that all incoming notifications are queried""" user1 = get_user_model().objects.get(email='*****@*****.**') user2 = get_user_model().objects.get(email='*****@*****.**') list_notifications_1 = Notification.get_incoming_notifications(user1) list_notifications_2 = Notification.get_incoming_notifications(user2) self.assertEqual(list_notifications_1.count(), 1) self.assertEqual(list_notifications_2.count(), 2)
def document_delete(**kwargs): assert kwargs['sender'] == models.Document document = kwargs['instance'] if document.e: Notification.direct( user=document.user.user, text="Error when processing document: "+str(document.e), node=document.parent, url=reverse('node_canonic',args=[nodeid]), )
def post(self): form_cls = model_form(Notification) notification = Notification() form = form_cls(request.form, csrf_enabled=False) if not form.validate(): return json.dumps(form.errors, default=json_util.default), 400 form.populate_obj(notification) notification.save() data = [dict(message=notification.message, id='%s' % notification.pk)] return json.dumps({'data': data}, default=json_util.default), 201
def ping_filter(message, users, sending_user, notify_text, notify_type, notify_id=None): for user in users: if username_in_message(message, user.username): # Create notification if user == sending_user: continue note = Notification( text="{} {}: {}".format(sending_user.username, notify_text, message), user=user, from_user=sending_user, type=notify_type, identifier=notify_id, ) note.save() logger.info("Created notification for user {} from {}".format(note.user, note.from_user)) return message
def pending_document_save(**kwargs): assert kwargs['sender'] == models.PendingDocument pending = kwargs['instance'] if pending.state == 'done': # Send notification to the uploader Notification.direct( user=pending.document.user.user, text="Finished processing document "+pending.document.name, node=pending.document, url=reverse('document_show', args=[pending.document.id]) ) PreNotification.objects.create( node=pending.document, text="Nouveau document: "+pending.document.name, url=reverse('document_show', args=[pending.document.id]), user=pending.document.user.user )
def ping_filter(message, users, sending_user, notify_text, notify_type, notify_id=None): for user in users: if username_in_message(message, user.username): # Create notification if user == sending_user: continue note = Notification(text='{} {}: {}'.format( sending_user.username, notify_text, message), user=user, from_user=sending_user, type=notify_type, identifier=notify_id) note.save() logger.info("Created notification for user {} from {}".format( note.user, note.from_user)) return message
def notifications_show(request): unread_len = Notification.unread(request.user).count() s = unread_len + 20 notifs = list( Notification.objects.filter(user=request.user).order_by('read','-id').select_related('prenotif')[:s] ) read_notifs = notifs[unread_len:] notifs = notifs[:unread_len] context = {"notifications": notifs, 'read_notifications': read_notifs} return render(request, "notifications.html", context)
def checksum(self, document_id): document = Document.objects.get(pk=document_id) contents = document.original.read() hashed = hashlib.md5(contents).hexdigest() query = Document.objects.filter(md5=hashed).exclude(md5='') if query.count() != 0: dup = query.first() Notification.direct( user=document.user, text='Votre document "{}" a été refusé car c\'est une copie conforme de {}'.format(document.name, dup.name), node=document.parent, url=reverse('node_canonic', args=[dup.id]), icon="x", ) did = document.id document.delete() raise ExisingChecksum("Document {} has the same checksum as {}".format(did, dup.id)) else: document.md5 = hashed document.save() return document_id
def notifier(sender, **kwargs): recipient = kwargs.pop('recipient', None) recipient_list = kwargs.pop('recipient_list', None) verb = kwargs.pop('verb', None) description = kwargs.pop('description', None) nf_type = kwargs.pop('nf_type', 'default') actor = kwargs.pop('actor', None) actor_text = kwargs.pop('actor_text', None) actor_url = kwargs.pop('actor_url', None) target = kwargs.pop('target', None) target_text = kwargs.pop('target_text', None) target_url = kwargs.pop('target_url', None) obj = kwargs.pop('obj', None) obj_text = kwargs.pop('obj_text', None) obj_url = kwargs.pop('obj_url', None) extra = kwargs.pop('extra', None) if recipient and recipient_list: raise TypeError(_("You must specify either a single recipient or a list" " of recipients, not both.")) elif not recipient and not recipient_list: raise TypeError(_("You must specify the recipient of the notification.")) if not actor and not actor_text: raise TypeError(_("Actor not specified.")) if not verb: raise TypeError(_("Verb not specified.")) if recipient_list and not isinstance(recipient_list, list): raise TypeError(_("Supplied recipient is not an instance of list.")) if recipient: notification = Notification( recipient=recipient, verb=verb, description=description, nf_type=nf_type, actor_content_object=actor, actor_text=actor_text, actor_url_text=actor_url, target_content_object=target, target_text=target_text, target_url_text=target_url, obj_content_object=obj, obj_text=obj_text, obj_url_text=obj_url, extra=extra ) saved_notification = notification.save() else: notifications = [] for recipient in recipient_list: notifications.append(Notification( recipient=recipient, verb=verb, description=description, nf_type=nf_type, actor_content_object=actor, actor_text=actor_text, actor_url_text=actor_url, target_content_object=target, target_text=target_text, target_url_text=target_url, obj_content_object=obj, obj_text=obj_text, obj_url_text=obj_url, extra=extra )) saved_notification = Notification.objects.bulk_create(notifications) return saved_notification
def notifier(sender, **kwargs): recipient = kwargs.pop('recipient', None) recipient_list = kwargs.pop('recipient_list', None) verb = kwargs.pop('verb', None) description = kwargs.pop('description', None) nf_type = kwargs.pop('nf_type', 'default') actor = kwargs.pop('actor', None) actor_text = kwargs.pop('actor_text', None) actor_url = kwargs.pop('actor_url', None) target = kwargs.pop('target', None) target_text = kwargs.pop('target_text', None) target_url = kwargs.pop('target_url', None) obj = kwargs.pop('obj', None) obj_text = kwargs.pop('obj_text', None) obj_url = kwargs.pop('obj_url', None) extra = kwargs.pop('extra', None) actor_text = truncate( actor_text, Notification._meta.get_field('actor_text').max_length) actor_url = truncate( actor_url, Notification._meta.get_field('actor_url_text').max_length) target_text = truncate( target_text, Notification._meta.get_field('target_text').max_length) target_url = truncate( target_url, Notification._meta.get_field('target_url_text').max_length) obj_text = truncate(obj_text, Notification._meta.get_field('obj_text').max_length) obj_url = truncate(obj_url, Notification._meta.get_field('obj_url_text').max_length) if recipient and recipient_list: raise TypeError( _("You must specify either a single recipient or a list" " of recipients, not both.")) elif not recipient and not recipient_list: raise TypeError( _("You must specify the recipient of the notification.")) if not actor and not actor_text: raise TypeError(_("Actor not specified.")) if not verb: raise TypeError(_("Verb not specified.")) if recipient_list and not isinstance( recipient_list, list) and not isinstance(recipient_list, set): raise TypeError( _("Supplied recipient is not an instance of list or set.")) if recipient: notification = Notification(recipient=recipient, verb=verb, description=description, nf_type=nf_type, actor_content_object=actor, actor_text=actor_text, actor_url_text=actor_url, target_content_object=target, target_text=target_text, target_url_text=target_url, obj_content_object=obj, obj_text=obj_text, obj_url_text=obj_url, extra=extra) saved_notification = notification.save() else: notifications = [] for recipient in recipient_list: notifications.append( Notification(recipient=recipient, verb=verb, description=description, nf_type=nf_type, actor_content_object=actor, actor_text=actor_text, actor_url_text=actor_url, target_content_object=target, target_text=target_text, target_url_text=target_url, obj_content_object=obj, obj_text=obj_text, obj_url_text=obj_url, extra=extra)) saved_notification = Notification.objects.bulk_create(notifications) return saved_notification
def notifications_get(request): notifs = list(Notification.unread(request.user)) if len(notifs) < 5: notifs += list(Notification.objects.filter(user=request.user, read=True)[:(5 - len(notifs))]) return HttpResponse(dumps(jsonise_notifications(notifs)), mimetype='application/json')
def generate_notifications(): """looks through all student requests, older than 20 secs, find offline tutors and send notification if allowed and interval is OKAY """ # filter relevant student requests student_rs = StudentRequest.objects.filter( is_active=True, meeting__isnull=True, match__isnull=True, created__lte=timezone.now()-timedelta(seconds=5) ) # TODO: first step is to filter student requests that have no notifications sent yet? # next would be, filter only the ones that havent sent notifications in X seconds student_rs = student_rs.filter(Q(notifications__isnull=True) | Q(notifications__date__lte=timezone.now() - timedelta(seconds=10))).prefetch_related('user', 'subject', 'notifications').distinct() # TODO: prioritize those with longer waiting times # student_rs = student_rs.order_by( # fetch possible tutors beforehand, reducing the query complexity each step # Find matching tutors # this may need to be optimized further --> Selecting whole user table! all_tutors = CustomUser.objects.prefetch_related('tutordata').filter( tutordata__isnull=False, email_verified=True, tutordata__verified=True, notificationsettings__isnull=False) all_tutors = all_tutors.exclude(meeting__ended=False) # find those who have notifications turned on and interval is okay all_tutors = all_tutors.filter( Q(notificationsettings__enable_push=True) | Q( notificationsettings__enable_mail=True)).exclude( notification__date__gte=timezone.now() - F('notificationsettings__notify_interval')).distinct() time_range_query = Q(notificationsettings__ranges__days__contains=timezone.datetime.today().weekday(), notificationsettings__ranges__start_time__lte=timezone.now().time(), notificationsettings__ranges__end_time__gte=timezone.now().time()) # now to find those whose time is in range all_tutors = all_tutors.filter((Q(notificationsettings__ranges_mode=NotificationSettings.RANGE_ALLOW) & time_range_query) | Q( Q(notificationsettings__ranges_mode=NotificationSettings.RANGE_BLOCK) & ~time_range_query)).distinct() # don't do anything if there arent any student requests if not student_rs: return # all_tutors = list(all_tutors) for request in student_rs: # filter again for those who didn't already get a notification for the same request tutors = all_tutors.filter(tutordata__subjects=request.subject).exclude( notification__in=request.notifications.all()) # .exclude(notification__date__gte=timezone.now() - F('notificationsettings__notify_interval')).distinct() # now to find the 10 best! sorted_tutors = sorted(tutors, key=lambda tutor: calculate_user_matching_score( request, tutor))[::-1][:10] for t in sorted_tutors: notification = Notification() notification.user = t notification.type = Notification.STUDENT_REQUEST notification.title = f"{request.user.first_name} braucht deine Hilfe!" notification.body = f"Fach: {request.subject.name} in {str(request.user.studentdata.school_data)}" notification.content_object = request notification.save() notification.send()
def notifications_show(request): notifs = list(Notification.unread(request.user).order_by('-id')) read_notifs = list(Notification.objects.filter(user=request.user, read=True).order_by('-id')[:5]) context = {"notifications": notifs, 'read_notifications': read_notifs} return render(request, "notifications.html", context)