Mastodon: Started implementation of read preferences from instance. Currently only content warnings are displayed by taking into accounts values from instance preferences

This commit is contained in:
Manuel Cortez 2022-12-23 13:58:10 -06:00
parent 460cea702b
commit 18a7a42b5a
No known key found for this signature in database
GPG Key ID: 9E0735CA15EFE790
10 changed files with 90 additions and 28 deletions

View File

@ -11,6 +11,7 @@ TWBlue Changelog
* Fixed an issue that was preventing TWBlue to create more than one user timeline during startup. * Fixed an issue that was preventing TWBlue to create more than one user timeline during startup.
* TWBlue will display properly new paragraphs in mastodon posts. * TWBlue will display properly new paragraphs in mastodon posts.
* In the session manager, Mastodon sessions are now displayed including the instance to avoid confusion. * In the session manager, Mastodon sessions are now displayed including the instance to avoid confusion.
* TWBlue will now read default visibility preferences when posting new statuses, and display sensitive content. These preferences can be set on the mastodon instance, in the account's preferences section. If you wish to change TWBlue's behavior and have it not read those preferences from your instance, but instead set the default public visibility and hide sensitive content, you can uncheck the Read preferences from instance checkbox in the account options.
## Changes in version 2022.12.13 ## Changes in version 2022.12.13

View File

@ -9,6 +9,7 @@ import config
import sound import sound
import languageHandler import languageHandler
import logging import logging
from mastodon import MastodonNotFoundError
from audio_services import youtube_utils from audio_services import youtube_utils
from controller.buffers.base import base from controller.buffers.base import base
from controller.mastodon import messages from controller.mastodon import messages
@ -72,14 +73,22 @@ class BaseBuffer(base.Buffer):
post.message.destroy() post.message.destroy()
def get_formatted_message(self): def get_formatted_message(self):
return self.compose_function(self.get_item(), self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"])[1] safe = True
if self.session.settings["general"]["read_preferences_from_instance"]:
safe = self.session.expand_spoilers == False
return self.compose_function(self.get_item(), self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], safe=safe)[1]
def get_message(self): def get_message(self):
post = self.get_item() post = self.get_item()
if post == None: if post == None:
return return
template = self.session.settings["templates"]["post"] template = self.session.settings["templates"]["post"]
# If template is set to hide sensitive media by default, let's change it according to user preferences.
if self.session.settings["general"]["read_preferences_from_instance"] == True:
if self.session.expand_spoilers == True and "$safe_text" in template:
template = template.replace("$safe_text", "$text")
elif self.session.expand_spoilers == False and "$text" in template:
template = template.replace("$text", "$safe_text")
t = templates.render_post(post, template, relative_times=self.session.settings["general"]["relative_times"], offset_hours=self.session.db["utc_offset"]) t = templates.render_post(post, template, relative_times=self.session.settings["general"]["relative_times"], offset_hours=self.session.db["utc_offset"])
return t return t
@ -124,7 +133,10 @@ class BaseBuffer(base.Buffer):
else: else:
post = self.session.db[self.name][0] post = self.session.db[self.name][0]
output.speak(_("New post in {0}").format(self.get_buffer_name())) output.speak(_("New post in {0}").format(self.get_buffer_name()))
output.speak(" ".join(self.compose_function(post, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"]))) safe = True
if self.session.settings["general"]["read_preferences_from_instance"]:
safe = self.session.expand_spoilers == False
output.speak(" ".join(self.compose_function(post, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], safe=safe)))
elif number_of_items > 1 and self.name in self.session.settings["other_buffers"]["autoread_buffers"] and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and self.session.settings["sound"]["session_mute"] == False: elif number_of_items > 1 and self.name in self.session.settings["other_buffers"]["autoread_buffers"] and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and self.session.settings["sound"]["session_mute"] == False:
output.speak(_("{0} new posts in {1}.").format(number_of_items, self.get_buffer_name())) output.speak(_("{0} new posts in {1}.").format(number_of_items, self.get_buffer_name()))
@ -150,13 +162,16 @@ class BaseBuffer(base.Buffer):
self.session.db[self.name] = items_db self.session.db[self.name] = items_db
selection = self.buffer.list.get_selected() selection = self.buffer.list.get_selected()
log.debug("Retrieved %d items from cursored search in function %s." % (len(elements), self.function)) log.debug("Retrieved %d items from cursored search in function %s." % (len(elements), self.function))
safe = True
if self.session.settings["general"]["read_preferences_from_instance"]:
safe = self.session.expand_spoilers == False
if self.session.settings["general"]["reverse_timelines"] == False: if self.session.settings["general"]["reverse_timelines"] == False:
for i in elements: for i in elements:
post = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"]) post = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], safe=safe)
self.buffer.list.insert_item(True, *post) self.buffer.list.insert_item(True, *post)
else: else:
for i in elements: for i in elements:
post = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"]) post = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], safe=safe)
self.buffer.list.insert_item(False, *post) self.buffer.list.insert_item(False, *post)
self.buffer.list.select_item(selection) self.buffer.list.select_item(selection)
output.speak(_(u"%s items retrieved") % (str(len(elements))), True) output.speak(_(u"%s items retrieved") % (str(len(elements))), True)
@ -185,27 +200,33 @@ class BaseBuffer(base.Buffer):
if number_of_items == 0 and self.session.settings["general"]["persist_size"] == 0: return if number_of_items == 0 and self.session.settings["general"]["persist_size"] == 0: return
log.debug("The list contains %d items " % (self.buffer.list.get_count(),)) log.debug("The list contains %d items " % (self.buffer.list.get_count(),))
log.debug("Putting %d items on the list" % (number_of_items,)) log.debug("Putting %d items on the list" % (number_of_items,))
safe = True
if self.session.settings["general"]["read_preferences_from_instance"]:
safe = self.session.expand_spoilers == False
if self.buffer.list.get_count() == 0: if self.buffer.list.get_count() == 0:
for i in list_to_use: for i in list_to_use:
post = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"]) post = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], safe=safe)
self.buffer.list.insert_item(False, *post) self.buffer.list.insert_item(False, *post)
self.buffer.set_position(self.session.settings["general"]["reverse_timelines"]) self.buffer.set_position(self.session.settings["general"]["reverse_timelines"])
elif self.buffer.list.get_count() > 0 and number_of_items > 0: elif self.buffer.list.get_count() > 0 and number_of_items > 0:
if self.session.settings["general"]["reverse_timelines"] == False: if self.session.settings["general"]["reverse_timelines"] == False:
items = list_to_use[len(list_to_use)-number_of_items:] items = list_to_use[len(list_to_use)-number_of_items:]
for i in items: for i in items:
post = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"]) post = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], safe=safe)
self.buffer.list.insert_item(False, *post) self.buffer.list.insert_item(False, *post)
else: else:
items = list_to_use[0:number_of_items] items = list_to_use[0:number_of_items]
items.reverse() items.reverse()
for i in items: for i in items:
post = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"]) post = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], safe=safe)
self.buffer.list.insert_item(True, *post) self.buffer.list.insert_item(True, *post)
log.debug("Now the list contains %d items " % (self.buffer.list.get_count(),)) log.debug("Now the list contains %d items " % (self.buffer.list.get_count(),))
def add_new_item(self, item): def add_new_item(self, item):
post = self.compose_function(item, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"]) safe = True
if self.session.settings["general"]["read_preferences_from_instance"]:
safe = self.session.expand_spoilers == False
post = self.compose_function(item, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], safe=safe)
if self.session.settings["general"]["reverse_timelines"] == False: if self.session.settings["general"]["reverse_timelines"] == False:
self.buffer.list.insert_item(False, *post) self.buffer.list.insert_item(False, *post)
else: else:
@ -214,7 +235,10 @@ class BaseBuffer(base.Buffer):
output.speak(" ".join(post[:2]), speech=self.session.settings["reporting"]["speech_reporting"], braille=self.session.settings["reporting"]["braille_reporting"]) output.speak(" ".join(post[:2]), speech=self.session.settings["reporting"]["speech_reporting"], braille=self.session.settings["reporting"]["braille_reporting"])
def update_item(self, item, position): def update_item(self, item, position):
post = self.compose_function(item, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"]) safe = True
if self.session.settings["general"]["read_preferences_from_instance"]:
safe = self.session.expand_spoilers == False
post = self.compose_function(item, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], safe=safe)
self.buffer.list.list.SetItem(position, 1, post[1]) self.buffer.list.list.SetItem(position, 1, post[1])
def bind_events(self): def bind_events(self):
@ -439,6 +463,7 @@ class BaseBuffer(base.Buffer):
self.buffer.list.remove_item(index) self.buffer.list.remove_item(index)
except Exception as e: except Exception as e:
self.session.sound.play("error.ogg") self.session.sound.play("error.ogg")
log.exception("")
self.session.db[self.name] = items self.session.db[self.name] = items
def user_details(self): def user_details(self):
@ -472,7 +497,11 @@ class BaseBuffer(base.Buffer):
item = self.get_item() item = self.get_item()
if item.reblog != None: if item.reblog != None:
item = item.reblog item = item.reblog
item = self.session.api.status(item.id) try:
item = self.session.api.status(item.id)
except MastodonNotFoundError:
output.speak(_("No status found with that ID"))
return
if item.favourited == False: if item.favourited == False:
call_threaded(self.session.api_call, call_name="status_favourite", preexec_message=_("Adding to favorites..."), _sound="favourite.ogg", id=item.id) call_threaded(self.session.api_call, call_name="status_favourite", preexec_message=_("Adding to favorites..."), _sound="favourite.ogg", id=item.id)
else: else:
@ -482,7 +511,11 @@ class BaseBuffer(base.Buffer):
item = self.get_item() item = self.get_item()
if item.reblog != None: if item.reblog != None:
item = item.reblog item = item.reblog
item = self.session.api.status(item.id) try:
item = self.session.api.status(item.id)
except MastodonNotFoundError:
output.speak(_("No status found with that ID"))
return
if item.bookmarked == False: if item.bookmarked == False:
call_threaded(self.session.api_call, call_name="status_bookmark", preexec_message=_("Adding to bookmarks..."), _sound="favourite.ogg", id=item.id) call_threaded(self.session.api_call, call_name="status_bookmark", preexec_message=_("Adding to bookmarks..."), _sound="favourite.ogg", id=item.id)
else: else:
@ -491,7 +524,11 @@ class BaseBuffer(base.Buffer):
def view_item(self): def view_item(self):
post = self.get_item() post = self.get_item()
# Update object so we can retrieve newer stats # Update object so we can retrieve newer stats
post = self.session.api.status(id=post.id) try:
post = self.session.api.status(id=post.id)
except MastodonNotFoundError:
output.speak(_("No status found with that ID"))
return
# print(post) # print(post)
msg = messages.viewPost(post, offset_hours=self.session.db["utc_offset"], item_url=self.get_item_url()) msg = messages.viewPost(post, offset_hours=self.session.db["utc_offset"], item_url=self.get_item_url())

View File

@ -4,6 +4,7 @@ import logging
import wx import wx
import widgetUtils import widgetUtils
import output import output
from mastodon import MastodonNotFoundError
from controller.mastodon import messages from controller.mastodon import messages
from controller.buffers.mastodon.base import BaseBuffer from controller.buffers.mastodon.base import BaseBuffer
from mysc.thread_utils import call_threaded from mysc.thread_utils import call_threaded
@ -200,7 +201,11 @@ class ConversationBuffer(BaseBuffer):
self.execution_time = current_time 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("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)) log.debug("args: %s, kwargs: %s" % (self.args, self.kwargs))
self.post = self.session.api.status(id=self.post.id) try:
self.post = self.session.api.status(id=self.post.id)
except MastodonNotFoundError:
output.speak(_("No status found with that ID"))
return
# toDo: Implement reverse timelines properly here. # toDo: Implement reverse timelines properly here.
try: try:
results = [] results = []

View File

@ -56,13 +56,16 @@ class MentionsBuffer(BaseBuffer):
self.session.db[self.name] = items_db self.session.db[self.name] = items_db
selection = self.buffer.list.get_selected() selection = self.buffer.list.get_selected()
log.debug("Retrieved %d items from cursored search in function %s." % (len(elements), self.function)) log.debug("Retrieved %d items from cursored search in function %s." % (len(elements), self.function))
safe = True
if self.session.settings["general"]["read_preferences_from_instance"]:
safe = self.session.expand_spoilers == False
if self.session.settings["general"]["reverse_timelines"] == False: if self.session.settings["general"]["reverse_timelines"] == False:
for i in elements: for i in elements:
post = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"]) post = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], safe=safe)
self.buffer.list.insert_item(True, *post) self.buffer.list.insert_item(True, *post)
else: else:
for i in elements: for i in elements:
post = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"]) post = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], safe=safe)
self.buffer.list.insert_item(False, *post) self.buffer.list.insert_item(False, *post)
self.buffer.list.select_item(selection) self.buffer.list.select_item(selection)
output.speak(_(u"%s items retrieved") % (str(len(elements))), True) output.speak(_(u"%s items retrieved") % (str(len(elements))), True)

View File

@ -185,6 +185,11 @@ class post(messages.basicTweet):
visibility_settings = ["public", "unlisted", "private", "direct"] visibility_settings = ["public", "unlisted", "private", "direct"]
return visibility_settings[self.message.visibility.GetSelection()] return visibility_settings[self.message.visibility.GetSelection()]
def set_visibility(self, setting):
visibility_settings = ["public", "unlisted", "private", "direct"]
visibility_setting = visibility_settings.index(setting)
self.message.visibility.SetSelection(setting)
class viewPost(post): class viewPost(post):
def __init__(self, post, offset_hours=0, date="", item_url=""): def __init__(self, post, offset_hours=0, date="", item_url=""):
if post.reblog != None: if post.reblog != None:

View File

@ -32,6 +32,7 @@ class accountSettingsController(globalSettingsController):
# widgetUtils.connect_event(self.dialog.general.userAutocompletionScan, widgetUtils.BUTTON_PRESSED, self.on_autocompletion_scan) # widgetUtils.connect_event(self.dialog.general.userAutocompletionScan, widgetUtils.BUTTON_PRESSED, self.on_autocompletion_scan)
# widgetUtils.connect_event(self.dialog.general.userAutocompletionManage, widgetUtils.BUTTON_PRESSED, self.on_autocompletion_manage) # widgetUtils.connect_event(self.dialog.general.userAutocompletionManage, widgetUtils.BUTTON_PRESSED, self.on_autocompletion_manage)
self.dialog.set_value("general", "relative_time", self.config["general"]["relative_times"]) self.dialog.set_value("general", "relative_time", self.config["general"]["relative_times"])
self.dialog.set_value("general", "read_preferences_from_instance", self.config["general"]["read_preferences_from_instance"])
self.dialog.set_value("general", "show_screen_names", self.config["general"]["show_screen_names"]) self.dialog.set_value("general", "show_screen_names", self.config["general"]["show_screen_names"])
self.dialog.set_value("general", "hide_emojis", self.config["general"]["hide_emojis"]) self.dialog.set_value("general", "hide_emojis", self.config["general"]["hide_emojis"])
self.dialog.set_value("general", "itemsPerApiCall", self.config["general"]["max_posts_per_call"]) self.dialog.set_value("general", "itemsPerApiCall", self.config["general"]["max_posts_per_call"])
@ -111,6 +112,7 @@ class accountSettingsController(globalSettingsController):
self.needs_restart = True self.needs_restart = True
log.debug("Triggered app restart due to change in relative times.") log.debug("Triggered app restart due to change in relative times.")
self.config["general"]["relative_times"] = self.dialog.get_value("general", "relative_time") self.config["general"]["relative_times"] = self.dialog.get_value("general", "relative_time")
self.config["general"]["read_preferences_from_instance"] = self.dialog.get_value("general", "read_preferences_from_instance")
self.config["general"]["show_screen_names"] = self.dialog.get_value("general", "show_screen_names") self.config["general"]["show_screen_names"] = self.dialog.get_value("general", "show_screen_names")
self.config["general"]["hide_emojis"] = self.dialog.get_value("general", "hide_emojis") self.config["general"]["hide_emojis"] = self.dialog.get_value("general", "hide_emojis")
self.config["general"]["max_posts_per_call"] = self.dialog.get_value("general", "itemsPerApiCall") self.config["general"]["max_posts_per_call"] = self.dialog.get_value("general", "itemsPerApiCall")

View File

@ -6,6 +6,7 @@ ignored_clients = list(default=list())
[general] [general]
relative_times = boolean(default=True) relative_times = boolean(default=True)
read_preferences_from_instance = boolean(default=True)
max_posts_per_call = integer(default=40) max_posts_per_call = integer(default=40)
reverse_timelines = boolean(default=False) reverse_timelines = boolean(default=False)
persist_size = integer(default=0) persist_size = integer(default=0)

View File

@ -3,7 +3,7 @@ import arrow
import languageHandler import languageHandler
from . import utils, templates from . import utils, templates
def compose_post(post, db, relative_times, show_screen_names): def compose_post(post, db, relative_times, show_screen_names, safe=True):
if show_screen_names == False: if show_screen_names == False:
user = post.account.get("display_name") user = post.account.get("display_name")
if user == "": if user == "":
@ -16,9 +16,9 @@ def compose_post(post, db, relative_times, show_screen_names):
else: else:
ts = original_date.shift(hours=db["utc_offset"]).format(_("dddd, MMMM D, YYYY H:m"), locale=languageHandler.curLang[:2]) ts = original_date.shift(hours=db["utc_offset"]).format(_("dddd, MMMM D, YYYY H:m"), locale=languageHandler.curLang[:2])
if post.reblog != None: if post.reblog != None:
text = _("Boosted from @{}: {}").format(post.reblog.account.acct, templates.process_text(post.reblog)) text = _("Boosted from @{}: {}").format(post.reblog.account.acct, templates.process_text(post.reblog, safe=safe))
else: else:
text = templates.process_text(post) text = templates.process_text(post, safe=safe)
source = post.get("application", "") source = post.get("application", "")
# "" means remote user, None for legacy apps so we should cover both sides. # "" means remote user, None for legacy apps so we should cover both sides.
if source != None and source != "": if source != None and source != "":
@ -27,7 +27,7 @@ def compose_post(post, 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, show_screen_names=False): def compose_user(user, db, relative_times=True, show_screen_names=False, safe=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=languageHandler.curLang[:2]) ts = original_date.humanize(locale=languageHandler.curLang[:2])
@ -38,7 +38,7 @@ def compose_user(user, db, relative_times=True, show_screen_names=False):
name = user.get("username") name = user.get("username")
return [_("%s (@%s). %s followers, %s following, %s posts. Joined %s") % (name, user.acct, user.followers_count, user.following_count, user.statuses_count, ts)] return [_("%s (@%s). %s followers, %s following, %s posts. 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): def compose_conversation(conversation, db, relative_times, show_screen_names, safe=False):
users = [] users = []
for account in conversation.accounts: for account in conversation.accounts:
if account.display_name != "": if account.display_name != "":
@ -50,7 +50,7 @@ def compose_conversation(conversation, db, relative_times, show_screen_names):
text = _("Last message from {}: {}").format(last_post[0], last_post[1]) text = _("Last message from {}: {}").format(last_post[0], last_post[1])
return [users, text, last_post[-2], last_post[-1]] return [users, text, last_post[-2], last_post[-1]]
def compose_notification(notification, db, relative_times, show_screen_names): def compose_notification(notification, db, relative_times, show_screen_names, safe=False):
if show_screen_names == False: if show_screen_names == False:
user = notification.account.get("display_name") user = notification.account.get("display_name")
if user == "": if user == "":
@ -64,15 +64,15 @@ def compose_notification(notification, db, relative_times, show_screen_names):
ts = original_date.shift(hours=db["utc_offset"]).format(_("dddd, MMMM D, YYYY H:m"), locale=languageHandler.curLang[:2]) ts = original_date.shift(hours=db["utc_offset"]).format(_("dddd, MMMM D, YYYY H:m"), locale=languageHandler.curLang[:2])
text = "Unknown: %r" % (notification) text = "Unknown: %r" % (notification)
if notification.type == "mention": if notification.type == "mention":
text = _("{username} has mentionned you: {status}").format(username=user, status=",".join(compose_post(notification.status, db, relative_times, show_screen_names))) text = _("{username} has mentionned you: {status}").format(username=user, status=",".join(compose_post(notification.status, db, relative_times, show_screen_names, safe=safe)))
elif notification.type == "reblog": elif notification.type == "reblog":
text = _("{username} has boosted: {status}").format(username=user, status=",".join(compose_post(notification.status, db, relative_times, show_screen_names))) text = _("{username} has boosted: {status}").format(username=user, status=",".join(compose_post(notification.status, db, relative_times, show_screen_names, safe=safe)))
elif notification.type == "favourite": elif notification.type == "favourite":
text = _("{username} has added to favorites: {status}").format(username=user, status=",".join(compose_post(notification.status, db, relative_times, show_screen_names))) text = _("{username} has added to favorites: {status}").format(username=user, status=",".join(compose_post(notification.status, db, relative_times, show_screen_names, safe=safe)))
elif notification.type == "follow": elif notification.type == "follow":
text = _("{username} has followed you.").format(username=user) text = _("{username} has followed you.").format(username=user)
elif notification.type == "poll": elif notification.type == "poll":
text = _("A poll in which you have voted has expired: {status}").format(status=",".join(compose_post(notification.status, db, relative_times, show_screen_names))) text = _("A poll in which you have voted has expired: {status}").format(status=",".join(compose_post(notification.status, db, relative_times, show_screen_names, safe=safe)))
elif notification.type == "follow_request": elif notification.type == "follow_request":
text = _("{username} wants to follow you.").format(username=user) text = _("{username} wants to follow you.").format(username=user)
return [user, text, ts] return [user, text, ts]

View File

@ -29,6 +29,8 @@ class Session(base.baseSession):
self.type = "mastodon" self.type = "mastodon"
self.db["pagination_info"] = dict() self.db["pagination_info"] = dict()
self.char_limit = 500 self.char_limit = 500
self.post_visibility = "public"
self.expand_spoilers = False
pub.subscribe(self.on_status, "mastodon.status_received") pub.subscribe(self.on_status, "mastodon.status_received")
pub.subscribe(self.on_status_updated, "mastodon.status_updated") pub.subscribe(self.on_status_updated, "mastodon.status_updated")
pub.subscribe(self.on_notification, "mastodon.notification_received") pub.subscribe(self.on_notification, "mastodon.notification_received")
@ -98,14 +100,18 @@ class Session(base.baseSession):
offset = time.timezone if (time.localtime().tm_isdst == 0) else time.altzone offset = time.timezone if (time.localtime().tm_isdst == 0) else time.altzone
offset = offset / 60 / 60 * -1 offset = offset / 60 / 60 * -1
self.db["utc_offset"] = offset self.db["utc_offset"] = offset
instance = self.api.instance()
if len(self.supported_languages) == 0: if len(self.supported_languages) == 0:
self.supported_languages = self.api.instance().languages self.supported_languages = instance.languages
self.get_lists() self.get_lists()
self.get_muted_users() self.get_muted_users()
# determine instance custom characters limit. # determine instance custom characters limit.
instance = self.api.instance()
if hasattr(instance, "configuration") and hasattr(instance.configuration, "statuses") and hasattr(instance.configuration.statuses, "max_characters"): if hasattr(instance, "configuration") and hasattr(instance.configuration, "statuses") and hasattr(instance.configuration.statuses, "max_characters"):
self.char_limit = instance.configuration.statuses.max_characters self.char_limit = instance.configuration.statuses.max_characters
# User preferences for some things.
preferences = self.api.preferences()
self.post_visibility = preferences.get("posting:default:visibility")
self.expand_spoilers = preferences.get("reading:expand:spoilers")
self.settings.write() self.settings.write()
def get_lists(self): def get_lists(self):

View File

@ -22,6 +22,8 @@ class generalAccount(wx.Panel, baseDialog.BaseWXDialog):
sizer.Add(autocompletionSizer, 0, wx.ALL, 5) sizer.Add(autocompletionSizer, 0, wx.ALL, 5)
self.relative_time = wx.CheckBox(self, wx.ID_ANY, _("Relative timestamps")) self.relative_time = wx.CheckBox(self, wx.ID_ANY, _("Relative timestamps"))
sizer.Add(self.relative_time, 0, wx.ALL, 5) sizer.Add(self.relative_time, 0, wx.ALL, 5)
self.read_preferences_from_instance = wx.CheckBox(self, wx.ID_ANY, _("Read preferences from instance (default visibility when publishing and displaying sensitive content)"))
sizer.Add(self.read_preferences_from_instance, 0, wx.ALL, 5)
itemsPerCallBox = wx.BoxSizer(wx.HORIZONTAL) itemsPerCallBox = wx.BoxSizer(wx.HORIZONTAL)
itemsPerCallBox.Add(wx.StaticText(self, -1, _("Items on each API call")), 0, wx.ALL, 5) itemsPerCallBox.Add(wx.StaticText(self, -1, _("Items on each API call")), 0, wx.ALL, 5)
self.itemsPerApiCall = wx.SpinCtrl(self, wx.ID_ANY) self.itemsPerApiCall = wx.SpinCtrl(self, wx.ID_ANY)