diff --git a/djangoldp/activities/services.py b/djangoldp/activities/services.py index db02400cb41aa7280ca77ff9cdfb7eb0835158fa..94d8e9d566e971281fa5e72de7c71382f1ee559b 100644 --- a/djangoldp/activities/services.py +++ b/djangoldp/activities/services.py @@ -260,6 +260,15 @@ class ActivityPubService(object): Follower.objects.create(object=obj_id, inbox=ActivityPubService.discover_inbox(urlid), follower=urlid, is_backlink=True) + @classmethod + def remove_followers_for_resource(cls, external_urlid, obj_id): + '''removes all followers which match the follower urlid, obj urlid combination''' + inbox = ActivityPubService.discover_inbox(external_urlid) + + for follower in Follower.objects.filter(object=obj_id, follower=external_urlid, + inbox=inbox, is_backlink=True): + follower.delete() + @receiver([post_save]) def check_save_for_backlinks(sender, instance, created, **kwargs): @@ -362,7 +371,4 @@ def check_m2m_for_backlinks(sender, instance, action, *args, **kwargs): elif action == "post_remove" or action == "pre_clear": for target in targets: ActivityPubService.send_remove_activity(BACKLINKS_ACTOR, obj, target) - inbox = ActivityPubService.discover_inbox(target['@id']) - for follower in Follower.objects.filter(object=obj['@id'], follower=target['@id'], - inbox=inbox, is_backlink=True): - follower.delete() + ActivityPubService.remove_followers_for_resource(target['@id'], obj['@id']) diff --git a/djangoldp/tests/tests_inbox.py b/djangoldp/tests/tests_inbox.py index 13f243390ff35a54efdb757613ee9579fdc2e632..41dadbba95b2510dae4c389d813158a47a6a5625 100644 --- a/djangoldp/tests/tests_inbox.py +++ b/djangoldp/tests/tests_inbox.py @@ -306,9 +306,13 @@ class TestsInbox(APITestCase): # REMOVE & DELETE ACTIVITIES # # project model has a direct many-to-many with User + @override_settings(SEND_BACKLINKS=True, DISABLE_OUTBOX=True) def test_remove_activity_project_using_origin(self): project = Project.objects.create(urlid="https://distant.com/projects/1/") self.user.projects.add(project) + Follower.objects.create(object=self.user.urlid, inbox='https://distant.com/inbox/', + follower=project.urlid, is_backlink=True) + prior_activity_count = Activity.objects.count() obj = { "@type": "hd:project", @@ -326,7 +330,8 @@ class TestsInbox(APITestCase): self.assertEquals(len(projects), 1) self.assertEquals(len(user_projects), 0) self.assertIn("https://distant.com/projects/1/", projects.values_list('urlid', flat=True)) - self._assert_activity_created(response) + self._assert_activity_created(response, prior_activity_count + 2) + self.assertEqual(Follower.objects.count(), 0) # TODO: test_remove_activity_project_using_target @@ -374,9 +379,12 @@ class TestsInbox(APITestCase): self.assertEqual(Activity.objects.all().count(), prior_count + 1) # Delete CircleMember + @override_settings(SEND_BACKLINKS=True, DISABLE_OUTBOX=True) def test_delete_activity_circle_using_origin(self): circle = Circle.objects.create(urlid="https://distant.com/circles/1/", allow_create_backlink=False) - CircleMember.objects.create(urlid="https://distant.com/circle-members/1/",circle=circle, user=self.user) + cm = CircleMember.objects.create(urlid="https://distant.com/circle-members/1/",circle=circle, user=self.user) + Follower.objects.create(object=self.user.urlid, inbox='https://distant.com/inbox/', + follower=cm.urlid, is_backlink=True) obj = { "@type": "hd:circlemember", @@ -400,9 +408,11 @@ class TestsInbox(APITestCase): circles = Circle.objects.all() user_circles = self.user.circles.all() self.assertEquals(len(circles), 1) + self.assertEquals(CircleMember.objects.count(), 0) self.assertEquals(len(user_circles), 0) self.assertIn("https://distant.com/circles/1/", circles.values_list('urlid', flat=True)) self._assert_activity_created(response) + self.assertEqual(Follower.objects.count(), 0) # TODO: test_delete_activity_circle_using_target diff --git a/djangoldp/views.py b/djangoldp/views.py index a110bfff07c0bf804b4c1ce8ab60314f9f2595d5..083c88c52122e826b80f3718b0abad952dc1f9ed 100644 --- a/djangoldp/views.py +++ b/djangoldp/views.py @@ -239,6 +239,7 @@ class InboxView(APIView): attr = getattr(origin, field_name) if attr.filter(urlid=object_instance.urlid).exists(): attr.remove(object_instance) + ActivityPubService.remove_followers_for_resource(origin.urlid, object_instance.urlid) def handle_create_or_update_activity(self, activity, **kwargs): ''' @@ -264,6 +265,10 @@ class InboxView(APIView): object_instance.allow_create_backlink = False object_instance.save() object_instance.delete() + urlid = getattr(object_instance, 'urlid', None) + if urlid is not None: + for follower in Follower.objects.filter(follower=urlid): + follower.delete() def handle_follow_activity(self, activity, **kwargs): '''