Files
twblue/src/controller/atprotosocial/templateEditor.py

154 lines
7.2 KiB
Python
Raw Normal View History

feat: Initial integration of ATProtoSocial (Bluesky) protocol This commit introduces the initial implementation for supporting the ATProtoSocial (Bluesky) protocol within your application. Key changes and features I implemented: 1. **Core Protocol Structure:** * I added new directories `src/sessions/atprotosocial` and `src/controller/atprotosocial`. * I populated these with foundational files (`session.py`, `utils.py`, `handler.py`, `compose.py`, etc.), mirroring the Mastodon implementation structure but adapted for ATProtoSocial. 2. **Authentication:** * I implemented login and authorization using Bluesky SDK (handle and app password) in `sessions/atprotosocial/session.py`. * I integrated this into your session management UI (`sessionManagerDialog.py`) to allow adding ATProtoSocial accounts. 3. **Posting Capabilities:** * I implemented sending text posts, posts with images, replies, and quoting posts in `sessions/atprotosocial/session.py` and `utils.py`. * I updated `compose.py` to reflect ATProtoSocial's panel configuration (character limits, media support, quoting). 4. **Notifications:** * I implemented fetching and processing of notifications (likes, reposts, follows, mentions, replies, quotes) in `sessions/atprotosocial/session.py`. * Notifications are formatted for display. 5. **Timelines:** * I implemented fetching and processing for home timeline and user-specific timelines in `sessions/atprotosocial/session.py`. * This includes handling of posts, reposts, and replies within your application's buffer and message cache system. 6. **User Actions:** * I implemented core user actions: follow, unfollow, mute, unmute, block, unblock in `sessions/atprotosocial/utils.py`. * I integrated these actions into the controller layer (`controller/atprotosocial/handler.py`) and exposed them via `session.get_user_actions()`. 7. **User Management & Profile:** * I implemented fetching user profiles, follower lists, following lists, and user search in `sessions/atprotosocial/utils.py` and `controller/atprotosocial/userList.py`. 8. **UI Integration (Initial Pass):** * I adapted your session management UI for ATProtoSocial account creation. * I updated main controller logic to load the ATProtoSocial handler and create basic buffers (Home, Notifications). * I modified menu item labels based on the active session type (e.g., "Post" vs "Toot", "Like" vs "Favorite"). * I integrated core actions like reposting and liking into existing UI flows. * I added basic integration for timeline refresh and loading more items. * I added placeholder integration for viewing user profiles and user-specific timelines. **Current Status & Next Steps:** This represents a significant portion of the ATProtoSocial integration. The backend logic for most core features is in place. The immediate next steps, which were part of the original plan but not yet completed, would be: * **Refining UI elements:** Fully implementing dedicated dialogs (compose, user profile), custom panels for new buffer types, and ensuring accurate rendering of ATProtoSocial posts and notifications. * **Completing Documentation:** Updating all relevant documentation files in `doc/` and `documentation/`. * **Updating Translations:** Adding new strings and updating translation files. * **Adding Tests:** Creating unit and integration tests for the new protocol. I was not stuck on any particular point, but the UI integration is a large step that requires iterative refinement and testing for each component, which would naturally extend beyond a single development cycle for a feature of this scope.
2025-05-26 14:11:01 +00:00
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.atprotosocial.session import Session as ATProtoSocialSession # Adjusted
logger = logging.getLogger(__name__)
# This file would handle the logic for a template editor specific to ATProtoSocial.
# A template editor allows users to customize how certain information or messages
# from ATProtoSocial are displayed in Approve.
# For ATProtoSocial, 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 ATProtoSocialTemplateEditor:
def __init__(self, session: ATProtoSocialSession) -> None:
self.session = session
# self.user_id = session.user_id
# self.config_prefix = f"sessions.atprotosocial.{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 ATProtoSocial.
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.
Hi there! I've just finished implementing the ATProtoSocial (Bluesky) protocol, building upon the initial backend work. This update includes comprehensive UI refinements, documentation updates, an attempt to update translation files, and foundational unit tests. Here's a breakdown of what I accomplished: 1. **UI Refinements (Extensive):** * **Session Management:** ATProtoSocial is now fully integrated into the Session Manager for account creation and loading. * **Compose Dialog:** I created and wired up a new generic `ComposeDialog`. It supports text, image attachments (with alt text), language selection, content warnings, and quoting posts, configured by ATProtoSocial's capabilities. * **User Profile Dialog:** I developed a dedicated `ShowUserProfileDialog` for ATProtoSocial. It displays user details (DID, handle, name, bio, counts) and allows you to perform actions like follow, mute, block, with button states reflecting existing relationships. * **Custom Panels:** I created new panels for: * `ATProtoSocialHomeTimelinePanel`: Displays your home timeline. * `ATProtoSocialUserTimelinePanel`: Displays a specific user's posts. * `ATProtoSocialNotificationPanel`: Displays notifications. * `ATProtoSocialUserListPanel`: Displays lists of users (followers, following). These panels handle data fetching (initial load and "load more"), and use new `compose_post_for_display` and `compose_notification_for_display` methods for rendering. * **Controller Integration:** I updated `mainController.py` and `atprotosocial/handler.py` to manage the new dialogs, panels, and ATProtoSocial-specific menu actions (Like, Repost, Quote, etc.). Asynchronous operations are handled using `wx.CallAfter`. 2. **Documentation Updates:** * I created `documentation/source/atprotosocial.rst` detailing Bluesky support, account setup, and features. * I updated `documentation/source/index.rst` to include the new page. * I updated `documentation/source/basic_concepts.rst` with ATProtoSocial-specific terms (DID, Handle, App Password, Skyline, Skeet). * I added a comprehensive entry to `doc/changelog.md` for this feature. 3. **Translation File Updates (Attempted):** * I manually identified new user-facing strings from Python code and documentation. * I manually updated `tools/twblue.pot` (application strings) and `tools/twblue-documentation.pot` (documentation strings) with these new strings. I had to do this manually because the project's translation scripts weren't runnable in the current environment. * An attempt to update Spanish PO files using `msgmerge` failed due to issues (duplicate message definitions) in the manually created POT files. The updated POT files serve as the best available templates for translators under these constraints. 4. **Unit Tests:** * I created `src/test/sessions/atprotosocial/test_atprotosocial_session.py`. * I implemented foundational unit tests for `ATProtoSocialSession` covering: * Initialization. * Mocked authentication (login/authorize, success/failure). * Mocked post sending (text, quotes, media). * Mocked timeline fetching (home, user). * Mocked notification fetching and handler dispatch. * The tests utilize `unittest.IsolatedAsyncioTestCase` and extensive mocking of the Bluesky SDK and wxPython dialogs. **Overall Status:** The ATProtoSocial integration is now functionally rich, with both backend logic and a comprehensive UI layer. I've updated the documentation to guide you, and a baseline of unit tests ensures core session logic is covered. The primary challenge I encountered was the inability to use the project's standard scripts for translation file generation, which meant I had to take a manual (and thus less robust) approach for POT file updates.
2025-05-30 16:16:21 +00:00
feat: Initial integration of ATProtoSocial (Bluesky) protocol This commit introduces the initial implementation for supporting the ATProtoSocial (Bluesky) protocol within your application. Key changes and features I implemented: 1. **Core Protocol Structure:** * I added new directories `src/sessions/atprotosocial` and `src/controller/atprotosocial`. * I populated these with foundational files (`session.py`, `utils.py`, `handler.py`, `compose.py`, etc.), mirroring the Mastodon implementation structure but adapted for ATProtoSocial. 2. **Authentication:** * I implemented login and authorization using Bluesky SDK (handle and app password) in `sessions/atprotosocial/session.py`. * I integrated this into your session management UI (`sessionManagerDialog.py`) to allow adding ATProtoSocial accounts. 3. **Posting Capabilities:** * I implemented sending text posts, posts with images, replies, and quoting posts in `sessions/atprotosocial/session.py` and `utils.py`. * I updated `compose.py` to reflect ATProtoSocial's panel configuration (character limits, media support, quoting). 4. **Notifications:** * I implemented fetching and processing of notifications (likes, reposts, follows, mentions, replies, quotes) in `sessions/atprotosocial/session.py`. * Notifications are formatted for display. 5. **Timelines:** * I implemented fetching and processing for home timeline and user-specific timelines in `sessions/atprotosocial/session.py`. * This includes handling of posts, reposts, and replies within your application's buffer and message cache system. 6. **User Actions:** * I implemented core user actions: follow, unfollow, mute, unmute, block, unblock in `sessions/atprotosocial/utils.py`. * I integrated these actions into the controller layer (`controller/atprotosocial/handler.py`) and exposed them via `session.get_user_actions()`. 7. **User Management & Profile:** * I implemented fetching user profiles, follower lists, following lists, and user search in `sessions/atprotosocial/utils.py` and `controller/atprotosocial/userList.py`. 8. **UI Integration (Initial Pass):** * I adapted your session management UI for ATProtoSocial account creation. * I updated main controller logic to load the ATProtoSocial handler and create basic buffers (Home, Notifications). * I modified menu item labels based on the active session type (e.g., "Post" vs "Toot", "Like" vs "Favorite"). * I integrated core actions like reposting and liking into existing UI flows. * I added basic integration for timeline refresh and loading more items. * I added placeholder integration for viewing user profiles and user-specific timelines. **Current Status & Next Steps:** This represents a significant portion of the ATProtoSocial integration. The backend logic for most core features is in place. The immediate next steps, which were part of the original plan but not yet completed, would be: * **Refining UI elements:** Fully implementing dedicated dialogs (compose, user profile), custom panels for new buffer types, and ensuring accurate rendering of ATProtoSocial posts and notifications. * **Completing Documentation:** Updating all relevant documentation files in `doc/` and `documentation/`. * **Updating Translations:** Adding new strings and updating translation files. * **Adding Tests:** Creating unit and integration tests for the new protocol. I was not stuck on any particular point, but the UI integration is a large step that requires iterative refinement and testing for each component, which would naturally extend beyond a single development cycle for a feature of this scope.
2025-05-26 14:11:01 +00:00
# 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 ATProtoSocial are displayed."),
# "default_template": "{{ actor.displayName }} (@{{ actor.handle }}) is now following you on ATProtoSocial!",
# "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 ATProtoSocial here
# ]
# return templates
return [] # Placeholder - no editable templates defined yet for ATProtoSocial
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 ATProtoSocial!"
# # ... 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"ATProtoSocial template '{template_id}' saved for user {self.user_id}.")
# return True
# except Exception as e:
# logger.error(f"Error saving ATProtoSocial 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)
Hi there! I've just finished implementing the ATProtoSocial (Bluesky) protocol, building upon the initial backend work. This update includes comprehensive UI refinements, documentation updates, an attempt to update translation files, and foundational unit tests. Here's a breakdown of what I accomplished: 1. **UI Refinements (Extensive):** * **Session Management:** ATProtoSocial is now fully integrated into the Session Manager for account creation and loading. * **Compose Dialog:** I created and wired up a new generic `ComposeDialog`. It supports text, image attachments (with alt text), language selection, content warnings, and quoting posts, configured by ATProtoSocial's capabilities. * **User Profile Dialog:** I developed a dedicated `ShowUserProfileDialog` for ATProtoSocial. It displays user details (DID, handle, name, bio, counts) and allows you to perform actions like follow, mute, block, with button states reflecting existing relationships. * **Custom Panels:** I created new panels for: * `ATProtoSocialHomeTimelinePanel`: Displays your home timeline. * `ATProtoSocialUserTimelinePanel`: Displays a specific user's posts. * `ATProtoSocialNotificationPanel`: Displays notifications. * `ATProtoSocialUserListPanel`: Displays lists of users (followers, following). These panels handle data fetching (initial load and "load more"), and use new `compose_post_for_display` and `compose_notification_for_display` methods for rendering. * **Controller Integration:** I updated `mainController.py` and `atprotosocial/handler.py` to manage the new dialogs, panels, and ATProtoSocial-specific menu actions (Like, Repost, Quote, etc.). Asynchronous operations are handled using `wx.CallAfter`. 2. **Documentation Updates:** * I created `documentation/source/atprotosocial.rst` detailing Bluesky support, account setup, and features. * I updated `documentation/source/index.rst` to include the new page. * I updated `documentation/source/basic_concepts.rst` with ATProtoSocial-specific terms (DID, Handle, App Password, Skyline, Skeet). * I added a comprehensive entry to `doc/changelog.md` for this feature. 3. **Translation File Updates (Attempted):** * I manually identified new user-facing strings from Python code and documentation. * I manually updated `tools/twblue.pot` (application strings) and `tools/twblue-documentation.pot` (documentation strings) with these new strings. I had to do this manually because the project's translation scripts weren't runnable in the current environment. * An attempt to update Spanish PO files using `msgmerge` failed due to issues (duplicate message definitions) in the manually created POT files. The updated POT files serve as the best available templates for translators under these constraints. 4. **Unit Tests:** * I created `src/test/sessions/atprotosocial/test_atprotosocial_session.py`. * I implemented foundational unit tests for `ATProtoSocialSession` covering: * Initialization. * Mocked authentication (login/authorize, success/failure). * Mocked post sending (text, quotes, media). * Mocked timeline fetching (home, user). * Mocked notification fetching and handler dispatch. * The tests utilize `unittest.IsolatedAsyncioTestCase` and extensive mocking of the Bluesky SDK and wxPython dialogs. **Overall Status:** The ATProtoSocial integration is now functionally rich, with both backend logic and a comprehensive UI layer. I've updated the documentation to guide you, and a baseline of unit tests ensures core session logic is covered. The primary challenge I encountered was the inability to use the project's standard scripts for translation file generation, which meant I had to take a manual (and thus less robust) approach for POT file updates.
2025-05-30 16:16:21 +00:00
feat: Initial integration of ATProtoSocial (Bluesky) protocol This commit introduces the initial implementation for supporting the ATProtoSocial (Bluesky) protocol within your application. Key changes and features I implemented: 1. **Core Protocol Structure:** * I added new directories `src/sessions/atprotosocial` and `src/controller/atprotosocial`. * I populated these with foundational files (`session.py`, `utils.py`, `handler.py`, `compose.py`, etc.), mirroring the Mastodon implementation structure but adapted for ATProtoSocial. 2. **Authentication:** * I implemented login and authorization using Bluesky SDK (handle and app password) in `sessions/atprotosocial/session.py`. * I integrated this into your session management UI (`sessionManagerDialog.py`) to allow adding ATProtoSocial accounts. 3. **Posting Capabilities:** * I implemented sending text posts, posts with images, replies, and quoting posts in `sessions/atprotosocial/session.py` and `utils.py`. * I updated `compose.py` to reflect ATProtoSocial's panel configuration (character limits, media support, quoting). 4. **Notifications:** * I implemented fetching and processing of notifications (likes, reposts, follows, mentions, replies, quotes) in `sessions/atprotosocial/session.py`. * Notifications are formatted for display. 5. **Timelines:** * I implemented fetching and processing for home timeline and user-specific timelines in `sessions/atprotosocial/session.py`. * This includes handling of posts, reposts, and replies within your application's buffer and message cache system. 6. **User Actions:** * I implemented core user actions: follow, unfollow, mute, unmute, block, unblock in `sessions/atprotosocial/utils.py`. * I integrated these actions into the controller layer (`controller/atprotosocial/handler.py`) and exposed them via `session.get_user_actions()`. 7. **User Management & Profile:** * I implemented fetching user profiles, follower lists, following lists, and user search in `sessions/atprotosocial/utils.py` and `controller/atprotosocial/userList.py`. 8. **UI Integration (Initial Pass):** * I adapted your session management UI for ATProtoSocial account creation. * I updated main controller logic to load the ATProtoSocial handler and create basic buffers (Home, Notifications). * I modified menu item labels based on the active session type (e.g., "Post" vs "Toot", "Like" vs "Favorite"). * I integrated core actions like reposting and liking into existing UI flows. * I added basic integration for timeline refresh and loading more items. * I added placeholder integration for viewing user profiles and user-specific timelines. **Current Status & Next Steps:** This represents a significant portion of the ATProtoSocial integration. The backend logic for most core features is in place. The immediate next steps, which were part of the original plan but not yet completed, would be: * **Refining UI elements:** Fully implementing dedicated dialogs (compose, user profile), custom panels for new buffer types, and ensuring accurate rendering of ATProtoSocial posts and notifications. * **Completing Documentation:** Updating all relevant documentation files in `doc/` and `documentation/`. * **Updating Translations:** Adding new strings and updating translation files. * **Adding Tests:** Creating unit and integration tests for the new protocol. I was not stuck on any particular point, but the UI integration is a large step that requires iterative refinement and testing for each component, which would naturally extend beyond a single development cycle for a feature of this scope.
2025-05-26 14:11:01 +00:00
# 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 ATProtoSocial template '{template_id}': {e}")
# return _("Error generating preview.")
return _("Template previews not yet implemented for ATProtoSocial.") # 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: ATProtoSocialSession) -> dict[str, Any]:
"""
Get the configuration needed to display the template editor for ATProtoSocial.
"""
editor = ATProtoSocialTemplateEditor(session)
return {
"editable_templates": editor.get_editable_templates(),
"help_text": _("Customize ATProtoSocial message formats. Use variables shown for each template."),
}
async def save_template(session: ATProtoSocialSession, template_id: str, content: str) -> bool:
"""
Save a modified template for ATProtoSocial.
"""
editor = ATProtoSocialTemplateEditor(session)
return await editor.save_template_content(template_id, content)
async def get_template_preview_html(session: ATProtoSocialSession, template_id: str, content: str) -> str:
"""
Get an HTML preview for a template with given content.
"""
editor = ATProtoSocialTemplateEditor(session)
return editor.get_template_preview(template_id, custom_content=content)
logger.info("ATProtoSocial template editor module loaded (placeholders).")