From f87a138d4988e92a498a1b438a54545439c9eb91 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 5 Jan 2021 21:23:36 -0800 Subject: [PATCH 1/7] Better matching for links in statuses --- bookwyrm/outgoing.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bookwyrm/outgoing.py b/bookwyrm/outgoing.py index 88377d33..f247b428 100644 --- a/bookwyrm/outgoing.py +++ b/bookwyrm/outgoing.py @@ -296,8 +296,7 @@ def find_mentions(content): def to_markdown(content): ''' catch links and convert to markdown ''' content = re.sub( - r'([^(href=")])(https?:\/\/([A-Za-z\.\-_\/]+' \ - r'\.[A-Za-z]{2,}[A-Za-z\.\-_\/]+))', + r'([^(href=")]|^)(https?:\/\/([\w\.\-_]+\.[a-z]{2,}(\/[\w\.\-_\/]+)?))', r'\g<1>\g<3>', content) content = markdown(content) From a25bc2383b667bbb0e0de3dc46f2d42632936add Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 6 Jan 2021 09:45:36 -0800 Subject: [PATCH 2/7] Improves tagging regex --- bookwyrm/outgoing.py | 9 ++++--- bookwyrm/tests/test_outgoing.py | 43 +++++++++++++++++++++++++++++++++ bookwyrm/utils/regex.py | 8 +++--- 3 files changed, 53 insertions(+), 7 deletions(-) diff --git a/bookwyrm/outgoing.py b/bookwyrm/outgoing.py index f247b428..7838b335 100644 --- a/bookwyrm/outgoing.py +++ b/bookwyrm/outgoing.py @@ -293,12 +293,15 @@ def find_mentions(content): yield (match.group(), mention_user) -def to_markdown(content): - ''' catch links and convert to markdown ''' - content = re.sub( +def format_links(content): + return re.sub( r'([^(href=")]|^)(https?:\/\/([\w\.\-_]+\.[a-z]{2,}(\/[\w\.\-_\/]+)?))', r'\g<1>\g<3>', content) + +def to_markdown(content): + ''' catch links and convert to markdown ''' + content = format_links(content) content = markdown(content) # sanitize resulting html sanitizer = InputHtmlParser() diff --git a/bookwyrm/tests/test_outgoing.py b/bookwyrm/tests/test_outgoing.py index e004d109..c99b89c0 100644 --- a/bookwyrm/tests/test_outgoing.py +++ b/bookwyrm/tests/test_outgoing.py @@ -447,3 +447,46 @@ class Outgoing(TestCase): self.assertEqual(reply.user, user) self.assertTrue(self.remote_user in reply.mention_users.all()) self.assertTrue(self.local_user in reply.mention_users.all()) + + def test_find_mentions(self): + ''' detect and look up @ mentions of users ''' + user = models.User.objects.create_user( + 'nutria@%s' % DOMAIN, 'nutria@nutria.com', 'password', + local=True, localname='nutria') + self.assertEqual(user.username, 'nutria@%s' % DOMAIN) + + self.assertEqual( + list(outgoing.find_mentions('@nutria'))[0], + ('@nutria', user) + ) + self.assertEqual( + list(outgoing.find_mentions('leading text @nutria'))[0], + ('@nutria', user) + ) + self.assertEqual( + list(outgoing.find_mentions('leading @nutria trailing text'))[0], + ('@nutria', user) + ) + self.assertEqual( + list(outgoing.find_mentions('@rat@example.com'))[0], + ('@rat@example.com', self.remote_user) + ) + + multiple = list(outgoing.find_mentions('@nutria and @rat@example.com')) + self.assertEqual(multiple[0], ('@nutria', user)) + self.assertEqual(multiple[1], ('@rat@example.com', self.remote_user)) + + with patch('bookwyrm.outgoing.handle_remote_webfinger') as rw: + rw.return_value = self.local_user + self.assertEqual( + list(outgoing.find_mentions('@beep@beep.com'))[0], + ('@beep@beep.com', self.local_user) + ) + with patch('bookwyrm.outgoing.handle_remote_webfinger') as rw: + rw.return_value = None + self.assertEqual(list(outgoing.find_mentions('@beep@beep.com')), []) + + self.assertEqual( + list(outgoing.find_mentions('@nutria@%s' % DOMAIN))[0], + ('@nutria@%s' % DOMAIN, user) + ) diff --git a/bookwyrm/utils/regex.py b/bookwyrm/utils/regex.py index 9553c913..b087b564 100644 --- a/bookwyrm/utils/regex.py +++ b/bookwyrm/utils/regex.py @@ -1,10 +1,10 @@ ''' defining regexes for regularly used concepts ''' -domain = r'[a-z-A-Z0-9_\-]+\.[a-z]+' -localname = r'@?[a-zA-Z_\-\.0-9]+' +domain = r'[\w_\-\.]+\.[a-z]{2,}' +localname = r'@?[a-zA-Z_\-\.0-9]+\b' strict_localname = r'@[a-zA-Z_\-\.0-9]+' username = r'%s(@%s)?' % (localname, domain) -strict_username = r'%s(@%s)?' % (strict_localname, domain) -full_username = r'%s@%s' % (localname, domain) +strict_username = r'\B%s(@%s)?\b' % (strict_localname, domain) +full_username = r'\B%s@%s\b' % (localname, domain) # should match (BookWyrm/1.0.0; or (BookWyrm/99.1.2; bookwyrm_user_agent = r'\(BookWyrm/[0-9]+\.[0-9]+\.[0-9]+;' From 9e07f094ada98aec9c1932bf3c3013c71d7da684 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 6 Jan 2021 10:08:43 -0800 Subject: [PATCH 3/7] Improves link detecting regex --- bookwyrm/outgoing.py | 3 ++- bookwyrm/tests/test_outgoing.py | 13 +++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/bookwyrm/outgoing.py b/bookwyrm/outgoing.py index 7838b335..b438f5d1 100644 --- a/bookwyrm/outgoing.py +++ b/bookwyrm/outgoing.py @@ -294,8 +294,9 @@ def find_mentions(content): def format_links(content): + ''' detect and format links ''' return re.sub( - r'([^(href=")]|^)(https?:\/\/([\w\.\-_]+\.[a-z]{2,}(\/[\w\.\-_\/]+)?))', + r'([^(href=")]|^)(https?:\/\/(%s([\w\.\-_\/])*))' % regex.domain, r'\g<1>\g<3>', content) diff --git a/bookwyrm/tests/test_outgoing.py b/bookwyrm/tests/test_outgoing.py index c99b89c0..498b43d9 100644 --- a/bookwyrm/tests/test_outgoing.py +++ b/bookwyrm/tests/test_outgoing.py @@ -490,3 +490,16 @@ class Outgoing(TestCase): list(outgoing.find_mentions('@nutria@%s' % DOMAIN))[0], ('@nutria@%s' % DOMAIN, user) ) + + def test_format_links(self): + ''' find and format urls into a tags ''' + url = 'http://www.fish.com/' + self.assertEqual( + outgoing.format_links(url), + 'www.fish.com/' % url) + url = 'https://archive.org/details/dli.granth.72113/page/n25/mode/2up' + self.assertEqual( + outgoing.format_links(url), + '' \ + 'archive.org/details/dli.granth.72113/page/n25/mode/2up' \ + % url) From 6638c9bb44dca2def13f68baf0f3381fa401b8d5 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 6 Jan 2021 11:36:28 -0800 Subject: [PATCH 4/7] Handles query params in urls --- bookwyrm/outgoing.py | 3 ++- bookwyrm/tests/test_outgoing.py | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/bookwyrm/outgoing.py b/bookwyrm/outgoing.py index b438f5d1..bc170748 100644 --- a/bookwyrm/outgoing.py +++ b/bookwyrm/outgoing.py @@ -296,7 +296,8 @@ def find_mentions(content): def format_links(content): ''' detect and format links ''' return re.sub( - r'([^(href=")]|^)(https?:\/\/(%s([\w\.\-_\/])*))' % regex.domain, + r'([^(href=")]|^)(https?:\/\/(%s([\w\.\-_\/+&\?=:;,])*))' % \ + regex.domain, r'\g<1>\g<3>', content) diff --git a/bookwyrm/tests/test_outgoing.py b/bookwyrm/tests/test_outgoing.py index 498b43d9..ba0d7d7d 100644 --- a/bookwyrm/tests/test_outgoing.py +++ b/bookwyrm/tests/test_outgoing.py @@ -503,3 +503,9 @@ class Outgoing(TestCase): '' \ 'archive.org/details/dli.granth.72113/page/n25/mode/2up' \ % url) + url = 'https://openlibrary.org/search' \ + '?q=arkady+strugatsky&mode=everything' + self.assertEqual( + outgoing.format_links(url), + 'openlibrary.org/search' \ + '?q=arkady+strugatsky&mode=everything' % url) From 7bf57c60fb561ad2e7ff5e3ead50647a7032339a Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 6 Jan 2021 11:43:39 -0800 Subject: [PATCH 5/7] Avoid throwing database error trying to fav unknown statuses --- bookwyrm/incoming.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bookwyrm/incoming.py b/bookwyrm/incoming.py index 5e42fe45..920e99c5 100644 --- a/bookwyrm/incoming.py +++ b/bookwyrm/incoming.py @@ -251,6 +251,9 @@ def handle_delete_status(activity): def handle_favorite(activity): ''' approval of your good good post ''' fav = activitypub.Like(**activity) + # we dont know this status, we don't care about this status + if not models.Status.objects.filter(remote_id=fav.object).exists(): + return fav = fav.to_model(models.Favorite) if fav.user.local: From 054f69993b7877680daa4b28841fddb176403a59 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 6 Jan 2021 11:59:59 -0800 Subject: [PATCH 6/7] Support bidirectional text in status content --- bookwyrm/templates/snippets/status_content.html | 4 ++-- bookwyrm/templates/snippets/trimmed_text.html | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bookwyrm/templates/snippets/status_content.html b/bookwyrm/templates/snippets/status_content.html index d2663653..49e1ecfa 100644 --- a/bookwyrm/templates/snippets/status_content.html +++ b/bookwyrm/templates/snippets/status_content.html @@ -3,7 +3,7 @@ {% if status.status_type == 'Review' %}

- {% if status.name %}{{ status.name }}
{% endif %} + {% if status.name %}{{ status.name }}
{% endif %}

{% include 'snippets/stars.html' with rating=status.rating %}

@@ -27,7 +27,7 @@ {% if status.quote %}
-
{{ status.quote | safe }}
+
{{ status.quote | safe }}

— {% include 'snippets/book_titleby.html' with book=status.book %}

diff --git a/bookwyrm/templates/snippets/trimmed_text.html b/bookwyrm/templates/snippets/trimmed_text.html index e8a1fa75..c2fab3ff 100644 --- a/bookwyrm/templates/snippets/trimmed_text.html +++ b/bookwyrm/templates/snippets/trimmed_text.html @@ -6,18 +6,18 @@ {% if trimmed != full %}
-
-
{% else %} -
{{ full | to_markdown | safe }}
+
{{ full | to_markdown | safe }}
{% endif %} {% endwith %} From 67f2b3d808fb7ba2179cfbfb4b3375a303094f91 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 6 Jan 2021 13:13:19 -0800 Subject: [PATCH 7/7] Proper errorhandling for registration with invite --- bookwyrm/templates/invite.html | 9 ++++++++- bookwyrm/view_actions.py | 6 +++++- bookwyrm/views.py | 8 ++------ 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/bookwyrm/templates/invite.html b/bookwyrm/templates/invite.html index 42f564d6..458ce3df 100644 --- a/bookwyrm/templates/invite.html +++ b/bookwyrm/templates/invite.html @@ -3,7 +3,8 @@
-
diff --git a/bookwyrm/view_actions.py b/bookwyrm/view_actions.py index d27701b2..16f53702 100644 --- a/bookwyrm/view_actions.py +++ b/bookwyrm/view_actions.py @@ -81,8 +81,12 @@ def register(request): if errors: data = { 'login_form': forms.LoginForm(), - 'register_form': form + 'register_form': form, + 'invite': invite, + 'valid': invite.valid() if invite else True, } + if invite: + return TemplateResponse(request, 'invite.html', data) return TemplateResponse(request, 'login.html', data) username = '%s@%s' % (localname, DOMAIN) diff --git a/bookwyrm/views.py b/bookwyrm/views.py index 413039b4..f1851da8 100644 --- a/bookwyrm/views.py +++ b/bookwyrm/views.py @@ -377,17 +377,13 @@ def invite_page(request, code): ''' endpoint for sending invites ''' if request.user.is_authenticated: return redirect('/') - try: - invite = models.SiteInvite.objects.get(code=code) - if not invite.valid(): - raise PermissionDenied - except models.SiteInvite.DoesNotExist: - raise PermissionDenied + invite = get_object_or_404(models.SiteInvite, code=code) data = { 'title': 'Join', 'register_form': forms.RegisterForm(), 'invite': invite, + 'valid': invite.valid() if invite else True, } return TemplateResponse(request, 'invite.html', data)