share to mastodon = reboost

This commit is contained in:
Your Name 2023-08-20 21:46:53 +00:00 committed by Henri Dickson
parent 0f1d1e0cde
commit 6710e7a950
4 changed files with 92 additions and 14 deletions

View file

@ -341,6 +341,15 @@ if DEBUG:
REDIS_HOST = os.environ.get("NEODB_REDIS_HOST", "127.0.0.1")
REDIS_PORT = int(os.environ.get("NEODB_REDIS_PORT", 6379))
REDIS_DB = int(os.environ.get("NEODB_REDIS_DB", 0))
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": f"redis://{REDIS_HOST}:{REDIS_PORT}/{REDIS_DB}",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
},
}
}
RQ_QUEUES = {
q: {

View file

@ -21,6 +21,7 @@ from catalog.common import jsondata
from catalog.common.models import Item, ItemCategory
from catalog.common.utils import DEFAULT_ITEM_COVER, piece_cover_path
from catalog.models import *
from mastodon.api import boost_toot
from takahe.utils import Takahe
from users.models import APIdentity
@ -88,8 +89,8 @@ class Mark:
if self.shelfmember:
return self.shelfmember.visibility
else:
logger.warning(f"no shelfmember for mark {self.owner}, {self.item}")
return 2
# mark not saved yet, return default visibility for editing ui
return self.owner.preference.default_visibility
@cached_property
def tags(self) -> list[str]:
@ -181,8 +182,23 @@ class Mark:
Rating.update_item_rating(self.item, self.owner, rating_grade, visibility)
self.rating_grade = rating_grade
if post_to_feed:
Takahe.post_mark(self, post_as_new)
post = Takahe.post_mark(self, post_as_new) if post_to_feed else None
if share_to_mastodon and post:
if (
self.owner.user
and self.owner.user.mastodon_token
and self.owner.user.mastodon_site
):
# TODO: make this a async task, given post to mastodon is slow and takahe post fanout may take time
if boost_toot(
self.owner.user.mastodon_site,
self.owner.user.mastodon_token,
post.url,
):
return True
return False
else:
return True
def delete(self):
# self.logs.delete() # When deleting a mark, all logs of the mark are deleted first.

View file

@ -67,6 +67,56 @@ def get_api_domain(domain):
# low level api below
def boost_toot(site, token, toot_url):
domain = get_api_domain(site)
headers = {
"User-Agent": USER_AGENT,
"Authorization": f"Bearer {token}",
}
url = (
"https://"
+ domain
+ API_SEARCH
+ "?type=statuses&resolve=true&q="
+ quote(toot_url)
)
try:
response = get(url, headers=headers)
if response.status_code != 200:
logger.error(f"Error search {toot_url} on {domain} {response.status_code}")
return None
j = response.json()
if "statuses" in j and len(j["statuses"]) > 0:
s = j["statuses"][0]
if s["uri"] != toot_url and s["url"] != toot_url:
logger.error(
f"Error status url mismatch {s['uri']} or {s['uri']} != {toot_url}"
)
return None
if s["reblogged"]:
logger.info(f"Already boosted {toot_url}")
# TODO unboost and boost again?
return None
url = (
"https://"
+ domain
+ API_PUBLISH_TOOT
+ "/"
+ j["statuses"][0]["id"]
+ "/reblog"
)
response = post(url, headers=headers)
if response.status_code != 200:
logger.error(
f"Error search {toot_url} on {domain} {response.status_code}"
)
return None
return response.json()
except Exception:
logger.error(f"Error search {toot_url} on {domain}")
return None
def post_toot(
site,
content,

View file

@ -345,7 +345,7 @@ class Takahe:
post_pk: int | None = None,
post_time: datetime.datetime | None = None,
reply_to_pk: int | None = None,
) -> int | None:
) -> Post | None:
identity = Identity.objects.get(pk=author_pk)
post = (
Post.objects.filter(author=identity, pk=post_pk).first()
@ -373,7 +373,7 @@ class Takahe:
published=post_time,
reply_to=reply_to_post,
)
return post.pk if post else None
return post
@staticmethod
def get_post(post_pk: int) -> str | None:
@ -390,7 +390,7 @@ class Takahe:
Post.objects.filter(pk=mark.shelfmember.post_id).update(state="deleted")
@staticmethod
def post_mark(mark, share_as_new_post: bool):
def post_mark(mark, share_as_new_post: bool) -> Post | None:
from catalog.common import ItemCategory
from takahe.utils import Takahe
@ -427,7 +427,7 @@ class Takahe:
v = Takahe.Visibilities.public
else:
v = Takahe.Visibilities.unlisted
post_pk = Takahe.post(
post = Takahe.post(
mark.owner.pk,
pre_conetent,
content,
@ -436,15 +436,18 @@ class Takahe:
None if share_as_new_post else mark.shelfmember.post_id,
mark.shelfmember.created_time,
)
if post_pk != mark.shelfmember.post_id:
mark.shelfmember.post_id = post_pk
if not post:
return
if post.pk != mark.shelfmember.post_id:
mark.shelfmember.post_id = post.pk
mark.shelfmember.save(update_fields=["post_id"])
if mark.comment and post_pk != mark.comment.post_id:
mark.comment.post_id = post_pk
if mark.comment and post.pk != mark.comment.post_id:
mark.comment.post_id = post.pk
mark.comment.save(update_fields=["post_id"])
if mark.rating and post_pk != mark.rating.post_id:
mark.rating.post_id = post_pk
if mark.rating and post.pk != mark.rating.post_id:
mark.rating.post_id = post.pk
mark.rating.save(update_fields=["post_id"])
return post
@staticmethod
def interact_post(post_pk: int, identity_pk: int, type: str):