Merge pull request #3000 from dato/position_serialization

Minor improvements to Quotation pure content
This commit is contained in:
Mouse Reeve 2023-09-23 17:47:27 -07:00 committed by GitHub
commit bab28a8fc9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 29 deletions

View file

@ -1,5 +1,6 @@
""" models for storing different kinds of Activities """ """ models for storing different kinds of Activities """
from dataclasses import MISSING from dataclasses import MISSING
from typing import Optional
import re import re
from django.apps import apps from django.apps import apps
@ -269,7 +270,7 @@ class GeneratedNote(Status):
"""indicate the book in question for mastodon (or w/e) users""" """indicate the book in question for mastodon (or w/e) users"""
message = self.content message = self.content
books = ", ".join( books = ", ".join(
f'<a href="{book.remote_id}">"{book.title}"</a>' f'<a href="{book.remote_id}"><i>{book.title}</i></a>'
for book in self.mention_books.all() for book in self.mention_books.all()
) )
return f"{self.user.display_name} {message} {books}" return f"{self.user.display_name} {message} {books}"
@ -320,17 +321,14 @@ class Comment(BookStatus):
@property @property
def pure_content(self): def pure_content(self):
"""indicate the book in question for mastodon (or w/e) users""" """indicate the book in question for mastodon (or w/e) users"""
if self.progress_mode == "PG" and self.progress and (self.progress > 0): progress = self.progress or 0
return_value = ( citation = (
f'{self.content}<p>(comment on <a href="{self.book.remote_id}">' f'comment on <a href="{self.book.remote_id}">'
f'"{self.book.title}"</a>, page {self.progress})</p>' f"<i>{self.book.title}</i></a>"
) )
else: if self.progress_mode == "PG" and progress > 0:
return_value = ( citation += f", p. {progress}"
f'{self.content}<p>(comment on <a href="{self.book.remote_id}">' return f"{self.content}<p>({citation})</p>"
f'"{self.book.title}"</a>)</p>'
)
return return_value
activity_serializer = activitypub.Comment activity_serializer = activitypub.Comment
@ -354,22 +352,24 @@ class Quotation(BookStatus):
blank=True, blank=True,
) )
def _format_position(self) -> Optional[str]:
"""serialize page position"""
beg = self.position
end = self.endposition or 0
if self.position_mode != "PG" or not beg:
return None
return f"pp. {beg}-{end}" if end > beg else f"p. {beg}"
@property @property
def pure_content(self): def pure_content(self):
"""indicate the book in question for mastodon (or w/e) users""" """indicate the book in question for mastodon (or w/e) users"""
quote = re.sub(r"^<p>", '<p>"', self.quote) quote = re.sub(r"^<p>", '<p>"', self.quote)
quote = re.sub(r"</p>$", '"</p>', quote) quote = re.sub(r"</p>$", '"</p>', quote)
if self.position_mode == "PG" and self.position and (self.position > 0): title, href = self.book.title, self.book.remote_id
return_value = ( citation = f'— <a href="{href}"><i>{title}</i></a>'
f'{quote} <p>-- <a href="{self.book.remote_id}">' if position := self._format_position():
f'"{self.book.title}"</a>, page {self.position}</p>{self.content}' citation += f", {position}"
) return f"{quote} <p>{citation}</p>{self.content}"
else:
return_value = (
f'{quote} <p>-- <a href="{self.book.remote_id}">'
f'"{self.book.title}"</a></p>{self.content}'
)
return return_value
activity_serializer = activitypub.Quotation activity_serializer = activitypub.Quotation

View file

@ -5,7 +5,7 @@
{% block content %} {% block content %}
<div class="block"> <div class="block">
<h1 class="title">{% blocktrans with work_path=work.local_path work_title=work|book_title %}Editions of <a href="{{ work_path }}">"{{ work_title }}"</a>{% endblocktrans %}</h1> <h1 class="title">{% blocktrans with work_path=work.local_path work_title=work|book_title %}Editions of <a href="{{ work_path }}"><i>{{ work_title }}</i></a>{% endblocktrans %}</h1>
</div> </div>
{% include 'book/editions/edition_filters.html' %} {% include 'book/editions/edition_filters.html' %}

View file

@ -212,7 +212,7 @@ class Status(TestCase):
def test_generated_note_to_pure_activity(self, *_): def test_generated_note_to_pure_activity(self, *_):
"""subclass of the base model version with a "pure" serializer""" """subclass of the base model version with a "pure" serializer"""
status = models.GeneratedNote.objects.create( status = models.GeneratedNote.objects.create(
content="test content", user=self.local_user content="reads", user=self.local_user
) )
status.mention_books.set([self.book]) status.mention_books.set([self.book])
status.mention_users.set([self.local_user]) status.mention_users.set([self.local_user])
@ -220,7 +220,7 @@ class Status(TestCase):
self.assertEqual(activity["id"], status.remote_id) self.assertEqual(activity["id"], status.remote_id)
self.assertEqual( self.assertEqual(
activity["content"], activity["content"],
f'mouse test content <a href="{self.book.remote_id}">"Test Edition"</a>', f'mouse reads <a href="{self.book.remote_id}"><i>Test Edition</i></a>',
) )
self.assertEqual(len(activity["tag"]), 2) self.assertEqual(len(activity["tag"]), 2)
self.assertEqual(activity["type"], "Note") self.assertEqual(activity["type"], "Note")
@ -249,14 +249,18 @@ class Status(TestCase):
def test_comment_to_pure_activity(self, *_): def test_comment_to_pure_activity(self, *_):
"""subclass of the base model version with a "pure" serializer""" """subclass of the base model version with a "pure" serializer"""
status = models.Comment.objects.create( status = models.Comment.objects.create(
content="test content", user=self.local_user, book=self.book content="test content", user=self.local_user, book=self.book, progress=27
) )
activity = status.to_activity(pure=True) activity = status.to_activity(pure=True)
self.assertEqual(activity["id"], status.remote_id) self.assertEqual(activity["id"], status.remote_id)
self.assertEqual(activity["type"], "Note") self.assertEqual(activity["type"], "Note")
self.assertEqual( self.assertEqual(
activity["content"], activity["content"],
f'test content<p>(comment on <a href="{self.book.remote_id}">"Test Edition"</a>)</p>', (
"test content"
f'<p>(comment on <a href="{self.book.remote_id}">'
"<i>Test Edition</i></a>, p. 27)</p>"
),
) )
self.assertEqual(activity["attachment"][0]["type"], "Document") self.assertEqual(activity["attachment"][0]["type"], "Document")
# self.assertTrue( # self.assertTrue(
@ -295,7 +299,11 @@ class Status(TestCase):
self.assertEqual(activity["type"], "Note") self.assertEqual(activity["type"], "Note")
self.assertEqual( self.assertEqual(
activity["content"], activity["content"],
f'a sickening sense <p>-- <a href="{self.book.remote_id}">"Test Edition"</a></p>test content', (
"a sickening sense "
f'<p>— <a href="{self.book.remote_id}">'
"<i>Test Edition</i></a></p>test content"
),
) )
self.assertEqual(activity["attachment"][0]["type"], "Document") self.assertEqual(activity["attachment"][0]["type"], "Document")
self.assertTrue( self.assertTrue(
@ -306,6 +314,29 @@ class Status(TestCase):
) )
self.assertEqual(activity["attachment"][0]["name"], "Test Edition") self.assertEqual(activity["attachment"][0]["name"], "Test Edition")
def test_quotation_page_serialization(self, *_):
"""serialization of quotation page position"""
tests = [
("single pos", 7, None, "p. 7"),
("page range", 7, 10, "pp. 7-10"),
]
for desc, beg, end, pages in tests:
with self.subTest(desc):
status = models.Quotation.objects.create(
quote="<p>my quote</p>",
content="",
user=self.local_user,
book=self.book,
position=beg,
endposition=end,
position_mode="PG",
)
activity = status.to_activity(pure=True)
self.assertRegex(
activity["content"],
f'^<p>"my quote"</p> <p>— <a .+</a>, {pages}</p>$',
)
def test_review_to_activity(self, *_): def test_review_to_activity(self, *_):
"""subclass of the base model version with a "pure" serializer""" """subclass of the base model version with a "pure" serializer"""
status = models.Review.objects.create( status = models.Review.objects.create(