From 149ce51f4913b793a0e7e61030dce4d859107abb Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Fri, 18 Nov 2022 16:29:53 -0600 Subject: [PATCH] early support to user streaming events --- .../buffers/mastodon/conversations.py | 2 +- src/controller/mainController.py | 41 ++++++++++++---- src/sessions/mastodon/session.py | 48 ++++++++++++++++++- src/sessions/mastodon/streaming.py | 13 +++++ 4 files changed, 93 insertions(+), 11 deletions(-) create mode 100644 src/sessions/mastodon/streaming.py diff --git a/src/controller/buffers/mastodon/conversations.py b/src/controller/buffers/mastodon/conversations.py index 4f29a302..cbed5610 100644 --- a/src/controller/buffers/mastodon/conversations.py +++ b/src/controller/buffers/mastodon/conversations.py @@ -173,7 +173,7 @@ class ConversationListBuffer(BaseBuffer): item = self.get_item() conversation = self.get_conversation() visibility = item.visibility - title = _("Conversation with {}").format(conversation.accounts[0].username) + title = _("Reply to conversation with {}").format(conversation.accounts[0].username) caption = _("Write your message here") users = ["@{} ".format(user.acct) for user in conversation.accounts] users_str = "".join(users) diff --git a/src/controller/mainController.py b/src/controller/mainController.py index 8bf279de..07bc92d3 100644 --- a/src/controller/mainController.py +++ b/src/controller/mainController.py @@ -100,13 +100,20 @@ class Controller(object): def bind_other_events(self): """ Binds the local application events with their functions.""" log.debug("Binding other application events...") - pub.subscribe(self.buffer_title_changed, "buffer-title-changed") - pub.subscribe(self.manage_sent_dm, "twitter.sent_dm") - widgetUtils.connect_event(self.view, widgetUtils.CLOSE_EVENT, self.exit_) + + # Core application pubsub events. pub.subscribe(self.logout_account, "logout") pub.subscribe(self.login_account, "login") pub.subscribe(self.execute_action, "execute-action") pub.subscribe(self.search_topic, "search") + pub.subscribe(self.create_buffer, "createBuffer") + pub.subscribe(self.toggle_share_settings, "toggleShare") + pub.subscribe(self.invisible_shorcuts_changed, "invisible-shorcuts-changed") + pub.subscribe(self.create_account_buffer, "core.create_account") + + # Twitter specific events. + pub.subscribe(self.buffer_title_changed, "buffer-title-changed") + pub.subscribe(self.manage_sent_dm, "twitter.sent_dm") pub.subscribe(self.update_sent_dms, "twitter.sent_dms_updated") pub.subscribe(self.more_dms, "twitter.more_sent_dms") pub.subscribe(self.manage_sent_tweets, "twitter.sent_tweet") @@ -117,11 +124,13 @@ class Controller(object): pub.subscribe(self.manage_unfavourite, "twitter.unfavourite") pub.subscribe(self.manage_blocked_user, "twitter.blocked_user") pub.subscribe(self.manage_unblocked_user, "twitter.unblocked_user") - pub.subscribe(self.create_buffer, "createBuffer") - pub.subscribe(self.toggle_share_settings, "toggleShare") pub.subscribe(self.restart_streaming, "twitter.restart_streaming") - pub.subscribe(self.invisible_shorcuts_changed, "invisible-shorcuts-changed") - pub.subscribe(self.create_account_buffer, "core.create_account") + + # Mastodon specific events. + pub.subscribe(self.mastodon_new_item, "mastodon.new_item") + + # connect application events to GUI + widgetUtils.connect_event(self.view, widgetUtils.CLOSE_EVENT, self.exit_) widgetUtils.connect_event(self.view, widgetUtils.MENU, self.show_hide, menuitem=self.view.show_hide) widgetUtils.connect_event(self.view, widgetUtils.MENU, self.search, menuitem=self.view.menuitem_search) widgetUtils.connect_event(self.view, widgetUtils.MENU, self.list_manager, menuitem=self.view.lists) @@ -1211,4 +1220,20 @@ class Controller(object): if sessions.sessions[s].session_id == session: log.debug("Restarting stream in session %s" % (session)) sessions.sessions[s].stop_streaming() - sessions.sessions[s].start_streaming() \ No newline at end of file + sessions.sessions[s].start_streaming() + + def mastodon_new_item(self, item, session_name, _buffers): + sound_to_play = None + for buff in _buffers: + buffer = self.search_buffer(buff, session_name) + if buffer == None or buffer.session.get_name() != session_name: + return + buffer.add_new_item(item) + if buff == "home_timeline": sound_to_play = "tweet_received.ogg" + elif buff == "mentions": sound_to_play = "mention_received.ogg" + elif buff == "direct_messages": sound_to_play = "dm_received.ogg" + elif buff == "sent": sound_to_play = "tweet_send.ogg" + elif "timeline" in buff: sound_to_play = "tweet_timeline.ogg" + else: sound_to_play = None + if sound_to_play != None and buff not in buffer.session.settings["other_buffers"]["muted_buffers"]: + self.notify(buffer.session, sound_to_play) diff --git a/src/sessions/mastodon/session.py b/src/sessions/mastodon/session.py index b49a86d2..fa6b13af 100644 --- a/src/sessions/mastodon/session.py +++ b/src/sessions/mastodon/session.py @@ -14,7 +14,7 @@ from mastodon import MastodonError, MastodonNotFoundError, MastodonUnauthorizedE from pubsub import pub from mysc.thread_utils import call_threaded from sessions import base -from sessions.mastodon import utils +from sessions.mastodon import utils, streaming from .wxUI import authorisationDialog log = logging.getLogger("sessions.mastodonSession") @@ -30,6 +30,7 @@ class Session(base.baseSession): self.type = "mastodon" self.db["pagination_info"] = dict() self.char_limit = 500 + pub.subscribe(self.on_status, "mastodon.new_status") def login(self, verify_credentials=True): if self.settings["mastodon"]["access_token"] != None and self.settings["mastodon"]["instance"] != None: @@ -202,4 +203,47 @@ class Session(base.baseSession): instance = self.settings["mastodon"]["instance"] instance = instance.replace("https://", "") user = self.settings["mastodon"]["user_name"] - return "Mastodon: {}@{}".format(user, instance) \ No newline at end of file + return "Mastodon: {}@{}".format(user, instance) + + def start_streaming(self): + if config.app["app-settings"]["no_streaming"]: + return + listener = streaming.StreamListener(session_name=self.get_name(), user_id=self.db["user_id"]) + self.stream = self.api.stream_user(listener, run_async=True, reconnect_async=True) + + def stop_streaming(self): + if config.app["app-settings"]["no_streaming"]: + return + if hasattr(self, "stream"): + self.stream.close() + log.debug("Stream stopped for accounr {}".format(self.db["user_name"])) + + def check_streams(self): + if config.app["app-settings"]["no_streaming"]: + return + if not hasattr(self, "stream"): + return + log.debug("Status of running stream for user {}: {}".format(self.db["user_name"], self.stream.running)) + if self.stream.is_alive() == False or self.stream.is_receiving() == False: + self.start_streaming() + + def check_buffers(self, status): + buffers = [] + buffers.append("home_timeline") + if status.account.id == self.db["user_id"]: + buffers.append("sent") + mentions = [user.id for user in status.mentions] + if self.db["user_id"] in mentions: + buffers.append("mentions") + return buffers + + def on_status(self, status, session_name): + # Discard processing the status if the streaming sends a tweet for another account. + if self.get_name() != session_name: + return + buffers = self.check_buffers(status) + for b in buffers[::]: + num = self.order_buffer(b, [status]) + if num == 0: + buffers.remove(b) + pub.sendMessage("mastodon.new_item", session_name=self.get_name(), item=status, _buffers=buffers) \ No newline at end of file diff --git a/src/sessions/mastodon/streaming.py b/src/sessions/mastodon/streaming.py new file mode 100644 index 00000000..08759725 --- /dev/null +++ b/src/sessions/mastodon/streaming.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +import mastodon +from pubsub import pub + +class StreamListener(mastodon.StreamListener): + + def __init__(self, session_name, user_id): + self.session_name = session_name + self.user_id = user_id + super(StreamListener, self).__init__() + + def on_update(self, status): + pub.sendMessage("mastodon.new_status", status=status, session_name=self.session_name) \ No newline at end of file