From 6243cf0e4a763aacb5586338fbf6ef1127aa5349 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Mon, 26 Oct 2020 14:33:02 -0700 Subject: [PATCH 01/13] uses enum for post privacy database field --- bookwyrm/migrations/0057_auto_20201026_2131.py | 18 ++++++++++++++++++ bookwyrm/models/status.py | 13 ++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 bookwyrm/migrations/0057_auto_20201026_2131.py diff --git a/bookwyrm/migrations/0057_auto_20201026_2131.py b/bookwyrm/migrations/0057_auto_20201026_2131.py new file mode 100644 index 00000000..cc414e98 --- /dev/null +++ b/bookwyrm/migrations/0057_auto_20201026_2131.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.7 on 2020-10-26 21:31 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('bookwyrm', '0056_auto_20201021_0150'), + ] + + operations = [ + migrations.AlterField( + model_name='status', + name='privacy', + field=models.CharField(choices=[('public', 'Public'), ('unlisted', 'Unlisted'), ('followers', 'Followers'), ('direct', 'Direct')], default='public', max_length=255), + ), + ] diff --git a/bookwyrm/models/status.py b/bookwyrm/models/status.py index 61e9c500..dfc39194 100644 --- a/bookwyrm/models/status.py +++ b/bookwyrm/models/status.py @@ -10,6 +10,13 @@ from .base_model import ActivitypubMixin, OrderedCollectionPageMixin from .base_model import ActivityMapping, BookWyrmModel +PrivacyLevels = models.TextChoices('Privacy', [ + 'public', + 'unlisted', + 'followers', + 'direct' +]) + class Status(OrderedCollectionPageMixin, BookWyrmModel): ''' any post, like a reply to a review, etc ''' user = models.ForeignKey('User', on_delete=models.PROTECT) @@ -18,7 +25,11 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel): mention_books = models.ManyToManyField( 'Edition', related_name='mention_book') local = models.BooleanField(default=True) - privacy = models.CharField(max_length=255, default='public') + privacy = models.CharField( + max_length=255, + default='public', + choices=PrivacyLevels.choices + ) sensitive = models.BooleanField(default=False) # the created date can't be this, because of receiving federated posts published_date = models.DateTimeField(default=timezone.now) From 2afa111b705eb319e3822e70d9c2f3ce0776d289 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Mon, 26 Oct 2020 15:00:15 -0700 Subject: [PATCH 02/13] Create statuses from django form --- bookwyrm/outgoing.py | 59 +++++++++++----------------------------- bookwyrm/status.py | 1 + bookwyrm/view_actions.py | 48 ++++++-------------------------- 3 files changed, 26 insertions(+), 82 deletions(-) diff --git a/bookwyrm/outgoing.py b/bookwyrm/outgoing.py index f496a211..118f90fe 100644 --- a/bookwyrm/outgoing.py +++ b/bookwyrm/outgoing.py @@ -9,9 +9,8 @@ import requests from bookwyrm import activitypub from bookwyrm import models from bookwyrm.broadcast import broadcast -from bookwyrm.status import create_review, create_status -from bookwyrm.status import create_quotation, create_comment -from bookwyrm.status import create_tag, create_notification, create_rating +from bookwyrm.status import create_status +from bookwyrm.status import create_tag, create_notification from bookwyrm.status import create_generated_note from bookwyrm.status import delete_status from bookwyrm.remote_user import get_or_create_remote_user @@ -178,16 +177,18 @@ def handle_import_books(user, items): broadcast(user, activity) if item.rating or item.review: - review_title = "Review of {!r} on Goodreads".format( - item.book.title, - ) if item.review else "" - handle_review( - user, - item.book, - review_title, - item.review, - item.rating, - ) + pass + #review_title = "Review of {!r} on Goodreads".format( + # item.book.title, + #) if item.review else "" + # TODO + #handle_review( + # user, + # item.book, + # review_title, + # item.review, + # item.rating, + #) for read in item.reads: read.book = item.book read.user = user @@ -209,37 +210,9 @@ def handle_delete_status(user, status): broadcast(user, status.to_activity()) -def handle_rate(user, book, rating): - ''' a review that's just a rating ''' - builder = create_rating - handle_status(user, book, builder, rating) - - -def handle_review(user, book, name, content, rating): - ''' post a review ''' - # validated and saves the review in the database so it has an id - builder = create_review - handle_status(user, book, builder, name, content, rating) - - -def handle_quotation(user, book, content, quote): - ''' post a review ''' - # validated and saves the review in the database so it has an id - builder = create_quotation - handle_status(user, book, builder, content, quote) - - -def handle_comment(user, book, content): - ''' post a comment ''' - # validated and saves the review in the database so it has an id - builder = create_comment - handle_status(user, book, builder, content) - - -def handle_status(user, book_id, builder, *args): +def handle_status(user, form): ''' generic handler for statuses ''' - book = models.Edition.objects.get(id=book_id) - status = builder(user, book, *args) + status = form.save() broadcast(user, status.to_create_activity(user), software='bookwyrm') diff --git a/bookwyrm/status.py b/bookwyrm/status.py index 25619839..57c800e5 100644 --- a/bookwyrm/status.py +++ b/bookwyrm/status.py @@ -13,6 +13,7 @@ def delete_status(status): status.deleted_date = datetime.now() status.save() + def create_rating(user, book, rating): ''' a review that's just a rating ''' if not rating or rating < 1 or rating > 5: diff --git a/bookwyrm/view_actions.py b/bookwyrm/view_actions.py index 54ed353a..e8a3b1fc 100644 --- a/bookwyrm/view_actions.py +++ b/bookwyrm/view_actions.py @@ -296,67 +296,37 @@ def shelve(request): def rate(request): ''' just a star rating for a book ''' form = forms.RatingForm(request.POST) - book_id = request.POST.get('book') - # TODO: better failure behavior - if not form.is_valid(): - return redirect('/book/%s' % book_id) - - rating = form.cleaned_data.get('rating') - # throws a value error if the book is not found - - outgoing.handle_rate(request.user, book_id, rating) - return redirect('/book/%s' % book_id) + return handle_status(request, form) @login_required def review(request): ''' create a book review ''' form = forms.ReviewForm(request.POST) - book_id = request.POST.get('book') - if not form.is_valid(): - return redirect('/book/%s' % book_id) - - # TODO: validation, htmlification - name = form.cleaned_data.get('name') - content = form.cleaned_data.get('content') - rating = form.data.get('rating', None) - try: - rating = int(rating) - except ValueError: - rating = None - - outgoing.handle_review(request.user, book_id, name, content, rating) - return redirect('/book/%s' % book_id) + return handle_status(request, form) @login_required def quotate(request): ''' create a book quotation ''' form = forms.QuotationForm(request.POST) - book_id = request.POST.get('book') - if not form.is_valid(): - return redirect('/book/%s' % book_id) - - quote = form.cleaned_data.get('quote') - content = form.cleaned_data.get('content') - - outgoing.handle_quotation(request.user, book_id, content, quote) - return redirect('/book/%s' % book_id) + return handle_status(request, form) @login_required def comment(request): ''' create a book comment ''' form = forms.CommentForm(request.POST) + return handle_status(request, form) + + +def handle_status(request, form): + ''' all the review/comment/quote etc functions are the same ''' book_id = request.POST.get('book') - # TODO: better failure behavior if not form.is_valid(): return redirect('/book/%s' % book_id) - # TODO: validation, htmlification - content = form.data.get('content') - - outgoing.handle_comment(request.user, book_id, content) + outgoing.handle_status(request.user, form) return redirect('/book/%s' % book_id) From 39b9fe8f4a671bad786e757ea85fd5757184bdc2 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Mon, 26 Oct 2020 15:10:32 -0700 Subject: [PATCH 03/13] Fixes serializing reviews with no rating --- bookwyrm/models/status.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/bookwyrm/models/status.py b/bookwyrm/models/status.py index dfc39194..b1283c9d 100644 --- a/bookwyrm/models/status.py +++ b/bookwyrm/models/status.py @@ -192,9 +192,14 @@ class Review(Status): @property def ap_pure_name(self): ''' clarify review names for mastodon serialization ''' - return 'Review of "%s" (%d stars): %s' % ( + if self.rating: + return 'Review of "%s" (%d stars): %s' % ( + self.book.title, + self.rating, + self.name + ) + return 'Review of "%s": %s' % ( self.book.title, - self.rating, self.name ) From b7061c0f4d13576729a568d647be62e22ab40d4b Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 27 Oct 2020 11:32:15 -0700 Subject: [PATCH 04/13] Fixes create status forms --- bookwyrm/forms.py | 26 +++------------- bookwyrm/outgoing.py | 31 +++++++------------ .../templates/snippets/create_status.html | 8 +++++ bookwyrm/templates/snippets/interaction.html | 4 ++- bookwyrm/view_actions.py | 26 ++++++---------- 5 files changed, 38 insertions(+), 57 deletions(-) diff --git a/bookwyrm/forms.py b/bookwyrm/forms.py index 7b18a2ff..0c3b19ba 100644 --- a/bookwyrm/forms.py +++ b/bookwyrm/forms.py @@ -52,47 +52,31 @@ class RegisterForm(CustomForm): class RatingForm(CustomForm): class Meta: model = models.Review - fields = ['rating'] + fields = ['user', 'book', 'content', 'rating', 'privacy'] class ReviewForm(CustomForm): class Meta: model = models.Review - fields = ['name', 'content'] - help_texts = {f: None for f in fields} - labels = { - 'name': 'Title', - 'content': 'Review', - } + fields = ['user', 'book', 'name', 'content', 'rating', 'privacy'] class CommentForm(CustomForm): class Meta: model = models.Comment - fields = ['content'] - help_texts = {f: None for f in fields} - labels = { - 'content': 'Comment', - } + fields = ['user', 'book', 'content', 'privacy'] class QuotationForm(CustomForm): class Meta: model = models.Quotation - fields = ['quote', 'content'] - help_texts = {f: None for f in fields} - labels = { - 'quote': 'Quote', - 'content': 'Comment', - } + fields = ['user', 'book', 'quote', 'content', 'privacy'] class ReplyForm(CustomForm): class Meta: model = models.Status - fields = ['content'] - help_texts = {f: None for f in fields} - labels = {'content': 'Comment'} + fields = ['user', 'content', 'reply_parent', 'privacy'] class EditUserForm(CustomForm): diff --git a/bookwyrm/outgoing.py b/bookwyrm/outgoing.py index 118f90fe..bcdf7170 100644 --- a/bookwyrm/outgoing.py +++ b/bookwyrm/outgoing.py @@ -9,7 +9,6 @@ import requests from bookwyrm import activitypub from bookwyrm import models from bookwyrm.broadcast import broadcast -from bookwyrm.status import create_status from bookwyrm.status import create_tag, create_notification from bookwyrm.status import create_generated_note from bookwyrm.status import delete_status @@ -214,12 +213,21 @@ def handle_status(user, form): ''' generic handler for statuses ''' status = form.save() + # notify reply parent or (TODO) tagged users + if status.reply_parent and status.reply_parent.user.local: + create_notification( + status.reply_parent.user, + 'REPLY', + related_user=user, + related_status=status + ) + broadcast(user, status.to_create_activity(user), software='bookwyrm') # re-format the activity for non-bookwyrm servers - remote_activity = status.to_create_activity(user, pure=True) - - broadcast(user, remote_activity, software='other') + if hasattr(status, 'pure_activity_serializer'): + remote_activity = status.to_create_activity(user, pure=True) + broadcast(user, remote_activity, software='other') def handle_tag(user, book, name): @@ -238,21 +246,6 @@ def handle_untag(user, book, name): broadcast(user, tag_activity) -def handle_reply(user, review, content): - ''' respond to a review or status ''' - # validated and saves the comment in the database so it has an id - reply = create_status(user, content, reply_parent=review) - if reply.reply_parent: - create_notification( - reply.reply_parent.user, - 'REPLY', - related_user=user, - related_status=reply, - ) - - broadcast(user, reply.to_create_activity(user)) - - def handle_favorite(user, status): ''' a user likes a status ''' try: diff --git a/bookwyrm/templates/snippets/create_status.html b/bookwyrm/templates/snippets/create_status.html index 88558df9..28eded97 100644 --- a/bookwyrm/templates/snippets/create_status.html +++ b/bookwyrm/templates/snippets/create_status.html @@ -22,6 +22,8 @@ - +
+
+ +
+ +
diff --git a/bookwyrm/templates/snippets/interaction.html b/bookwyrm/templates/snippets/interaction.html index 27bbbf8b..a48d8a7c 100644 --- a/bookwyrm/templates/snippets/interaction.html +++ b/bookwyrm/templates/snippets/interaction.html @@ -6,7 +6,7 @@ {% csrf_token %} - + From bdbf449dc07f7062fc2bd15f06c70771f967363d Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 28 Oct 2020 13:17:02 -0700 Subject: [PATCH 13/13] Usbale navbar links --- bookwyrm/templates/layout.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bookwyrm/templates/layout.html b/bookwyrm/templates/layout.html index f5f72e65..55380652 100644 --- a/bookwyrm/templates/layout.html +++ b/bookwyrm/templates/layout.html @@ -47,11 +47,11 @@