mirror of
https://github.com/MCV-Software/TWBlue.git
synced 2024-11-26 12:53:12 -06:00
Merge branch 'next-gen' of github.com:mcv-software/twblue into next-gen
This commit is contained in:
commit
8940825509
@ -7,6 +7,7 @@ We had to release a 2023.2.8 version of TWblue, which removes the API deprecatio
|
|||||||
* TWBlue should be able to display variables within templates (for example, now it is possible to send a template inside a post's text). Before, it was removing $variables so it was difficult to show how to edit templates from the client. ([#515](https://github.com/MCV-Software/TWBlue/issues/515))
|
* TWBlue should be able to display variables within templates (for example, now it is possible to send a template inside a post's text). Before, it was removing $variables so it was difficult to show how to edit templates from the client. ([#515](https://github.com/MCV-Software/TWBlue/issues/515))
|
||||||
* Mastodon:
|
* Mastodon:
|
||||||
* it is possible to add descriptions for all media available on Mastodon (audio, photos, video and Givs). ([#516](https://github.com/MCV-Software/TWBlue/issues/516))
|
* it is possible to add descriptions for all media available on Mastodon (audio, photos, video and Givs). ([#516](https://github.com/MCV-Software/TWBlue/issues/516))
|
||||||
|
* Fixed an error on mentions buffer that was making TWBlue unable to load posts if there were mentions from a blocked or deleted account.
|
||||||
|
|
||||||
## Changes on version 2023.2.6
|
## Changes on version 2023.2.6
|
||||||
|
|
||||||
|
@ -565,3 +565,15 @@ class BaseBuffer(base.Buffer):
|
|||||||
if answer != wx.ID_OK:
|
if answer != wx.ID_OK:
|
||||||
return
|
return
|
||||||
poll = self.session.api_call(call_name="poll_vote", id=poll.id, choices=options, preexec_message=_("Sending vote..."))
|
poll = self.session.api_call(call_name="poll_vote", id=poll.id, choices=options, preexec_message=_("Sending vote..."))
|
||||||
|
|
||||||
|
def post_from_error(self, visibility, data):
|
||||||
|
title = _("Post")
|
||||||
|
caption = _("Write your post here")
|
||||||
|
post = messages.post(session=self.session, title=title, caption=caption)
|
||||||
|
post.set_post_data(visibility=visibility, data=data)
|
||||||
|
response = post.message.ShowModal()
|
||||||
|
if response == wx.ID_OK:
|
||||||
|
post_data = post.get_data()
|
||||||
|
call_threaded(self.session.send_post, posts=post_data, visibility=post.get_visibility())
|
||||||
|
if hasattr(post.message, "destroy"):
|
||||||
|
post.message.destroy()
|
||||||
|
@ -28,6 +28,8 @@ class MentionsBuffer(BaseBuffer):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.exception("Error %s" % (str(e)))
|
log.exception("Error %s" % (str(e)))
|
||||||
return
|
return
|
||||||
|
# Attempt to remove items with no statuses attached to them as it might happen when blocked accounts have notifications.
|
||||||
|
items = [item for item in items if item.status != None]
|
||||||
number_of_items = self.session.order_buffer(self.name, items)
|
number_of_items = self.session.order_buffer(self.name, items)
|
||||||
log.debug("Number of items retrieved: %d" % (number_of_items,))
|
log.debug("Number of items retrieved: %d" % (number_of_items,))
|
||||||
self.put_items_on_list(number_of_items)
|
self.put_items_on_list(number_of_items)
|
||||||
@ -49,7 +51,8 @@ class MentionsBuffer(BaseBuffer):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.exception("Error %s" % (str(e)))
|
log.exception("Error %s" % (str(e)))
|
||||||
return
|
return
|
||||||
print(items)
|
# Attempt to remove items with no statuses attached to them as it might happen when blocked accounts have notifications.
|
||||||
|
items = [item for item in items if item.status != None]
|
||||||
items_db = self.session.db[self.name]
|
items_db = self.session.db[self.name]
|
||||||
for i in items:
|
for i in items:
|
||||||
if utils.find_item(i, self.session.db[self.name]) == None:
|
if utils.find_item(i, self.session.db[self.name]) == None:
|
||||||
|
@ -130,7 +130,7 @@ class Controller(object):
|
|||||||
pub.subscribe(self.mastodon_new_item, "mastodon.new_item")
|
pub.subscribe(self.mastodon_new_item, "mastodon.new_item")
|
||||||
pub.subscribe(self.mastodon_updated_item, "mastodon.updated_item")
|
pub.subscribe(self.mastodon_updated_item, "mastodon.updated_item")
|
||||||
pub.subscribe(self.mastodon_new_conversation, "mastodon.conversation_received")
|
pub.subscribe(self.mastodon_new_conversation, "mastodon.conversation_received")
|
||||||
|
pub.subscribe(self.mastodon_error_post, "mastodon.error_post")
|
||||||
# connect application events to GUI
|
# connect application events to GUI
|
||||||
widgetUtils.connect_event(self.view, widgetUtils.CLOSE_EVENT, self.exit_)
|
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.show_hide, menuitem=self.view.show_hide)
|
||||||
@ -1306,6 +1306,10 @@ class Controller(object):
|
|||||||
# if "direct_messages" not in buffer.session.settings["other_buffers"]["muted_buffers"]:
|
# if "direct_messages" not in buffer.session.settings["other_buffers"]["muted_buffers"]:
|
||||||
# self.notify(buffer.session, sound_to_play)
|
# self.notify(buffer.session, sound_to_play)
|
||||||
|
|
||||||
|
def mastodon_error_post(self, name, reply_to, visibility, posts):
|
||||||
|
home = self.search_buffer("home_timeline", name)
|
||||||
|
wx.CallAfter(home.post_from_error, visibility=visibility, data=posts)
|
||||||
|
|
||||||
def report_error(self, *args, **kwargs):
|
def report_error(self, *args, **kwargs):
|
||||||
"""Redirects the user to the issue page on github"""
|
"""Redirects the user to the issue page on github"""
|
||||||
log.debug("Redirecting the user to report an error...")
|
log.debug("Redirecting the user to report an error...")
|
||||||
|
@ -64,6 +64,23 @@ class post(messages.basicTweet):
|
|||||||
self.add_post(event=None, update_gui=False)
|
self.add_post(event=None, update_gui=False)
|
||||||
return self.thread
|
return self.thread
|
||||||
|
|
||||||
|
def set_post_data(self, visibility, data):
|
||||||
|
if len(data) == 0:
|
||||||
|
return
|
||||||
|
if len(data) > 1:
|
||||||
|
self.thread = data[:-1]
|
||||||
|
for p in self.thread:
|
||||||
|
self.message.add_item(item=[p.get("text") or "", len(p.get("attachments") or [])], list_type="post")
|
||||||
|
post = data[-1]
|
||||||
|
self.attachments = post.get("attachments") or []
|
||||||
|
self.message.text.SetValue(post.get("text") or "")
|
||||||
|
self.message.sensitive.SetValue(post.get("sensitive") or False)
|
||||||
|
self.message.spoiler.SetValue(post.get("spoiler_text") or "")
|
||||||
|
visibility_settings = dict(public=0, unlisted=1, private=2, direct=3)
|
||||||
|
self.message.visibility.SetSelection(visibility_settings.get(visibility))
|
||||||
|
self.message.on_sensitivity_changed()
|
||||||
|
self.text_processor()
|
||||||
|
|
||||||
def text_processor(self, *args, **kwargs):
|
def text_processor(self, *args, **kwargs):
|
||||||
text = self.message.text.GetValue()
|
text = self.message.text.GetValue()
|
||||||
cw = self.message.spoiler.GetValue()
|
cw = self.message.spoiler.GetValue()
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -66,7 +66,7 @@ def compose_notification(notification, db, relative_times, show_screen_names, sa
|
|||||||
if notification.type == "status":
|
if notification.type == "status":
|
||||||
text = _("{username} has posted: {status}").format(username=user, status=",".join(compose_post(notification.status, db, relative_times, show_screen_names, safe=safe)))
|
text = _("{username} has posted: {status}").format(username=user, status=",".join(compose_post(notification.status, db, relative_times, show_screen_names, safe=safe)))
|
||||||
elif notification.type == "mention":
|
elif notification.type == "mention":
|
||||||
text = _("{username} has mentionned you: {status}").format(username=user, status=",".join(compose_post(notification.status, db, relative_times, show_screen_names, safe=safe)))
|
text = _("{username} has mentioned 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, safe=safe)))
|
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":
|
||||||
|
@ -6,6 +6,7 @@ import logging
|
|||||||
import webbrowser
|
import webbrowser
|
||||||
import wx
|
import wx
|
||||||
import mastodon
|
import mastodon
|
||||||
|
import demoji
|
||||||
import config
|
import config
|
||||||
import config_utils
|
import config_utils
|
||||||
import output
|
import output
|
||||||
@ -123,14 +124,23 @@ class Session(base.baseSession):
|
|||||||
self.db["muted_users"] = self.api.mutes()
|
self.db["muted_users"] = self.api.mutes()
|
||||||
|
|
||||||
def get_user_alias(self, user):
|
def get_user_alias(self, user):
|
||||||
|
if user.display_name == None or user.display_name == "":
|
||||||
|
display_name = user.username
|
||||||
|
else:
|
||||||
|
display_name = user.display_name
|
||||||
aliases = self.settings.get("user-aliases")
|
aliases = self.settings.get("user-aliases")
|
||||||
if aliases == None:
|
if aliases == None:
|
||||||
log.error("Aliases are not defined for this config spec.")
|
log.error("Aliases are not defined for this config spec.")
|
||||||
return user.name
|
return self.demoji_user(display_name)
|
||||||
user_alias = aliases.get(user.id_str)
|
user_alias = aliases.get(user.id)
|
||||||
if user_alias != None:
|
if user_alias != None:
|
||||||
return user_alias
|
return user_alias
|
||||||
return user.name
|
return self.demoji_user(display_name)
|
||||||
|
|
||||||
|
def demoji_user(self, name):
|
||||||
|
if self.settings["general"]["hide_emojis"] == True:
|
||||||
|
return demoji.replace(name, "")
|
||||||
|
return name
|
||||||
|
|
||||||
def order_buffer(self, name, data, ignore_older=False):
|
def order_buffer(self, name, data, ignore_older=False):
|
||||||
num = 0
|
num = 0
|
||||||
@ -173,38 +183,43 @@ class Session(base.baseSession):
|
|||||||
tries = 0
|
tries = 0
|
||||||
if preexec_message:
|
if preexec_message:
|
||||||
output.speak(preexec_message, True)
|
output.speak(preexec_message, True)
|
||||||
while finished==False and tries < 25:
|
while finished==False and tries < 5:
|
||||||
try:
|
try:
|
||||||
val = getattr(self.api, call_name)(*args, **kwargs)
|
val = getattr(self.api, call_name)(*args, **kwargs)
|
||||||
finished = True
|
finished = True
|
||||||
except MastodonError as e:
|
except Exception as e:
|
||||||
output.speak(str(e))
|
output.speak(str(e))
|
||||||
val = None
|
val = None
|
||||||
if type(e) != MastodonNotFoundError and type(e) != MastodonUnauthorizedError :
|
if type(e) != MastodonNotFoundError and type(e) != MastodonUnauthorizedError :
|
||||||
tries = tries+1
|
tries = tries+1
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
elif report_failure:
|
if tries == 4 and finished == False:
|
||||||
output.speak(_("%s failed. Reason: %s") % (action, str(e)))
|
raise e
|
||||||
finished = True
|
else:
|
||||||
# except:
|
raise e
|
||||||
# tries = tries + 1
|
|
||||||
# time.sleep(5)
|
|
||||||
if report_success:
|
if report_success:
|
||||||
output.speak(_("%s succeeded.") % action)
|
output.speak(_("%s succeeded.") % action)
|
||||||
if _sound != None: self.sound.play(_sound)
|
if _sound != None:
|
||||||
|
self.sound.play(_sound)
|
||||||
return val
|
return val
|
||||||
|
|
||||||
def send_post(self, reply_to=None, users=None, visibility=None, posts=[]):
|
def send_post(self, reply_to=None, visibility=None, posts=[]):
|
||||||
""" Convenience function to send a thread. """
|
""" Convenience function to send a thread. """
|
||||||
in_reply_to_id = reply_to
|
in_reply_to_id = reply_to
|
||||||
for obj in posts:
|
for obj in posts:
|
||||||
text = obj.get("text")
|
text = obj.get("text")
|
||||||
if len(obj["attachments"]) == 0:
|
if len(obj["attachments"]) == 0:
|
||||||
|
try:
|
||||||
item = self.api_call(call_name="status_post", status=text, _sound="tweet_send.ogg", in_reply_to_id=in_reply_to_id, visibility=visibility, sensitive=obj["sensitive"], spoiler_text=obj["spoiler_text"])
|
item = self.api_call(call_name="status_post", status=text, _sound="tweet_send.ogg", in_reply_to_id=in_reply_to_id, visibility=visibility, sensitive=obj["sensitive"], spoiler_text=obj["spoiler_text"])
|
||||||
|
# If it fails, let's basically send an event with all passed info so we will catch it later.
|
||||||
|
except Exception as e:
|
||||||
|
pub.sendMessage("mastodon.error_post", name=self.get_name(), reply_to=reply_to, visibility=visibility, posts=posts)
|
||||||
|
return
|
||||||
if item != None:
|
if item != None:
|
||||||
in_reply_to_id = item["id"]
|
in_reply_to_id = item["id"]
|
||||||
else:
|
else:
|
||||||
media_ids = []
|
media_ids = []
|
||||||
|
try:
|
||||||
poll = None
|
poll = None
|
||||||
if len(obj["attachments"]) == 1 and obj["attachments"][0]["type"] == "poll":
|
if len(obj["attachments"]) == 1 and obj["attachments"][0]["type"] == "poll":
|
||||||
poll = self.api.make_poll(options=obj["attachments"][0]["options"], expires_in=obj["attachments"][0]["expires_in"], multiple=obj["attachments"][0]["multiple"], hide_totals=obj["attachments"][0]["hide_totals"])
|
poll = self.api.make_poll(options=obj["attachments"][0]["options"], expires_in=obj["attachments"][0]["expires_in"], multiple=obj["attachments"][0]["multiple"], hide_totals=obj["attachments"][0]["hide_totals"])
|
||||||
@ -215,6 +230,9 @@ class Session(base.baseSession):
|
|||||||
item = self.api_call(call_name="status_post", status=text, _sound="tweet_send.ogg", in_reply_to_id=in_reply_to_id, media_ids=media_ids, visibility=visibility, poll=poll, sensitive=obj["sensitive"], spoiler_text=obj["spoiler_text"])
|
item = self.api_call(call_name="status_post", status=text, _sound="tweet_send.ogg", in_reply_to_id=in_reply_to_id, media_ids=media_ids, visibility=visibility, poll=poll, sensitive=obj["sensitive"], spoiler_text=obj["spoiler_text"])
|
||||||
if item != None:
|
if item != None:
|
||||||
in_reply_to_id = item["id"]
|
in_reply_to_id = item["id"]
|
||||||
|
except Exception as e:
|
||||||
|
pub.sendMessage("mastodon.error_post", name=self.get_name(), reply_to=reply_to, visibility=visibility, posts=posts)
|
||||||
|
return
|
||||||
|
|
||||||
def get_name(self):
|
def get_name(self):
|
||||||
instance = self.settings["mastodon"]["instance"]
|
instance = self.settings["mastodon"]["instance"]
|
||||||
|
@ -152,7 +152,7 @@ def render_notification(notification, template, post_template, relative_times=Fa
|
|||||||
if notification.type == "status":
|
if notification.type == "status":
|
||||||
text = _("has posted: {status}").format(status=render_post(notification.status, post_template, relative_times, offset_hours))
|
text = _("has posted: {status}").format(status=render_post(notification.status, post_template, relative_times, offset_hours))
|
||||||
elif notification.type == "mention":
|
elif notification.type == "mention":
|
||||||
text = _("has mentionned you: {status}").format(status=render_post(notification.status, post_template, relative_times, offset_hours))
|
text = _("has mentioned you: {status}").format(status=render_post(notification.status, post_template, relative_times, offset_hours))
|
||||||
elif notification.type == "reblog":
|
elif notification.type == "reblog":
|
||||||
text = _("has boosted: {status}").format(status=render_post(notification.status, post_template, relative_times, offset_hours))
|
text = _("has boosted: {status}").format(status=render_post(notification.status, post_template, relative_times, offset_hours))
|
||||||
elif notification.type == "favourite":
|
elif notification.type == "favourite":
|
||||||
|
Loading…
Reference in New Issue
Block a user