mirror of
https://github.com/MCV-Software/TWBlue.git
synced 2026-05-12 21:07:37 +02:00
Merge branch 'next-gen' of github.com:mcv-software/twblue into next-gen
This commit is contained in:
@@ -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))
|
||||
* 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))
|
||||
* 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
|
||||
|
||||
|
||||
@@ -565,3 +565,15 @@ class BaseBuffer(base.Buffer):
|
||||
if answer != wx.ID_OK:
|
||||
return
|
||||
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:
|
||||
log.exception("Error %s" % (str(e)))
|
||||
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)
|
||||
log.debug("Number of items retrieved: %d" % (number_of_items,))
|
||||
self.put_items_on_list(number_of_items)
|
||||
@@ -49,7 +51,8 @@ class MentionsBuffer(BaseBuffer):
|
||||
except Exception as e:
|
||||
log.exception("Error %s" % (str(e)))
|
||||
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]
|
||||
for i in items:
|
||||
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_updated_item, "mastodon.updated_item")
|
||||
pub.subscribe(self.mastodon_new_conversation, "mastodon.conversation_received")
|
||||
|
||||
pub.subscribe(self.mastodon_error_post, "mastodon.error_post")
|
||||
# connect application events to GUI
|
||||
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)
|
||||
@@ -1306,6 +1306,10 @@ class Controller(object):
|
||||
# if "direct_messages" not in buffer.session.settings["other_buffers"]["muted_buffers"]:
|
||||
# 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):
|
||||
"""Redirects the user to the issue page on github"""
|
||||
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)
|
||||
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):
|
||||
text = self.message.text.GetValue()
|
||||
cw = self.message.spoiler.GetValue()
|
||||
|
||||
+1684
-1807
File diff suppressed because it is too large
Load Diff
+1679
-1802
File diff suppressed because it is too large
Load Diff
+1691
-1811
File diff suppressed because it is too large
Load Diff
+1692
-1808
File diff suppressed because it is too large
Load Diff
+1635
-1765
File diff suppressed because it is too large
Load Diff
+1623
-1757
File diff suppressed because it is too large
Load Diff
+1694
-1815
File diff suppressed because it is too large
Load Diff
+1629
-1759
File diff suppressed because it is too large
Load Diff
+1696
-1816
File diff suppressed because it is too large
Load Diff
+1544
-1671
File diff suppressed because it is too large
Load Diff
+1723
-1844
File diff suppressed because it is too large
Load Diff
+2517
-2639
File diff suppressed because it is too large
Load Diff
+1677
-1789
File diff suppressed because it is too large
Load Diff
+1582
-1821
File diff suppressed because it is too large
Load Diff
+1598
-1715
File diff suppressed because it is too large
Load Diff
+1688
-1811
File diff suppressed because it is too large
Load Diff
+1692
-1810
File diff suppressed because it is too large
Load Diff
+1708
-1828
File diff suppressed because it is too large
Load Diff
+1690
-1808
File diff suppressed because it is too large
Load Diff
+1601
-1732
File diff suppressed because it is too large
Load Diff
+2511
-2629
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":
|
||||
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":
|
||||
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":
|
||||
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":
|
||||
|
||||
@@ -6,6 +6,7 @@ import logging
|
||||
import webbrowser
|
||||
import wx
|
||||
import mastodon
|
||||
import demoji
|
||||
import config
|
||||
import config_utils
|
||||
import output
|
||||
@@ -123,14 +124,23 @@ class Session(base.baseSession):
|
||||
self.db["muted_users"] = self.api.mutes()
|
||||
|
||||
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")
|
||||
if aliases == None:
|
||||
log.error("Aliases are not defined for this config spec.")
|
||||
return user.name
|
||||
user_alias = aliases.get(user.id_str)
|
||||
return self.demoji_user(display_name)
|
||||
user_alias = aliases.get(user.id)
|
||||
if user_alias != None:
|
||||
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):
|
||||
num = 0
|
||||
@@ -173,38 +183,43 @@ class Session(base.baseSession):
|
||||
tries = 0
|
||||
if preexec_message:
|
||||
output.speak(preexec_message, True)
|
||||
while finished==False and tries < 25:
|
||||
while finished==False and tries < 5:
|
||||
try:
|
||||
val = getattr(self.api, call_name)(*args, **kwargs)
|
||||
finished = True
|
||||
except MastodonError as e:
|
||||
except Exception as e:
|
||||
output.speak(str(e))
|
||||
val = None
|
||||
if type(e) != MastodonNotFoundError and type(e) != MastodonUnauthorizedError :
|
||||
tries = tries+1
|
||||
time.sleep(5)
|
||||
elif report_failure:
|
||||
output.speak(_("%s failed. Reason: %s") % (action, str(e)))
|
||||
finished = True
|
||||
# except:
|
||||
# tries = tries + 1
|
||||
# time.sleep(5)
|
||||
if tries == 4 and finished == False:
|
||||
raise e
|
||||
else:
|
||||
raise e
|
||||
if report_success:
|
||||
output.speak(_("%s succeeded.") % action)
|
||||
if _sound != None: self.sound.play(_sound)
|
||||
if _sound != None:
|
||||
self.sound.play(_sound)
|
||||
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. """
|
||||
in_reply_to_id = reply_to
|
||||
for obj in posts:
|
||||
text = obj.get("text")
|
||||
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"])
|
||||
# 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:
|
||||
in_reply_to_id = item["id"]
|
||||
else:
|
||||
media_ids = []
|
||||
try:
|
||||
poll = None
|
||||
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"])
|
||||
@@ -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"])
|
||||
if item != None:
|
||||
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):
|
||||
instance = self.settings["mastodon"]["instance"]
|
||||
|
||||
@@ -152,7 +152,7 @@ def render_notification(notification, template, post_template, relative_times=Fa
|
||||
if notification.type == "status":
|
||||
text = _("has posted: {status}").format(status=render_post(notification.status, post_template, relative_times, offset_hours))
|
||||
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":
|
||||
text = _("has boosted: {status}").format(status=render_post(notification.status, post_template, relative_times, offset_hours))
|
||||
elif notification.type == "favourite":
|
||||
|
||||
Reference in New Issue
Block a user