diff --git a/djangoldp_notification/models.py b/djangoldp_notification/models.py index 1fc0cec..e99fcda 100644 --- a/djangoldp_notification/models.py +++ b/djangoldp_notification/models.py @@ -1,5 +1,3 @@ -import logging - import requests from django.conf import settings from django.contrib.auth import get_user_model @@ -13,10 +11,14 @@ from django.urls import NoReverseMatch, get_resolver from django.utils.translation import ugettext_lazy as _ from djangoldp.fields import LDPUrlField from djangoldp.models import Model -from threading import Thread +from djangoldp.activities.services import ActivityQueueService, ActivityPubService, activity_sending_finished from djangoldp_notification.middlewares import MODEL_MODIFICATION_USER_FIELD from djangoldp_notification.permissions import InboxPermissions, SubscriptionsPermissions from djangoldp_notification.views import LDPNotificationsViewSet +import logging + + +logger = logging.getLogger('djangoldp') class Notification(Model): @@ -115,7 +117,10 @@ def create_nested_subscribers(sender, instance, created, **kwargs): @receiver(post_delete, dispatch_uid="delete_callback_notif") def send_notification(sender, instance, **kwargs): if sender != Notification: - threads = [] + # don't send notifications for foreign resources + if hasattr(instance, 'urlid') and Model.is_external(instance.urlid): + return + recipients = [] try: url_container = settings.BASE_URL + Model.container_id(instance) @@ -125,47 +130,55 @@ def send_notification(sender, instance, **kwargs): # dispatch a notification for every Subscription on this resource for subscription in Subscription.objects.filter(models.Q(object=url_resource) | models.Q(object=url_container)): - if not instance.is_backlink and subscription.inbox not in recipients and \ - (not subscription.is_backlink or not kwargs.get("created")): + if subscription.inbox not in recipients and (not subscription.is_backlink or not kwargs.get("created")): # I may have configured to send the subscription to a foreign key if subscription.field is not None and len(subscription.field) > 1: try: instance = getattr(instance, subscription.field, instance) + + # don't send notifications for foreign resources + if hasattr(instance, 'urlid') and Model.is_external(instance.urlid): + continue + url_resource = settings.BASE_URL + Model.resource_id(instance) except NoReverseMatch: continue except ObjectDoesNotExist: continue - process = Thread(target=send_request, args=[subscription.inbox, url_resource, instance, - kwargs.get("created", False)]) - process.start() - threads.append(process) + send_request(subscription.inbox, url_resource, instance, kwargs.get("created", False)) recipients.append(subscription.inbox) +@receiver(activity_sending_finished, sender=ActivityQueueService) +def _handle_prosody_response(sender, response, saved_activity, **kwargs): + '''callback function for handling a response from Prosody on a notification''' + # if text is defined in the response body then it's an error + if saved_activity is not None: + response_body = saved_activity.response_to_json() + if 'condition' in response_body: + logger.error("[DjangoLDP-Notification.models._handle_prosody_response] error in Prosody response " + + str(response_body)) + + def send_request(target, object_iri, instance, created): unknown = str(_("Auteur inconnu")) author = getattr(getattr(instance, MODEL_MODIFICATION_USER_FIELD, unknown), "urlid", unknown) request_type = "creation" if created else "update" - try: - # local inbox - if target.startswith(settings.SITE_URL): - user = Model.resolve_parent(target.replace(settings.SITE_URL, '')) - Notification.objects.create(user=user, object=object_iri, type=request_type, author=author) - # external inbox - else: - json = { - "@context": settings.LDP_RDF_CONTEXT, - "object": object_iri, - "author": author, - "type": request_type - } - requests.post(target, json=json, headers={"Content-Type": "application/ld+json"}) - except Exception as e: - logging.error('Djangoldp_notifications: Error with request: {}'.format(e)) - return True + # local inbox + if target.startswith(settings.SITE_URL): + user = Model.resolve_parent(target.replace(settings.SITE_URL, '')) + Notification.objects.create(user=user, object=object_iri, type=request_type, author=author) + # external inbox + else: + json = { + "@context": settings.LDP_RDF_CONTEXT, + "object": object_iri, + "author": author, + "type": request_type + } + ActivityQueueService.send_activity(target, json) @receiver(post_save, sender=Notification) diff --git a/setup.cfg b/setup.cfg index a7120f4..78936c3 100644 --- a/setup.cfg +++ b/setup.cfg @@ -10,7 +10,7 @@ license = MIT [options] packages = find: install_requires = - djangoldp>=1.0.0 + djangoldp>=1.2.0 [options.extras_require] include_package_data = True