refactor note footer handling

This commit is contained in:
Your Name 2024-06-15 21:54:39 -04:00 committed by Henri Dickson
parent 7157f3b0b0
commit 4872430203
9 changed files with 84 additions and 59 deletions

View file

@ -139,7 +139,7 @@ class Comment(Content):
def to_post_params(self):
item_link = f"{settings.SITE_INFO['site_url']}/~neodb~{self.item_url}"
pre_conetent = (
prepend_content = (
self.get_repost_template().format(
item=f'<a href="{item_link}">{self.item.display_title}</a>'
)
@ -148,7 +148,7 @@ class Comment(Content):
spoiler_text, txt = render_spoiler_text(self.text, self.item)
content = f"{txt}\n{self.get_repost_postfix()}"
return {
"pre_conetent": pre_conetent,
"prepend_content": prepend_content,
"content": content,
"summary": spoiler_text,
"sensitive": bool(spoiler_text),

View file

@ -297,27 +297,7 @@ class Piece(PolymorphicModel, UserOwnedObjectMixin):
d["edited_time"] = datetime.fromisoformat(obj["updated"])
p = cls.objects.create(**d)
p.link_post_id(post.id)
if local:
# a local piece is reconstructred from a post, update post and fanout
if not post.type_data:
post.type_data = {}
# always_merger.merge(
# post.type_data,
# {
# "object": {
# "tag": [item.ap_object_ref],
# "relatedWith": [p.ap_object],
# }
# },
# )
post.type_data = {
"object": {
"tag": [item.ap_object_ref],
"relatedWith": [p.ap_object],
}
}
post.save(update_fields=["type_data"])
Takahe.update_state(post, "edited")
# subclass may have to add additional code to update type_data in local post
return p
def sync_to_mastodon(self, delete_existing=False):

View file

@ -2,6 +2,7 @@ import re
from functools import cached_property
from typing import override
from deepmerge import always_merger
from django.db import models
from django.utils.translation import gettext_lazy as _
from loguru import logger
@ -15,7 +16,12 @@ from .renderers import render_text
from .shelf import ShelfMember
_progress = re.compile(
r"^\s*(?P<prefix>(p|pg|page|ch|chapter|pt|part|e|ep|episode|trk|track|cycle))?(\s|\.|#)*(?P<value>(\d[\d\:\.\-]*\d|\d))\s*(?P<postfix>(%))?\s*(\s|\n|\.|:)",
r"(.*\s)?(?P<prefix>(p|pg|page|ch|chapter|pt|part|e|ep|episode|trk|track|cycle))(\s|\.|#)*(?P<value>(\d[\d\:\.\-]*\d|\d))\s*(?P<postfix>(%))?(\s|\n|\.|。)?$",
re.IGNORECASE,
)
_progress2 = re.compile(
r"(.*\s)?(?P<value>(\d[\d\:\.\-]*\d|\d))\s*(?P<postfix>(%))?(\s|\n|\.|。)?$",
re.IGNORECASE,
)
@ -106,9 +112,17 @@ class Note(Content):
@override
@classmethod
def params_from_ap_object(cls, post, obj, piece):
content = obj.get("content", "").strip()
footer = []
if post.local:
# strip footer from local post if detected
lines = content.splitlines()
if len(lines) > 2 and lines[-2].strip() in ["", "-"]:
content = "\n".join(lines[:-2])
footer = lines[-2:]
params = {
"title": obj.get("title", post.summary),
"content": obj.get("content", "").strip(),
"content": content,
"sensitive": obj.get("sensitive", post.sensitive),
"attachments": [],
}
@ -117,12 +131,14 @@ class Note(Content):
params["progress_type"] = progress.get("type")
if progress.get("value"):
params["progress_value"] = progress.get("value")
if post.local:
progress_type, progress_value = cls.extract_progress(params["content"])
print(progress_type, progress_value)
if post.local and len(footer) == 2:
progress_type, progress_value = cls.extract_progress(footer[1])
if progress_value:
params["progress_type"] = progress_type
params["progress_value"] = progress_value
elif not footer[1].startswith("https://"):
# add footer back if unable to regconize correct patterns
params["content"] += "\n" + "\n".join(footer)
if post:
for atta in post.attachments.all():
params["attachments"].append(
@ -138,14 +154,16 @@ class Note(Content):
@override
@classmethod
def update_by_ap_object(cls, owner, item, obj, post):
# new_piece = cls.get_by_post_id(post.id) is None
p = super().update_by_ap_object(owner, item, obj, post)
if (
p
and p.local
and owner.user.preference.mastodon_default_repost
and owner.user.mastodon_username
):
p.sync_to_mastodon()
if p and p.local:
# if local piece is created from a post, update post type_data and fanout
p.sync_to_timeline()
if (
owner.user.preference.mastodon_default_repost
and owner.user.mastodon_username
):
p.sync_to_mastodon()
return p
@cached_property
@ -153,9 +171,10 @@ class Note(Content):
return ShelfMember.objects.filter(item=self.item, owner=self.owner).first()
def to_mastodon_params(self):
footer = f"\n\n{self.item.display_title}{self.progress_display}\n{self.item.absolute_url}"
params = {
"spoiler_text": self.title,
"content": self.content,
"content": self.content + footer,
"sensitive": self.sensitive,
"reply_to_toot_url": (
self.shelfmember.get_mastodon_repost_url() if self.shelfmember else None
@ -170,9 +189,11 @@ class Note(Content):
return params
def to_post_params(self):
footer = f'\n<p>—<br><a href="{self.item.absolute_url}">{self.item.display_title}</a> {self.progress_display}\n</p>'
return {
"summary": self.title,
"content": self.content,
"append_content": footer,
"sensitive": self.sensitive,
"reply_to_pk": (
self.shelfmember.latest_post_id if self.shelfmember else None
@ -183,8 +204,11 @@ class Note(Content):
@classmethod
def extract_progress(cls, content):
m = _progress.match(content)
if not m:
m = _progress2.match(content)
if m and m["value"]:
typ_ = "percentage" if m["postfix"] == "%" else m["prefix"]
m = m.groupdict()
typ_ = "percentage" if m["postfix"] == "%" else m.get("prefix", "")
match typ_:
case "p" | "pg" | "page":
typ = Note.ProgressType.PAGE

View file

@ -98,7 +98,7 @@ class Review(Content):
def to_post_params(self):
item_link = f"{settings.SITE_INFO['site_url']}/~neodb~{self.item.url}"
pre_conetent = (
prepend_content = (
self.get_repost_template().format(
item=f'<a href="{item_link}">{self.item.display_title}</a>'
)
@ -106,7 +106,7 @@ class Review(Content):
)
content = f"{render_rating(self.rating_grade, 1)}\n{self.get_repost_postfix()}"
return {
"pre_conetent": pre_conetent,
"prepend_content": prepend_content,
"content": content,
}

View file

@ -125,7 +125,6 @@ class WrappedShareView(LoginRequiredMixin, TemplateView):
identity.pk,
comment,
Takahe.visibility_n2t(visibility, user.preference.post_public_mode),
"",
attachments=[media],
)
classic_repost = user.preference.mastodon_repost_mode == 1

View file

@ -15,6 +15,7 @@ from journal.models import (
Review,
ShelfMember,
)
from users.middlewares import activate_language_for_user
from users.models.apidentity import APIdentity
from .models import Follow, Identity, Post, TimelineEvent
@ -102,6 +103,7 @@ def post_edited(pk, post_data):
def post_fetched(pk, post_data):
post = Post.objects.get(pk=pk)
owner = Takahe.get_or_create_remote_apidentity(post.author)
activate_language_for_user(owner.user)
if not post.type_data and not post_data:
logger.warning(f"Post {post} has no type_data")
return

View file

@ -1084,8 +1084,9 @@ class Post(models.Model):
def create_local(
cls,
author: Identity,
raw_prepend_content: str,
content: str,
raw_prepend_content: str,
raw_append_content: str,
summary: str | None = None,
sensitive: bool = False,
visibility: int = Visibilities.public,
@ -1107,7 +1108,10 @@ class Post(models.Model):
emojis = Emoji.emojis_from_content(content, None)
# Strip all unwanted HTML and apply linebreaks filter, grabbing hashtags on the way
parser = FediverseHtmlParser(linebreaks_filter(content), find_hashtags=True)
content = parser.html.replace("<p>", "<p>" + raw_prepend_content, 1)
content = (
parser.html.replace("<p>", "<p>" + raw_prepend_content, 1)
+ raw_append_content
)
hashtags = (
sorted([tag[: Hashtag.MAXIMUM_LENGTH] for tag in parser.hashtags])
or None
@ -1158,8 +1162,9 @@ class Post(models.Model):
def edit_local(
self,
raw_prepend_content: str,
content: str,
raw_prepend_content: str,
raw_append_content: str,
summary: str | None = None,
sensitive: bool | None = None,
visibility: int = Visibilities.public,
@ -1172,7 +1177,10 @@ class Post(models.Model):
with transaction.atomic():
# Strip all HTML and apply linebreaks filter
parser = FediverseHtmlParser(linebreaks_filter(content), find_hashtags=True)
self.content = parser.html.replace("<p>", "<p>" + raw_prepend_content, 1)
self.content = (
parser.html.replace("<p>", "<p>" + raw_prepend_content, 1)
+ raw_append_content
)
self.hashtags = (
sorted([tag[: Hashtag.MAXIMUM_LENGTH] for tag in parser.hashtags])
or None

View file

@ -444,7 +444,8 @@ class Takahe:
author_pk: int,
content: str,
visibility: Visibilities,
pre_conetent: str = "",
prepend_content: str = "",
append_content: str = "",
summary: str | None = None,
sensitive: bool = False,
data: dict | None = None,
@ -469,8 +470,9 @@ class Takahe:
raise ValueError(f"Cannot find post to reply: {reply_to_pk}")
if post:
post.edit_local(
pre_conetent,
content,
prepend_content,
append_content,
summary,
sensitive,
visibility=visibility,
@ -482,8 +484,9 @@ class Takahe:
else:
post = Post.create_local(
identity,
pre_conetent,
content,
prepend_content,
append_content,
summary,
sensitive,
visibility=visibility,
@ -589,7 +592,7 @@ class Takahe:
return existing_post
action = _("created collection")
item_link = collection.absolute_url
pre_conetent = f'{action} <a href="{item_link}">{collection.title}</a><br>'
prepend_content = f'{action} <a href="{item_link}">{collection.title}</a><br>'
content = collection.plain_content
if len(content) > 360:
content = content[:357] + "..."
@ -603,7 +606,8 @@ class Takahe:
collection.owner.pk,
content,
visibility,
pre_conetent,
prepend_content,
"",
None,
False,
data,
@ -622,7 +626,7 @@ class Takahe:
user = mark.owner.user
stars = _rating_to_emoji(mark.rating_grade, 1)
item_link = f"{settings.SITE_INFO['site_url']}/~neodb~{mark.item.url}"
pre_conetent = mark.get_action_for_feed(item_link=item_link)
prepend_content = mark.get_action_for_feed(item_link=item_link)
spoiler, txt = Takahe.get_spoiler_text(mark.comment_text, mark.item)
content = f"{stars} \n{txt}\n{mark.tag_text}"
data = {
@ -647,7 +651,8 @@ class Takahe:
mark.owner.pk,
content + append_content,
v,
pre_conetent,
prepend_content,
"",
spoiler,
spoiler is not None,
data,

View file

@ -3,14 +3,21 @@ from django.middleware.locale import LocaleMiddleware
from django.utils import translation
def activate_language_for_user(user, request=None):
user_language = None
if user and user.is_authenticated:
user_language = getattr(user, "language", "")
if not user_language:
if request:
user_language = translation.get_language_from_request(request)
else:
user_language = settings.LANGUAGE_CODE
# if user_language in dict(settings.LANGUAGES).keys():
translation.activate(user_language)
return translation.get_language()
class LanguageMiddleware(LocaleMiddleware):
def process_request(self, request):
user_language = None
user = getattr(request, "user", None)
if user and user.is_authenticated:
user_language = getattr(user, "language", "")
if not user_language:
user_language = translation.get_language_from_request(request)
# if user_language in dict(settings.LANGUAGES).keys():
translation.activate(user_language)
request.LANGUAGE_CODE = translation.get_language()
request.LANGUAGE_CODE = activate_language_for_user(user, request)