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">.*(div|span)>')
@@ -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