diff --git a/bookwyrm/activitystreams.py b/bookwyrm/activitystreams.py index 01ca3f77..bad7c59f 100644 --- a/bookwyrm/activitystreams.py +++ b/bookwyrm/activitystreams.py @@ -199,6 +199,40 @@ class BooksStream(ActivityStream): privacy_levels=["public"], ) + def add_book_statuses(self, user, book): + """add statuses about a book to a user's feed""" + work = book.parent_work + statuses = privacy_filter( + user, + models.Status.objects.select_subclasses() + .filter( + Q(comment__book__parent_work=work) + | Q(quotation__book__parent_work=work) + | Q(review__book__parent_work=work) + | Q(mention_books__parent_work=work) + ) + .distinct(), + privacy_levels=["public"], + ) + self.bulk_add_objects_to_store(statuses, self.stream_id(user)) + + def remove_book_statuses(self, user, book): + """add statuses about a book to a user's feed""" + work = book.parent_work + statuses = privacy_filter( + user, + models.Status.objects.select_subclasses() + .filter( + Q(comment__book__parent_work=work) + | Q(quotation__book__parent_work=work) + | Q(review__book__parent_work=work) + | Q(mention_books__parent_work=work) + ) + .distinct(), + privacy_levels=["public"], + ) + self.bulk_remove_objects_from_store(statuses, self.stream_id(user)) + # determine which streams are enabled in settings.py available_streams = [s["key"] for s in STREAMS] @@ -316,3 +350,33 @@ def populate_streams_on_account_create(sender, instance, created, *args, **kwarg for stream in streams.values(): stream.populate_streams(instance) + + +@receiver(signals.pre_save, sender=models.ShelfBook) +# pylint: disable=unused-argument +def add_statuses_on_shelve(sender, instance, *args, **kwargs): + """update books stream when user shelves a book""" + if not instance.user.local: + return + # check if the book is already on the user's shelves + if models.ShelfBook.objects.filter( + user=instance.user, book__in=instance.book.parent_work.editions.all() + ).exists(): + return + + BooksStream().add_book_statuses(instance.user, instance.book) + + +@receiver(signals.post_delete, sender=models.ShelfBook) +# pylint: disable=unused-argument +def remove_statuses_on_shelve(sender, instance, *args, **kwargs): + """update books stream when user unshelves a book""" + if not instance.user.local: + return + # check if the book is actually unshelved, not just moved + if models.ShelfBook.objects.filter( + user=instance.user, book__in=instance.book.parent_work.editions.all() + ).exists(): + return + + BooksStream().remove_book_statuses(instance.user, instance.book) diff --git a/bookwyrm/tests/test_activitystreams.py b/bookwyrm/tests/test_activitystreams.py index ba495089..ac57d8b3 100644 --- a/bookwyrm/tests/test_activitystreams.py +++ b/bookwyrm/tests/test_activitystreams.py @@ -6,6 +6,7 @@ from bookwyrm import activitystreams, models @patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") @patch("bookwyrm.activitystreams.ActivityStream.add_status") +@patch("bookwyrm.activitystreams.BooksStream.add_book_statuses") @patch("bookwyrm.suggested_users.rerank_suggestions_task.delay") class Activitystreams(TestCase): """using redis to build activity streams""" diff --git a/bookwyrm/tests/views/test_edit_user.py b/bookwyrm/tests/views/test_edit_user.py index ccfb4c90..df89d5b0 100644 --- a/bookwyrm/tests/views/test_edit_user.py +++ b/bookwyrm/tests/views/test_edit_user.py @@ -34,7 +34,9 @@ class EditUserViews(TestCase): "rat@local.com", "rat@rat.rat", "password", local=True, localname="rat" ) - self.book = models.Edition.objects.create(title="test") + self.book = models.Edition.objects.create( + title="test", parent_work=models.Work.objects.create(title="test work") + ) with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): models.ShelfBook.objects.create( book=self.book, diff --git a/bookwyrm/tests/views/test_user.py b/bookwyrm/tests/views/test_user.py index 0efdf16a..740f0d29 100644 --- a/bookwyrm/tests/views/test_user.py +++ b/bookwyrm/tests/views/test_user.py @@ -28,7 +28,9 @@ class UserViews(TestCase): self.rat = models.User.objects.create_user( "rat@local.com", "rat@rat.rat", "password", local=True, localname="rat" ) - self.book = models.Edition.objects.create(title="test") + self.book = models.Edition.objects.create( + title="test", parent_work=models.Work.objects.create(title="test work") + ) with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"): models.ShelfBook.objects.create(