From ec68c7ccae8c11277f16741d66a73e1a77e363b2 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Wed, 14 Dec 2022 12:12:05 -0600 Subject: [PATCH] Mastodon: Added initial implementation for notifications buffer (actions not available yet) --- src/controller/buffers/mastodon/__init__.py | 3 +- .../buffers/mastodon/notifications.py | 43 ++++++++++++++++++ src/controller/mastodon/handler.py | 2 + src/sessions/mastodon/templates.py | 44 ++++++++++++++++++- src/wxUI/buffers/mastodon/__init__.py | 1 + src/wxUI/buffers/mastodon/notifications.py | 39 ++++++++++++++++ 6 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 src/controller/buffers/mastodon/notifications.py create mode 100644 src/wxUI/buffers/mastodon/notifications.py diff --git a/src/controller/buffers/mastodon/__init__.py b/src/controller/buffers/mastodon/__init__.py index 9ad9d46d..2e1bdebe 100644 --- a/src/controller/buffers/mastodon/__init__.py +++ b/src/controller/buffers/mastodon/__init__.py @@ -2,4 +2,5 @@ from .base import BaseBuffer from .mentions import MentionsBuffer from .conversations import ConversationBuffer, ConversationListBuffer -from .users import UserBuffer \ No newline at end of file +from .users import UserBuffer +from .notifications import NotificationsBuffer \ No newline at end of file diff --git a/src/controller/buffers/mastodon/notifications.py b/src/controller/buffers/mastodon/notifications.py new file mode 100644 index 00000000..dc7976a3 --- /dev/null +++ b/src/controller/buffers/mastodon/notifications.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +import time +import logging +import widgetUtils +from controller.buffers.mastodon.base import BaseBuffer +from sessions.mastodon import compose, templates +from wxUI import buffers + +log = logging.getLogger("controller.buffers.mastodon.notifications") + +class NotificationsBuffer(BaseBuffer): + + def get_message(self): + notification = self.get_item() + if notification == None: + return + template = self.session.settings["templates"]["notification"] + post_template = self.session.settings["templates"]["post"] + t = templates.render_notification(notification, template, post_template, relative_times=self.session.settings["general"]["relative_times"], offset_hours=self.session.db["utc_offset"]) + return t + + def create_buffer(self, parent, name): + self.buffer = buffers.mastodon.notificationsPanel(parent, name) + + def onFocus(self, *args, **kwargs): + item = self.get_item() + if self.session.settings["general"]["relative_times"] == True: + original_date = arrow.get(self.session.db[self.name][self.buffer.list.get_selected()].created_at) + ts = original_date.humanize(locale=languageHandler.getLanguage()) + self.buffer.list.list.SetItem(self.buffer.list.get_selected(), 1, ts) + + def bind_events(self): + widgetUtils.connect_event(self.buffer.list.list, widgetUtils.KEYPRESS, self.get_event) + widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.post_status, self.buffer.post) + + def fav(self): + pass + + def unfav(self): + pass + + def can_share(self): + return False diff --git a/src/controller/mastodon/handler.py b/src/controller/mastodon/handler.py index d281d448..ee9da430 100644 --- a/src/controller/mastodon/handler.py +++ b/src/controller/mastodon/handler.py @@ -48,6 +48,8 @@ class Handler(object): pub.sendMessage("createBuffer", buffer_type="UserBuffer", session_type=session.type, buffer_title=_("Muted users"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, compose_func="compose_user", function="mutes", name="muted", sessionObject=session, account=name)) elif i == 'blocked': 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)) 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"]: diff --git a/src/sessions/mastodon/templates.py b/src/sessions/mastodon/templates.py index 803aab3d..0c8fac33 100644 --- a/src/sessions/mastodon/templates.py +++ b/src/sessions/mastodon/templates.py @@ -12,11 +12,13 @@ from . import utils, compose post_variables = ["date", "display_name", "screen_name", "source", "lang", "safe_text", "text", "image_descriptions", "visibility"] 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"] # 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") def process_date(field, relative_times=True, offset_hours=0): original_date = arrow.get(field) @@ -134,4 +136,44 @@ def render_conversation(conversation, template, post_template, relative_times=Fa available_data = dict(users=users, last_post=last_post) result = Template(_(template)).safe_substitute(**available_data) result = remove_unneeded_variables(result, conversation_variables) - return result \ No newline at end of file + return result + +def render_notification(notification, template, post_template, relative_times=False, offset_hours=0): + """ Renders any given notification according to the passed template. + Available data for notifications will be stored in the following variables: + $date: Creation date. + $display_name: User profile name. + $screen_name: User screen name, this is the same name used to reference the user in Twitter. + $text: Notification text, describing the action. + """ + global notification_variables + available_data = dict() + created_at = process_date(notification.created_at, relative_times, offset_hours) + available_data.update(date=created_at) + # user. + display_name = notification.account.display_name + if display_name == "": + display_name = notification.account.username + available_data.update(display_name=display_name, screen_name=notification.account.acct) + text = "Unknown: %r" % (notification) + # Remove date from status, so it won't be rendered twice. + post_template = post_template.replace("$date", "") + if notification.type == "mention": + text = _("has mentionned you: {status}").format(status=render_post(notification.status, post_template, relative_times, offset_hours)) + elif notification.type == "reblog": + text = _("has boosted: {status}").format(status=render_post(notification.status, post_template, relative_times, offset_hours)) + elif notification.type == "favourite": + text = _("has added to favorites: {status}").format(status=render_post(notification.status, post_template, relative_times, offset_hours)) + elif notification.type == "update": + text = _("has updated a status: {status}").format(status=render_post(notification.status, post_template, relative_times, offset_hours)) + elif notification.type == "follow": + text = _("has followed you.") + elif notification.type == "poll": + text = _("A poll in which you have voted has expired: {status}").format(status=render_post(notification.status, post_template, relative_times, offset_hours)) + elif notification.type == "follow_request": + text = _("wants to follow you.") + available_data.update(text=text) + result = Template(_(template)).safe_substitute(**available_data) + result = remove_unneeded_variables(result, post_variables) + result = result.replace(" . ", "") + return result diff --git a/src/wxUI/buffers/mastodon/__init__.py b/src/wxUI/buffers/mastodon/__init__.py index 5cff6033..32791133 100644 --- a/src/wxUI/buffers/mastodon/__init__.py +++ b/src/wxUI/buffers/mastodon/__init__.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- from .base import basePanel from .conversationList import conversationListPanel +from .notifications import notificationsPanel from .user import userPanel \ No newline at end of file diff --git a/src/wxUI/buffers/mastodon/notifications.py b/src/wxUI/buffers/mastodon/notifications.py new file mode 100644 index 00000000..1e8e2ddb --- /dev/null +++ b/src/wxUI/buffers/mastodon/notifications.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +import wx +from multiplatform_widgets import widgets + +class notificationsPanel(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, _("Text"), _("Date"), style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_VRULES) + self.list.set_windows_size(0, 320) + self.list.set_windows_size(2, 110) + self.list.set_size() + + def __init__(self, parent, name): + super(notificationsPanel, self).__init__(parent) + self.name = name + self.type = "baseBuffer" + self.sizer = wx.BoxSizer(wx.VERTICAL) + self.create_list() + self.post = wx.Button(self, -1, _("Post")) + self.dismiss = wx.Button(self, -1, _("Dismiss")) + btnSizer = wx.BoxSizer(wx.HORIZONTAL) + btnSizer.Add(self.post, 0, wx.ALL, 5) + btnSizer.Add(self.dismiss, 0, wx.ALL, 5) + self.sizer.Add(btnSizer, 0, wx.ALL, 5) + self.sizer.Add(self.list.list, 0, 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()