Allow markdown in html fields

This commit is contained in:
Mouse Reeve 2020-12-19 18:54:56 -08:00
parent 27ec80515e
commit ef696782ab
8 changed files with 27 additions and 23 deletions

View file

@ -11,6 +11,7 @@ from django.core.files.base import ContentFile
from django.db import models
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from markdown import markdown
from bookwyrm import activitypub
from bookwyrm.sanitize_html import InputHtmlParser
from bookwyrm.settings import DOMAIN
@ -25,6 +26,7 @@ def validate_remote_id(value):
params={'value': value},
)
def validate_username(value):
''' make sure usernames look okay '''
if not re.match(r'^[A-Za-z\-_\.]+$', value):
@ -399,6 +401,16 @@ class HtmlField(ActivitypubFieldMixin, models.TextField):
sanitizer.feed(value)
return sanitizer.get_output()
def to_python(self, value):# pylint: disable=no-self-use
''' process markdown before save '''
if not value:
return value
content = markdown(value)
# sanitize resulting html
sanitizer = InputHtmlParser()
sanitizer.feed(content)
return sanitizer.get_output()
class ArrayField(ActivitypubFieldMixin, DjangoArrayField):
''' activitypub-aware array field '''
def field_to_activity(self, value):

View file

@ -211,17 +211,13 @@ def handle_status(user, form):
''' generic handler for statuses '''
status = form.save(commit=False)
if not status.sensitive and status.content_warning:
# the cw text field remains populated hen you click "remove"
# the cw text field remains populated when you click "remove"
status.content_warning = None
status.save()
# inspect the text for user tags
text = status.content
matches = re.finditer(
regex.username,
text
)
for match in matches:
for match in re.finditer(regex.username, text):
username = match.group().strip().split('@')[1:]
if len(username) == 1:
# this looks like a local user (@user), fill in the domain
@ -242,6 +238,7 @@ def handle_status(user, form):
related_user=user,
related_status=status
)
status.save()
# notify reply parent or tagged users

View file

@ -6,7 +6,11 @@ class InputHtmlParser(HTMLParser):#pylint: disable=abstract-method
def __init__(self):
HTMLParser.__init__(self)
self.allowed_tags = ['p', 'b', 'i', 'pre', 'a', 'span']
self.allowed_tags = [
'p', 'br',
'b', 'i', 'strong', 'em', 'pre',
'a', 'span', 'ul', 'ol', 'li'
]
self.tag_stack = []
self.output = []
# if the html appears invalid, we just won't allow any at all

View file

@ -137,8 +137,3 @@ input.toggle-control:checked ~ .modal.toggle-content {
content: "\e904";
right: 0;
}
/* --- BLOCKQUOTE --- */
blockquote {
white-space: pre-line;
}

View file

@ -103,14 +103,14 @@
<div>
{% for shelf in user_shelves %}
<p>
This edition is on your <a href="/user/{{ user.localname }}/shelves/{{ shelf.shelf.identifier }}">{{ shelf.shelf.name }}</a> shelf.
This edition is on your <a href="/user/{{ user.localname }}/shelf/{{ shelf.shelf.identifier }}">{{ shelf.shelf.name }}</a> shelf.
{% include 'snippets/shelf_selector.html' with current=shelf.shelf %}
</p>
{% endfor %}
{% for shelf in other_edition_shelves %}
<p>
A <a href="/book/{{ shelf.book.id }}">different edition</a> of this book is on your <a href="/user/{{ user.localname }}/shelves/{{ shelf.shelf.identifier }}">{{ shelf.shelf.name }}</a> shelf.
A <a href="/book/{{ shelf.book.id }}">different edition</a> of this book is on your <a href="/user/{{ user.localname }}/shelf/{{ shelf.shelf.identifier }}">{{ shelf.shelf.name }}</a> shelf.
{% include 'snippets/switch_edition_button.html' with edition=book %}
</p>
{% endfor %}

View file

@ -27,7 +27,7 @@
{% if status.quote %}
<div class="quote block">
<blockquote>{{ status.quote }}</blockquote>
<blockquote>{{ status.quote | safe }}</blockquote>
<p> &mdash; {% include 'snippets/book_titleby.html' with book=status.book %}</p>
</div>

View file

@ -615,18 +615,13 @@ def book_page(request, book_id):
book__parent_work=book.parent_work,
)
rating = reviews.aggregate(Avg('rating'))
tags = models.UserTag.objects.filter(
book=book,
)
data = {
'title': book.title,
'book': book,
'reviews': reviews_page,
'ratings': reviews.filter(content__isnull=True),
'rating': rating['rating__avg'],
'tags': tags,
'rating': reviews.aggregate(Avg('rating'))['rating__avg'],
'tags': models.UserTag.objects.filter(book=book),
'user_tags': user_tags,
'user_shelves': user_shelves,
'other_edition_shelves': other_edition_shelves,
@ -761,7 +756,7 @@ def shelf_page(request, username, shelf_identifier):
return JsonResponse(shelf.to_activity(**request.GET))
data = {
'title': user.name,
'title': '%s\'s %s shelf' % (user.display_name, shelf.name),
'user': user,
'is_self': is_self,
'shelves': shelves.all(),

View file

@ -4,6 +4,7 @@ Django==3.0.7
django-model-utils==4.0.0
environs==7.2.0
flower==0.9.4
Markdown==3.3.3
Pillow>=7.1.0
psycopg2==2.8.4
pycryptodome==3.9.4