mirror of
https://github.com/MCV-Software/TWBlue.git
synced 2026-03-06 01:17:32 +01:00
Refactor y eliminar patrones raros.
This commit is contained in:
@@ -98,6 +98,24 @@ def format_error_message(error_description: str, details: str | None = None) ->
|
||||
logger.info("Blueski messages module loaded (placeholders).")
|
||||
|
||||
|
||||
class post(base_messages.basicMessage):
|
||||
def __init__(self, session: Any, title: str, caption: str, text: str = "", *args, **kwargs):
|
||||
self.session = session
|
||||
self.title = title
|
||||
self.message = postDialogs.Post(caption=caption, text=text, *args, **kwargs)
|
||||
try:
|
||||
self.message.SetTitle(title)
|
||||
self.message.text.SetInsertionPoint(len(self.message.text.GetValue()))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def get_data(self):
|
||||
return self.message.get_payload()
|
||||
|
||||
def text_processor(self):
|
||||
pass
|
||||
|
||||
|
||||
def _g(obj: Any, key: str, default: Any = None) -> Any:
|
||||
if isinstance(obj, dict):
|
||||
return obj.get(key, default)
|
||||
|
||||
@@ -190,28 +190,20 @@ class BaseBuffer(base.Buffer):
|
||||
pub.sendMessage("execute-action", action="copy_to_clipboard")
|
||||
|
||||
def on_post(self, evt):
|
||||
from wxUI.dialogs.blueski import postDialogs
|
||||
dlg = postDialogs.Post(caption=_("New Post"))
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
text, files, cw, langs = dlg.get_payload()
|
||||
if not text and not files:
|
||||
dlg.Destroy()
|
||||
return
|
||||
def do_send():
|
||||
try:
|
||||
uri = self.session.send_message(message=text, files=files, cw_text=cw, langs=langs)
|
||||
if uri:
|
||||
wx.CallAfter(self.session.sound.play, "tweet_send.ogg")
|
||||
wx.CallAfter(output.speak, _("Sent."))
|
||||
if hasattr(self, "start_stream"):
|
||||
wx.CallAfter(self.start_stream, False, False)
|
||||
else:
|
||||
wx.CallAfter(output.speak, _("Failed to send post."), True)
|
||||
except Exception:
|
||||
log.exception("Error sending Bluesky post")
|
||||
wx.CallAfter(output.speak, _("An error occurred while posting."), True)
|
||||
call_threaded(do_send)
|
||||
dlg.Destroy()
|
||||
dlg = blueski_messages.post(session=self.session, title=_("New Post"), caption=_("New Post"))
|
||||
if dlg.message.ShowModal() == wx.ID_OK:
|
||||
text, files, cw, langs = dlg.get_data()
|
||||
self._send_post_async(
|
||||
text=text,
|
||||
files=files,
|
||||
cw_text=cw,
|
||||
langs=langs,
|
||||
success_message=_("Sent."),
|
||||
error_message=_("An error occurred while posting."),
|
||||
sound="tweet_send.ogg",
|
||||
refresh_args=(False, False),
|
||||
)
|
||||
dlg.message.Destroy()
|
||||
|
||||
def on_reply(self, evt):
|
||||
item = self.get_item()
|
||||
@@ -237,38 +229,71 @@ class BaseBuffer(base.Buffer):
|
||||
handle = g(author, "handle", "")
|
||||
initial_text = f"@{handle} " if handle and not handle.startswith("@") else (f"{handle} " if handle else "")
|
||||
|
||||
from wxUI.dialogs.blueski import postDialogs
|
||||
dlg = postDialogs.Post(caption=_("Reply"), text=initial_text)
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
text, files, cw, langs = dlg.get_payload()
|
||||
if not text and not files:
|
||||
dlg.Destroy()
|
||||
return
|
||||
def do_send():
|
||||
try:
|
||||
uri_resp = self.session.send_message(
|
||||
message=text,
|
||||
files=files,
|
||||
reply_to=uri,
|
||||
reply_to_cid=reply_cid,
|
||||
cw_text=cw,
|
||||
langs=langs
|
||||
)
|
||||
if uri_resp:
|
||||
wx.CallAfter(self.session.sound.play, "reply_send.ogg")
|
||||
wx.CallAfter(output.speak, _("Reply sent."))
|
||||
if getattr(self, "type", "") == "conversation":
|
||||
try:
|
||||
wx.CallAfter(self.start_stream, True, False)
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
wx.CallAfter(output.speak, _("Failed to send reply."), True)
|
||||
except Exception:
|
||||
log.exception("Error sending Bluesky reply")
|
||||
wx.CallAfter(output.speak, _("An error occurred while replying."), True)
|
||||
call_threaded(do_send)
|
||||
dlg.Destroy()
|
||||
dlg = blueski_messages.post(session=self.session, title=_("Reply"), caption=_("Reply"), text=initial_text)
|
||||
if dlg.message.ShowModal() == wx.ID_OK:
|
||||
text, files, cw, langs = dlg.get_data()
|
||||
refresh_args = (True, False) if getattr(self, "type", "") == "conversation" else None
|
||||
self._send_post_async(
|
||||
text=text,
|
||||
files=files,
|
||||
cw_text=cw,
|
||||
langs=langs,
|
||||
reply_to=uri,
|
||||
reply_to_cid=reply_cid,
|
||||
success_message=_("Reply sent."),
|
||||
error_message=_("An error occurred while replying."),
|
||||
sound="reply_send.ogg",
|
||||
refresh_args=refresh_args,
|
||||
)
|
||||
dlg.message.Destroy()
|
||||
|
||||
def _send_post_async(
|
||||
self,
|
||||
*,
|
||||
text,
|
||||
files,
|
||||
cw_text,
|
||||
langs,
|
||||
reply_to=None,
|
||||
reply_to_cid=None,
|
||||
success_message="",
|
||||
error_message="",
|
||||
sound=None,
|
||||
refresh_args=None,
|
||||
):
|
||||
if not text and not files:
|
||||
return
|
||||
|
||||
def do_send():
|
||||
try:
|
||||
uri_resp = self.session.send_message(
|
||||
message=text,
|
||||
files=files,
|
||||
reply_to=reply_to,
|
||||
reply_to_cid=reply_to_cid,
|
||||
cw_text=cw_text,
|
||||
langs=langs,
|
||||
)
|
||||
if uri_resp:
|
||||
if sound:
|
||||
wx.CallAfter(self.session.sound.play, sound)
|
||||
if success_message:
|
||||
wx.CallAfter(output.speak, success_message)
|
||||
if refresh_args and hasattr(self, "start_stream"):
|
||||
try:
|
||||
wx.CallAfter(self.start_stream, *refresh_args)
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
wx.CallAfter(output.speak, _("Failed to send post."), True)
|
||||
except Exception:
|
||||
log.exception("Error sending Bluesky post")
|
||||
if error_message:
|
||||
wx.CallAfter(output.speak, error_message, True)
|
||||
else:
|
||||
wx.CallAfter(output.speak, _("An error occurred while posting."), True)
|
||||
|
||||
call_threaded(do_send)
|
||||
|
||||
def on_repost(self, evt):
|
||||
self.share_item(confirm=True)
|
||||
|
||||
@@ -6,3 +6,4 @@ from .users import UserBuffer
|
||||
from .notifications import NotificationsBuffer
|
||||
from .search import SearchBuffer
|
||||
from .community import CommunityBuffer
|
||||
from .announcements import AnnouncementsBuffer
|
||||
165
srcantiguo/controller/buffers/mastodon/announcements.py
Normal file
165
srcantiguo/controller/buffers/mastodon/announcements.py
Normal file
@@ -0,0 +1,165 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import time
|
||||
import logging
|
||||
import arrow
|
||||
import widgetUtils
|
||||
import wx
|
||||
import output
|
||||
import languageHandler
|
||||
import config
|
||||
from pubsub import pub
|
||||
from controller.buffers.mastodon.base import BaseBuffer
|
||||
from sessions.mastodon import compose, templates
|
||||
from wxUI import buffers
|
||||
from wxUI.dialogs.mastodon import menus
|
||||
from mysc.thread_utils import call_threaded
|
||||
|
||||
log = logging.getLogger("controller.buffers.mastodon.announcements")
|
||||
|
||||
class AnnouncementsBuffer(BaseBuffer):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
# We enforce compose_func="compose_announcement"
|
||||
kwargs["compose_func"] = "compose_announcement"
|
||||
super(AnnouncementsBuffer, self).__init__(*args, **kwargs)
|
||||
self.type = "announcementsBuffer"
|
||||
|
||||
def create_buffer(self, parent, name):
|
||||
self.buffer = buffers.mastodon.announcementsPanel(parent, name)
|
||||
|
||||
def get_buffer_name(self):
|
||||
return _("Announcements")
|
||||
|
||||
def bind_events(self):
|
||||
self.buffer.set_focus_function(self.onFocus)
|
||||
widgetUtils.connect_event(self.buffer.list.list, widgetUtils.KEYPRESS, self.get_event)
|
||||
widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.dismiss_announcement, self.buffer.dismiss)
|
||||
widgetUtils.connect_event(self.buffer.list.list, wx.EVT_LIST_ITEM_RIGHT_CLICK, self.show_menu)
|
||||
widgetUtils.connect_event(self.buffer.list.list, wx.EVT_LIST_KEY_DOWN, self.show_menu_by_key)
|
||||
|
||||
def dismiss_announcement(self, event=None, item=None, *args, **kwargs):
|
||||
index = self.buffer.list.get_selected()
|
||||
if index == -1: return
|
||||
item = self.session.db[self.name][index]
|
||||
|
||||
# Optimistic UI update or wait for API? Let's wait for API to be safe, but run threaded.
|
||||
# We need a custom call because 'announcements_dismiss' returns None on success usually.
|
||||
def _do_dismiss():
|
||||
try:
|
||||
self.session.api_call(call_name="announcements_dismiss", id=str(item.id))
|
||||
# If success, update UI in main thread
|
||||
wx.CallAfter(self._on_dismiss_success, index)
|
||||
except Exception as e:
|
||||
log.exception("Error dismissing announcement")
|
||||
self.session.sound.play("error.ogg")
|
||||
|
||||
call_threaded(_do_dismiss)
|
||||
|
||||
def _on_dismiss_success(self, index):
|
||||
if index < len(self.session.db[self.name]):
|
||||
self.session.db[self.name].pop(index)
|
||||
self.buffer.list.remove_item(index)
|
||||
output.speak(_("Announcement dismissed."))
|
||||
|
||||
def show_menu(self, ev, pos=0, *args, **kwargs):
|
||||
if self.buffer.list.get_count() == 0:
|
||||
return
|
||||
# Create a simple menu
|
||||
menu = wx.Menu()
|
||||
dismiss_item = menu.Append(wx.ID_ANY, _("Dismiss"))
|
||||
copy_item = menu.Append(wx.ID_ANY, _("Copy text"))
|
||||
|
||||
self.buffer.Bind(wx.EVT_MENU, self.dismiss_announcement, dismiss_item)
|
||||
self.buffer.Bind(wx.EVT_MENU, self.copy, copy_item)
|
||||
|
||||
if pos != 0:
|
||||
self.buffer.PopupMenu(menu, pos)
|
||||
else:
|
||||
self.buffer.PopupMenu(menu, self.buffer.list.list.GetPosition())
|
||||
|
||||
def url(self, *args, **kwargs):
|
||||
self.dismiss_announcement()
|
||||
|
||||
def get_more_items(self): output.speak(_("This buffer does not support loading more items."), True)
|
||||
|
||||
# Disable social interactions not applicable to announcements
|
||||
def reply(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def share_item(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def toggle_favorite(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def add_to_favorites(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def remove_from_favorites(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def toggle_bookmark(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def mute_conversation(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def vote(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def send_message(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def user_details(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def view_item(self, *args, **kwargs):
|
||||
# We could implement a specific viewer for announcements if needed,
|
||||
# but the default one expects a status object structure.
|
||||
pass
|
||||
|
||||
def copy(self, event=None):
|
||||
item = self.get_item()
|
||||
if item:
|
||||
pub.sendMessage("execute-action", action="copy_to_clipboard")
|
||||
|
||||
def onFocus(self, *args, **kwargs):
|
||||
# Similar logic to BaseBuffer but adapted if needed.
|
||||
# BaseBuffer.onFocus handles reading long posts.
|
||||
if config.app["app-settings"]["read_long_posts_in_gui"] == True and self.buffer.list.list.HasFocus():
|
||||
wx.CallLater(40, output.speak, self.get_message(), interrupt=True)
|
||||
|
||||
def get_message(self):
|
||||
# Override to use announcement template
|
||||
announcement = self.get_item()
|
||||
if announcement == None:
|
||||
return
|
||||
template = self.session.settings.get("templates", {}).get("announcement", templates.announcement_default_template)
|
||||
t = templates.render_announcement(announcement, template, self.session.settings, relative_times=self.session.settings["general"]["relative_times"], offset_hours=self.session.db["utc_offset"])
|
||||
return t
|
||||
|
||||
def start_stream(self, mandatory=False, play_sound=True, avoid_autoreading=False):
|
||||
current_time = time.time()
|
||||
if self.execution_time == 0 or current_time-self.execution_time >= 300 or mandatory==True:
|
||||
self.execution_time = current_time
|
||||
log.debug("Starting stream for announcements buffer")
|
||||
try:
|
||||
# The announcements API does not accept min_id or limit parameters
|
||||
results = self.session.api.announcements()
|
||||
# Reverse the list so order_buffer processes them according to user preference
|
||||
results.reverse()
|
||||
except Exception as e:
|
||||
log.exception("Error retrieving announcements: %s" % (str(e)))
|
||||
return 0
|
||||
|
||||
# order_buffer handles duplication filtering by ID internally
|
||||
number_of_items = self.session.order_buffer(self.name, results)
|
||||
log.debug("Number of new announcements retrieved: %d" % (number_of_items,))
|
||||
|
||||
self.put_items_on_list(number_of_items)
|
||||
|
||||
if number_of_items > 0 and play_sound == True and self.sound != None and self.session.settings["sound"]["session_mute"] == False:
|
||||
self.session.sound.play(self.sound)
|
||||
|
||||
return number_of_items
|
||||
return 0
|
||||
@@ -126,14 +126,16 @@ class BaseBuffer(base.Buffer):
|
||||
min_id = None
|
||||
# toDo: Implement reverse timelines properly here.
|
||||
if (self.name != "favorites" and self.name != "bookmarks") and self.name in self.session.db and len(self.session.db[self.name]) > 0:
|
||||
if self.session.settings["general"]["reverse_timelines"]:
|
||||
min_id = self.session.db[self.name][0].id
|
||||
else:
|
||||
min_id = self.session.db[self.name][-1].id
|
||||
# We use the maximum ID present in the buffer to ensure we only request posts
|
||||
# that are newer than our most recent chronological post.
|
||||
# This prevents old pinned posts from pulling in hundreds of previous statuses.
|
||||
min_id = max(item.id for item in self.session.db[self.name])
|
||||
# loads pinned posts from user accounts.
|
||||
# Load those posts only when there are no items previously loaded.
|
||||
if "-timeline" in self.name and "account_statuses" in self.function and len(self.session.db.get(self.name, [])) == 0:
|
||||
pinned_posts = self.session.api.account_statuses(pinned=True, limit=count, *self.args, **self.kwargs)
|
||||
for p in pinned_posts:
|
||||
p["pinned"] = True
|
||||
pinned_posts.reverse()
|
||||
else:
|
||||
pinned_posts = None
|
||||
@@ -182,10 +184,17 @@ class BaseBuffer(base.Buffer):
|
||||
|
||||
def get_more_items(self):
|
||||
elements = []
|
||||
if self.session.settings["general"]["reverse_timelines"] == False:
|
||||
max_id = self.session.db[self.name][0].id
|
||||
if len(self.session.db[self.name]) == 0:
|
||||
return
|
||||
# We use the minimum ID in the buffer to correctly request the next page of older items.
|
||||
# This prevents old pinned posts from causing us to skip chronological posts.
|
||||
# We try to exclude pinned posts from this calculation as they are usually outliers at the top.
|
||||
unpinned_ids = [item.id for item in self.session.db[self.name] if not getattr(item, "pinned", False)]
|
||||
if unpinned_ids:
|
||||
max_id = min(unpinned_ids)
|
||||
else:
|
||||
max_id = self.session.db[self.name][-1].id
|
||||
max_id = min(item.id for item in self.session.db[self.name])
|
||||
|
||||
try:
|
||||
items = getattr(self.session.api, self.function)(max_id=max_id, limit=self.session.settings["general"]["max_posts_per_call"], *self.args, **self.kwargs)
|
||||
except Exception as e:
|
||||
@@ -311,8 +320,10 @@ class BaseBuffer(base.Buffer):
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.user_actions, menuitem=menu.userActions)
|
||||
if self.can_share() == True:
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.share_item, menuitem=menu.boost)
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.quote, menuitem=menu.quote)
|
||||
else:
|
||||
menu.boost.Enable(False)
|
||||
menu.quote.Enable(False)
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.fav, menuitem=menu.fav)
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.unfav, menuitem=menu.unfav)
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.mute_conversation, menuitem=menu.mute)
|
||||
@@ -442,11 +453,30 @@ class BaseBuffer(base.Buffer):
|
||||
id = item.id
|
||||
if self.session.settings["general"]["boost_mode"] == "ask":
|
||||
answer = mastodon_dialogs.boost_question()
|
||||
if answer == True:
|
||||
if answer == 1:
|
||||
self._direct_boost(id)
|
||||
elif answer == 2:
|
||||
self.quote(item=item)
|
||||
else:
|
||||
self._direct_boost(id)
|
||||
|
||||
def quote(self, event=None, item=None, *args, **kwargs):
|
||||
if item == None:
|
||||
item = self.get_item()
|
||||
if self.can_share(item=item) == False:
|
||||
return output.speak(_("This action is not supported on conversations."))
|
||||
|
||||
title = _("Quote post")
|
||||
caption = _("Write your comment here")
|
||||
post = messages.post(session=self.session, title=title, caption=caption)
|
||||
|
||||
response = post.message.ShowModal()
|
||||
if response == wx.ID_OK:
|
||||
post_data = post.get_data()
|
||||
call_threaded(self.session.send_post, quote_id=item.id, posts=post_data, visibility=post.get_visibility(), language=post.get_language(), **kwargs)
|
||||
if hasattr(post.message, "destroy"):
|
||||
post.message.destroy()
|
||||
|
||||
def _direct_boost(self, id):
|
||||
item = self.session.api_call(call_name="status_reblog", _sound="retweet_send.ogg", id=id)
|
||||
|
||||
|
||||
@@ -33,10 +33,7 @@ class CommunityBuffer(base.BaseBuffer):
|
||||
min_id = None
|
||||
# toDo: Implement reverse timelines properly here.
|
||||
if self.name in self.session.db and len(self.session.db[self.name]) > 0:
|
||||
if self.session.settings["general"]["reverse_timelines"]:
|
||||
min_id = self.session.db[self.name][0].id
|
||||
else:
|
||||
min_id = self.session.db[self.name][-1].id
|
||||
min_id = max(item.id for item in self.session.db[self.name])
|
||||
try:
|
||||
results = self.community_api.timeline(timeline=self.timeline, min_id=min_id, limit=count, *self.args, **self.kwargs)
|
||||
results.reverse()
|
||||
@@ -55,10 +52,15 @@ class CommunityBuffer(base.BaseBuffer):
|
||||
|
||||
def get_more_items(self):
|
||||
elements = []
|
||||
if self.session.settings["general"]["reverse_timelines"] == False:
|
||||
max_id = self.session.db[self.name][0].id
|
||||
if len(self.session.db[self.name]) == 0:
|
||||
return
|
||||
|
||||
unpinned_ids = [item.id for item in self.session.db[self.name] if not getattr(item, "pinned", False)]
|
||||
if unpinned_ids:
|
||||
max_id = min(unpinned_ids)
|
||||
else:
|
||||
max_id = self.session.db[self.name][-1].id
|
||||
max_id = min(item.id for item in self.session.db[self.name])
|
||||
|
||||
try:
|
||||
items = self.community_api.timeline(timeline=self.timeline, max_id=max_id, limit=self.session.settings["general"]["max_posts_per_call"], *self.args, **self.kwargs)
|
||||
except Exception as e:
|
||||
|
||||
@@ -42,10 +42,22 @@ class MentionsBuffer(BaseBuffer):
|
||||
|
||||
def get_more_items(self):
|
||||
elements = []
|
||||
if self.session.settings["general"]["reverse_timelines"] == False:
|
||||
max_id = self.session.db[self.name][0].id
|
||||
else:
|
||||
max_id = self.session.db[self.name][-1].id
|
||||
if len(self.session.db[self.name]) == 0:
|
||||
return
|
||||
|
||||
# In mentions buffer, items are notification objects which don't have 'pinned' attribute directly.
|
||||
# But we check the status attached to the notification if it exists.
|
||||
# However, notifications are strictly chronological usually. Pinned mentions don't exist?
|
||||
# But let's stick to the safe ID extraction.
|
||||
# The logic here is tricky because self.session.db stores notification objects, but sometimes just dicts?
|
||||
# Let's assume they are objects with 'id' attribute.
|
||||
# Notifications don't have 'pinned', so we just take the min ID.
|
||||
# But wait, did I change this file previously to use min()? Yes.
|
||||
# Is there any case where a notification ID is "pinned" (old)? No.
|
||||
# So min() should be fine here. But for consistency with other buffers if any weird logic exists...
|
||||
# Actually, let's keep min() as notifications don't support pinning.
|
||||
|
||||
max_id = min(item.id for item in self.session.db[self.name])
|
||||
try:
|
||||
items = getattr(self.session.api, self.function)(max_id=max_id, limit=self.session.settings["general"]["max_posts_per_call"], types=["mention"], *self.args, **self.kwargs)
|
||||
except Exception as e:
|
||||
|
||||
@@ -33,10 +33,7 @@ class SearchBuffer(BaseBuffer):
|
||||
self.execution_time = current_time
|
||||
min_id = None
|
||||
if self.name in self.session.db and len(self.session.db[self.name]) > 0:
|
||||
if self.session.settings["general"]["reverse_timelines"]:
|
||||
min_id = self.session.db[self.name][0].id
|
||||
else:
|
||||
min_id = self.session.db[self.name][-1].id
|
||||
min_id = max(item.id for item in self.session.db[self.name])
|
||||
try:
|
||||
results = getattr(self.session.api, self.function)(min_id=min_id, **self.kwargs)
|
||||
except Exception as mess:
|
||||
|
||||
@@ -35,6 +35,7 @@ class Handler(object):
|
||||
compose=_("&Post"),
|
||||
reply=_("Re&ply"),
|
||||
share=_("&Boost"),
|
||||
quote=_("&Quote"),
|
||||
fav=_("&Add to favorites"),
|
||||
unfav=_("Remove from favorites"),
|
||||
view=_("&Show post"),
|
||||
@@ -92,6 +93,8 @@ class Handler(object):
|
||||
pub.sendMessage("createBuffer", buffer_type="UserBuffer", session_type=session.type, buffer_title=_("Blocked users"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, compose_func="compose_user", function="blocks", name="blocked", sessionObject=session, account=name))
|
||||
elif i == 'notifications':
|
||||
pub.sendMessage("createBuffer", buffer_type="NotificationsBuffer", session_type=session.type, buffer_title=_("Notifications"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, compose_func="compose_notification", function="notifications", name="notifications", sessionObject=session, account=name))
|
||||
elif i == 'announcements':
|
||||
pub.sendMessage("createBuffer", buffer_type="AnnouncementsBuffer", session_type=session.type, buffer_title=_("Announcements"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, function="announcements", name="announcements", sessionObject=session, account=name, sound="new_event.ogg"))
|
||||
pub.sendMessage("createBuffer", buffer_type="EmptyBuffer", session_type="base", buffer_title=_("Timelines"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, name="timelines", account=name))
|
||||
timelines_position =controller.view.search("timelines", name)
|
||||
for i in session.settings["other_buffers"]["timelines"]:
|
||||
|
||||
@@ -10,7 +10,7 @@ import languageHandler
|
||||
from twitter_text import parse_tweet, config
|
||||
from mastodon import MastodonError
|
||||
from controller import messages
|
||||
from sessions.mastodon import templates
|
||||
from sessions.mastodon import templates, utils
|
||||
from wxUI.dialogs.mastodon import postDialogs
|
||||
from extra.autocompletionUsers import completion
|
||||
from . import userList
|
||||
@@ -282,10 +282,7 @@ class editPost(post):
|
||||
# Extract text from post
|
||||
if item.reblog != None:
|
||||
item = item.reblog
|
||||
text = item.content
|
||||
# Remove HTML tags from content
|
||||
import re
|
||||
text = re.sub('<[^<]+?>', '', text)
|
||||
text = utils.html_filter(item.content)
|
||||
# Initialize parent class
|
||||
super(editPost, self).__init__(session, title, caption, text=text, *args, **kwargs)
|
||||
# Store the post ID for editing
|
||||
|
||||
@@ -52,10 +52,12 @@ class accountSettingsController(globalSettingsController):
|
||||
post_template = self.config["templates"]["post"]
|
||||
conversation_template = self.config["templates"]["conversation"]
|
||||
person_template = self.config["templates"]["person"]
|
||||
self.dialog.create_templates(post_template=post_template, conversation_template=conversation_template, person_template=person_template)
|
||||
announcement_template = self.config.get("templates", {}).get("announcement", "$text. Published $published_at. $read")
|
||||
self.dialog.create_templates(post_template=post_template, conversation_template=conversation_template, person_template=person_template, announcement_template=announcement_template)
|
||||
widgetUtils.connect_event(self.dialog.templates.post, widgetUtils.BUTTON_PRESSED, self.edit_post_template)
|
||||
widgetUtils.connect_event(self.dialog.templates.conversation, widgetUtils.BUTTON_PRESSED, self.edit_conversation_template)
|
||||
widgetUtils.connect_event(self.dialog.templates.person, widgetUtils.BUTTON_PRESSED, self.edit_person_template)
|
||||
widgetUtils.connect_event(self.dialog.templates.announcement, widgetUtils.BUTTON_PRESSED, self.edit_announcement_template)
|
||||
self.dialog.create_other_buffers()
|
||||
buffer_values = self.get_buffers_list()
|
||||
self.dialog.buffers.insert_buffers(buffer_values)
|
||||
@@ -109,6 +111,15 @@ class accountSettingsController(globalSettingsController):
|
||||
self.config.write()
|
||||
self.dialog.templates.person.SetLabel(_("Edit template for persons. Current template: {}").format(result))
|
||||
|
||||
def edit_announcement_template(self, *args, **kwargs):
|
||||
template = self.config.get("templates", {}).get("announcement", "$text. Published $published_at. $read")
|
||||
control = EditTemplate(template=template, type="announcement")
|
||||
result = control.run_dialog()
|
||||
if result != "": # Template has been saved.
|
||||
self.config["templates"]["announcement"] = result
|
||||
self.config.write()
|
||||
self.dialog.templates.announcement.SetLabel(_("Edit template for announcements. Current template: {}").format(result))
|
||||
|
||||
def save_configuration(self):
|
||||
if self.config["general"]["relative_times"] != self.dialog.get_value("general", "relative_time"):
|
||||
self.needs_restart = True
|
||||
@@ -204,6 +215,7 @@ class accountSettingsController(globalSettingsController):
|
||||
all_buffers['blocked']=_("Blocked users")
|
||||
all_buffers['muted']=_("Muted users")
|
||||
all_buffers['notifications']=_("Notifications")
|
||||
all_buffers['announcements']=_("Announcements")
|
||||
list_buffers = []
|
||||
hidden_buffers=[]
|
||||
all_buffers_keys = list(all_buffers.keys())
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import re
|
||||
import wx
|
||||
from typing import List
|
||||
from sessions.mastodon.templates import post_variables, conversation_variables, person_variables
|
||||
from sessions.mastodon.templates import post_variables, conversation_variables, person_variables, announcement_variables
|
||||
from wxUI.dialogs import templateDialogs
|
||||
|
||||
class EditTemplate(object):
|
||||
@@ -13,6 +13,8 @@ class EditTemplate(object):
|
||||
self.variables = post_variables
|
||||
elif type == "conversation":
|
||||
self.variables = conversation_variables
|
||||
elif type == "announcement":
|
||||
self.variables = announcement_variables
|
||||
else:
|
||||
self.variables = person_variables
|
||||
self.template: str = template
|
||||
|
||||
@@ -23,7 +23,6 @@ url = string(default="control+win+b")
|
||||
go_home = string(default="control+win+home")
|
||||
go_end = string(default="control+win+end")
|
||||
delete = string(default="control+win+delete")
|
||||
edit_post = string(default="")
|
||||
clear_buffer = string(default="control+win+shift+delete")
|
||||
repeat_item = string(default="control+win+space")
|
||||
copy_to_clipboard = string(default="control+win+shift+c")
|
||||
@@ -37,4 +36,13 @@ update_buffer = string(default="control+win+shift+u")
|
||||
ocr_image = string(default="win+alt+o")
|
||||
open_in_browser = string(default="alt+control+win+return")
|
||||
add_alias=string(default="")
|
||||
vote=string(default="alt+win+shift+v")
|
||||
vote=string(default="alt+win+shift+v")
|
||||
edit_post=string(default="")
|
||||
open_favs_timeline=string(default="")
|
||||
community_timeline=string(default="")
|
||||
seekLeft=string(default="")
|
||||
seekRight=string(default="")
|
||||
manage_aliases=string(default="")
|
||||
create_filter=string(default="")
|
||||
manage_filters=string(default="")
|
||||
manage_accounts=string(default="")
|
||||
@@ -33,7 +33,6 @@ go_page_up = string(default="control+win+pageup")
|
||||
go_page_down = string(default="control+win+pagedown")
|
||||
update_profile = string(default="control+win+shift+p")
|
||||
delete = string(default="control+win+delete")
|
||||
edit_post = string(default="")
|
||||
clear_buffer = string(default="control+win+shift+delete")
|
||||
repeat_item = string(default="control+win+space")
|
||||
copy_to_clipboard = string(default="control+win+shift+c")
|
||||
@@ -56,4 +55,13 @@ update_buffer = string(default="control+win+shift+u")
|
||||
ocr_image = string(default="win+alt+o")
|
||||
open_in_browser = string(default="alt+control+win+return")
|
||||
add_alias=string(default="")
|
||||
vote=string(default="alt+win+shift+v")
|
||||
vote=string(default="alt+win+shift+v")
|
||||
edit_post=string(default="")
|
||||
open_favs_timeline=string(default="")
|
||||
community_timeline=string(default="")
|
||||
seekLeft=string(default="")
|
||||
seekRight=string(default="")
|
||||
manage_aliases=string(default="")
|
||||
create_filter=string(default="")
|
||||
manage_filters=string(default="")
|
||||
manage_accounts=string(default="")
|
||||
@@ -33,7 +33,6 @@ go_page_up = string(default="control+win+pageup")
|
||||
go_page_down = string(default="control+win+pagedown")
|
||||
update_profile = string(default="alt+win+p")
|
||||
delete = string(default="alt+win+delete")
|
||||
edit_post = string(default="")
|
||||
clear_buffer = string(default="alt+win+shift+delete")
|
||||
repeat_item = string(default="alt+win+space")
|
||||
copy_to_clipboard = string(default="alt+win+shift+c")
|
||||
@@ -59,4 +58,13 @@ open_in_browser = string(default="alt+control+win+return")
|
||||
add_alias=string(default="")
|
||||
mute_conversation=string(default="control+alt+win+back")
|
||||
find = string(default="control+win+{")
|
||||
vote=string(default="alt+win+shift+v")
|
||||
vote=string(default="alt+win+shift+v")
|
||||
edit_post=string(default="")
|
||||
open_favs_timeline=string(default="")
|
||||
community_timeline=string(default="")
|
||||
seekLeft=string(default="")
|
||||
seekRight=string(default="")
|
||||
manage_aliases=string(default="")
|
||||
create_filter=string(default="")
|
||||
manage_filters=string(default="")
|
||||
manage_accounts=string(default="")
|
||||
@@ -33,7 +33,6 @@ go_page_up = string(default="control+win+pageup")
|
||||
go_page_down = string(default="control+win+pagedown")
|
||||
update_profile = string(default="alt+win+p")
|
||||
delete = string(default="alt+win+delete")
|
||||
edit_post = string(default="")
|
||||
clear_buffer = string(default="alt+win+shift+delete")
|
||||
repeat_item = string(default="control+alt+win+space")
|
||||
copy_to_clipboard = string(default="alt+win+shift+c")
|
||||
@@ -59,4 +58,13 @@ open_in_browser = string(default="alt+control+win+return")
|
||||
add_alias=string(default="")
|
||||
mute_conversation=string(default="control+alt+win+back")
|
||||
find = string(default="control+win+{")
|
||||
vote=string(default="alt+win+shift+v")
|
||||
vote=string(default="alt+win+shift+v")
|
||||
edit_post=string(default="")
|
||||
open_favs_timeline=string(default="")
|
||||
community_timeline=string(default="")
|
||||
seekLeft=string(default="")
|
||||
seekRight=string(default="")
|
||||
manage_aliases=string(default="")
|
||||
create_filter=string(default="")
|
||||
manage_filters=string(default="")
|
||||
manage_accounts=string(default="")
|
||||
@@ -58,4 +58,13 @@ update_buffer = string(default="control+win+shift+u")
|
||||
open_in_browser = string(default="alt+control+win+return")
|
||||
add_alias=string(default="")
|
||||
mute_conversation=string(default="alt+win+shift+delete")
|
||||
vote=string(default="alt+win+shift+v")
|
||||
vote=string(default="alt+win+shift+v")
|
||||
edit_post=string(default="")
|
||||
open_favs_timeline=string(default="")
|
||||
community_timeline=string(default="")
|
||||
seekLeft=string(default="")
|
||||
seekRight=string(default="")
|
||||
manage_aliases=string(default="")
|
||||
create_filter=string(default="")
|
||||
manage_filters=string(default="")
|
||||
manage_accounts=string(default="")
|
||||
@@ -34,7 +34,6 @@ go_page_up = string(default="control+win+pageup")
|
||||
go_page_down = string(default="control+win+pagedown")
|
||||
update_profile = string(default="alt+win+p")
|
||||
delete = string(default="control+win+delete")
|
||||
edit_post = string(default="")
|
||||
clear_buffer = string(default="control+win+shift+delete")
|
||||
repeat_item = string(default="control+win+space")
|
||||
copy_to_clipboard = string(default="control+win+shift+c")
|
||||
@@ -60,4 +59,13 @@ ocr_image = string(default="win+alt+o")
|
||||
open_in_browser = string(default="alt+control+win+return")
|
||||
add_alias=string(default="")
|
||||
mute_conversation=string(default="alt+win+shift+delete")
|
||||
vote=string(default="alt+win+shift+v")
|
||||
vote=string(default="alt+win+shift+v")
|
||||
edit_post=string(default="")
|
||||
open_favs_timeline=string(default="")
|
||||
community_timeline=string(default="")
|
||||
seekLeft=string(default="")
|
||||
seekRight=string(default="")
|
||||
manage_aliases=string(default="")
|
||||
create_filter=string(default="")
|
||||
manage_filters=string(default="")
|
||||
manage_accounts=string(default="")
|
||||
@@ -29,7 +29,7 @@ actions = {
|
||||
"go_end": _(u"Jump to the last element of the current buffer"),
|
||||
"go_page_up": _(u"Jump 20 elements up in the current buffer"),
|
||||
"go_page_down": _(u"Jump 20 elements down in the current buffer"),
|
||||
# "update_profile": _(u"Edit profile"),
|
||||
"update_profile": _(u"Edit profile"),
|
||||
"delete": _("Delete post"),
|
||||
"clear_buffer": _(u"Empty the current buffer"),
|
||||
"repeat_item": _(u"Repeat last item"),
|
||||
@@ -55,4 +55,14 @@ actions = {
|
||||
"ocr_image": _(u"Extracts the text from a picture and displays the result in a dialog."),
|
||||
"add_alias": _("Adds an alias to an user"),
|
||||
"mute_conversation": _("Mute/Unmute conversation"),
|
||||
"edit_post": _(u"Edit the selected post"),
|
||||
"vote": _(u"Vote in the selected poll"),
|
||||
"open_favs_timeline": _(u"Open favorites timeline"),
|
||||
"community_timeline": _(u"Open local/federated timeline"),
|
||||
"seekLeft": _(u"Seek media backward"),
|
||||
"seekRight": _(u"Seek media forward"),
|
||||
"manage_aliases": _(u"Manage user aliases"),
|
||||
"create_filter": _(u"Create a new filter"),
|
||||
"manage_filters": _(u"Manage filters"),
|
||||
"manage_accounts": _(u"Manage accounts"),
|
||||
}
|
||||
@@ -14,7 +14,7 @@ persist_size = integer(default=0)
|
||||
load_cache_in_memory=boolean(default=True)
|
||||
show_screen_names = boolean(default=False)
|
||||
hide_emojis = boolean(default=False)
|
||||
buffer_order = list(default=list('home', 'local', 'mentions', 'direct_messages', 'sent', 'favorites', 'bookmarks', 'followers', 'following', 'blocked', 'muted', 'notifications'))
|
||||
buffer_order = list(default=list('home', 'local', 'mentions', 'direct_messages', 'sent', 'favorites', 'bookmarks', 'followers', 'following', 'blocked', 'muted', 'notifications', 'announcements'))
|
||||
boost_mode = string(default="ask")
|
||||
disable_streaming = boolean(default=False)
|
||||
|
||||
@@ -54,6 +54,7 @@ post = string(default="$display_name, $safe_text $image_descriptions $date. $vis
|
||||
person = string(default="$display_name (@$screen_name). $followers followers, $following following, $posts posts. Joined $created_at.")
|
||||
conversation = string(default="Conversation with $users. Last message: $last_post")
|
||||
notification = string(default="$display_name $text, $date")
|
||||
announcement = string(default="$text. Published $published_at. $read")
|
||||
|
||||
[filters]
|
||||
|
||||
|
||||
@@ -84,4 +84,10 @@ def compose_notification(notification, db, settings, relative_times, show_screen
|
||||
filtered = utils.evaluate_filters(post=notification, current_context="notifications")
|
||||
if filtered != None:
|
||||
text = _("hidden by filter {}").format(filtered)
|
||||
return [user, text, ts]
|
||||
return [user, text, ts]
|
||||
|
||||
def compose_announcement(announcement, db, settings, relative_times, show_screen_names, safe=False):
|
||||
# Use the default template or a configured one if available
|
||||
template = settings.get("templates", {}).get("announcement", templates.announcement_default_template)
|
||||
text = templates.render_announcement(announcement, template, settings, relative_times, db["utc_offset"])
|
||||
return [text]
|
||||
@@ -217,38 +217,69 @@ class Session(base.baseSession):
|
||||
self.sound.play(_sound)
|
||||
return val
|
||||
|
||||
def send_post(self, reply_to=None, visibility=None, language=None, posts=[]):
|
||||
def _send_quote_post(self, text, quote_id, visibility, sensitive, spoiler_text, language, scheduled_at, in_reply_to_id=None, media_ids=[], poll=None):
|
||||
"""Internal helper to send a quote post using direct API call."""
|
||||
params = {
|
||||
'status': text,
|
||||
'visibility': visibility,
|
||||
'quoted_status_id': quote_id,
|
||||
}
|
||||
if in_reply_to_id:
|
||||
params['in_reply_to_id'] = in_reply_to_id
|
||||
if sensitive:
|
||||
params['sensitive'] = sensitive
|
||||
if spoiler_text:
|
||||
params['spoiler_text'] = spoiler_text
|
||||
if language:
|
||||
params['language'] = language
|
||||
if scheduled_at:
|
||||
if hasattr(scheduled_at, 'isoformat'):
|
||||
params['scheduled_at'] = scheduled_at.isoformat()
|
||||
else:
|
||||
params['scheduled_at'] = scheduled_at
|
||||
if media_ids:
|
||||
params['media_ids'] = media_ids
|
||||
if poll:
|
||||
params['poll'] = poll
|
||||
|
||||
# Use the internal API request method directly
|
||||
return self.api._Mastodon__api_request('POST', '/api/v1/statuses', params)
|
||||
|
||||
def send_post(self, reply_to=None, quote_id=None, visibility=None, language=None, posts=[]):
|
||||
""" Convenience function to send a thread. """
|
||||
in_reply_to_id = reply_to
|
||||
for obj in posts:
|
||||
text = obj.get("text")
|
||||
scheduled_at = obj.get("scheduled_at")
|
||||
if len(obj["attachments"]) == 0:
|
||||
|
||||
# Prepare media and polls first as they are needed for both standard and quote posts
|
||||
media_ids = []
|
||||
poll = None
|
||||
if len(obj["attachments"]) > 0:
|
||||
try:
|
||||
item = self.api_call(call_name="status_post", status=text, _sound="tweet_send.ogg", in_reply_to_id=in_reply_to_id, visibility=visibility, sensitive=obj["sensitive"], spoiler_text=obj["spoiler_text"], language=language, scheduled_at=scheduled_at)
|
||||
# If it fails, let's basically send an event with all passed info so we will catch it later.
|
||||
except Exception as e:
|
||||
pub.sendMessage("mastodon.error_post", name=self.get_name(), reply_to=reply_to, visibility=visibility, posts=posts, lang=language)
|
||||
return
|
||||
if item != None:
|
||||
in_reply_to_id = item["id"]
|
||||
else:
|
||||
media_ids = []
|
||||
try:
|
||||
poll = None
|
||||
if len(obj["attachments"]) == 1 and obj["attachments"][0]["type"] == "poll":
|
||||
poll = self.api.make_poll(options=obj["attachments"][0]["options"], expires_in=obj["attachments"][0]["expires_in"], multiple=obj["attachments"][0]["multiple"], hide_totals=obj["attachments"][0]["hide_totals"])
|
||||
else:
|
||||
for i in obj["attachments"]:
|
||||
media = self.api_call("media_post", media_file=i["file"], description=i["description"], synchronous=True)
|
||||
media_ids.append(media.id)
|
||||
item = self.api_call(call_name="status_post", status=text, _sound="tweet_send.ogg", in_reply_to_id=in_reply_to_id, media_ids=media_ids, visibility=visibility, poll=poll, sensitive=obj["sensitive"], spoiler_text=obj["spoiler_text"], language=language, scheduled_at=scheduled_at)
|
||||
if item != None:
|
||||
in_reply_to_id = item["id"]
|
||||
except Exception as e:
|
||||
pub.sendMessage("mastodon.error_post", name=self.get_name(), reply_to=reply_to, visibility=visibility, posts=posts, lang=language)
|
||||
pub.sendMessage("mastodon.error_post", name=self.get_name(), reply_to=reply_to, visibility=visibility, posts=posts, language=language)
|
||||
return
|
||||
|
||||
try:
|
||||
if quote_id:
|
||||
item = self._send_quote_post(text, quote_id, visibility, obj["sensitive"], obj["spoiler_text"], language, scheduled_at, in_reply_to_id, media_ids, poll)
|
||||
self.sound.play("tweet_send.ogg")
|
||||
else:
|
||||
item = self.api_call(call_name="status_post", status=text, _sound="tweet_send.ogg", in_reply_to_id=in_reply_to_id, media_ids=media_ids, visibility=visibility, poll=poll, sensitive=obj["sensitive"], spoiler_text=obj["spoiler_text"], language=language, scheduled_at=scheduled_at)
|
||||
|
||||
if item != None:
|
||||
in_reply_to_id = item["id"]
|
||||
except Exception as e:
|
||||
pub.sendMessage("mastodon.error_post", name=self.get_name(), reply_to=reply_to, visibility=visibility, posts=posts, language=language)
|
||||
return
|
||||
|
||||
def edit_post(self, post_id, posts=[]):
|
||||
""" Convenience function to edit a post. Only the first item in posts list is used as threads cannot be edited.
|
||||
|
||||
|
||||
@@ -13,12 +13,14 @@ post_variables = ["date", "display_name", "screen_name", "source", "lang", "safe
|
||||
person_variables = ["display_name", "screen_name", "description", "followers", "following", "favorites", "posts", "created_at"]
|
||||
conversation_variables = ["users", "last_post"]
|
||||
notification_variables = ["display_name", "screen_name", "text", "date"]
|
||||
announcement_variables = ["text", "published_at", "updated_at", "starts_at", "ends_at", "read"]
|
||||
|
||||
# Default, translatable templates.
|
||||
post_default_template = _("$display_name, $text $image_descriptions $date. $source")
|
||||
dm_sent_default_template = _("Dm to $recipient_display_name, $text $date")
|
||||
person_default_template = _("$display_name (@$screen_name). $followers followers, $following following, $posts posts. Joined $created_at.")
|
||||
notification_default_template = _("$display_name $text, $date")
|
||||
announcement_default_template = _("$text. Published $published_at. $read")
|
||||
|
||||
def process_date(field, relative_times=True, offset_hours=0):
|
||||
original_date = arrow.get(field)
|
||||
@@ -185,3 +187,23 @@ def render_notification(notification, template, post_template, settings, relativ
|
||||
result = Template(_(template)).safe_substitute(**available_data)
|
||||
result = result.replace(" . ", "")
|
||||
return result
|
||||
|
||||
def render_announcement(announcement, template, settings, relative_times=False, offset_hours=0):
|
||||
""" Renders any given announcement according to the passed template. """
|
||||
global announcement_variables
|
||||
available_data = dict()
|
||||
# Process dates
|
||||
for date_field in ["published_at", "updated_at", "starts_at", "ends_at"]:
|
||||
if hasattr(announcement, date_field) and getattr(announcement, date_field) is not None:
|
||||
available_data[date_field] = process_date(getattr(announcement, date_field), relative_times, offset_hours)
|
||||
else:
|
||||
available_data[date_field] = ""
|
||||
|
||||
available_data["text"] = utils.html_filter(announcement.content)
|
||||
if announcement.read:
|
||||
available_data["read"] = _("Read")
|
||||
else:
|
||||
available_data["read"] = _("Unread")
|
||||
|
||||
result = Template(_(template)).safe_substitute(**available_data)
|
||||
return result
|
||||
|
||||
@@ -3,7 +3,7 @@ import sys
|
||||
import application
|
||||
import platform
|
||||
import os
|
||||
from cx_Freeze import setup, Executable, winmsvcr
|
||||
from cx_Freeze import setup, Executable
|
||||
from requests import certs
|
||||
|
||||
def get_architecture_files():
|
||||
@@ -34,7 +34,7 @@ def find_accessible_output2_datafiles():
|
||||
|
||||
base = None
|
||||
if sys.platform == 'win32':
|
||||
base = 'Win32GUI'
|
||||
base = 'GUI'
|
||||
|
||||
build_exe_options = dict(
|
||||
build_exe="dist",
|
||||
@@ -51,8 +51,6 @@ executables = [
|
||||
Executable('main.py', base=base, target_name="twblue")
|
||||
]
|
||||
|
||||
winmsvcr.FILES = ()
|
||||
winmsvcr.FILES_TO_DUPLICATE = ()
|
||||
setup(name=application.name,
|
||||
version=application.version,
|
||||
description=application.description,
|
||||
|
||||
@@ -2,4 +2,5 @@
|
||||
from .base import basePanel
|
||||
from .conversationList import conversationListPanel
|
||||
from .notifications import notificationsPanel
|
||||
from .user import userPanel
|
||||
from .user import userPanel
|
||||
from .announcements import announcementsPanel
|
||||
|
||||
36
srcantiguo/wxUI/buffers/mastodon/announcements.py
Normal file
36
srcantiguo/wxUI/buffers/mastodon/announcements.py
Normal file
@@ -0,0 +1,36 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import wx
|
||||
from multiplatform_widgets import widgets
|
||||
|
||||
class announcementsPanel(wx.Panel):
|
||||
|
||||
def set_focus_function(self, f):
|
||||
self.list.list.Bind(wx.EVT_LIST_ITEM_FOCUSED, f)
|
||||
|
||||
def create_list(self):
|
||||
self.list = widgets.list(self, _("Announcement"), style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_VRULES)
|
||||
self.list.set_windows_size(0, 800)
|
||||
self.list.set_size()
|
||||
|
||||
def __init__(self, parent, name):
|
||||
super(announcementsPanel, self).__init__(parent)
|
||||
self.name = name
|
||||
self.type = "baseBuffer"
|
||||
self.sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self.create_list()
|
||||
self.dismiss = wx.Button(self, -1, _("Dismiss"))
|
||||
btnSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
btnSizer.Add(self.dismiss, 0, wx.ALL, 5)
|
||||
self.sizer.Add(btnSizer, 0, wx.ALL, 5)
|
||||
self.sizer.Add(self.list.list, 1, wx.ALL|wx.EXPAND, 5)
|
||||
self.SetSizer(self.sizer)
|
||||
self.SetClientSize(self.sizer.CalcMin())
|
||||
|
||||
def set_position(self, reversed=False):
|
||||
if reversed == False:
|
||||
self.list.select_item(self.list.get_count()-1)
|
||||
else:
|
||||
self.list.select_item(0)
|
||||
|
||||
def set_focus_in_list(self):
|
||||
self.list.list.SetFocus()
|
||||
@@ -47,7 +47,7 @@ class generalAccount(wx.Panel, baseDialog.BaseWXDialog):
|
||||
self.SetSizer(sizer)
|
||||
|
||||
class templates(wx.Panel, baseDialog.BaseWXDialog):
|
||||
def __init__(self, parent, post_template, conversation_template, person_template):
|
||||
def __init__(self, parent, post_template, conversation_template, person_template, announcement_template):
|
||||
super(templates, self).__init__(parent)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self.post = wx.Button(self, wx.ID_ANY, _("Edit template for &posts. Current template: {}").format(post_template))
|
||||
@@ -56,6 +56,8 @@ class templates(wx.Panel, baseDialog.BaseWXDialog):
|
||||
sizer.Add(self.conversation, 0, wx.ALL, 5)
|
||||
self.person = wx.Button(self, wx.ID_ANY, _("Edit template for p&ersons. Current template: {}").format(person_template))
|
||||
sizer.Add(self.person, 0, wx.ALL, 5)
|
||||
self.announcement = wx.Button(self, wx.ID_ANY, _("Edit template for &announcements. Current template: {}").format(announcement_template))
|
||||
sizer.Add(self.announcement, 0, wx.ALL, 5)
|
||||
self.SetSizer(sizer)
|
||||
|
||||
class sound(wx.Panel):
|
||||
@@ -152,8 +154,8 @@ class configurationDialog(baseDialog.BaseWXDialog):
|
||||
self.buffers = other_buffers(self.notebook)
|
||||
self.notebook.AddPage(self.buffers, _(u"Buffers"))
|
||||
|
||||
def create_templates(self, post_template, conversation_template, person_template):
|
||||
self.templates = templates(self.notebook, post_template=post_template, conversation_template=conversation_template, person_template=person_template)
|
||||
def create_templates(self, post_template, conversation_template, person_template, announcement_template):
|
||||
self.templates = templates(self.notebook, post_template=post_template, conversation_template=conversation_template, person_template=person_template, announcement_template=announcement_template)
|
||||
self.notebook.AddPage(self.templates, _("Templates"))
|
||||
|
||||
def create_sound(self, output_devices, input_devices, soundpacks):
|
||||
|
||||
@@ -2,11 +2,43 @@
|
||||
import wx
|
||||
import application
|
||||
|
||||
class BoostDialog(wx.Dialog):
|
||||
def __init__(self):
|
||||
super(BoostDialog, self).__init__(None, title=_("Boost"))
|
||||
p = wx.Panel(self)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
lbl = wx.StaticText(p, wx.ID_ANY, _("What would you like to do with this post?"))
|
||||
sizer.Add(lbl, 0, wx.ALL, 10)
|
||||
|
||||
btn_sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
self.btn_boost = wx.Button(p, wx.ID_ANY, _("Boost"))
|
||||
self.btn_quote = wx.Button(p, wx.ID_ANY, _("Quote"))
|
||||
self.btn_cancel = wx.Button(p, wx.ID_CANCEL, _("Cancel"))
|
||||
|
||||
btn_sizer.Add(self.btn_boost, 0, wx.ALL, 5)
|
||||
btn_sizer.Add(self.btn_quote, 0, wx.ALL, 5)
|
||||
btn_sizer.Add(self.btn_cancel, 0, wx.ALL, 5)
|
||||
|
||||
sizer.Add(btn_sizer, 0, wx.ALIGN_CENTER)
|
||||
p.SetSizer(sizer)
|
||||
sizer.Fit(self)
|
||||
|
||||
self.btn_boost.Bind(wx.EVT_BUTTON, self.on_boost)
|
||||
self.btn_quote.Bind(wx.EVT_BUTTON, self.on_quote)
|
||||
self.result = 0
|
||||
|
||||
def on_boost(self, event):
|
||||
self.result = 1
|
||||
self.EndModal(wx.ID_OK)
|
||||
|
||||
def on_quote(self, event):
|
||||
self.result = 2
|
||||
self.EndModal(wx.ID_OK)
|
||||
|
||||
def boost_question():
|
||||
result = False
|
||||
dlg = wx.MessageDialog(None, _("Would you like to share this post?"), _("Boost"), wx.YES_NO|wx.ICON_QUESTION)
|
||||
if dlg.ShowModal() == wx.ID_YES:
|
||||
result = True
|
||||
dlg = BoostDialog()
|
||||
dlg.ShowModal()
|
||||
result = dlg.result
|
||||
dlg.Destroy()
|
||||
return result
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ class base(wx.Menu):
|
||||
super(base, self).__init__()
|
||||
self.boost = wx.MenuItem(self, wx.ID_ANY, _("&Boost"))
|
||||
self.Append(self.boost)
|
||||
self.quote = wx.MenuItem(self, wx.ID_ANY, _("&Quote"))
|
||||
self.Append(self.quote)
|
||||
self.reply = wx.MenuItem(self, wx.ID_ANY, _(u"Re&ply"))
|
||||
self.Append(self.reply)
|
||||
self.edit = wx.MenuItem(self, wx.ID_ANY, _(u"&Edit"))
|
||||
@@ -38,6 +40,8 @@ class notification(wx.Menu):
|
||||
if item in valid_types:
|
||||
self.boost = wx.MenuItem(self, wx.ID_ANY, _("&Boost"))
|
||||
self.Append(self.boost)
|
||||
self.quote = wx.MenuItem(self, wx.ID_ANY, _("&Quote"))
|
||||
self.Append(self.quote)
|
||||
self.reply = wx.MenuItem(self, wx.ID_ANY, _(u"Re&ply"))
|
||||
self.Append(self.reply)
|
||||
self.edit = wx.MenuItem(self, wx.ID_ANY, _(u"&Edit"))
|
||||
|
||||
Reference in New Issue
Block a user