From a3b9c621afe964ff3b2f77046ee4cd4dabc26c59 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 24 Mar 2022 11:25:42 -0700 Subject: [PATCH 1/4] Trigger rebroadcast of follow requests --- bookwyrm/models/relationship.py | 4 +++- bookwyrm/views/follow.py | 19 ++++++++----------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/bookwyrm/models/relationship.py b/bookwyrm/models/relationship.py index e95c38fa5..cd72c756b 100644 --- a/bookwyrm/models/relationship.py +++ b/bookwyrm/models/relationship.py @@ -133,7 +133,9 @@ class UserFollowRequest(ActivitypubMixin, UserRelationship): user_object=self.user_subject, ) ).exists(): - raise IntegrityError() + raise IntegrityError( + "Attempting to follow blocked user", self.user_subject, self.user_object + ) super().save(*args, **kwargs) if broadcast and self.user_subject.local and not self.user_object.local: diff --git a/bookwyrm/views/follow.py b/bookwyrm/views/follow.py index 6e58a2b22..3ee392e32 100644 --- a/bookwyrm/views/follow.py +++ b/bookwyrm/views/follow.py @@ -2,7 +2,6 @@ import urllib.parse import re from django.contrib.auth.decorators import login_required -from django.db import IntegrityError from django.shortcuts import get_object_or_404, redirect from django.template.response import TemplateResponse from django.views.decorators.http import require_POST @@ -23,16 +22,14 @@ def follow(request): username = request.POST["user"] to_follow = get_user_from_username(request.user, username) - try: - models.UserFollowRequest.objects.create( - user_subject=request.user, - user_object=to_follow, - ) - except IntegrityError: - pass - - if request.GET.get("next"): - return redirect(request.GET.get("next", "/")) + follow_request, created = models.UserFollowRequest.objects.get_or_create( + user_subject=request.user, + user_object=to_follow, + ) + if not created: + # this request probably failed to connect with the remote + # that means we should save to trigger a re-broadcast + follow_request.save() return redirect(to_follow.local_path) From 4f24b05d60e271c684773a1dbee73120208cc54a Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 24 Mar 2022 13:10:49 -0700 Subject: [PATCH 2/4] Clear cache regardless of view success --- bookwyrm/models/relationship.py | 28 +++++++++++++++++++++------- bookwyrm/views/follow.py | 7 +++++-- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/bookwyrm/models/relationship.py b/bookwyrm/models/relationship.py index cd72c756b..a0939b4b1 100644 --- a/bookwyrm/models/relationship.py +++ b/bookwyrm/models/relationship.py @@ -39,15 +39,14 @@ class UserRelationship(BookWyrmModel): def save(self, *args, **kwargs): """clear the template cache""" - # invalidate the template cache - cache.delete_many( - [ - f"relationship-{self.user_subject.id}-{self.user_object.id}", - f"relationship-{self.user_object.id}-{self.user_subject.id}", - ] - ) + clear_cache(self.user_subject, self.user_subject) super().save(*args, **kwargs) + def delete(self, *args, **kwargs): + """clear the template cache""" + clear_cache(self.user_subject, self.user_subject) + super().delete(*args, **kwargs) + class Meta: """relationships should be unique""" @@ -98,6 +97,7 @@ class UserFollows(ActivityMixin, UserRelationship): @classmethod def from_request(cls, follow_request): """converts a follow request into a follow relationship""" + print("from!!", cls) return cls.objects.create( user_subject=follow_request.user_subject, user_object=follow_request.user_object, @@ -115,6 +115,7 @@ class UserFollowRequest(ActivitypubMixin, UserRelationship): """make sure the follow or block relationship doesn't already exist""" # if there's a request for a follow that already exists, accept it # without changing the local database state + print("UHHH????") if UserFollows.objects.filter( user_subject=self.user_subject, user_object=self.user_object, @@ -136,6 +137,7 @@ class UserFollowRequest(ActivitypubMixin, UserRelationship): raise IntegrityError( "Attempting to follow blocked user", self.user_subject, self.user_object ) + print("super save!") super().save(*args, **kwargs) if broadcast and self.user_subject.local and not self.user_object.local: @@ -144,10 +146,12 @@ class UserFollowRequest(ActivitypubMixin, UserRelationship): if self.user_object.local: manually_approves = self.user_object.manually_approves_followers if not manually_approves: + print("accept") self.accept() model = apps.get_model("bookwyrm.Notification", require_ready=True) notification_type = "FOLLOW_REQUEST" if manually_approves else "FOLLOW" + print("notification") model.objects.create( user=self.user_object, related_user=self.user_subject, @@ -175,6 +179,7 @@ class UserFollowRequest(ActivitypubMixin, UserRelationship): return with transaction.atomic(): + print("from request") UserFollows.from_request(self) self.delete() @@ -209,3 +214,12 @@ class UserBlocks(ActivityMixin, UserRelationship): Q(user_subject=self.user_subject, user_object=self.user_object) | Q(user_subject=self.user_object, user_object=self.user_subject) ).delete() + +def clear_cache(user_subject, user_object): + """clear relationship cache""" + cache.delete_many( + [ + f"relationship-{user_subject.id}-{user_object.id}", + f"relationship-{user_object.id}-{user_subject.id}", + ] + ) diff --git a/bookwyrm/views/follow.py b/bookwyrm/views/follow.py index 3ee392e32..8bbcfca86 100644 --- a/bookwyrm/views/follow.py +++ b/bookwyrm/views/follow.py @@ -7,6 +7,7 @@ from django.template.response import TemplateResponse from django.views.decorators.http import require_POST from bookwyrm import models +from bookwyrm.models.relationship import clear_cache from .helpers import ( get_user_from_username, handle_remote_webfinger, @@ -21,11 +22,13 @@ def follow(request): """follow another user, here or abroad""" username = request.POST["user"] to_follow = get_user_from_username(request.user, username) + clear_cache(request.user, to_follow) follow_request, created = models.UserFollowRequest.objects.get_or_create( user_subject=request.user, user_object=to_follow, ) + if not created: # this request probably failed to connect with the remote # that means we should save to trigger a re-broadcast @@ -46,14 +49,14 @@ def unfollow(request): user_subject=request.user, user_object=to_unfollow ).delete() except models.UserFollows.DoesNotExist: - pass + clear_cache(request.user, to_unfollow) try: models.UserFollowRequest.objects.get( user_subject=request.user, user_object=to_unfollow ).delete() except models.UserFollowRequest.DoesNotExist: - pass + clear_cache(request.user, to_unfollow) # this is handled with ajax so it shouldn't really matter return redirect(request.headers.get("Referer", "/")) From 2d7902ff89181b08107b16e29825474dc450c3fd Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 26 Mar 2022 10:27:49 -0700 Subject: [PATCH 3/4] Resolve second integrity error --- bookwyrm/models/relationship.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/bookwyrm/models/relationship.py b/bookwyrm/models/relationship.py index a0939b4b1..ff1e13b53 100644 --- a/bookwyrm/models/relationship.py +++ b/bookwyrm/models/relationship.py @@ -39,12 +39,12 @@ class UserRelationship(BookWyrmModel): def save(self, *args, **kwargs): """clear the template cache""" - clear_cache(self.user_subject, self.user_subject) + clear_cache(self.user_subject, self.user_object) super().save(*args, **kwargs) def delete(self, *args, **kwargs): """clear the template cache""" - clear_cache(self.user_subject, self.user_subject) + clear_cache(self.user_subject, self.user_object) super().delete(*args, **kwargs) class Meta: @@ -89,7 +89,9 @@ class UserFollows(ActivityMixin, UserRelationship): user_object=self.user_subject, ) ).exists(): - raise IntegrityError() + raise IntegrityError( + "Attempting to follow blocked user", self.user_subject, self.user_object + ) # don't broadcast this type of relationship -- accepts and requests # are handled by the UserFollowRequest model super().save(*args, broadcast=False, **kwargs) @@ -97,12 +99,12 @@ class UserFollows(ActivityMixin, UserRelationship): @classmethod def from_request(cls, follow_request): """converts a follow request into a follow relationship""" - print("from!!", cls) - return cls.objects.create( + obj, _ = cls.objects.get_or_create( user_subject=follow_request.user_subject, user_object=follow_request.user_object, remote_id=follow_request.remote_id, ) + return obj class UserFollowRequest(ActivitypubMixin, UserRelationship): @@ -115,7 +117,6 @@ class UserFollowRequest(ActivitypubMixin, UserRelationship): """make sure the follow or block relationship doesn't already exist""" # if there's a request for a follow that already exists, accept it # without changing the local database state - print("UHHH????") if UserFollows.objects.filter( user_subject=self.user_subject, user_object=self.user_object, @@ -137,7 +138,6 @@ class UserFollowRequest(ActivitypubMixin, UserRelationship): raise IntegrityError( "Attempting to follow blocked user", self.user_subject, self.user_object ) - print("super save!") super().save(*args, **kwargs) if broadcast and self.user_subject.local and not self.user_object.local: @@ -146,12 +146,10 @@ class UserFollowRequest(ActivitypubMixin, UserRelationship): if self.user_object.local: manually_approves = self.user_object.manually_approves_followers if not manually_approves: - print("accept") self.accept() model = apps.get_model("bookwyrm.Notification", require_ready=True) notification_type = "FOLLOW_REQUEST" if manually_approves else "FOLLOW" - print("notification") model.objects.create( user=self.user_object, related_user=self.user_subject, @@ -179,9 +177,9 @@ class UserFollowRequest(ActivitypubMixin, UserRelationship): return with transaction.atomic(): - print("from request") UserFollows.from_request(self) - self.delete() + if self.id: + self.delete() def reject(self): """generate a Reject for this follow request""" From 85f507d6b91b417e76b6317bae49ebaa34d73ec6 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 26 Mar 2022 10:34:02 -0700 Subject: [PATCH 4/4] Python formatting --- bookwyrm/models/relationship.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bookwyrm/models/relationship.py b/bookwyrm/models/relationship.py index ff1e13b53..171f45840 100644 --- a/bookwyrm/models/relationship.py +++ b/bookwyrm/models/relationship.py @@ -213,6 +213,7 @@ class UserBlocks(ActivityMixin, UserRelationship): | Q(user_subject=self.user_object, user_object=self.user_subject) ).delete() + def clear_cache(user_subject, user_object): """clear relationship cache""" cache.delete_many(