Merge pull request #2056 from bookwyrm-social/duplicate-follow-requests

Trigger rebroadcast of follow requests
This commit is contained in:
Mouse Reeve 2022-03-26 10:42:06 -07:00 committed by GitHub
commit 7cbf78c5fd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 23 deletions

View file

@ -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_object)
super().save(*args, **kwargs)
def delete(self, *args, **kwargs):
"""clear the template cache"""
clear_cache(self.user_subject, self.user_object)
super().delete(*args, **kwargs)
class Meta:
"""relationships should be unique"""
@ -90,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)
@ -98,11 +99,12 @@ class UserFollows(ActivityMixin, UserRelationship):
@classmethod
def from_request(cls, follow_request):
"""converts a follow request into a follow relationship"""
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):
@ -133,7 +135,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:
@ -174,6 +178,7 @@ class UserFollowRequest(ActivitypubMixin, UserRelationship):
with transaction.atomic():
UserFollows.from_request(self)
if self.id:
self.delete()
def reject(self):
@ -207,3 +212,13 @@ 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}",
]
)

View file

@ -2,12 +2,12 @@
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
from bookwyrm import models
from bookwyrm.models.relationship import clear_cache
from .helpers import (
get_user_from_username,
handle_remote_webfinger,
@ -22,17 +22,17 @@ 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)
try:
models.UserFollowRequest.objects.create(
follow_request, created = models.UserFollowRequest.objects.get_or_create(
user_subject=request.user,
user_object=to_follow,
)
except IntegrityError:
pass
if request.GET.get("next"):
return redirect(request.GET.get("next", "/"))
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)
@ -49,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", "/"))