Added initial support for direct messages, users need to open conversations for every dm

This commit is contained in:
Manuel Cortez 2022-11-12 11:20:16 -06:00
parent 39fc982665
commit 81ff530a71
No known key found for this signature in database
GPG Key ID: 9E0735CA15EFE790
9 changed files with 109 additions and 41 deletions

View File

@ -1,4 +1,4 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from .base import BaseBuffer from .base import BaseBuffer
from .mentions import MentionsBuffer from .mentions import MentionsBuffer
from .conversations import ConversationBuffer from .conversations import ConversationBuffer, ConversationListBuffer

View File

@ -26,7 +26,7 @@ class BaseBuffer(base.Buffer):
def __init__(self, parent, function, name, sessionObject, account, sound=None, compose_func="compose_toot", *args, **kwargs): def __init__(self, parent, function, name, sessionObject, account, sound=None, compose_func="compose_toot", *args, **kwargs):
super(BaseBuffer, self).__init__(parent, function, *args, **kwargs) super(BaseBuffer, self).__init__(parent, function, *args, **kwargs)
log.debug("Initializing buffer %s, account %s" % (name, account,)) log.debug("Initializing buffer %s, account %s" % (name, account,))
self.buffer = buffers.mastodon.basePanel(parent, name) self.create_buffer(parent, name)
self.invisible = True self.invisible = True
self.name = name self.name = name
self.type = self.buffer.type self.type = self.buffer.type
@ -38,6 +38,9 @@ class BaseBuffer(base.Buffer):
self.bind_events() self.bind_events()
self.sound = sound self.sound = sound
def create_buffer(self, parent, name):
self.buffer = buffers.mastodon.basePanel(parent, name)
def get_buffer_name(self): def get_buffer_name(self):
""" Get buffer name from a set of different techniques.""" """ Get buffer name from a set of different techniques."""
# firstly let's take the easier buffers. # firstly let's take the easier buffers.

View File

@ -1,12 +1,71 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import time import time
import logging import logging
import wx
import widgetUtils import widgetUtils
from controller.buffers.mastodon.base import BaseBuffer from controller.buffers.mastodon.base import BaseBuffer
from sessions.mastodon import utils from sessions.mastodon import utils, templates
from wxUI import commonMessageDialogs from wxUI import buffers, commonMessageDialogs
log = logging.getLogger("controller.buffers.mastodon.conversations") log = logging.getLogger("controller.buffers.mastodon.conversations")
class ConversationListBuffer(BaseBuffer):
def create_buffer(self, parent, name):
self.buffer = buffers.mastodon.conversationListPanel(parent, name)
def get_item(self):
index = self.buffer.list.get_selected()
if index > -1 and self.session.db.get(self.name) != None:
return self.session.db[self.name][index]["last_status"]
def get_formatted_message(self):
return self.compose_function(self.get_conversation(), self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"])[1]
def get_conversation(self):
index = self.buffer.list.get_selected()
if index > -1 and self.session.db.get(self.name) != None:
return self.session.db[self.name][index]
def get_message(self):
conversation = self.get_conversation()
if conversation == None:
return
template = self.session.settings["templates"]["conversation"]
toot_template = self.session.settings["templates"]["toot"]
t = templates.render_conversation(conversation=conversation, template=template, toot_template=toot_template, relative_times=self.session.settings["general"]["relative_times"], offset_hours=self.session.db["utc_offset"])
return t
def bind_events(self):
log.debug("Binding events...")
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.post_status, self.buffer.toot)
widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.reply, self.buffer.reply)
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 fav(self):
pass
def unfav(self):
pass
def can_share(self):
return False
def send_message(self):
return self.reply()
def onFocus(self, *args, **kwargs):
toot = self.get_item()
if self.session.settings['sound']['indicate_audio'] and utils.is_audio_or_video(toot):
self.session.sound.play("audio.ogg")
if self.session.settings['sound']['indicate_img'] and utils.is_image(toot):
self.session.sound.play("image.ogg")
def destroy_status(self):
pass
class ConversationBuffer(BaseBuffer): class ConversationBuffer(BaseBuffer):
def __init__(self, toot, *args, **kwargs): def __init__(self, toot, *args, **kwargs):
@ -41,38 +100,7 @@ class ConversationBuffer(BaseBuffer):
return number_of_items return number_of_items
def get_more_items(self): def get_more_items(self):
elements = [] output.speak(_(u"This action is not supported for this buffer"), True)
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
try:
items = getattr(self.session.api, self.function)(max_id=max_id, limit=self.session.settings["general"]["max_toots_per_call"], exclude_types=["follow", "favourite", "reblog", "poll", "follow_request"], *self.args, **self.kwargs)
items = [item.status for item in items if item.get("status") and item.type == "mention"]
except Exception as e:
log.exception("Error %s" % (str(e)))
return
items_db = self.session.db[self.name]
for i in items:
if utils.find_item(i, self.session.db[self.name]) == None:
elements.append(i)
if self.session.settings["general"]["reverse_timelines"] == False:
items_db.insert(0, i)
else:
items_db.append(i)
self.session.db[self.name] = items_db
selection = self.buffer.list.get_selected()
log.debug("Retrieved %d items from cursored search in function %s." % (len(elements), self.function))
if self.session.settings["general"]["reverse_timelines"] == False:
for i in elements:
toot = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"])
self.buffer.list.insert_item(True, *toot)
else:
for i in items:
toot = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"])
self.buffer.list.insert_item(False, *toot)
self.buffer.list.select_item(selection)
output.speak(_(u"%s items retrieved") % (str(len(elements))), True)
def remove_buffer(self, force=False): def remove_buffer(self, force=False):
if force == False: if force == False:

View File

@ -24,6 +24,8 @@ class Handler(object):
pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Federated"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, function="timeline_public", name="federated_timeline", sessionObject=session, account=session.db["user_name"], sound="tweet_received.ogg")) pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Federated"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, function="timeline_public", name="federated_timeline", sessionObject=session, account=session.db["user_name"], sound="tweet_received.ogg"))
elif i == 'mentions': elif i == 'mentions':
pub.sendMessage("createBuffer", buffer_type="MentionsBuffer", session_type=session.type, buffer_title=_("Mentions"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, function="notifications", name="mentions", sessionObject=session, account=session.db["user_name"], sound="mention_received.ogg")) pub.sendMessage("createBuffer", buffer_type="MentionsBuffer", session_type=session.type, buffer_title=_("Mentions"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, function="notifications", name="mentions", sessionObject=session, account=session.db["user_name"], sound="mention_received.ogg"))
elif i == 'direct_messages':
pub.sendMessage("createBuffer", buffer_type="ConversationListBuffer", session_type=session.type, buffer_title=_("Direct messages"), parent_tab=root_position, start=False, kwargs=dict(compose_func="compose_conversation", parent=controller.view.nb, function="conversations", name="direct_messages", sessionObject=session, account=session.db["user_name"], sound="dm_received.ogg"))
elif i == 'sent': elif i == 'sent':
pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Sent"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, function="account_statuses", name="sent", sessionObject=session, account=session.db["user_name"], sound="tweet_received.ogg", id=session.db["user_id"])) pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Sent"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, function="account_statuses", name="sent", sessionObject=session, account=session.db["user_name"], sound="tweet_received.ogg", id=session.db["user_id"]))
# elif i == 'dm': # elif i == 'dm':
@ -76,3 +78,10 @@ class Handler(object):
buffer.start_stream(play_sound=False) buffer.start_stream(play_sound=False)
except Exception as err: except Exception as err:
log.exception("Error %s starting buffer %s on account %s, with args %r and kwargs %r." % (str(err), buffer.name, buffer.account, buffer.args, buffer.kwargs)) log.exception("Error %s starting buffer %s on account %s, with args %r and kwargs %r." % (str(err), buffer.name, buffer.account, buffer.args, buffer.kwargs))
def open_conversation(self, controller, buffer):
toot = buffer.get_item()
if toot.reblog != None:
toot = toot.reblog
conversations_position =controller.view.search("direct_messages", buffer.session.db["user_name"])
pub.sendMessage("createBuffer", buffer_type="ConversationBuffer", session_type=buffer.session.type, buffer_title=_("Conversation with {0}").format(toot.account.acct), parent_tab=conversations_position, start=True, kwargs=dict(parent=controller.view.nb, function="status_context", name="%s-conversation" % (toot.id,), sessionObject=buffer.session, account=buffer.session.db["user_name"], sound="search_updated.ogg", toot=toot, id=toot.id))

View File

@ -11,7 +11,7 @@ reverse_timelines = boolean(default=False)
persist_size = integer(default=0) persist_size = integer(default=0)
load_cache_in_memory=boolean(default=True) load_cache_in_memory=boolean(default=True)
show_screen_names = boolean(default=False) show_screen_names = boolean(default=False)
buffer_order = list(default=list('home', 'local', 'federated', 'mentions', 'conversations', 'sent', 'favorites', 'bookmarks', 'followers', 'friends', 'blocks', 'muted', 'notifications')) buffer_order = list(default=list('home', 'local', 'federated', 'mentions', 'direct_messages', 'sent', 'favorites', 'bookmarks', 'followers', 'friends', 'blocks', 'muted', 'notifications'))
boost_mode = string(default="ask") boost_mode = string(default="ask")
[sound] [sound]
@ -46,6 +46,7 @@ speech_reporting = boolean(default=True)
[templates] [templates]
toot = string(default="$display_name, $safe_text $image_descriptions $date. $source") toot = string(default="$display_name, $safe_text $image_descriptions $date. $source")
person = string(default="$display_name (@$screen_name). $followers followers, $following following, $toots toots. Joined $created_at.") person = string(default="$display_name (@$screen_name). $followers followers, $following following, $toots toots. Joined $created_at.")
conversation = string(default="Conversation with $users. Last message: $last_toot")
[filters] [filters]

View File

@ -36,3 +36,15 @@ def compose_user(user, db, relative_times=True):
if name == "": if name == "":
name = user.get("username") name = user.get("username")
return [_("%s (@%s). %s followers, %s following, %s toots. Joined %s") % (name, user.acct, user.followers_count, user.following_count, user.statuses_count, ts)] return [_("%s (@%s). %s followers, %s following, %s toots. Joined %s") % (name, user.acct, user.followers_count, user.following_count, user.statuses_count, ts)]
def compose_conversation(conversation, db, relative_times, show_screen_names):
users = []
for account in conversation.accounts:
if account.display_name != "":
users.append(account.display_name)
else:
users.append(account.username)
users = ", ".join(users)
last_toot = compose_toot(conversation.last_status, db, relative_times, show_screen_names)
text = _("Last message from {}: {}").format(last_toot[0], last_toot[1])
return [users, text, last_toot[-1], ""]

View File

@ -3,7 +3,7 @@ import re
import arrow import arrow
import languageHandler import languageHandler
from string import Template from string import Template
from . import utils from . import utils, compose
# Define variables that would be available for all template objects. # Define variables that would be available for all template objects.
# This will be used for the edit template dialog. # This will be used for the edit template dialog.
@ -11,6 +11,7 @@ from . import utils
# safe_text will be the content warning in case a toot contains one, text will always be the full text, no matter if has a content warning or not. # safe_text will be the content warning in case a toot contains one, text will always be the full text, no matter if has a content warning or not.
toot_variables = ["date", "display_name", "screen_name", "source", "lang", "safe_text", "text", "image_descriptions"] toot_variables = ["date", "display_name", "screen_name", "source", "lang", "safe_text", "text", "image_descriptions"]
person_variables = ["display_name", "screen_name", "description", "followers", "following", "favorites", "toots", "created_at"] person_variables = ["display_name", "screen_name", "description", "followers", "following", "favorites", "toots", "created_at"]
conversation_variables = ["users", "last_toot"]
# Default, translatable templates. # Default, translatable templates.
toot_default_template = _("$display_name, $text $image_descriptions $date. $source") toot_default_template = _("$display_name, $text $image_descriptions $date. $source")
@ -119,3 +120,17 @@ def render_person(user, template, relative_times=True, offset_hours=0):
result = Template(_(template)).safe_substitute(**available_data) result = Template(_(template)).safe_substitute(**available_data)
result = remove_unneeded_variables(result, person_variables) result = remove_unneeded_variables(result, person_variables)
return result return result
def render_conversation(conversation, template, toot_template, relative_times=False, offset_hours=0):
users = []
for account in conversation.accounts:
if account.display_name != "":
users.append(account.display_name)
else:
users.append(account.username)
users = ", ".join(users)
last_toot = render_toot(conversation.last_status, toot_template, relative_times=relative_times, offset_hours=offset_hours)
available_data = dict(users=users, last_toot=last_toot)
result = Template(_(template)).safe_substitute(**available_data)
result = remove_unneeded_variables(result, conversation_variables)
return result

View File

@ -21,8 +21,7 @@ def find_item(item, listItems):
for i in range(0, len(listItems)): for i in range(0, len(listItems)):
if listItems[i].id == item.id: if listItems[i].id == item.id:
return i return i
# Check also retweets. if hasattr(item, "reblog") and item.reblog != None and item.reblog.id == listItems[i].id:
if item.reblog != None and item.reblog.id == listItems[i].id:
return i return i
return None return None

View File

@ -1,2 +1,3 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from .base import basePanel from .base import basePanel
from .conversationList import conversationListPanel