From 21c0a0163a947f28a889343aa2f2b4e18102b20b Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 4 Nov 2020 15:23:52 -0800 Subject: [PATCH 1/2] Deduplicate incoming Create notes --- bookwyrm/incoming.py | 4 ++++ bookwyrm/models/status.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/bookwyrm/incoming.py b/bookwyrm/incoming.py index c6a22caa1..7adc181d4 100644 --- a/bookwyrm/incoming.py +++ b/bookwyrm/incoming.py @@ -217,6 +217,10 @@ def handle_create(activity): return # render the json into an activity object + status_id = activity['object']['id'] + if models.Status.objects.filter(remote_id=status_id).count(): + return + serializer = activitypub.activity_objects[activity['object']['type']] activity = serializer(**activity['object']) diff --git a/bookwyrm/models/status.py b/bookwyrm/models/status.py index fa80fecb9..31b96a255 100644 --- a/bookwyrm/models/status.py +++ b/bookwyrm/models/status.py @@ -76,8 +76,8 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel): return tags shared_mappings = [ - ActivityMapping('id', 'remote_id'), ActivityMapping('url', 'remote_id'), + ActivityMapping('id', 'remote_id'), ActivityMapping('inReplyTo', 'reply_parent'), ActivityMapping('published', 'published_date'), ActivityMapping('attributedTo', 'user'), From 152343d251b0bddc7e81964bb51a3b25b388d1a7 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 4 Nov 2020 16:28:32 -0800 Subject: [PATCH 2/2] Boost and unboost federation fixes --- bookwyrm/activitypub/base_activity.py | 6 ++++ bookwyrm/activitypub/interaction.py | 4 +-- bookwyrm/incoming.py | 47 +++++++++++++-------------- bookwyrm/models/status.py | 5 ++- 4 files changed, 35 insertions(+), 27 deletions(-) diff --git a/bookwyrm/activitypub/base_activity.py b/bookwyrm/activitypub/base_activity.py index 54cc4679d..5f16906b7 100644 --- a/bookwyrm/activitypub/base_activity.py +++ b/bookwyrm/activitypub/base_activity.py @@ -76,6 +76,12 @@ class ActivityObject: if not isinstance(self, model.activity_serializer): raise TypeError('Wrong activity type for model') + # check for an existing instance + try: + return model.objects.get(remote_id=self.id) + except model.DoesNotExist: + pass + model_fields = [m.name for m in model._meta.get_fields()] mapped_fields = {} diff --git a/bookwyrm/activitypub/interaction.py b/bookwyrm/activitypub/interaction.py index 2da005875..752b2fe3f 100644 --- a/bookwyrm/activitypub/interaction.py +++ b/bookwyrm/activitypub/interaction.py @@ -8,7 +8,7 @@ from .base_activity import ActivityObject class Like(ActivityObject): ''' a user faving an object ''' actor: str - object: ActivityObject + object: str type: str = 'Like' @@ -16,5 +16,5 @@ class Like(ActivityObject): class Boost(ActivityObject): ''' boosting a status ''' actor: str - object: ActivityObject + object: str type: str = 'Announce' diff --git a/bookwyrm/incoming.py b/bookwyrm/incoming.py index 7adc181d4..134c54845 100644 --- a/bookwyrm/incoming.py +++ b/bookwyrm/incoming.py @@ -68,6 +68,7 @@ def shared_inbox(request): 'Undo': { 'Follow': handle_unfollow, 'Like': handle_unfavorite, + 'Announce': handle_unboost, }, 'Update': { 'Person': handle_update_user, @@ -217,10 +218,6 @@ def handle_create(activity): return # render the json into an activity object - status_id = activity['object']['id'] - if models.Status.objects.filter(remote_id=status_id).count(): - return - serializer = activitypub.activity_objects[activity['object']['type']] activity = serializer(**activity['object']) @@ -271,48 +268,50 @@ def handle_delete_status(activity): @app.task def handle_favorite(activity): ''' approval of your good good post ''' - fav = activitypub.Like(**activity['object']) - # raises ValueError in to_model if a foreign key could not be resolved in + fav = activitypub.Like(**activity) liker = get_or_create_remote_user(activity['actor']) if liker.local: return - status = fav.to_model(models.Favorite) + fav = fav.to_model(models.Favorite) status_builder.create_notification( - status.user, + fav.status.user, 'FAVORITE', related_user=liker, - related_status=status, + related_status=fav.status, ) @app.task def handle_unfavorite(activity): ''' approval of your good good post ''' - like = activitypub.Like(**activity['object']) - fav = models.Favorite.objects.filter(remote_id=like.id).first() - - fav.delete() + like = activitypub.Like(**activity['object']).to_model(models.Favorite) + like.delete() @app.task def handle_boost(activity): ''' someone gave us a boost! ''' - status_id = activity['object'].split('/')[-1] - status = models.Status.objects.get(id=status_id) - booster = get_or_create_remote_user(activity['actor']) + boost = activitypub.Boost(**activity).to_model(models.Boost) - if not booster.local: - status_builder.create_boost_from_activity(booster, activity) + if not boost.user.local: + status_builder.create_notification( + boost.boosted_status.user, + 'BOOST', + related_user=boost.user, + related_status=boost.boosted_status, + ) - status_builder.create_notification( - status.user, - 'BOOST', - related_user=booster, - related_status=status, - ) + +@app.task +def handle_unboost(activity): + ''' someone gave us a boost! ''' + boost = models.Boost.objects.filter(remote_id=activity['object']['id']).first() + if not boost: + return + status_builder.delete_status(boost) @app.task diff --git a/bookwyrm/models/status.py b/bookwyrm/models/status.py index 31b96a255..f9a217e7f 100644 --- a/bookwyrm/models/status.py +++ b/bookwyrm/models/status.py @@ -76,7 +76,7 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel): return tags shared_mappings = [ - ActivityMapping('url', 'remote_id'), + ActivityMapping('url', 'remote_id', lambda x: None), ActivityMapping('id', 'remote_id'), ActivityMapping('inReplyTo', 'reply_parent'), ActivityMapping('published', 'published_date'), @@ -136,6 +136,7 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel): return ActivitypubMixin.to_activity(self, pure=pure) def save(self, *args, **kwargs): + ''' update user active time ''' self.user.last_active_date = timezone.now() self.user.save() super().save(*args, **kwargs) @@ -240,6 +241,7 @@ class Favorite(ActivitypubMixin, BookWyrmModel): activity_serializer = activitypub.Like def save(self, *args, **kwargs): + ''' update user active time ''' self.user.last_active_date = timezone.now() self.user.save() super().save(*args, **kwargs) @@ -285,6 +287,7 @@ class ReadThrough(BookWyrmModel): null=True) def save(self, *args, **kwargs): + ''' update user active time ''' self.user.last_active_date = timezone.now() self.user.save() super().save(*args, **kwargs)