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 -*-
from .base import BaseBuffer
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):
super(BaseBuffer, self).__init__(parent, function, *args, **kwargs)
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.name = name
self.type = self.buffer.type
@ -38,6 +38,9 @@ class BaseBuffer(base.Buffer):
self.bind_events()
self.sound = sound
def create_buffer(self, parent, name):
self.buffer = buffers.mastodon.basePanel(parent, name)
def get_buffer_name(self):
""" Get buffer name from a set of different techniques."""
# firstly let's take the easier buffers.

View File

@ -1,12 +1,71 @@
# -*- coding: utf-8 -*-
import time
import logging
import wx
import widgetUtils
from controller.buffers.mastodon.base import BaseBuffer
from sessions.mastodon import utils
from wxUI import commonMessageDialogs
from sessions.mastodon import utils, templates
from wxUI import buffers, commonMessageDialogs
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):
def __init__(self, toot, *args, **kwargs):
@ -41,38 +100,7 @@ class ConversationBuffer(BaseBuffer):
return number_of_items
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
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)
output.speak(_(u"This action is not supported for this buffer"), True)
def remove_buffer(self, 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"))
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"))
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':
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':
@ -76,3 +78,10 @@ class Handler(object):
buffer.start_stream(play_sound=False)
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))
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)
load_cache_in_memory=boolean(default=True)
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")
[sound]
@ -46,6 +46,7 @@ speech_reporting = boolean(default=True)
[templates]
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.")
conversation = string(default="Conversation with $users. Last message: $last_toot")
[filters]

View File

@ -36,3 +36,15 @@ def compose_user(user, db, relative_times=True):
if name == "":
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)]
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 languageHandler
from string import Template
from . import utils
from . import utils, compose
# Define variables that would be available for all template objects.
# 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.
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"]
conversation_variables = ["users", "last_toot"]
# Default, translatable templates.
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 = remove_unneeded_variables(result, person_variables)
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)):
if listItems[i].id == item.id:
return i
# Check also retweets.
if item.reblog != None and item.reblog.id == listItems[i].id:
if hasattr(item, "reblog") and item.reblog != None and item.reblog.id == listItems[i].id:
return i
return None

View File

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