From aca017ade883b2e0f7fe4e36cbc96325f7ac93d8 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 13 Jun 2024 23:02:12 -0400 Subject: [PATCH] refactor review sync to timeline --- journal/forms.py | 2 +- journal/models/renderers.py | 21 +++++++++++++ journal/models/review.py | 63 +++++++++++++++++++++++++++---------- mastodon/api.py | 41 ------------------------ takahe/utils.py | 47 --------------------------- 5 files changed, 68 insertions(+), 106 deletions(-) diff --git a/journal/forms.py b/journal/forms.py index f910f0db..85567b94 100644 --- a/journal/forms.py +++ b/journal/forms.py @@ -18,7 +18,7 @@ class ReviewForm(forms.ModelForm): title = forms.CharField(label=_("Title")) body = MarkdownxFormField(label=_("Content (Markdown)"), strip=False) 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()) visibility = forms.TypedChoiceField( diff --git a/journal/models/renderers.py b/journal/models/renderers.py index bb2ddc0e..cfae1fcf 100644 --- a/journal/models/renderers.py +++ b/journal/models/renderers.py @@ -2,6 +2,7 @@ import re from typing import TYPE_CHECKING, cast import mistune +from django.conf import settings from django.utils.html import escape 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("[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 diff --git a/journal/models/review.py b/journal/models/review.py index 8120a8bb..8cc89dca 100644 --- a/journal/models/review.py +++ b/journal/models/review.py @@ -2,19 +2,22 @@ import re from datetime import datetime from functools import cached_property +from django.conf import settings from django.db import models from django.utils import timezone +from django.utils.translation import gettext as _ from markdownify import markdownify as md from markdownx.models import MarkdownxField 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 users.models import APIdentity from .common import Content 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_SPOILER_TAG = re.compile(r'<(div|span)\sclass="spoiler">.*') @@ -75,6 +78,38 @@ class Review(Content): p.link_post_id(post.id) 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'{self.item.display_title}' + ) + + f'
{self.title}' + ) + content = f"{render_rating(self.rating_grade, 1)}\n{self.get_repost_postfix()}" + return { + "pre_conetent": pre_conetent, + "content": content, + } + @cached_property def mark(self): from .mark import Mark @@ -98,13 +133,13 @@ class Review(Content): created_time=None, share_to_mastodon: bool = False, ): - from takahe.utils import Takahe - - if title is None: - review = Review.objects.filter(owner=owner, item=item).first() - if review is not None: + review = Review.objects.filter(owner=owner, item=item).first() + delete_existing_post = False + if review is not None: + if title is None: review.delete() - return None + return + delete_existing_post = review.visibility != visibility defaults = { "title": title, "body": body, @@ -117,13 +152,7 @@ class Review(Content): review, created = cls.objects.update_or_create( item=item, owner=owner, defaults=defaults ) - post = Takahe.post_review(review, created) - if post and share_to_mastodon: - if ( - owner.user.preference.mastodon_repost_mode == 1 - and owner.user.mastodon_site - ): - share_review(review) - else: - boost_toot_later(owner.user, post.url) + review.sync_to_timeline(delete_existing=delete_existing_post) + if share_to_mastodon: + review.sync_to_mastodon(delete_existing=delete_existing_post) return review diff --git a/mastodon/api.py b/mastodon/api.py index 3a26e542..d93249a4 100644 --- a/mastodon/api.py +++ b/mastodon/api.py @@ -718,47 +718,6 @@ def share_mark(mark, post_as_new=False): 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): visibility = get_toot_visibility(visibility_no, user) tags = ( diff --git a/takahe/utils.py b/takahe/utils.py index c2e63d00..063b3da3 100644 --- a/takahe/utils.py +++ b/takahe/utils.py @@ -663,53 +663,6 @@ class Takahe: comment.link_post_id(post.pk) 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'{review.item.display_title}') - + f'
{review.title}' - ) - 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 def post_mark(mark, share_as_new_post: bool, append_content="") -> Post | None: from catalog.common import ItemCategory