mirror of
https://github.com/MCV-Software/TWBlue.git
synced 2026-03-06 09:27:33 +01:00
Chats, plantillas, movidas varias.
This commit is contained in:
@@ -222,42 +222,65 @@ def compose_notification(notification, db, settings, relative_times, show_screen
|
||||
# Notification reason/type
|
||||
reason = g(notification, "reason", "unknown")
|
||||
|
||||
# Get post text if available
|
||||
# Get post text - try multiple locations depending on notification type
|
||||
record = g(notification, "record", {})
|
||||
post_text = ""
|
||||
|
||||
# For mentions, replies, quotes: text is in the record itself
|
||||
post_text = g(record, "text", "")
|
||||
|
||||
# Format like Mastodon: "{username} has action: {status}"
|
||||
# For likes and reposts: try to get the subject post text
|
||||
if not post_text and reason in ("like", "repost"):
|
||||
# First check for hydrated subject text (added by NotificationBuffer)
|
||||
post_text = g(notification, "_subject_text", "")
|
||||
|
||||
# Check if there's a reasonSubject with embedded post data
|
||||
if not post_text:
|
||||
reason_subject = g(notification, "reasonSubject") or g(notification, "reason_subject")
|
||||
if reason_subject:
|
||||
# Sometimes the subject post is embedded
|
||||
subject_record = g(reason_subject, "record", {})
|
||||
post_text = g(subject_record, "text", "")
|
||||
|
||||
# Check if there's subject post data in other locations
|
||||
if not post_text:
|
||||
subject = g(record, "subject", {})
|
||||
subject_text = g(subject, "text", "")
|
||||
if subject_text:
|
||||
post_text = subject_text
|
||||
|
||||
# Format: action text without username (username is already in column 0)
|
||||
if reason == "like":
|
||||
if post_text:
|
||||
text = _("{username} has added to favorites: {status}").format(username=user_str, status=post_text)
|
||||
text = _("has added to favorites: {status}").format(status=post_text)
|
||||
else:
|
||||
text = _("{username} has added to favorites").format(username=user_str)
|
||||
text = _("has added to favorites")
|
||||
elif reason == "repost":
|
||||
if post_text:
|
||||
text = _("{username} has reposted: {status}").format(username=user_str, status=post_text)
|
||||
text = _("has reposted: {status}").format(status=post_text)
|
||||
else:
|
||||
text = _("{username} has reposted").format(username=user_str)
|
||||
text = _("has reposted")
|
||||
elif reason == "follow":
|
||||
text = _("{username} has followed you.").format(username=user_str)
|
||||
text = _("has followed you.")
|
||||
elif reason == "mention":
|
||||
if post_text:
|
||||
text = _("{username} has mentioned you: {status}").format(username=user_str, status=post_text)
|
||||
text = _("has mentioned you: {status}").format(status=post_text)
|
||||
else:
|
||||
text = _("{username} has mentioned you").format(username=user_str)
|
||||
text = _("has mentioned you")
|
||||
elif reason == "reply":
|
||||
if post_text:
|
||||
text = _("{username} has replied: {status}").format(username=user_str, status=post_text)
|
||||
text = _("has replied: {status}").format(status=post_text)
|
||||
else:
|
||||
text = _("{username} has replied").format(username=user_str)
|
||||
text = _("has replied")
|
||||
elif reason == "quote":
|
||||
if post_text:
|
||||
text = _("{username} has quoted your post: {status}").format(username=user_str, status=post_text)
|
||||
text = _("has quoted your post: {status}").format(status=post_text)
|
||||
else:
|
||||
text = _("{username} has quoted your post").format(username=user_str)
|
||||
text = _("has quoted your post")
|
||||
elif reason == "starterpack-joined":
|
||||
text = _("{username} has joined your starter pack.").format(username=user_str)
|
||||
text = _("has joined your starter pack.")
|
||||
else:
|
||||
text = f"{user_str}: {reason}"
|
||||
text = reason
|
||||
|
||||
# Date
|
||||
indexed_at = g(notification, "indexedAt", "") or g(notification, "indexed_at", "")
|
||||
@@ -315,10 +338,10 @@ def compose_user(user, db, settings, relative_times, show_screen_names=False, sa
|
||||
ts = ""
|
||||
|
||||
# Format like Mastodon: "Name (@handle). X followers, Y following, Z posts. Joined date"
|
||||
if ts:
|
||||
return [_("%s (@%s). %s followers, %s following, %s posts. Joined %s") % (display_name, handle, followers, following, posts, ts)]
|
||||
else:
|
||||
return [_("%s (@%s). %s followers, %s following, %s posts.") % (display_name, handle, followers, following, posts)]
|
||||
# Use the exact same translatable string as Mastodon (sessions/mastodon/compose.py)
|
||||
if not ts:
|
||||
ts = _("unknown")
|
||||
return [_("%s (@%s). %s followers, %s following, %s posts. Joined %s") % (display_name, handle, followers, following, posts, ts)]
|
||||
|
||||
|
||||
def compose_convo(convo, db, settings, relative_times, show_screen_names=False, safe=True):
|
||||
|
||||
@@ -528,12 +528,18 @@ class Session(base.baseSession):
|
||||
api = self._ensure_client()
|
||||
if not actors:
|
||||
return {"items": []}
|
||||
try:
|
||||
res = api.app.bsky.actor.get_profiles({"actors": actors})
|
||||
return {"items": getattr(res, "profiles", []) or []}
|
||||
except Exception:
|
||||
log.exception("Error fetching Bluesky profiles batch")
|
||||
return {"items": []}
|
||||
# API limit is 25 actors per request, batch if needed
|
||||
all_profiles = []
|
||||
batch_size = 25
|
||||
for i in range(0, len(actors), batch_size):
|
||||
batch = actors[i:i + batch_size]
|
||||
try:
|
||||
res = api.app.bsky.actor.get_profiles({"actors": batch})
|
||||
profiles = getattr(res, "profiles", []) or []
|
||||
all_profiles.extend(profiles)
|
||||
except Exception:
|
||||
log.exception("Error fetching Bluesky profiles batch")
|
||||
return {"items": all_profiles}
|
||||
|
||||
def get_post_likes(self, uri: str, limit: int = 50, cursor: str | None = None) -> dict[str, Any]:
|
||||
api = self._ensure_client()
|
||||
@@ -734,24 +740,57 @@ class Session(base.baseSession):
|
||||
api = self._ensure_client()
|
||||
# Chat API requires using the chat proxy
|
||||
dm_client = api.with_bsky_chat_proxy()
|
||||
res = dm_client.chat.bsky.convo.list_convos({"limit": limit, "cursor": cursor})
|
||||
return {"items": res.convos, "cursor": res.cursor}
|
||||
dm = dm_client.chat.bsky.convo
|
||||
params = {"limit": limit}
|
||||
if cursor:
|
||||
params["cursor"] = cursor
|
||||
try:
|
||||
res = dm.list_convos(params)
|
||||
return {"items": res.convos, "cursor": getattr(res, "cursor", None)}
|
||||
except Exception:
|
||||
log.exception("Error listing conversations")
|
||||
return {"items": [], "cursor": None}
|
||||
|
||||
def get_convo_messages(self, convo_id: str, limit: int = 50, cursor: str | None = None) -> dict[str, Any]:
|
||||
api = self._ensure_client()
|
||||
dm_client = api.with_bsky_chat_proxy()
|
||||
res = dm_client.chat.bsky.convo.get_messages({"convoId": convo_id, "limit": limit, "cursor": cursor})
|
||||
return {"items": res.messages, "cursor": res.cursor}
|
||||
dm = dm_client.chat.bsky.convo
|
||||
params = {"convoId": convo_id, "limit": limit}
|
||||
if cursor:
|
||||
params["cursor"] = cursor
|
||||
try:
|
||||
res = dm.get_messages(params)
|
||||
return {"items": res.messages, "cursor": getattr(res, "cursor", None)}
|
||||
except Exception:
|
||||
log.exception("Error getting conversation messages")
|
||||
return {"items": [], "cursor": None}
|
||||
|
||||
def send_chat_message(self, convo_id: str, text: str) -> Any:
|
||||
api = self._ensure_client()
|
||||
dm_client = api.with_bsky_chat_proxy()
|
||||
return dm_client.chat.bsky.convo.send_message({
|
||||
"convoId": convo_id,
|
||||
"message": {
|
||||
"text": text
|
||||
}
|
||||
})
|
||||
dm = dm_client.chat.bsky.convo
|
||||
try:
|
||||
return dm.send_message({
|
||||
"convoId": convo_id,
|
||||
"message": {
|
||||
"text": text
|
||||
}
|
||||
})
|
||||
except Exception:
|
||||
log.exception("Error sending chat message")
|
||||
raise
|
||||
|
||||
def get_or_create_convo(self, members: list[str]) -> dict[str, Any] | None:
|
||||
"""Get or create a conversation with the given members (DIDs)."""
|
||||
api = self._ensure_client()
|
||||
dm_client = api.with_bsky_chat_proxy()
|
||||
dm = dm_client.chat.bsky.convo
|
||||
try:
|
||||
res = dm.get_convo_for_members({"members": members})
|
||||
return res.convo
|
||||
except Exception:
|
||||
log.exception("Error getting/creating conversation")
|
||||
return None
|
||||
|
||||
# Streaming/Polling methods
|
||||
|
||||
|
||||
@@ -227,32 +227,42 @@ def render_notification(notification, template, post_template, settings, relativ
|
||||
screen_name = _g(author, "handle", "")
|
||||
reason = _g(notification, "reason", "unknown")
|
||||
record = _g(notification, "record") or {}
|
||||
|
||||
# Get post text - try multiple locations depending on notification type
|
||||
post_text = _g(record, "text", "") or ""
|
||||
|
||||
# For likes and reposts: try to get the subject post text
|
||||
if not post_text and reason in ("like", "repost"):
|
||||
# First check for hydrated subject text (added by NotificationBuffer)
|
||||
post_text = _g(notification, "_subject_text", "") or ""
|
||||
|
||||
# Check if there's a reasonSubject with embedded post data
|
||||
if not post_text:
|
||||
reason_subject = _g(notification, "reasonSubject") or _g(notification, "reason_subject")
|
||||
if reason_subject:
|
||||
subject_record = _g(reason_subject, "record", {})
|
||||
post_text = _g(subject_record, "text", "") or ""
|
||||
|
||||
# Check subject in record
|
||||
if not post_text:
|
||||
subject = _g(record, "subject", {})
|
||||
post_text = _g(subject, "text", "") or ""
|
||||
|
||||
# Format: action text without username (username is already in display_name for template)
|
||||
if reason == "like":
|
||||
text = _("{username} has added to favorites: {status}").format(
|
||||
username=display_name, status=post_text
|
||||
) if post_text else _("{username} has added to favorites").format(username=display_name)
|
||||
text = _("has added to favorites: {status}").format(status=post_text) if post_text else _("has added to favorites")
|
||||
elif reason == "repost":
|
||||
text = _("{username} has reposted: {status}").format(
|
||||
username=display_name, status=post_text
|
||||
) if post_text else _("{username} has reposted").format(username=display_name)
|
||||
text = _("has reposted: {status}").format(status=post_text) if post_text else _("has reposted")
|
||||
elif reason == "follow":
|
||||
text = _("{username} has followed you.").format(username=display_name)
|
||||
text = _("has followed you.")
|
||||
elif reason == "mention":
|
||||
text = _("{username} has mentioned you: {status}").format(
|
||||
username=display_name, status=post_text
|
||||
) if post_text else _("{username} has mentioned you").format(username=display_name)
|
||||
text = _("has mentioned you: {status}").format(status=post_text) if post_text else _("has mentioned you")
|
||||
elif reason == "reply":
|
||||
text = _("{username} has replied: {status}").format(
|
||||
username=display_name, status=post_text
|
||||
) if post_text else _("{username} has replied").format(username=display_name)
|
||||
text = _("has replied: {status}").format(status=post_text) if post_text else _("has replied")
|
||||
elif reason == "quote":
|
||||
text = _("{username} has quoted your post: {status}").format(
|
||||
username=display_name, status=post_text
|
||||
) if post_text else _("{username} has quoted your post").format(username=display_name)
|
||||
text = _("has quoted your post: {status}").format(status=post_text) if post_text else _("has quoted your post")
|
||||
else:
|
||||
text = "{user}: {reason}".format(user=display_name or screen_name, reason=reason)
|
||||
text = reason
|
||||
|
||||
indexed_at = _g(notification, "indexedAt") or _g(notification, "indexed_at")
|
||||
date = process_date(indexed_at, relative_times, offset_hours) if indexed_at else ""
|
||||
|
||||
Reference in New Issue
Block a user