mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-11-26 03:21:05 +00:00
Adds commenting
This commit is contained in:
parent
ff5217efd8
commit
9194b3c50d
8 changed files with 89 additions and 10 deletions
|
@ -1,7 +1,7 @@
|
|||
''' status serializers '''
|
||||
def get_review(review):
|
||||
''' fedireads json for book reviews '''
|
||||
status = get_status_json(review)
|
||||
status = get_status(review)
|
||||
status['inReplyTo'] = review.book.absolute_id
|
||||
status['fedireadsType'] = review.status_type,
|
||||
status['name'] = review.name
|
||||
|
|
|
@ -40,8 +40,17 @@ class ReviewForm(ModelForm):
|
|||
}
|
||||
|
||||
|
||||
class CommentForm(ModelForm):
|
||||
class Meta:
|
||||
model = models.Status
|
||||
fields = ['content']
|
||||
help_texts = {f: None for f in fields}
|
||||
labels = {'content': 'Comment'}
|
||||
|
||||
|
||||
class EditUserForm(ModelForm):
|
||||
class Meta:
|
||||
model = models.User
|
||||
fields = ['avatar', 'name', 'summary']
|
||||
help_texts = {f: None for f in fields}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ from fedireads import models
|
|||
from fedireads import outgoing
|
||||
from fedireads.status import create_review, create_status
|
||||
from fedireads.remote_user import get_or_create_remote_user
|
||||
from fedireads.settings import DOMAIN
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
|
@ -133,6 +134,34 @@ def get_status(request, username, status_id):
|
|||
return JsonResponse(activitypub.get_status(status))
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
def get_replies(request, username, status_id):
|
||||
''' ordered collection of replies to a status '''
|
||||
if request.method != 'GET':
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
replies = models.Status.objects.filter(
|
||||
reply_parent=status_id
|
||||
).first()
|
||||
|
||||
path_id = 'https://%s/user/%s/status/%s/replies' % \
|
||||
(DOMAIN, username, status_id)
|
||||
replies_activity = {
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
'id': path_id,
|
||||
'type': 'Collection',
|
||||
'first': {
|
||||
'id': '%s?page=true' % path_id,
|
||||
'type': 'CollectionPage',
|
||||
'next': '%s?only_other_accounts=true&page=true' % path_id,
|
||||
'partOf': path_id,
|
||||
'items': [replies.activity]
|
||||
}
|
||||
}
|
||||
return JsonResponse(replies_activity)
|
||||
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
def get_followers(request, username):
|
||||
''' return a list of followers for an actor '''
|
||||
|
|
|
@ -4,9 +4,9 @@ from django.views.decorators.csrf import csrf_exempt
|
|||
import requests
|
||||
from urllib.parse import urlencode
|
||||
|
||||
from fedireads import activitypub
|
||||
from fedireads import models
|
||||
from fedireads.status import create_review, create_status
|
||||
from fedireads import activitypub
|
||||
from fedireads.remote_user import get_or_create_remote_user
|
||||
from fedireads.broadcast import get_recipients, broadcast
|
||||
|
||||
|
@ -135,3 +135,14 @@ def handle_review(user, book, name, content, rating):
|
|||
recipients = get_recipients(user, 'public')
|
||||
broadcast(user, create_activity, recipients)
|
||||
|
||||
|
||||
def handle_comment(user, review, content):
|
||||
''' post a review '''
|
||||
# validated and saves the comment in the database so it has an id
|
||||
comment = create_status(user, content, reply_parent=review)
|
||||
comment_activity = activitypub.get_status(comment)
|
||||
create_activity = activitypub.get_create(user, comment_activity)
|
||||
|
||||
recipients = get_recipients(user, 'public')
|
||||
broadcast(user, create_activity, recipients)
|
||||
|
||||
|
|
|
@ -9,10 +9,7 @@ def create_review(user, possible_book, name, content, rating):
|
|||
# throws a value error if the book is not found
|
||||
book = get_or_create_book(possible_book)
|
||||
|
||||
# sanitize review html
|
||||
parser = InputHtmlParser()
|
||||
parser.feed(content)
|
||||
content = parser.get_output()
|
||||
content = sanitize(content)
|
||||
|
||||
# no ratings outside of 0-5
|
||||
rating = rating if 0 <= rating <= 5 else 0
|
||||
|
@ -41,8 +38,15 @@ def create_status(user, content, reply_parent=None, mention_books=None):
|
|||
reply_parent=reply_parent,
|
||||
)
|
||||
|
||||
if mention_books:
|
||||
for book in mention_books:
|
||||
status.mention_books.add(book)
|
||||
|
||||
return status
|
||||
|
||||
|
||||
def sanitize(content):
|
||||
''' remove invalid html from free text '''
|
||||
parser = InputHtmlParser()
|
||||
parser.feed(content)
|
||||
return parser.get_output()
|
||||
|
|
|
@ -66,7 +66,15 @@
|
|||
<p>{{ activity.rating | stars }}</p>
|
||||
<p>{{ activity.content | safe }}</p>
|
||||
</div>
|
||||
<div class="interaction"><button>⭐️ Like</button></div>
|
||||
<div class="interaction">
|
||||
<button>⭐️ Like</button>
|
||||
<form name="comment" action="/comment" method="post">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="review" value="{{ activity.id }}"></input>
|
||||
{{ comment_form.content }}
|
||||
<button type="submit">Comment</button>
|
||||
</form>
|
||||
</div>
|
||||
{% elif activity.status_type == 'Note' %}
|
||||
posted</h2>
|
||||
{{ activity.content | safe }}
|
||||
|
|
|
@ -24,7 +24,10 @@ urlpatterns = [
|
|||
r'^user/(?P<username>\w+)/(status|review)/(?P<status_id>\d+)/activity/?$',
|
||||
incoming.get_status
|
||||
),
|
||||
re_path(r'^user/(?P<username>\w+)/(status|review)/?$', incoming.get_following),
|
||||
re_path(
|
||||
r'^user/(?P<username>\w+)/(status|review)/(?P<status_id>\d+)/replies/?$',
|
||||
incoming.get_replies
|
||||
),
|
||||
# TODO: shelves need pages in the UI and for their activitypub Collection
|
||||
|
||||
# .well-known endpoints
|
||||
|
@ -47,6 +50,7 @@ urlpatterns = [
|
|||
|
||||
# internal action endpoints
|
||||
re_path(r'^review/?$', views.review),
|
||||
re_path(r'^comment/?$', views.comment),
|
||||
re_path(
|
||||
r'^shelve/(?P<username>\w+)/(?P<shelf_id>[\w-]+)/(?P<book_id>\d+)/?$',
|
||||
views.shelve
|
||||
|
|
|
@ -43,6 +43,7 @@ def home(request):
|
|||
'-created_date'
|
||||
)[:10]
|
||||
|
||||
comment_form = forms.CommentForm()
|
||||
data = {
|
||||
'user': request.user,
|
||||
'reading': reading,
|
||||
|
@ -50,6 +51,7 @@ def home(request):
|
|||
'recent_books': recent_books,
|
||||
'user_books': user_books,
|
||||
'activities': activities,
|
||||
'comment_form': comment_form,
|
||||
}
|
||||
return TemplateResponse(request, 'feed.html', data)
|
||||
|
||||
|
@ -250,6 +252,18 @@ def review(request):
|
|||
return redirect('/book/%s' % book_identifier)
|
||||
|
||||
|
||||
def comment(request):
|
||||
''' respond to a book review '''
|
||||
form = forms.CommentForm(request.POST)
|
||||
# this is a bit of a formality, the form is just one text field
|
||||
if not form.is_valid():
|
||||
return redirect('/')
|
||||
review_id = request.POST['review']
|
||||
parent = models.Review.objects.get(id=review_id)
|
||||
outgoing.handle_comment(request.user, parent, form.data['content'])
|
||||
return redirect('/')
|
||||
|
||||
|
||||
@login_required
|
||||
def follow(request):
|
||||
''' follow another user, here or abroad '''
|
||||
|
|
Loading…
Reference in a new issue