From 646df03d81c89763778e2310f9346deeeb594547 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 20 Dec 2020 11:51:17 -0800 Subject: [PATCH 1/8] show books for authors who only have editions --- bookwyrm/views.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bookwyrm/views.py b/bookwyrm/views.py index c27391cc..8e40f362 100644 --- a/bookwyrm/views.py +++ b/bookwyrm/views.py @@ -684,7 +684,8 @@ def author_page(request, author_id): if is_api_request(request): return JsonResponse(author.to_activity(), encoder=ActivityEncoder) - books = models.Work.objects.filter(authors=author) + books = models.Work.objects.filter( + Q(authors=author) | Q(editions__authors=author)).distinct() data = { 'title': author.name, 'author': author, From 7f1ac33859cecc8e0f5133d08bc11619951981e5 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 20 Dec 2020 11:51:33 -0800 Subject: [PATCH 2/8] Format html on book descriptions --- bookwyrm/outgoing.py | 8 +++----- bookwyrm/templates/snippets/trimmed_text.html | 6 +++--- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/bookwyrm/outgoing.py b/bookwyrm/outgoing.py index 7daa74de..13df9026 100644 --- a/bookwyrm/outgoing.py +++ b/bookwyrm/outgoing.py @@ -221,8 +221,6 @@ def handle_status(user, form): matches = [] for match in re.finditer(regex.username, status.content): username = match.group().strip().split('@')[1:] - print(match.group()) - print(len(username)) if len(username) == 1: # this looks like a local user (@user), fill in the domain username.append(DOMAIN) @@ -251,9 +249,9 @@ def handle_status(user, form): r'%s\g<1>' % (url, username), content) if not isinstance(status, models.GeneratedNote): - status.content = to_markown(content) + status.content = to_markdown(content) if hasattr(status, 'quote'): - status.quote = to_markown(status.quote) + status.quote = to_markdown(status.quote) status.save() # notify reply parent or tagged users @@ -272,7 +270,7 @@ def handle_status(user, form): broadcast(user, remote_activity, software='other') -def to_markown(content): +def to_markdown(content): ''' catch links and convert to markdown ''' content = re.sub( r'([^(href=")])(https?:\/\/([A-Za-z\.\-_\/]+' \ diff --git a/bookwyrm/templates/snippets/trimmed_text.html b/bookwyrm/templates/snippets/trimmed_text.html index b3207a92..25f76984 100644 --- a/bookwyrm/templates/snippets/trimmed_text.html +++ b/bookwyrm/templates/snippets/trimmed_text.html @@ -6,18 +6,18 @@ {% if trimmed != full %}
-
-
{% else %} -
{{ full }}
+
{{ full | safe }}
{% endif %} {% endwith %} From 60738011a2a6c4ae6f1c2143c7bdde503cbdf2fb Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 20 Dec 2020 12:09:19 -0800 Subject: [PATCH 3/8] user's name and bio field are optional get it together, mouse --- bookwyrm/activitypub/person.py | 4 ++-- .../migrations/0027_auto_20201220_2007.py | 24 +++++++++++++++++++ bookwyrm/models/user.py | 4 ++-- bookwyrm/view_actions.py | 6 +++-- 4 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 bookwyrm/migrations/0027_auto_20201220_2007.py diff --git a/bookwyrm/activitypub/person.py b/bookwyrm/activitypub/person.py index 88349c02..7e7d027e 100644 --- a/bookwyrm/activitypub/person.py +++ b/bookwyrm/activitypub/person.py @@ -18,13 +18,13 @@ class PublicKey(ActivityObject): class Person(ActivityObject): ''' actor activitypub json ''' preferredUsername: str - name: str inbox: str outbox: str followers: str - summary: str publicKey: PublicKey endpoints: Dict + name: str = None + summary: str = None icon: Image = field(default_factory=lambda: {}) bookwyrmUser: bool = False manuallyApprovesFollowers: str = False diff --git a/bookwyrm/migrations/0027_auto_20201220_2007.py b/bookwyrm/migrations/0027_auto_20201220_2007.py new file mode 100644 index 00000000..a3ad4dda --- /dev/null +++ b/bookwyrm/migrations/0027_auto_20201220_2007.py @@ -0,0 +1,24 @@ +# Generated by Django 3.0.7 on 2020-12-20 20:07 + +import bookwyrm.models.fields +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('bookwyrm', '0026_status_content_warning'), + ] + + operations = [ + migrations.AlterField( + model_name='user', + name='name', + field=bookwyrm.models.fields.CharField(blank=True, max_length=100, null=True), + ), + migrations.AlterField( + model_name='user', + name='summary', + field=bookwyrm.models.fields.HtmlField(blank=True, null=True), + ), + ] diff --git a/bookwyrm/models/user.py b/bookwyrm/models/user.py index ce50fc09..654bc811 100644 --- a/bookwyrm/models/user.py +++ b/bookwyrm/models/user.py @@ -42,7 +42,7 @@ class User(OrderedCollectionPageMixin, AbstractUser): blank=True, ) outbox = fields.RemoteIdField(unique=True) - summary = fields.HtmlField(default='') + summary = fields.HtmlField(null=True, blank=True) local = models.BooleanField(default=False) bookwyrm_user = fields.BooleanField(default=True) localname = models.CharField( @@ -51,7 +51,7 @@ class User(OrderedCollectionPageMixin, AbstractUser): unique=True ) # name is your display name, which you can change at will - name = fields.CharField(max_length=100, default='') + name = fields.CharField(max_length=100, null=True, blank=True) avatar = fields.ImageField( upload_to='avatars/', blank=True, null=True, activitypub_field='icon', alt_field='alt_text') diff --git a/bookwyrm/view_actions.py b/bookwyrm/view_actions.py index 1df1dcba..5fd8cff3 100644 --- a/bookwyrm/view_actions.py +++ b/bookwyrm/view_actions.py @@ -208,7 +208,7 @@ def edit_profile(request): ContentFile(output.getvalue()) ) - request.user.summary = form.data['summary'] + request.user.summary = outgoing.to_markdown(form.data['summary']) request.user.manually_approves_followers = \ form.cleaned_data['manually_approves_followers'] request.user.save() @@ -244,7 +244,9 @@ def edit_book(request, book_id): 'form': form } return TemplateResponse(request, 'edit_book.html', data) - form.save() + book = form.save(commit=False) + book.description = outgoing.to_markown(book.description) + book.save() outgoing.handle_update_book(request.user, book) return redirect('/book/%s' % book.id) From 689cc6579084ccf1816c9d12de467e0c989b1d18 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 20 Dec 2020 12:24:17 -0800 Subject: [PATCH 4/8] keep saved version of bio and description field as markdown --- bookwyrm/templates/snippets/trimmed_text.html | 6 +++--- bookwyrm/templates/snippets/user_header.html | 9 ++++++++- bookwyrm/templatetags/bookwyrm_tags.py | 8 ++++++++ bookwyrm/view_actions.py | 10 +++------- 4 files changed, 22 insertions(+), 11 deletions(-) diff --git a/bookwyrm/templates/snippets/trimmed_text.html b/bookwyrm/templates/snippets/trimmed_text.html index 25f76984..e8a1fa75 100644 --- a/bookwyrm/templates/snippets/trimmed_text.html +++ b/bookwyrm/templates/snippets/trimmed_text.html @@ -6,18 +6,18 @@ {% if trimmed != full %}
-
-
{% else %} -
{{ full | safe }}
+
{{ full | to_markdown | safe }}
{% endif %} {% endwith %} diff --git a/bookwyrm/templates/snippets/user_header.html b/bookwyrm/templates/snippets/user_header.html index f4f9733f..c06465e8 100644 --- a/bookwyrm/templates/snippets/user_header.html +++ b/bookwyrm/templates/snippets/user_header.html @@ -23,7 +23,14 @@
{% if user.summary %} -
{{ user.summary | safe }}
+
+
+ +
+
+
{{ user.summary | to_markdown | safe }}
+
+
{% endif %}
diff --git a/bookwyrm/templatetags/bookwyrm_tags.py b/bookwyrm/templatetags/bookwyrm_tags.py index 91934d48..61b097bd 100644 --- a/bookwyrm/templatetags/bookwyrm_tags.py +++ b/bookwyrm/templatetags/bookwyrm_tags.py @@ -7,6 +7,7 @@ from django import template from django.utils import timezone from bookwyrm import models +from bookwyrm.outgoing import to_markdown register = template.Library() @@ -132,6 +133,13 @@ def time_since(date): return '%ds' % delta.seconds +@register.filter(name="to_markdown") +def get_markdown(content): + ''' convert markdown to html ''' + if content: + return to_markdown(content) + return None + @register.simple_tag(takes_context=True) def active_shelf(context, book): ''' check what shelf a user has a book on, if any ''' diff --git a/bookwyrm/view_actions.py b/bookwyrm/view_actions.py index 5fd8cff3..c3e4d2be 100644 --- a/bookwyrm/view_actions.py +++ b/bookwyrm/view_actions.py @@ -17,10 +17,8 @@ from django.template.response import TemplateResponse from django.utils import timezone from django.views.decorators.http import require_GET, require_POST -from bookwyrm import books_manager +from bookwyrm import books_manager, forms, models, outgoing, goodreads_import from bookwyrm.broadcast import broadcast -from bookwyrm import forms, models, outgoing -from bookwyrm import goodreads_import from bookwyrm.emailing import password_reset_email from bookwyrm.settings import DOMAIN from bookwyrm.views import get_user_from_username @@ -208,7 +206,7 @@ def edit_profile(request): ContentFile(output.getvalue()) ) - request.user.summary = outgoing.to_markdown(form.data['summary']) + request.user.summary = form.data['summary'] request.user.manually_approves_followers = \ form.cleaned_data['manually_approves_followers'] request.user.save() @@ -244,9 +242,7 @@ def edit_book(request, book_id): 'form': form } return TemplateResponse(request, 'edit_book.html', data) - book = form.save(commit=False) - book.description = outgoing.to_markown(book.description) - book.save() + book = form.save() outgoing.handle_update_book(request.user, book) return redirect('/book/%s' % book.id) From 23cbeab4c1b849defdd9ecc39da7a53d8893c77c Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 20 Dec 2020 12:31:39 -0800 Subject: [PATCH 5/8] cleans up remote version of quote status --- bookwyrm/models/status.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/bookwyrm/models/status.py b/bookwyrm/models/status.py index 3162c22b..3654e554 100644 --- a/bookwyrm/models/status.py +++ b/bookwyrm/models/status.py @@ -1,5 +1,7 @@ ''' models for storing different kinds of Activities ''' from dataclasses import MISSING +import re + from django.apps import apps from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models @@ -155,7 +157,7 @@ class Comment(Status): @property def pure_content(self): ''' indicate the book in question for mastodon (or w/e) users ''' - return '

%s

(comment on "%s")

' % \ + return '%s

(comment on "%s")

' % \ (self.content, self.book.remote_id, self.book.title) activity_serializer = activitypub.Comment @@ -171,8 +173,10 @@ class Quotation(Status): @property def pure_content(self): ''' indicate the book in question for mastodon (or w/e) users ''' - return '

"%s"
-- "%s"

%s

' % ( - self.quote, + quote = re.sub(r'^

', '

"', self.quote) + quote = re.sub(r'

$', '"

', quote) + return '%s

-- "%s"

%s' % ( + quote, self.book.remote_id, self.book.title, self.content, From 3597ca460cf15b91e0e952178d658575c44ce50e Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 20 Dec 2020 12:40:20 -0800 Subject: [PATCH 6/8] Don't let author and book remote ids get overridden --- bookwyrm/models/author.py | 7 +++---- bookwyrm/models/book.py | 5 ++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/bookwyrm/models/author.py b/bookwyrm/models/author.py index 47714d4e..911cc109 100644 --- a/bookwyrm/models/author.py +++ b/bookwyrm/models/author.py @@ -28,11 +28,10 @@ class Author(ActivitypubMixin, BookWyrmModel): bio = fields.HtmlField(null=True, blank=True) def save(self, *args, **kwargs): - ''' can't be abstract for query reasons, but you shouldn't USE it ''' - if self.id and not self.remote_id: + ''' handle remote vs origin ids ''' + if self.id: self.remote_id = self.get_remote_id() - - if not self.id: + else: self.origin_id = self.remote_id self.remote_id = None return super().save(*args, **kwargs) diff --git a/bookwyrm/models/book.py b/bookwyrm/models/book.py index e4f1f29b..0a326591 100644 --- a/bookwyrm/models/book.py +++ b/bookwyrm/models/book.py @@ -83,10 +83,9 @@ class Book(ActivitypubMixin, BookWyrmModel): if not isinstance(self, Edition) and not isinstance(self, Work): raise ValueError('Books should be added as Editions or Works') - if self.id and not self.remote_id: + if self.id: self.remote_id = self.get_remote_id() - - if not self.id: + else: self.origin_id = self.remote_id self.remote_id = None return super().save(*args, **kwargs) From 79973687d5ca852b2b4f7960a499f85b9019baf3 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 20 Dec 2020 12:50:35 -0800 Subject: [PATCH 7/8] Updates tests --- bookwyrm/models/user.py | 2 +- bookwyrm/tests/activitypub/test_base_activity.py | 2 +- bookwyrm/tests/models/test_status_model.py | 7 +++---- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/bookwyrm/models/user.py b/bookwyrm/models/user.py index 654bc811..30eeffbc 100644 --- a/bookwyrm/models/user.py +++ b/bookwyrm/models/user.py @@ -100,7 +100,7 @@ class User(OrderedCollectionPageMixin, AbstractUser): @property def display_name(self): ''' show the cleanest version of the user's name possible ''' - if self.name != '': + if self.name and self.name != '': return self.name return self.localname or self.username diff --git a/bookwyrm/tests/activitypub/test_base_activity.py b/bookwyrm/tests/activitypub/test_base_activity.py index 87420aa7..4cdc2c70 100644 --- a/bookwyrm/tests/activitypub/test_base_activity.py +++ b/bookwyrm/tests/activitypub/test_base_activity.py @@ -103,7 +103,7 @@ class BaseActivity(TestCase): def test_to_model_simple_fields(self): ''' test setting simple fields ''' - self.assertEqual(self.user.name, '') + self.assertIsNone(self.user.name) activity = activitypub.Person( id=self.user.remote_id, diff --git a/bookwyrm/tests/models/test_status_model.py b/bookwyrm/tests/models/test_status_model.py index b9a6d6c9..d98b8b18 100644 --- a/bookwyrm/tests/models/test_status_model.py +++ b/bookwyrm/tests/models/test_status_model.py @@ -167,8 +167,7 @@ class Status(TestCase): self.assertEqual(activity['type'], 'Note') self.assertEqual( activity['content'], - '

test content

' \ - '(comment on "Test Edition")

' % + 'test content

(comment on "Test Edition")

' % self.book.remote_id) self.assertEqual(activity['attachment'][0].type, 'Image') self.assertEqual(activity['attachment'][0].url, 'https://%s%s' % \ @@ -198,8 +197,8 @@ class Status(TestCase): self.assertEqual(activity['type'], 'Note') self.assertEqual( activity['content'], - '

"a sickening sense"
-- "Test Edition"

' \ - '

test content

' % self.book.remote_id) + 'a sickening sense

-- "Test Edition"

' \ + 'test content' % self.book.remote_id) self.assertEqual(activity['attachment'][0].type, 'Image') self.assertEqual(activity['attachment'][0].url, 'https://%s%s' % \ (settings.DOMAIN, self.book.cover.url)) From e72c3e11dda8a15519c342fcc2f5ace21c0dbf9d Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 20 Dec 2020 12:54:30 -0800 Subject: [PATCH 8/8] Fixes incoming user test --- bookwyrm/tests/test_incoming.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwyrm/tests/test_incoming.py b/bookwyrm/tests/test_incoming.py index 2cc4c1f4..7e58da86 100644 --- a/bookwyrm/tests/test_incoming.py +++ b/bookwyrm/tests/test_incoming.py @@ -464,7 +464,7 @@ class Incoming(TestCase): 'data/ap_user.json') userdata = json.loads(datafile.read_bytes()) del userdata['icon'] - self.assertEqual(self.local_user.name, '') + self.assertIsNone(self.local_user.name) incoming.handle_update_user({'object': userdata}) user = models.User.objects.get(id=self.local_user.id) self.assertEqual(user.name, 'MOUSE?? MOUSE!!')