Remove most of Twitter code as Twitter's API access has been removed

This commit is contained in:
2023-04-03 13:35:05 -06:00
parent 74fe437684
commit 8acebc290b
95 changed files with 74 additions and 7643 deletions

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
from . import base as base
from . import twitter as twitter
from . import mastodon as mastodon

View File

@@ -1,7 +0,0 @@
# -*- coding: utf-8 -*-
from .base import BaseBuffer
from .directMessages import DirectMessagesBuffer, SentDirectMessagesBuffer
from .list import ListBuffer
from .people import PeopleBuffer
from .trends import TrendsBuffer
from .search import SearchBuffer, SearchPeopleBuffer, ConversationBuffer

View File

@@ -1,663 +0,0 @@
# -*- coding: utf-8 -*-
import time
import wx
import widgetUtils
import arrow
import webbrowser
import output
import config
import sound
import languageHandler
import logging
from audio_services import youtube_utils
from controller.buffers.base import base
from sessions.twitter import compose, utils, reduce, templates
from mysc.thread_utils import call_threaded
from tweepy.errors import TweepyException
from tweepy.cursor import Cursor
from pubsub import pub
from extra import ocr
from sessions.twitter.long_tweets import twishort, tweets
from wxUI import buffers, dialogs, commonMessageDialogs, menus
from controller.twitter import user, messages
log = logging.getLogger("controller.buffers")
def _tweets_exist(function):
""" A decorator to execute a function only if the selected buffer contains at least one item."""
def function_(self, *args, **kwargs):
if self.buffer.list.get_count() > 0:
function(self, *args, **kwargs)
return function_
class BaseBuffer(base.Buffer):
def __init__(self, parent, function, name, sessionObject, account, sound=None, bufferType=None, compose_func="compose_tweet", *args, **kwargs):
super(BaseBuffer, self).__init__(parent, function, *args, **kwargs)
log.debug("Initializing buffer %s, account %s" % (name, account,))
if bufferType != None:
self.buffer = getattr(buffers.twitter, bufferType)(parent, name)
else:
self.buffer = buffers.twitter.basePanel(parent, name)
self.invisible = True
self.name = name
self.type = self.buffer.type
self.session = sessionObject
self.compose_function = getattr(compose, compose_func)
log.debug("Compose_function: %s" % (self.compose_function,))
self.account = account
self.buffer.account = account
self.bind_events()
self.sound = sound
if "-timeline" in self.name or "-favorite" in self.name:
self.finished_timeline = False
# Add a compatibility layer for username based timelines from config.
# ToDo: Remove this in some new versions of the client, when user ID timelines become mandatory.
try:
int(self.kwargs["user_id"])
except ValueError:
self.is_screen_name = True
self.kwargs["screen_name"] = self.kwargs["user_id"]
self.kwargs.pop("user_id")
def get_buffer_name(self):
""" Get buffer name from a set of different techniques."""
# firstly let's take the easier buffers.
basic_buffers = dict(home_timeline=_(u"Home"), mentions=_(u"Mentions"), direct_messages=_(u"Direct messages"), sent_direct_messages=_(u"Sent direct messages"), sent_tweets=_(u"Sent tweets"), favourites=_(u"Likes"), followers=_(u"Followers"), friends=_(u"Friends"), blocked=_(u"Blocked users"), muted=_(u"Muted users"))
if self.name in list(basic_buffers.keys()):
return basic_buffers[self.name]
# Check user timelines
elif hasattr(self, "username"):
if "-timeline" in self.name:
return _(u"{username}'s timeline").format(username=self.username,)
elif "-favorite" in self.name:
return _(u"{username}'s likes").format(username=self.username,)
elif "-followers" in self.name:
return _(u"{username}'s followers").format(username=self.username,)
elif "-friends" in self.name:
return _(u"{username}'s friends").format(username=self.username,)
log.error("Error getting name for buffer %s" % (self.name,))
return _(u"Unknown buffer")
def post_status(self, *args, **kwargs):
title = _("Tweet")
caption = _("Write the tweet here")
tweet = messages.tweet(self.session, title, caption, "")
response = tweet.message.ShowModal()
if response == wx.ID_OK:
tweet_data = tweet.get_tweet_data()
call_threaded(self.session.send_tweet, *tweet_data)
if hasattr(tweet.message, "destroy"):
tweet.message.destroy()
def get_formatted_message(self):
if self.type == "dm" or self.name == "direct_messages":
return self.compose_function(self.get_right_tweet(), self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session)[1]
return self.get_message()
def get_message(self):
template = self.session.settings["templates"]["tweet"]
tweet = self.get_right_tweet()
t = templates.render_tweet(tweet, template, self.session, relative_times=self.session.settings["general"]["relative_times"], offset_seconds=self.session.db["utc_offset"])
return t
def get_full_tweet(self):
tweet = self.get_right_tweet()
tweetsList = []
tweet_id = tweet.id
message = None
if hasattr(tweet, "message"):
message = tweet.message
try:
tweet = self.session.twitter.get_status(id=tweet_id, include_ext_alt_text=True, tweet_mode="extended")
tweet.full_text = utils.expand_urls(tweet.full_text, tweet.entities)
except TweepyException as e:
utils.twitter_error(e)
return
if message != None:
tweet.message = message
l = tweets.is_long(tweet)
while l != False:
tweetsList.append(tweet)
try:
tweet = self.session.twitter.get_status(id=l, include_ext_alt_text=True, tweet_mode="extended")
tweet.full_text = utils.expand_urls(tweet.full_text, tweet.entities)
except TweepyException as e:
utils.twitter_error(e)
return
l = tweets.is_long(tweet)
if l == False:
tweetsList.append(tweet)
return (tweet, tweetsList)
def start_stream(self, mandatory=False, play_sound=True, avoid_autoreading=False):
# starts stream every 3 minutes.
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))
if self.name != "direct_messages":
val = self.session.call_paged(self.function, self.name, *self.args, **self.kwargs)
else:
# 50 results are allowed per API call, so let's assume max value can be 50.
# reference: https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/list-events
if self.session.settings["general"]["max_tweets_per_call"] > 50:
count = 50
else:
count = self.session.settings["general"]["max_tweets_per_call"]
# try to retrieve the cursor for the current buffer.
try:
val = getattr(self.session.twitter, self.function)(return_cursors=True, count=count, *self.args, **self.kwargs)
if type(val) == tuple:
val, cursor = val
if type(cursor) == tuple:
cursor = cursor[1]
cursors = self.session.db["cursors"]
cursors[self.name] = cursor
self.session.db["cursors"] = cursors
results = [i for i in val]
val = results
val.reverse()
log.debug("Retrieved %d items from the cursored search on function %s." %(len(val), self.function))
user_ids = [item.message_create["sender_id"] for item in val]
self.session.save_users(user_ids)
except TweepyException as e:
log.exception("Error %s" % (str(e)))
return
number_of_items = self.session.order_buffer(self.name, val)
log.debug("Number of items retrieved: %d" % (number_of_items,))
self.put_items_on_list(number_of_items)
if hasattr(self, "finished_timeline") and self.finished_timeline == False:
if "-timeline" in self.name:
self.username = self.session.get_user(self.kwargs.get("user_id")).screen_name
elif "-favorite" in self.name:
self.username = self.session.get_user(self.kwargs.get("user_id")).screen_name
self.finished_timeline = True
if number_of_items > 0 and self.name != "sent_tweets" 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 auto_read(self, number_of_items):
if 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:
if self.session.settings["general"]["reverse_timelines"] == False:
tweet = self.session.db[self.name][-1]
else:
tweet = self.session.db[self.name][0]
output.speak(_(u"New tweet in {0}").format(self.get_buffer_name()))
output.speak(" ".join(self.compose_function(tweet, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session)))
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(_(u"{0} new tweets in {1}.").format(number_of_items, self.get_buffer_name()))
def get_more_items(self):
elements = []
if self.session.settings["general"]["reverse_timelines"] == False:
last_id = self.session.db[self.name][0].id
else:
last_id = self.session.db[self.name][-1].id
try:
items = getattr(self.session.twitter, self.function)(max_id=last_id, count=self.session.settings["general"]["max_tweets_per_call"], *self.args, **self.kwargs)
except TweepyException as e:
log.exception("Error %s" % (str(e)))
return
if items == None:
return
items_db = self.session.db[self.name]
self.session.add_users_from_results(items)
for i in items:
if utils.is_allowed(i, self.session.settings, self.name) == True and utils.find_item(i, self.session.db[self.name]) == None:
i = reduce.reduce_tweet(i)
i = self.session.check_quoted_status(i)
i = self.session.check_long_tweet(i)
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:
tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session)
self.buffer.list.insert_item(True, *tweet)
else:
for i in items:
tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session)
self.buffer.list.insert_item(False, *tweet)
self.buffer.list.select_item(selection)
output.speak(_(u"%s items retrieved") % (str(len(elements))), True)
def remove_buffer(self, force=False):
if "-timeline" in self.name:
if force == False:
dlg = commonMessageDialogs.remove_buffer()
else:
dlg = widgetUtils.YES
if dlg == widgetUtils.YES:
if self.name[:-9] in self.session.settings["other_buffers"]["timelines"]:
self.session.settings["other_buffers"]["timelines"].remove(self.name[:-9])
self.session.settings.write()
if self.name in self.session.db:
self.session.db.pop(self.name)
return True
elif dlg == widgetUtils.NO:
return False
elif "favorite" in self.name:
if force == False:
dlg = commonMessageDialogs.remove_buffer()
else:
dlg = widgetUtils.YES
if dlg == widgetUtils.YES:
if self.name[:-9] in self.session.settings["other_buffers"]["favourites_timelines"]:
self.session.settings["other_buffers"]["favourites_timelines"].remove(self.name[:-9])
if self.name in self.session.db:
self.session.db.pop(self.name)
self.session.settings.write()
return True
elif dlg == widgetUtils.NO:
return False
else:
output.speak(_(u"This buffer is not a timeline; it can't be deleted."), True)
return False
def remove_tweet(self, id):
if type(self.session.db[self.name]) == dict: return
items = self.session.db[self.name]
for i in range(0, len(items)):
if items[i].id == id:
items.pop(i)
self.remove_item(i)
self.session.db[self.name] = items
def put_items_on_list(self, number_of_items):
list_to_use = self.session.db[self.name]
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("Putting %d items on the list" % (number_of_items,))
if self.buffer.list.get_count() == 0:
for i in list_to_use:
tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session)
self.buffer.list.insert_item(False, *tweet)
self.buffer.set_position(self.session.settings["general"]["reverse_timelines"])
elif self.buffer.list.get_count() > 0 and number_of_items > 0:
if self.session.settings["general"]["reverse_timelines"] == False:
items = list_to_use[len(list_to_use)-number_of_items:]
for i in items:
tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session)
self.buffer.list.insert_item(False, *tweet)
else:
items = list_to_use[0:number_of_items]
items.reverse()
for i in items:
tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session)
self.buffer.list.insert_item(True, *tweet)
log.debug("Now the list contains %d items " % (self.buffer.list.get_count(),))
def add_new_item(self, item):
tweet = self.compose_function(item, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session)
if self.session.settings["general"]["reverse_timelines"] == False:
self.buffer.list.insert_item(False, *tweet)
else:
self.buffer.list.insert_item(True, *tweet)
if 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(" ".join(tweet[:2]), speech=self.session.settings["reporting"]["speech_reporting"], braille=self.session.settings["reporting"]["braille_reporting"])
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.tweet)
# if self.type == "baseBuffer":
widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.share_item, self.buffer.retweet)
widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.send_message, self.buffer.dm)
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 show_menu(self, ev, pos=0, *args, **kwargs):
if self.buffer.list.get_count() == 0: return
if self.name == "sent_tweets" or self.name == "direct_messages":
menu = menus.sentPanelMenu()
elif self.name == "direct_messages":
menu = menus.dmPanelMenu()
widgetUtils.connect_event(menu, widgetUtils.MENU, self.send_message, menuitem=menu.reply)
widgetUtils.connect_event(menu, widgetUtils.MENU, self.user_actions, menuitem=menu.userActions)
else:
menu = menus.basePanelMenu()
widgetUtils.connect_event(menu, widgetUtils.MENU, self.reply, menuitem=menu.reply)
widgetUtils.connect_event(menu, widgetUtils.MENU, self.user_actions, menuitem=menu.userActions)
widgetUtils.connect_event(menu, widgetUtils.MENU, self.share_item, menuitem=menu.retweet)
widgetUtils.connect_event(menu, widgetUtils.MENU, self.fav, menuitem=menu.fav)
widgetUtils.connect_event(menu, widgetUtils.MENU, self.unfav, menuitem=menu.unfav)
widgetUtils.connect_event(menu, widgetUtils.MENU, self.url_, menuitem=menu.openUrl)
widgetUtils.connect_event(menu, widgetUtils.MENU, self.audio, menuitem=menu.play)
widgetUtils.connect_event(menu, widgetUtils.MENU, self.view, menuitem=menu.view)
widgetUtils.connect_event(menu, widgetUtils.MENU, self.copy, menuitem=menu.copy)
widgetUtils.connect_event(menu, widgetUtils.MENU, self.destroy_status, menuitem=menu.remove)
if hasattr(menu, "openInBrowser"):
widgetUtils.connect_event(menu, widgetUtils.MENU, self.open_in_browser, menuitem=menu.openInBrowser)
if pos != 0:
self.buffer.PopupMenu(menu, pos)
else:
self.buffer.PopupMenu(menu, ev.GetPosition())
def view(self, *args, **kwargs):
pub.sendMessage("execute-action", action="view_item")
def copy(self, *args, **kwargs):
pub.sendMessage("execute-action", action="copy_to_clipboard")
def user_actions(self, *args, **kwargs):
pub.sendMessage("execute-action", action="follow")
def fav(self, *args, **kwargs):
pub.sendMessage("execute-action", action="add_to_favourites")
def unfav(self, *args, **kwargs):
pub.sendMessage("execute-action", action="remove_from_favourites")
def delete_item_(self, *args, **kwargs):
pub.sendMessage("execute-action", action="delete_item")
def url_(self, *args, **kwargs):
self.url()
def show_menu_by_key(self, ev):
if self.buffer.list.get_count() == 0:
return
if ev.GetKeyCode() == wx.WXK_WINDOWS_MENU:
self.show_menu(widgetUtils.MENU, pos=self.buffer.list.list.GetPosition())
def get_tweet(self):
if hasattr(self.session.db[self.name][self.buffer.list.get_selected()], "retweeted_status"):
tweet = self.session.db[self.name][self.buffer.list.get_selected()].retweeted_status
else:
tweet = self.session.db[self.name][self.buffer.list.get_selected()]
return tweet
def get_right_tweet(self):
tweet = self.session.db[self.name][self.buffer.list.get_selected()]
return tweet
def can_share(self):
tweet = self.get_right_tweet()
user = self.session.get_user(tweet.user)
is_protected = user.protected
return is_protected==False
@_tweets_exist
def reply(self, *args, **kwargs):
tweet = self.get_right_tweet()
user = self.session.get_user(tweet.user)
screen_name = user.screen_name
id = tweet.id
users = utils.get_all_mentioned(tweet, self.session.db, field="screen_name")
ids = utils.get_all_mentioned(tweet, self.session.db, field="id")
# Build the window title
if len(users) < 1:
title=_("Reply to {arg0}").format(arg0=screen_name)
else:
title=_("Reply")
message = messages.reply(self.session, title, _("Reply to %s") % (screen_name,), "", users=users, ids=ids)
if message.message.ShowModal() == widgetUtils.OK:
if config.app["app-settings"]["remember_mention_and_longtweet"]:
if len(users) > 0:
config.app["app-settings"]["mention_all"] = message.message.mention_all.GetValue()
config.app.write()
tweet_data = dict(text=message.message.text.GetValue(), attachments=message.attachments, poll_options=message.poll_options, poll_period=message.poll_period)
call_threaded(self.session.reply, in_reply_to_status_id=id, text=message.message.text.GetValue(), attachments=message.attachments, exclude_reply_user_ids=message.get_ids())
if hasattr(message.message, "destroy"): message.message.destroy()
self.session.settings.write()
@_tweets_exist
def send_message(self, *args, **kwargs):
tweet = self.get_right_tweet()
if self.type == "dm":
screen_name = self.session.get_user(tweet.message_create["sender_id"]).screen_name
users = [screen_name]
elif self.type == "people":
screen_name = tweet.screen_name
users = [screen_name]
else:
screen_name = self.session.get_user(tweet.user).screen_name
users = utils.get_all_users(tweet, self.session)
dm = messages.dm(self.session, _("Direct message to %s") % (screen_name,), _("New direct message"), users)
if dm.message.ShowModal() == widgetUtils.OK:
screen_name = dm.message.cb.GetValue()
user = self.session.get_user_by_screen_name(screen_name)
recipient_id = user
text = dm.message.text.GetValue()
if len(dm.attachments) > 0:
attachment = dm.attachments[0]
else:
attachment = None
call_threaded(self.session.direct_message, text=text, recipient=recipient_id, attachment=attachment)
if hasattr(dm.message, "destroy"): dm.message.destroy()
@_tweets_exist
def share_item(self, *args, **kwargs):
if self.can_share() == False:
return output.speak(_("This action is not supported on protected accounts."))
tweet = self.get_right_tweet()
id = tweet.id
if self.session.settings["general"]["retweet_mode"] == "ask":
answer = commonMessageDialogs.retweet_question(self.buffer)
if answer == widgetUtils.YES:
self._retweet_with_comment(tweet, id)
elif answer == widgetUtils.NO:
self._direct_retweet(id)
elif self.session.settings["general"]["retweet_mode"] == "direct":
self._direct_retweet(id)
else:
self._retweet_with_comment(tweet, id)
def _retweet_with_comment(self, tweet, id):
if hasattr(tweet, "retweeted_status"):
tweet = tweet.retweeted_status
retweet = messages.tweet(session=self.session, title=_("Quote"), caption=_("Add your comment to the tweet"), thread_mode=False)
if retweet.message.ShowModal() == widgetUtils.OK:
text = retweet.message.text.GetValue()
tweet_data = dict(text=text, attachments=retweet.attachments, poll_period=retweet.poll_period, poll_options=retweet.poll_options)
tweet_data.update(quote_tweet_id=id)
call_threaded(self.session.send_tweet, *[tweet_data])
if hasattr(retweet.message, "destroy"):
retweet.message.Destroy()
def _direct_retweet(self, id):
item = self.session.api_call(call_name="retweet", _sound="retweet_send.ogg", id=id)
def onFocus(self, *args, **kwargs):
tweet = self.get_tweet()
if self.session.settings["general"]["relative_times"] == True:
# fix this:
original_date = arrow.get(self.session.db[self.name][self.buffer.list.get_selected()].created_at, locale="en")
ts = original_date.humanize(locale=languageHandler.getLanguage())
self.buffer.list.list.SetItem(self.buffer.list.get_selected(), 2, ts)
if self.session.settings['sound']['indicate_audio'] and utils.is_audio(tweet):
self.session.sound.play("audio.ogg")
if self.session.settings['sound']['indicate_geo'] and utils.is_geocoded(tweet):
self.session.sound.play("geo.ogg")
if self.session.settings['sound']['indicate_img'] and utils.is_media(tweet):
self.session.sound.play("image.ogg")
can_share = self.can_share()
pub.sendMessage("toggleShare", shareable=can_share)
self.buffer.retweet.Enable(can_share)
def audio(self, url='', *args, **kwargs):
if sound.URLPlayer.player.is_playing():
return sound.URLPlayer.stop_audio()
tweet = self.get_tweet()
if tweet == None: return
urls = utils.find_urls(tweet, twitter_media=True)
if len(urls) == 1:
url=urls[0]
elif len(urls) > 1:
urls_list = dialogs.urlList.urlList()
urls_list.populate_list(urls)
if urls_list.get_response() == widgetUtils.OK:
url=urls_list.get_string()
if hasattr(urls_list, "destroy"): urls_list.destroy()
if url != '':
# try:
sound.URLPlayer.play(url, self.session.settings["sound"]["volume"])
# except:
# log.error("Exception while executing audio method.")
# @_tweets_exist
def url(self, url='', announce=True, *args, **kwargs):
if url == '':
tweet = self.get_tweet()
urls = utils.find_urls(tweet)
if len(urls) == 1:
url=urls[0]
elif len(urls) > 1:
urls_list = dialogs.urlList.urlList()
urls_list.populate_list(urls)
if urls_list.get_response() == widgetUtils.OK:
url=urls_list.get_string()
if hasattr(urls_list, "destroy"): urls_list.destroy()
if url != '':
if announce:
output.speak(_(u"Opening URL..."), True)
webbrowser.open_new_tab(url)
def clear_list(self):
dlg = commonMessageDialogs.clear_list()
if dlg == widgetUtils.YES:
self.session.db[self.name] = []
self.buffer.list.clear()
@_tweets_exist
def destroy_status(self, *args, **kwargs):
index = self.buffer.list.get_selected()
if self.type == "events" or self.type == "people" or self.type == "empty" or self.type == "account": return
answer = commonMessageDialogs.delete_tweet_dialog(None)
if answer == widgetUtils.YES:
items = self.session.db[self.name]
try:
if self.name == "direct_messages" or self.name == "sent_direct_messages":
self.session.twitter.delete_direct_message(id=self.get_right_tweet().id)
items.pop(index)
else:
self.session.twitter.destroy_status(id=self.get_right_tweet().id)
items.pop(index)
self.buffer.list.remove_item(index)
except TweepyException:
self.session.sound.play("error.ogg")
self.session.db[self.name] = items
@_tweets_exist
def user_details(self):
tweet = self.get_right_tweet()
if self.type == "dm":
users = [self.session.get_user(tweet.message_create["sender_id"]).screen_name]
elif self.type == "people":
users = [tweet.screen_name]
else:
users = utils.get_all_users(tweet, self.session)
dlg = dialogs.utils.selectUserDialog(title=_(u"User details"), users=users)
if dlg.get_response() == widgetUtils.OK:
user.profileController(session=self.session, user=dlg.get_user())
if hasattr(dlg, "destroy"): dlg.destroy()
def get_quoted_tweet(self, tweet):
quoted_tweet = self.session.twitter.get_status(id=tweet.id)
quoted_tweet.text = utils.find_urls_in_text(quoted_tweet.text, quoted_tweet.entities)
l = tweets.is_long(quoted_tweet)
id = tweets.get_id(l)
original_tweet = self.session.twitter.get_status(id=id)
original_tweet.text = utils.find_urls_in_text(original_tweet.text, original_tweet.entities)
return compose.compose_quoted_tweet(quoted_tweet, original_tweet, self.session.db, self.session.settings["general"]["relative_times"])
def get_item_url(self):
tweet = self.get_tweet()
url = "https://twitter.com/{screen_name}/status/{tweet_id}".format(screen_name=self.session.get_user(tweet.user).screen_name, tweet_id=tweet.id)
return url
def open_in_browser(self, *args, **kwargs):
url = self.get_item_url()
output.speak(_(u"Opening item in web browser..."))
webbrowser.open(url)
def add_to_favorites(self):
id = self.get_tweet().id
call_threaded(self.session.api_call, call_name="create_favorite", _sound="favourite.ogg", id=id)
def remove_from_favorites(self):
id = self.get_tweet().id
call_threaded(self.session.api_call, call_name="destroy_favorite", id=id)
def toggle_favorite(self):
id = self.get_tweet().id
tweet = self.session.twitter.get_status(id=id, include_ext_alt_text=True, tweet_mode="extended")
if tweet.favorited == False:
call_threaded(self.session.api_call, call_name="create_favorite", _sound="favourite.ogg", id=id)
else:
call_threaded(self.session.api_call, call_name="destroy_favorite", id=id)
def view_item(self):
if self.type == "dm" or self.name == "direct_messages":
non_tweet = self.get_formatted_message()
item = self.get_right_tweet()
original_date = arrow.get(int(item.created_timestamp))
date = original_date.shift(seconds=self.session.db["utc_offset"]).format(_(u"MMM D, YYYY. H:m"), locale=languageHandler.getLanguage())
msg = messages.viewTweet(non_tweet, [], False, date=date)
else:
tweet, tweetsList = self.get_full_tweet()
msg = messages.viewTweet(tweet, tweetsList, utc_offset=self.session.db["utc_offset"], item_url=self.get_item_url())
def reverse_geocode(self, geocoder):
try:
tweet = self.get_tweet()
if tweet.coordinates != None:
x = tweet.coordinates["coordinates"][0]
y = tweet.coordinates["coordinates"][1]
address = geocoder.reverse_geocode(y, x, language = languageHandler.curLang)
return address
else:
output.speak(_("There are no coordinates in this tweet"))
# except GeocoderError:
# output.speak(_(u"There are no results for the coordinates in this tweet"))
except ValueError:
output.speak(_(u"Error decoding coordinates. Try again later."))
except KeyError:
pass
except AttributeError:
pass
def ocr_image(self):
tweet = self.get_tweet()
media_list = []
if hasattr(tweet, "entities") and tweet.entities.get("media") != None:
[media_list.append(i) for i in tweet.entities["media"] if i not in media_list]
elif hasattr(tweet, "retweeted_status") and tweet.retweeted_status.get("media") != None:
[media_list.append(i) for i in tweet.retweeted_status.entities["media"] if i not in media_list]
elif hasattr(tweet, "quoted_status") and tweet.quoted_status.entities.get("media") != None:
[media_list.append(i) for i in tweet.quoted_status.entities["media"] if i not in media_list]
if len(media_list) > 1:
image_list = [_(u"Picture {0}").format(i,) for i in range(0, len(media_list))]
dialog = dialogs.urlList.urlList(title=_(u"Select the picture"))
if dialog.get_response() == widgetUtils.OK:
img = media_list[dialog.get_item()]
else:
return
elif len(media_list) == 1:
img = media_list[0]
else:
output.speak(_(u"Invalid buffer"))
return
if self.session.settings["mysc"]["ocr_language"] != "":
ocr_lang = self.session.settings["mysc"]["ocr_language"]
else:
ocr_lang = ocr.OCRSpace.short_langs.index(tweet.lang)
ocr_lang = ocr.OCRSpace.OcrLangs[ocr_lang]
api = ocr.OCRSpace.OCRSpaceAPI()
try:
text = api.OCR_URL(img["media_url"], lang=ocr_lang)
except ocr.OCRSpace.APIError as er:
output.speak(_(u"Unable to extract text"))
return
msg = messages.viewTweet(text["ParsedText"], [], False)

View File

@@ -1,164 +0,0 @@
# -*- coding: utf-8 -*-
import widgetUtils
import arrow
import webbrowser
import output
import config
import languageHandler
import logging
from sessions.twitter import compose, utils, templates
from mysc.thread_utils import call_threaded
from tweepy.errors import TweepyException
from pubsub import pub
from wxUI import commonMessageDialogs
from controller.twitter import messages
from . import base
log = logging.getLogger("controller.buffers.twitter.dmBuffer")
class DirectMessagesBuffer(base.BaseBuffer):
def get_more_items(self):
# 50 results are allowed per API call, so let's assume max value can be 50.
# reference: https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/list-events
if self.session.settings["general"]["max_tweets_per_call"] > 50:
count = 50
else:
count = self.session.settings["general"]["max_tweets_per_call"]
total = 0
# try to retrieve the cursor for the current buffer.
cursor = self.session.db["cursors"].get(self.name)
try:
items = getattr(self.session.twitter, self.function)(return_cursors=True, cursor=cursor, count=count, *self.args, **self.kwargs)
if type(items) == tuple:
items, cursor = items
if type(cursor) == tuple:
cursor = cursor[1]
cursors = self.session.db["cursors"]
cursors[self.name] = cursor
self.session.db["cursors"] = cursors
results = [i for i in items]
items = results
log.debug("Retrieved %d items for cursored search in function %s" % (len(items), self.function))
except TweepyException as e:
log.exception("Error %s" % (str(e)))
return
if items == None:
return
sent = []
received = []
sent_dms = self.session.db["sent_direct_messages"]
received_dms = self.session.db["direct_messages"]
for i in items:
if int(i.message_create["sender_id"]) == self.session.db["user_id"]:
if self.session.settings["general"]["reverse_timelines"] == False:
sent_dms.insert(0, i)
sent.append(i)
else:
sent_dms.append(i)
sent.insert(0, i)
else:
if self.session.settings["general"]["reverse_timelines"] == False:
received_dms.insert(0, i)
received.append(i)
else:
received_dms.append(i)
received.insert(0, i)
total = total+1
self.session.db["direct_messages"] = received_dms
self.session.db["sent_direct_messages"] = sent_dms
user_ids = [item.message_create["sender_id"] for item in items]
self.session.save_users(user_ids)
pub.sendMessage("twitter.more_sent_dms", data=sent, account=self.session.db["user_name"])
selected = self.buffer.list.get_selected()
if self.session.settings["general"]["reverse_timelines"] == True:
for i in received:
if int(i.message_create["sender_id"]) == self.session.db["user_id"]:
continue
tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session)
self.buffer.list.insert_item(True, *tweet)
self.buffer.list.select_item(selected)
else:
for i in received:
if int(i.message_create["sender_id"]) == self.session.db["user_id"]:
continue
tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session)
self.buffer.list.insert_item(True, *tweet)
output.speak(_(u"%s items retrieved") % (total), True)
def reply(self, *args, **kwargs):
return self.send_message()
def onFocus(self, *args, **kwargs):
tweet = self.get_tweet()
if self.session.settings["general"]["relative_times"] == True:
# fix this:
original_date = arrow.get(int(tweet.created_timestamp))
ts = original_date.humanize(locale=languageHandler.getLanguage())
self.buffer.list.list.SetItem(self.buffer.list.get_selected(), 2, ts)
if self.session.settings['sound']['indicate_audio'] and utils.is_audio(tweet):
self.session.sound.play("audio.ogg")
if self.session.settings['sound']['indicate_img'] and utils.is_media(tweet):
self.session.sound.play("image.ogg")
def clear_list(self):
dlg = commonMessageDialogs.clear_list()
if dlg == widgetUtils.YES:
self.session.db[self.name] = []
self.buffer.list.clear()
def auto_read(self, number_of_items):
if 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:
if self.session.settings["general"]["reverse_timelines"] == False:
tweet = self.session.db[self.name][-1]
else:
tweet = self.session.db[self.name][0]
output.speak(_(u"New direct message"))
output.speak(" ".join(self.compose_function(tweet, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session)))
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(_(u"{0} new direct messages.").format(number_of_items,))
def open_in_browser(self, *args, **kwargs):
output.speak(_(u"This action is not supported in the buffer yet."))
def get_message(self):
template = self.session.settings["templates"]["dm"]
dm = self.get_right_tweet()
t = templates.render_dm(dm, template, self.session, relative_times=self.session.settings["general"]["relative_times"], offset_seconds=self.session.db["utc_offset"])
return t
class SentDirectMessagesBuffer(DirectMessagesBuffer):
def __init__(self, *args, **kwargs):
super(SentDirectMessagesBuffer, self).__init__(*args, **kwargs)
if ("sent_direct_messages" in self.session.db) == False:
self.session.db["sent_direct_messages"] = []
def get_more_items(self):
output.speak(_(u"Getting more items cannot be done in this buffer. Use the direct messages buffer instead."))
def start_stream(self, *args, **kwargs):
pass
def put_more_items(self, items):
if self.session.settings["general"]["reverse_timelines"] == True:
for i in items:
tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session)
self.buffer.list.insert_item(False, *tweet)
else:
for i in items:
tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session)
self.buffer.list.insert_item(False, *tweet)
def get_message(self):
template = self.session.settings["templates"]["dm_sent"]
dm = self.get_right_tweet()
t = templates.render_dm(dm, template, self.session, relative_times=self.session.settings["general"]["relative_times"], offset_seconds=self.session.db["utc_offset"])
return t
def view_item(self):
non_tweet = self.get_formatted_message()
item = self.get_right_tweet()
original_date = arrow.get(int(item.created_timestamp))
date = original_date.shift(seconds=self.session.db["utc_offset"]).format(_(u"MMM D, YYYY. H:m"), locale=languageHandler.getLanguage())
msg = messages.viewTweet(non_tweet, [], False, date=date)

View File

@@ -1,39 +0,0 @@
# -*- coding: utf-8 -*-
import widgetUtils
import logging
from tweepy.cursor import Cursor
from wxUI import dialogs, commonMessageDialogs
from . import base
log = logging.getLogger("controller.buffers.twitter.listBuffer")
class ListBuffer(base.BaseBuffer):
def __init__(self, parent, function, name, sessionObject, account, sound=None, bufferType=None, list_id=None, *args, **kwargs):
super(ListBuffer, self).__init__(parent, function, name, sessionObject, account, sound=None, bufferType=None, *args, **kwargs)
self.users = []
self.list_id = list_id
self.kwargs["list_id"] = list_id
def start_stream(self, mandatory=False, play_sound=True, avoid_autoreading=False):
self.get_user_ids()
super(ListBuffer, self).start_stream(mandatory, play_sound, avoid_autoreading)
def get_user_ids(self):
for i in Cursor(self.session.twitter.get_list_members, list_id=self.list_id, include_entities=False, skip_status=True, count=5000).items():
if i.id not in self.users:
self.users.append(i.id)
def remove_buffer(self, force=False):
if force == False:
dlg = commonMessageDialogs.remove_buffer()
else:
dlg = widgetUtils.YES
if dlg == widgetUtils.YES:
if self.name[:-5] in self.session.settings["other_buffers"]["lists"]:
self.session.settings["other_buffers"]["lists"].remove(self.name[:-5])
if self.name in self.session.db:
self.session.db.pop(self.name)
self.session.settings.write()
return True
elif dlg == widgetUtils.NO:
return False

View File

@@ -1,254 +0,0 @@
# -*- coding: utf-8 -*-
import time
import widgetUtils
import webbrowser
import output
import config
import logging
from mysc.thread_utils import call_threaded
from tweepy.errors import TweepyException
from pubsub import pub
from controller.twitter import user, messages
from sessions.twitter import compose, templates
from wxUI import commonMessageDialogs, menus
from . import base
log = logging.getLogger("controller.buffers.twitter.peopleBuffer")
def _tweets_exist(function):
""" A decorator to execute a function only if the selected buffer contains at least one item."""
def function_(self, *args, **kwargs):
if self.buffer.list.get_count() > 0:
function(self, *args, **kwargs)
return function_
class PeopleBuffer(base.BaseBuffer):
def __init__(self, parent, function, name, sessionObject, account, bufferType=None, *args, **kwargs):
super(PeopleBuffer, self).__init__(parent, function, name, sessionObject, account, bufferType="peoplePanel", *args, **kwargs)
log.debug("Initializing buffer %s, account %s" % (name, account,))
self.compose_function = compose.compose_followers_list
log.debug("Compose_function: %s" % (self.compose_function,))
self.get_tweet = self.get_right_tweet
self.url = self.interact
if "-followers" in self.name or "-friends" in self.name:
self.finished_timeline = False
# Add a compatibility layer for username based timelines from config.
# ToDo: Remove this in some new versions of the client, when user ID timelines become mandatory.
try:
int(self.kwargs["user_id"])
except ValueError:
self.is_screen_name = True
self.kwargs["screen_name"] = self.kwargs["user_id"]
self.kwargs.pop("user_id")
def remove_buffer(self, force=True):
if "-followers" in self.name:
if force == False:
dlg = commonMessageDialogs.remove_buffer()
else:
dlg = widgetUtils.YES
if dlg == widgetUtils.YES:
if self.name[:-10] in self.session.settings["other_buffers"]["followers_timelines"]:
self.session.settings["other_buffers"]["followers_timelines"].remove(self.name[:-10])
if self.name in self.session.db:
self.session.db.pop(self.name)
self.session.settings.write()
return True
elif dlg == widgetUtils.NO:
return False
elif "-friends" in self.name:
if force == False:
dlg = commonMessageDialogs.remove_buffer()
else:
dlg = widgetUtils.YES
if dlg == widgetUtils.YES:
if self.name[:-8] in self.session.settings["other_buffers"]["friends_timelines"]:
self.session.settings["other_buffers"]["friends_timelines"].remove(self.name[:-8])
if self.name in self.session.db:
self.session.db.pop(self.name)
self.session.settings.write()
return True
elif dlg == widgetUtils.NO:
return False
else:
output.speak(_(u"This buffer is not a timeline; it can't be deleted."), True)
return False
def onFocus(self, ev):
pass
def get_message(self):
template = self.session.settings["templates"]["person"]
user = self.get_right_tweet()
t = templates.render_person(user, template, self.session, relative_times=True, offset_seconds=self.session.db["utc_offset"])
return t
def delete_item(self): pass
@_tweets_exist
def reply(self, *args, **kwargs):
tweet = self.get_right_tweet()
screen_name = tweet.screen_name
message = messages.tweet(session=self.session, title=_("Mention"), caption=_("Mention to %s") % (screen_name,), text="@%s " % (screen_name,), thread_mode=False)
if message.message.ShowModal() == widgetUtils.OK:
tweet_data = message.get_tweet_data()
call_threaded(self.session.send_tweet, *tweet_data)
if hasattr(message.message, "destroy"):
message.message.destroy()
def start_stream(self, mandatory=False, play_sound=True, avoid_autoreading=False):
# starts stream every 3 minutes.
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 %s buffer, %s account" % (self.name, self.account,))
log.debug("args: %s, kwargs: %s" % (self.args, self.kwargs))
try:
val = getattr(self.session.twitter, self.function)(return_cursors=True, count=self.session.settings["general"]["max_tweets_per_call"], *self.args, **self.kwargs)
if type(val) == tuple:
val, cursor = val
if type(cursor) == tuple:
cursor = cursor[1]
cursors = self.session.db["cursors"]
cursors[self.name] = cursor
self.session.db["cursors"] = cursors
results = [i for i in val]
val = results
val.reverse()
log.debug("Retrieved %d items from cursored search in function %s" % (len(val), self.function))
except TweepyException as e:
log.exception("Error %s" % (str(e)))
return
number_of_items = self.session.order_people(self.name, val)
log.debug("Number of items retrieved: %d" % (number_of_items,))
self.put_items_on_list(number_of_items)
if hasattr(self, "finished_timeline") and self.finished_timeline == False:
self.username = self.session.api_call("get_user", **self.kwargs).screen_name
self.finished_timeline = True
if number_of_items > 0 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):
try:
cursor = self.session.db["cursors"].get(self.name)
items = getattr(self.session.twitter, self.function)(return_cursors=True, users=True, cursor=cursor, count=self.session.settings["general"]["max_tweets_per_call"], *self.args, **self.kwargs)
if type(items) == tuple:
items, cursor = items
if type(cursor) == tuple:
cursor = cursor[1]
cursors = self.session.db["cursors"]
cursors[self.name] = cursor
self.session.db["cursors"] = cursors
results = [i for i in items]
items = results
log.debug("Retrieved %d items from cursored search in function %s" % (len(items), self.function))
except TweepyException as e:
log.exception("Error %s" % (str(e)))
return
if items == None:
return
items_db = self.session.db[self.name]
for i in items:
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
selected = self.buffer.list.get_selected()
if self.session.settings["general"]["reverse_timelines"] == True:
for i in items:
tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session)
self.buffer.list.insert_item(True, *tweet)
self.buffer.list.select_item(selected)
else:
for i in items:
tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session)
self.buffer.list.insert_item(True, *tweet)
output.speak(_(u"%s items retrieved") % (len(items)), True)
def put_items_on_list(self, number_of_items):
log.debug("The list contains %d items" % (self.buffer.list.get_count(),))
# log.debug("Putting %d items on the list..." % (number_of_items,))
if self.buffer.list.get_count() == 0:
for i in self.session.db[self.name]:
tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session)
self.buffer.list.insert_item(False, *tweet)
self.buffer.set_position(self.session.settings["general"]["reverse_timelines"])
# self.buffer.set_list_position()
elif self.buffer.list.get_count() > 0:
if self.session.settings["general"]["reverse_timelines"] == False:
for i in self.session.db[self.name][len(self.session.db[self.name])-number_of_items:]:
tweet = self.compose_function(i, self.session.db)
self.buffer.list.insert_item(False, *tweet)
else:
items = self.session.db[self.name][0:number_of_items]
items.reverse()
for i in items:
tweet = self.compose_function(i, self.session.db)
self.buffer.list.insert_item(True, *tweet)
log.debug("now the list contains %d items" % (self.buffer.list.get_count(),))
def get_right_tweet(self):
tweet = self.session.db[self.name][self.buffer.list.get_selected()]
return tweet
def add_new_item(self, item):
tweet = self.compose_function(item, self.session.db, self.session.settings["general"]["relative_times"], self.session)
if self.session.settings["general"]["reverse_timelines"] == False:
self.buffer.list.insert_item(False, *tweet)
else:
self.buffer.list.insert_item(True, *tweet)
if 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(" ".join(tweet))
def clear_list(self):
dlg = commonMessageDialogs.clear_list()
if dlg == widgetUtils.YES:
self.session.db[self.name] = []
self.session.db["cursors"][self.name] = -1
self.buffer.list.clear()
def interact(self):
user.profileController(self.session, user=self.get_right_tweet().screen_name)
def show_menu(self, ev, pos=0, *args, **kwargs):
menu = menus.peoplePanelMenu()
widgetUtils.connect_event(menu, widgetUtils.MENU, self.send_message, menuitem=menu.reply)
widgetUtils.connect_event(menu, widgetUtils.MENU, self.user_actions, menuitem=menu.userActions)
widgetUtils.connect_event(menu, widgetUtils.MENU, self.details, menuitem=menu.details)
# widgetUtils.connect_event(menu, widgetUtils.MENU, self.lists, menuitem=menu.lists)
widgetUtils.connect_event(menu, widgetUtils.MENU, self.view, menuitem=menu.view)
widgetUtils.connect_event(menu, widgetUtils.MENU, self.copy, menuitem=menu.copy)
if hasattr(menu, "openInBrowser"):
widgetUtils.connect_event(menu, widgetUtils.MENU, self.open_in_browser, menuitem=menu.openInBrowser)
if pos != 0:
self.buffer.PopupMenu(menu, pos)
else:
self.buffer.PopupMenu(menu, ev.GetPosition())
def details(self, *args, **kwargs):
pub.sendMessage("execute-action", action="user_details")
def auto_read(self, number_of_items):
if 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:
if self.session.settings["general"]["reverse_timelines"] == False:
tweet = self.session.db[self.name][-1]
else:
tweet = self.session.db[self.name][0]
output.speak(" ".join(self.compose_function(tweet, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session)))
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(_(u"{0} new followers.").format(number_of_items))
def get_item_url(self, *args, **kwargs):
tweet = self.get_tweet()
url = "https://twitter.com/{screen_name}".format(screen_name=tweet.screen_name)
return url
def view_item(self):
item_url = self.get_item_url()
non_tweet = self.get_formatted_message()
msg = messages.viewTweet(non_tweet, [], False, item_url=item_url)

View File

@@ -1,187 +0,0 @@
# -*- coding: utf-8 -*-
import time
import locale
import widgetUtils
import logging
from tweepy.errors import TweepyException
from wxUI import commonMessageDialogs
from . import base, people
log = logging.getLogger("controller.buffers.twitter.searchBuffer")
class SearchBuffer(base.BaseBuffer):
def remove_buffer(self, force=False):
if force == False:
dlg = commonMessageDialogs.remove_buffer()
else:
dlg = widgetUtils.YES
if dlg == widgetUtils.YES:
if self.name[:-11] in self.session.settings["other_buffers"]["tweet_searches"]:
self.session.settings["other_buffers"]["tweet_searches"].remove(self.name[:-11])
self.session.settings.write()
if self.name in self.session.db:
self.session.db.pop(self.name)
return True
elif dlg == widgetUtils.NO:
return False
class SearchPeopleBuffer(people.PeopleBuffer):
""" This is identical to a normal peopleBufferController, except that uses the page parameter instead of a cursor."""
def __init__(self, parent, function, name, sessionObject, account, bufferType="peoplePanel", *args, **kwargs):
super(SearchPeopleBuffer, self).__init__(parent, function, name, sessionObject, account, bufferType="peoplePanel", *args, **kwargs)
if ("page" in self.kwargs) == False:
self.page = 1
else:
self.page = self.kwargs.pop("page")
def get_more_items(self, *args, **kwargs):
# Add 1 to the page parameter, put it in kwargs and calls to get_more_items in the parent buffer.
self.page = self.page +1
self.kwargs["page"] = self.page
super(SearchPeopleBuffer, self).get_more_items(*args, **kwargs)
# remove the parameter again to make sure start_stream won't fetch items for this page indefinitely.
self.kwargs.pop("page")
def remove_buffer(self, force=False):
if force == False:
dlg = commonMessageDialogs.remove_buffer()
else:
dlg = widgetUtils.YES
if dlg == widgetUtils.YES:
if self.name[:-11] in self.session.settings["other_buffers"]["tweet_searches"]:
self.session.settings["other_buffers"]["tweet_searches"].remove(self.name[:-11])
self.session.settings.write()
if self.name in self.session.db:
self.session.db.pop(self.name)
return True
elif dlg == widgetUtils.NO:
return False
class ConversationBuffer(SearchBuffer):
last_thread_id = None
last_reply_id = None
def __init__(self, tweet, *args, **kwargs):
self.tweet = tweet
super(ConversationBuffer, self).__init__(*args, **kwargs)
def start_stream(self, start=False, 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("Retrieving conversation. Last thread ID is {}, last reply ID is {}".format(self.last_thread_id, self.last_reply_id))
results = self.get_replies(self.tweet)
log.debug("Retrieved {} items before filters.".format(len(results)))
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.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 remove_buffer(self, force=False):
if force == False:
dlg = commonMessageDialogs.remove_buffer()
else:
dlg = widgetUtils.YES
if dlg == widgetUtils.YES:
if self.name in self.session.db:
self.session.db.pop(self.name)
return True
elif dlg == widgetUtils.NO:
return False
def get_replies(self, tweet):
""" Try to retrieve the whole conversation for the passed object by using a mix between calls to API V1.1 and V2 """
# firstly we would try to retrieve the whole thread, then we will get replies.
# this makes us to waste two search API calls, but there's no better option to retrieve the whole thread including replies, unfortunately.
thread_results = []
reply_results = []
# try to fetch conversation_id of the tweet initiating the buffer.
try:
tweet = self.session.twitter_v2.get_tweet(id=self.tweet.id, user_auth=True, tweet_fields=["conversation_id", "author_id"])
thread_results.append(tweet.data)
except TweepyException as e:
log.exception("Error attempting to retrieve tweet conversation ID")
thread_results.append(self.tweet)
# Return earlier cause we can't do anything if we cannot fetch the object from twitter.
return thread_results
# If tweet contains a conversation_id param, let's retrieve the original tweet which started the conversation so we will have the whole reference for later.
if hasattr(tweet.data, "conversation_id") and tweet.data.conversation_id != None:
conversation_id = tweet.data.conversation_id
original_tweet = self.session.twitter_v2.get_tweet(id=tweet.data.conversation_id, user_auth=True, tweet_fields=["conversation_id", "author_id"])
thread_results.insert(0, original_tweet.data)
else:
conversation_id = tweet.data.id
# find all tweets replying to the original thread only. Those tweets are sent by the same author who originally posted the first tweet.
try:
term = "conversation_id:{} from:{} to:{}".format(conversation_id, original_tweet.data.author_id, original_tweet.data.author_id)
thread_tweets = self.session.twitter_v2.search_recent_tweets(term, user_auth=True, max_results=98, since_id=self.last_thread_id, tweet_fields=["in_reply_to_user_id", "author_id", "conversation_id"])
if thread_tweets.data != None:
thread_results.extend(thread_tweets.data)
# Search only replies to conversation_id.
term = "conversation_id:{}".format(conversation_id, original_tweet.data.author_id)
reply_tweets = self.session.twitter_v2.search_recent_tweets(term, user_auth=True, max_results=50, since_id=self.last_reply_id, tweet_fields=["in_reply_to_user_id", "author_id", "conversation_id"])
if reply_tweets.data != None:
reply_results.extend(reply_tweets.data)
except TweepyException as e:
log.exception("There was an error when attempting to retrieve the whole conversation for buffer {}".format(self.buffer.name))
# convert v2 tweets in normal, V1.1 tweets so we don't have to deal with those kind of objects in our infrastructure.
# ToDo: Remove this last step once we support natively all objects fetched via Twitter API V2.
results = []
ids = [tweet.id for tweet in thread_results]
if len(ids) > 0:
try:
thread_results = self.session.twitter.lookup_statuses(ids, include_ext_alt_text=True, tweet_mode="extended")
thread_results.sort(key=lambda x: x.id)
self.last_thread_id = thread_results[-1].id
results.extend(thread_results)
except TweepyException as e:
log.exception("There was an error attempting to retrieve tweets for Twitter API V1.1, in conversation buffer {}".format(self.name))
return []
ids = [tweet.id for tweet in reply_results]
if len(ids) > 0:
try:
reply_results = self.session.twitter.lookup_statuses(ids, include_ext_alt_text=True, tweet_mode="extended")
reply_results.sort(key=lambda x: x.id)
self.last_reply_id = reply_results[-1].id
results.extend(reply_results)
except TweepyException as e:
log.exception("There was an error attempting to retrieve tweets for Twitter API V1.1, in conversation buffer {}".format(self.name))
results.sort(key=lambda x: x.id)
return results
def get_replies_v1(self, tweet):
try:
tweet = self.session.twitter.get_status(id=tweet.id, tweet_mode="extended")
except:
log.exception("Error getting tweet for making a conversation buffer.")
return []
results = []
results.append(tweet)
if hasattr(tweet, "in_reply_to_status_id") and tweet.in_reply_to_status_id != None:
while tweet.in_reply_to_status_id != None:
original_tweet = self.session.twitter.get_status(id=tweet.in_reply_to_status_id, tweet_mode="extended")
results.insert(0, original_tweet)
tweet = original_tweet
try:
term = "from:{} to:{}".format(tweet.user.screen_name, tweet.user.screen_name)
thread_tweets = self.session.twitter.search_tweets(term, count=100, since_id=tweet.id, tweet_mode="extended")
results.extend(thread_tweets)
except TweepyException as e:
log.exception("There was an error when attempting to retrieve the whole conversation for buffer {}".format(self.buffer.name))
try:
term = "to:{}".format(tweet.user.screen_name)
reply_tweets = self.session.twitter.search_tweets(term, count=100, since_id=tweet.id, tweet_mode="extended")
ids = [t.id for t in results]
reply_tweets = [t for t in reply_tweets if hasattr(t, "in_reply_to_status_id") and t.in_reply_to_status_id in ids]
results.extend(reply_tweets)
except TweepyException as e:
log.exception("There was an error when attempting to retrieve the whole conversation for buffer {}".format(self.buffer.name))
results.sort(key=lambda x: x.id)
return results

View File

@@ -1,144 +0,0 @@
# -*- coding: utf-8 -*-
import time
import wx
import widgetUtils
import output
import logging
from mysc.thread_utils import call_threaded
from tweepy.errors import TweepyException
from pubsub import pub
from wxUI import buffers, commonMessageDialogs, menus
from controller.twitter import user, messages
from controller.buffers import base
log = logging.getLogger("controller.buffers.twitter.trends")
class TrendsBuffer(base.Buffer):
def __init__(self, parent, name, sessionObject, account, trendsFor, *args, **kwargs):
super(TrendsBuffer, self).__init__(parent=parent, sessionObject=sessionObject)
self.trendsFor = trendsFor
self.session = sessionObject
self.account = account
self.invisible = True
self.buffer = buffers.twitter.trendsPanel(parent, name)
self.buffer.account = account
self.type = self.buffer.type
self.bind_events()
self.sound = "trends_updated.ogg"
self.trends = []
self.name = name
self.buffer.name = name
self.compose_function = self.compose_function_
self.get_formatted_message = self.get_message
self.reply = self.search_topic
def post_status(self, *args, **kwargs):
title = _("Tweet")
caption = _("Write the tweet here")
tweet = messages.tweet(self.session, title, caption, "")
response = tweet.message.ShowModal()
if response == wx.ID_OK:
tweet_data = tweet.get_tweet_data()
call_threaded(self.session.send_tweet, *tweet_data)
if hasattr(tweet.message, "destroy"):
tweet.message.destroy()
def start_stream(self, mandatory=False, play_sound=True, avoid_autoreading=False):
# starts stream every 3 minutes.
current_time = time.time()
if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory == True:
self.execution_time = current_time
try:
data = self.session.twitter.get_place_trends(id=self.trendsFor)
except TweepyException as err:
log.exception("Error %s" % (str(err)))
if not hasattr(self, "name_"):
self.name_ = data[0]["locations"][0]["name"]
pub.sendMessage("buffer-title-changed", buffer=self)
self.trends = data[0]["trends"]
self.put_items_on_the_list()
if 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)
def put_items_on_the_list(self):
selected_item = self.buffer.list.get_selected()
self.buffer.list.clear()
for i in self.trends:
tweet = self.compose_function(i)
self.buffer.list.insert_item(False, *tweet)
self.buffer.set_position(self.session.settings["general"]["reverse_timelines"])
def compose_function_(self, trend):
return [trend["name"]]
def bind_events(self):
log.debug("Binding events...")
self.buffer.list.list.Bind(wx.EVT_CHAR_HOOK, self.get_event)
widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.tweet_about_this_trend, self.buffer.tweetTrendBtn)
widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.post_status, self.buffer.tweet)
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)
widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.search_topic, self.buffer.search_topic)
def get_message(self):
return self.compose_function(self.trends[self.buffer.list.get_selected()])[0]
def remove_buffer(self, force=False):
if force == False:
dlg = commonMessageDialogs.remove_buffer()
else:
dlg = widgetUtils.YES
if dlg == widgetUtils.YES:
if self.name[:-3] in self.session.settings["other_buffers"]["trending_topic_buffers"]:
self.session.settings["other_buffers"]["trending_topic_buffers"].remove(self.name[:-3])
self.session.settings.write()
if self.name in self.session.db:
self.session.db.pop(self.name)
return True
elif dlg == widgetUtils.NO:
return False
def url(self, *args, **kwargs):
self.tweet_about_this_trend()
def search_topic(self, *args, **kwargs):
topic = self.trends[self.buffer.list.get_selected()]["name"]
pub.sendMessage("search", term=topic)
def show_menu(self, ev, pos=0, *args, **kwargs):
menu = menus.trendsPanelMenu()
widgetUtils.connect_event(menu, widgetUtils.MENU, self.search_topic, menuitem=menu.search_topic)
widgetUtils.connect_event(menu, widgetUtils.MENU, self.tweet_about_this_trend, menuitem=menu.tweetThisTrend)
widgetUtils.connect_event(menu, widgetUtils.MENU, self.view, menuitem=menu.view)
widgetUtils.connect_event(menu, widgetUtils.MENU, self.copy, menuitem=menu.copy)
if pos != 0:
self.buffer.PopupMenu(menu, pos)
else:
self.buffer.PopupMenu(menu, ev.GetPosition())
def view(self, *args, **kwargs):
pub.sendMessage("execute-action", action="view_item")
def copy(self, *args, **kwargs):
pub.sendMessage("execute-action", action="copy_to_clipboard")
def tweet_about_this_trend(self, *args, **kwargs):
if self.buffer.list.get_count() == 0: return
title = _("Tweet")
caption = _("Write the tweet here")
tweet = messages.tweet(session=self.session, title=title, caption=caption, text=self.get_message()+ " ")
tweet.message.SetInsertionPoint(len(tweet.message.GetValue()))
if tweet.message.ShowModal() == widgetUtils.OK:
tweet_data = tweet.get_tweet_data()
call_threaded(self.session.send_tweet, *tweet_data)
if hasattr(tweet.message, "destroy"): tweet.message.destroy()
def show_menu_by_key(self, ev):
if self.buffer.list.get_count() == 0:
return
if ev.GetKeyCode() == wx.WXK_WINDOWS_MENU:
self.show_menu(widgetUtils.MENU, pos=self.buffer.list.list.GetPosition())
def open_in_browser(self, *args, **kwargs):
output.speak(_(u"This action is not supported in the buffer, yet."))

View File

@@ -13,8 +13,6 @@ import application
import sound
import output
from pubsub import pub
from tweepy.errors import TweepyException, Forbidden
from geopy.geocoders import Nominatim
from extra import SoundsTutorial
from update import updater
from wxUI import view, dialogs, commonMessageDialogs, sysTrayIcon
@@ -25,14 +23,11 @@ from mysc import restart
from mysc import localization
from mysc.thread_utils import call_threaded
from mysc.repeating_timer import RepeatingTimer
from controller.twitter import handler as TwitterHandler
from controller.mastodon import handler as MastodonHandler
from . import settings, userAlias
log = logging.getLogger("mainController")
geocoder = Nominatim(user_agent="TWBlue")
class Controller(object):
""" Main Controller for TWBlue. It manages the main window and sessions."""
@@ -111,34 +106,17 @@ class Controller(object):
pub.subscribe(self.invisible_shorcuts_changed, "invisible-shorcuts-changed")
pub.subscribe(self.create_account_buffer, "core.create_account")
# Twitter specific events.
pub.subscribe(self.buffer_title_changed, "buffer-title-changed")
pub.subscribe(self.manage_sent_dm, "twitter.sent_dm")
pub.subscribe(self.update_sent_dms, "twitter.sent_dms_updated")
pub.subscribe(self.more_dms, "twitter.more_sent_dms")
pub.subscribe(self.manage_sent_tweets, "twitter.sent_tweet")
pub.subscribe(self.manage_new_tweet, "twitter.new_tweet")
pub.subscribe(self.manage_friend, "twitter.friend")
pub.subscribe(self.manage_unfollowing, "twitter.unfollowing")
pub.subscribe(self.manage_favourite, "twitter.favourite")
pub.subscribe(self.manage_unfavourite, "twitter.unfavourite")
pub.subscribe(self.manage_blocked_user, "twitter.blocked_user")
pub.subscribe(self.manage_unblocked_user, "twitter.unblocked_user")
pub.subscribe(self.restart_streaming, "twitter.restart_streaming")
# Mastodon specific events.
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)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.search, menuitem=self.view.menuitem_search)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.list_manager, menuitem=self.view.lists)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.get_trending_topics, menuitem=self.view.trends)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.filter, menuitem=self.view.filter)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.manage_filters, menuitem=self.view.manage_filters)
# widgetUtils.connect_event(self.view, widgetUtils.MENU, self.list_manager, menuitem=self.view.lists)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.find, menuitem=self.view.find)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.accountConfiguration, menuitem=self.view.account_settings)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.configuration, menuitem=self.view.prefs)
@@ -156,13 +134,10 @@ class Controller(object):
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.add_to_favourites, self.view.fav)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.remove_from_favourites, self.view.unfav)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.view_item, self.view.view)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.view_reverse_geocode, menuitem=self.view.view_coordinates)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.delete, self.view.delete)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.follow, menuitem=self.view.follow)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.send_dm, self.view.dm)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.view_user_lists, menuitem=self.view.viewLists)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.get_more_items, menuitem=self.view.load_previous_items)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.view_user_lists, menuitem=self.view.viewLists)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.clear_buffer, menuitem=self.view.clear)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.remove_buffer, self.view.deleteTl)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.check_for_updates, self.view.check_for_updates)
@@ -170,8 +145,6 @@ class Controller(object):
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.visit_website, menuitem=self.view.visit_website)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.get_soundpacks, menuitem=self.view.get_soundpacks)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.manage_accounts, self.view.manage_accounts)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.update_profile, menuitem=self.view.updateProfile)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.user_details, menuitem=self.view.details)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.toggle_autoread, menuitem=self.view.autoread)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.toggle_buffer_mute, self.view.mute_buffer)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.open_timeline, self.view.timeline)
@@ -183,19 +156,16 @@ class Controller(object):
widgetUtils.connect_event(self.view.nb, widgetUtils.NOTEBOOK_PAGE_CHANGED, self.buffer_changed)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.view_documentation, self.view.doc)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.view_changelog, self.view.changelog)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.add_alias, self.view.addAlias)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.add_to_list, self.view.addToList)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.remove_from_list, self.view.removeFromList)
# widgetUtils.connect_event(self.view, widgetUtils.MENU, self.add_alias, self.view.addAlias)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.update_buffer, self.view.update_buffer)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.manage_aliases, self.view.manageAliases)
# widgetUtils.connect_event(self.view, widgetUtils.MENU, self.manage_aliases, self.view.manageAliases)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.report_error, self.view.reportError)
def set_systray_icon(self):
self.systrayIcon = sysTrayIcon.SysTrayIcon()
widgetUtils.connect_event(self.systrayIcon, widgetUtils.MENU, self.post_tweet, menuitem=self.systrayIcon.tweet)
widgetUtils.connect_event(self.systrayIcon, widgetUtils.MENU, self.post_tweet, menuitem=self.systrayIcon.post)
widgetUtils.connect_event(self.systrayIcon, widgetUtils.MENU, self.configuration, menuitem=self.systrayIcon.global_settings)
widgetUtils.connect_event(self.systrayIcon, widgetUtils.MENU, self.accountConfiguration, menuitem=self.systrayIcon.account_settings)
widgetUtils.connect_event(self.systrayIcon, widgetUtils.MENU, self.update_profile, menuitem=self.systrayIcon.update_profile)
widgetUtils.connect_event(self.systrayIcon, widgetUtils.MENU, self.show_hide, menuitem=self.systrayIcon.show_hide)
widgetUtils.connect_event(self.systrayIcon, widgetUtils.MENU, self.check_for_updates, menuitem=self.systrayIcon.check_for_updates)
widgetUtils.connect_event(self.systrayIcon, widgetUtils.MENU, self.view_documentation, menuitem=self.systrayIcon.doc)
@@ -215,9 +185,7 @@ class Controller(object):
def get_handler(self, type):
handler = self.handlers.get(type)
if handler == None:
if type == "twitter":
handler = TwitterHandler.Handler()
elif type == "mastodon":
if type == "mastodon":
handler = MastodonHandler.Handler()
self.handlers[type]=handler
return handler
@@ -262,9 +230,9 @@ class Controller(object):
if sessions.sessions[i].is_logged == False:
self.create_ignored_session_buffer(sessions.sessions[i])
continue
# Valid types currently are twitter and mastodon (Work in progress)
# Valid types currently are mastodon (Work in progress)
# More can be added later.
valid_session_types = ["twitter", "mastodon"]
valid_session_types = ["mastodon"]
if sessions.sessions[i].type in valid_session_types:
handler = self.get_handler(type=sessions.sessions[i].type)
handler.create_buffers(sessions.sessions[i], controller=self)
@@ -285,8 +253,6 @@ class Controller(object):
if config.app["app-settings"]["speak_ready_msg"] == True:
output.speak(_(u"Ready"))
self.started = True
self.streams_checker_function = RepeatingTimer(60, self.check_streams)
self.streams_checker_function.start()
if len(self.accounts) > 0:
b = self.get_first_buffer(self.accounts[0])
self.update_menus(handler=self.get_handler(b.session.type))
@@ -406,21 +372,6 @@ class Controller(object):
return output.speak(page.get_message(), True)
output.speak(_(u"{0} not found.").format(string,), True)
def filter(self, *args, **kwargs):
buffer = self.get_current_buffer()
if not hasattr(buffer.buffer, "list"):
output.speak(_(u"No session is currently in focus. Focus a session with the next or previous session shortcut."), True)
return
handler = self.get_handler(type=buffer.session.type)
if handler != None and hasattr(handler, "filter"):
return handler.filter(buffer=buffer)
def manage_filters(self, *args, **kwargs):
buffer = self.get_best_buffer()
handler = self.get_handler(type=buffer.session.type)
if handler != None and hasattr(handler, "manage_filters"):
return handler.manage_filters(session=buffer.session)
def seekLeft(self, *args, **kwargs):
try:
sound.URLPlayer.seek(-5000)
@@ -457,31 +408,6 @@ class Controller(object):
buffer = self.get_best_buffer()
SoundsTutorial.soundsTutorial(buffer.session)
def view_user_lists(self, *args, **kwargs):
buffer = self.get_best_buffer()
handler = self.get_handler(type=buffer.session.type)
if handler != None and hasattr(handler, "view_user_lists"):
return handler.view_user_lists(buffer=buffer)
def add_to_list(self, *args, **kwargs):
buffer = self.get_best_buffer()
handler = self.get_handler(type=buffer.session.type)
if handler != None and hasattr(handler, "add_to_list"):
return handler.add_to_list(controller=self, buffer=buffer)
def remove_from_list(self, *args, **kwargs):
buffer = self.get_best_buffer()
handler = self.get_handler(type=buffer.session.type)
if handler != None and hasattr(handler, "remove_from_list"):
return handler.remove_from_list(controller=self, buffer=buffer)
def list_manager(self, *args, **kwargs):
buffer = self.get_best_buffer()
handler = self.get_handler(type=buffer.session.type)
if handler != None and hasattr(handler, "list_manager"):
lists_buffer_position = self.view.search("lists", buffer.session.get_name())
return handler.list_manager(session=buffer.session, lists_buffer_position=lists_buffer_position)
def configuration(self, *args, **kwargs):
""" Opens the global settings dialogue."""
d = settings.globalSettingsController()
@@ -527,10 +453,6 @@ class Controller(object):
for item in sessions.sessions:
if sessions.sessions[item].logged == False:
continue
if hasattr(sessions.sessions[item], "stop_streaming"):
log.debug("Disconnecting streaming endpoint for session" + sessions.sessions[item].session_id)
sessions.sessions[item].stop_streaming()
log.debug("Disconnecting streams for %s session" % (sessions.sessions[item].session_id,))
sessions.sessions[item].sound.cleaner.cancel()
log.debug("Saving database for " + sessions.sessions[item].session_id)
sessions.sessions[item].save_persistent_data()
@@ -538,9 +460,6 @@ class Controller(object):
pidpath = os.path.join(os.getenv("temp"), "{}.pid".format(application.name))
if os.path.exists(pidpath):
os.remove(pidpath)
if hasattr(self, "streams_checker_function"):
log.debug("Stopping stream checker...")
self.streams_checker_function.cancel()
widgetUtils.exit_application()
def follow(self, *args, **kwargs):
@@ -642,19 +561,6 @@ class Controller(object):
self.view.Show()
self.showing = True
def get_trending_topics(self, *args, **kwargs):
buffer = self.get_best_buffer()
handler = self.get_handler(type=buffer.session.type)
if handler != None and hasattr(handler, "get_trending_topics"):
return handler.get_trending_topics(controller=self, session=buffer.session)
def view_reverse_geocode(self, event=None):
buffer = self.get_current_buffer()
if hasattr(buffer, "reverse_geocode"):
address = buffer.reverse_geocode()
if address != None:
dlg = commonMessageDialogs.view_geodata(address[0].__str__())
def get_more_items(self, *args, **kwargs):
buffer = self.get_current_buffer()
if hasattr(buffer, "get_more_items"):
@@ -953,70 +859,6 @@ class Controller(object):
if message != None:
output.speak(message, speech=session.settings["reporting"]["speech_reporting"], braille=session.settings["reporting"]["braille_reporting"])
def manage_sent_dm(self, data, session_name):
buffer = self.search_buffer("sent_direct_messages", session_name)
if buffer == None:
return
play_sound = "dm_sent.ogg"
if "sent_direct_messages" not in buffer.session.settings["other_buffers"]["muted_buffers"]:
self.notify(buffer.session, play_sound=play_sound)
buffer.add_new_item(data)
def manage_sent_tweets(self, data, session_name):
buffer = self.search_buffer("sent_tweets", session_name)
if buffer == None:
return
data = buffer.session.check_quoted_status(data)
data = buffer.session.check_long_tweet(data)
if data == False: # Long tweet deleted from twishort.
return
items = buffer.session.db[buffer.name]
if buffer.session.settings["general"]["reverse_timelines"] == False:
items.append(data)
else:
items.insert(0, data)
buffer.session.db[buffer.name] = items
buffer.add_new_item(data)
def manage_friend(self, data, session_name):
buffer = self.search_buffer("friends", session_name)
if buffer == None:
return
buffer.add_new_item(data)
def manage_unfollowing(self, item, session_name):
buffer = self.search_buffer("friends", session_name)
if buffer == None:
return
buffer.remove_item(item)
def manage_favourite(self, data, session_name):
buffer = self.search_buffer("favourites", session_name)
if buffer == None:
return
play_sound = "favourite.ogg"
if "favourites" not in buffer.session.settings["other_buffers"]["muted_buffers"]:
self.notify(buffer.session, play_sound=play_sound)
buffer.add_new_item(data)
def manage_unfavourite(self, item, session_name):
buffer = self.search_buffer("favourites", session_name)
if buffer == None:
return
buffer.remove_item(item)
def manage_blocked_user(self, data, session_name):
buffer = self.search_buffer("blocked", session_name)
if buffer == None:
return
buffer.add_new_item(data)
def manage_unblocked_user(self, item, session_name):
buffer = self.search_buffer("blocked", session_name)
if buffer == None:
return
buffer.remove_item(item)
def start_buffers(self, session):
log.debug("starting buffers... Session %s" % (session.session_id,))
handler = self.get_handler(type=session.type)
@@ -1028,17 +870,6 @@ class Controller(object):
for i in sessions.sessions:
self.set_buffer_positions(i)
def check_connection(self):
if self.started == False:
return
for i in sessions.sessions:
try:
if sessions.sessions[i].is_logged == False:
continue
sessions.sessions[i].check_connection()
except: # We shouldn't allow this function to die.
pass
def invisible_shorcuts_changed(self, registered):
if registered == True:
km = self.create_invisible_keyboard_shorcuts()
@@ -1099,17 +930,6 @@ class Controller(object):
self.accounts.remove(sessions.sessions[i].get_name())
sessions.sessions.pop(i)
def update_profile(self, *args, **kwargs):
buffer = self.get_best_buffer()
handler = self.get_handler(type=buffer.session.type)
if hasattr(handler, "update_profile"):
return handler.update_profile(session=buffer.session)
def user_details(self, *args, **kwargs):
buffer = self.get_current_buffer()
if hasattr(buffer, "user_details"):
buffer.user_details()
def toggle_autoread(self, *args, **kwargs):
buffer = self.get_current_buffer()
if hasattr(buffer, "session") and buffer.session == None:
@@ -1174,16 +994,6 @@ class Controller(object):
i.start_stream(mandatory=True)
except Exception as err:
log.exception("Error %s starting buffer %s on account %s, with args %r and kwargs %r." % (str(err), i.name, i.account, i.args, i.kwargs))
# Determine if this error was caused by a block applied to the current user (IE permission errors).
if type(err) == Forbidden:
buff = self.view.search(i.name, i.account)
i.remove_buffer(force=True)
commonMessageDialogs.blocked_timeline()
if self.get_current_buffer() == i:
self.right()
self.view.delete_buffer(buff)
self.buffers.remove(i)
del i
def update_buffer(self, *args, **kwargs):
bf = self.get_current_buffer()
@@ -1198,16 +1008,12 @@ class Controller(object):
def buffer_title_changed(self, buffer):
if buffer.name.endswith("-timeline"):
title = _(u"Timeline for {}").format(buffer.username,)
elif buffer.name.endswith("-favorite"):
title = _(u"Likes for {}").format(buffer.username,)
elif buffer.name.endswith("-followers"):
title = _(u"Followers for {}").format(buffer.username,)
elif buffer.name.endswith("-friends"):
title = _(u"Friends for {}").format(buffer.username,)
elif buffer.name.endswith("-following"):
title = _(u"Following for {}").format(buffer.username,)
elif buffer.name.endswith("_tt"):
title = _("Trending topics for %s") % (buffer.name_)
buffer_index = self.view.search(buffer.name, buffer.account)
self.view.set_page_title(buffer_index, title)
@@ -1216,55 +1022,13 @@ class Controller(object):
if hasattr(buffer, "ocr_image"):
return buffer.ocr_image()
def update_sent_dms(self, total, session_name):
sent_dms = self.search_buffer("sent_direct_messages", session_name)
if sent_dms != None:
sent_dms.put_items_on_list(total)
def more_dms(self, data, account):
sent_dms = self.search_buffer("sent_direct_messages", account)
if sent_dms != None:
sent_dms.put_more_items(data)
def save_data_in_db(self):
for i in sessions.sessions:
sessions.sessions[i].save_persistent_data()
def manage_new_tweet(self, data, session_name, _buffers):
sound_to_play = None
for buff in _buffers:
buffer = self.search_buffer(buff, session_name)
if buffer == None or buffer.session.get_name() != session_name:
return
buffer.add_new_item(data)
if buff == "home_timeline": sound_to_play = "tweet_received.ogg"
elif buff == "mentions": sound_to_play = "mention_received.ogg"
elif buff == "sent_tweets": sound_to_play = "tweet_send.ogg"
elif "timeline" in buff: sound_to_play = "tweet_timeline.ogg"
else: sound_to_play = None
if sound_to_play != None and buff not in buffer.session.settings["other_buffers"]["muted_buffers"]:
self.notify(buffer.session, sound_to_play)
def toggle_share_settings(self, shareable=True):
self.view.share.Enable(shareable)
def check_streams(self):
if self.started == False:
return
for i in sessions.sessions:
try:
if sessions.sessions[i].is_logged == False: continue
sessions.sessions[i].check_streams()
except TweepyException: # We shouldn't allow this function to die.
pass
def restart_streaming(self, session):
for s in sessions.sessions:
if sessions.sessions[s].session_id == session:
log.debug("Restarting stream in session %s" % (session))
sessions.sessions[s].stop_streaming()
sessions.sessions[s].start_streaming()
def mastodon_new_item(self, item, session_name, _buffers):
sound_to_play = None
for buff in _buffers:
@@ -1308,7 +1072,8 @@ class Controller(object):
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)
if home != None:
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"""

View File

@@ -3,11 +3,9 @@ import wx
import logging
from pubsub import pub
from mysc import restart
from wxUI.dialogs.mastodon import dialogs
from wxUI.dialogs.mastodon import search as search_dialogs
from wxUI.dialogs.mastodon import dialogs
from wxUI import commonMessageDialogs
from sessions.twitter import utils
from . import userActions, settings
log = logging.getLogger("controller.mastodon.handler")

View File

@@ -6,7 +6,7 @@ import widgetUtils
import config
import output
from twitter_text import parse_tweet, config
from controller.twitter import messages
from controller import messages
from sessions.mastodon import templates
from wxUI.dialogs.mastodon import postDialogs
@@ -23,7 +23,7 @@ def character_count(post_text, post_cw, character_limit=500):
parsed = parse_tweet(full_text, options=options)
return parsed.weightedLength
class post(messages.basicTweet):
class post(messages.basicMessage):
def __init__(self, session, title, caption, text="", *args, **kwargs):
# take max character limit from session as this might be different for some instances.
self.max = session.char_limit

View File

@@ -9,7 +9,7 @@ import output
from collections import OrderedDict
from wxUI import commonMessageDialogs
from wxUI.dialogs.mastodon import configuration
from extra.autocompletionUsers import scan, manage
#from extra.autocompletionUsers import scan, manage
from extra.ocr import OCRSpace
from controller.settings import globalSettingsController
from . templateEditor import EditTemplate

View File

@@ -3,7 +3,7 @@ import re
import wx
from typing import List
from sessions.mastodon.templates import post_variables, conversation_variables, person_variables
from wxUI.dialogs.twitterDialogs import templateDialogs
from wxUI.dialogs import templateDialogs
class EditTemplate(object):
def __init__(self, template: str, type: str) -> None:

View File

@@ -6,7 +6,7 @@ from wxUI.dialogs.mastodon import userActions as userActionsDialog
from wxUI.dialogs.mastodon import userTimeline as userTimelineDialog
from pubsub import pub
from mastodon import MastodonError, MastodonNotFoundError
from extra.autocompletionUsers import completion
#from extra.autocompletionUsers import completion
log = logging.getLogger("controller.mastodon.userActions")

View File

@@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
import widgetUtils
import output
from extra import translator, SpellChecker
class basicMessage(object):
def translate(self, event=None):
dlg = translator.gui.translateDialog()
if dlg.get_response() == widgetUtils.OK:
text_to_translate = self.message.text.GetValue()
language_dict = translator.translator.available_languages()
for k in language_dict:
if language_dict[k] == dlg.dest_lang.GetStringSelection():
dst = k
msg = translator.translator.translate(text=text_to_translate, target=dst)
self.message.text.ChangeValue(msg)
self.message.text.SetInsertionPoint(len(self.message.text.GetValue()))
self.text_processor()
self.message.text.SetFocus()
output.speak(_(u"Translated"))
else:
return
def text_processor(self, *args, **kwargs):
pass
def spellcheck(self, event=None):
text = self.message.text.GetValue()
checker = SpellChecker.spellchecker.spellChecker(text, "")
if hasattr(checker, "fixed_text"):
self.message.text.ChangeValue(checker.fixed_text)
self.text_processor()
self.message.text.SetFocus()
def remove_attachment(self, *args, **kwargs):
attachment = self.message.attachments.GetFocusedItem()
if attachment > -1 and len(self.attachments) > attachment:
self.attachments.pop(attachment)
self.message.remove_item(list_type="attachment")
self.text_processor()
self.message.text.SetFocus()

View File

@@ -1 +0,0 @@
# -*- coding: utf-8 -*-

View File

@@ -1,76 +0,0 @@
# -*- coding: utf-8 -*-
import time
import widgetUtils
import application
from wxUI.dialogs import filterDialogs
from wxUI import commonMessageDialogs
class filter(object):
def __init__(self, buffer, filter_title=None, if_word_exists=None, in_lang=None, regexp=None, word=None, in_buffer=None):
self.buffer = buffer
self.dialog = filterDialogs.filterDialog(languages=[i["name"] for i in application.supported_languages])
if self.dialog.get_response() == widgetUtils.OK:
title = self.dialog.get("title")
contains = self.dialog.get("contains")
term = self.dialog.get("term")
regexp = self.dialog.get("regexp")
allow_rts = self.dialog.get("allow_rts")
allow_quotes = self.dialog.get("allow_quotes")
allow_replies = self.dialog.get("allow_replies")
load_language = self.dialog.get("load_language")
ignore_language = self.dialog.get("ignore_language")
lang_option = None
if ignore_language:
lang_option = False
elif load_language:
lang_option = True
langs = self.dialog.get_selected_langs()
langcodes = []
for i in application.supported_languages:
if i["name"] in langs:
langcodes.append(i["code"])
d = dict(in_buffer=self.buffer.name, word=term, regexp=regexp, in_lang=lang_option, languages=langcodes, if_word_exists=contains, allow_rts=allow_rts, allow_quotes=allow_quotes, allow_replies=allow_replies)
if title in self.buffer.session.settings["filters"]:
return commonMessageDialogs.existing_filter()
self.buffer.session.settings["filters"][title] = d
self.buffer.session.settings.write()
class filterManager(object):
def __init__(self, session):
self.session = session
self.dialog = filterDialogs.filterManagerDialog()
self.insert_filters(self.session.settings["filters"])
if self.dialog.filters.get_count() == 0:
self.dialog.edit.Enable(False)
self.dialog.delete.Enable(False)
else:
widgetUtils.connect_event(self.dialog.edit, widgetUtils.BUTTON_PRESSED, self.edit_filter)
widgetUtils.connect_event(self.dialog.delete, widgetUtils.BUTTON_PRESSED, self.delete_filter)
response = self.dialog.get_response()
def insert_filters(self, filters):
self.dialog.filters.clear()
for f in list(filters.keys()):
filterName = f
buffer = filters[f]["in_buffer"]
if filters[f]["if_word_exists"] == "True" and filters[f]["word"] != "":
filter_by_word = "True"
else:
filter_by_word = "False"
filter_by_lang = ""
if filters[f]["in_lang"] != "None":
filter_by_lang = "True"
b = [f, buffer, filter_by_word, filter_by_lang]
self.dialog.filters.insert_item(False, *b)
def edit_filter(self, *args, **kwargs):
pass
def delete_filter(self, *args, **kwargs):
filter_title = self.dialog.filters.get_text_column(self.dialog.filters.get_selected(), 0)
response = commonMessageDialogs.delete_filter()
if response == widgetUtils.YES:
self.session.settings["filters"].pop(filter_title)
self.session.settings.write()
self.insert_filters(self.session.settings["filters"])

View File

@@ -1,377 +0,0 @@
# -*- coding: utf-8 -*-
import logging
import widgetUtils
import output
from pubsub import pub
from tweepy.errors import TweepyException, Forbidden
from mysc import restart
from sessions.twitter import utils, compose
from controller import userSelector
from wxUI import dialogs, commonMessageDialogs
from . import filters, lists, settings, userActions, trendingTopics, user
log = logging.getLogger("controller.twitter.handler")
class Handler(object):
def __init__(self):
super(Handler, self).__init__()
# Structure to hold names for menu bar items.
# empty names mean the item will be Disabled.
self.menus = dict(
# In application menu.
updateProfile=_("&Update profile"),
menuitem_search=_("&Search"),
lists=_("&Lists manager"),
manageAliases=_("Manage user aliases"),
# In Item Menu.
compose=_("&Tweet"),
reply=_("Re&ply"),
share=_("&Retweet"),
fav=_("&Like"),
unfav=_("&Unlike"),
view=_("&Show tweet"),
view_coordinates=_("View &address"),
view_conversation=_("View conversa&tion"),
ocr=_("Read text in picture"),
delete=_("&Delete"),
# In user menu.
follow=_("&Actions..."),
timeline=_("&View timeline..."),
dm=_("Direct me&ssage"),
addAlias=_("Add a&lias"),
addToList=_("&Add to list"),
removeFromList=_("R&emove from list"),
viewLists=_("&View lists"),
details=_("Show user &profile"),
favs=_("View likes"),
# In buffer menu.
trends=_("New &trending topics buffer..."),
filter=_("Create a &filter"),
manage_filters=_("&Manage filters"),
)
# Name for the "tweet" menu in the menu bar.
self.item_menu = _("&Tweet")
def create_buffers(self, session, createAccounts=True, controller=None):
session.get_user_info()
name = session.get_name()
controller.accounts.append(name)
if createAccounts == True:
pub.sendMessage("core.create_account", name=name, session_id=session.session_id, logged=True)
root_position =controller.view.search(name, name)
for i in session.settings['general']['buffer_order']:
if i == 'home':
pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Home"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, function="home_timeline", name="home_timeline", sessionObject=session, account=session.get_name(), sound="tweet_received.ogg", include_ext_alt_text=True, tweet_mode="extended"))
elif i == 'mentions':
pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Mentions"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, function="mentions_timeline", name="mentions", sessionObject=session, account=session.get_name(), sound="mention_received.ogg", include_ext_alt_text=True, tweet_mode="extended"))
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.get_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.get_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.get_name(), screen_name=session.db["user_name"], include_ext_alt_text=True, tweet_mode="extended"))
elif i == 'favorites':
pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Likes"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, function="get_favorites", name="favourites", sessionObject=session, account=session.get_name(), sound="favourite.ogg", include_ext_alt_text=True, tweet_mode="extended"))
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.get_name(), sound="update_followers.ogg", screen_name=session.db["user_name"]))
elif i == 'friends':
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.get_name(), screen_name=session.db["user_name"]))
elif i == 'blocks':
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.get_name()))
elif i == 'muted':
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.get_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=name))
timelines_position =controller.view.search("timelines", name)
for i in session.settings["other_buffers"]["timelines"]:
pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_(u"Timeline for {}").format(i,), parent_tab=timelines_position, start=False, kwargs=dict(parent=controller.view.nb, function="user_timeline", name="%s-timeline" % (i,), sessionObject=session, account=session.get_name(), sound="tweet_timeline.ogg", bufferType=None, user_id=i, include_ext_alt_text=True, tweet_mode="extended"))
pub.sendMessage("createBuffer", buffer_type="EmptyBuffer", session_type="base", buffer_title=_("Likes timelines"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, name="favs_timelines", account=name))
favs_timelines_position =controller.view.search("favs_timelines", name)
for i in session.settings["other_buffers"]["favourites_timelines"]:
pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Likes for {}").format(i,), parent_tab=favs_timelines_position, start=False, kwargs=dict(parent=controller.view.nb, function="get_favorites", name="%s-favorite" % (i,), sessionObject=session, account=name, bufferType=None, sound="favourites_timeline_updated.ogg", user_id=i, include_ext_alt_text=True, tweet_mode="extended"))
pub.sendMessage("createBuffer", buffer_type="EmptyBuffer", session_type="base", buffer_title=_("Followers timelines"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, name="followers_timelines", account=session.get_name()))
followers_timelines_position =controller.view.search("followers_timelines", name)
for i in session.settings["other_buffers"]["followers_timelines"]:
pub.sendMessage("createBuffer", buffer_type="PeopleBuffer", session_type=session.type, buffer_title=_("Followers for {}").format(i,), parent_tab=followers_timelines_position, start=False, kwargs=dict(parent=controller.view.nb, function="get_followers", name="%s-followers" % (i,), sessionObject=session, account=session.get_name(), sound="new_event.ogg", user_id=i))
pub.sendMessage("createBuffer", buffer_type="EmptyBuffer", session_type="base", buffer_title=_("Following timelines"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, name="friends_timelines", account=name))
friends_timelines_position =controller.view.search("friends_timelines", name)
for i in session.settings["other_buffers"]["friends_timelines"]:
pub.sendMessage("createBuffer", buffer_type="PeopleBuffer", session_type=session.type, buffer_title=_(u"Friends for {}").format(i,), parent_tab=friends_timelines_position, start=False, kwargs=dict(parent=controller.view.nb, function="get_friends", name="%s-friends" % (i,), sessionObject=session, account=session.get_name(), sound="new_event.ogg", user_id=i))
pub.sendMessage("createBuffer", buffer_type="EmptyBuffer", session_type="base", buffer_title=_("Lists"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, name="lists", account=name))
lists_position =controller.view.search("lists", name)
for i in session.settings["other_buffers"]["lists"]:
pub.sendMessage("createBuffer", buffer_type="ListBuffer", session_type=session.type, buffer_title=_(u"List for {}").format(i), parent_tab=lists_position, start=False, kwargs=dict(parent=controller.view.nb, function="list_timeline", name="%s-list" % (i,), sessionObject=session, account=session.get_name(), bufferType=None, sound="list_tweet.ogg", list_id=utils.find_list(i, session.db["lists"]), include_ext_alt_text=True, tweet_mode="extended"))
pub.sendMessage("createBuffer", buffer_type="EmptyBuffer", session_type="base", buffer_title=_("Searches"), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, name="searches", account=name))
searches_position =controller.view.search("searches", name)
for i in session.settings["other_buffers"]["tweet_searches"]:
pub.sendMessage("createBuffer", buffer_type="SearchBuffer", session_type=session.type, buffer_title=_(u"Search for {}").format(i), parent_tab=searches_position, start=False, kwargs=dict(parent=controller.view.nb, function="search_tweets", name="%s-searchterm" % (i,), sessionObject=session, account=session.get_name(), bufferType="searchPanel", sound="search_updated.ogg", q=i, include_ext_alt_text=True, tweet_mode="extended"))
for i in session.settings["other_buffers"]["trending_topic_buffers"]:
pub.sendMessage("createBuffer", buffer_type="TrendsBuffer", session_type=session.type, buffer_title=_("Trending topics for %s") % (i), parent_tab=root_position, start=False, kwargs=dict(parent=controller.view.nb, name="%s_tt" % (i,), sessionObject=session, account=session.get_name(), trendsFor=i, sound="trends_updated.ogg"))
def filter(self, buffer):
# Let's prevent filtering of some buffers (people buffers, direct messages, events and sent items).
if (buffer.name == "direct_messages" or buffer.name == "sent_tweets") or buffer.type == "people":
output.speak(_("Filters cannot be applied on this buffer"))
return
new_filter = filters.filter(buffer)
def manage_filters(self, session):
manage_filters = filters.filterManager(session)
def view_user_lists(self, buffer):
if not hasattr(buffer, "get_right_tweet"):
return
tweet = buffer.get_right_tweet()
if buffer.type == "people":
users = [tweet.screen_name]
elif buffer.type == "dm":
users = [buffer.session.get_user(tweet.message_create["sender_id"]).screen_name]
else:
users = utils.get_all_users(tweet, buffer.session)
selector = userSelector.userSelector(users=users, session_id=buffer.session.session_id)
user = selector.get_user()
if user == None:
return
l = lists.listsController(buffer.session, user=user)
def add_to_list(self, controller, buffer):
if not hasattr(buffer, "get_right_tweet"):
return
tweet = buffer.get_right_tweet()
if buffer.type == "people":
users = [tweet.screen_name]
elif buffer.type == "dm":
users = [buffer.session.get_user(tweet.message_create["sender_id"]).screen_name]
else:
users = utils.get_all_users(tweet, buffer.session)
selector = userSelector.userSelector(users=users, session_id=buffer.session.session_id)
user = selector.get_user()
if user == None:
return
dlg = dialogs.lists.addUserListDialog()
dlg.populate_list([compose.compose_list(item) for item in buffer.session.db["lists"]])
if dlg.get_response() == widgetUtils.OK:
try:
list = buffer.session.twitter.add_list_member(list_id=buffer.session.db["lists"][dlg.get_item()].id, screen_name=user)
older_list = utils.find_item(buffer.session.db["lists"][dlg.get_item()].id, buffer.session.db["lists"])
listBuffer = controller.search_buffer("%s-list" % (buffer.session.db["lists"][dlg.get_item()].name.lower()), buff.session.get_name())
if listBuffer != None:
listBuffer.get_user_ids()
buffer.session.db["lists"].pop(older_list)
buffer.session.db["lists"].append(list)
except TweepyException as e:
log.exception("error %s" % (str(e)))
output.speak("error %s" % (str(e)))
def remove_from_list(self, controller, buffer):
if not hasattr(buffer, "get_right_tweet"):
return
tweet = buffer.get_right_tweet()
if buffer.type == "people":
users = [tweet.screen_name]
elif buffer.type == "dm":
users = [buffer.session.get_user(tweet.message_create["sender_id"]).screen_name]
else:
users = utils.get_all_users(tweet, buffer.session)
selector = userSelector.userSelector(users=users, session_id=buffer.session.session_id)
user = selector.get_user()
if user == None:
return
dlg = dialogs.lists.removeUserListDialog()
dlg.populate_list([compose.compose_list(item) for item in buffer.session.db["lists"]])
if dlg.get_response() == widgetUtils.OK:
try:
list = buffer.session.twitter.remove_list_member(list_id=buffer.session.db["lists"][dlg.get_item()].id, screen_name=user)
older_list = utils.find_item(buffer.session.db["lists"][dlg.get_item()].id, buffer.session.db["lists"])
listBuffer = controller.search_buffer("%s-list" % (buffer.session.db["lists"][dlg.get_item()].name.lower()), buffer.session.get_name())
if listBuffer != None:
listBuffer.get_user_ids()
buffer.session.db["lists"].pop(older_list)
buffer.session.db["lists"].append(list)
except TweepyException as e:
output.speak("error %s" % (str(e)))
log.exception("error %s" % (str(e)))
def list_manager(self, session, lists_buffer_position):
return lists.listsController(session=session, lists_buffer_position=lists_buffer_position)
def account_settings(self, buffer, controller):
d = settings.accountSettingsController(buffer, controller)
if d.response == widgetUtils.OK:
d.save_configuration()
if d.needs_restart == True:
commonMessageDialogs.needs_restart()
buffer.session.settings.write()
buffer.session.save_persistent_data()
restart.restart_program()
def follow(self, buffer):
if not hasattr(buffer, "get_right_tweet"):
return
tweet = buffer.get_right_tweet()
if buffer.type == "people":
users = [tweet.screen_name]
elif buffer.type == "dm":
users = [buffer.session.get_user(tweet.message_create["sender_id"]).screen_name]
else:
users = utils.get_all_users(tweet, buffer.session)
u = userActions.userActionsController(buffer, users)
def add_alias(self, buffer):
if not hasattr(buffer, "get_right_tweet"):
return
tweet = buffer.get_right_tweet()
if buffer.type == "people":
users = [tweet.screen_name]
elif buffer.type == "dm":
users = [buffer.session.get_user(tweet.message_create["sender_id"]).screen_name]
else:
users = utils.get_all_users(tweet, buffer.session)
dlg = dialogs.userAliasDialogs.addAliasDialog(_("Add an user alias"), users)
if dlg.get_response() == widgetUtils.OK:
user, alias = dlg.get_user()
if user == "" or alias == "":
return
user_id = buffer.session.get_user_by_screen_name(user)
buffer.session.settings["user-aliases"][str(user_id)] = alias
buffer.session.settings.write()
output.speak(_("Alias has been set correctly for {}.").format(user))
pub.sendMessage("alias-added")
# ToDo: explore how to play sound & save config differently.
# currently, TWBlue will play the sound and save the config for the timeline even if the buffer did not load or something else.
def open_timeline(self, controller, buffer, default="tweets"):
if not hasattr(buffer, "get_right_tweet"):
return
tweet = buffer.get_right_tweet()
if buffer.type == "people":
users = [tweet.screen_name]
elif buffer.type == "dm":
users = [buffer.session.get_user(tweet.message_create["sender_id"]).screen_name]
else:
users = utils.get_all_users(tweet, buffer.session)
dlg = dialogs.userSelection.selectUserDialog(users=users, default=default)
if dlg.get_response() == widgetUtils.OK:
usr = utils.if_user_exists(buffer.session.twitter, dlg.get_user())
if usr != None:
if usr == dlg.get_user():
commonMessageDialogs.suspended_user()
return
if usr.protected == True:
if usr.following == False:
commonMessageDialogs.no_following()
return
tl_type = dlg.get_action()
if tl_type == "tweets":
if usr.statuses_count == 0:
commonMessageDialogs.no_tweets()
return
if usr.id_str in buffer.session.settings["other_buffers"]["timelines"]:
commonMessageDialogs.timeline_exist()
return
timelines_position =controller.view.search("timelines", buffer.session.get_name())
pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=buffer.session.type, buffer_title=_("Timeline for {}").format(usr.screen_name,), parent_tab=timelines_position, start=True, kwargs=dict(parent=controller.view.nb, function="user_timeline", name="%s-timeline" % (usr.id_str,), sessionObject=buffer.session, account=buffer.session.get_name(), sound="tweet_timeline.ogg", bufferType=None, user_id=usr.id_str, include_ext_alt_text=True, tweet_mode="extended"))
buffer.session.settings["other_buffers"]["timelines"].append(usr.id_str)
buffer.session.sound.play("create_timeline.ogg")
elif tl_type == "favourites":
if usr.favourites_count == 0:
commonMessageDialogs.no_favs()
return
if usr.id_str in buffer.session.settings["other_buffers"]["favourites_timelines"]:
commonMessageDialogs.timeline_exist()
return
favs_timelines_position =controller.view.search("favs_timelines", buffer.session.get_name())
pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=buffer.session.type, buffer_title=_("Likes for {}").format(usr.screen_name,), parent_tab=favs_timelines_position, start=True, kwargs=dict(parent=controller.view.nb, function="get_favorites", name="%s-favorite" % (usr.id_str,), sessionObject=buffer.session, account=buffer.session.get_name(), bufferType=None, sound="favourites_timeline_updated.ogg", user_id=usr.id_str, include_ext_alt_text=True, tweet_mode="extended"))
buffer.session.settings["other_buffers"]["favourites_timelines"].append(usr.id_str)
buffer.session.sound.play("create_timeline.ogg")
elif tl_type == "followers":
if usr.followers_count == 0:
commonMessageDialogs.no_followers()
return
if usr.id_str in buffer.session.settings["other_buffers"]["followers_timelines"]:
commonMessageDialogs.timeline_exist()
return
followers_timelines_position =controller.view.search("followers_timelines", buffer.session.get_name())
pub.sendMessage("createBuffer", buffer_type="PeopleBuffer", session_type=buffer.session.type, buffer_title=_("Followers for {}").format(usr.screen_name,), parent_tab=followers_timelines_position, start=True, kwargs=dict(parent=controller.view.nb, function="get_followers", name="%s-followers" % (usr.id_str,), sessionObject=buffer.session, account=buffer.session.get_name(), sound="new_event.ogg", user_id=usr.id_str))
buffer.session.settings["other_buffers"]["followers_timelines"].append(usr.id_str)
buffer.session.sound.play("create_timeline.ogg")
elif tl_type == "friends":
if usr.friends_count == 0:
commonMessageDialogs.no_friends()
return
if usr.id_str in buffer.session.settings["other_buffers"]["friends_timelines"]:
commonMessageDialogs.timeline_exist()
return
friends_timelines_position =controller.view.search("friends_timelines", buffer.session.get_name())
pub.sendMessage("createBuffer", buffer_type="PeopleBuffer", session_type=buffer.session.type, buffer_title=_("Friends for {}").format(usr.screen_name,), parent_tab=friends_timelines_position, start=True, kwargs=dict(parent=controller.view.nb, function="get_friends", name="%s-friends" % (usr.id_str,), sessionObject=buffer.session, account=buffer.session.get_name(), sound="new_event.ogg", user_id=usr.id_str))
buffer.session.settings["other_buffers"]["friends_timelines"].append(usr.id_str)
buffer.session.sound.play("create_timeline.ogg")
else:
commonMessageDialogs.user_not_exist()
buffer.session.settings.write()
def open_conversation(self, controller, buffer):
tweet = buffer.get_right_tweet()
if hasattr(tweet, "retweeted_status") and tweet.retweeted_status != None:
tweet = tweet.retweeted_status
user = buffer.session.get_user(tweet.user).screen_name
searches_position =controller.view.search("searches", buffer.session.get_name())
pub.sendMessage("createBuffer", buffer_type="ConversationBuffer", session_type=buffer.session.type, buffer_title=_(u"Conversation with {0}").format(user), parent_tab=searches_position, start=True, kwargs=dict(tweet=tweet, parent=controller.view.nb, function="search_tweets", name="%s-searchterm" % (tweet.id,), sessionObject=buffer.session, account=buffer.session.get_name(), bufferType="searchPanel", sound="search_updated.ogg", since_id=tweet.id, q="@{0}".format(user)))
def get_trending_topics(self, controller, session):
trends = trendingTopics.trendingTopicsController(session)
if trends.dialog.get_response() == widgetUtils.OK:
woeid = trends.get_woeid()
if woeid in session.settings["other_buffers"]["trending_topic_buffers"]:
return
root_position =controller.view.search(session.get_name(), session.get_name())
pub.sendMessage("createBuffer", buffer_type="TrendsBuffer", session_type=session.type, buffer_title=_("Trending topics for %s") % (trends.get_string()), parent_tab=root_position, start=True, kwargs=dict(parent=controller.view.nb, name="%s_tt" % (woeid,), sessionObject=session, account=session.get_name(), trendsFor=woeid, sound="trends_updated.ogg"))
session.settings["other_buffers"]["trending_topic_buffers"].append(str(woeid))
session.settings.write()
def start_buffer(self, controller, buffer):
if hasattr(buffer, "finished_timeline") and buffer.finished_timeline == False:
change_title = True
else:
change_title = False
try:
if "mentions" in buffer.name or "direct_messages" in buffer.name:
buffer.start_stream()
else:
buffer.start_stream(play_sound=False)
except TweepyException 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))
# Determine if this error was caused by a block applied to the current user (IE permission errors).
if type(err) == Forbidden:
buff = controller.view.search(buffer.name, buffer.account)
buffer.remove_buffer(force=True)
commonMessageDialogs.blocked_timeline()
if controller.get_current_buffer() == buffer:
controller.right()
controller.view.delete_buffer(buff)
controller.buffers.remove(buffer)
del buffer
if change_title:
pub.sendMessage("buffer-title-changed", buffer=buffer)
def update_profile(self, session):
r = user.profileController(session)
def search(self, controller, session, value):
log.debug("Creating a new search...")
dlg = dialogs.search.searchDialog(value)
if dlg.get_response() == widgetUtils.OK and dlg.get("term") != "":
term = dlg.get("term")
searches_position =controller.view.search("searches", session.get_name())
if dlg.get("tweets") == True:
if term not in session.settings["other_buffers"]["tweet_searches"]:
session.settings["other_buffers"]["tweet_searches"].append(term)
session.settings.write()
args = {"lang": dlg.get_language(), "result_type": dlg.get_result_type()}
pub.sendMessage("createBuffer", buffer_type="SearchBuffer", session_type=session.type, buffer_title=_("Search for {}").format(term), parent_tab=searches_position, start=True, kwargs=dict(parent=controller.view.nb, function="search_tweets", name="%s-searchterm" % (term,), sessionObject=session, account=session.get_name(), bufferType="searchPanel", sound="search_updated.ogg", q=term, include_ext_alt_text=True, tweet_mode="extended"))
else:
log.error("A buffer for the %s search term is already created. You can't create a duplicate buffer." % (term,))
return
elif dlg.get("users") == True:
pub.sendMessage("createBuffer", buffer_type="SearchPeopleBuffer", session_type=session.type, buffer_title=_("Search for {}").format(term), parent_tab=searches_position, start=True, kwargs=dict(parent=controller.view.nb, function="search_users", name="%s-searchUser" % (term,), sessionObject=session, account=session.get_name(), bufferType=None, sound="search_updated.ogg", q=term))
dlg.Destroy()

View File

@@ -1,117 +0,0 @@
# -*- coding: utf-8 -*-
import widgetUtils
import output
import logging
from wxUI.dialogs import lists
from tweepy.errors import TweepyException
from sessions.twitter import compose, utils
from pubsub import pub
log = logging.getLogger("controller.listsController")
class listsController(object):
def __init__(self, session, user=None, lists_buffer_position=0):
super(listsController, self).__init__()
self.session = session
self.lists_buffer_position = lists_buffer_position
if user == None:
self.dialog = lists.listViewer()
self.dialog.populate_list(self.get_all_lists())
widgetUtils.connect_event(self.dialog.createBtn, widgetUtils.BUTTON_PRESSED, self.create_list)
widgetUtils.connect_event(self.dialog.editBtn, widgetUtils.BUTTON_PRESSED, self.edit_list)
widgetUtils.connect_event(self.dialog.deleteBtn, widgetUtils.BUTTON_PRESSED, self.remove_list)
widgetUtils.connect_event(self.dialog.view, widgetUtils.BUTTON_PRESSED, self.open_list_as_buffer)
widgetUtils.connect_event(self.dialog.deleteBtn, widgetUtils.BUTTON_PRESSED, self.remove_list)
else:
self.dialog = lists.userListViewer(user)
self.dialog.populate_list(self.get_user_lists(user))
widgetUtils.connect_event(self.dialog.createBtn, widgetUtils.BUTTON_PRESSED, self.subscribe)
widgetUtils.connect_event(self.dialog.deleteBtn, widgetUtils.BUTTON_PRESSED, self.unsubscribe)
self.dialog.get_response()
def get_all_lists(self):
return [compose.compose_list(item) for item in self.session.db["lists"]]
def get_user_lists(self, user):
self.lists = self.session.twitter.get_lists(reverse=True, screen_name=user)
return [compose.compose_list(item) for item in self.lists]
def create_list(self, *args, **kwargs):
dialog = lists.createListDialog()
if dialog.get_response() == widgetUtils.OK:
name = dialog.get("name")
description = dialog.get("description")
p = dialog.get("public")
if p == True:
mode = "public"
else:
mode = "private"
try:
new_list = self.session.twitter.create_list(name=name, description=description, mode=mode)
self.session.db["lists"].append(new_list)
self.dialog.lista.insert_item(False, *compose.compose_list(new_list))
except TweepyException as e:
output.speak("error %s" % (str(e)))
log.exception("error %s" % (str(e)))
dialog.destroy()
def edit_list(self, *args, **kwargs):
if self.dialog.lista.get_count() == 0: return
list = self.session.db["lists"][self.dialog.get_item()]
dialog = lists.editListDialog(list)
if dialog.get_response() == widgetUtils.OK:
name = dialog.get("name")
description = dialog.get("description")
p = dialog.get("public")
if p == True:
mode = "public"
else:
mode = "private"
try:
self.session.twitter.update_list(list_id=list.id, name=name, description=description, mode=mode)
self.session.get_lists()
self.dialog.populate_list(self.get_all_lists(), True)
except TweepyException as e:
output.speak("error %s" % (str(e)))
log.exception("error %s" % (str(e)))
dialog.destroy()
def remove_list(self, *args, **kwargs):
if self.dialog.lista.get_count() == 0: return
list = self.session.db["lists"][self.dialog.get_item()].id
if lists.remove_list() == widgetUtils.YES:
try:
self.session.twitter.destroy_list(list_id=list)
self.session.db["lists"].pop(self.dialog.get_item())
self.dialog.lista.remove_item(self.dialog.get_item())
except TweepyException as e:
output.speak("error %s" % (str(e)))
log.exception("error %s" % (str(e)))
def open_list_as_buffer(self, *args, **kwargs):
if self.dialog.lista.get_count() == 0: return
list = self.session.db["lists"][self.dialog.get_item()]
pub.sendMessage("createBuffer", buffer_type="ListBuffer", session_type=self.session.type, buffer_title=_("List for {}").format(list.name), parent_tab=self.lists_buffer_position, start=True, kwargs=dict(function="list_timeline", name="%s-list" % (list.name,), sessionObject=self.session, account=self.session.get_name(), bufferType=None, sound="list_tweet.ogg", list_id=list.id, include_ext_alt_text=True, tweet_mode="extended"))
self.session.settings["other_buffers"]["lists"].append(list.name)
self.session.settings.write()
def subscribe(self, *args, **kwargs):
if self.dialog.lista.get_count() == 0: return
list_id = self.lists[self.dialog.get_item()].id
try:
list = self.session.twitter.subscribe_list(list_id=list_id)
item = utils.find_item(list.id, self.session.db["lists"])
self.session.db["lists"].append(list)
except TweepyException as e:
output.speak("error %s" % (str(e)))
log.exception("error %s" % (str(e)))
def unsubscribe(self, *args, **kwargs):
if self.dialog.lista.get_count() == 0: return
list_id = self.lists[self.dialog.get_item()].id
try:
list = self.session.twitter.unsubscribe_list(list_id=list_id)
self.session.db["lists"].remove(list)
except TweepyException as e:
output.speak("error %s" % (str(e)))
log.exception("error %s" % (str(e)))

View File

@@ -1,382 +0,0 @@
# -*- coding: utf-8 -*-
import os
import arrow
import languageHandler
import wx
import widgetUtils
import output
import sound
import config
from pubsub import pub
from twitter_text.parse_tweet import parse_tweet
from wxUI.dialogs import twitterDialogs, urlList
from wxUI import commonMessageDialogs
from extra import translator, SpellChecker
from extra.AudioUploader import audioUploader
from extra.autocompletionUsers import completion
from sessions.twitter import utils
class basicTweet(object):
""" This class handles the tweet main features. Other classes should derive from this class."""
def __init__(self, session, title, caption, text="", messageType="tweet", max=280, *args, **kwargs):
super(basicTweet, self).__init__()
self.max = max
self.title = title
self.session = session
self.message = getattr(twitterDialogs, messageType)(title=title, caption=caption, message=text, max_length=max, *args, **kwargs)
self.message.text.SetValue(text)
self.message.text.SetInsertionPoint(len(self.message.text.GetValue()))
widgetUtils.connect_event(self.message.spellcheck, widgetUtils.BUTTON_PRESSED, self.spellcheck)
widgetUtils.connect_event(self.message.add_audio, widgetUtils.BUTTON_PRESSED, self.attach)
widgetUtils.connect_event(self.message.text, widgetUtils.ENTERED_TEXT, self.text_processor)
widgetUtils.connect_event(self.message.translate, widgetUtils.BUTTON_PRESSED, self.translate)
if hasattr(self.message, "add"):
widgetUtils.connect_event(self.message.add, widgetUtils.BUTTON_PRESSED, self.on_attach)
self.attachments = []
def translate(self, event=None):
dlg = translator.gui.translateDialog()
if dlg.get_response() == widgetUtils.OK:
text_to_translate = self.message.text.GetValue()
language_dict = translator.translator.available_languages()
for k in language_dict:
if language_dict[k] == dlg.dest_lang.GetStringSelection():
dst = k
msg = translator.translator.translate(text=text_to_translate, target=dst)
self.message.text.ChangeValue(msg)
self.message.text.SetInsertionPoint(len(self.message.text.GetValue()))
self.text_processor()
self.message.text.SetFocus()
output.speak(_(u"Translated"))
else:
return
def text_processor(self, *args, **kwargs):
text = self.message.text.GetValue()
results = parse_tweet(text)
self.message.SetTitle(_("%s - %s of %d characters") % (self.title, results.weightedLength, self.max))
if results.weightedLength > self.max:
self.session.sound.play("max_length.ogg")
def spellcheck(self, event=None):
text = self.message.text.GetValue()
checker = SpellChecker.spellchecker.spellChecker(text, "")
if hasattr(checker, "fixed_text"):
self.message.text.ChangeValue(checker.fixed_text)
self.text_processor()
self.message.text.SetFocus()
def attach(self, *args, **kwargs):
def completed_callback(dlg):
url = dlg.uploaderFunction.get_url()
pub.unsubscribe(dlg.uploaderDialog.update, "uploading")
dlg.uploaderDialog.destroy()
if "sndup.net/" in url:
self.message.text.ChangeValue(self.message.text.GetValue()+url+" #audio")
self.text_processor()
else:
commonMessageDialogs.common_error(url)
dlg.cleanup()
dlg = audioUploader.audioUploader(self.session.settings, completed_callback)
self.message.text.SetFocus()
def can_attach(self):
if len(self.attachments) == 0:
return True
elif len(self.attachments) == 1 and (self.attachments[0]["type"] == "video" or self.attachments[0]["type"] == "gif"):
return False
elif len(self.attachments) < 4:
return True
return False
def on_attach(self, *args, **kwargs):
can_attach = self.can_attach()
menu = self.message.attach_menu(can_attach)
self.message.Bind(wx.EVT_MENU, self.on_attach_image, self.message.add_image)
self.message.Bind(wx.EVT_MENU, self.on_attach_video, self.message.add_video)
if hasattr(self.message, "add_poll"):
self.message.Bind(wx.EVT_MENU, self.on_attach_poll, self.message.add_poll)
self.message.PopupMenu(menu, self.message.add.GetPosition())
def on_attach_image(self, *args, **kwargs):
can_attach = self.can_attach()
video_or_gif_present = False
for a in self.attachments:
if a["type"] == "video" or a["type"] == "gif":
video_or_gif = True
break
if can_attach == False or video_or_gif_present == True:
return self.message.unable_to_attach_file()
image, description = self.message.get_image()
if image != None:
if image.endswith("gif"):
image_type = "gif"
else:
image_type = "photo"
imageInfo = {"type": image_type, "file": image, "description": description}
if len(self.attachments) > 0 and image_type == "gif":
return self.message.unable_to_attach_file()
self.attachments.append(imageInfo)
self.message.add_item(item=[os.path.basename(imageInfo["file"]), imageInfo["type"], imageInfo["description"]])
self.text_processor()
def on_attach_video(self, *args, **kwargs):
if len(self.attachments) > 0:
return self.message.unable_to_attach_file()
video = self.message.get_video()
if video != None:
videoInfo = {"type": "video", "file": video, "description": ""}
if len(self.attachments) > 0:
return self.message.unable_to_attach_file()
self.attachments.append(videoInfo)
self.message.add_item(item=[os.path.basename(videoInfo["file"]), videoInfo["type"], videoInfo["description"]])
self.text_processor()
def on_attach_poll(self, *args, **kwargs):
dlg = twitterDialogs.poll()
if dlg.ShowModal() == wx.ID_OK:
self.poll_options = dlg.get_options()
self.poll_period = 60*24*dlg.period.GetValue()
dlg.Destroy()
def remove_attachment(self, *args, **kwargs):
attachment = self.message.attachments.GetFocusedItem()
if attachment > -1 and len(self.attachments) > attachment:
self.attachments.pop(attachment)
self.message.remove_item(list_type="attachment")
self.text_processor()
self.message.text.SetFocus()
class tweet(basicTweet):
def __init__(self, session, title, caption, text="", max=280, messageType="tweet", *args, **kwargs):
self.thread = []
self.poll_options = None
self.poll_period = None
super(tweet, self).__init__(session, title, caption, text, messageType, max, *args, **kwargs)
widgetUtils.connect_event(self.message.autocomplete_users, widgetUtils.BUTTON_PRESSED, self.autocomplete_users)
if hasattr(self.message, "add_tweet"):
widgetUtils.connect_event(self.message.add_tweet, widgetUtils.BUTTON_PRESSED, self.add_tweet)
widgetUtils.connect_event(self.message.remove_tweet, widgetUtils.BUTTON_PRESSED, self.remove_tweet)
widgetUtils.connect_event(self.message.remove_attachment, widgetUtils.BUTTON_PRESSED, self.remove_attachment)
self.text_processor()
def autocomplete_users(self, *args, **kwargs):
c = completion.autocompletionUsers(self.message, self.session.session_id)
c.show_menu()
def add_tweet(self, event, update_gui=True, *args, **kwargs):
text = self.message.text.GetValue()
attachments = self.attachments[::]
tweetdata = dict(text=text, attachments=attachments, poll_options=self.poll_options, poll_period=self.poll_period)
self.thread.append(tweetdata)
self.attachments = []
self.poll_options = None
self.poll_period = None
if update_gui:
self.message.reset_controls()
self.message.add_item(item=[text, len(attachments)], list_type="tweet")
self.message.text.SetFocus()
self.text_processor()
def get_tweet_data(self):
self.add_tweet(event=None, update_gui=False)
return self.thread
def text_processor(self, *args, **kwargs):
super(tweet, self).text_processor(*args, **kwargs)
if len(self.thread) > 0:
if hasattr(self.message, "tweets"):
self.message.tweets.Enable(True)
self.message.remove_tweet.Enable(True)
else:
self.message.tweets.Enable(False)
self.message.remove_tweet.Enable(False)
if len(self.attachments) > 0:
self.message.attachments.Enable(True)
self.message.remove_attachment.Enable(True)
else:
self.message.attachments.Enable(False)
self.message.remove_attachment.Enable(False)
if hasattr(self.message, "add_tweet"):
if len(self.message.text.GetValue()) > 0 or len(self.attachments) > 0:
self.message.add_tweet.Enable(True)
else:
self.message.add_tweet.Enable(False)
def remove_tweet(self, *args, **kwargs):
tweet = self.message.tweets.GetFocusedItem()
if tweet > -1 and len(self.thread) > tweet:
self.thread.pop(tweet)
self.message.remove_item(list_type="tweet")
self.text_processor()
self.message.text.SetFocus()
class reply(tweet):
def __init__(self, session, title, caption, text, users=[], ids=[]):
super(reply, self).__init__(session, title, caption, text, messageType="reply", users=users)
self.ids = ids
self.users = users
if len(users) > 0:
widgetUtils.connect_event(self.message.mention_all, widgetUtils.CHECKBOX, self.mention_all)
self.message.mention_all.Enable(True)
if config.app["app-settings"]["remember_mention_and_longtweet"]:
self.message.mention_all.SetValue(config.app["app-settings"]["mention_all"])
self.mention_all()
self.message.text.SetInsertionPoint(len(self.message.text.GetValue()))
self.text_processor()
def text_processor(self, *args, **kwargs):
super(tweet, self).text_processor(*args, **kwargs)
if len(self.attachments) > 0:
self.message.attachments.Enable(True)
self.message.remove_attachment.Enable(True)
else:
self.message.attachments.Enable(False)
self.message.remove_attachment.Enable(False)
def mention_all(self, *args, **kwargs):
if self.message.mention_all.GetValue() == True:
for i in self.message.checkboxes:
i.SetValue(True)
i.Hide()
else:
for i in self.message.checkboxes:
i.SetValue(False)
i.Show()
def get_ids(self):
excluded_ids = []
for i in range(0, len(self.message.checkboxes)):
if self.message.checkboxes[i].GetValue() == False:
excluded_ids.append(self.ids[i])
return excluded_ids
def get_people(self):
people = ""
for i in range(0, len(self.message.checkboxes)):
if self.message.checkboxes[i].GetValue() == True:
people = people + "{0} ".format(self.message.checkboxes[i].GetLabel(),)
return people
class dm(basicTweet):
def __init__(self, session, title, caption, users):
super(dm, self).__init__(session, title, caption, messageType="dm", max=10000, users=users)
widgetUtils.connect_event(self.message.autocomplete_users, widgetUtils.BUTTON_PRESSED, self.autocomplete_users)
self.text_processor()
widgetUtils.connect_event(self.message.cb, widgetUtils.ENTERED_TEXT, self.user_changed)
def user_changed(self, *args, **kwargs):
self.title = _("Direct message to %s") % (self.message.cb.GetValue())
self.text_processor()
def autocomplete_users(self, *args, **kwargs):
c = completion.autocompletionUsers(self.message, self.session.session_id)
c.show_menu("dm")
def text_processor(self, *args, **kwargs):
super(dm, self).text_processor(*args, **kwargs)
if len(self.attachments) > 0:
self.message.attachments.Enable(True)
self.message.remove_attachment.Enable(True)
else:
self.message.attachments.Enable(False)
self.message.remove_attachment.Enable(False)
def can_attach(self):
if len(self.attachments) == 0:
return True
return False
class viewTweet(basicTweet):
def __init__(self, tweet, tweetList, is_tweet=True, utc_offset=0, date="", item_url=""):
""" This represents a tweet displayer. However it could be used for showing something wich is not a tweet, like a direct message or an event.
param tweet: A dictionary that represents a full tweet or a string for non-tweets.
param tweetList: If is_tweet is set to True, this could be a list of quoted tweets.
param is_tweet: True or false, depending wether the passed object is a tweet or not."""
if is_tweet == True:
self.title = _(u"Tweet")
image_description = []
text = ""
for i in range(0, len(tweetList)):
# tweets with message keys are longer tweets, the message value is the full messaje taken from twishort.
if hasattr(tweetList[i], "message") and tweetList[i].is_quote_status == False:
value = "message"
else:
value = "full_text"
if hasattr(tweetList[i], "retweeted_status") and tweetList[i].is_quote_status == False:
if not hasattr(tweetList[i], "message"):
text = text + "rt @%s: %s\n" % (tweetList[i].retweeted_status.user.screen_name, tweetList[i].retweeted_status.full_text)
else:
text = text + "rt @%s: %s\n" % (tweetList[i].retweeted_status.user.screen_name, getattr(tweetList[i], value))
else:
text = text + " @%s: %s\n" % (tweetList[i].user.screen_name, getattr(tweetList[i], value))
# tweets with extended_entities could include image descriptions.
if hasattr(tweetList[i], "extended_entities") and "media" in tweetList[i].extended_entities:
for z in tweetList[i].extended_entities["media"]:
if "ext_alt_text" in z and z["ext_alt_text"] != None:
image_description.append(z["ext_alt_text"])
if hasattr(tweetList[i], "retweeted_status") and hasattr(tweetList[i].retweeted_status, "extended_entities") and "media" in tweetList[i].retweeted_status["extended_entities"]:
for z in tweetList[i].retweeted_status.extended_entities["media"]:
if "ext_alt_text" in z and z["ext_alt_text"] != None:
image_description.append(z["ext_alt_text"])
# set rt and likes counters.
rt_count = str(tweet.retweet_count)
favs_count = str(tweet.favorite_count)
# Gets the client from where this tweet was made.
source = tweet.source
original_date = arrow.get(tweet.created_at, locale="en")
date = original_date.shift(seconds=utc_offset).format(_(u"MMM D, YYYY. H:m"), locale=languageHandler.getLanguage())
if text == "":
if hasattr(tweet, "message"):
value = "message"
else:
value = "full_text"
if hasattr(tweet, "retweeted_status"):
if not hasattr(tweet, "message"):
text = "rt @%s: %s" % (tweet.retweeted_status.user.screen_name, tweet.retweeted_status.full_text)
else:
text = "rt @%s: %s" % (tweet.retweeted_status.user.screen_name, getattr(tweet, value))
else:
text = getattr(tweet, value)
text = self.clear_text(text)
if hasattr(tweet, "extended_entities") and "media" in tweet.extended_entities:
for z in tweet.extended_entities["media"]:
if "ext_alt_text" in z and z["ext_alt_text"] != None:
image_description.append(z["ext_alt_text"])
if hasattr(tweet, "retweeted_status") and hasattr(tweet.retweeted_status, "extended_entities") and "media" in tweet.retweeted_status.extended_entities:
for z in tweet.retweeted_status.extended_entities["media"]:
if "ext_alt_text" in z and z["ext_alt_text"] != None:
image_description.append(z["ext_alt_text"])
self.message = twitterDialogs.viewTweet(text, rt_count, favs_count, source, date)
results = parse_tweet(text)
self.message.set_title(results.weightedLength)
[self.message.set_image_description(i) for i in image_description]
else:
self.title = _(u"View item")
text = tweet
self.message = twitterDialogs.viewNonTweet(text, date)
widgetUtils.connect_event(self.message.spellcheck, widgetUtils.BUTTON_PRESSED, self.spellcheck)
if item_url != "":
self.message.enable_button("share")
widgetUtils.connect_event(self.message.share, widgetUtils.BUTTON_PRESSED, self.share)
self.item_url = item_url
widgetUtils.connect_event(self.message.translateButton, widgetUtils.BUTTON_PRESSED, self.translate)
self.message.ShowModal()
# We won't need text_processor in this dialog, so let's avoid it.
def text_processor(self):
pass
def clear_text(self, text):
text = utils.StripChars(text)
urls = utils.find_urls_in_text(text)
for i in urls:
if "https://twitter.com/" in i:
text = text.replace(i, "\n")
return text
def share(self, *args, **kwargs):
if hasattr(self, "item_url"):
output.copy(self.item_url)
output.speak(_("Link copied to clipboard."))

View File

@@ -1,247 +0,0 @@
# -*- coding: utf-8 -*-
import os
import threading
import logging
import sound_lib
import paths
import widgetUtils
import output
from collections import OrderedDict
from wxUI import commonMessageDialogs
from extra.autocompletionUsers import scan, manage
from extra.ocr import OCRSpace
from controller.settings import globalSettingsController
from . templateEditor import EditTemplate
log = logging.getLogger("Settings")
class accountSettingsController(globalSettingsController):
def __init__(self, buffer, window):
self.user = buffer.session.db["user_name"]
self.buffer = buffer
self.window = window
self.config = buffer.session.settings
super(accountSettingsController, self).__init__()
def create_config(self):
self.dialog.create_general_account()
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)
self.dialog.set_value("general", "relative_time", self.config["general"]["relative_times"])
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", "itemsPerApiCall", self.config["general"]["max_tweets_per_call"])
self.dialog.set_value("general", "reverse_timelines", self.config["general"]["reverse_timelines"])
rt = self.config["general"]["retweet_mode"]
if rt == "ask":
self.dialog.set_value("general", "retweet_mode", _(u"Ask"))
elif rt == "direct":
self.dialog.set_value("general", "retweet_mode", _(u"Retweet without comments"))
else:
self.dialog.set_value("general", "retweet_mode", _(u"Retweet with comments"))
self.dialog.set_value("general", "persist_size", str(self.config["general"]["persist_size"]))
self.dialog.set_value("general", "load_cache_in_memory", self.config["general"]["load_cache_in_memory"])
self.dialog.create_reporting()
self.dialog.set_value("reporting", "speech_reporting", self.config["reporting"]["speech_reporting"])
self.dialog.set_value("reporting", "braille_reporting", self.config["reporting"]["braille_reporting"])
tweet_template = self.config["templates"]["tweet"]
dm_template = self.config["templates"]["dm"]
sent_dm_template = self.config["templates"]["dm_sent"]
person_template = self.config["templates"]["person"]
self.dialog.create_templates(tweet_template=tweet_template, dm_template=dm_template, sent_dm_template=sent_dm_template, person_template=person_template)
widgetUtils.connect_event(self.dialog.templates.tweet, widgetUtils.BUTTON_PRESSED, self.edit_tweet_template)
widgetUtils.connect_event(self.dialog.templates.dm, widgetUtils.BUTTON_PRESSED, self.edit_dm_template)
widgetUtils.connect_event(self.dialog.templates.sent_dm, widgetUtils.BUTTON_PRESSED, self.edit_sent_dm_template)
widgetUtils.connect_event(self.dialog.templates.person, widgetUtils.BUTTON_PRESSED, self.edit_person_template)
self.dialog.create_other_buffers()
buffer_values = self.get_buffers_list()
self.dialog.buffers.insert_buffers(buffer_values)
self.dialog.buffers.connect_hook_func(self.toggle_buffer_active)
widgetUtils.connect_event(self.dialog.buffers.toggle_state, widgetUtils.BUTTON_PRESSED, self.toggle_state)
widgetUtils.connect_event(self.dialog.buffers.up, widgetUtils.BUTTON_PRESSED, self.dialog.buffers.move_up)
widgetUtils.connect_event(self.dialog.buffers.down, widgetUtils.BUTTON_PRESSED, self.dialog.buffers.move_down)
self.dialog.create_ignored_clients(self.config["twitter"]["ignored_clients"])
widgetUtils.connect_event(self.dialog.ignored_clients.add, widgetUtils.BUTTON_PRESSED, self.add_ignored_client)
widgetUtils.connect_event(self.dialog.ignored_clients.remove, widgetUtils.BUTTON_PRESSED, self.remove_ignored_client)
self.input_devices = sound_lib.input.Input.get_device_names()
self.output_devices = sound_lib.output.Output.get_device_names()
self.soundpacks = []
[self.soundpacks.append(i) for i in os.listdir(paths.sound_path()) if os.path.isdir(os.path.join(paths.sound_path(), i)) == True ]
self.dialog.create_sound(self.input_devices, self.output_devices, self.soundpacks)
self.dialog.set_value("sound", "volumeCtrl", int(self.config["sound"]["volume"]*100))
self.dialog.set_value("sound", "input", self.config["sound"]["input_device"])
self.dialog.set_value("sound", "output", self.config["sound"]["output_device"])
self.dialog.set_value("sound", "session_mute", self.config["sound"]["session_mute"])
self.dialog.set_value("sound", "soundpack", self.config["sound"]["current_soundpack"])
self.dialog.set_value("sound", "indicate_audio", self.config["sound"]["indicate_audio"])
self.dialog.set_value("sound", "indicate_geo", self.config["sound"]["indicate_geo"])
self.dialog.set_value("sound", "indicate_img", self.config["sound"]["indicate_img"])
self.dialog.create_extras(OCRSpace.translatable_langs)
self.dialog.set_value("extras", "sndup_apiKey", self.config["sound"]["sndup_api_key"])
language_index = OCRSpace.OcrLangs.index(self.config["mysc"]["ocr_language"])
self.dialog.extras.ocr_lang.SetSelection(language_index)
self.dialog.realize()
self.dialog.set_title(_(u"Account settings for %s") % (self.user,))
self.response = self.dialog.get_response()
def edit_tweet_template(self, *args, **kwargs):
template = self.config["templates"]["tweet"]
control = EditTemplate(template=template, type="tweet")
result = control.run_dialog()
if result != "": # Template has been saved.
self.config["templates"]["tweet"] = result
self.config.write()
self.dialog.templates.tweet.SetLabel(_("Edit template for tweets. Current template: {}").format(result))
def edit_dm_template(self, *args, **kwargs):
template = self.config["templates"]["dm"]
control = EditTemplate(template=template, type="dm")
result = control.run_dialog()
if result != "": # Template has been saved.
self.config["templates"]["dm"] = result
self.config.write()
self.dialog.templates.dm.SetLabel(_("Edit template for direct messages. Current template: {}").format(result))
def edit_sent_dm_template(self, *args, **kwargs):
template = self.config["templates"]["dm_sent"]
control = EditTemplate(template=template, type="dm")
result = control.run_dialog()
if result != "": # Template has been saved.
self.config["templates"]["dm_sent"] = result
self.config.write()
self.dialog.templates.sent_dm.SetLabel(_("Edit template for sent direct messages. Current template: {}").format(result))
def edit_person_template(self, *args, **kwargs):
template = self.config["templates"]["person"]
control = EditTemplate(template=template, type="person")
result = control.run_dialog()
if result != "": # Template has been saved.
self.config["templates"]["person"] = result
self.config.write()
self.dialog.templates.person.SetLabel(_("Edit template for persons. Current template: {}").format(result))
def save_configuration(self):
if self.config["general"]["relative_times"] != self.dialog.get_value("general", "relative_time"):
self.needs_restart = True
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"]["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"]["max_tweets_per_call"] = self.dialog.get_value("general", "itemsPerApiCall")
if self.config["general"]["load_cache_in_memory"] != self.dialog.get_value("general", "load_cache_in_memory"):
self.config["general"]["load_cache_in_memory"] = self.dialog.get_value("general", "load_cache_in_memory")
self.needs_restart = True
log.debug("Triggered app restart due to change in database strategy management.")
if self.config["general"]["persist_size"] != self.dialog.get_value("general", "persist_size"):
if self.dialog.get_value("general", "persist_size") == '':
self.config["general"]["persist_size"] =-1
else:
try:
self.config["general"]["persist_size"] = int(self.dialog.get_value("general", "persist_size"))
except ValueError:
output.speak("Invalid cache size, setting to default.",True)
self.config["general"]["persist_size"] =1764
if self.config["general"]["reverse_timelines"] != self.dialog.get_value("general", "reverse_timelines"):
self.needs_restart = True
log.debug("Triggered app restart due to change in timeline order.")
self.config["general"]["reverse_timelines"] = self.dialog.get_value("general", "reverse_timelines")
rt = self.dialog.get_value("general", "retweet_mode")
if rt == _(u"Ask"):
self.config["general"]["retweet_mode"] = "ask"
elif rt == _(u"Retweet without comments"):
self.config["general"]["retweet_mode"] = "direct"
else:
self.config["general"]["retweet_mode"] = "comment"
buffers_list = self.dialog.buffers.get_list()
if buffers_list != self.config["general"]["buffer_order"]:
self.needs_restart = True
log.debug("Triggered app restart due to change in buffer ordering.")
self.config["general"]["buffer_order"] = buffers_list
self.config["reporting"]["speech_reporting"] = self.dialog.get_value("reporting", "speech_reporting")
self.config["reporting"]["braille_reporting"] = self.dialog.get_value("reporting", "braille_reporting")
self.config["mysc"]["ocr_language"] = OCRSpace.OcrLangs[self.dialog.extras.ocr_lang.GetSelection()]
if self.config["sound"]["input_device"] != self.dialog.sound.get("input"):
self.config["sound"]["input_device"] = self.dialog.sound.get("input")
try:
self.buffer.session.sound.input.set_device(self.buffer.session.sound.input.find_device_by_name(self.config["sound"]["input_device"]))
except:
self.config["sound"]["input_device"] = "default"
if self.config["sound"]["output_device"] != self.dialog.sound.get("output"):
self.config["sound"]["output_device"] = self.dialog.sound.get("output")
try:
self.buffer.session.sound.output.set_device(self.buffer.session.sound.output.find_device_by_name(self.config["sound"]["output_device"]))
except:
self.config["sound"]["output_device"] = "default"
self.config["sound"]["volume"] = self.dialog.get_value("sound", "volumeCtrl")/100.0
self.config["sound"]["session_mute"] = self.dialog.get_value("sound", "session_mute")
self.config["sound"]["current_soundpack"] = self.dialog.sound.get("soundpack")
self.config["sound"]["indicate_audio"] = self.dialog.get_value("sound", "indicate_audio")
self.config["sound"]["indicate_geo"] = self.dialog.get_value("sound", "indicate_geo")
self.config["sound"]["indicate_img"] = self.dialog.get_value("sound", "indicate_img")
self.config["sound"]["sndup_api_key"] = self.dialog.get_value("extras", "sndup_apiKey")
self.buffer.session.sound.config = self.config["sound"]
self.buffer.session.sound.check_soundpack()
self.config.write()
def toggle_state(self,*args,**kwargs):
return self.dialog.buffers.change_selected_item()
def on_autocompletion_scan(self, *args, **kwargs):
configuration = scan.autocompletionScan(self.buffer.session.settings, self.buffer, self.window)
to_scan = configuration.show_dialog()
if to_scan == True:
configuration.prepare_progress_dialog()
t = threading.Thread(target=configuration.scan)
t.start()
def on_autocompletion_manage(self, *args, **kwargs):
configuration = manage.autocompletionManage(self.buffer.session)
configuration.show_settings()
def add_ignored_client(self, *args, **kwargs):
client = commonMessageDialogs.get_ignored_client()
if client == None: return
if client not in self.config["twitter"]["ignored_clients"]:
self.config["twitter"]["ignored_clients"].append(client)
self.dialog.ignored_clients.append(client)
def remove_ignored_client(self, *args, **kwargs):
if self.dialog.ignored_clients.get_clients() == 0: return
id = self.dialog.ignored_clients.get_client_id()
self.config["twitter"]["ignored_clients"].pop(id)
self.dialog.ignored_clients.remove_(id)
def get_buffers_list(self):
all_buffers=OrderedDict()
all_buffers['home']=_(u"Home")
all_buffers['mentions']=_(u"Mentions")
all_buffers['dm']=_(u"Direct Messages")
all_buffers['sent_dm']=_(u"Sent direct messages")
all_buffers['sent_tweets']=_(u"Sent tweets")
all_buffers['favorites']=_(u"Likes")
all_buffers['followers']=_(u"Followers")
all_buffers['friends']=_(u"Friends")
all_buffers['blocks']=_(u"Blocked users")
all_buffers['muted']=_(u"Muted users")
list_buffers = []
hidden_buffers=[]
all_buffers_keys = list(all_buffers.keys())
# Check buffers shown first.
for i in self.config["general"]["buffer_order"]:
if i in all_buffers_keys:
list_buffers.append((i, all_buffers[i], True))
# This second pass will retrieve all hidden buffers.
for i in all_buffers_keys:
if i not in self.config["general"]["buffer_order"]:
hidden_buffers.append((i, all_buffers[i], False))
list_buffers.extend(hidden_buffers)
return list_buffers
def toggle_buffer_active(self, ev):
change = self.dialog.buffers.get_event(ev)
if change == True:
self.dialog.buffers.change_selected_item()

View File

@@ -1,40 +0,0 @@
# -*- coding: utf-8 -*-
import re
import wx
from typing import List
from sessions.twitter.templates import tweet_variables, dm_variables, person_variables
from wxUI.dialogs.twitterDialogs import templateDialogs
class EditTemplate(object):
def __init__(self, template: str, type: str) -> None:
super(EditTemplate, self).__init__()
self.default_template = template
if type == "tweet":
self.variables = tweet_variables
elif type == "dm":
self.variables = dm_variables
else:
self.variables = person_variables
self.template: str = template
def validate_template(self, template: str) -> bool:
used_variables: List[str] = re.findall("\$\w+", template)
validated: bool = True
for var in used_variables:
if var[1:] not in self.variables:
validated = False
return validated
def run_dialog(self) -> str:
dialog = templateDialogs.EditTemplateDialog(template=self.template, variables=self.variables, default_template=self.default_template)
response = dialog.ShowModal()
if response == wx.ID_SAVE:
validated: bool = self.validate_template(dialog.template.GetValue())
if validated == False:
templateDialogs.invalid_template()
self.template = dialog.template.GetValue()
return self.run_dialog()
else:
return dialog.template.GetValue()
else:
return ""

View File

@@ -1,45 +0,0 @@
# -*- coding: utf-8 -*-
from wxUI.dialogs import trends
import widgetUtils
class trendingTopicsController(object):
def __init__(self, session):
super(trendingTopicsController, self).__init__()
self.countries = {}
self.cities = {}
self.dialog = trends.trendingTopicsDialog()
self.information = session.twitter.available_trends()
self.split_information()
widgetUtils.connect_event(self.dialog.country, widgetUtils.RADIOBUTTON, self.get_places)
widgetUtils.connect_event(self.dialog.city, widgetUtils.RADIOBUTTON, self.get_places)
self.get_places()
def split_information(self):
for i in self.information:
if i["placeType"]["name"] == "Country":
self.countries[i["name"]] = i["woeid"]
else:
self.cities[i["name"]] = i["woeid"]
def get_places(self, event=None):
values = []
if self.dialog.get_active() == "country":
for i in self.information:
if i["placeType"]["name"] == "Country":
values.append(i["name"])
elif self.dialog.get_active() == "city":
for i in self.information:
if i["placeType"]["name"] != "Country":
values.append(i["name"])
self.dialog.set(values)
def get_woeid(self):
selected = self.dialog.get_item()
if self.dialog.get_active() == "country":
woeid = self.countries[selected]
else:
woeid = self.cities[selected]
return woeid
def get_string(self):
return self.dialog.get_item()

View File

@@ -1,128 +0,0 @@
# -*- coding: utf-8 -*-
import wx
import webbrowser
import widgetUtils
import output
from wxUI.dialogs import update_profile, show_user
import logging
log = logging.getLogger("controller.user")
from tweepy.errors import TweepyException, Forbidden, NotFound
from sessions.twitter import utils
class profileController(object):
def __init__(self, session, user=None):
super(profileController, self).__init__()
self.file = None
self.session = session
self.user = user
if user == None:
self.get_data(screen_name=self.session.db["user_name"])
self.dialog = update_profile.updateProfileDialog()
self.fill_profile_fields()
self.uploaded = False
widgetUtils.connect_event(self.dialog.upload_image, widgetUtils.BUTTON_PRESSED, self.upload_image)
else:
try:
self.get_data(screen_name=self.user)
except TweepyException as err:
if type(err) == NotFound:
wx.MessageDialog(None, _(u"That user does not exist"), _(u"Error"), wx.ICON_ERROR).ShowModal()
if type(err) == Forbidden:
wx.MessageDialog(None, _(u"User has been suspended"), _(u"Error"), wx.ICON_ERROR).ShowModal()
log.error("error %s" % (str(err)))
return
self.dialog = show_user.showUserProfile()
string = self.get_user_info()
self.dialog.set("text", string)
self.dialog.set_title(_(u"Information for %s") % (self.data.screen_name))
if self.data.url != None:
self.dialog.enable_url()
widgetUtils.connect_event(self.dialog.url, widgetUtils.BUTTON_PRESSED, self.visit_url)
if self.dialog.get_response() == widgetUtils.OK and self.user == None:
self.do_update()
def get_data(self, screen_name):
self.data = self.session.twitter.get_user(screen_name=screen_name)
if screen_name != self.session.db["user_name"]:
self.friendship_status = self.session.twitter.get_friendship(source_screen_name=self.session.db["user_name"], target_screen_name=screen_name)
def fill_profile_fields(self):
self.dialog.set_name(self.data.name)
if self.data.url != None:
self.dialog.set_url(self.data.url)
if len(self.data.location) > 0:
self.dialog.set_location(self.data.location)
if len(self.data.description) > 0:
self.dialog.set_description(self.data.description)
def get_image(self):
file = self.dialog.upload_picture()
if file != None:
self.file = open(file, "rb")
self.uploaded = True
self.dialog.change_upload_button(self.uploaded)
def discard_image(self):
self.file = None
output.speak(_(u"Discarded"))
self.uploaded = False
self.dialog.change_upload_button(self.uploaded)
def upload_image(self, *args, **kwargs):
if self.uploaded == False:
self.get_image()
elif self.uploaded == True:
self.discard_image()
def do_update(self):
if self.user != None: return
name = self.dialog.get("name")
description = self.dialog.get("description")
location = self.dialog.get("location")
url = self.dialog.get("url")
if self.file != None:
try:
self.session.twitter.update_profile_image(image=self.file)
except TweepyException as e:
output.speak(u"Error %s" % (str(e)))
try:
self.session.twitter.update_profile(name=name, description=description, location=location, url=url)
except TweepyException as e:
output.speak(u"Error %s." % (str(e)))
def get_user_info(self):
string = u""
string = string + _(u"Username: @%s\n") % (self.data.screen_name)
string = string + _(u"Name: %s\n") % (self.data.name)
if self.data.location != "":
string = string + _(u"Location: %s\n") % (self.data.location)
if self.data.url != None:
string = string+ _(u"URL: %s\n") % (self.data.entities["url"]["urls"][0]["expanded_url"])
if self.data.description != "":
if self.data.entities.get("description") != None and self.data.entities["description"].get("urls"):
self.data.description = utils.expand_urls(self.data.description, self.data.entities["description"])
string = string+ _(u"Bio: %s\n") % (self.data.description)
if self.data.protected == True: protected = _(u"Yes")
else: protected = _(u"No")
string = string+ _(u"Protected: %s\n") % (protected)
if hasattr(self, "friendship_status"):
relation = False
friendship = _(u"Relationship: ")
if self.friendship_status[0].following:
friendship += _(u"You follow {0}. ").format(self.data.name,)
relation = True
if self.friendship_status[1].following:
friendship += _(u"{0} is following you.").format(self.data.name,)
relation = True
if relation == True:
string = string+friendship+"\n"
string = string+_(u"Followers: %s\n Friends: %s\n") % (self.data.followers_count, self.data.friends_count)
if self.data.verified == True: verified = _(u"Yes")
else: verified = _(u"No")
string = string+ _(u"Verified: %s\n") % (verified)
string = string+ _(u"Tweets: %s\n") % (self.data.statuses_count)
string = string+ _(u"Likes: %s") % (self.data.favourites_count)
return string
def visit_url(self, *args, **kwargs):
webbrowser.open_new_tab(self.data.url)

View File

@@ -1,85 +0,0 @@
# -*- coding: utf-8 -*-
import widgetUtils
import output
from wxUI.dialogs import userActions
from pubsub import pub
from tweepy.errors import TweepyException
from extra.autocompletionUsers import completion
class userActionsController(object):
def __init__(self, buffer, users=[], default="follow"):
super(userActionsController, self).__init__()
self.buffer = buffer
self.session = buffer.session
self.dialog = userActions.UserActionsDialog(users, default)
widgetUtils.connect_event(self.dialog.autocompletion, widgetUtils.BUTTON_PRESSED, self.autocomplete_users)
if self.dialog.get_response() == widgetUtils.OK:
self.process_action()
def autocomplete_users(self, *args, **kwargs):
c = completion.autocompletionUsers(self.dialog, self.session.session_id)
c.show_menu("dm")
def process_action(self):
action = self.dialog.get_action()
user = self.dialog.get_user()
if user == "": return
getattr(self, action)(user)
def follow(self, user):
try:
self.session.twitter.create_friendship(screen_name=user )
pub.sendMessage("twitter.restart_streaming", session=self.session.session_id)
except TweepyException as err:
output.speak("Error %s" % (str(err)), True)
def unfollow(self, user):
try:
id = self.session.twitter.destroy_friendship(screen_name=user )
pub.sendMessage("twitter.restart_streaming", session=self.session.session_id)
except TweepyException as err:
output.speak("Error %s" % (str(err)), True)
def mute(self, user):
try:
id = self.session.twitter.create_mute(screen_name=user )
pub.sendMessage("twitter.restart_streaming", session=self.session.session_id)
except TweepyException as err:
output.speak("Error %s" % (str(err)), True)
def unmute(self, user):
try:
id = self.session.twitter.destroy_mute(screen_name=user )
pub.sendMessage("twitter.restart_streaming", session=self.session.session_id)
except TweepyException as err:
output.speak("Error %s" % (str(err)), True)
def report(self, user):
try:
id = self.session.twitter.report_spam(screen_name=user )
pub.sendMessage("twitter.restart_streaming", session=self.session.session_id)
except TweepyException as err:
output.speak("Error %s" % (str(err)), True)
def block(self, user):
try:
id = self.session.twitter.create_block(screen_name=user )
pub.sendMessage("twitter.restart_streaming", session=self.session.session_id)
except TweepyException as err:
output.speak("Error %s" % (str(err)), True)
def unblock(self, user):
try:
id = self.session.twitter.destroy_block(screen_name=user )
except TweepyException as err:
output.speak("Error %s" % (str(err)), True)
def ignore_client(self, user):
tweet = self.buffer.get_right_tweet()
if hasattr(tweet, "sender"):
output.speak(_(u"You can't ignore direct messages"))
return
client = tweet.source
if client not in self.session.settings["twitter"]["ignored_clients"]:
self.session.settings["twitter"]["ignored_clients"].append(client)
self.session.settings.write()

View File

@@ -1,39 +0,0 @@
# -*- coding: utf-8 -*-
""" Small utility dessigned to select users from the currently focused item or the autocomplete database. """
import wx
import widgetUtils
from wxUI.dialogs import utils
from extra.autocompletionUsers import completion
class userSelector(object):
def __init__(self, users, session_id, title=_("Select user")):
""" Creates a dialog that chooses an user selector, from where users who have the autocomplete database already filled can also use that feature.
:param users: lists of users extracted from the currently focused item.
:type users: list
:param session_id: ID of the session to instantiate autocomplete database.
:type session_id: str
:param title: Title of the user selector dialog.
:type title: str
"""
self.session_id = session_id
self.dlg = utils.selectUserDialog(users=users, title=title)
widgetUtils.connect_event(self.dlg.autocompletion, widgetUtils.BUTTON_PRESSED, self.on_autocomplete_users)
def on_autocomplete_users(self, *args, **kwargs):
""" performs user autocompletion, if configured properly. """
c = completion.autocompletionUsers(self.dlg, self.session_id)
c.show_menu("dm")
def get_user(self):
""" Actually shows the dialog and returns an user if the dialog was accepted, None otherwise.
:rtype: str or None
"""
if self.dlg.ShowModal() == wx.ID_OK:
user = self.dlg.get_user()
else:
user = None
self.dlg.Destroy()
return user