Merge pull request #1480 from bookwyrm-social/comment-formatting

Post-processes statuses composed in modals
This commit is contained in:
Mouse Reeve 2021-10-01 12:00:56 -07:00 committed by GitHub
commit a24fe558fc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 146 additions and 69 deletions

View file

@ -58,6 +58,9 @@ class ReadingViews(TestCase):
"post-status": True,
"privacy": "followers",
"start_date": "2020-01-05",
"book": self.book.id,
"mention_books": self.book.id,
"user": self.local_user.id,
},
)
request.user = self.local_user
@ -77,6 +80,45 @@ class ReadingViews(TestCase):
self.assertEqual(readthrough.user, self.local_user)
self.assertEqual(readthrough.book, self.book)
def test_start_reading_with_comment(self, *_):
"""begin a book"""
shelf = self.local_user.shelf_set.get(identifier=models.Shelf.READING)
self.assertFalse(shelf.books.exists())
self.assertFalse(models.Status.objects.exists())
request = self.factory.post(
"",
{
"post-status": True,
"privacy": "followers",
"start_date": "2020-01-05",
"content": "hello hello",
"book": self.book.id,
"mention_books": self.book.id,
"user": self.local_user.id,
"reading_status": "reading",
},
)
request.user = self.local_user
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"):
views.ReadingStatus.as_view()(request, "start", self.book.id)
self.assertEqual(shelf.books.get(), self.book)
status = models.Comment.objects.get()
self.assertEqual(status.user, self.local_user)
self.assertEqual(status.book, self.book)
self.assertFalse(status.mention_books.exists())
self.assertEqual(status.privacy, "followers")
self.assertEqual(status.content, "<p>hello hello</p>")
self.assertEqual(status.reading_status, "reading")
readthrough = models.ReadThrough.objects.get()
self.assertIsNotNone(readthrough.start_date)
self.assertIsNone(readthrough.finish_date)
self.assertEqual(readthrough.user, self.local_user)
self.assertEqual(readthrough.book, self.book)
@patch("bookwyrm.activitystreams.add_book_statuses_task.delay")
@patch("bookwyrm.activitystreams.remove_book_statuses_task.delay")
def test_start_reading_reshelve(self, *_):
@ -203,3 +245,42 @@ class ReadingViews(TestCase):
self.assertEqual(readthrough.finish_date.day, 7)
self.assertEqual(readthrough.book, self.book)
self.assertEqual(readthrough.user, self.local_user)
def test_update_progress_comment(self, *_):
"""update progress with commentary"""
readthrough = models.ReadThrough.objects.create(
user=self.local_user, start_date=timezone.now(), book=self.book
)
request = self.factory.post(
"",
{
"post-status": True,
"privacy": "followers",
"start_date": "2020-01-05",
"content": "hello hello",
"book": self.book.id,
"mention_books": self.book.id,
"user": self.local_user.id,
"id": readthrough.id,
"progress": 23,
"progress_mode": "PCT",
},
)
request.user = self.local_user
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"):
views.update_progress(request, self.book.id)
status = models.Comment.objects.get()
self.assertEqual(status.user, self.local_user)
self.assertEqual(status.book, self.book)
self.assertFalse(status.mention_books.exists())
self.assertEqual(status.privacy, "followers")
self.assertEqual(status.content, "<p>hello hello</p>")
self.assertIsNone(status.reading_status)
self.assertEqual(status.progress, 23)
self.assertEqual(status.progress_mode, "PCT")
self.assertIsNotNone(readthrough.start_date)
self.assertIsNone(readthrough.finish_date)
self.assertEqual(readthrough.user, self.local_user)
self.assertEqual(readthrough.book, self.book)

View file

@ -51,8 +51,7 @@ from .list import save_list, unsave_list, delete_list
from .login import Login, Logout
from .notifications import Notifications
from .outbox import Outbox
from .reading import edit_readthrough, create_readthrough
from .reading import delete_readthrough, delete_progressupdate
from .reading import create_readthrough, delete_readthrough, delete_progressupdate
from .reading import ReadingStatus
from .register import Register, ConfirmEmail, ConfirmEmailCode, resend_link
from .rss_feed import RssFeed
@ -62,6 +61,7 @@ from .shelf import Shelf
from .shelf import create_shelf, delete_shelf
from .shelf import shelve, unshelve
from .status import CreateStatus, DeleteStatus, DeleteAndRedraft, update_progress
from .status import edit_readthrough
from .updates import get_notification_count, get_unread_status_count
from .user import User, Followers, Following, hide_suggestions
from .wellknown import *

View file

@ -1,5 +1,10 @@
""" helper functions used in various views """
import re
from datetime import datetime
import dateutil.parser
import dateutil.tz
from dateutil.parser import ParserError
from requests import HTTPError
from django.core.exceptions import FieldError
from django.db.models import Q
@ -180,3 +185,15 @@ def get_landing_books():
.order_by("-review__published_date")[:6]
)
)
def load_date_in_user_tz_as_utc(date_str: str, user: models.User) -> datetime:
"""ensures that data is stored consistently in the UTC timezone"""
if not date_str:
return None
user_tz = dateutil.tz.gettz(user.preferred_timezone)
date = dateutil.parser.parse(date_str, ignoretz=True)
try:
return date.replace(tzinfo=user_tz).astimezone(dateutil.tz.UTC)
except ParserError:
return None

View file

@ -1,9 +1,4 @@
""" the good stuff! the books! """
from datetime import datetime
import dateutil.parser
import dateutil.tz
from dateutil.parser import ParserError
from django.contrib.auth.decorators import login_required
from django.db import transaction
from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseNotFound
@ -13,8 +8,10 @@ from django.utils.decorators import method_decorator
from django.views import View
from django.views.decorators.http import require_POST
from bookwyrm import forms, models
from bookwyrm import models
from .status import CreateStatus
from .helpers import get_edition, handle_reading_status, is_api_request
from .helpers import load_date_in_user_tz_as_utc
@method_decorator(login_required, name="dispatch")
@ -88,15 +85,9 @@ class ReadingStatus(View):
if request.POST.get("post-status"):
# is it a comment?
if request.POST.get("content"):
form = forms.CommentForm(request.POST)
if form.is_valid():
form.save()
else:
# uh oh
raise Exception(form.errors)
else:
privacy = request.POST.get("privacy")
handle_reading_status(request.user, desired_shelf, book, privacy)
return CreateStatus.as_view()(request, "comment")
privacy = request.POST.get("privacy")
handle_reading_status(request.user, desired_shelf, book, privacy)
if is_api_request(request):
return HttpResponse()
@ -133,45 +124,6 @@ def update_readthrough_on_shelve(
active_readthrough.save()
@login_required
@require_POST
def edit_readthrough(request):
"""can't use the form because the dates are too finnicky"""
readthrough = get_object_or_404(models.ReadThrough, id=request.POST.get("id"))
readthrough.raise_not_editable(request.user)
readthrough.start_date = load_date_in_user_tz_as_utc(
request.POST.get("start_date"), request.user
)
readthrough.finish_date = load_date_in_user_tz_as_utc(
request.POST.get("finish_date"), request.user
)
progress = request.POST.get("progress")
try:
progress = int(progress)
readthrough.progress = progress
except (ValueError, TypeError):
pass
progress_mode = request.POST.get("progress_mode")
try:
progress_mode = models.ProgressMode(progress_mode)
readthrough.progress_mode = progress_mode
except ValueError:
pass
readthrough.save()
# record the progress update individually
# use default now for date field
readthrough.create_update()
if is_api_request(request):
return HttpResponse()
return redirect(request.headers.get("Referer", "/"))
@login_required
@require_POST
def delete_readthrough(request):
@ -204,18 +156,6 @@ def create_readthrough(request):
return redirect("book", book.id)
def load_date_in_user_tz_as_utc(date_str: str, user: models.User) -> datetime:
"""ensures that data is stored consistently in the UTC timezone"""
if not date_str:
return None
user_tz = dateutil.tz.gettz(user.preferred_timezone)
date = dateutil.parser.parse(date_str, ignoretz=True)
try:
return date.replace(tzinfo=user_tz).astimezone(dateutil.tz.UTC)
except ParserError:
return None
@login_required
@require_POST
def delete_progressupdate(request):

View file

@ -18,7 +18,7 @@ from bookwyrm.sanitize_html import InputHtmlParser
from bookwyrm.settings import DOMAIN
from bookwyrm.utils import regex
from .helpers import handle_remote_webfinger, is_api_request
from .reading import edit_readthrough
from .helpers import load_date_in_user_tz_as_utc
# pylint: disable= no-self-use
@ -145,6 +145,45 @@ def update_progress(request, book_id): # pylint: disable=unused-argument
return edit_readthrough(request)
@login_required
@require_POST
def edit_readthrough(request):
"""can't use the form because the dates are too finnicky"""
readthrough = get_object_or_404(models.ReadThrough, id=request.POST.get("id"))
readthrough.raise_not_editable(request.user)
readthrough.start_date = load_date_in_user_tz_as_utc(
request.POST.get("start_date"), request.user
)
readthrough.finish_date = load_date_in_user_tz_as_utc(
request.POST.get("finish_date"), request.user
)
progress = request.POST.get("progress")
try:
progress = int(progress)
readthrough.progress = progress
except (ValueError, TypeError):
pass
progress_mode = request.POST.get("progress_mode")
try:
progress_mode = models.ProgressMode(progress_mode)
readthrough.progress_mode = progress_mode
except ValueError:
pass
readthrough.save()
# record the progress update individually
# use default now for date field
readthrough.create_update()
if is_api_request(request):
return HttpResponse()
return redirect(request.headers.get("Referer", "/"))
def find_mentions(content):
"""detect @mentions in raw status content"""
if not content: