refactor review sync to timeline
This commit is contained in:
parent
88a688e32b
commit
aca017ade8
5 changed files with 68 additions and 106 deletions
|
@ -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(
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 = (
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue