Added user buffers (buffers for followers, following, blocked and muted users for now)

This commit is contained in:
Manuel Cortez 2022-11-13 22:17:28 -06:00
parent 2a0e73ad33
commit 035de92496
No known key found for this signature in database
GPG Key ID: 9E0735CA15EFE790
10 changed files with 216 additions and 29 deletions

View File

@ -2,3 +2,4 @@
from .base import BaseBuffer from .base import BaseBuffer
from .mentions import MentionsBuffer from .mentions import MentionsBuffer
from .conversations import ConversationBuffer, ConversationListBuffer from .conversations import ConversationBuffer, ConversationListBuffer
from .users import UserBuffer

View File

@ -335,7 +335,7 @@ class BaseBuffer(base.Buffer):
toot.message.visibility.SetSelection(3) toot.message.visibility.SetSelection(3)
response = toot.message.ShowModal() response = toot.message.ShowModal()
if response == wx.ID_OK: if response == wx.ID_OK:
toot_data = toot.get_tweet_data() toot_data = toot.get_data()
call_threaded(self.session.send_toot, toots=toot_data, visibility="direct") call_threaded(self.session.send_toot, toots=toot_data, visibility="direct")
if hasattr(toot.message, "destroy"): if hasattr(toot.message, "destroy"):
toot.message.destroy() toot.message.destroy()

View File

@ -0,0 +1,154 @@
# -*- coding: utf-8 -*-
import time
import logging
import wx
import widgetUtils
import output
from mysc.thread_utils import call_threaded
from controller.buffers.mastodon.base import BaseBuffer
from controller.mastodon import messages
from sessions.mastodon import templates, utils
from wxUI import buffers
log = logging.getLogger("controller.buffers.mastodon.conversations")
class UserBuffer(BaseBuffer):
def create_buffer(self, parent, name):
self.buffer = buffers.mastodon.userPanel(parent, name)
def get_message(self):
user = self.get_item()
if user == None:
return
template = self.session.settings["templates"]["person"]
t = templates.render_user(user=user, template=template, relative_times=self.session.settings["general"]["relative_times"], offset_hours=self.session.db["utc_offset"])
return t
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.toot)
widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.send_message, self.buffer.message)
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 reply(self, *args, **kwargs):
return self.send_message()
def send_message(self, *args, **kwargs):
item = self.get_item()
title = _("New conversation with {}").format(item.username)
caption = _("Write your message here")
users_str = "@{} ".format(item.acct)
toot = messages.toot(session=self.session, title=title, caption=caption, text=users_str)
toot.message.visibility.SetSelection(3)
response = toot.message.ShowModal()
if response == wx.ID_OK:
toot_data = toot.get_data()
call_threaded(self.session.send_toot, toots=toot_data, visibility="direct")
if hasattr(toot.message, "destroy"):
toot.message.destroy()
def audio(self):
pass
def url(self):
pass
def destroy_status(self):
pass
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 >= 180 or mandatory==True:
self.execution_time = current_time
log.debug("Starting stream for buffer %s, account %s and type %s" % (self.name, self.account, self.type))
log.debug("args: %s, kwargs: %s" % (self.args, self.kwargs))
count = self.session.settings["general"]["max_toots_per_call"]
# toDo: Implement reverse timelines properly here.
try:
results = getattr(self.session.api, self.function)(limit=count, *self.args, **self.kwargs)
if hasattr(results, "_pagination_next") and self.name not in self.session.db["pagination_info"]:
self.session.db["pagination_info"][self.name] = results._pagination_next
results.reverse()
except Exception as e:
log.exception("Error %s" % (str(e)))
return
number_of_items = self.session.order_buffer(self.name, results)
log.debug("Number of items retrieved: %d" % (number_of_items,))
self.put_items_on_list(number_of_items)
if number_of_items > 0 and self.name != "sent_toots" and self.name != "sent_direct_messages" and self.sound != None and self.session.settings["sound"]["session_mute"] == False and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and play_sound == True:
self.session.sound.play(self.sound)
# Autoread settings
if avoid_autoreading == False and mandatory == True and number_of_items > 0 and self.name in self.session.settings["other_buffers"]["autoread_buffers"]:
self.auto_read(number_of_items)
return number_of_items
def get_more_items(self):
elements = []
pagination_info = self.session.db["pagination_info"].get(self.name)
if pagination_info == None:
output.speak(_("There are no more items in this buffer."))
return
try:
items = self.session.api.fetch_next(pagination_info)
if hasattr(items, "_pagination_next"):
self.session.db["pagination_info"][self.name] = items._pagination_next
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 get_item_url(self):
item = self.get_item()
return item.url
def user_details(self):
item = self.get_item()
pass
def add_to_favorites(self):
pass
def remove_from_favorites(self):
pass
def toggle_favorite(self):
pass
def view_item(self):
item = self.get_item()
print(item)
def ocr_image(self):
pass

View File

@ -28,24 +28,18 @@ class Handler(object):
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")) 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':
# pub.sendMessage("createBuffer", buffer_type="DirectMessagesBuffer", session_type=session.type, buffer_title=_("Direct messages"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, function="get_direct_messages", name="direct_messages", sessionObject=session, account=session.db["user_name"], bufferType="dmPanel", compose_func="compose_direct_message", sound="dm_received.ogg"))
# elif i == 'sent_dm':
# pub.sendMessage("createBuffer", buffer_type="SentDirectMessagesBuffer", session_type=session.type, buffer_title=_("Sent direct messages"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, function=None, name="sent_direct_messages", sessionObject=session, account=session.db["user_name"], bufferType="dmPanel", compose_func="compose_direct_message"))
# elif i == 'sent_tweets':
# pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Sent tweets"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, function="user_timeline", name="sent_tweets", sessionObject=session, account=session.db["user_name"], screen_name=session.db["user_name"], include_ext_alt_text=True, tweet_mode="extended"))
elif i == 'favorites': elif i == 'favorites':
pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Favorites"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, function="favourites", name="favorites", sessionObject=session, account=session.db["user_name"], sound="favourite.ogg")) pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Favorites"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, function="favourites", name="favorites", sessionObject=session, account=session.db["user_name"], sound="favourite.ogg"))
elif i == 'bookmarks': elif i == 'bookmarks':
pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Bookmarks"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, function="bookmarks", name="bookmarks", sessionObject=session, account=session.db["user_name"], sound="favourite.ogg")) pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Bookmarks"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, function="bookmarks", name="bookmarks", sessionObject=session, account=session.db["user_name"], sound="favourite.ogg"))
# elif i == 'followers': elif i == 'followers':
# pub.sendMessage("createBuffer", buffer_type="PeopleBuffer", session_type=session.type, buffer_title=_("Followers"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, function="get_followers", name="followers", sessionObject=session, account=session.db["user_name"], sound="update_followers.ogg", screen_name=session.db["user_name"])) pub.sendMessage("createBuffer", buffer_type="UserBuffer", session_type=session.type, buffer_title=_("Followers"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, compose_func="compose_user", function="account_followers", name="followers", sessionObject=session, account=session.db["user_name"], sound="new_event.ogg", id=session.db["user_id"]))
# elif i == 'friends': elif i == 'following':
# pub.sendMessage("createBuffer", buffer_type="PeopleBuffer", session_type=session.type, buffer_title=_("Following"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, function="get_friends", name="friends", sessionObject=session, account=session.db["user_name"], screen_name=session.db["user_name"])) pub.sendMessage("createBuffer", buffer_type="UserBuffer", session_type=session.type, buffer_title=_("Following"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, compose_func="compose_user", function="account_following", name="following", sessionObject=session, account=session.db["user_name"], sound="new_event.ogg", id=session.db["user_id"]))
# elif i == 'blocks': elif i == 'muted':
# pub.sendMessage("createBuffer", buffer_type="PeopleBuffer", session_type=session.type, buffer_title=_("Blocked users"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, function="get_blocks", name="blocked", sessionObject=session, account=session.db["user_name"])) 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=session.db["user_name"]))
# elif i == 'muted': elif i == 'blocks':
# pub.sendMessage("createBuffer", buffer_type="PeopleBuffer", session_type=session.type, buffer_title=_("Muted users"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, function="get_mutes", name="muted", sessionObject=session, account=session.db["user_name"])) 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=session.db["user_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=session.db["user_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=session.db["user_name"]))
# timelines_position =controller.view.search("timelines", session.db["user_name"]) # timelines_position =controller.view.search("timelines", session.db["user_name"])
# for i in session.settings["other_buffers"]["timelines"]: # for i in session.settings["other_buffers"]["timelines"]:

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', 'direct_messages', 'sent', 'favorites', 'bookmarks', 'followers', 'friends', 'blocks', 'muted', 'notifications')) buffer_order = list(default=list('home', 'local', 'federated', 'mentions', 'direct_messages', 'sent', 'favorites', 'bookmarks', 'followers', 'following', 'blocks', 'muted', 'notifications'))
boost_mode = string(default="ask") boost_mode = string(default="ask")
[sound] [sound]

View File

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import arrow import arrow
import languageHandler
from . import utils, templates from . import utils, templates
def compose_toot(toot, db, relative_times, show_screen_names): def compose_toot(toot, db, relative_times, show_screen_names):
@ -11,9 +12,9 @@ def compose_toot(toot, db, relative_times, show_screen_names):
user = toot.account.get("acct") user = toot.account.get("acct")
original_date = arrow.get(toot.created_at) original_date = arrow.get(toot.created_at)
if relative_times: if relative_times:
ts = original_date.humanize(locale="es") ts = original_date.humanize(locale=languageHandler.curLang[:2])
else: else:
ts = original_date.shift(hours=db["utc_offset"]).format(_("dddd, MMMM D, YYYY H:m:s"), locale="es") ts = original_date.shift(hours=db["utc_offset"]).format(_("dddd, MMMM D, YYYY H:m"), locale=languageHandler.curLang[:2])
if toot.reblog != None: if toot.reblog != None:
text = _("Boosted from @{}: {}").format(toot.reblog.account.acct, templates.process_text(toot.reblog)) text = _("Boosted from @{}: {}").format(toot.reblog.account.acct, templates.process_text(toot.reblog))
else: else:
@ -26,12 +27,12 @@ def compose_toot(toot, db, relative_times, show_screen_names):
source = "" source = ""
return [user+", ", text, ts+", ", source] return [user+", ", text, ts+", ", source]
def compose_user(user, db, relative_times=True): def compose_user(user, db, relative_times=True, show_screen_names=False):
original_date = arrow.get(user.created_at) original_date = arrow.get(user.created_at)
if relative_times: if relative_times:
ts = original_date.humanize(locale="es") ts = original_date.humanize(locale=languageHandler.curLang[:2])
else: else:
ts = original_date.shift(hours=db["utc_offset"]).format(_("dddd, MMMM D, YYYY H:m:s"), locale="es") ts = original_date.shift(hours=db["utc_offset"]).format(_("dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.curLang[:2])
name = user.display_name name = user.display_name
if name == "": if name == "":
name = user.get("username") name = user.get("username")

View File

@ -25,6 +25,7 @@ class Session(base.baseSession):
self.config_spec = "mastodon.defaults" self.config_spec = "mastodon.defaults"
self.supported_languages = [] self.supported_languages = []
self.type = "mastodon" self.type = "mastodon"
self.db["pagination_info"] = dict()
def login(self, verify_credentials=True): def login(self, verify_credentials=True):
if self.settings["mastodon"]["access_token"] != None and self.settings["mastodon"]["instance"] != None: if self.settings["mastodon"]["access_token"] != None and self.settings["mastodon"]["instance"] != None:

View File

@ -95,24 +95,22 @@ def render_toot(toot, template, relative_times=False, offset_hours=0):
result = remove_unneeded_variables(result, toot_variables) result = remove_unneeded_variables(result, toot_variables)
return result return result
def render_person(user, template, relative_times=True, offset_hours=0): def render_user(user, template, relative_times=True, offset_hours=0):
""" Renders persons by using the provided template. """ Renders persons by using the provided template.
Available data will be stored in the following variables: Available data will be stored in the following variables:
$display_name: The name of the user, as theyve defined it. Not necessarily a persons name. Typically capped at 50 characters, but subject to change. $display_name: The name of the user, as theyve defined it. Not necessarily a persons name. Typically capped at 50 characters, but subject to change.
$screen_name: The screen name, handle, or alias that this user identifies themselves with. $screen_name: The screen name, handle, or alias that this user identifies themselves with.
$location: The user-defined location for this accounts profile. Not necessarily a location, nor machine-parseable.
$description: The user-defined UTF-8 string describing their account. $description: The user-defined UTF-8 string describing their account.
$followers: The number of followers this account currently has. This value might be inaccurate. $followers: The number of followers this account currently has. This value might be inaccurate.
$following: The number of users this account is following (AKA their followings). This value might be inaccurate. $following: The number of users this account is following (AKA their followings). This value might be inaccurate.
$favorites: The number of Tweets this user has liked in the accounts lifetime. This value might be inaccurate. $toots: The number of Tweets (including retweets) issued by the user. This value might be inaccurate.
$tweets: The number of Tweets (including retweets) issued by the user. This value might be inaccurate.
$created_at: The date and time that the user account was created on Twitter. $created_at: The date and time that the user account was created on Twitter.
""" """
global person_variables global person_variables
display_name = user.display_name display_name = user.display_name
if display_name == "": if display_name == "":
display_name = user.username display_name = user.username
available_data = dict(display_name=display_name, screen_name=user.acct, followers=user.followers_count, following=user.following_count, favorites=user.favourites_count, toots=user.statuses_count) available_data = dict(display_name=display_name, screen_name=user.acct, followers=user.followers_count, following=user.following_count, toots=user.statuses_count)
# Nullable values. # Nullable values.
nullables = ["description"] nullables = ["description"]
for nullable in nullables: for nullable in nullables:

View File

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

View File

@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
import wx
from multiplatform_widgets import widgets
class userPanel(wx.Panel):
def create_list(self):
self.list = widgets.list(self, _("User"), style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_VRULES)
self.list.set_windows_size(0, 320)
self.list.set_size()
def __init__(self, parent, name):
super(userPanel, self).__init__(parent)
self.name = name
self.type = "baseBuffer"
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.create_list()
self.toot = wx.Button(self, -1, _("Toot"))
self.actions = wx.Button(self, -1, _("Actions"))
self.message = wx.Button(self, -1, _("Message"))
btnSizer = wx.BoxSizer(wx.HORIZONTAL)
btnSizer.Add(self.toot, 0, wx.ALL, 5)
btnSizer.Add(self.actions, 0, wx.ALL, 5)
btnSizer.Add(self.message, 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()