refactor review sync to timeline

This commit is contained in:
Your Name 2024-06-13 23:02:12 -04:00 committed by Henri Dickson
parent 88a688e32b
commit aca017ade8
5 changed files with 68 additions and 106 deletions

View file

@ -18,7 +18,7 @@ class ReviewForm(forms.ModelForm):
title = forms.CharField(label=_("Title")) title = forms.CharField(label=_("Title"))
body = MarkdownxFormField(label=_("Content (Markdown)"), strip=False) body = MarkdownxFormField(label=_("Content (Markdown)"), strip=False)
share_to_mastodon = forms.BooleanField( share_to_mastodon = forms.BooleanField(
label=_("Post to Fediverse"), initial=False, required=False label=_("Post to Fediverse"), initial=True, required=False
) )
id = forms.IntegerField(required=False, widget=forms.HiddenInput()) id = forms.IntegerField(required=False, widget=forms.HiddenInput())
visibility = forms.TypedChoiceField( visibility = forms.TypedChoiceField(

View file

@ -2,6 +2,7 @@ import re
from typing import TYPE_CHECKING, cast from typing import TYPE_CHECKING, cast
import mistune import mistune
from django.conf import settings
from django.utils.html import escape from django.utils.html import escape
from catalog.models import Item, ItemCategory from catalog.models import Item, ItemCategory
@ -62,3 +63,23 @@ def render_post_with_macro(txt: str, item: Item) -> str:
.replace("[title]", item.display_title) .replace("[title]", item.display_title)
.replace("[url]", item.absolute_url) .replace("[url]", item.absolute_url)
) )
def render_rating(score: int | None, star_mode=0) -> str:
"""convert score(0~10) to mastodon star emoji code"""
if score is None or score == "" or score == 0:
return ""
solid_stars = score // 2
half_star = int(bool(score % 2))
empty_stars = 5 - solid_stars if not half_star else 5 - solid_stars - 1
if star_mode == 1:
emoji_code = "🌕" * solid_stars + "🌗" * half_star + "🌑" * empty_stars
else:
emoji_code = (
settings.STAR_SOLID * solid_stars
+ settings.STAR_HALF * half_star
+ settings.STAR_EMPTY * empty_stars
)
emoji_code = emoji_code.replace("::", ": :")
emoji_code = " " + emoji_code + " "
return emoji_code

View file

@ -2,19 +2,22 @@ import re
from datetime import datetime from datetime import datetime
from functools import cached_property from functools import cached_property
from django.conf import settings
from django.db import models from django.db import models
from django.utils import timezone from django.utils import timezone
from django.utils.translation import gettext as _
from markdownify import markdownify as md from markdownify import markdownify as md
from markdownx.models import MarkdownxField from markdownx.models import MarkdownxField
from catalog.models import Item from catalog.models import Item
from mastodon.api import boost_toot_later, share_review from mastodon.api import boost_toot_later
from takahe.utils import Takahe from takahe.utils import Takahe
from users.models import APIdentity from users.models import APIdentity
from .common import Content from .common import Content
from .rating import Rating from .rating import Rating
from .renderers import render_md from .renderers import render_md, render_post_with_macro, render_rating
from .shelf import ShelfManager
_RE_HTML_TAG = re.compile(r"<[^>]*>") _RE_HTML_TAG = re.compile(r"<[^>]*>")
_RE_SPOILER_TAG = re.compile(r'<(div|span)\sclass="spoiler">.*</(div|span)>') _RE_SPOILER_TAG = re.compile(r'<(div|span)\sclass="spoiler">.*</(div|span)>')
@ -75,6 +78,38 @@ class Review(Content):
p.link_post_id(post.id) p.link_post_id(post.id)
return p return p
def get_repost_postfix(self):
tags = render_post_with_macro(
self.owner.user.preference.mastodon_append_tag, self.item
)
return "\n" + tags if tags else ""
def get_repost_template(self):
return _(ShelfManager.get_action_template("reviewed", self.item.category))
def to_mastodon_params(self):
content = (
self.get_repost_template().format(item=self.item.display_title)
+ f"\n{self.title}\n{self.absolute_url} "
+ self.get_repost_postfix()
)
params = {"content": content}
return params
def to_post_params(self):
item_link = f"{settings.SITE_INFO['site_url']}/~neodb~{self.item.url}"
pre_conetent = (
self.get_repost_template().format(
item=f'<a href="{item_link}">{self.item.display_title}</a>'
)
+ f'<br><a href="{self.absolute_url}">{self.title}</a>'
)
content = f"{render_rating(self.rating_grade, 1)}\n{self.get_repost_postfix()}"
return {
"pre_conetent": pre_conetent,
"content": content,
}
@cached_property @cached_property
def mark(self): def mark(self):
from .mark import Mark from .mark import Mark
@ -98,13 +133,13 @@ class Review(Content):
created_time=None, created_time=None,
share_to_mastodon: bool = False, share_to_mastodon: bool = False,
): ):
from takahe.utils import Takahe review = Review.objects.filter(owner=owner, item=item).first()
delete_existing_post = False
if title is None: if review is not None:
review = Review.objects.filter(owner=owner, item=item).first() if title is None:
if review is not None:
review.delete() review.delete()
return None return
delete_existing_post = review.visibility != visibility
defaults = { defaults = {
"title": title, "title": title,
"body": body, "body": body,
@ -117,13 +152,7 @@ class Review(Content):
review, created = cls.objects.update_or_create( review, created = cls.objects.update_or_create(
item=item, owner=owner, defaults=defaults item=item, owner=owner, defaults=defaults
) )
post = Takahe.post_review(review, created) review.sync_to_timeline(delete_existing=delete_existing_post)
if post and share_to_mastodon: if share_to_mastodon:
if ( review.sync_to_mastodon(delete_existing=delete_existing_post)
owner.user.preference.mastodon_repost_mode == 1
and owner.user.mastodon_site
):
share_review(review)
else:
boost_toot_later(owner.user, post.url)
return review return review

View file

@ -718,47 +718,6 @@ def share_mark(mark, post_as_new=False):
return False, response.status_code if response is not None else -1 return False, response.status_code if response is not None else -1
def share_review(review):
from catalog.common import ItemCategory
from journal.models import ShelfManager
user = review.owner.user
visibility = get_toot_visibility(review.visibility, user)
tags = (
"\n"
+ user.preference.mastodon_append_tag.replace(
"[category]", str(ItemCategory(review.item.category).label)
)
if user.preference.mastodon_append_tag
else ""
)
tpl = ShelfManager.get_action_template("reviewed", review.item.category)
content = (
_(tpl).format(item=review.item.display_title)
+ f"\n{review.title}\n{review.absolute_url} "
+ tags
)
update_id = None
if review.metadata.get(
"shared_link"
): # "https://mastodon.social/@username/1234567890"
r = re.match(
r".+/(\w+)$", review.metadata.get("shared_link")
) # might be re.match(r'.+/([^/]+)$', u) if Pleroma supports edit
update_id = r[1] if r else None
response = post_toot(
user.mastodon_site, content, visibility, user.mastodon_token, False, update_id
)
if response is not None and response.status_code in [200, 201]:
j = response.json()
if "url" in j:
review.metadata["shared_link"] = j["url"]
review.save()
return True
else:
return False
def share_collection(collection, comment, user, visibility_no, link): def share_collection(collection, comment, user, visibility_no, link):
visibility = get_toot_visibility(visibility_no, user) visibility = get_toot_visibility(visibility_no, user)
tags = ( tags = (

View file

@ -663,53 +663,6 @@ class Takahe:
comment.link_post_id(post.pk) comment.link_post_id(post.pk)
return post return post
@staticmethod
def post_review(review, share_as_new_post: bool) -> Post | None:
from catalog.common import ItemCategory
from journal.models import ShelfManager
user = review.owner.user
tags = (
"\n"
+ user.preference.mastodon_append_tag.replace(
"[category]", str(ItemCategory(review.item.category).label)
)
if user.preference.mastodon_append_tag
else ""
)
stars = _rating_to_emoji(review.rating_grade, 1)
item_link = f"{settings.SITE_INFO['site_url']}/~neodb~{review.item.url}"
tpl = ShelfManager.get_action_template("reviewed", review.item.category)
pre_conetent = (
_(tpl).format(item=f'<a href="{item_link}">{review.item.display_title}</a>')
+ f'<br><a href="{review.absolute_url}">{review.title}</a>'
)
content = f"{stars}\n{tags}"
data = {
"object": {
"tag": [review.item.ap_object_ref],
"relatedWith": [review.ap_object],
}
}
v = Takahe.visibility_n2t(review.visibility, user.preference.post_public_mode)
existing_post = None if share_as_new_post else review.latest_post
post = Takahe.post( # TODO post as Article?
review.owner.pk,
content,
v,
pre_conetent,
None,
False,
data,
existing_post.pk if existing_post else None,
review.created_time,
)
if not post:
return
review.link_post_id(post.pk)
return post
@staticmethod @staticmethod
def post_mark(mark, share_as_new_post: bool, append_content="") -> Post | None: def post_mark(mark, share_as_new_post: bool, append_content="") -> Post | None:
from catalog.common import ItemCategory from catalog.common import ItemCategory