Plantillas

This commit is contained in:
Jesús Pavón Abián
2026-02-01 21:10:46 +01:00
parent b14bff2d0e
commit 93d37ab3e8
5 changed files with 345 additions and 157 deletions

View File

@@ -350,7 +350,51 @@ class Handler:
ask_default = True if current_mode in (None, "ask") else False
from wxUI.dialogs.blueski.configuration import AccountSettingsDialog
from .templateEditor import EditTemplate
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()
if resp == wx.ID_OK:
vals = dlg.get_values()

View File

@@ -1,153 +1,45 @@
from __future__ import annotations
import logging
from typing import TYPE_CHECKING, Any
# fromapprove.controller.mastodon import templateEditor as mastodon_template_editor # If adapting
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)
# -*- coding: utf-8 -*-
import re
import wx
from typing import List
from sessions.blueski.templates import post_variables, person_variables, notification_variables
from wxUI.dialogs import templateDialogs
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 ""

View File

@@ -10,7 +10,7 @@ import languageHandler
from pubsub import pub
from controller.buffers.base import base
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 wxUI.buffers.blueski import panels as BlueskiPanels
from wxUI import commonMessageDialogs
@@ -739,11 +739,31 @@ class BaseBuffer(base.Buffer):
item = self.get_item()
if item is None:
return
# Use the compose function to get the full formatted text
# Bluesky compose returns [user, text, date, source]
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))
# Join them for a full readout similar to Mastodon's template render
return " ".join(composed)
relative_times = self.session.settings["general"].get("relative_times", False)
offset_hours = 0
if isinstance(self.session.db, dict):
offset_hours = self.session.db.get("utc_offset", 0) or 0
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):
item = self.get_item()