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: diff --git a/bookwyrm/outgoing.py b/bookwyrm/outgoing.py index 88377d33..bc170748 100644 --- a/bookwyrm/outgoing.py +++ b/bookwyrm/outgoing.py @@ -293,13 +293,17 @@ def find_mentions(content): yield (match.group(), mention_user) -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\.\-_\/]+))', +def format_links(content): + ''' detect and format links ''' + return re.sub( + r'([^(href=")]|^)(https?:\/\/(%s([\w\.\-_\/+&\?=:;,])*))' % \ + regex.domain, 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/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/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 %} diff --git a/bookwyrm/tests/test_outgoing.py b/bookwyrm/tests/test_outgoing.py index e004d109..ba0d7d7d 100644 --- a/bookwyrm/tests/test_outgoing.py +++ b/bookwyrm/tests/test_outgoing.py @@ -447,3 +447,65 @@ 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) + ) + + 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) + 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) 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]+;' 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)