mirror of
https://github.com/MCV-Software/TWBlue.git
synced 2026-03-06 09:27:33 +01:00
Plantillas
This commit is contained in:
@@ -350,7 +350,51 @@ class Handler:
|
|||||||
ask_default = True if current_mode in (None, "ask") else False
|
ask_default = True if current_mode in (None, "ask") else False
|
||||||
|
|
||||||
from wxUI.dialogs.blueski.configuration import AccountSettingsDialog
|
from wxUI.dialogs.blueski.configuration import AccountSettingsDialog
|
||||||
|
from .templateEditor import EditTemplate
|
||||||
dlg = AccountSettingsDialog(controller.view, ask_before_boost=ask_default)
|
dlg = AccountSettingsDialog(controller.view, ask_before_boost=ask_default)
|
||||||
|
try:
|
||||||
|
if buffer.session.settings.get("templates") is None:
|
||||||
|
buffer.session.settings["templates"] = {}
|
||||||
|
templates_cfg = buffer.session.settings.get("templates", {})
|
||||||
|
template_state = {
|
||||||
|
"post": templates_cfg.get("post", "$display_name, $safe_text $date."),
|
||||||
|
"person": templates_cfg.get("person", "$display_name (@$screen_name). $followers followers, $following following, $posts posts."),
|
||||||
|
"notification": templates_cfg.get("notification", "$display_name $text, $date"),
|
||||||
|
}
|
||||||
|
dlg.set_template_labels(template_state["post"], template_state["person"], template_state["notification"])
|
||||||
|
|
||||||
|
def edit_post_template(*args, **kwargs):
|
||||||
|
control = EditTemplate(template=template_state["post"], type="post")
|
||||||
|
result = control.run_dialog()
|
||||||
|
if result:
|
||||||
|
buffer.session.settings["templates"]["post"] = result
|
||||||
|
buffer.session.settings.write()
|
||||||
|
template_state["post"] = result
|
||||||
|
dlg.set_template_labels(template_state["post"], template_state["person"], template_state["notification"])
|
||||||
|
|
||||||
|
def edit_person_template(*args, **kwargs):
|
||||||
|
control = EditTemplate(template=template_state["person"], type="person")
|
||||||
|
result = control.run_dialog()
|
||||||
|
if result:
|
||||||
|
buffer.session.settings["templates"]["person"] = result
|
||||||
|
buffer.session.settings.write()
|
||||||
|
template_state["person"] = result
|
||||||
|
dlg.set_template_labels(template_state["post"], template_state["person"], template_state["notification"])
|
||||||
|
|
||||||
|
def edit_notification_template(*args, **kwargs):
|
||||||
|
control = EditTemplate(template=template_state["notification"], type="notification")
|
||||||
|
result = control.run_dialog()
|
||||||
|
if result:
|
||||||
|
buffer.session.settings["templates"]["notification"] = result
|
||||||
|
buffer.session.settings.write()
|
||||||
|
template_state["notification"] = result
|
||||||
|
dlg.set_template_labels(template_state["post"], template_state["person"], template_state["notification"])
|
||||||
|
|
||||||
|
widgetUtils.connect_event(dlg.template_post, widgetUtils.BUTTON_PRESSED, edit_post_template)
|
||||||
|
widgetUtils.connect_event(dlg.template_person, widgetUtils.BUTTON_PRESSED, edit_person_template)
|
||||||
|
widgetUtils.connect_event(dlg.template_notification, widgetUtils.BUTTON_PRESSED, edit_notification_template)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error("Failed to init Bluesky templates editor: %s", e)
|
||||||
resp = dlg.ShowModal()
|
resp = dlg.ShowModal()
|
||||||
if resp == wx.ID_OK:
|
if resp == wx.ID_OK:
|
||||||
vals = dlg.get_values()
|
vals = dlg.get_values()
|
||||||
|
|||||||
@@ -1,153 +1,45 @@
|
|||||||
from __future__ import annotations
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
import logging
|
import wx
|
||||||
from typing import TYPE_CHECKING, Any
|
from typing import List
|
||||||
|
from sessions.blueski.templates import post_variables, person_variables, notification_variables
|
||||||
# fromapprove.controller.mastodon import templateEditor as mastodon_template_editor # If adapting
|
from wxUI.dialogs import templateDialogs
|
||||||
fromapprove.translation import translate as _
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
fromapprove.sessions.blueski.session import Session as BlueskiSession # Adjusted
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
# This file would handle the logic for a template editor specific to Blueski.
|
|
||||||
# A template editor allows users to customize how certain information or messages
|
|
||||||
# from Blueski are displayed in Approve.
|
|
||||||
|
|
||||||
# For Blueski, this might be less relevant initially if its content structure
|
|
||||||
# is simpler than Mastodon's, or if user-customizable templates are not a primary feature.
|
|
||||||
# However, having the structure allows for future expansion.
|
|
||||||
|
|
||||||
# Example: Customizing the format of a "new follower" notification, or how a "skeet" is displayed.
|
|
||||||
|
|
||||||
class BlueskiTemplateEditor:
|
|
||||||
def __init__(self, session: BlueskiSession) -> None:
|
|
||||||
self.session = session
|
|
||||||
# self.user_id = session.user_id
|
|
||||||
# self.config_prefix = f"sessions.blueski.{self.user_id}.templates." # Example config path
|
|
||||||
|
|
||||||
def get_editable_templates(self) -> list[dict[str, Any]]:
|
|
||||||
"""
|
|
||||||
Returns a list of templates that the user can edit for Blueski.
|
|
||||||
Each entry should describe the template, its purpose, and current value.
|
|
||||||
"""
|
|
||||||
# This would typically fetch template definitions from a default set
|
|
||||||
# and override with any user-customized versions from config.
|
|
||||||
|
|
||||||
# Example structure for an editable template:
|
|
||||||
# templates = [
|
|
||||||
# {
|
|
||||||
# "id": "new_follower_notification", # Unique ID for this template
|
|
||||||
# "name": _("New Follower Notification Format"),
|
|
||||||
# "description": _("Customize how new follower notifications from Blueski are displayed."),
|
|
||||||
# "default_template": "{{ actor.displayName }} (@{{ actor.handle }}) is now following you on Blueski!",
|
|
||||||
# "current_template": self._get_template_content("new_follower_notification"),
|
|
||||||
# "variables": [ # Available variables for this template
|
|
||||||
# {"name": "actor.displayName", "description": _("Display name of the new follower")},
|
|
||||||
# {"name": "actor.handle", "description": _("Handle of the new follower")},
|
|
||||||
# {"name": "actor.url", "description": _("URL to the new follower's profile")},
|
|
||||||
# ],
|
|
||||||
# "category": "notifications", # For grouping in UI
|
|
||||||
# },
|
|
||||||
# # Add more editable templates for Blueski here
|
|
||||||
# ]
|
|
||||||
# return templates
|
|
||||||
return [] # Placeholder - no editable templates defined yet for Blueski
|
|
||||||
|
|
||||||
def _get_template_content(self, template_id: str) -> str:
|
|
||||||
"""
|
|
||||||
Retrieves the current content of a specific template, either user-customized or default.
|
|
||||||
"""
|
|
||||||
# config_key = self.config_prefix + template_id
|
|
||||||
# default_value = self._get_default_template_content(template_id)
|
|
||||||
# return approve.config.config.get_value(config_key, default_value) # Example config access
|
|
||||||
return self._get_default_template_content(template_id) # Placeholder
|
|
||||||
|
|
||||||
def _get_default_template_content(self, template_id: str) -> str:
|
|
||||||
"""
|
|
||||||
Returns the default content for a given template ID.
|
|
||||||
"""
|
|
||||||
# This could be hardcoded or loaded from a defaults file.
|
|
||||||
# if template_id == "new_follower_notification":
|
|
||||||
# return "{{ actor.displayName }} (@{{ actor.handle }}) is now following you on Blueski!"
|
|
||||||
# # ... other default templates
|
|
||||||
return "" # Placeholder
|
|
||||||
|
|
||||||
async def save_template_content(self, template_id: str, content: str) -> bool:
|
|
||||||
"""
|
|
||||||
Saves the user-customized content for a specific template.
|
|
||||||
"""
|
|
||||||
# config_key = self.config_prefix + template_id
|
|
||||||
# try:
|
|
||||||
# await approve.config.config.set_value(config_key, content) # Example config access
|
|
||||||
# logger.info(f"Blueski template '{template_id}' saved for user {self.user_id}.")
|
|
||||||
# return True
|
|
||||||
# except Exception as e:
|
|
||||||
# logger.error(f"Error saving Blueski template '{template_id}' for user {self.user_id}: {e}")
|
|
||||||
# return False
|
|
||||||
return False # Placeholder
|
|
||||||
|
|
||||||
def get_template_preview(self, template_id: str, custom_content: str | None = None) -> str:
|
|
||||||
"""
|
|
||||||
Generates a preview of a template using sample data.
|
|
||||||
If custom_content is provided, it's used instead of the saved template.
|
|
||||||
"""
|
|
||||||
# content_to_render = custom_content if custom_content is not None else self._get_template_content(template_id)
|
|
||||||
# sample_data = self._get_sample_data_for_template(template_id)
|
|
||||||
|
|
||||||
# try:
|
|
||||||
# # Use a templating engine (like Jinja2) to render the preview
|
|
||||||
# # from jinja2 import Template
|
|
||||||
# # template = Template(content_to_render)
|
|
||||||
# # preview = template.render(**sample_data)
|
|
||||||
# # return preview
|
|
||||||
# return f"Preview for '{template_id}': {content_to_render}" # Basic placeholder
|
|
||||||
# except Exception as e:
|
|
||||||
# logger.error(f"Error generating preview for Blueski template '{template_id}': {e}")
|
|
||||||
# return _("Error generating preview.")
|
|
||||||
return _("Template previews not yet implemented for Blueski.") # Placeholder
|
|
||||||
|
|
||||||
def _get_sample_data_for_template(self, template_id: str) -> dict[str, Any]:
|
|
||||||
"""
|
|
||||||
Returns sample data appropriate for previewing a specific template.
|
|
||||||
"""
|
|
||||||
# if template_id == "new_follower_notification":
|
|
||||||
# return {
|
|
||||||
# "actor": {
|
|
||||||
# "displayName": "Test User",
|
|
||||||
# "handle": "testuser.bsky.social",
|
|
||||||
# "url": "https://bsky.app/profile/testuser.bsky.social"
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
# # ... other sample data
|
|
||||||
return {} # Placeholder
|
|
||||||
|
|
||||||
# Functions to be called by the main controller/handler for template editor actions.
|
|
||||||
|
|
||||||
async def get_editor_config(session: BlueskiSession) -> dict[str, Any]:
|
|
||||||
"""
|
|
||||||
Get the configuration needed to display the template editor for Blueski.
|
|
||||||
"""
|
|
||||||
editor = BlueskiTemplateEditor(session)
|
|
||||||
return {
|
|
||||||
"editable_templates": editor.get_editable_templates(),
|
|
||||||
"help_text": _("Customize Blueski message formats. Use variables shown for each template."),
|
|
||||||
}
|
|
||||||
|
|
||||||
async def save_template(session: BlueskiSession, template_id: str, content: str) -> bool:
|
|
||||||
"""
|
|
||||||
Save a modified template for Blueski.
|
|
||||||
"""
|
|
||||||
editor = BlueskiTemplateEditor(session)
|
|
||||||
return await editor.save_template_content(template_id, content)
|
|
||||||
|
|
||||||
async def get_template_preview_html(session: BlueskiSession, template_id: str, content: str) -> str:
|
|
||||||
"""
|
|
||||||
Get an HTML preview for a template with given content.
|
|
||||||
"""
|
|
||||||
editor = BlueskiTemplateEditor(session)
|
|
||||||
return editor.get_template_preview(template_id, custom_content=content)
|
|
||||||
|
|
||||||
|
|
||||||
logger.info("Blueski template editor module loaded (placeholders).")
|
class EditTemplate(object):
|
||||||
|
def __init__(self, template: str, type: str) -> None:
|
||||||
|
super(EditTemplate, self).__init__()
|
||||||
|
self.default_template = template
|
||||||
|
if type == "post":
|
||||||
|
self.variables = post_variables
|
||||||
|
elif type == "notification":
|
||||||
|
self.variables = notification_variables
|
||||||
|
else:
|
||||||
|
self.variables = person_variables
|
||||||
|
self.template: str = template
|
||||||
|
|
||||||
|
def validate_template(self, template: str) -> bool:
|
||||||
|
used_variables: List[str] = re.findall(r"\$\w+", template)
|
||||||
|
validated: bool = True
|
||||||
|
for var in used_variables:
|
||||||
|
if var[1:] not in self.variables:
|
||||||
|
validated = False
|
||||||
|
return validated
|
||||||
|
|
||||||
|
def run_dialog(self) -> str:
|
||||||
|
dialog = templateDialogs.EditTemplateDialog(
|
||||||
|
template=self.template,
|
||||||
|
variables=self.variables,
|
||||||
|
default_template=self.default_template,
|
||||||
|
)
|
||||||
|
response = dialog.ShowModal()
|
||||||
|
if response == wx.ID_SAVE:
|
||||||
|
validated: bool = self.validate_template(dialog.template.GetValue())
|
||||||
|
if validated == False:
|
||||||
|
templateDialogs.invalid_template()
|
||||||
|
self.template = dialog.template.GetValue()
|
||||||
|
return self.run_dialog()
|
||||||
|
else:
|
||||||
|
return dialog.template.GetValue()
|
||||||
|
else:
|
||||||
|
return ""
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import languageHandler
|
|||||||
from pubsub import pub
|
from pubsub import pub
|
||||||
from controller.buffers.base import base
|
from controller.buffers.base import base
|
||||||
from controller.blueski import messages as blueski_messages
|
from controller.blueski import messages as blueski_messages
|
||||||
from sessions.blueski import compose, utils
|
from sessions.blueski import compose, utils, templates
|
||||||
from mysc.thread_utils import call_threaded
|
from mysc.thread_utils import call_threaded
|
||||||
from wxUI.buffers.blueski import panels as BlueskiPanels
|
from wxUI.buffers.blueski import panels as BlueskiPanels
|
||||||
from wxUI import commonMessageDialogs
|
from wxUI import commonMessageDialogs
|
||||||
@@ -739,11 +739,31 @@ class BaseBuffer(base.Buffer):
|
|||||||
item = self.get_item()
|
item = self.get_item()
|
||||||
if item is None:
|
if item is None:
|
||||||
return
|
return
|
||||||
# Use the compose function to get the full formatted text
|
relative_times = self.session.settings["general"].get("relative_times", False)
|
||||||
# Bluesky compose returns [user, text, date, source]
|
offset_hours = 0
|
||||||
composed = self.compose_function(item, self.session.db, self.session.settings, self.session.settings["general"].get("relative_times", False), self.session.settings["general"].get("show_screen_names", False))
|
if isinstance(self.session.db, dict):
|
||||||
# Join them for a full readout similar to Mastodon's template render
|
offset_hours = self.session.db.get("utc_offset", 0) or 0
|
||||||
return " ".join(composed)
|
template_settings = self.session.settings.get("templates", {})
|
||||||
|
try:
|
||||||
|
if self.type == "notifications":
|
||||||
|
template = template_settings.get("notification", "$display_name $text, $date")
|
||||||
|
post_template = template_settings.get("post", "$display_name, $safe_text $date.")
|
||||||
|
return templates.render_notification(item, template, post_template, self.session.settings, relative_times, offset_hours)
|
||||||
|
if self.type in ("user", "post_user_list"):
|
||||||
|
template = template_settings.get("person", "$display_name (@$screen_name). $followers followers, $following following, $posts posts.")
|
||||||
|
return templates.render_user(item, template, self.session.settings, relative_times, offset_hours)
|
||||||
|
template = template_settings.get("post", "$display_name, $safe_text $date.")
|
||||||
|
return templates.render_post(item, template, self.session.settings, relative_times, offset_hours)
|
||||||
|
except Exception:
|
||||||
|
# Fallback to compose if any template render fails.
|
||||||
|
composed = self.compose_function(
|
||||||
|
item,
|
||||||
|
self.session.db,
|
||||||
|
self.session.settings,
|
||||||
|
relative_times,
|
||||||
|
self.session.settings["general"].get("show_screen_names", False),
|
||||||
|
)
|
||||||
|
return " ".join(composed)
|
||||||
|
|
||||||
def view_conversation(self, *args, **kwargs):
|
def view_conversation(self, *args, **kwargs):
|
||||||
item = self.get_item()
|
item = self.get_item()
|
||||||
|
|||||||
218
src/sessions/blueski/templates.py
Normal file
218
src/sessions/blueski/templates.py
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import arrow
|
||||||
|
import languageHandler
|
||||||
|
from string import Template
|
||||||
|
|
||||||
|
|
||||||
|
post_variables = [
|
||||||
|
"date",
|
||||||
|
"display_name",
|
||||||
|
"screen_name",
|
||||||
|
"source",
|
||||||
|
"lang",
|
||||||
|
"safe_text",
|
||||||
|
"text",
|
||||||
|
"image_descriptions",
|
||||||
|
"visibility",
|
||||||
|
"pinned",
|
||||||
|
]
|
||||||
|
person_variables = [
|
||||||
|
"display_name",
|
||||||
|
"screen_name",
|
||||||
|
"description",
|
||||||
|
"followers",
|
||||||
|
"following",
|
||||||
|
"favorites",
|
||||||
|
"posts",
|
||||||
|
"created_at",
|
||||||
|
]
|
||||||
|
notification_variables = ["display_name", "screen_name", "text", "date"]
|
||||||
|
|
||||||
|
|
||||||
|
def _g(obj, key, default=None):
|
||||||
|
if isinstance(obj, dict):
|
||||||
|
return obj.get(key, default)
|
||||||
|
return getattr(obj, key, default)
|
||||||
|
|
||||||
|
|
||||||
|
def _extract_labels(obj):
|
||||||
|
labels = _g(obj, "labels", None)
|
||||||
|
if labels is None:
|
||||||
|
return []
|
||||||
|
if isinstance(labels, dict):
|
||||||
|
return labels.get("values", []) or []
|
||||||
|
if isinstance(labels, list):
|
||||||
|
return labels
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
def _extract_cw_text(post, record):
|
||||||
|
labels = _extract_labels(post) + _extract_labels(record)
|
||||||
|
for label in labels:
|
||||||
|
val = _g(label, "val", "")
|
||||||
|
if val == "warn":
|
||||||
|
return _("Sensitive Content")
|
||||||
|
if isinstance(val, str) and val.startswith("warn:"):
|
||||||
|
return val.split("warn:", 1)[-1].strip()
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
def _extract_image_descriptions(post, record):
|
||||||
|
def collect_images(embed):
|
||||||
|
if not embed:
|
||||||
|
return []
|
||||||
|
etype = _g(embed, "$type") or _g(embed, "py_type") or ""
|
||||||
|
if "recordWithMedia" in etype:
|
||||||
|
media = _g(embed, "media")
|
||||||
|
mtype = _g(media, "$type") or _g(media, "py_type") or ""
|
||||||
|
if "images" in mtype:
|
||||||
|
return list(_g(media, "images", []) or [])
|
||||||
|
return []
|
||||||
|
if "images" in etype:
|
||||||
|
return list(_g(embed, "images", []) or [])
|
||||||
|
return []
|
||||||
|
|
||||||
|
images = []
|
||||||
|
images.extend(collect_images(_g(post, "embed")))
|
||||||
|
if not images:
|
||||||
|
images.extend(collect_images(_g(record, "embed")))
|
||||||
|
|
||||||
|
descriptions = []
|
||||||
|
for idx, img in enumerate(images, start=1):
|
||||||
|
alt = _g(img, "alt", "") or ""
|
||||||
|
if alt:
|
||||||
|
descriptions.append(_("Media description {index}: {alt}").format(index=idx, alt=alt))
|
||||||
|
return "\n".join(descriptions)
|
||||||
|
|
||||||
|
|
||||||
|
def process_date(field, relative_times=True, offset_hours=0):
|
||||||
|
original_date = arrow.get(field)
|
||||||
|
if relative_times:
|
||||||
|
return original_date.humanize(locale=languageHandler.curLang[:2])
|
||||||
|
return original_date.shift(hours=offset_hours).format(_("dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.curLang[:2])
|
||||||
|
|
||||||
|
|
||||||
|
def render_post(post, template, settings, relative_times=False, offset_hours=0):
|
||||||
|
actual_post = _g(post, "post", post)
|
||||||
|
record = _g(actual_post, "record") or _g(post, "record") or {}
|
||||||
|
author = _g(actual_post, "author") or _g(post, "author") or {}
|
||||||
|
|
||||||
|
reason = _g(post, "reason")
|
||||||
|
is_repost = False
|
||||||
|
reposter = None
|
||||||
|
if reason:
|
||||||
|
rtype = _g(reason, "$type") or _g(reason, "py_type") or ""
|
||||||
|
if "reasonRepost" in rtype:
|
||||||
|
is_repost = True
|
||||||
|
reposter = _g(reason, "by")
|
||||||
|
|
||||||
|
if is_repost and reposter:
|
||||||
|
display_name = _g(reposter, "displayName") or _g(reposter, "display_name") or _g(reposter, "handle", "")
|
||||||
|
screen_name = _g(reposter, "handle", "")
|
||||||
|
else:
|
||||||
|
display_name = _g(author, "displayName") or _g(author, "display_name") or _g(author, "handle", "")
|
||||||
|
screen_name = _g(author, "handle", "")
|
||||||
|
|
||||||
|
text = _g(record, "text", "") or ""
|
||||||
|
if is_repost:
|
||||||
|
original_handle = _g(author, "handle", "")
|
||||||
|
text = _("Reposted from @{handle}: {text}").format(handle=original_handle, text=text)
|
||||||
|
|
||||||
|
cw_text = _extract_cw_text(actual_post, record)
|
||||||
|
safe_text = text
|
||||||
|
if cw_text:
|
||||||
|
safe_text = _("Content warning: {cw}").format(cw=cw_text)
|
||||||
|
|
||||||
|
created_at = _g(record, "createdAt") or _g(record, "created_at")
|
||||||
|
indexed_at = _g(actual_post, "indexedAt") or _g(actual_post, "indexed_at")
|
||||||
|
date_field = created_at or indexed_at
|
||||||
|
date = process_date(date_field, relative_times, offset_hours) if date_field else ""
|
||||||
|
|
||||||
|
langs = _g(record, "langs") or _g(record, "languages") or []
|
||||||
|
lang = langs[0] if isinstance(langs, list) and langs else ""
|
||||||
|
|
||||||
|
image_descriptions = _extract_image_descriptions(actual_post, record)
|
||||||
|
|
||||||
|
available_data = dict(
|
||||||
|
date=date,
|
||||||
|
display_name=display_name,
|
||||||
|
screen_name=screen_name,
|
||||||
|
source="Bluesky",
|
||||||
|
lang=lang,
|
||||||
|
safe_text=safe_text,
|
||||||
|
text=text,
|
||||||
|
image_descriptions=image_descriptions,
|
||||||
|
visibility=_("Public"),
|
||||||
|
pinned="",
|
||||||
|
)
|
||||||
|
return Template(_(template)).safe_substitute(**available_data)
|
||||||
|
|
||||||
|
|
||||||
|
def render_user(user, template, settings, relative_times=True, offset_hours=0):
|
||||||
|
display_name = _g(user, "displayName") or _g(user, "display_name") or _g(user, "handle", "")
|
||||||
|
screen_name = _g(user, "handle", "")
|
||||||
|
description = _g(user, "description", "") or ""
|
||||||
|
followers = _g(user, "followersCount", 0) or 0
|
||||||
|
following = _g(user, "followsCount", 0) or 0
|
||||||
|
posts = _g(user, "postsCount", 0) or 0
|
||||||
|
created_at = _g(user, "createdAt")
|
||||||
|
created = ""
|
||||||
|
if created_at:
|
||||||
|
created = process_date(created_at, relative_times, offset_hours)
|
||||||
|
|
||||||
|
available_data = dict(
|
||||||
|
display_name=display_name,
|
||||||
|
screen_name=screen_name,
|
||||||
|
description=description,
|
||||||
|
followers=followers,
|
||||||
|
following=following,
|
||||||
|
favorites="",
|
||||||
|
posts=posts,
|
||||||
|
created_at=created,
|
||||||
|
)
|
||||||
|
return Template(_(template)).safe_substitute(**available_data)
|
||||||
|
|
||||||
|
|
||||||
|
def render_notification(notification, template, post_template, settings, relative_times=False, offset_hours=0):
|
||||||
|
author = _g(notification, "author") or {}
|
||||||
|
display_name = _g(author, "displayName") or _g(author, "display_name") or _g(author, "handle", "")
|
||||||
|
screen_name = _g(author, "handle", "")
|
||||||
|
reason = _g(notification, "reason", "unknown")
|
||||||
|
record = _g(notification, "record") or {}
|
||||||
|
post_text = _g(record, "text", "") or ""
|
||||||
|
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
elif reason == "follow":
|
||||||
|
text = _("{username} has followed you.").format(username=display_name)
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
else:
|
||||||
|
text = "{user}: {reason}".format(user=display_name or screen_name, reason=reason)
|
||||||
|
|
||||||
|
indexed_at = _g(notification, "indexedAt") or _g(notification, "indexed_at")
|
||||||
|
date = process_date(indexed_at, relative_times, offset_hours) if indexed_at else ""
|
||||||
|
|
||||||
|
available_data = dict(
|
||||||
|
display_name=display_name,
|
||||||
|
screen_name=screen_name,
|
||||||
|
text=text,
|
||||||
|
date=date,
|
||||||
|
)
|
||||||
|
return Template(_(template)).safe_substitute(**available_data)
|
||||||
@@ -15,6 +15,15 @@ class AccountSettingsDialog(wx.Dialog):
|
|||||||
self.ask_before_boost.SetValue(bool(ask_before_boost))
|
self.ask_before_boost.SetValue(bool(ask_before_boost))
|
||||||
sizer.Add(self.ask_before_boost, 0, wx.ALL, 8)
|
sizer.Add(self.ask_before_boost, 0, wx.ALL, 8)
|
||||||
|
|
||||||
|
templates_box = wx.StaticBoxSizer(wx.StaticBox(panel, wx.ID_ANY, _("Templates")), wx.VERTICAL)
|
||||||
|
self.template_post = wx.Button(panel, wx.ID_ANY, _("Edit template for posts"))
|
||||||
|
self.template_person = wx.Button(panel, wx.ID_ANY, _("Edit template for persons"))
|
||||||
|
self.template_notification = wx.Button(panel, wx.ID_ANY, _("Edit template for notifications"))
|
||||||
|
templates_box.Add(self.template_post, 0, wx.ALL, 4)
|
||||||
|
templates_box.Add(self.template_person, 0, wx.ALL, 4)
|
||||||
|
templates_box.Add(self.template_notification, 0, wx.ALL, 4)
|
||||||
|
sizer.Add(templates_box, 0, wx.EXPAND | wx.ALL, 8)
|
||||||
|
|
||||||
# Buttons
|
# Buttons
|
||||||
btn_sizer = self.CreateSeparatedButtonSizer(wx.OK | wx.CANCEL)
|
btn_sizer = self.CreateSeparatedButtonSizer(wx.OK | wx.CANCEL)
|
||||||
|
|
||||||
@@ -31,3 +40,8 @@ class AccountSettingsDialog(wx.Dialog):
|
|||||||
"ask_before_boost": self.ask_before_boost.GetValue(),
|
"ask_before_boost": self.ask_before_boost.GetValue(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def set_template_labels(self, post_template, person_template, notification_template):
|
||||||
|
self.template_post.SetLabel(_("Edit template for posts. Current template: {}").format(post_template))
|
||||||
|
self.template_person.SetLabel(_("Edit template for persons. Current template: {}").format(person_template))
|
||||||
|
self.template_notification.SetLabel(_("Edit template for notifications. Current template: {}").format(notification_template))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user