Prepare for py3 port.

This commit is contained in:
Bill Dengler 2017-06-16 21:06:26 +00:00
parent 6d33f310ab
commit 4bdc2b2a6a
75 changed files with 7017 additions and 6922 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,276 +1,277 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import re from __future__ import absolute_import
import platform import re
import attach import platform
system = platform.system() from . import attach
import widgetUtils system = platform.system()
import output import widgetUtils
import url_shortener import output
import sound import url_shortener
from pubsub import pub import sound
if system == "Windows": from pubsub import pub
from wxUI.dialogs import message, urlList if system == "Windows":
from extra import translator, SpellChecker, autocompletionUsers from wxUI.dialogs import message, urlList
from extra.AudioUploader import audioUploader from extra import translator, SpellChecker, autocompletionUsers
elif system == "Linux": from extra.AudioUploader import audioUploader
from gtkUI.dialogs import message elif system == "Linux":
from twitter import utils from gtkUI.dialogs import message
from twitter import utils
class basicTweet(object):
""" This class handles the tweet main features. Other classes should derive from this class.""" class basicTweet(object):
def __init__(self, session, title, caption, text, messageType="tweet", max=140, *args, **kwargs): """ This class handles the tweet main features. Other classes should derive from this class."""
super(basicTweet, self).__init__() def __init__(self, session, title, caption, text, messageType="tweet", max=140, *args, **kwargs):
self.max = max super(basicTweet, self).__init__()
self.title = title self.max = max
self.session = session self.title = title
self.message = getattr(message, messageType)(title, caption, text, *args, **kwargs) self.session = session
widgetUtils.connect_event(self.message.spellcheck, widgetUtils.BUTTON_PRESSED, self.spellcheck) self.message = getattr(message, messageType)(title, caption, text, *args, **kwargs)
widgetUtils.connect_event(self.message.attach, widgetUtils.BUTTON_PRESSED, self.attach) widgetUtils.connect_event(self.message.spellcheck, widgetUtils.BUTTON_PRESSED, self.spellcheck)
# if system == "Windows": widgetUtils.connect_event(self.message.attach, widgetUtils.BUTTON_PRESSED, self.attach)
# if messageType != "dm": # if system == "Windows":
widgetUtils.connect_event(self.message.text, widgetUtils.ENTERED_TEXT, self.text_processor) # if messageType != "dm":
widgetUtils.connect_event(self.message.shortenButton, widgetUtils.BUTTON_PRESSED, self.shorten) widgetUtils.connect_event(self.message.text, widgetUtils.ENTERED_TEXT, self.text_processor)
widgetUtils.connect_event(self.message.unshortenButton, widgetUtils.BUTTON_PRESSED, self.unshorten) widgetUtils.connect_event(self.message.shortenButton, widgetUtils.BUTTON_PRESSED, self.shorten)
widgetUtils.connect_event(self.message.translateButton, widgetUtils.BUTTON_PRESSED, self.translate) widgetUtils.connect_event(self.message.unshortenButton, widgetUtils.BUTTON_PRESSED, self.unshorten)
if hasattr(self.message, "long_tweet"): widgetUtils.connect_event(self.message.translateButton, widgetUtils.BUTTON_PRESSED, self.translate)
widgetUtils.connect_event(self.message.long_tweet, widgetUtils.CHECKBOX, self.text_processor) if hasattr(self.message, "long_tweet"):
self.attachments = [] widgetUtils.connect_event(self.message.long_tweet, widgetUtils.CHECKBOX, self.text_processor)
self.attachments = []
def translate(self, event=None):
dlg = translator.gui.translateDialog() def translate(self, event=None):
if dlg.get_response() == widgetUtils.OK: dlg = translator.gui.translateDialog()
text_to_translate = self.message.get_text() if dlg.get_response() == widgetUtils.OK:
source = [x[0] for x in translator.translator.available_languages()][dlg.get("source_lang")] text_to_translate = self.message.get_text()
dest = [x[0] for x in translator.translator.available_languages()][dlg.get("dest_lang")] source = [x[0] for x in translator.translator.available_languages()][dlg.get("source_lang")]
msg = translator.translator.translate(text=text_to_translate, source=source, target=dest) dest = [x[0] for x in translator.translator.available_languages()][dlg.get("dest_lang")]
self.message.set_text(msg) msg = translator.translator.translate(text=text_to_translate, source=source, target=dest)
self.text_processor() self.message.set_text(msg)
self.message.text_focus() self.text_processor()
output.speak(_(u"Translated")) self.message.text_focus()
else: output.speak(_(u"Translated"))
return else:
return
def shorten(self, event=None):
urls = utils.find_urls_in_text(self.message.get_text()) def shorten(self, event=None):
if len(urls) == 0: urls = utils.find_urls_in_text(self.message.get_text())
output.speak(_(u"There's no URL to be shortened")) if len(urls) == 0:
self.message.text_focus() output.speak(_(u"There's no URL to be shortened"))
elif len(urls) == 1: self.message.text_focus()
self.message.set_text(self.message.get_text().replace(urls[0], url_shortener.shorten(urls[0]))) elif len(urls) == 1:
output.speak(_(u"URL shortened")) self.message.set_text(self.message.get_text().replace(urls[0], url_shortener.shorten(urls[0])))
self.text_processor() output.speak(_(u"URL shortened"))
self.message.text_focus() self.text_processor()
elif len(urls) > 1: self.message.text_focus()
list_urls = urlList.urlList() elif len(urls) > 1:
list_urls.populate_list(urls) list_urls = urlList.urlList()
if list_urls.get_response() == widgetUtils.OK: list_urls.populate_list(urls)
self.message.set_text(self.message.get_text().replace(urls[list_urls.get_item()], url_shortener.shorten(list_urls.get_string()))) if list_urls.get_response() == widgetUtils.OK:
output.speak(_(u"URL shortened")) self.message.set_text(self.message.get_text().replace(urls[list_urls.get_item()], url_shortener.shorten(list_urls.get_string())))
self.text_processor() output.speak(_(u"URL shortened"))
self.message.text_focus() self.text_processor()
self.message.text_focus()
def unshorten(self, event=None):
urls = utils.find_urls_in_text(self.message.get_text()) def unshorten(self, event=None):
if len(urls) == 0: urls = utils.find_urls_in_text(self.message.get_text())
output.speak(_(u"There's no URL to be expanded")) if len(urls) == 0:
self.message.text_focus() output.speak(_(u"There's no URL to be expanded"))
elif len(urls) == 1: self.message.text_focus()
self.message.set_text(self.message.get_text().replace(urls[0], url_shortener.unshorten(urls[0]))) elif len(urls) == 1:
output.speak(_(u"URL expanded")) self.message.set_text(self.message.get_text().replace(urls[0], url_shortener.unshorten(urls[0])))
self.text_processor() output.speak(_(u"URL expanded"))
self.message.text_focus() self.text_processor()
elif len(urls) > 1: self.message.text_focus()
list_urls = urlList.urlList() elif len(urls) > 1:
list_urls.populate_list(urls) list_urls = urlList.urlList()
if list_urls.get_response() == widgetUtils.OK: list_urls.populate_list(urls)
self.message.set_text(self.message.get_text().replace(urls[list_urls.get_item()], url_shortener.unshorten(list_urls.get_string()))) if list_urls.get_response() == widgetUtils.OK:
output.speak(_(u"URL expanded")) self.message.set_text(self.message.get_text().replace(urls[list_urls.get_item()], url_shortener.unshorten(list_urls.get_string())))
self.text_processor() output.speak(_(u"URL expanded"))
self.message.text_focus() self.text_processor()
self.message.text_focus()
def text_processor(self, *args, **kwargs):
if len(self.message.get_text()) > 1: def text_processor(self, *args, **kwargs):
self.message.enable_button("shortenButton") if len(self.message.get_text()) > 1:
self.message.enable_button("unshortenButton") self.message.enable_button("shortenButton")
else: self.message.enable_button("unshortenButton")
self.message.disable_button("shortenButton") else:
self.message.disable_button("unshortenButton") self.message.disable_button("shortenButton")
if self.message.get("long_tweet") == False: self.message.disable_button("unshortenButton")
self.message.set_title(_(u"%s - %s of %d characters") % (self.title, len(self.message.get_text()), self.max)) if self.message.get("long_tweet") == False:
if len(self.message.get_text()) > self.max: self.message.set_title(_(u"%s - %s of %d characters") % (self.title, len(self.message.get_text()), self.max))
self.session.sound.play("max_length.ogg") if len(self.message.get_text()) > self.max:
else: self.session.sound.play("max_length.ogg")
self.message.set_title(_(u"%s - %s characters") % (self.title, len(self.message.get_text()))) else:
self.message.set_title(_(u"%s - %s characters") % (self.title, len(self.message.get_text())))
def spellcheck(self, event=None):
text = self.message.get_text() def spellcheck(self, event=None):
checker = SpellChecker.spellchecker.spellChecker(text, "") text = self.message.get_text()
if hasattr(checker, "fixed_text"): checker = SpellChecker.spellchecker.spellChecker(text, "")
self.message.set_text(checker.fixed_text) if hasattr(checker, "fixed_text"):
self.text_processor() self.message.set_text(checker.fixed_text)
self.message.text_focus() self.text_processor()
self.message.text_focus()
def attach(self, *args, **kwargs):
def completed_callback(dlg): def attach(self, *args, **kwargs):
url = dlg.uploaderFunction.get_url() def completed_callback(dlg):
pub.unsubscribe(dlg.uploaderDialog.update, "uploading") url = dlg.uploaderFunction.get_url()
dlg.uploaderDialog.destroy() pub.unsubscribe(dlg.uploaderDialog.update, "uploading")
if url != 0: dlg.uploaderDialog.destroy()
self.message.set_text(self.message.get_text()+url+" #audio") if url != 0:
self.text_processor() self.message.set_text(self.message.get_text()+url+" #audio")
else: self.text_processor()
output.speak(_(u"Unable to upload the audio")) else:
dlg.cleanup() output.speak(_(u"Unable to upload the audio"))
dlg = audioUploader.audioUploader(self.session.settings, completed_callback) dlg.cleanup()
self.message.text_focus() dlg = audioUploader.audioUploader(self.session.settings, completed_callback)
self.message.text_focus()
class tweet(basicTweet):
def __init__(self, session, title, caption, text, twishort_enabled, messageType="tweet", max=140, *args, **kwargs): class tweet(basicTweet):
super(tweet, self).__init__(session, title, caption, text, messageType, max, *args, **kwargs) def __init__(self, session, title, caption, text, twishort_enabled, messageType="tweet", max=140, *args, **kwargs):
self.image = None super(tweet, self).__init__(session, title, caption, text, messageType, max, *args, **kwargs)
widgetUtils.connect_event(self.message.upload_image, widgetUtils.BUTTON_PRESSED, self.upload_image) self.image = None
widgetUtils.connect_event(self.message.autocompletionButton, widgetUtils.BUTTON_PRESSED, self.autocomplete_users) widgetUtils.connect_event(self.message.upload_image, widgetUtils.BUTTON_PRESSED, self.upload_image)
if twishort_enabled == False: widgetUtils.connect_event(self.message.autocompletionButton, widgetUtils.BUTTON_PRESSED, self.autocomplete_users)
try: self.message.long_tweet.SetValue(False) if twishort_enabled == False:
except AttributeError: pass try: self.message.long_tweet.SetValue(False)
self.text_processor() except AttributeError: pass
self.text_processor()
def upload_image(self, *args, **kwargs):
a = attach.attach() def upload_image(self, *args, **kwargs):
if len(a.attachments) != 0: a = attach.attach()
self.attachments = a.attachments if len(a.attachments) != 0:
self.attachments = a.attachments
def autocomplete_users(self, *args, **kwargs):
c = autocompletionUsers.completion.autocompletionUsers(self.message, self.session.session_id) def autocomplete_users(self, *args, **kwargs):
c.show_menu() c = autocompletionUsers.completion.autocompletionUsers(self.message, self.session.session_id)
c.show_menu()
class reply(tweet):
def __init__(self, session, title, caption, text, twishort_enabled, users=[], ids=[]): class reply(tweet):
super(reply, self).__init__(session, title, caption, text, twishort_enabled, messageType="reply", users=users) def __init__(self, session, title, caption, text, twishort_enabled, users=[], ids=[]):
self.ids = ids super(reply, self).__init__(session, title, caption, text, twishort_enabled, messageType="reply", users=users)
self.users = users self.ids = ids
if len(users) > 0: self.users = users
widgetUtils.connect_event(self.message.mentionAll, widgetUtils.CHECKBOX, self.mention_all) if len(users) > 0:
self.message.enable_button("mentionAll") widgetUtils.connect_event(self.message.mentionAll, widgetUtils.CHECKBOX, self.mention_all)
self.message.mentionAll.SetValue(self.session.settings["mysc"]["mention_all"]) self.message.enable_button("mentionAll")
if self.message.mentionAll.GetValue() == True: self.message.mentionAll.SetValue(self.session.settings["mysc"]["mention_all"])
self.mention_all() if self.message.mentionAll.GetValue() == True:
self.message.set_cursor_at_end() self.mention_all()
self.text_processor() self.message.set_cursor_at_end()
self.text_processor()
def mention_all(self, *args, **kwargs):
if self.message.mentionAll.GetValue() == True: def mention_all(self, *args, **kwargs):
for i in self.message.checkboxes: if self.message.mentionAll.GetValue() == True:
i.SetValue(True) for i in self.message.checkboxes:
i.Hide() i.SetValue(True)
else: i.Hide()
for i in self.message.checkboxes: else:
i.SetValue(False) for i in self.message.checkboxes:
i.Show() i.SetValue(False)
i.Show()
def get_ids(self):
excluded_ids = "" def get_ids(self):
for i in xrange(0, len(self.message.checkboxes)): excluded_ids = ""
if self.message.checkboxes[i].GetValue() == False: for i in xrange(0, len(self.message.checkboxes)):
excluded_ids = excluded_ids + "{0},".format(self.ids[i],) if self.message.checkboxes[i].GetValue() == False:
return excluded_ids excluded_ids = excluded_ids + "{0},".format(self.ids[i],)
return excluded_ids
def get_people(self):
people = "" def get_people(self):
for i in xrange(0, len(self.message.checkboxes)): people = ""
if self.message.checkboxes[i].GetValue() == True: for i in xrange(0, len(self.message.checkboxes)):
people = people + "{0} ".format(self.message.checkboxes[i].GetLabel(),) if self.message.checkboxes[i].GetValue() == True:
return people people = people + "{0} ".format(self.message.checkboxes[i].GetLabel(),)
return people
class dm(basicTweet):
def __init__(self, session, title, caption, text): class dm(basicTweet):
super(dm, self).__init__(session, title, caption, text, messageType="dm", max=10000) def __init__(self, session, title, caption, text):
widgetUtils.connect_event(self.message.autocompletionButton, widgetUtils.BUTTON_PRESSED, self.autocomplete_users) super(dm, self).__init__(session, title, caption, text, messageType="dm", max=10000)
self.text_processor() widgetUtils.connect_event(self.message.autocompletionButton, widgetUtils.BUTTON_PRESSED, self.autocomplete_users)
self.text_processor()
def autocomplete_users(self, *args, **kwargs):
c = autocompletionUsers.completion.autocompletionUsers(self.message, self.session.session_id) def autocomplete_users(self, *args, **kwargs):
c.show_menu("dm") c = autocompletionUsers.completion.autocompletionUsers(self.message, self.session.session_id)
c.show_menu("dm")
class viewTweet(basicTweet):
def __init__(self, tweet, tweetList, is_tweet=True): class viewTweet(basicTweet):
""" 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. def __init__(self, tweet, tweetList, is_tweet=True):
param tweet: A dictionary that represents a full tweet or a string for non-tweets. """ 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 tweetList: If is_tweet is set to True, this could be a list of quoted tweets. param tweet: A dictionary that represents a full tweet or a string for non-tweets.
param is_tweet: True or false, depending wether the passed object is a tweet or not.""" param tweetList: If is_tweet is set to True, this could be a list of quoted tweets.
if is_tweet == True: param is_tweet: True or false, depending wether the passed object is a tweet or not."""
image_description = [] if is_tweet == True:
text = "" image_description = []
for i in xrange(0, len(tweetList)): text = ""
# tweets with message keys are longer tweets, the message value is the full messaje taken from twishort. for i in xrange(0, len(tweetList)):
if tweetList[i].has_key("message") and tweetList[i]["is_quote_status"] == False: # tweets with message keys are longer tweets, the message value is the full messaje taken from twishort.
value = "message" if "message" in tweetList[i] and tweetList[i]["is_quote_status"] == False:
else: value = "message"
value = "full_text" else:
if tweetList[i].has_key("retweeted_status") and tweetList[i]["is_quote_status"] == False: value = "full_text"
if tweetList[i].has_key("message") == False: if "retweeted_status" in tweetList[i] and tweetList[i]["is_quote_status"] == False:
text = text + "rt @%s: %s\n" % (tweetList[i]["retweeted_status"]["user"]["screen_name"], tweetList[i]["retweeted_status"]["full_text"]) if ("message" in tweetList[i]) == False:
else: text = text + "rt @%s: %s\n" % (tweetList[i]["retweeted_status"]["user"]["screen_name"], tweetList[i]["retweeted_status"]["full_text"])
text = text + "rt @%s: %s\n" % (tweetList[i]["retweeted_status"]["user"]["screen_name"], tweetList[i][value]) else:
else: text = text + "rt @%s: %s\n" % (tweetList[i]["retweeted_status"]["user"]["screen_name"], tweetList[i][value])
text = text + " @%s: %s\n" % (tweetList[i]["user"]["screen_name"], tweetList[i][value]) else:
# tweets with extended_entities could include image descriptions. text = text + " @%s: %s\n" % (tweetList[i]["user"]["screen_name"], tweetList[i][value])
if tweetList[i].has_key("extended_entities") and tweetList[i]["extended_entities"].has_key("media"): # tweets with extended_entities could include image descriptions.
for z in tweetList[i]["extended_entities"]["media"]: if "extended_entities" in tweetList[i] and "media" in tweetList[i]["extended_entities"]:
if z.has_key("ext_alt_text") and z["ext_alt_text"] != None: for z in tweetList[i]["extended_entities"]["media"]:
image_description.append(z["ext_alt_text"]) if "ext_alt_text" in z and z["ext_alt_text"] != None:
if tweetList[i].has_key("retweeted_status") and tweetList[i]["retweeted_status"].has_key("extended_entities") and tweetList[i]["retweeted_status"]["extended_entities"].has_key("media"): image_description.append(z["ext_alt_text"])
for z in tweetList[i]["retweeted_status"]["extended_entities"]["media"]: if "retweeted_status" in tweetList[i] and "extended_entities" in tweetList[i]["retweeted_status"] and "media" in tweetList[i]["retweeted_status"]["extended_entities"]:
if z.has_key("ext_alt_text") and z["ext_alt_text"] != None: for z in tweetList[i]["retweeted_status"]["extended_entities"]["media"]:
image_description.append(z["ext_alt_text"]) if "ext_alt_text" in z and z["ext_alt_text"] != None:
# set rt and likes counters. image_description.append(z["ext_alt_text"])
rt_count = str(tweet["retweet_count"]) # set rt and likes counters.
favs_count = str(tweet["favorite_count"]) rt_count = str(tweet["retweet_count"])
# Gets the client from where this tweet was made. favs_count = str(tweet["favorite_count"])
source = str(re.sub(r"(?s)<.*?>", "", tweet["source"].encode("utf-8"))) # Gets the client from where this tweet was made.
if text == "": source = str(re.sub(r"(?s)<.*?>", "", tweet["source"].encode("utf-8")))
if tweet.has_key("message"): if text == "":
value = "message" if "message" in tweet:
else: value = "message"
value = "full_text" else:
if tweet.has_key("retweeted_status"): value = "full_text"
if tweet.has_key("message") == False: if "retweeted_status" in tweet:
text = "rt @%s: %s" % (tweet["retweeted_status"]["user"]["screen_name"], tweet["retweeted_status"]["full_text"]) if ("message" in tweet) == False:
else: text = "rt @%s: %s" % (tweet["retweeted_status"]["user"]["screen_name"], tweet["retweeted_status"]["full_text"])
text = "rt @%s: %s" % (tweet["retweeted_status"]["user"]["screen_name"], tweet[value]) else:
else: text = "rt @%s: %s" % (tweet["retweeted_status"]["user"]["screen_name"], tweet[value])
text = tweet[value] else:
text = self.clear_text(text) text = tweet[value]
if tweet.has_key("extended_entities") and tweet["extended_entities"].has_key("media"): text = self.clear_text(text)
for z in tweet["extended_entities"]["media"]: if "extended_entities" in tweet and "media" in tweet["extended_entities"]:
if z.has_key("ext_alt_text") and z["ext_alt_text"] != None: for z in tweet["extended_entities"]["media"]:
image_description.append(z["ext_alt_text"]) if "ext_alt_text" in z and z["ext_alt_text"] != None:
if tweet.has_key("retweeted_status") and tweet["retweeted_status"].has_key("extended_entities") and tweet["retweeted_status"]["extended_entities"].has_key("media"): image_description.append(z["ext_alt_text"])
for z in tweet["retweeted_status"]["extended_entities"]["media"]: if "retweeted_status" in tweet and "extended_entities" in tweet["retweeted_status"] and "media" in tweet["retweeted_status"]["extended_entities"]:
if z.has_key("ext_alt_text") and z["ext_alt_text"] != None: for z in tweet["retweeted_status"]["extended_entities"]["media"]:
image_description.append(z["ext_alt_text"]) if "ext_alt_text" in z and z["ext_alt_text"] != None:
self.message = message.viewTweet(text, rt_count, favs_count, source.decode("utf-8")) image_description.append(z["ext_alt_text"])
self.message.set_title(len(text)) self.message = message.viewTweet(text, rt_count, favs_count, source.decode("utf-8"))
[self.message.set_image_description(i) for i in image_description] self.message.set_title(len(text))
else: [self.message.set_image_description(i) for i in image_description]
text = tweet else:
self.message = message.viewNonTweet(text) text = tweet
widgetUtils.connect_event(self.message.spellcheck, widgetUtils.BUTTON_PRESSED, self.spellcheck) self.message = message.viewNonTweet(text)
widgetUtils.connect_event(self.message.translateButton, widgetUtils.BUTTON_PRESSED, self.translate) widgetUtils.connect_event(self.message.spellcheck, widgetUtils.BUTTON_PRESSED, self.spellcheck)
if self.contain_urls() == True: widgetUtils.connect_event(self.message.translateButton, widgetUtils.BUTTON_PRESSED, self.translate)
self.message.enable_button("unshortenButton") if self.contain_urls() == True:
widgetUtils.connect_event(self.message.unshortenButton, widgetUtils.BUTTON_PRESSED, self.unshorten) self.message.enable_button("unshortenButton")
self.message.get_response() widgetUtils.connect_event(self.message.unshortenButton, widgetUtils.BUTTON_PRESSED, self.unshorten)
self.message.get_response()
def contain_urls(self):
if len(utils.find_urls_in_text(self.message.get_text())) > 0: def contain_urls(self):
return True if len(utils.find_urls_in_text(self.message.get_text())) > 0:
return False return True
return False
def clear_text(self, text):
urls = utils.find_urls_in_text(text) def clear_text(self, text):
for i in urls: urls = utils.find_urls_in_text(text)
if "https://twitter.com/" in i: for i in urls:
text = text.replace(i, "\n") if "https://twitter.com/" in i:
return text text = text.replace(i, "\n")
return text

View File

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

View File

@ -1,178 +1,179 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
############################################################ ############################################################
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net> # Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or # the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
############################################################ ############################################################
import widgetUtils from __future__ import absolute_import
import wx_ui import widgetUtils
import wx_transfer_dialogs from . import wx_ui
import transfer from . import wx_transfer_dialogs
import output from . import transfer
import tempfile import output
import sound import tempfile
import os import sound
import config import os
from pubsub import pub import config
from mysc.thread_utils import call_threaded from pubsub import pub
import sound_lib from mysc.thread_utils import call_threaded
import logging import sound_lib
import logging
log = logging.getLogger("extra.AudioUploader.audioUploader")
log = logging.getLogger("extra.AudioUploader.audioUploader")
class audioUploader(object):
def __init__(self, configFile, completed_callback): class audioUploader(object):
self.config = configFile def __init__(self, configFile, completed_callback):
super(audioUploader, self).__init__() self.config = configFile
self.dialog = wx_ui.audioDialog(services=self.get_available_services()) super(audioUploader, self).__init__()
self.file = None self.dialog = wx_ui.audioDialog(services=self.get_available_services())
self.recorded = False self.file = None
self.recording = None self.recorded = False
self.playing = None self.recording = None
widgetUtils.connect_event(self.dialog.play, widgetUtils.BUTTON_PRESSED, self.on_play) self.playing = None
widgetUtils.connect_event(self.dialog.pause, widgetUtils.BUTTON_PRESSED, self.on_pause) widgetUtils.connect_event(self.dialog.play, widgetUtils.BUTTON_PRESSED, self.on_play)
widgetUtils.connect_event(self.dialog.record, widgetUtils.BUTTON_PRESSED, self.on_record) widgetUtils.connect_event(self.dialog.pause, widgetUtils.BUTTON_PRESSED, self.on_pause)
widgetUtils.connect_event(self.dialog.attach_exists, widgetUtils.BUTTON_PRESSED, self.on_attach_exists) widgetUtils.connect_event(self.dialog.record, widgetUtils.BUTTON_PRESSED, self.on_record)
widgetUtils.connect_event(self.dialog.discard, widgetUtils.BUTTON_PRESSED, self.on_discard) widgetUtils.connect_event(self.dialog.attach_exists, widgetUtils.BUTTON_PRESSED, self.on_attach_exists)
if self.dialog.get_response() == widgetUtils.OK: widgetUtils.connect_event(self.dialog.discard, widgetUtils.BUTTON_PRESSED, self.on_discard)
self.postprocess() if self.dialog.get_response() == widgetUtils.OK:
log.debug("Uploading file %s to %s..." % (self.file, self.dialog.get("services"))) self.postprocess()
self.uploaderDialog = wx_transfer_dialogs.UploadDialog(self.file) log.debug("Uploading file %s to %s..." % (self.file, self.dialog.get("services")))
output.speak(_(u"Attaching...")) self.uploaderDialog = wx_transfer_dialogs.UploadDialog(self.file)
if self.dialog.get("services") == "SNDUp": output.speak(_(u"Attaching..."))
base_url = "http://sndup.net/post.php" if self.dialog.get("services") == "SNDUp":
if len(self.config["sound"]["sndup_api_key"]) > 0: base_url = "http://sndup.net/post.php"
url = base_url + '?apikey=' + self.config['sound']['sndup_api_key'] if len(self.config["sound"]["sndup_api_key"]) > 0:
else: url = base_url + '?apikey=' + self.config['sound']['sndup_api_key']
url = base_url else:
self.uploaderFunction = transfer.Upload(obj=self, field='file', url=url, filename=self.file, completed_callback=completed_callback) url = base_url
pub.subscribe(self.uploaderDialog.update, "uploading") self.uploaderFunction = transfer.Upload(obj=self, field='file', url=url, filename=self.file, completed_callback=completed_callback)
self.uploaderDialog.get_response(self.uploaderFunction.perform_threaded) pub.subscribe(self.uploaderDialog.update, "uploading")
self.uploaderDialog.get_response(self.uploaderFunction.perform_threaded)
def get_available_services(self):
services = [] def get_available_services(self):
services.append("SNDUp") services = []
return services services.append("SNDUp")
return services
def on_pause(self, *args, **kwargs):
if self.dialog.get("pause") == _(u"Pause"): def on_pause(self, *args, **kwargs):
self.recording.pause() if self.dialog.get("pause") == _(u"Pause"):
self.dialog.set("pause", _(u"&Resume")) self.recording.pause()
elif self.dialog.get("pause") == _(u"Resume"): self.dialog.set("pause", _(u"&Resume"))
self.recording.play() elif self.dialog.get("pause") == _(u"Resume"):
self.dialog.set("pause", _(U"&Pause")) self.recording.play()
self.dialog.set("pause", _(U"&Pause"))
def on_record(self, *args, **kwargs):
if self.recording != None: def on_record(self, *args, **kwargs):
self.stop_recording() if self.recording != None:
self.dialog.disable_control("pause") self.stop_recording()
else: self.dialog.disable_control("pause")
self.start_recording() else:
self.dialog.enable_control("pause") self.start_recording()
self.dialog.enable_control("pause")
def start_recording(self):
self.dialog.disable_control("attach_exists") def start_recording(self):
self.file = tempfile.mktemp(suffix='.wav') self.dialog.disable_control("attach_exists")
self.recording = sound.recording(self.file) self.file = tempfile.mktemp(suffix='.wav')
self.recording.play() self.recording = sound.recording(self.file)
self.dialog.set("record", _(u"&Stop")) self.recording.play()
output.speak(_(u"Recording")) self.dialog.set("record", _(u"&Stop"))
output.speak(_(u"Recording"))
def stop_recording(self):
self.recording.stop() def stop_recording(self):
self.recording.free() self.recording.stop()
output.speak(_(u"Stopped")) self.recording.free()
self.recorded = True output.speak(_(u"Stopped"))
self.dialog.set("record", _(u"&Record")) self.recorded = True
self.file_attached() self.dialog.set("record", _(u"&Record"))
self.file_attached()
def file_attached(self):
self.dialog.set("pause", _(u"&Pause")) def file_attached(self):
self.dialog.disable_control("record") self.dialog.set("pause", _(u"&Pause"))
self.dialog.enable_control("play") self.dialog.disable_control("record")
self.dialog.enable_control("discard") self.dialog.enable_control("play")
self.dialog.disable_control("attach_exists") self.dialog.enable_control("discard")
self.dialog.enable_control("attach") self.dialog.disable_control("attach_exists")
self.dialog.play.SetFocus() self.dialog.enable_control("attach")
self.dialog.play.SetFocus()
def on_discard(self, *args, **kwargs):
if self.playing: def on_discard(self, *args, **kwargs):
self._stop() if self.playing:
if self.recording != None: self._stop()
self.cleanup() if self.recording != None:
self.dialog.disable_control("attach") self.cleanup()
self.dialog.disable_control("play") self.dialog.disable_control("attach")
self.file = None self.dialog.disable_control("play")
self.dialog.enable_control("record") self.file = None
self.dialog.enable_control("attach_exists") self.dialog.enable_control("record")
self.dialog.record.SetFocus() self.dialog.enable_control("attach_exists")
self.dialog.disable_control("discard") self.dialog.record.SetFocus()
self.recording = None self.dialog.disable_control("discard")
output.speak(_(u"Discarded")) self.recording = None
output.speak(_(u"Discarded"))
def on_play(self, *args, **kwargs):
if not self.playing: def on_play(self, *args, **kwargs):
call_threaded(self._play) if not self.playing:
else: call_threaded(self._play)
self._stop() else:
self._stop()
def _play(self):
output.speak(_(u"Playing...")) def _play(self):
# try: output.speak(_(u"Playing..."))
self.playing = sound_lib.stream.FileStream(file=unicode(self.file), flags=sound_lib.stream.BASS_UNICODE) # try:
self.playing.play() self.playing = sound_lib.stream.FileStream(file=unicode(self.file), flags=sound_lib.stream.BASS_UNICODE)
self.dialog.set("play", _(u"&Stop")) self.playing.play()
try: self.dialog.set("play", _(u"&Stop"))
while self.playing.is_playing: try:
pass while self.playing.is_playing:
self.dialog.set("play", _(u"&Play")) pass
self.playing.free() self.dialog.set("play", _(u"&Play"))
self.playing = None self.playing.free()
except: self.playing = None
pass except:
pass
def _stop(self):
output.speak(_(u"Stopped")) def _stop(self):
self.playing.stop() output.speak(_(u"Stopped"))
self.playing.free() self.playing.stop()
self.dialog.set("play", _(u"&Play")) self.playing.free()
self.playing = None self.dialog.set("play", _(u"&Play"))
self.playing = None
def postprocess(self):
if self.file.lower().endswith('.wav'): def postprocess(self):
output.speak(_(u"Recoding audio...")) if self.file.lower().endswith('.wav'):
sound.recode_audio(self.file) output.speak(_(u"Recoding audio..."))
self.wav_file = self.file sound.recode_audio(self.file)
self.file = '%s.ogg' % self.file[:-4] self.wav_file = self.file
self.file = '%s.ogg' % self.file[:-4]
def cleanup(self):
if self.playing and self.playing.is_playing: def cleanup(self):
self.playing.stop() if self.playing and self.playing.is_playing:
if self.recording != None: self.playing.stop()
if self.recording.is_playing: if self.recording != None:
self.recording.stop() if self.recording.is_playing:
try: self.recording.stop()
self.recording.free() try:
except: self.recording.free()
pass except:
os.remove(self.file) pass
if hasattr(self, 'wav_file'): os.remove(self.file)
os.remove(self.wav_file) if hasattr(self, 'wav_file'):
os.remove(self.wav_file)
def on_attach_exists(self, *args, **kwargs):
self.file = self.dialog.get_file() def on_attach_exists(self, *args, **kwargs):
if self.file != False: self.file = self.dialog.get_file()
self.file_attached() if self.file != False:
self.file_attached()

View File

@ -1,9 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import
import sys import sys
import threading import threading
import time import time
import logging import logging
from utils import convert_bytes from .utils import convert_bytes
from pubsub import pub from pubsub import pub
log = logging.getLogger("extra.AudioUploader.transfer") log = logging.getLogger("extra.AudioUploader.transfer")
from requests_toolbelt.multipart.encoder import MultipartEncoder, MultipartEncoderMonitor from requests_toolbelt.multipart.encoder import MultipartEncoder, MultipartEncoderMonitor

View File

@ -1,61 +1,62 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import wx from __future__ import absolute_import
from utils import * import wx
import widgetUtils from .utils import *
import widgetUtils
class UploadDialog(widgetUtils.BaseDialog):
class UploadDialog(widgetUtils.BaseDialog):
def __init__(self, filename, *args, **kwargs):
super(UploadDialog, self).__init__(parent=None, id=wx.NewId(), *args, **kwargs) def __init__(self, filename, *args, **kwargs):
self.pane = wx.Panel(self) super(UploadDialog, self).__init__(parent=None, id=wx.NewId(), *args, **kwargs)
self.progress_bar = wx.Gauge(parent=self.pane) self.pane = wx.Panel(self)
fileBox = wx.BoxSizer(wx.HORIZONTAL) self.progress_bar = wx.Gauge(parent=self.pane)
fileLabel = wx.StaticText(self.pane, -1, _(u"File")) fileBox = wx.BoxSizer(wx.HORIZONTAL)
self.file = wx.TextCtrl(self.pane, -1, value=filename, style=wx.TE_READONLY|wx.TE_MULTILINE, size=(200, 100)) fileLabel = wx.StaticText(self.pane, -1, _(u"File"))
self.file.SetFocus() self.file = wx.TextCtrl(self.pane, -1, value=filename, style=wx.TE_READONLY|wx.TE_MULTILINE, size=(200, 100))
fileBox.Add(fileLabel) self.file.SetFocus()
fileBox.Add(self.file) fileBox.Add(fileLabel)
currentAmountBox = wx.BoxSizer(wx.HORIZONTAL) fileBox.Add(self.file)
current_amount_label = wx.StaticText(self.pane, -1, _(u"Transferred")) currentAmountBox = wx.BoxSizer(wx.HORIZONTAL)
self.current_amount = wx.TextCtrl(self.pane, -1, value='0', style=wx.TE_READONLY|wx.TE_MULTILINE) current_amount_label = wx.StaticText(self.pane, -1, _(u"Transferred"))
currentAmountBox.Add(current_amount_label) self.current_amount = wx.TextCtrl(self.pane, -1, value='0', style=wx.TE_READONLY|wx.TE_MULTILINE)
currentAmountBox.Add(self.current_amount) currentAmountBox.Add(current_amount_label)
totalSizeBox = wx.BoxSizer(wx.HORIZONTAL) currentAmountBox.Add(self.current_amount)
total_size_label = wx.StaticText(self.pane, -1, _(u"Total file size")) totalSizeBox = wx.BoxSizer(wx.HORIZONTAL)
self.total_size = wx.TextCtrl(self.pane, -1, value='0', style=wx.TE_READONLY|wx.TE_MULTILINE) total_size_label = wx.StaticText(self.pane, -1, _(u"Total file size"))
totalSizeBox.Add(total_size_label) self.total_size = wx.TextCtrl(self.pane, -1, value='0', style=wx.TE_READONLY|wx.TE_MULTILINE)
totalSizeBox.Add(self.total_size) totalSizeBox.Add(total_size_label)
speedBox = wx.BoxSizer(wx.HORIZONTAL) totalSizeBox.Add(self.total_size)
speedLabel = wx.StaticText(self.pane, -1, _(u"Transfer rate")) speedBox = wx.BoxSizer(wx.HORIZONTAL)
self.speed = wx.TextCtrl(self.pane, -1, style=wx.TE_READONLY|wx.TE_MULTILINE, value="0 Kb/s") speedLabel = wx.StaticText(self.pane, -1, _(u"Transfer rate"))
speedBox.Add(speedLabel) self.speed = wx.TextCtrl(self.pane, -1, style=wx.TE_READONLY|wx.TE_MULTILINE, value="0 Kb/s")
speedBox.Add(self.speed) speedBox.Add(speedLabel)
etaBox = wx.BoxSizer(wx.HORIZONTAL) speedBox.Add(self.speed)
etaLabel = wx.StaticText(self.pane, -1, _(u"Time left")) etaBox = wx.BoxSizer(wx.HORIZONTAL)
self.eta = wx.TextCtrl(self.pane, -1, style=wx.TE_READONLY|wx.TE_MULTILINE, value="Unknown", size=(200, 100)) etaLabel = wx.StaticText(self.pane, -1, _(u"Time left"))
etaBox.Add(etaLabel) self.eta = wx.TextCtrl(self.pane, -1, style=wx.TE_READONLY|wx.TE_MULTILINE, value="Unknown", size=(200, 100))
etaBox.Add(self.eta) etaBox.Add(etaLabel)
self.create_buttons() etaBox.Add(self.eta)
sizer = wx.BoxSizer(wx.VERTICAL) self.create_buttons()
sizer.Add(fileBox) sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(currentAmountBox) sizer.Add(fileBox)
sizer.Add(totalSizeBox) sizer.Add(currentAmountBox)
sizer.Add(speedBox) sizer.Add(totalSizeBox)
sizer.Add(etaBox) sizer.Add(speedBox)
sizer.Add(self.progress_bar) sizer.Add(etaBox)
self.pane.SetSizerAndFit(sizer) sizer.Add(self.progress_bar)
self.pane.SetSizerAndFit(sizer)
def update(self, data):
wx.CallAfter(self.progress_bar.SetValue, data["percent"]) def update(self, data):
wx.CallAfter(self.current_amount.SetValue, '%s (%d%%)' % (convert_bytes(data["current"]), data["percent"])) wx.CallAfter(self.progress_bar.SetValue, data["percent"])
wx.CallAfter(self.total_size.SetValue, convert_bytes(data["total"])) wx.CallAfter(self.current_amount.SetValue, '%s (%d%%)' % (convert_bytes(data["current"]), data["percent"]))
wx.CallAfter(self.speed.SetValue, data["speed"]) wx.CallAfter(self.total_size.SetValue, convert_bytes(data["total"]))
if data["eta"]: wx.CallAfter(self.speed.SetValue, data["speed"])
wx.CallAfter(self.eta.SetValue, seconds_to_string(data["eta"])) if data["eta"]:
wx.CallAfter(self.eta.SetValue, seconds_to_string(data["eta"]))
def create_buttons(self):
self.cancel_button = wx.Button(parent=self.pane, id=wx.ID_CANCEL) def create_buttons(self):
self.cancel_button = wx.Button(parent=self.pane, id=wx.ID_CANCEL)
def get_response(self, fn):
wx.CallAfter(fn, 0.01) def get_response(self, fn):
self.ShowModal() wx.CallAfter(fn, 0.01)
self.ShowModal()

View File

@ -1 +1,2 @@
from soundsTutorial import soundsTutorial from __future__ import absolute_import
from .soundsTutorial import soundsTutorial

View File

@ -1,34 +1,35 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import platform from __future__ import absolute_import
import widgetUtils import platform
import os import widgetUtils
import paths import os
import logging import paths
log = logging.getLogger("extra.SoundsTutorial.soundsTutorial") import logging
import soundsTutorial_constants log = logging.getLogger("extra.SoundsTutorial.soundsTutorial")
if platform.system() == "Windows": from . import soundsTutorial_constants
import wx_ui as UI if platform.system() == "Windows":
elif platform.system() == "Linux": from . import wx_ui as UI
import gtk_ui as UI elif platform.system() == "Linux":
from . import gtk_ui as UI
class soundsTutorial(object):
def __init__(self, sessionObject): class soundsTutorial(object):
log.debug("Creating sounds tutorial object...") def __init__(self, sessionObject):
super(soundsTutorial, self).__init__() log.debug("Creating sounds tutorial object...")
self.session = sessionObject super(soundsTutorial, self).__init__()
self.actions = [] self.session = sessionObject
log.debug("Loading actions for sounds tutorial...") self.actions = []
[self.actions.append(i[1]) for i in soundsTutorial_constants.actions] log.debug("Loading actions for sounds tutorial...")
self.files = [] [self.actions.append(i[1]) for i in soundsTutorial_constants.actions]
log.debug("Searching sound files...") self.files = []
[self.files.append(i[0]) for i in soundsTutorial_constants.actions] log.debug("Searching sound files...")
log.debug("Creating dialog...") [self.files.append(i[0]) for i in soundsTutorial_constants.actions]
self.dialog = UI.soundsTutorialDialog(self.actions) log.debug("Creating dialog...")
widgetUtils.connect_event(self.dialog.play, widgetUtils.BUTTON_PRESSED, self.on_play) self.dialog = UI.soundsTutorialDialog(self.actions)
self.dialog.get_response() widgetUtils.connect_event(self.dialog.play, widgetUtils.BUTTON_PRESSED, self.on_play)
self.dialog.get_response()
def on_play(self, *args, **kwargs):
try: def on_play(self, *args, **kwargs):
self.session.sound.play(self.files[self.dialog.get_selection()]+".ogg") try:
except: self.session.sound.play(self.files[self.dialog.get_selection()]+".ogg")
except:
log.exception("Error playing the %s sound" % (self.files[self.dialog.items.GetSelection()],)) log.exception("Error playing the %s sound" % (self.files[self.dialog.items.GetSelection()],))

View File

@ -1,28 +1,30 @@
#-*- coding: utf-8 -*- #-*- coding: utf-8 -*-
import reverse_sort from __future__ import absolute_import
import application #-*- coding: utf-8 -*-
actions = reverse_sort.reverse_sort([ ("audio", _(u"Audio tweet.")), from . import reverse_sort
("create_timeline", _(u"User timeline buffer created.")), import application
("delete_timeline", _(u"Buffer destroied.")), actions = reverse_sort.reverse_sort([ ("audio", _(u"Audio tweet.")),
("dm_received", _(u"Direct message received.")), ("create_timeline", _(u"User timeline buffer created.")),
("dm_sent", _(u"Direct message sent.")), ("delete_timeline", _(u"Buffer destroied.")),
("error", _(u"Error.")), ("dm_received", _(u"Direct message received.")),
("favourite", _(u"Tweet liked.")), ("dm_sent", _(u"Direct message sent.")),
("favourites_timeline_updated", _(u"Likes buffer updated.")), ("error", _(u"Error.")),
("geo", _(u"Geotweet.")), ("favourite", _(u"Tweet liked.")),
("image", _("Tweet contains one or more images")), ("favourites_timeline_updated", _(u"Likes buffer updated.")),
("limit", _(u"Boundary reached.")), ("geo", _(u"Geotweet.")),
("list_tweet", _(u"List updated.")), ("image", _("Tweet contains one or more images")),
("max_length", _(u"Too many characters.")), ("limit", _(u"Boundary reached.")),
("mention_received", _(u"Mention received.")), ("list_tweet", _(u"List updated.")),
("new_event", _(u"New event.")), ("max_length", _(u"Too many characters.")),
("ready", _(u"{0} is ready.").format(application.name,)), ("mention_received", _(u"Mention received.")),
("reply_send", _(u"Mention sent.")), ("new_event", _(u"New event.")),
("retweet_send", _(u"Tweet retweeted.")), ("ready", _(u"{0} is ready.").format(application.name,)),
("search_updated", _(u"Search buffer updated.")), ("reply_send", _(u"Mention sent.")),
("tweet_received", _(u"Tweet received.")), ("retweet_send", _(u"Tweet retweeted.")),
("tweet_send", _(u"Tweet sent.")), ("search_updated", _(u"Search buffer updated.")),
("trends_updated", _(u"Trending topics buffer updated.")), ("tweet_received", _(u"Tweet received.")),
("tweet_timeline", _(u"New tweet in user timeline buffer.")), ("tweet_send", _(u"Tweet sent.")),
("update_followers", _(u"New follower.")), ("trends_updated", _(u"Trending topics buffer updated.")),
("volume_changed", _(u"Volume changed."))]) ("tweet_timeline", _(u"New tweet in user timeline buffer.")),
("update_followers", _(u"New follower.")),
("volume_changed", _(u"Volume changed."))])

View File

@ -1,4 +1,5 @@
import spellchecker from __future__ import absolute_import
import platform from . import spellchecker
if platform.system() == "Windows": import platform
from wx_ui import * if platform.system() == "Windows":
from .wx_ui import *

View File

@ -1,70 +1,71 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import logging from __future__ import absolute_import
log = logging.getLogger("extra.SpellChecker.spellChecker") import logging
import wx_ui log = logging.getLogger("extra.SpellChecker.spellChecker")
import widgetUtils from . import wx_ui
import output import widgetUtils
import config import output
import languageHandler import config
from enchant.checker import SpellChecker import languageHandler
from enchant.errors import DictNotFoundError from enchant.checker import SpellChecker
from enchant import tokenize from enchant.errors import DictNotFoundError
import twitterFilter from enchant import tokenize
from . import twitterFilter
class spellChecker(object):
def __init__(self, text, dictionary): class spellChecker(object):
super(spellChecker, self).__init__() def __init__(self, text, dictionary):
log.debug("Creating the SpellChecker object. Dictionary: %s" % (dictionary,)) super(spellChecker, self).__init__()
self.active = True log.debug("Creating the SpellChecker object. Dictionary: %s" % (dictionary,))
try: self.active = True
if config.app["app-settings"]["language"] == "system": try:
log.debug("Using the system language") if config.app["app-settings"]["language"] == "system":
self.checker = SpellChecker(languageHandler.curLang[:2], filters=[twitterFilter.TwitterFilter, tokenize.EmailFilter, tokenize.URLFilter]) log.debug("Using the system language")
else: self.checker = SpellChecker(languageHandler.curLang[:2], filters=[twitterFilter.TwitterFilter, tokenize.EmailFilter, tokenize.URLFilter])
log.debug("Using language: %s" % (languageHandler.getLanguage(),)) else:
self.checker = SpellChecker(languageHandler.getLanguage()[:2], filters=[twitterFilter.TwitterFilter, tokenize.EmailFilter, tokenize.URLFilter]) log.debug("Using language: %s" % (languageHandler.getLanguage(),))
self.checker.set_text(text) self.checker = SpellChecker(languageHandler.getLanguage()[:2], filters=[twitterFilter.TwitterFilter, tokenize.EmailFilter, tokenize.URLFilter])
except DictNotFoundError: self.checker.set_text(text)
log.exception("Dictionary for language %s not found." % (dictionary,)) except DictNotFoundError:
wx_ui.dict_not_found_error() log.exception("Dictionary for language %s not found." % (dictionary,))
self.active = False wx_ui.dict_not_found_error()
if self.active == True: self.active = False
log.debug("Creating dialog...") if self.active == True:
self.dialog = wx_ui.spellCheckerDialog() log.debug("Creating dialog...")
widgetUtils.connect_event(self.dialog.ignore, widgetUtils.BUTTON_PRESSED, self.ignore) self.dialog = wx_ui.spellCheckerDialog()
widgetUtils.connect_event(self.dialog.ignoreAll, widgetUtils.BUTTON_PRESSED, self.ignoreAll) widgetUtils.connect_event(self.dialog.ignore, widgetUtils.BUTTON_PRESSED, self.ignore)
widgetUtils.connect_event(self.dialog.replace, widgetUtils.BUTTON_PRESSED, self.replace) widgetUtils.connect_event(self.dialog.ignoreAll, widgetUtils.BUTTON_PRESSED, self.ignoreAll)
widgetUtils.connect_event(self.dialog.replaceAll, widgetUtils.BUTTON_PRESSED, self.replaceAll) widgetUtils.connect_event(self.dialog.replace, widgetUtils.BUTTON_PRESSED, self.replace)
self.check() widgetUtils.connect_event(self.dialog.replaceAll, widgetUtils.BUTTON_PRESSED, self.replaceAll)
self.dialog.get_response() self.check()
self.fixed_text = self.checker.get_text() self.dialog.get_response()
self.fixed_text = self.checker.get_text()
def check(self):
try: def check(self):
self.checker.next() try:
textToSay = _(u"Misspelled word: %s") % (self.checker.word,) next(self.checker)
context = u"... %s %s %s" % (self.checker.leading_context(10), self.checker.word, self.checker.trailing_context(10)) textToSay = _(u"Misspelled word: %s") % (self.checker.word,)
self.dialog.set_title(textToSay) context = u"... %s %s %s" % (self.checker.leading_context(10), self.checker.word, self.checker.trailing_context(10))
output.speak(textToSay) self.dialog.set_title(textToSay)
self.dialog.set_word_and_suggestions(word=self.checker.word, context=context, suggestions=self.checker.suggest()) output.speak(textToSay)
except StopIteration: self.dialog.set_word_and_suggestions(word=self.checker.word, context=context, suggestions=self.checker.suggest())
log.debug("Process finished.") except StopIteration:
wx_ui.finished() log.debug("Process finished.")
self.dialog.Destroy() wx_ui.finished()
# except AttributeError: self.dialog.Destroy()
# pass # except AttributeError:
# pass
def ignore(self, ev):
self.check() def ignore(self, ev):
self.check()
def ignoreAll(self, ev):
self.checker.ignore_always(word=self.checker.word) def ignoreAll(self, ev):
self.check() self.checker.ignore_always(word=self.checker.word)
self.check()
def replace(self, ev):
self.checker.replace(self.dialog.get_selected_suggestion()) def replace(self, ev):
self.check() self.checker.replace(self.dialog.get_selected_suggestion())
self.check()
def replaceAll(self, ev):
self.checker.replace_always(self.dialog.get_selected_suggestion()) def replaceAll(self, ev):
self.checker.replace_always(self.dialog.get_selected_suggestion())
self.check() self.check()

View File

@ -1,2 +1,4 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import completion, settings from __future__ import absolute_import
# -*- coding: utf-8 -*-
from . import completion, settings

View File

@ -1,47 +1,48 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import output from __future__ import absolute_import
import storage import output
import wx_menu from . import storage
from . import wx_menu
class autocompletionUsers(object):
def __init__(self, window, session_id): class autocompletionUsers(object):
super(autocompletionUsers, self).__init__() def __init__(self, window, session_id):
self.window = window super(autocompletionUsers, self).__init__()
self.db = storage.storage(session_id) self.window = window
self.db = storage.storage(session_id)
def show_menu(self, mode="tweet"):
position = self.window.get_position() def show_menu(self, mode="tweet"):
if mode == "tweet": position = self.window.get_position()
text = self.window.get_text() if mode == "tweet":
text = text[:position] text = self.window.get_text()
try: text = text[:position]
pattern = text.split()[-1] try:
except IndexError: pattern = text.split()[-1]
output.speak(_(u"You have to start writing")) except IndexError:
return output.speak(_(u"You have to start writing"))
if pattern.startswith("@") == True: return
menu = wx_menu.menu(self.window.text, pattern[1:], mode=mode) if pattern.startswith("@") == True:
users = self.db.get_users(pattern[1:]) menu = wx_menu.menu(self.window.text, pattern[1:], mode=mode)
if len(users) > 0: users = self.db.get_users(pattern[1:])
menu.append_options(users) if len(users) > 0:
self.window.popup_menu(menu) menu.append_options(users)
menu.destroy() self.window.popup_menu(menu)
else: menu.destroy()
output.speak(_(u"There are no results in your users database")) else:
else: output.speak(_(u"There are no results in your users database"))
output.speak(_(u"Autocompletion only works for users.")) else:
elif mode == "dm": output.speak(_(u"Autocompletion only works for users."))
text = self.window.get_user() elif mode == "dm":
try: text = self.window.get_user()
pattern = text.split()[-1] try:
except IndexError: pattern = text.split()[-1]
output.speak(_(u"You have to start writing")) except IndexError:
return output.speak(_(u"You have to start writing"))
menu = wx_menu.menu(self.window.cb, pattern, mode=mode) return
users = self.db.get_users(pattern) menu = wx_menu.menu(self.window.cb, pattern, mode=mode)
if len(users) > 0: users = self.db.get_users(pattern)
menu.append_options(users) if len(users) > 0:
self.window.popup_menu(menu) menu.append_options(users)
menu.destroy() self.window.popup_menu(menu)
else: menu.destroy()
else:
output.speak(_(u"There are no results in your users database")) output.speak(_(u"There are no results in your users database"))

View File

@ -1,43 +1,45 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import storage from __future__ import absolute_import
import widgetUtils # -*- coding: utf-8 -*-
import wx_manage from . import storage
from wxUI import commonMessageDialogs import widgetUtils
from . import wx_manage
class autocompletionManage(object): from wxUI import commonMessageDialogs
def __init__(self, session):
super(autocompletionManage, self).__init__() class autocompletionManage(object):
self.session = session def __init__(self, session):
self.dialog = wx_manage.autocompletionManageDialog() super(autocompletionManage, self).__init__()
self.database = storage.storage(self.session.session_id) self.session = session
self.users = self.database.get_all_users() self.dialog = wx_manage.autocompletionManageDialog()
self.dialog.put_users(self.users) self.database = storage.storage(self.session.session_id)
widgetUtils.connect_event(self.dialog.add, widgetUtils.BUTTON_PRESSED, self.add_user) self.users = self.database.get_all_users()
widgetUtils.connect_event(self.dialog.remove, widgetUtils.BUTTON_PRESSED, self.remove_user) self.dialog.put_users(self.users)
self.dialog.get_response() widgetUtils.connect_event(self.dialog.add, widgetUtils.BUTTON_PRESSED, self.add_user)
widgetUtils.connect_event(self.dialog.remove, widgetUtils.BUTTON_PRESSED, self.remove_user)
def update_list(self): self.dialog.get_response()
item = self.dialog.users.get_selected()
self.dialog.users.clear() def update_list(self):
self.users = self.database.get_all_users() item = self.dialog.users.get_selected()
self.dialog.put_users(self.users) self.dialog.users.clear()
self.dialog.users.select_item(item) self.users = self.database.get_all_users()
self.dialog.put_users(self.users)
def add_user(self, *args, **kwargs): self.dialog.users.select_item(item)
usr = self.dialog.get_user()
if usr == False: def add_user(self, *args, **kwargs):
return usr = self.dialog.get_user()
try: if usr == False:
data = self.session.twitter.twitter.show_user(screen_name=usr) return
except: try:
self.dialog.show_invalid_user_error() data = self.session.twitter.twitter.show_user(screen_name=usr)
return except:
self.database.set_user(data["screen_name"], data["name"], 0) self.dialog.show_invalid_user_error()
self.update_list() return
self.database.set_user(data["screen_name"], data["name"], 0)
def remove_user(self, ev): self.update_list()
if commonMessageDialogs.delete_user_from_db() == widgetUtils.YES:
item = self.dialog.users.get_selected() def remove_user(self, ev):
user = self.users[item] if commonMessageDialogs.delete_user_from_db() == widgetUtils.YES:
self.database.remove_user(user[0]) item = self.dialog.users.get_selected()
user = self.users[item]
self.database.remove_user(user[0])
self.update_list() self.update_list()

View File

@ -1,59 +1,61 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import storage from __future__ import absolute_import
import widgetUtils # -*- coding: utf-8 -*-
import wx_settings from . import storage
import manage import widgetUtils
import output from . import wx_settings
from mysc.thread_utils import call_threaded from . import manage
import output
class autocompletionSettings(object): from mysc.thread_utils import call_threaded
def __init__(self, config, buffer, window):
super(autocompletionSettings, self).__init__() class autocompletionSettings(object):
self.config = config def __init__(self, config, buffer, window):
self.buffer = buffer super(autocompletionSettings, self).__init__()
self.window = window self.config = config
self.dialog = wx_settings.autocompletionSettingsDialog() self.buffer = buffer
self.dialog.set("friends_buffer", self.config["mysc"]["save_friends_in_autocompletion_db"]) self.window = window
self.dialog.set("followers_buffer", self.config["mysc"]["save_followers_in_autocompletion_db"]) self.dialog = wx_settings.autocompletionSettingsDialog()
widgetUtils.connect_event(self.dialog.viewList, widgetUtils.BUTTON_PRESSED, self.view_list) self.dialog.set("friends_buffer", self.config["mysc"]["save_friends_in_autocompletion_db"])
if self.dialog.get_response() == widgetUtils.OK: self.dialog.set("followers_buffer", self.config["mysc"]["save_followers_in_autocompletion_db"])
call_threaded(self.add_users_to_database) widgetUtils.connect_event(self.dialog.viewList, widgetUtils.BUTTON_PRESSED, self.view_list)
if self.dialog.get_response() == widgetUtils.OK:
def add_users_to_database(self): call_threaded(self.add_users_to_database)
self.config["mysc"]["save_friends_in_autocompletion_db"] = self.dialog.get("friends_buffer")
self.config["mysc"]["save_followers_in_autocompletion_db"] = self.dialog.get("followers_buffer") def add_users_to_database(self):
output.speak(_(u"Updating database... You can close this window now. A message will tell you when the process finishes.")) self.config["mysc"]["save_friends_in_autocompletion_db"] = self.dialog.get("friends_buffer")
database = storage.storage(self.buffer.session.session_id) self.config["mysc"]["save_followers_in_autocompletion_db"] = self.dialog.get("followers_buffer")
if self.dialog.get("followers_buffer") == True: output.speak(_(u"Updating database... You can close this window now. A message will tell you when the process finishes."))
buffer = self.window.search_buffer("followers", self.config["twitter"]["user_name"]) database = storage.storage(self.buffer.session.session_id)
for i in buffer.session.db[buffer.name]["items"]: if self.dialog.get("followers_buffer") == True:
database.set_user(i["screen_name"], i["name"], 1) buffer = self.window.search_buffer("followers", self.config["twitter"]["user_name"])
else: for i in buffer.session.db[buffer.name]["items"]:
database.remove_by_buffer(1) database.set_user(i["screen_name"], i["name"], 1)
if self.dialog.get("friends_buffer") == True: else:
buffer = self.window.search_buffer("friends", self.config["twitter"]["user_name"]) database.remove_by_buffer(1)
for i in buffer.session.db[buffer.name]["items"]: if self.dialog.get("friends_buffer") == True:
database.set_user(i["screen_name"], i["name"], 2) buffer = self.window.search_buffer("friends", self.config["twitter"]["user_name"])
else: for i in buffer.session.db[buffer.name]["items"]:
database.remove_by_buffer(2) database.set_user(i["screen_name"], i["name"], 2)
wx_settings.show_success_dialog() else:
self.dialog.destroy() database.remove_by_buffer(2)
wx_settings.show_success_dialog()
def view_list(self, ev): self.dialog.destroy()
q = manage.autocompletionManage(self.buffer.session)
def view_list(self, ev):
q = manage.autocompletionManage(self.buffer.session)
def execute_at_startup(window, buffer, config):
database = storage.storage(buffer.session.session_id)
if config["mysc"]["save_followers_in_autocompletion_db"] == True and config["other_buffers"]["show_followers"] == True: def execute_at_startup(window, buffer, config):
buffer = window.search_buffer("followers", config["twitter"]["user_name"]) database = storage.storage(buffer.session.session_id)
for i in buffer.session.db[buffer.name]: if config["mysc"]["save_followers_in_autocompletion_db"] == True and config["other_buffers"]["show_followers"] == True:
database.set_user(i["screen_name"], i["name"], 1) buffer = window.search_buffer("followers", config["twitter"]["user_name"])
else: for i in buffer.session.db[buffer.name]:
database.remove_by_buffer(1) database.set_user(i["screen_name"], i["name"], 1)
if config["mysc"]["save_friends_in_autocompletion_db"] == True and config["other_buffers"]["show_friends"] == True: else:
buffer = window.search_buffer("friends", config["twitter"]["user_name"]) database.remove_by_buffer(1)
for i in buffer.session.db[buffer.name]: if config["mysc"]["save_friends_in_autocompletion_db"] == True and config["other_buffers"]["show_friends"] == True:
database.set_user(i["screen_name"], i["name"], 2) buffer = window.search_buffer("friends", config["twitter"]["user_name"])
else: for i in buffer.session.db[buffer.name]:
database.set_user(i["screen_name"], i["name"], 2)
else:
database.remove_by_buffer(2) database.remove_by_buffer(2)

View File

@ -1,2 +1,4 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import OCRSpace from __future__ import absolute_import
# -*- coding: utf-8 -*-
from . import OCRSpace

View File

@ -1,6 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import translator from __future__ import absolute_import
import platform from . import translator
if platform.system() == "Windows": import platform
import wx_ui as gui if platform.system() == "Windows":
from . import wx_ui as gui

View File

@ -1,45 +1,64 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
############################################################ ############################################################
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net> # Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or # the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
############################################################ ############################################################
import translator from __future__ import absolute_import
import wx # -*- coding: utf-8 -*-
from wxUI.dialogs import baseDialog ############################################################
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
class translateDialog(baseDialog.BaseWXDialog): #
def __init__(self): # This program is free software: you can redistribute it and/or modify
super(translateDialog, self).__init__(None, -1, title=_(u"Translate message")) # it under the terms of the GNU General Public License as published by
panel = wx.Panel(self) # the Free Software Foundation, either version 2 of the License, or
sizer = wx.BoxSizer(wx.VERTICAL) # (at your option) any later version.
staticSource = wx.StaticText(panel, -1, _(u"Source language")) #
self.source_lang = wx.ComboBox(panel, -1, choices=[x[1] for x in translator.available_languages()], style = wx.CB_READONLY) # This program is distributed in the hope that it will be useful,
self.source_lang.SetFocus() # but WITHOUT ANY WARRANTY; without even the implied warranty of
staticDest = wx.StaticText(panel, -1, _(u"Target language")) # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
self.source_lang.SetSelection(0) # GNU General Public License for more details.
self.dest_lang = wx.ComboBox(panel, -1, choices=[x[1] for x in translator.available_languages()], style = wx.CB_READONLY) #
listSizer = wx.BoxSizer(wx.HORIZONTAL) # You should have received a copy of the GNU General Public License
listSizer.Add(staticSource) # along with this program. If not, see <http://www.gnu.org/licenses/>.
listSizer.Add(self.source_lang) #
listSizer.Add(staticDest) ############################################################
listSizer.Add(self.dest_lang) from . import translator
ok = wx.Button(panel, wx.ID_OK) import wx
ok.SetDefault() from wxUI.dialogs import baseDialog
cancel = wx.Button(panel, wx.ID_CANCEL)
self.SetEscapeId(wx.ID_CANCEL) class translateDialog(baseDialog.BaseWXDialog):
def __init__(self):
def get(self, control): super(translateDialog, self).__init__(None, -1, title=_(u"Translate message"))
panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
staticSource = wx.StaticText(panel, -1, _(u"Source language"))
self.source_lang = wx.ComboBox(panel, -1, choices=[x[1] for x in translator.available_languages()], style = wx.CB_READONLY)
self.source_lang.SetFocus()
staticDest = wx.StaticText(panel, -1, _(u"Target language"))
self.source_lang.SetSelection(0)
self.dest_lang = wx.ComboBox(panel, -1, choices=[x[1] for x in translator.available_languages()], style = wx.CB_READONLY)
listSizer = wx.BoxSizer(wx.HORIZONTAL)
listSizer.Add(staticSource)
listSizer.Add(self.source_lang)
listSizer.Add(staticDest)
listSizer.Add(self.dest_lang)
ok = wx.Button(panel, wx.ID_OK)
ok.SetDefault()
cancel = wx.Button(panel, wx.ID_CANCEL)
self.SetEscapeId(wx.ID_CANCEL)
def get(self, control):
return getattr(self, control).GetSelection() return getattr(self, control).GetSelection()

View File

@ -1,15 +1,16 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" This module contains some bugfixes for packages used in TWBlue.""" """ This module contains some bugfixes for packages used in TWBlue."""
import sys from __future__ import absolute_import
import fix_arrow # A few new locales for Three languages in arrow. import sys
import fix_urllib3_warnings # Avoiding some SSL warnings related to Twython. from . import fix_arrow # A few new locales for Three languages in arrow.
import fix_win32com from . import fix_urllib3_warnings # Avoiding some SSL warnings related to Twython.
import fix_requests #fix cacert.pem location for TWBlue binary copies from . import fix_win32com
def setup(): from . import fix_requests #fix cacert.pem location for TWBlue binary copies
fix_arrow.fix() def setup():
if hasattr(sys, "frozen"): fix_arrow.fix()
fix_win32com.fix() if hasattr(sys, "frozen"):
fix_requests.fix(True) fix_win32com.fix()
else: fix_requests.fix(True)
fix_requests.fix(False) else:
fix_requests.fix(False)
fix_urllib3_warnings.fix() fix_urllib3_warnings.fix()

View File

@ -1,64 +1,65 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
############################################################ ############################################################
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net> # Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or # the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
############################################################ ############################################################
import keys from __future__ import absolute_import
import wx import keys
import wx_ui import wx
import widgetUtils from . import wx_ui
import application import widgetUtils
from suds.client import Client import application
import constants from suds.client import Client
from . import constants
class reportBug(object):
def __init__(self, user_name): class reportBug(object):
self.user_name = user_name def __init__(self, user_name):
self.categories = [_(u"General")] self.user_name = user_name
self.reproducibilities = [_(u"always"), _(u"sometimes"), _(u"random"), _(u"have not tried"), _(u"unable to duplicate")] self.categories = [_(u"General")]
self.severities = [_(u"block"), _(u"crash"), _(u"major"), _(u"minor"), _(u"tweak"), _(u"text"), _(u"trivial"), _(u"feature")] self.reproducibilities = [_(u"always"), _(u"sometimes"), _(u"random"), _(u"have not tried"), _(u"unable to duplicate")]
self.dialog = wx_ui.reportBugDialog(self.categories, self.reproducibilities, self.severities) self.severities = [_(u"block"), _(u"crash"), _(u"major"), _(u"minor"), _(u"tweak"), _(u"text"), _(u"trivial"), _(u"feature")]
widgetUtils.connect_event(self.dialog.ok, widgetUtils.BUTTON_PRESSED, self.send) self.dialog = wx_ui.reportBugDialog(self.categories, self.reproducibilities, self.severities)
self.dialog.get_response() widgetUtils.connect_event(self.dialog.ok, widgetUtils.BUTTON_PRESSED, self.send)
self.dialog.get_response()
def send(self, *args, **kwargs):
if self.dialog.get("summary") == "" or self.dialog.get("description") == "": def send(self, *args, **kwargs):
self.dialog.no_filled() if self.dialog.get("summary") == "" or self.dialog.get("description") == "":
return self.dialog.no_filled()
if self.dialog.get("agree") == False: return
self.dialog.no_checkbox() if self.dialog.get("agree") == False:
return self.dialog.no_checkbox()
try: return
client = Client(application.report_bugs_url) try:
issue = client.factory.create('IssueData') client = Client(application.report_bugs_url)
issue.project.name = application.name issue = client.factory.create('IssueData')
issue.project.id = 0 issue.project.name = application.name
issue.summary = self.dialog.get("summary"), issue.project.id = 0
issue.description = "Reported by @%s on version %s (snapshot = %s)\n\n" % (self.user_name, application.version, application.snapshot) + self.dialog.get("description") issue.summary = self.dialog.get("summary"),
# to do: Create getters for category, severity and reproducibility in wx_UI. issue.description = "Reported by @%s on version %s (snapshot = %s)\n\n" % (self.user_name, application.version, application.snapshot) + self.dialog.get("description")
issue.category = constants.categories[self.dialog.category.GetSelection()] # to do: Create getters for category, severity and reproducibility in wx_UI.
issue.reproducibility.name = constants.reproducibilities[self.dialog.reproducibility.GetSelection()] issue.category = constants.categories[self.dialog.category.GetSelection()]
issue.severity.name = constants.severities[self.dialog.severity.GetSelection()] issue.reproducibility.name = constants.reproducibilities[self.dialog.reproducibility.GetSelection()]
issue.priority.name = "normal" issue.severity.name = constants.severities[self.dialog.severity.GetSelection()]
issue.view_state.name = "public" issue.priority.name = "normal"
issue.resolution.name = "open" issue.view_state.name = "public"
issue.projection.name = "none" issue.resolution.name = "open"
issue.eta.name = "eta" issue.projection.name = "none"
issue.status.name = "new" issue.eta.name = "eta"
id = client.service.mc_issue_add(keys.keyring.get("bts_user"), keys.keyring.get("bts_password"), issue) issue.status.name = "new"
self.dialog.success(id) id = client.service.mc_issue_add(keys.keyring.get("bts_user"), keys.keyring.get("bts_password"), issue)
except: self.dialog.success(id)
self.dialog.error() except:
self.dialog.error()

View File

@ -1,3 +1,4 @@
from main import KeyboardHandler, KeyboardHandlerError from __future__ import absolute_import
#from wx_handler import WXKeyboardHandler from .main import KeyboardHandler, KeyboardHandlerError
__all__ = ["KeyboardHandler", "KeyboardHandlerError", "WXKeyboardHandler", "WXPanelKeyboardHandler"] #from wx_handler import WXKeyboardHandler
__all__ = ["KeyboardHandler", "KeyboardHandlerError", "WXKeyboardHandler", "WXPanelKeyboardHandler"]

View File

@ -1,7 +1,8 @@
import platform from __future__ import absolute_import
if platform.system() == 'Linux': import platform
from linux import LinuxKeyboardHandler as GlobalKeyboardHandler if platform.system() == 'Linux':
elif platform.system() == 'Windows': from .linux import LinuxKeyboardHandler as GlobalKeyboardHandler
from wx_handler import WXKeyboardHandler as GlobalKeyboardHandler elif platform.system() == 'Windows':
elif platform.system() == 'Darwin': from .wx_handler import WXKeyboardHandler as GlobalKeyboardHandler
from osx import OSXKeyboardHandler as GlobalKeyboardHandler elif platform.system() == 'Darwin':
from .osx import OSXKeyboardHandler as GlobalKeyboardHandler

View File

@ -1,58 +1,59 @@
from main import KeyboardHandler from __future__ import absolute_import
import threading from .main import KeyboardHandler
import thread import threading
import pyatspi import thread
def parse(s): import pyatspi
"""parse a string like control+f into (modifier, key). def parse(s):
Unknown modifiers will return ValueError.""" """parse a string like control+f into (modifier, key).
m = 0 Unknown modifiers will return ValueError."""
lst = s.split('+') m = 0
if not len(lst): return (0, s) lst = s.split('+')
#Are these right? if not len(lst): return (0, s)
d = { #Are these right?
"shift": 1<<pyatspi.MODIFIER_SHIFT, d = {
"control": 1<<pyatspi.MODIFIER_CONTROL, "shift": 1<<pyatspi.MODIFIER_SHIFT,
"alt": 1<<pyatspi.MODIFIER_ALT, "control": 1<<pyatspi.MODIFIER_CONTROL,
"win":1<<pyatspi.MODIFIER_META3, "alt": 1<<pyatspi.MODIFIER_ALT,
} "win":1<<pyatspi.MODIFIER_META3,
for item in lst: }
if item in d: for item in lst:
m|=d[item] if item in d:
lst.remove(item) m|=d[item]
#end if lst.remove(item)
if len(lst) > 1: #more than one key, parse error #end if
raise ValueError, 'unknown modifier %s' % lst[0] if len(lst) > 1: #more than one key, parse error
return (m, lst[0].lower()) raise ValueError('unknown modifier %s' % lst[0])
class AtspiThread(threading.Thread): return (m, lst[0].lower())
def run(self): class AtspiThread(threading.Thread):
pyatspi.Registry.registerKeystrokeListener(handler, kind=(pyatspi.KEY_PRESSED_EVENT,), def run(self):
mask=pyatspi.allModifiers()) pyatspi.Registry.registerKeystrokeListener(handler, kind=(pyatspi.KEY_PRESSED_EVENT,),
pyatspi.Registry.start() mask=pyatspi.allModifiers())
#the keys we registered pyatspi.Registry.start()
keys = {} #the keys we registered
def handler(e): keys = {}
m,k = e.modifiers,e.event_string.lower() def handler(e):
#not sure why we can't catch control+f. Try to fix it. m,k = e.modifiers,e.event_string.lower()
if (not e.is_text) and e.id >= 97 <= 126: #not sure why we can't catch control+f. Try to fix it.
k = chr(e.id) if (not e.is_text) and e.id >= 97 <= 126:
if (m,k) not in keys: return False k = chr(e.id)
thread.start_new(keys[(m,k)], ()) if (m,k) not in keys: return False
return True #don't pass it on thread.start_new(keys[(m,k)], ())
class LinuxKeyboardHandler(KeyboardHandler): return True #don't pass it on
def __init__(self, *args, **kwargs): class LinuxKeyboardHandler(KeyboardHandler):
KeyboardHandler.__init__(self, *args, **kwargs) def __init__(self, *args, **kwargs):
t = AtspiThread() KeyboardHandler.__init__(self, *args, **kwargs)
t.start() t = AtspiThread()
def register_key(self, key, function): t.start()
"""key will be a string, such as control+shift+f. def register_key(self, key, function):
We need to convert that, using parse_key, """key will be a string, such as control+shift+f.
into modifier and key to put into our dictionary.""" We need to convert that, using parse_key,
#register key so we know if we have it on event receive. into modifier and key to put into our dictionary."""
t = parse(key) #register key so we know if we have it on event receive.
keys[t] = function t = parse(key)
#if we got this far, the key is valid. keys[t] = function
KeyboardHandler.register_key(self, key, function) #if we got this far, the key is valid.
KeyboardHandler.register_key(self, key, function)
def unregister_key (self, key, function):
KeyboardHandler.unregister_key(self, key, function) def unregister_key (self, key, function):
del keys[parse(key)] KeyboardHandler.unregister_key(self, key, function)
del keys[parse(key)]

View File

@ -1,88 +1,88 @@
import platform import platform
import time import time
class KeyboardHandlerError (Exception): pass class KeyboardHandlerError (Exception): pass
class KeyboardHandler(object): class KeyboardHandler(object):
def __init__(self, repeat_rate=0.0, *args, **kwargs): def __init__(self, repeat_rate=0.0, *args, **kwargs):
self.repeat_rate = repeat_rate #How long between accepting the same keystroke? self.repeat_rate = repeat_rate #How long between accepting the same keystroke?
self._last_key = None self._last_key = None
self._last_keypress_time = 0 self._last_keypress_time = 0
super(KeyboardHandler, self).__init__(*args, **kwargs) super(KeyboardHandler, self).__init__(*args, **kwargs)
self.active_keys = {} self.active_keys = {}
if not hasattr(self, 'replacement_mods'): if not hasattr(self, 'replacement_mods'):
self.replacement_mods = {} self.replacement_mods = {}
if not hasattr(self, 'replacement_keys'): if not hasattr(self, 'replacement_keys'):
self.replacement_keys = {} self.replacement_keys = {}
def register_key (self, key, function): def register_key (self, key, function):
if key in self.active_keys: if key in self.active_keys:
raise KeyboardHandlerError, "Key %s is already registered to a function" % key raise KeyboardHandlerError("Key %s is already registered to a function" % key)
if not callable(function): if not callable(function):
raise TypeError, "Must provide a callable to be invoked upon keypress" raise TypeError("Must provide a callable to be invoked upon keypress")
self.active_keys[key] = function self.active_keys[key] = function
def unregister_key (self, key, function): def unregister_key (self, key, function):
try: try:
if self.active_keys[key] != function: if self.active_keys[key] != function:
raise KeyboardHandlerError, "key %s is not registered to that function" % key raise KeyboardHandlerError("key %s is not registered to that function" % key)
except KeyError: except KeyError:
raise KeyboardHandlerError, "Key %s not currently registered" raise KeyboardHandlerError("Key %s not currently registered")
del(self.active_keys[key]) del(self.active_keys[key])
def unregister_all_keys(self): def unregister_all_keys(self):
for key in list(self.active_keys): for key in list(self.active_keys):
self.unregister_key(key, self.active_keys[key]) self.unregister_key(key, self.active_keys[key])
def handle_key (self, key): def handle_key (self, key):
if self.repeat_rate and key == self._last_key and time.time() - self._last_keypress_time < self.repeat_rate: if self.repeat_rate and key == self._last_key and time.time() - self._last_keypress_time < self.repeat_rate:
return return
try: try:
function = self.active_keys[key] function = self.active_keys[key]
except KeyError: except KeyError:
return return
self._last_key = key self._last_key = key
self._last_keypress_time = time.time() self._last_keypress_time = time.time()
return function() return function()
def register_keys(self, keys): def register_keys(self, keys):
"""Given a mapping of keystrokes to functions, registers all keystrokes""" """Given a mapping of keystrokes to functions, registers all keystrokes"""
for k in keys: for k in keys:
self.register_key(k, keys[k]) self.register_key(k, keys[k])
def unregister_keys(self, keys): def unregister_keys(self, keys):
"""Given a mapping of keys to their functions, unregisters all provided keys.""" """Given a mapping of keys to their functions, unregisters all provided keys."""
for k in keys: for k in keys:
self.unregister_key(k, keys[k]) self.unregister_key(k, keys[k])
def standardize_key(self, key): def standardize_key(self, key):
"""Takes a keystroke and places it in a standard case and order in a list.""" """Takes a keystroke and places it in a standard case and order in a list."""
working = key.split('+') working = key.split('+')
working = [i.lower() for i in working] working = [i.lower() for i in working]
answer = [] answer = []
if "control" in working: if "control" in working:
answer.append("control") answer.append("control")
if "win" in working: if "win" in working:
answer.append("win") answer.append("win")
if "alt" in working: if "alt" in working:
answer.append("alt") answer.append("alt")
if "shift" in working: if "shift" in working:
answer.append("shift") answer.append("shift")
if working[-1] not in answer: if working[-1] not in answer:
answer.append(working[-1]) answer.append(working[-1])
return answer return answer
def standardize_keymap(self, keymap): def standardize_keymap(self, keymap):
"""Given a keymap, returns the keymap standardized.""" """Given a keymap, returns the keymap standardized."""
full = {} full = {}
for i in keymap: for i in keymap:
answer = "" answer = ""
new = self.standardize_key(keymap[i]) new = self.standardize_key(keymap[i])
for (c, j) in enumerate(new): for (c, j) in enumerate(new):
if c < len(new)-1: if c < len(new)-1:
answer = "%s%s+" % (answer, j) answer = "%s%s+" % (answer, j)
else: else:
answer = "%s%s" % (answer, j) answer = "%s%s" % (answer, j)
full[i] = answer full[i] = answer
return full return full

View File

@ -1,56 +1,57 @@
from AppKit import * from __future__ import absolute_import
from PyObjCTools import AppHelper from AppKit import *
from Carbon.CarbonEvt import RegisterEventHotKey, GetApplicationEventTarget from PyObjCTools import AppHelper
from Carbon.Events import cmdKey, controlKey from Carbon.CarbonEvt import RegisterEventHotKey, GetApplicationEventTarget
import struct from Carbon.Events import cmdKey, controlKey
from threading import Thread import struct
from threading import Thread
from main import KeyboardHandler
from .main import KeyboardHandler
kEventHotKeyPressedSubtype = 6
kEventHotKeyReleasedSubtype = 9 kEventHotKeyPressedSubtype = 6
kEventHotKeyReleasedSubtype = 9
class OSXKeyboardHandler(KeyboardHandler):
class OSXKeyboardHandler(KeyboardHandler):
def __init__(self):
super(OSXKeyboardHandler, self).__init__() def __init__(self):
self.replacement_keys = dict() super(OSXKeyboardHandler, self).__init__()
self.app = KeyboardCapturingNSApplication.alloc().init() self.replacement_keys = dict()
self._event_thread = Thread(target=AppHelper.runEventLoop) self.app = KeyboardCapturingNSApplication.alloc().init()
self._event_thread.start() self._event_thread = Thread(target=AppHelper.runEventLoop)
self._event_thread.start()
def register_key (self, key, function):
super(OSXKeyboardHandler, self).register_key(key, function) def register_key (self, key, function):
k, m = self.parse_key(key) super(OSXKeyboardHandler, self).register_key(key, function)
key_id = RegisterEventHotKey(k, m, (0, 0), GetApplicationEventTarget(), 0) k, m = self.parse_key(key)
self.key_ids[key] = key_id key_id = RegisterEventHotKey(k, m, (0, 0), GetApplicationEventTarget(), 0)
self.key_ids[key] = key_id
def unregister_key (self, key, function):
super(OSXKeyboardHandler, self).unregister_key(key, function) def unregister_key (self, key, function):
key_id = self.key_ids[key] super(OSXKeyboardHandler, self).unregister_key(key, function)
raise NotImplementedError key_id = self.key_ids[key]
raise NotImplementedError
def parse_key (self, key):
key=key.split("+") def parse_key (self, key):
#replacements key=key.split("+")
#Modifier keys: #replacements
for index, item in enumerate(key[0:-1]): #Modifier keys:
if self.replacement_mods.has_key(item): for index, item in enumerate(key[0:-1]):
key[index] = self.replacement_mods[item] if item in self.replacement_mods:
if self.replacement_keys.has_key(key[-1]): key[index] = self.replacement_mods[item]
key[-1] = self.replacement_keys[key[-1]] if key[-1] in self.replacement_keys:
elif len(key[-1])==1: key[-1] = self.replacement_keys[key[-1]]
key[-1] = ord(str(key[-1]))-36 elif len(key[-1])==1:
mods = 0 key[-1] = ord(str(key[-1]))-36
for i in key[:-1]: mods = 0
mods = mods|i for i in key[:-1]:
return [key[-1], mods] mods = mods|i
return [key[-1], mods]
class KeyboardCapturingNSApplication(NSApplication):
class KeyboardCapturingNSApplication(NSApplication):
def sendEvent_(self, theEvent):
if theEvent.type() == NSSystemDefined and theEvent.subtype() == kEventHotKeyPressedSubtype: def sendEvent_(self, theEvent):
self.activateIgnoringOtherApps_(True) if theEvent.type() == NSSystemDefined and theEvent.subtype() == kEventHotKeyPressedSubtype:
NSRunAlertPanel(u'Hot Key Pressed', u'Hot Key Pressed', None, None, None) self.activateIgnoringOtherApps_(True)
super(NSApplication, self).sendEvent_(theEvent) NSRunAlertPanel(u'Hot Key Pressed', u'Hot Key Pressed', None, None, None)
super(NSApplication, self).sendEvent_(theEvent)

View File

@ -1,40 +1,41 @@
import win32api from __future__ import absolute_import
import win32con import win32api
import win32con
from main import KeyboardHandler
from .main import KeyboardHandler
class WindowsKeyboardHandler(KeyboardHandler):
class WindowsKeyboardHandler(KeyboardHandler):
def __init__ (self, *args, **kwargs):
super(WindowsKeyboardHandler, self).__init__(*args, **kwargs) def __init__ (self, *args, **kwargs):
#Setup the replacement dictionaries. super(WindowsKeyboardHandler, self).__init__(*args, **kwargs)
for i in dir(win32con): #Setup the replacement dictionaries.
if i.startswith("VK_"): for i in dir(win32con):
key = i[3:].lower() if i.startswith("VK_"):
self.replacement_keys[key] = getattr(win32con, i) key = i[3:].lower()
elif i.startswith("MOD_"): self.replacement_keys[key] = getattr(win32con, i)
key = i[4:].lower() elif i.startswith("MOD_"):
self.replacement_mods[key] = getattr(win32con, i) key = i[4:].lower()
self.replacement_keys .update(dict(pageup=win32con.VK_PRIOR, pagedown=win32con.VK_NEXT)) self.replacement_mods[key] = getattr(win32con, i)
self.replacement_keys .update(dict(pageup=win32con.VK_PRIOR, pagedown=win32con.VK_NEXT))
def parse_key (self, keystroke, separator="+"):
keystroke = str(keystroke) #We don't want unicode def parse_key (self, keystroke, separator="+"):
keystroke = [self.keycode_from_key(i) for i in keystroke.split(separator)] keystroke = str(keystroke) #We don't want unicode
mods = 0 keystroke = [self.keycode_from_key(i) for i in keystroke.split(separator)]
for i in keystroke[:-1]: mods = 0
mods = mods | i #or everything together for i in keystroke[:-1]:
return (mods, keystroke[-1]) mods = mods | i #or everything together
return (mods, keystroke[-1])
def keycode_from_key(self, key):
if key in self.replacement_mods: def keycode_from_key(self, key):
return self.replacement_mods[key] if key in self.replacement_mods:
if key in self.replacement_keys: return self.replacement_mods[key]
return self.replacement_keys[key] if key in self.replacement_keys:
if len(key) == 1: return self.replacement_keys[key]
return win32api.VkKeyScanEx(key, win32api.GetKeyboardLayout()) if len(key) == 1:
return win32api.VkKeyScanEx(key, win32api.GetKeyboardLayout())
def is_key_pressed(self, key):
"""Returns if the given key was pressed. Requires an active message loop or will simply give if the key was pressed recently.""" def is_key_pressed(self, key):
key = self.keycode_from_key(key) """Returns if the given key was pressed. Requires an active message loop or will simply give if the key was pressed recently."""
return win32api.GetAsyncKeyState(key) key = self.keycode_from_key(key)
return win32api.GetAsyncKeyState(key)

View File

@ -1,119 +1,121 @@
import functools from __future__ import print_function
import wx from __future__ import absolute_import
import platform import functools
from main import KeyboardHandler import wx
import platform
__all__ = ['WXKeyboardHandler', 'WXControlKeyboardHandler'] from .main import KeyboardHandler
__all__ = ['WXKeyboardHandler', 'WXControlKeyboardHandler']
def call_after(func):
def wrapper(*args, **kwargs):
wx.CallAfter(func, *args, **kwargs) def call_after(func):
functools.update_wrapper(wrapper, func) def wrapper(*args, **kwargs):
return wrapper wx.CallAfter(func, *args, **kwargs)
functools.update_wrapper(wrapper, func)
return wrapper
class BaseWXKeyboardHandler(KeyboardHandler):
def __init__(self, *args, **kwargs): class BaseWXKeyboardHandler(KeyboardHandler):
super(BaseWXKeyboardHandler, self).__init__(*args, **kwargs)
#Setup the replacement dictionaries. def __init__(self, *args, **kwargs):
for i in dir(wx): super(BaseWXKeyboardHandler, self).__init__(*args, **kwargs)
if i.startswith('WXK_'): #Setup the replacement dictionaries.
key = i[4:].lower() for i in dir(wx):
self.replacement_keys[key] = getattr(wx, i) if i.startswith('WXK_'):
elif i.startswith('MOD_'): key = i[4:].lower()
key = i[4:].lower() self.replacement_keys[key] = getattr(wx, i)
self.replacement_mods[key] = getattr(wx, i) elif i.startswith('MOD_'):
key = i[4:].lower()
def parse_key (self, keystroke, separator="+"): self.replacement_mods[key] = getattr(wx, i)
keystroke = [self.keycode_from_key(i) for i in keystroke.split(separator)]
mods = 0 def parse_key (self, keystroke, separator="+"):
for i in keystroke[:-1]: keystroke = [self.keycode_from_key(i) for i in keystroke.split(separator)]
mods = mods | i #or everything together mods = 0
return (mods, keystroke[-1]) for i in keystroke[:-1]:
mods = mods | i #or everything together
def keycode_from_key(self, key): return (mods, keystroke[-1])
if key in self.replacement_mods:
result = self.replacement_mods[key] def keycode_from_key(self, key):
elif key in self.replacement_keys: if key in self.replacement_mods:
result = self.replacement_keys[key] result = self.replacement_mods[key]
if result >= 277: elif key in self.replacement_keys:
result -= 277 result = self.replacement_keys[key]
elif len(key) == 1: if result >= 277:
result = ord(key.upper()) result -= 277
print "result: ", result elif len(key) == 1:
return result result = ord(key.upper())
print("result: ", result)
return result
#try:
if platform.system() == "Windows":
from windows import WindowsKeyboardHandler as keyboard_handler #try:
elif platform.system() == "Linux": if platform.system() == "Windows":
from linux import LinuxKeyboardHandler as keyboard_handler from .windows import WindowsKeyboardHandler as keyboard_handler
elif platform.system() == "Darwin": elif platform.system() == "Linux":
from osx import OSXKeyboardHandler as keyboard_handler from .linux import LinuxKeyboardHandler as keyboard_handler
elif platform.system() == "Darwin":
class WXKeyboardHandler(keyboard_handler): from .osx import OSXKeyboardHandler as keyboard_handler
def __init__ (self, parent, *args, **kwargs):
super(WXKeyboardHandler, self).__init__(*args, **kwargs) class WXKeyboardHandler(keyboard_handler):
self.parent = parent def __init__ (self, parent, *args, **kwargs):
self.key_ids = {} super(WXKeyboardHandler, self).__init__(*args, **kwargs)
self.parent = parent
@call_after self.key_ids = {}
def register_key(self, key, function):
super(WXKeyboardHandler, self).register_key(key, function) @call_after
key_id = wx.NewId() def register_key(self, key, function):
parsed = self.parse_key(key) super(WXKeyboardHandler, self).register_key(key, function)
self.parent.RegisterHotKey(key_id, *parsed) key_id = wx.NewId()
self.parent.Bind(wx.EVT_HOTKEY, lambda evt: self.process_key(evt, key_id), id=key_id) parsed = self.parse_key(key)
self.key_ids[key] = key_id self.parent.RegisterHotKey(key_id, *parsed)
self.parent.Bind(wx.EVT_HOTKEY, lambda evt: self.process_key(evt, key_id), id=key_id)
@call_after self.key_ids[key] = key_id
def unregister_key (self, key, function):
super(WXKeyboardHandler, self).unregister_key(key, function) @call_after
if key not in self.key_ids: def unregister_key (self, key, function):
return #there's nothing we can do. super(WXKeyboardHandler, self).unregister_key(key, function)
key_id = self.key_ids[key] if key not in self.key_ids:
self.parent.UnregisterHotKey(key_id) return #there's nothing we can do.
self.parent.Unbind( wx.EVT_HOTKEY, id=key_id) key_id = self.key_ids[key]
self.key_ids.pop(key) self.parent.UnregisterHotKey(key_id)
self.parent.Unbind( wx.EVT_HOTKEY, id=key_id)
def process_key (self, evt, id): self.key_ids.pop(key)
evt.Skip()
key_ids = self.key_ids.keys() def process_key (self, evt, id):
for i in key_ids: evt.Skip()
if self.key_ids.get(i) == id: key_ids = self.key_ids.keys()
self.handle_key(i) for i in key_ids:
if self.key_ids.get(i) == id:
class WXControlKeyboardHandler(wx.StaticText, KeyboardHandler): self.handle_key(i)
def __init__(self, parent=None, *a, **k): class WXControlKeyboardHandler(wx.StaticText, KeyboardHandler):
wx.StaticText.__init__(self, parent=parent)
KeyboardHandler.__init__(self, *a, **k) def __init__(self, parent=None, *a, **k):
self.wx_replacements = {} wx.StaticText.__init__(self, parent=parent)
for i in [d for d in dir(wx) if d.startswith('WXK_')]: KeyboardHandler.__init__(self, *a, **k)
self.wx_replacements[getattr(wx, i)] = i[4:].lower() self.wx_replacements = {}
self.Bind(wx.EVT_KEY_DOWN, self.process_key, self) for i in [d for d in dir(wx) if d.startswith('WXK_')]:
self.SetFocus() self.wx_replacements[getattr(wx, i)] = i[4:].lower()
self.Bind(wx.EVT_KEY_DOWN, self.process_key, self)
def process_key(self, evt): self.SetFocus()
keycode = evt.GetKeyCode()
keyname = self.wx_replacements.get(keycode, None) def process_key(self, evt):
modifiers = "" keycode = evt.GetKeyCode()
replacements = ( (evt.ControlDown(), 'control+'), keyname = self.wx_replacements.get(keycode, None)
(evt.AltDown(), 'alt+'), modifiers = ""
(evt.ShiftDown(), 'shift+'), replacements = ( (evt.ControlDown(), 'control+'),
(evt.MetaDown(), 'win+') (evt.AltDown(), 'alt+'),
) (evt.ShiftDown(), 'shift+'),
for mod, ch in (replacements): (evt.MetaDown(), 'win+')
if mod: )
modifiers += ch for mod, ch in (replacements):
if keyname is None: if mod:
if 27 < keycode < 256: modifiers += ch
keyname = chr(keycode).lower() if keyname is None:
else: if 27 < keycode < 256:
keyname = "(%s)unknown" % keycode keyname = chr(keycode).lower()
key = modifiers + keyname else:
self.handle_key(key) keyname = "(%s)unknown" % keycode
key = modifiers + keyname
self.handle_key(key)

View File

@ -1 +1,2 @@
from keystrokeEditor import KeystrokeEditor from __future__ import absolute_import
from .keystrokeEditor import KeystrokeEditor

View File

@ -1,58 +1,59 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import widgetUtils from __future__ import absolute_import
import config import widgetUtils
import wx_ui import config
import constants from . import wx_ui
from pubsub import pub from . import constants
from pubsub import pub
class KeystrokeEditor(object):
def __init__(self): class KeystrokeEditor(object):
super(KeystrokeEditor, self).__init__() def __init__(self):
self.changed = False # Change it if the keyboard shorcuts are reassigned. super(KeystrokeEditor, self).__init__()
self.dialog = wx_ui.keystrokeEditorDialog() self.changed = False # Change it if the keyboard shorcuts are reassigned.
self.map = config.keymap["keymap"] self.dialog = wx_ui.keystrokeEditorDialog()
# we need to copy the keymap before modify it, for unregistering the old keystrokes if is needed. self.map = config.keymap["keymap"]
self.hold_map = self.map.copy() # we need to copy the keymap before modify it, for unregistering the old keystrokes if is needed.
self.dialog.put_keystrokes(constants.actions, self.map) self.hold_map = self.map.copy()
widgetUtils.connect_event(self.dialog.edit, widgetUtils.BUTTON_PRESSED, self.edit_keystroke) self.dialog.put_keystrokes(constants.actions, self.map)
widgetUtils.connect_event(self.dialog.execute, widgetUtils.BUTTON_PRESSED, self.execute_action) widgetUtils.connect_event(self.dialog.edit, widgetUtils.BUTTON_PRESSED, self.edit_keystroke)
self.dialog.get_response() widgetUtils.connect_event(self.dialog.execute, widgetUtils.BUTTON_PRESSED, self.execute_action)
self.dialog.get_response()
def edit_keystroke(self, *args, **kwargs):
action = self.dialog.actions[self.dialog.get_action()] def edit_keystroke(self, *args, **kwargs):
edit_dialog = wx_ui.editKeystrokeDialog() action = self.dialog.actions[self.dialog.get_action()]
self.set_keystroke(self.map[action], edit_dialog) edit_dialog = wx_ui.editKeystrokeDialog()
answer = edit_dialog.get_response() self.set_keystroke(self.map[action], edit_dialog)
if answer == widgetUtils.OK: answer = edit_dialog.get_response()
new_keystroke = self.get_edited_keystroke(edit_dialog) if answer == widgetUtils.OK:
if new_keystroke != self.map[action]: new_keystroke = self.get_edited_keystroke(edit_dialog)
self.changed = True if new_keystroke != self.map[action]:
self.map[action] = new_keystroke self.changed = True
self.dialog.put_keystrokes(constants.actions, self.map) self.map[action] = new_keystroke
self.dialog.put_keystrokes(constants.actions, self.map)
def set_keystroke(self, keystroke, dialog):
for i in keystroke.split("+"): def set_keystroke(self, keystroke, dialog):
if hasattr(dialog, i): for i in keystroke.split("+"):
dialog.set(i, True) if hasattr(dialog, i):
dialog.set("key", keystroke.split("+")[-1]) dialog.set(i, True)
dialog.set("key", keystroke.split("+")[-1])
def get_edited_keystroke(self, dialog):
keys = [] def get_edited_keystroke(self, dialog):
if dialog.get("control") == True: keys = []
keys.append("control") if dialog.get("control") == True:
if dialog.get("win") == True: keys.append("control")
keys.append("win") if dialog.get("win") == True:
if dialog.get("alt") == True: keys.append("win")
keys.append("alt") if dialog.get("alt") == True:
if dialog.get("shift") == True: keys.append("alt")
keys.append("shift") if dialog.get("shift") == True:
if dialog.get("key") != "": keys.append("shift")
keys.append(dialog.get("key")) if dialog.get("key") != "":
else: keys.append(dialog.get("key"))
wx_ui.no_key() else:
return wx_ui.no_key()
return "+".join(keys) return
return "+".join(keys)
def execute_action(self, *args, **kwargs):
action = self.dialog.actions[self.dialog.get_action()] def execute_action(self, *args, **kwargs):
action = self.dialog.actions[self.dialog.get_action()]
pub.sendMessage("execute-action", action=action) pub.sendMessage("execute-action", action=action)

View File

@ -1,81 +1,81 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import wx import wx
from multiplatform_widgets import widgets from multiplatform_widgets import widgets
from wxUI.dialogs import baseDialog from wxUI.dialogs import baseDialog
class keystrokeEditorDialog(baseDialog.BaseWXDialog): class keystrokeEditorDialog(baseDialog.BaseWXDialog):
def __init__(self): def __init__(self):
super(keystrokeEditorDialog, self).__init__(parent=None, id=-1, title=_(u"Keystroke editor")) super(keystrokeEditorDialog, self).__init__(parent=None, id=-1, title=_(u"Keystroke editor"))
panel = wx.Panel(self) panel = wx.Panel(self)
self.actions = [] self.actions = []
sizer = wx.BoxSizer(wx.VERTICAL) sizer = wx.BoxSizer(wx.VERTICAL)
keysText = wx.StaticText(panel, -1, _(u"Select a keystroke to edit")) keysText = wx.StaticText(panel, -1, _(u"Select a keystroke to edit"))
self.keys = widgets.list(self, _(u"Action"), _(u"Keystroke"), style=wx.LC_REPORT|wx.LC_SINGLE_SEL, size=(400, 450)) self.keys = widgets.list(self, _(u"Action"), _(u"Keystroke"), style=wx.LC_REPORT|wx.LC_SINGLE_SEL, size=(400, 450))
self.keys.list.SetFocus() self.keys.list.SetFocus()
firstSizer = wx.BoxSizer(wx.HORIZONTAL) firstSizer = wx.BoxSizer(wx.HORIZONTAL)
firstSizer.Add(keysText, 0, wx.ALL, 5) firstSizer.Add(keysText, 0, wx.ALL, 5)
firstSizer.Add(self.keys.list, 0, wx.ALL, 5) firstSizer.Add(self.keys.list, 0, wx.ALL, 5)
self.edit = wx.Button(panel, -1, _(u"Edit")) self.edit = wx.Button(panel, -1, _(u"Edit"))
self.edit.SetDefault() self.edit.SetDefault()
self.execute = wx.Button(panel, -1, _(u"Execute action")) self.execute = wx.Button(panel, -1, _(u"Execute action"))
close = wx.Button(panel, wx.ID_CANCEL, _(u"Close")) close = wx.Button(panel, wx.ID_CANCEL, _(u"Close"))
secondSizer = wx.BoxSizer(wx.HORIZONTAL) secondSizer = wx.BoxSizer(wx.HORIZONTAL)
secondSizer.Add(self.edit, 0, wx.ALL, 5) secondSizer.Add(self.edit, 0, wx.ALL, 5)
secondSizer.Add(self.execute, 0, wx.ALL, 5) secondSizer.Add(self.execute, 0, wx.ALL, 5)
secondSizer.Add(close, 0, wx.ALL, 5) secondSizer.Add(close, 0, wx.ALL, 5)
sizer.Add(firstSizer, 0, wx.ALL, 5) sizer.Add(firstSizer, 0, wx.ALL, 5)
sizer.Add(secondSizer, 0, wx.ALL, 5) sizer.Add(secondSizer, 0, wx.ALL, 5)
panel.SetSizer(sizer) panel.SetSizer(sizer)
self.SetClientSize(sizer.CalcMin()) self.SetClientSize(sizer.CalcMin())
def put_keystrokes(self, actions, keystrokes): def put_keystrokes(self, actions, keystrokes):
selection = self.keys.get_selected() selection = self.keys.get_selected()
self.keys.clear() self.keys.clear()
for i in keystrokes: for i in keystrokes:
if actions.has_key(i) == False: if (i in actions) == False:
continue continue
action = actions[i] action = actions[i]
self.actions.append(i) self.actions.append(i)
keystroke = keystrokes[i] keystroke = keystrokes[i]
self.keys.insert_item(False, *[action, keystroke]) self.keys.insert_item(False, *[action, keystroke])
self.keys.select_item(selection) self.keys.select_item(selection)
def get_action(self): def get_action(self):
return self.keys.get_selected() return self.keys.get_selected()
class editKeystrokeDialog(baseDialog.BaseWXDialog): class editKeystrokeDialog(baseDialog.BaseWXDialog):
def __init__(self): def __init__(self):
super(editKeystrokeDialog, self).__init__(parent=None, id=-1, title=_(u"Editing keystroke")) super(editKeystrokeDialog, self).__init__(parent=None, id=-1, title=_(u"Editing keystroke"))
panel = wx.Panel(self) panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL) sizer = wx.BoxSizer(wx.VERTICAL)
self.control = wx.CheckBox(panel, -1, _(u"Control")) self.control = wx.CheckBox(panel, -1, _(u"Control"))
self.alt = wx.CheckBox(panel, -1, _(u"Alt")) self.alt = wx.CheckBox(panel, -1, _(u"Alt"))
self.shift = wx.CheckBox(panel, -1, _(u"Shift")) self.shift = wx.CheckBox(panel, -1, _(u"Shift"))
self.win = wx.CheckBox(panel, -1, _(u"Windows")) self.win = wx.CheckBox(panel, -1, _(u"Windows"))
sizer1 = wx.BoxSizer(wx.HORIZONTAL) sizer1 = wx.BoxSizer(wx.HORIZONTAL)
sizer1.Add(self.control) sizer1.Add(self.control)
sizer1.Add(self.alt) sizer1.Add(self.alt)
sizer1.Add(self.shift) sizer1.Add(self.shift)
sizer1.Add(self.win) sizer1.Add(self.win)
charLabel = wx.StaticText(panel, -1, _(u"Key")) charLabel = wx.StaticText(panel, -1, _(u"Key"))
self.key = wx.TextCtrl(panel, -1) self.key = wx.TextCtrl(panel, -1)
sizer2 = wx.BoxSizer(wx.HORIZONTAL) sizer2 = wx.BoxSizer(wx.HORIZONTAL)
sizer2.Add(charLabel) sizer2.Add(charLabel)
sizer2.Add(self.key) sizer2.Add(self.key)
ok = wx.Button(panel, wx.ID_OK, _(u"OK")) ok = wx.Button(panel, wx.ID_OK, _(u"OK"))
ok.SetDefault() ok.SetDefault()
cancel = wx.Button(panel, wx.ID_CANCEL) cancel = wx.Button(panel, wx.ID_CANCEL)
sizer3 = wx.BoxSizer(wx.HORIZONTAL) sizer3 = wx.BoxSizer(wx.HORIZONTAL)
sizer3.Add(ok) sizer3.Add(ok)
sizer3.Add(cancel) sizer3.Add(cancel)
sizer.Add(sizer1) sizer.Add(sizer1)
sizer.Add(sizer2) sizer.Add(sizer2)
sizer.Add(sizer3) sizer.Add(sizer3)
panel.SetSizerAndFit(sizer) panel.SetSizerAndFit(sizer)
def no_win_message(): def no_win_message():
return wx.MessageDialog(None, _(u"You need to use the Windows key"), _(u"Invalid keystroke"), wx.OK|wx.ICON_ERROR).ShowModal() return wx.MessageDialog(None, _(u"You need to use the Windows key"), _(u"Invalid keystroke"), wx.OK|wx.ICON_ERROR).ShowModal()
def no_key(): def no_key():
return wx.MessageDialog(None, _(u"You must provide a character for the keystroke"), _(u"Invalid keystroke"), wx.ICON_ERROR).ShowModal() return wx.MessageDialog(None, _(u"You must provide a character for the keystroke"), _(u"Invalid keystroke"), wx.ICON_ERROR).ShowModal()

View File

@ -1,34 +1,34 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
############################################################ ############################################################
# Copyright (c) 2015 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net> # Copyright (c) 2015 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or # the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
############################################################ ############################################################
from twitter import utils from twitter import utils
def is_long(tweet): def is_long(tweet):
if tweet.has_key("is_quote_status") and tweet["is_quote_status"] == True and tweet.has_key("quoted_status"): if "is_quote_status" in tweet and tweet["is_quote_status"] == True and "quoted_status" in tweet:
return tweet["quoted_status_id"] return tweet["quoted_status_id"]
return False return False
def clear_url(tweet): def clear_url(tweet):
if tweet.has_key("full_text"): if "full_text" in tweet:
value = "full_text" value = "full_text"
else: else:
value = "text" value = "text"
urls = utils.find_urls_in_text(tweet[value]) urls = utils.find_urls_in_text(tweet[value])
try: tweet["message"] = tweet["message"].replace(urls[-1], "") try: tweet["message"] = tweet["message"].replace(urls[-1], "")
except IndexError: pass except IndexError: pass
return tweet return tweet

View File

@ -1,87 +1,88 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
############################################################ ############################################################
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net> # Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or # the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
############################################################ ############################################################
import requests from __future__ import print_function
import keys import requests
import logging import keys
log = logging.getLogger("long_tweets.twishort") import logging
from twitter import utils log = logging.getLogger("long_tweets.twishort")
from requests_oauthlib import OAuth1Session from twitter import utils
from requests_oauthlib import OAuth1Session
def get_twishort_uri(url):
try: def get_twishort_uri(url):
return url.split("twishort.com/")[1] try:
except ValueError: return url.split("twishort.com/")[1]
return False except ValueError:
return False
def is_long(tweet):
long = False def is_long(tweet):
for url in range(0, len(tweet["entities"]["urls"])): long = False
try: for url in range(0, len(tweet["entities"]["urls"])):
if tweet["entities"]["urls"][url] != None and "twishort.com" in tweet["entities"]["urls"][url]["expanded_url"]: try:
long = get_twishort_uri(tweet["entities"]["urls"][url]["expanded_url"]) if tweet["entities"]["urls"][url] != None and "twishort.com" in tweet["entities"]["urls"][url]["expanded_url"]:
except IndexError: long = get_twishort_uri(tweet["entities"]["urls"][url]["expanded_url"])
pass except IndexError:
# sometimes Twitter returns URL's with None objects, so let's take it. pass
# see https://github.com/manuelcortez/TWBlue/issues/103 # sometimes Twitter returns URL's with None objects, so let's take it.
except TypeError: # see https://github.com/manuelcortez/TWBlue/issues/103
pass except TypeError:
if long == False and tweet.has_key("retweeted_status"): pass
for url in range(0, len(tweet["retweeted_status"]["entities"]["urls"])): if long == False and "retweeted_status" in tweet:
try: for url in range(0, len(tweet["retweeted_status"]["entities"]["urls"])):
if tweet["retweeted_status"]["entities"]["urls"][url] != None and "twishort.com" in tweet["retweeted_status"]["entities"]["urls"][url]["expanded_url"]: try:
long = get_twishort_uri(tweet["retweeted_status"]["entities"]["urls"][url]["expanded_url"]) if tweet["retweeted_status"]["entities"]["urls"][url] != None and "twishort.com" in tweet["retweeted_status"]["entities"]["urls"][url]["expanded_url"]:
except IndexError: long = get_twishort_uri(tweet["retweeted_status"]["entities"]["urls"][url]["expanded_url"])
pass except IndexError:
except TypeError: pass
pass except TypeError:
return long pass
return long
def get_full_text(uri):
try: def get_full_text(uri):
r = requests.get("http://api.twishort.com/1.1/get.json", params={"uri": uri, "api_key": keys.keyring.get("twishort_api_key")}) try:
msg = r.json()["text"] r = requests.get("http://api.twishort.com/1.1/get.json", params={"uri": uri, "api_key": keys.keyring.get("twishort_api_key")})
# Try to parse possible HTML entities. msg = r.json()["text"]
from twitter.compose import StripChars # Try to parse possible HTML entities.
msg = StripChars(msg) from twitter.compose import StripChars
return msg msg = StripChars(msg)
except: return msg
return False except:
return False
def create_tweet(user_token, user_secret, text, media=0):
twitter = OAuth1Session(keys.keyring.get("api_key"), client_secret=keys.keyring.get("api_secret"), resource_owner_key=user_token, resource_owner_secret=user_secret) def create_tweet(user_token, user_secret, text, media=0):
twishort_key=keys.keyring.get("twishort_api_key") twitter = OAuth1Session(keys.keyring.get("api_key"), client_secret=keys.keyring.get("api_secret"), resource_owner_key=user_token, resource_owner_secret=user_secret)
x_auth_service_provider = "https://api.twitter.com/1.1/account/verify_credentials.json" twishort_key=keys.keyring.get("twishort_api_key")
twishort_post_url = "http://api.twishort.com/1.1/post.json" x_auth_service_provider = "https://api.twitter.com/1.1/account/verify_credentials.json"
twishort_update_ids_url = "http://api.twishort.com/1.1/update_ids.json" twishort_post_url = "http://api.twishort.com/1.1/post.json"
r=requests.Request('GET', x_auth_service_provider) twishort_update_ids_url = "http://api.twishort.com/1.1/update_ids.json"
prep=twitter.prepare_request(r) r=requests.Request('GET', x_auth_service_provider)
resp=twitter.send(prep) prep=twitter.prepare_request(r)
twitter.headers={ resp=twitter.send(prep)
'X-Auth-Service-Provider':x_auth_service_provider, twitter.headers={
'X-Verify-Credentials-Authorization':prep.headers['Authorization'], 'X-Auth-Service-Provider':x_auth_service_provider,
} 'X-Verify-Credentials-Authorization':prep.headers['Authorization'],
data = {'api_key':twishort_key, }
"text": text.encode("utf-8"), data = {'api_key':twishort_key,
"media": media} "text": text.encode("utf-8"),
response = twitter.post(twishort_post_url, data=data) "media": media}
try: response = twitter.post(twishort_post_url, data=data)
return response.json()["text_to_tweet"] try:
except: return response.json()["text_to_tweet"]
print "There was a problem creating a long tweet" except:
return 0 print("There was a problem creating a long tweet")
return 0

View File

@ -1 +1,2 @@
import widgets from __future__ import absolute_import
from . import widgets

View File

@ -1,21 +1,22 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" A cross platform notification system. """ A cross platform notification system.
Under Linux, the wx.NotificationMessage does not show a notification on the taskbar, so we decided to use dbus for showing notifications for linux and wx for Windows.""" Under Linux, the wx.NotificationMessage does not show a notification on the taskbar, so we decided to use dbus for showing notifications for linux and wx for Windows."""
import platform from __future__ import absolute_import
import platform
notify = None
notify = None
def setup():
global notify def setup():
if platform.system() == "Windows": global notify
import windows if platform.system() == "Windows":
notify = windows.notification() from . import windows
elif platform.system() == "Linux": notify = windows.notification()
import linux elif platform.system() == "Linux":
notify = linux.notification() from . import linux
notify = linux.notification()
def send(title, text):
global notify def send(title, text):
if not notify or notify is None: global notify
setup() if not notify or notify is None:
setup()
notify.notify(title, text) notify.notify(title, text)

View File

@ -1,41 +1,42 @@
import _winreg from __future__ import print_function
import os import _winreg
import sys import os
from platform_utils import paths import sys
from platform_utils import paths
RUN_REGKEY = ur"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
RUN_REGKEY = ur"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
def is_installed(app_subkey):
"""Checks if the currently running copy is installed or portable variant. Requires the name of the application subkey found under the uninstall section in Windows registry.""" def is_installed(app_subkey):
"""Checks if the currently running copy is installed or portable variant. Requires the name of the application subkey found under the uninstall section in Windows registry."""
try:
key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s" % app_subkey) try:
inst_dir = _winreg.QueryValueEx(key,"InstallLocation")[0] key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s" % app_subkey)
except WindowsError: inst_dir = _winreg.QueryValueEx(key,"InstallLocation")[0]
return False except WindowsError:
_winreg.CloseKey(key) return False
try: _winreg.CloseKey(key)
return os.stat(inst_dir) == os.stat(paths.app_path()) try:
except WindowsError: return os.stat(inst_dir) == os.stat(paths.app_path())
return False except WindowsError:
return False
def getAutoStart(app_name):
"""Queries if the automatic startup should be set for the application or not, depending on it's current state.""" def getAutoStart(app_name):
"""Queries if the automatic startup should be set for the application or not, depending on it's current state."""
try:
key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, RUN_REGKEY) try:
val = _winreg.QueryValueEx(key, unicode(app_name))[0] key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, RUN_REGKEY)
return os.stat(val) == os.stat(sys.argv[0]) val = _winreg.QueryValueEx(key, unicode(app_name))[0]
except (WindowsError, OSError): return os.stat(val) == os.stat(sys.argv[0])
return False except (WindowsError, OSError):
return False
def setAutoStart(app_name, enable=True):
"""Configures automatic startup for the application, if the enable argument is set to True. If set to False, deletes the application AutoStart value.""" def setAutoStart(app_name, enable=True):
print paths.get_executable() """Configures automatic startup for the application, if the enable argument is set to True. If set to False, deletes the application AutoStart value."""
if getAutoStart(app_name) == enable: print(paths.get_executable())
return if getAutoStart(app_name) == enable:
key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, RUN_REGKEY, 0, _winreg.KEY_WRITE) return
if enable: key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, RUN_REGKEY, 0, _winreg.KEY_WRITE)
_winreg.SetValueEx(key, unicode(app_name), None, _winreg.REG_SZ, paths.get_executable()) if enable:
else: _winreg.SetValueEx(key, unicode(app_name), None, _winreg.REG_SZ, paths.get_executable())
_winreg.DeleteValue(key, unicode(app_name)) else:
_winreg.DeleteValue(key, unicode(app_name))

View File

@ -1,49 +1,50 @@
# -*- coding: cp1252 -*- # -*- coding: cp1252 -*-
#from config_utils import Configuration, ConfigurationResetException #from config_utils import Configuration, ConfigurationResetException
import config from __future__ import absolute_import
import paths import config
import os import paths
import logging import os
log = logging.getLogger("sessionmanager.manager") import logging
import session_exceptions log = logging.getLogger("sessionmanager.manager")
from . import session_exceptions
manager = None
def setup(): manager = None
global manager def setup():
if not manager: global manager
manager = sessionManager() if not manager:
manager = sessionManager()
class sessionManager(object):
# def __init__(self): class sessionManager(object):
# FILE = "sessions.conf" # def __init__(self):
# SPEC = "app-configuration.defaults" # FILE = "sessions.conf"
# try: # SPEC = "app-configuration.defaults"
# self.main = Configuration(paths.config_path(FILE), paths.app_path(SPEC)) # try:
# except ConfigurationResetException: # self.main = Configuration(paths.config_path(FILE), paths.app_path(SPEC))
# pass # except ConfigurationResetException:
# pass
def get_current_session(self):
if self.is_valid(config.app["sessions"]["current_session"]): def get_current_session(self):
return config.app["sessions"]["current_session"] if self.is_valid(config.app["sessions"]["current_session"]):
else: return config.app["sessions"]["current_session"]
return False else:
return False
def add_session(self, id):
log.debug("Adding a new session: %s" % (id,)) def add_session(self, id):
path = paths.config_path(id) log.debug("Adding a new session: %s" % (id,))
if not os.path.exists(path): path = paths.config_path(id)
log.debug("Creating %s path" % (paths.config_path(path),)) if not os.path.exists(path):
os.mkdir(path) log.debug("Creating %s path" % (paths.config_path(path),))
config.app["sessions"]["sessions"].append(id) os.mkdir(path)
config.app["sessions"]["sessions"].append(id)
def set_current_session(self, sessionID):
config.app["sessions"]["current_session"] = sessionID def set_current_session(self, sessionID):
config.app.write() config.app["sessions"]["current_session"] = sessionID
config.app.write()
def is_valid(self, id):
if not os.path.exists(paths.config_path(id)): def is_valid(self, id):
raise session_exceptions.NonExistentSessionError("That session does not exist.") if not os.path.exists(paths.config_path(id)):
config.app["sessions"]["current_session"] = "" raise session_exceptions.NonExistentSessionError("That session does not exist.")
return False config.app["sessions"]["current_session"] = ""
else: return False
else:
return True return True

View File

@ -1,482 +1,483 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" The main session object. Here are the twitter functions to interact with the "model" of TWBlue.""" """ The main session object. Here are the twitter functions to interact with the "model" of TWBlue."""
import urllib2 from __future__ import absolute_import
import config import urllib2
import twitter import config
from keys import keyring import twitter
import session_exceptions as Exceptions from keys import keyring
import paths from . import session_exceptions as Exceptions
import output import paths
import time import output
import sound import time
import logging import sound
from twitter import utils, compose import logging
from twython import TwythonError, TwythonRateLimitError, TwythonAuthError from twitter import utils, compose
import config_utils from twython import TwythonError, TwythonRateLimitError, TwythonAuthError
import shelve import config_utils
import application import shelve
import os import application
from mysc.thread_utils import stream_threaded import os
from pubsub import pub from mysc.thread_utils import stream_threaded
log = logging.getLogger("sessionmanager.session") from pubsub import pub
from long_tweets import tweets, twishort log = logging.getLogger("sessionmanager.session")
from long_tweets import tweets, twishort
sessions = {}
sessions = {}
class Session(object):
""" A session object where we will save configuration, the twitter object and a local storage for saving the items retrieved through the Twitter API methods""" class Session(object):
""" A session object where we will save configuration, the twitter object and a local storage for saving the items retrieved through the Twitter API methods"""
# Decorators.
# Decorators.
def _require_login(fn):
def _require_login(fn):
""" Decorator for checking if the user is logged in(a twitter object has credentials) on twitter.
Some functions may need this to avoid making unneeded twitter API calls.""" """ Decorator for checking if the user is logged in(a twitter object has credentials) on twitter.
Some functions may need this to avoid making unneeded twitter API calls."""
def f(self, *args, **kwargs):
if self.logged == True: def f(self, *args, **kwargs):
fn(self, *args, **kwargs) if self.logged == True:
else: fn(self, *args, **kwargs)
raise Exceptions.NotLoggedSessionError("You are not logged in yet.") else:
return f raise Exceptions.NotLoggedSessionError("You are not logged in yet.")
return f
def _require_configuration(fn):
def _require_configuration(fn):
""" Check if the user has a configured session."""
""" Check if the user has a configured session."""
def f(self, *args, **kwargs):
if self.settings != None: def f(self, *args, **kwargs):
fn(self, *args, **kwargs) if self.settings != None:
else: fn(self, *args, **kwargs)
raise Exceptions.NotConfiguredSessionError("Not configured.") else:
return f raise Exceptions.NotConfiguredSessionError("Not configured.")
return f
def order_buffer(self, name, data, ignore_older=True):
def order_buffer(self, name, data, ignore_older=True):
""" Put the new items in the local database.
name str: The name for the buffer stored in the dictionary. """ Put the new items in the local database.
data list: A list with tweets. name str: The name for the buffer stored in the dictionary.
returns the number of items that have been added in this execution""" data list: A list with tweets.
returns the number of items that have been added in this execution"""
num = 0
last_id = None num = 0
if self.db.has_key(name) == False: last_id = None
self.db[name] = [] if (name in self.db) == False:
if ignore_older and len(self.db[name]) > 0: self.db[name] = []
if self.settings["general"]["reverse_timelines"] == False: if ignore_older and len(self.db[name]) > 0:
last_id = self.db[name][0]["id"] if self.settings["general"]["reverse_timelines"] == False:
else: last_id = self.db[name][0]["id"]
last_id = self.db[name][-1]["id"] else:
for i in data: last_id = self.db[name][-1]["id"]
if ignore_older and last_id != None: for i in data:
if i["id"] < last_id: if ignore_older and last_id != None:
log.error("Ignoring an older tweet... Last id: {0}, tweet id: {1}".format(last_id, i["id"])) if i["id"] < last_id:
continue log.error("Ignoring an older tweet... Last id: {0}, tweet id: {1}".format(last_id, i["id"]))
if utils.find_item(i["id"], self.db[name]) == None and utils.is_allowed(i, self.settings["twitter"]["ignored_clients"]) == True: continue
try: i = self.check_quoted_status(i) if utils.find_item(i["id"], self.db[name]) == None and utils.is_allowed(i, self.settings["twitter"]["ignored_clients"]) == True:
except: pass try: i = self.check_quoted_status(i)
i = self.check_long_tweet(i) except: pass
if i == False: continue i = self.check_long_tweet(i)
if self.settings["general"]["reverse_timelines"] == False: self.db[name].append(i) if i == False: continue
else: self.db[name].insert(0, i) if self.settings["general"]["reverse_timelines"] == False: self.db[name].append(i)
num = num+1 else: self.db[name].insert(0, i)
return num num = num+1
return num
def order_cursored_buffer(self, name, data):
def order_cursored_buffer(self, name, data):
""" Put the new items on the local database. Useful for cursored buffers (followers, friends, users of a list and searches)
name str: The name for the buffer stored in the dictionary. """ Put the new items on the local database. Useful for cursored buffers (followers, friends, users of a list and searches)
data list: A list with items and some information about cursors. name str: The name for the buffer stored in the dictionary.
returns the number of items that have been added in this execution""" data list: A list with items and some information about cursors.
returns the number of items that have been added in this execution"""
num = 0
if self.db.has_key(name) == False: num = 0
self.db[name] = {} if (name in self.db) == False:
self.db[name]["items"] = [] self.db[name] = {}
# if len(self.db[name]["items"]) > 0: self.db[name]["items"] = []
for i in data: # if len(self.db[name]["items"]) > 0:
if utils.find_item(i["id"], self.db[name]["items"]) == None: for i in data:
if self.settings["general"]["reverse_timelines"] == False: self.db[name]["items"].append(i) if utils.find_item(i["id"], self.db[name]["items"]) == None:
else: self.db[name]["items"].insert(0, i) if self.settings["general"]["reverse_timelines"] == False: self.db[name]["items"].append(i)
num = num+1 else: self.db[name]["items"].insert(0, i)
return num num = num+1
return num
def __init__(self, session_id):
def __init__(self, session_id):
""" session_id (str): The name of the folder inside the config directory where the session is located."""
""" session_id (str): The name of the folder inside the config directory where the session is located."""
super(Session, self).__init__()
self.session_id = session_id super(Session, self).__init__()
self.logged = False self.session_id = session_id
self.settings = None self.logged = False
self.twitter = twitter.twitter.twitter() self.settings = None
self.db={} self.twitter = twitter.twitter.twitter()
self.reconnection_function_active = False self.db={}
self.counter = 0 self.reconnection_function_active = False
self.lists = [] self.counter = 0
pub.subscribe(self.add_friends, "friends-receibed") self.lists = []
pub.subscribe(self.add_friends, "friends-receibed")
@property
def is_logged(self): @property
return self.logged def is_logged(self):
return self.logged
def get_configuration(self):
def get_configuration(self):
""" Gets settings for a session."""
""" Gets settings for a session."""
file_ = "%s/session.conf" % (self.session_id,)
# try: file_ = "%s/session.conf" % (self.session_id,)
log.debug("Creating config file %s" % (file_,)) # try:
self.settings = config_utils.load_config(paths.config_path(file_), paths.app_path("Conf.defaults")) log.debug("Creating config file %s" % (file_,))
self.init_sound() self.settings = config_utils.load_config(paths.config_path(file_), paths.app_path("Conf.defaults"))
self.deshelve() self.init_sound()
# except: self.deshelve()
# log.exception("The session configuration has failed.") # except:
# self.settings = None # log.exception("The session configuration has failed.")
# self.settings = None
def init_sound(self):
try: self.sound = sound.soundSystem(self.settings["sound"]) def init_sound(self):
except: log.exception("Exception thrown during sound system initialization") try: self.sound = sound.soundSystem(self.settings["sound"])
except: log.exception("Exception thrown during sound system initialization")
@_require_configuration
def login(self, verify_credentials=True): @_require_configuration
def login(self, verify_credentials=True):
""" Log into twitter using credentials from settings.
if the user account isn't authorised, it needs to call self.authorise() before login.""" """ Log into twitter using credentials from settings.
if the user account isn't authorised, it needs to call self.authorise() before login."""
if self.settings["twitter"]["user_key"] != None and self.settings["twitter"]["user_secret"] != None:
try: if self.settings["twitter"]["user_key"] != None and self.settings["twitter"]["user_secret"] != None:
log.debug("Logging in to twitter...") try:
self.twitter.login(self.settings["twitter"]["user_key"], self.settings["twitter"]["user_secret"], verify_credentials) log.debug("Logging in to twitter...")
self.logged = True self.twitter.login(self.settings["twitter"]["user_key"], self.settings["twitter"]["user_secret"], verify_credentials)
log.debug("Logged.") self.logged = True
self.counter = 0 log.debug("Logged.")
except: self.counter = 0
log.error("The login attempt failed.") except:
self.logged = False log.error("The login attempt failed.")
else: self.logged = False
self.logged = False else:
raise Exceptions.RequireCredentialsSessionError self.logged = False
raise Exceptions.RequireCredentialsSessionError
@_require_configuration
def authorise(self): @_require_configuration
def authorise(self):
""" Authorises a Twitter account. This function needs to be called for each new session, after self.get_configuration() and before self.login()"""
""" Authorises a Twitter account. This function needs to be called for each new session, after self.get_configuration() and before self.login()"""
if self.logged == True:
raise Exceptions.AlreadyAuthorisedError("The authorisation process is not needed at this time.") if self.logged == True:
else: raise Exceptions.AlreadyAuthorisedError("The authorisation process is not needed at this time.")
self.twitter.authorise(self.settings) else:
self.twitter.authorise(self.settings)
def get_more_items(self, update_function, users=False, name=None, *args, **kwargs):
results = [] def get_more_items(self, update_function, users=False, name=None, *args, **kwargs):
data = getattr(self.twitter.twitter, update_function)(*args, **kwargs) results = []
if users == True: data = getattr(self.twitter.twitter, update_function)(*args, **kwargs)
if type(data) == dict and data.has_key("cursor"): if users == True:
self.db[name]["cursor"] = data["next_cursor"] if type(data) == dict and "cursor" in data:
for i in data["users"]: results.append(i) self.db[name]["cursor"] = data["next_cursor"]
elif type(data) == list: for i in data["users"]: results.append(i)
results.extend(data[1:]) elif type(data) == list:
else: results.extend(data[1:])
results.extend(data[1:]) else:
return results results.extend(data[1:])
return results
def api_call(self, call_name, action="", _sound=None, report_success=False, report_failure=True, preexec_message="", *args, **kwargs):
def api_call(self, call_name, action="", _sound=None, report_success=False, report_failure=True, preexec_message="", *args, **kwargs):
""" Make a call to the Twitter API. If there is a connectionError or another exception not related to Twitter, It will call the method again at least 25 times, waiting a while between calls. Useful for post methods.
If twitter returns an error, it will not call the method anymore. """ Make a call to the Twitter API. If there is a connectionError or another exception not related to Twitter, It will call the method again at least 25 times, waiting a while between calls. Useful for post methods.
call_name str: The method to call If twitter returns an error, it will not call the method anymore.
action str: What you are doing on twitter, it will be reported to the user if report_success is set to True. call_name str: The method to call
for example "following @tw_blue2" will be reported as "following @tw_blue2 succeeded". action str: What you are doing on twitter, it will be reported to the user if report_success is set to True.
_sound str: a sound to play if the call is executed properly. for example "following @tw_blue2" will be reported as "following @tw_blue2 succeeded".
report_success and report_failure bool: These are self explanatory. True or False. _sound str: a sound to play if the call is executed properly.
preexec_message str: A message to speak to the user while the method is running, example: "trying to follow x user".""" report_success and report_failure bool: These are self explanatory. True or False.
preexec_message str: A message to speak to the user while the method is running, example: "trying to follow x user"."""
finished = False
tries = 0 finished = False
if preexec_message: tries = 0
output.speak(preexec_message, True) if preexec_message:
while finished==False and tries < 25: output.speak(preexec_message, True)
try: while finished==False and tries < 25:
val = getattr(self.twitter.twitter, call_name)(*args, **kwargs) try:
finished = True val = getattr(self.twitter.twitter, call_name)(*args, **kwargs)
except TwythonError as e: finished = True
output.speak(e.message) except TwythonError as e:
if e.error_code != 403 and e.error_code != 404: output.speak(e.message)
tries = tries+1 if e.error_code != 403 and e.error_code != 404:
time.sleep(5) tries = tries+1
elif report_failure and hasattr(e, 'message'): time.sleep(5)
output.speak(_("%s failed. Reason: %s") % (action, e.message)) elif report_failure and hasattr(e, 'message'):
finished = True output.speak(_("%s failed. Reason: %s") % (action, e.message))
# except: finished = True
# tries = tries + 1 # except:
# time.sleep(5) # tries = tries + 1
if report_success: # time.sleep(5)
output.speak(_("%s succeeded.") % action) if report_success:
if _sound != None: self.sound.play(_sound) output.speak(_("%s succeeded.") % action)
return val if _sound != None: self.sound.play(_sound)
return val
def search(self, name, *args, **kwargs):
tl = self.twitter.twitter.search(*args, **kwargs) def search(self, name, *args, **kwargs):
tl["statuses"].reverse() tl = self.twitter.twitter.search(*args, **kwargs)
return tl["statuses"] tl["statuses"].reverse()
return tl["statuses"]
@_require_login
def get_favourites_timeline(self, name, *args, **kwargs): @_require_login
def get_favourites_timeline(self, name, *args, **kwargs):
""" Gets favourites for the authenticated user or a friend or follower.
name str: Name for storage in the database.""" """ Gets favourites for the authenticated user or a friend or follower.
name str: Name for storage in the database."""
tl = self.call_paged(self.twitter.twitter.get_favorites, *args, **kwargs)
return self.order_buffer(name, tl) tl = self.call_paged(self.twitter.twitter.get_favorites, *args, **kwargs)
return self.order_buffer(name, tl)
def call_paged(self, update_function, *args, **kwargs):
def call_paged(self, update_function, *args, **kwargs):
""" Makes a call to the Twitter API methods several times. Useful for get methods.
this function is needed for retrieving more than 200 items. """ Makes a call to the Twitter API methods several times. Useful for get methods.
update_function str: The function to call. This function must be child of self.twitter.twitter this function is needed for retrieving more than 200 items.
returns a list with all items retrieved.""" update_function str: The function to call. This function must be child of self.twitter.twitter
returns a list with all items retrieved."""
max = int(self.settings["general"]["max_api_calls"])-1
results = [] max = int(self.settings["general"]["max_api_calls"])-1
data = getattr(self.twitter.twitter, update_function)(count=self.settings["general"]["max_tweets_per_call"], *args, **kwargs) results = []
results.extend(data) data = getattr(self.twitter.twitter, update_function)(count=self.settings["general"]["max_tweets_per_call"], *args, **kwargs)
for i in range(0, max): results.extend(data)
if i == 0: max_id = results[-1]["id"] for i in range(0, max):
else: max_id = results[0]["id"] if i == 0: max_id = results[-1]["id"]
data = getattr(self.twitter.twitter, update_function)(max_id=max_id, count=self.settings["general"]["max_tweets_per_call"], *args, **kwargs) else: max_id = results[0]["id"]
results.extend(data) data = getattr(self.twitter.twitter, update_function)(max_id=max_id, count=self.settings["general"]["max_tweets_per_call"], *args, **kwargs)
results.reverse() results.extend(data)
return results results.reverse()
return results
@_require_login
def get_user_info(self): @_require_login
def get_user_info(self):
""" Retrieves some information required by TWBlue for setup."""
f = self.twitter.twitter.get_account_settings() """ Retrieves some information required by TWBlue for setup."""
sn = f["screen_name"] f = self.twitter.twitter.get_account_settings()
self.settings["twitter"]["user_name"] = sn sn = f["screen_name"]
self.db["user_name"] = sn self.settings["twitter"]["user_name"] = sn
self.db["user_id"] = self.twitter.twitter.show_user(screen_name=sn)["id_str"] self.db["user_name"] = sn
try: self.db["user_id"] = self.twitter.twitter.show_user(screen_name=sn)["id_str"]
self.db["utc_offset"] = f["time_zone"]["utc_offset"] try:
except KeyError: self.db["utc_offset"] = f["time_zone"]["utc_offset"]
self.db["utc_offset"] = -time.timezone except KeyError:
self.get_lists() self.db["utc_offset"] = -time.timezone
self.get_muted_users() self.get_lists()
self.settings.write() self.get_muted_users()
self.settings.write()
@_require_login
def get_lists(self): @_require_login
def get_lists(self):
""" Gets the lists that the user is subscribed to and stores them in the database. Returns None."""
""" Gets the lists that the user is subscribed to and stores them in the database. Returns None."""
self.db["lists"] = self.twitter.twitter.show_lists(reverse=True)
self.db["lists"] = self.twitter.twitter.show_lists(reverse=True)
@_require_login
def get_muted_users(self): @_require_login
def get_muted_users(self):
""" Gets muted users (oh really?)."""
""" Gets muted users (oh really?)."""
self.db["muted_users"] = self.twitter.twitter.list_mute_ids()["ids"]
self.db["muted_users"] = self.twitter.twitter.list_mute_ids()["ids"]
@_require_login
def get_stream(self, name, function, *args, **kwargs): @_require_login
def get_stream(self, name, function, *args, **kwargs):
""" Retrieves the items for a regular stream.
name str: Name to save items to the database. """ Retrieves the items for a regular stream.
function str: A function to get the items.""" name str: Name to save items to the database.
function str: A function to get the items."""
last_id = -1
if self.db.has_key(name): last_id = -1
try: if name in self.db:
if self.db[name][0]["id"] > self.db[name][-1]["id"]: try:
last_id = self.db[name][0]["id"] if self.db[name][0]["id"] > self.db[name][-1]["id"]:
else: last_id = self.db[name][0]["id"]
last_id = self.db[name][-1]["id"] else:
except IndexError: last_id = self.db[name][-1]["id"]
pass except IndexError:
tl = self.call_paged(function, sinze_id=last_id, *args, **kwargs) pass
self.order_buffer(name, tl) tl = self.call_paged(function, sinze_id=last_id, *args, **kwargs)
self.order_buffer(name, tl)
def get_cursored_stream(self, name, function, items="users", get_previous=False, *args, **kwargs):
def get_cursored_stream(self, name, function, items="users", get_previous=False, *args, **kwargs):
""" Gets items for API calls that require using cursors to paginate the results.
name str: Name to save it in the database. """ Gets items for API calls that require using cursors to paginate the results.
function str: Function that provides the items. name str: Name to save it in the database.
items: When the function returns the list with results, items will tell how the order function should be look. function str: Function that provides the items.
for example get_followers_list returns a list and users are under list["users"], here the items should point to "users".""" items: When the function returns the list with results, items will tell how the order function should be look.
for example get_followers_list returns a list and users are under list["users"], here the items should point to "users"."""
items_ = []
try: items_ = []
if self.db[name].has_key("cursor") and get_previous: try:
cursor = self.db[name]["cursor"] if "cursor" in self.db[name] and get_previous:
else: cursor = self.db[name]["cursor"]
cursor = -1 else:
except KeyError: cursor = -1
cursor = -1 except KeyError:
tl = getattr(self.twitter.twitter, function)(cursor=cursor, count=self.settings["general"]["max_tweets_per_call"], *args, **kwargs) cursor = -1
tl[items].reverse() tl = getattr(self.twitter.twitter, function)(cursor=cursor, count=self.settings["general"]["max_tweets_per_call"], *args, **kwargs)
num = self.order_cursored_buffer(name, tl[items]) tl[items].reverse()
self.db[name]["cursor"] = tl["next_cursor"] num = self.order_cursored_buffer(name, tl[items])
return num self.db[name]["cursor"] = tl["next_cursor"]
return num
def start_streaming(self):
def start_streaming(self):
""" Start the streaming for sending tweets in realtime."""
if not hasattr(self, "main_stream"): """ Start the streaming for sending tweets in realtime."""
self.get_timelines() if not hasattr(self, "main_stream"):
if not hasattr(self, "timelinesStream"): self.get_timelines()
self.get_main_stream() if not hasattr(self, "timelinesStream"):
self.get_main_stream()
def get_main_stream(self):
log.debug("Starting the main stream...") def get_main_stream(self):
self.main_stream = twitter.buffers.stream.streamer(keyring.get("api_key"), keyring.get("api_secret"), self.settings["twitter"]["user_key"], self.settings["twitter"]["user_secret"], self) log.debug("Starting the main stream...")
stream_threaded(self.main_stream.user, self.session_id) self.main_stream = twitter.buffers.stream.streamer(keyring.get("api_key"), keyring.get("api_secret"), self.settings["twitter"]["user_key"], self.settings["twitter"]["user_secret"], self)
stream_threaded(self.main_stream.user, self.session_id)
def get_timelines(self):
log.debug("Starting the timelines stream...") def get_timelines(self):
self.timelinesStream = twitter.buffers.indibidual.timelinesStreamer(keyring.get("api_key"), keyring.get("api_secret"), self.settings["twitter"]["user_key"], self.settings["twitter"]["user_secret"], session=self) log.debug("Starting the timelines stream...")
ids = "" self.timelinesStream = twitter.buffers.indibidual.timelinesStreamer(keyring.get("api_key"), keyring.get("api_secret"), self.settings["twitter"]["user_key"], self.settings["twitter"]["user_secret"], session=self)
for i in self.settings["other_buffers"]["timelines"]: ids = ""
ids = ids + "%s, " % (self.db[i+"-timeline"][0]["user"]["id_str"]) for i in self.settings["other_buffers"]["timelines"]:
for i in self.lists: ids = ids + "%s, " % (self.db[i+"-timeline"][0]["user"]["id_str"])
for z in i.users: for i in self.lists:
ids += str(z) + ", " for z in i.users:
if ids != "": ids += str(z) + ", "
# print ids if ids != "":
stream_threaded(self.timelinesStream.statuses.filter, self.session_id, follow=ids) # print ids
stream_threaded(self.timelinesStream.statuses.filter, self.session_id, follow=ids)
def add_friends(self):
try: def add_friends(self):
# print "setting friends" try:
self.timelinesStream.set_friends(self.main_stream.friends) # print "setting friends"
except AttributeError: self.timelinesStream.set_friends(self.main_stream.friends)
pass except AttributeError:
pass
def listen_stream_error(self):
if hasattr(self, "main_stream"): def listen_stream_error(self):
log.debug("Disconnecting the main stream...") if hasattr(self, "main_stream"):
self.main_stream.disconnect() log.debug("Disconnecting the main stream...")
del self.main_stream self.main_stream.disconnect()
if hasattr(self, "timelinesStream"): del self.main_stream
log.debug("disconnecting the timelines stream...") if hasattr(self, "timelinesStream"):
self.timelinesStream.disconnect() log.debug("disconnecting the timelines stream...")
del self.timelinesStream self.timelinesStream.disconnect()
del self.timelinesStream
def check_connection(self):
instan = 0 def check_connection(self):
self.counter += 1 instan = 0
if self.counter >= 4: self.counter += 1
del self.twitter if self.counter >= 4:
self.logged = False del self.twitter
self.twitter = twitter.twitter.twitter() self.logged = False
self.login(False) self.twitter = twitter.twitter.twitter()
pub.sendMessage("restart_streams", session=self.session_id) self.login(False)
if self.reconnection_function_active == True: return pub.sendMessage("restart_streams", session=self.session_id)
self.reconnection_function_active = True if self.reconnection_function_active == True: return
if not hasattr(self, "main_stream"): self.reconnection_function_active = True
self.get_main_stream() if not hasattr(self, "main_stream"):
if not hasattr(self, "timelinesStream"): self.get_main_stream()
self.get_timelines() if not hasattr(self, "timelinesStream"):
self.reconnection_function_active = False self.get_timelines()
if hasattr(self, "timelinesStream") and not hasattr(self.timelinesStream, "friends"): self.reconnection_function_active = False
self.add_friends() if hasattr(self, "timelinesStream") and not hasattr(self.timelinesStream, "friends"):
# try: self.add_friends()
# urllib2.urlopen("http://74.125.228.231", timeout=5) # try:
# except urllib2.URLError: # urllib2.urlopen("http://74.125.228.231", timeout=5)
# pub.sendMessage("stream-error", session=self.session_id) # except urllib2.URLError:
# pub.sendMessage("stream-error", session=self.session_id)
def remove_stream(self, stream):
if stream == "timelinesStream": def remove_stream(self, stream):
if hasattr(self, "timelinesStream"): if stream == "timelinesStream":
self.timelinesStream.disconnect() if hasattr(self, "timelinesStream"):
del self.timelinesStream self.timelinesStream.disconnect()
else: del self.timelinesStream
self.main_stream.disconnect() else:
del self.main_stream self.main_stream.disconnect()
del self.main_stream
def shelve(self):
"Shelve the database to allow for persistance." def shelve(self):
shelfname=paths.config_path(str(self.session_id)+"/cache.db") "Shelve the database to allow for persistance."
if self.settings["general"]["persist_size"] == 0: shelfname=paths.config_path(str(self.session_id)+"/cache.db")
if os.path.exists(shelfname): if self.settings["general"]["persist_size"] == 0:
os.remove(shelfname) if os.path.exists(shelfname):
return os.remove(shelfname)
try: return
if not os.path.exists(shelfname): try:
output.speak("Generating database, this might take a while.",True) if not os.path.exists(shelfname):
shelf=shelve.open(paths.config_path(shelfname),'c') output.speak("Generating database, this might take a while.",True)
for key,value in self.db.items(): shelf=shelve.open(paths.config_path(shelfname),'c')
if type(key) != str and type(key) != unicode: for key,value in self.db.items():
output.speak("Uh oh, while shelving the database, a key of type " + str(type(key)) + " has been found. It will be converted to type str, but this will cause all sorts of problems on deshelve. Please bring this to the attention of the " + application.name + " developers immediately. More information about the error will be written to the error log.",True) if type(key) != str and type(key) != unicode:
log.error("Uh oh, " + str(key) + " is of type " + str(type(key)) + "!") output.speak("Uh oh, while shelving the database, a key of type " + str(type(key)) + " has been found. It will be converted to type str, but this will cause all sorts of problems on deshelve. Please bring this to the attention of the " + application.name + " developers immediately. More information about the error will be written to the error log.",True)
# Convert unicode objects to UTF-8 strings before shelve these objects. log.error("Uh oh, " + str(key) + " is of type " + str(type(key)) + "!")
if type(value) == list and self.settings["general"]["persist_size"] != -1 and len(value) > self.settings["general"]["persist_size"]: # Convert unicode objects to UTF-8 strings before shelve these objects.
shelf[str(key.encode("utf-8"))]=value[self.settings["general"]["persist_size"]:] if type(value) == list and self.settings["general"]["persist_size"] != -1 and len(value) > self.settings["general"]["persist_size"]:
else: shelf[str(key.encode("utf-8"))]=value[self.settings["general"]["persist_size"]:]
shelf[str(key.encode("utf-8"))]=value else:
shelf.close() shelf[str(key.encode("utf-8"))]=value
except: shelf.close()
output.speak("An exception occurred while shelving the " + application.name + " database. It will be deleted and rebuilt automatically. If this error persists, send the error log to the " + application.name + " developers.",True) except:
log.exception("Exception while shelving" + shelfname) output.speak("An exception occurred while shelving the " + application.name + " database. It will be deleted and rebuilt automatically. If this error persists, send the error log to the " + application.name + " developers.",True)
os.remove(shelfname) log.exception("Exception while shelving" + shelfname)
os.remove(shelfname)
def deshelve(self):
"Import a shelved database." def deshelve(self):
shelfname=paths.config_path(str(self.session_id)+"/cache.db") "Import a shelved database."
if self.settings["general"]["persist_size"] == 0: shelfname=paths.config_path(str(self.session_id)+"/cache.db")
if os.path.exists(shelfname): if self.settings["general"]["persist_size"] == 0:
os.remove(shelfname) if os.path.exists(shelfname):
return os.remove(shelfname)
try: return
shelf=shelve.open(paths.config_path(shelfname),'c') try:
for key,value in shelf.items(): shelf=shelve.open(paths.config_path(shelfname),'c')
self.db[key]=value for key,value in shelf.items():
shelf.close() self.db[key]=value
except: shelf.close()
output.speak("An exception occurred while deshelving the " + application.name + " database. It will be deleted and rebuilt automatically. If this error persists, send the error log to the " + application.name + " developers.",True) except:
log.exception("Exception while deshelving" + shelfname) output.speak("An exception occurred while deshelving the " + application.name + " database. It will be deleted and rebuilt automatically. If this error persists, send the error log to the " + application.name + " developers.",True)
try: log.exception("Exception while deshelving" + shelfname)
os.remove(shelfname) try:
except: os.remove(shelfname)
pass except:
pass
def check_quoted_status(self, tweet):
status = tweets.is_long(tweet) def check_quoted_status(self, tweet):
if status != False and config.app["app-settings"]["handle_longtweets"]: status = tweets.is_long(tweet)
tweet = self.get_quoted_tweet(tweet) if status != False and config.app["app-settings"]["handle_longtweets"]:
return tweet tweet = self.get_quoted_tweet(tweet)
return tweet
def get_quoted_tweet(self, tweet):
quoted_tweet = tweet def get_quoted_tweet(self, tweet):
if tweet.has_key("full_text"): quoted_tweet = tweet
value = "full_text" if "full_text" in tweet:
else: value = "full_text"
value = "text" else:
urls = utils.find_urls_in_text(quoted_tweet[value]) value = "text"
for url in range(0, len(urls)): urls = utils.find_urls_in_text(quoted_tweet[value])
try: quoted_tweet[value] = quoted_tweet[value].replace(urls[url], quoted_tweet["entities"]["urls"][url]["expanded_url"]) for url in range(0, len(urls)):
except IndexError: pass try: quoted_tweet[value] = quoted_tweet[value].replace(urls[url], quoted_tweet["entities"]["urls"][url]["expanded_url"])
id = tweets.is_long(quoted_tweet) except IndexError: pass
try: original_tweet = self.twitter.twitter.show_status(id=id, tweet_mode="extended") id = tweets.is_long(quoted_tweet)
except: return quoted_tweet try: original_tweet = self.twitter.twitter.show_status(id=id, tweet_mode="extended")
original_tweet = self.check_long_tweet(original_tweet) except: return quoted_tweet
urls = utils.find_urls_in_text(original_tweet["full_text"]) original_tweet = self.check_long_tweet(original_tweet)
for url in range(0, len(urls)): urls = utils.find_urls_in_text(original_tweet["full_text"])
try: original_tweet["full_text"] = original_tweet["full_text"].replace(urls[url], original_tweet["entities"]["urls"][url]["expanded_url"]) for url in range(0, len(urls)):
except IndexError: pass try: original_tweet["full_text"] = original_tweet["full_text"].replace(urls[url], original_tweet["entities"]["urls"][url]["expanded_url"])
return compose.compose_quoted_tweet(quoted_tweet, original_tweet) except IndexError: pass
return compose.compose_quoted_tweet(quoted_tweet, original_tweet)
def check_long_tweet(self, tweet):
long = twishort.is_long(tweet) def check_long_tweet(self, tweet):
if long != False and config.app["app-settings"]["handle_longtweets"]: long = twishort.is_long(tweet)
tweet["message"] = twishort.get_full_text(long) if long != False and config.app["app-settings"]["handle_longtweets"]:
if tweet["message"] == False: return False tweet["message"] = twishort.get_full_text(long)
tweet["twishort"] = True if tweet["message"] == False: return False
for i in tweet["entities"]["user_mentions"]: tweet["twishort"] = True
if "@%s" % (i["screen_name"]) not in tweet["message"] and i["screen_name"] != tweet["user"]["screen_name"]: for i in tweet["entities"]["user_mentions"]:
if tweet.has_key("retweeted_status") and tweet["retweeted_status"]["user"]["screen_name"] == i["screen_name"]: if "@%s" % (i["screen_name"]) not in tweet["message"] and i["screen_name"] != tweet["user"]["screen_name"]:
continue if "retweeted_status" in tweet and tweet["retweeted_status"]["user"]["screen_name"] == i["screen_name"]:
tweet["message"] = u"@%s %s" % (i["screen_name"], tweet["message"]) continue
tweet["message"] = u"@%s %s" % (i["screen_name"], tweet["message"])
return tweet return tweet

View File

@ -1,117 +1,118 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import shutil from __future__ import absolute_import
import widgetUtils import shutil
import platform import widgetUtils
import output import platform
if platform.system() == "Windows": import output
import wxUI as view if platform.system() == "Windows":
from controller import settings from . import wxUI as view
elif platform.system() == "Linux": from controller import settings
import gtkUI as view elif platform.system() == "Linux":
import paths from . import gtkUI as view
import time import paths
import os import time
import logging import os
import session import logging
import manager from . import session
import config_utils from . import manager
import config import config_utils
import config
log = logging.getLogger("sessionmanager.sessionManager")
log = logging.getLogger("sessionmanager.sessionManager")
class sessionManagerController(object):
def __init__(self, started=False): class sessionManagerController(object):
super(sessionManagerController, self).__init__() def __init__(self, started=False):
log.debug("Setting up the session manager.") super(sessionManagerController, self).__init__()
self.started = started log.debug("Setting up the session manager.")
manager.setup() self.started = started
self.view = view.sessionManagerWindow() manager.setup()
widgetUtils.connect_event(self.view.new, widgetUtils.BUTTON_PRESSED, self.manage_new_account) self.view = view.sessionManagerWindow()
widgetUtils.connect_event(self.view.remove, widgetUtils.BUTTON_PRESSED, self.remove) widgetUtils.connect_event(self.view.new, widgetUtils.BUTTON_PRESSED, self.manage_new_account)
if self.started == False: widgetUtils.connect_event(self.view.remove, widgetUtils.BUTTON_PRESSED, self.remove)
widgetUtils.connect_event(self.view.configuration, widgetUtils.BUTTON_PRESSED, self.configuration) if self.started == False:
else: widgetUtils.connect_event(self.view.configuration, widgetUtils.BUTTON_PRESSED, self.configuration)
self.view.hide_configuration() else:
self.new_sessions = {} self.view.hide_configuration()
self.removed_sessions = [] self.new_sessions = {}
self.removed_sessions = []
def fill_list(self):
sessionsList = [] def fill_list(self):
log.debug("Filling the sessions list.") sessionsList = []
self.sessions = [] log.debug("Filling the sessions list.")
for i in os.listdir(paths.config_path()): self.sessions = []
if os.path.isdir(paths.config_path(i)): for i in os.listdir(paths.config_path()):
log.debug("Adding session %s" % (i,)) if os.path.isdir(paths.config_path(i)):
strconfig = "%s/session.conf" % (paths.config_path(i)) log.debug("Adding session %s" % (i,))
config_test = config_utils.load_config(strconfig) strconfig = "%s/session.conf" % (paths.config_path(i))
if len(config_test) == 0: config_test = config_utils.load_config(strconfig)
try: if len(config_test) == 0:
log.debug("Deleting session %s" % (i,)) try:
shutil.rmtree(paths.config_path(i)) log.debug("Deleting session %s" % (i,))
continue shutil.rmtree(paths.config_path(i))
except: continue
output.speak("An exception was raised while attempting to clean malformed session data. See the error log for details. If this message persists, contact the developers.",True) except:
os.exception("Exception thrown while removing malformed session") output.speak("An exception was raised while attempting to clean malformed session data. See the error log for details. If this message persists, contact the developers.",True)
continue os.exception("Exception thrown while removing malformed session")
name = config_test["twitter"]["user_name"] continue
if config_test["twitter"]["user_key"] != "" and config_test["twitter"]["user_secret"] != "": name = config_test["twitter"]["user_name"]
sessionsList.append(name) if config_test["twitter"]["user_key"] != "" and config_test["twitter"]["user_secret"] != "":
self.sessions.append(i) sessionsList.append(name)
else: self.sessions.append(i)
try: else:
log.debug("Deleting session %s" % (i,)) try:
shutil.rmtree(paths.config_path(i)) log.debug("Deleting session %s" % (i,))
except: shutil.rmtree(paths.config_path(i))
output.speak("An exception was raised while attempting to clean malformed session data. See the error log for details. If this message persists, contact the developers.",True) except:
os.exception("Exception thrown while removing malformed session") output.speak("An exception was raised while attempting to clean malformed session data. See the error log for details. If this message persists, contact the developers.",True)
self.view.fill_list(sessionsList) os.exception("Exception thrown while removing malformed session")
self.view.fill_list(sessionsList)
def show(self):
if self.view.get_response() == widgetUtils.OK: def show(self):
self.do_ok() if self.view.get_response() == widgetUtils.OK:
# else: self.do_ok()
self.view.destroy() # else:
self.view.destroy()
def do_ok(self):
log.debug("Starting sessions...") def do_ok(self):
for i in self.sessions: log.debug("Starting sessions...")
if session.sessions.has_key(i) == True: continue for i in self.sessions:
s = session.Session(i) if (i in session.sessions) == True: continue
s.get_configuration() s = session.Session(i)
if i not in config.app["sessions"]["ignored_sessions"]: s.get_configuration()
s.login() if i not in config.app["sessions"]["ignored_sessions"]:
session.sessions[i] = s s.login()
self.new_sessions[i] = s session.sessions[i] = s
# self.view.destroy() self.new_sessions[i] = s
# self.view.destroy()
def manage_new_account(self, *args, **kwargs):
if self.view.new_account_dialog() == widgetUtils.YES: def manage_new_account(self, *args, **kwargs):
location = (str(time.time())[-6:]) if self.view.new_account_dialog() == widgetUtils.YES:
log.debug("Creating session in the %s path" % (location,)) location = (str(time.time())[-6:])
s = session.Session(location) log.debug("Creating session in the %s path" % (location,))
manager.manager.add_session(location) s = session.Session(location)
s.get_configuration() manager.manager.add_session(location)
# try: s.get_configuration()
s.authorise() # try:
self.sessions.append(location) s.authorise()
self.view.add_new_session_to_list() self.sessions.append(location)
s.settings.write() self.view.add_new_session_to_list()
# except: s.settings.write()
# log.exception("Error authorising the session") # except:
# self.view.show_unauthorised_error() # log.exception("Error authorising the session")
# return # self.view.show_unauthorised_error()
# return
def remove(self, *args, **kwargs):
if self.view.remove_account_dialog() == widgetUtils.YES: def remove(self, *args, **kwargs):
selected_account = self.sessions[self.view.get_selected()] if self.view.remove_account_dialog() == widgetUtils.YES:
self.view.remove_session(self.view.get_selected()) selected_account = self.sessions[self.view.get_selected()]
self.removed_sessions.append(selected_account) self.view.remove_session(self.view.get_selected())
self.sessions.remove(selected_account) self.removed_sessions.append(selected_account)
shutil.rmtree(path=paths.config_path(selected_account), ignore_errors=True) self.sessions.remove(selected_account)
shutil.rmtree(path=paths.config_path(selected_account), ignore_errors=True)
def configuration(self, *args, **kwargs):
""" Opens the global settings dialogue.""" def configuration(self, *args, **kwargs):
d = settings.globalSettingsController() """ Opens the global settings dialogue."""
if d.response == widgetUtils.OK: d = settings.globalSettingsController()
d.save_configuration() if d.response == widgetUtils.OK:
d.save_configuration()

View File

@ -1 +1,2 @@
import buffers, utils, compose, twitter from __future__ import absolute_import
from . import buffers, utils, compose, twitter

View File

@ -1 +1,2 @@
import stream, indibidual from __future__ import absolute_import
from . import stream, indibidual

View File

@ -1,71 +1,71 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import config import config
from requests.auth import HTTPProxyAuth from requests.auth import HTTPProxyAuth
from twitter import compose, utils from twitter import compose, utils
from twython import TwythonStreamer from twython import TwythonStreamer
from pubsub import pub from pubsub import pub
import logging as original_logger import logging as original_logger
log = original_logger.getLogger("TimelinesStream") log = original_logger.getLogger("TimelinesStream")
class timelinesStreamer(TwythonStreamer): class timelinesStreamer(TwythonStreamer):
def __init__(self, app_key, app_secret, oauth_token, oauth_token_secret, timeout=300, retry_count=None, retry_in=10, client_args=None, handlers=None, chunk_size=1, session=None): def __init__(self, app_key, app_secret, oauth_token, oauth_token_secret, timeout=300, retry_count=None, retry_in=10, client_args=None, handlers=None, chunk_size=1, session=None):
self.session = session self.session = session
super(timelinesStreamer, self).__init__(app_key, app_secret, oauth_token, oauth_token_secret, timeout=60, retry_count=None, retry_in=180, handlers=None, chunk_size=1) super(timelinesStreamer, self).__init__(app_key, app_secret, oauth_token, oauth_token_secret, timeout=60, retry_count=None, retry_in=180, handlers=None, chunk_size=1)
self.lists = self.session.lists self.lists = self.session.lists
def on_error(self, status_code, data): def on_error(self, status_code, data):
log.error("error in stream: %s: %s" % (status_code, data)) log.error("error in stream: %s: %s" % (status_code, data))
# pub.sendMessage("stream-error", session=self.session.session_id) # pub.sendMessage("stream-error", session=self.session.session_id)
def on_timeout(self, *args, **kwargs): def on_timeout(self, *args, **kwargs):
log.error("Twitter timeout Error") log.error("Twitter timeout Error")
# pub.sendMessage("stream-error", session=self.session.session_id) # pub.sendMessage("stream-error", session=self.session.session_id)
def check_tls(self, data): def check_tls(self, data):
for i in self.session.settings["other_buffers"]["timelines"]: for i in self.session.settings["other_buffers"]["timelines"]:
if data["user"]["id_str"] == i: if data["user"]["id_str"] == i:
if utils.find_item(data["id"], self.session.db["%s-timeline" % (i,)]) != None: if utils.find_item(data["id"], self.session.db["%s-timeline" % (i,)]) != None:
log.error("duplicated tweet. Ignoring it...") log.error("duplicated tweet. Ignoring it...")
return return
# try: # try:
data_ = self.session.check_quoted_status(data) data_ = self.session.check_quoted_status(data)
data_ = self.session.check_long_tweet(data_) data_ = self.session.check_long_tweet(data_)
data = data_ data = data_
# except ValueError: # except ValueError:
# pass # pass
if self.session.settings["general"]["reverse_timelines"] == False: self.session.db["%s-timeline" % (i,)].append(data) if self.session.settings["general"]["reverse_timelines"] == False: self.session.db["%s-timeline" % (i,)].append(data)
else: self.session.db["%s-timeline" % (i,)].insert(0, data) else: self.session.db["%s-timeline" % (i,)].insert(0, data)
pub.sendMessage("item-in-timeline", data= data, user= self.session.db["user_name"], who= i) pub.sendMessage("item-in-timeline", data= data, user= self.session.db["user_name"], who= i)
return return
for i in self.session.lists: for i in self.session.lists:
try: try:
i.users.index(data["user"]["id"]) i.users.index(data["user"]["id"])
usr = data["in_reply_to_user_id"] usr = data["in_reply_to_user_id"]
if (usr != None and usr in self.friends) or data.has_key("retweeted_status"): if (usr != None and usr in self.friends) or "retweeted_status" in data:
data = self.session.check_quoted_status(data) data = self.session.check_quoted_status(data)
data = self.session.check_long_tweet(data) data = self.session.check_long_tweet(data)
if self.session.settings["general"]["reverse_timelines"] == False: self.session.db["%s" % (i.name,)].append(data) if self.session.settings["general"]["reverse_timelines"] == False: self.session.db["%s" % (i.name,)].append(data)
else: self.session.db["%s" % (i.name,)].insert(0, data) else: self.session.db["%s" % (i.name,)].insert(0, data)
pub.sendMessage("item-in-list", data=data, user=self.session.db["user_name"], where=i.name) pub.sendMessage("item-in-list", data=data, user=self.session.db["user_name"], where=i.name)
elif usr == None: elif usr == None:
data = self.session.check_quoted_status(data) data = self.session.check_quoted_status(data)
data = self.session.check_long_tweet(data) data = self.session.check_long_tweet(data)
if self.session.settings["general"]["reverse_timelines"] == False: self.session.db["%s" % (i.name,)].append(data) if self.session.settings["general"]["reverse_timelines"] == False: self.session.db["%s" % (i.name,)].append(data)
else: self.session.db["%s" % (i.name,)].insert(0, data) else: self.session.db["%s" % (i.name,)].insert(0, data)
pub.sendMessage("item-in-list", data=data, user=self.session.db["user_name"], where=i.name) pub.sendMessage("item-in-list", data=data, user=self.session.db["user_name"], where=i.name)
except ValueError: except ValueError:
pass pass
def set_friends(self, friends): def set_friends(self, friends):
self.friends = friends self.friends = friends
def on_success(self, data): def on_success(self, data):
# try: # try:
if "text" in data and utils.is_allowed(data, self.session.settings["twitter"]["ignored_clients"]) == True: if "text" in data and utils.is_allowed(data, self.session.settings["twitter"]["ignored_clients"]) == True:
if data.has_key("extended_tweet"): if "extended_tweet" in data:
data["full_text"] = data["extended_tweet"]["full_text"] data["full_text"] = data["extended_tweet"]["full_text"]
# data["entities"] = data["extended_tweet"]["entities"] # data["entities"] = data["extended_tweet"]["entities"]
# log.error(data["extended_entities"]) # log.error(data["extended_entities"])
self.check_tls(data) self.check_tls(data)
# except: # except:
# pass # pass

View File

@ -1,182 +1,182 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import config import config
from requests.auth import HTTPProxyAuth from requests.auth import HTTPProxyAuth
from twitter import utils from twitter import utils
from twython import TwythonStreamer from twython import TwythonStreamer
from pubsub import pub from pubsub import pub
import logging as original_logger import logging as original_logger
log = original_logger.getLogger("MainStream") log = original_logger.getLogger("MainStream")
class streamer(TwythonStreamer): class streamer(TwythonStreamer):
def __init__(self, app_key, app_secret, oauth_token, oauth_token_secret, sessionObject, *a, **kw): def __init__(self, app_key, app_secret, oauth_token, oauth_token_secret, sessionObject, *a, **kw):
super(streamer, self).__init__(app_key, app_secret, oauth_token, oauth_token_secret, *a, **kw) super(streamer, self).__init__(app_key, app_secret, oauth_token, oauth_token_secret, *a, **kw)
self.session = sessionObject self.session = sessionObject
self.muted_users = self.session.db["muted_users"] self.muted_users = self.session.db["muted_users"]
# self.blocked_users = [] # self.blocked_users = []
def on_timeout(self, *args, **kwargs): def on_timeout(self, *args, **kwargs):
log.error("Twitter timeout Error") log.error("Twitter timeout Error")
# pub.sendMessage("stream-error", session=self.session.session_id) # pub.sendMessage("stream-error", session=self.session.session_id)
def on_error(self, status_code, data): def on_error(self, status_code, data):
log.error("Error %s: %s" % (status_code, data)) log.error("Error %s: %s" % (status_code, data))
# pub.sendMessage("stream-error", session=self.session.session_id) # pub.sendMessage("stream-error", session=self.session.session_id)
def get_user(self): def get_user(self):
return self.session.db["user_name"] return self.session.db["user_name"]
def put_data(self, place, data): def put_data(self, place, data):
if self.session.db.has_key(place): if place in self.session.db:
if utils.find_item(data["id"], self.session.db[place]) != None: if utils.find_item(data["id"], self.session.db[place]) != None:
log.error("duplicated tweet. Ignoring it...") log.error("duplicated tweet. Ignoring it...")
return False return False
# try: # try:
data_ = self.session.check_quoted_status(data) data_ = self.session.check_quoted_status(data)
data_ = self.session.check_long_tweet(data_) data_ = self.session.check_long_tweet(data_)
data = data_ data = data_
# except: # except:
# pass # pass
if self.session.settings["general"]["reverse_timelines"] == False: if self.session.settings["general"]["reverse_timelines"] == False:
self.session.db[place].append(data) self.session.db[place].append(data)
else: else:
self.session.db[place].insert(0, data) self.session.db[place].insert(0, data)
utils.is_audio(data) utils.is_audio(data)
return True return True
def block_user(self, data): def block_user(self, data):
id = data["target"]["id"] id = data["target"]["id"]
if id in self.friends: if id in self.friends:
self.friends.remove(id) self.friends.remove(id)
if "blocks" in self.session.settings["general"]["buffer_order"]: if "blocks" in self.session.settings["general"]["buffer_order"]:
self.session.db["blocked"]["items"].append(data["target"]) self.session.db["blocked"]["items"].append(data["target"])
pub.sendMessage("blocked-user", data=data["target"], user=self.get_user()) pub.sendMessage("blocked-user", data=data["target"], user=self.get_user())
def unblock(self, data): def unblock(self, data):
if "blocks" in self.session.settings["general"]["buffer_order"] == True: if "blocks" in self.session.settings["general"]["buffer_order"] == True:
item = utils.find_item(data["target"]["id"], self.session.db["blocked"]["items"]) item = utils.find_item(data["target"]["id"], self.session.db["blocked"]["items"])
self.session.db["blocked"]["items"].pop(item) self.session.db["blocked"]["items"].pop(item)
pub.sendMessage("unblocked-user", item=item, user=self.get_user()) pub.sendMessage("unblocked-user", item=item, user=self.get_user())
def check_send(self, data): def check_send(self, data):
if self.session.db["user_name"] == data["user"]["screen_name"]: if self.session.db["user_name"] == data["user"]["screen_name"]:
d = self.put_data("sent_tweets", data) d = self.put_data("sent_tweets", data)
if d != False: if d != False:
pub.sendMessage("sent-tweet", data=data, user=self.get_user()) pub.sendMessage("sent-tweet", data=data, user=self.get_user())
def check_favs(self, data): def check_favs(self, data):
if data["source"]["screen_name"] == self.session.db["user_name"]: if data["source"]["screen_name"] == self.session.db["user_name"]:
d = self.put_data("favourites", data["target_object"]) d = self.put_data("favourites", data["target_object"])
if d != False: if d != False:
pub.sendMessage("favourite", data=data["target_object"], user=self.get_user()) pub.sendMessage("favourite", data=data["target_object"], user=self.get_user())
def check_mentions(self, data): def check_mentions(self, data):
if "@%s" % (self.session.db["user_name"]) in data["text"]: if "@%s" % (self.session.db["user_name"]) in data["text"]:
d = self.put_data("mentions", data) d = self.put_data("mentions", data)
if d != False: if d != False:
pub.sendMessage("mention", data=data, user=self.get_user()) pub.sendMessage("mention", data=data, user=self.get_user())
def set_quoted_tweet(self, data): def set_quoted_tweet(self, data):
if data["source"]["screen_name"] != self.session.db["user_name"]: if data["source"]["screen_name"] != self.session.db["user_name"]:
d = self.put_data("mentions", data["target_object"]) d = self.put_data("mentions", data["target_object"])
if d != False: if d != False:
pub.sendMessage("mention", data=data["target_object"], user=self.get_user()) pub.sendMessage("mention", data=data["target_object"], user=self.get_user())
def process_dm(self, data): def process_dm(self, data):
if self.session.db["user_name"] != data["direct_message"]["sender"]["screen_name"]: if self.session.db["user_name"] != data["direct_message"]["sender"]["screen_name"]:
# d = self.put_data("sent_direct_messages", data["direct_message"]) # d = self.put_data("sent_direct_messages", data["direct_message"])
# if d != False: # if d != False:
# pub.sendMessage("sent-dm", data=data["direct_message"], user=self.get_user()) # pub.sendMessage("sent-dm", data=data["direct_message"], user=self.get_user())
# else: # else:
d = self.put_data("direct_messages", data["direct_message"]) d = self.put_data("direct_messages", data["direct_message"])
if d != False: if d != False:
pub.sendMessage("direct-message", data=data["direct_message"], user=self.get_user()) pub.sendMessage("direct-message", data=data["direct_message"], user=self.get_user())
def check_follower(self, data): def check_follower(self, data):
if data["target"]["screen_name"] == self.session.db["user_name"]: if data["target"]["screen_name"] == self.session.db["user_name"]:
if self.session.settings["general"]["reverse_timelines"] == False: if self.session.settings["general"]["reverse_timelines"] == False:
self.session.db["followers"]["items"].append(data["source"]) self.session.db["followers"]["items"].append(data["source"])
else: else:
self.session.db["followers"]["items"].insert(0, data["source"]) self.session.db["followers"]["items"].insert(0, data["source"])
pub.sendMessage("follower", data=data["source"], user = self.get_user()) pub.sendMessage("follower", data=data["source"], user = self.get_user())
else: else:
if self.session.settings["general"]["reverse_timelines"] == False: if self.session.settings["general"]["reverse_timelines"] == False:
self.session.db["friends"]["items"].append(data["target"]) self.session.db["friends"]["items"].append(data["target"])
else: else:
self.session.db["friends"]["items"].insert(0, data["target"]) self.session.db["friends"]["items"].insert(0, data["target"])
pub.sendMessage("friend", data=data["target"], user=self.get_user()) pub.sendMessage("friend", data=data["target"], user=self.get_user())
### ###
def remove_fav(self, data): def remove_fav(self, data):
if self.session.db["user_name"] == data["source"]["screen_name"]: if self.session.db["user_name"] == data["source"]["screen_name"]:
item = utils.find_item(data["target_object"]["id"], self.session.db["favourites"]) item = utils.find_item(data["target_object"]["id"], self.session.db["favourites"])
self.session.db["favourites"].pop(item) self.session.db["favourites"].pop(item)
pub.sendMessage("unfavourite", item=item, user=self.get_user()) pub.sendMessage("unfavourite", item=item, user=self.get_user())
def remove_friend(self, data): def remove_friend(self, data):
if "friends" in self.session.settings["general"]["buffer_order"]: if "friends" in self.session.settings["general"]["buffer_order"]:
item = utils.find_item(data["target"]["id"], self.session.db["friends"]["items"]) item = utils.find_item(data["target"]["id"], self.session.db["friends"]["items"])
if item > 0: if item > 0:
self.friends.pop(item) self.friends.pop(item)
pub.sendMessage("unfollowing", item=item, user=self.get_user()) pub.sendMessage("unfollowing", item=item, user=self.get_user())
def on_success(self, data): def on_success(self, data):
try: try:
# if "delete" in data: # if "delete" in data:
# pub.sendMessage("tweet-deleted", data=data) # pub.sendMessage("tweet-deleted", data=data)
if "direct_message" in data: if "direct_message" in data:
self.process_dm(data) self.process_dm(data)
elif "friends" in data: elif "friends" in data:
self.friends = data["friends"] self.friends = data["friends"]
pub.sendMessage("friends-receibed") pub.sendMessage("friends-receibed")
elif "text" in data and utils.is_allowed(data, self.session.settings["twitter"]["ignored_clients"]) == True: elif "text" in data and utils.is_allowed(data, self.session.settings["twitter"]["ignored_clients"]) == True:
if data.has_key("extended_tweet"): if "extended_tweet" in data:
data["full_text"] = data["extended_tweet"]["full_text"] data["full_text"] = data["extended_tweet"]["full_text"]
data["entities"] = data["extended_tweet"]["entities"] data["entities"] = data["extended_tweet"]["entities"]
# log.error(data["extended_tweet"]) # log.error(data["extended_tweet"])
# log.error("Extended tweet") # log.error("Extended tweet")
if data["user"]["id"] in self.muted_users: return if data["user"]["id"] in self.muted_users: return
self.check_mentions(data) self.check_mentions(data)
self.check_send(data) self.check_send(data)
if data["user"]["id"] in self.friends or data["user"]["screen_name"] == self.session.db["user_name"]: if data["user"]["id"] in self.friends or data["user"]["screen_name"] == self.session.db["user_name"]:
d = self.put_data("home_timeline", data) d = self.put_data("home_timeline", data)
if d != False: if d != False:
pub.sendMessage("item-in-home", data=data, user=self.get_user()) pub.sendMessage("item-in-home", data=data, user=self.get_user())
elif data.has_key("event"): elif "event" in data:
if "favorite" == data["event"] and "favorites" in self.session.settings["general"]["buffer_order"]: if "favorite" == data["event"] and "favorites" in self.session.settings["general"]["buffer_order"]:
self.check_favs(data) self.check_favs(data)
elif "unfavorite" == data["event"] and "favorites" in self.session.settings["general"]["buffer_order"]: elif "unfavorite" == data["event"] and "favorites" in self.session.settings["general"]["buffer_order"]:
self.remove_fav(data) self.remove_fav(data)
elif "follow" == data["event"] and "followers" in self.session.settings["general"]["buffer_order"]: elif "follow" == data["event"] and "followers" in self.session.settings["general"]["buffer_order"]:
self.check_follower(data) self.check_follower(data)
elif "unfollow" == data["event"] and "friends" in self.session.settings["general"]["buffer_order"]: elif "unfollow" == data["event"] and "friends" in self.session.settings["general"]["buffer_order"]:
self.remove_friend(data) self.remove_friend(data)
elif "block" == data["event"]: elif "block" == data["event"]:
self.block_user(data) self.block_user(data)
elif "unblock" == data["event"]: elif "unblock" == data["event"]:
self.unblock(data) self.unblock(data)
elif "list_created" == data["event"]: elif "list_created" == data["event"]:
item = utils.find_item(data["target_object"]["id"], self.session.db["lists"]) item = utils.find_item(data["target_object"]["id"], self.session.db["lists"])
if item != None: self.session.db["lists"].append(data["target_object"]) if item != None: self.session.db["lists"].append(data["target_object"])
elif "list_destroyed" == data["event"]: elif "list_destroyed" == data["event"]:
item = utils.find_item(data["target_object"]["id"], self.session.db["lists"]) item = utils.find_item(data["target_object"]["id"], self.session.db["lists"])
if item != None: self.session.db["lists"].pop(item) if item != None: self.session.db["lists"].pop(item)
self.parent.remove_list(data["target_object"]["id"]) self.parent.remove_list(data["target_object"]["id"])
elif "list_member_added" == data["event"] and data["source"]["screen_name"] == self.get_user(): elif "list_member_added" == data["event"] and data["source"]["screen_name"] == self.get_user():
pub.sendMessage("new-list-member-added", **{"id":str(data["target"]["id"]), "list":data["target_object"], "user":self.get_user()}) pub.sendMessage("new-list-member-added", **{"id":str(data["target"]["id"]), "list":data["target_object"], "user":self.get_user()})
elif "list_member_added" == data["event"] and data["target"]["screen_name"] == self.get_user(): elif "list_member_added" == data["event"] and data["target"]["screen_name"] == self.get_user():
self.session.db["lists"].append(data["target_object"]) self.session.db["lists"].append(data["target_object"])
elif "list_member_removed" == data["event"] and data["source"]["screen_name"] == self.get_user(): elif "list_member_removed" == data["event"] and data["source"]["screen_name"] == self.get_user():
pub.sendMessage("list-member-deleted", **{"id":str(data["target"]["id"]), "list":data["target_object"], "user":self.get_user()}) pub.sendMessage("list-member-deleted", **{"id":str(data["target"]["id"]), "list":data["target_object"], "user":self.get_user()})
elif "list_member_removed" == data["event"] and data["target"] == self.get_user(): elif "list_member_removed" == data["event"] and data["target"] == self.get_user():
id = data["target_object"]["id"] id = data["target_object"]["id"]
list = utils.find_item(id, self.session.db["lists"]) list = utils.find_item(id, self.session.db["lists"])
if list != None: self.session.db["lists"].pop(list) if list != None: self.session.db["lists"].pop(list)
pub.sendMessage("list-deleted", **{"item":list, "user":self.get_user()}) pub.sendMessage("list-deleted", **{"item":list, "user":self.get_user()})
elif "quoted_tweet" == data["event"]: elif "quoted_tweet" == data["event"]:
self.set_quoted_tweet(data) self.set_quoted_tweet(data)
if "events" in self.session.settings["general"]["buffer_order"]: if "events" in self.session.settings["general"]["buffer_order"]:
pub.sendMessage("event", data= data, user= self.get_user()) pub.sendMessage("event", data= data, user= self.get_user())
# self.sound.play("new_event.ogg") # self.sound.play("new_event.ogg")
except KeyboardInterrupt: except KeyboardInterrupt:
pass pass

View File

@ -1,209 +1,210 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import platform from __future__ import absolute_import
system = platform.system() import platform
import utils system = platform.system()
import re from . import utils
import htmlentitydefs import re
import time import htmlentitydefs
import output import time
import languageHandler import output
import arrow import languageHandler
import logging import arrow
import config import logging
from long_tweets import twishort, tweets import config
log = logging.getLogger("compose") from long_tweets import twishort, tweets
log = logging.getLogger("compose")
def StripChars(s):
"""Converts any html entities in s to their unicode-decoded equivalents and returns a string.""" def StripChars(s):
entity_re = re.compile(r"&(#\d+|\w+);") """Converts any html entities in s to their unicode-decoded equivalents and returns a string."""
def matchFunc(match): entity_re = re.compile(r"&(#\d+|\w+);")
"""Nested function to handle a match object. def matchFunc(match):
If we match &blah; and it's not found, &blah; will be returned. """Nested function to handle a match object.
if we match #\d+, unichr(digits) will be returned. If we match &blah; and it's not found, &blah; will be returned.
Else, a unicode string will be returned.""" if we match #\d+, unichr(digits) will be returned.
if match.group(1).startswith('#'): return unichr(int(match.group(1)[1:])) Else, a unicode string will be returned."""
replacement = htmlentitydefs.entitydefs.get(match.group(1), "&%s;" % match.group(1)) if match.group(1).startswith('#'): return unichr(int(match.group(1)[1:]))
return replacement.decode('iso-8859-1') replacement = htmlentitydefs.entitydefs.get(match.group(1), "&%s;" % match.group(1))
return unicode(entity_re.sub(matchFunc, s)) return replacement.decode('iso-8859-1')
return unicode(entity_re.sub(matchFunc, s))
chars = "abcdefghijklmnopqrstuvwxyz"
chars = "abcdefghijklmnopqrstuvwxyz"
def compose_tweet(tweet, db, relative_times, show_screen_names=False):
""" It receives a tweet and returns a list with the user, text for the tweet or message, date and the client where user is.""" def compose_tweet(tweet, db, relative_times, show_screen_names=False):
if system == "Windows": """ It receives a tweet and returns a list with the user, text for the tweet or message, date and the client where user is."""
original_date = arrow.get(tweet["created_at"], "ddd MMM DD H:m:s Z YYYY", locale="en") if system == "Windows":
if relative_times == True: original_date = arrow.get(tweet["created_at"], "ddd MMM DD H:m:s Z YYYY", locale="en")
ts = original_date.humanize(locale=languageHandler.getLanguage()) if relative_times == True:
else: ts = original_date.humanize(locale=languageHandler.getLanguage())
ts = original_date.replace(seconds=db["utc_offset"]).format(_(u"dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.getLanguage()) else:
else: ts = original_date.replace(seconds=db["utc_offset"]).format(_(u"dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.getLanguage())
ts = tweet["created_at"] else:
if tweet.has_key("message"): ts = tweet["created_at"]
value = "message" if "message" in tweet:
elif tweet.has_key("full_text"): value = "message"
value = "full_text" elif "full_text" in tweet:
else: value = "full_text"
value = "text" else:
# log.exception(tweet.keys()) value = "text"
text = StripChars(tweet[value]) # log.exception(tweet.keys())
if show_screen_names: text = StripChars(tweet[value])
user = tweet["user"]["screen_name"] if show_screen_names:
else: user = tweet["user"]["screen_name"]
user = tweet["user"]["name"] else:
source = re.sub(r"(?s)<.*?>", "", tweet["source"]) user = tweet["user"]["name"]
if tweet.has_key("retweeted_status"): source = re.sub(r"(?s)<.*?>", "", tweet["source"])
if tweet.has_key("message") == False and tweet["retweeted_status"]["is_quote_status"] == False: if "retweeted_status" in tweet:
text = "RT @%s: %s" % (tweet["retweeted_status"]["user"]["screen_name"], StripChars(tweet["retweeted_status"][value])) if ("message" in tweet) == False and tweet["retweeted_status"]["is_quote_status"] == False:
elif tweet["retweeted_status"]["is_quote_status"]: text = "RT @%s: %s" % (tweet["retweeted_status"]["user"]["screen_name"], StripChars(tweet["retweeted_status"][value]))
text = "%s" % (StripChars(tweet[value])) elif tweet["retweeted_status"]["is_quote_status"]:
else: text = "%s" % (StripChars(tweet[value]))
text = "RT @%s: %s" % (tweet["retweeted_status"]["user"]["screen_name"], StripChars(tweet[value])) else:
# if text[-1] in chars: text=text+"." text = "RT @%s: %s" % (tweet["retweeted_status"]["user"]["screen_name"], StripChars(tweet[value]))
if tweet.has_key("message") == False: # if text[-1] in chars: text=text+"."
urls = utils.find_urls_in_text(text) if ("message" in tweet) == False:
for url in range(0, len(urls)): urls = utils.find_urls_in_text(text)
try: for url in range(0, len(urls)):
text = text.replace(urls[url], tweet["entities"]["urls"][url]["expanded_url"]) try:
except: pass text = text.replace(urls[url], tweet["entities"]["urls"][url]["expanded_url"])
if config.app['app-settings']['handle_longtweets']: pass except: pass
# return [user+", ", text, ts+", ", source] if config.app['app-settings']['handle_longtweets']: pass
return [user+", ", text, ts+", ", source] # return [user+", ", text, ts+", ", source]
return [user+", ", text, ts+", ", source]
def compose_dm(tweet, db, relative_times, show_screen_names=False):
""" It receives a tweet and returns a list with the user, text for the tweet or message, date and the client where user is.""" def compose_dm(tweet, db, relative_times, show_screen_names=False):
if system == "Windows": """ It receives a tweet and returns a list with the user, text for the tweet or message, date and the client where user is."""
original_date = arrow.get(tweet["created_at"], "ddd MMM DD H:m:s Z YYYY", locale="en") if system == "Windows":
if relative_times == True: original_date = arrow.get(tweet["created_at"], "ddd MMM DD H:m:s Z YYYY", locale="en")
ts = original_date.humanize(locale=languageHandler.getLanguage()) if relative_times == True:
else: ts = original_date.humanize(locale=languageHandler.getLanguage())
ts = original_date.replace(seconds=db["utc_offset"]).format(_(u"dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.getLanguage()) else:
else: ts = original_date.replace(seconds=db["utc_offset"]).format(_(u"dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.getLanguage())
ts = tweet["created_at"] else:
text = StripChars(tweet["text"]) ts = tweet["created_at"]
source = "DM" text = StripChars(tweet["text"])
if db["user_name"] == tweet["sender"]["screen_name"]: source = "DM"
if show_screen_names: if db["user_name"] == tweet["sender"]["screen_name"]:
user = _(u"Dm to %s ") % (tweet["recipient"]["screen_name"],) if show_screen_names:
else: user = _(u"Dm to %s ") % (tweet["recipient"]["screen_name"],)
user = _(u"Dm to %s ") % (tweet["recipient"]["name"],) else:
else: user = _(u"Dm to %s ") % (tweet["recipient"]["name"],)
if show_screen_names: else:
user = tweet["sender"]["screen_name"] if show_screen_names:
else: user = tweet["sender"]["screen_name"]
user = tweet["sender"]["name"] else:
if text[-1] in chars: text=text+"." user = tweet["sender"]["name"]
urls = utils.find_urls_in_text(text) if text[-1] in chars: text=text+"."
for url in range(0, len(urls)): urls = utils.find_urls_in_text(text)
try: text = text.replace(urls[url], tweet["entities"]["urls"][url]["expanded_url"]) for url in range(0, len(urls)):
except IndexError: pass try: text = text.replace(urls[url], tweet["entities"]["urls"][url]["expanded_url"])
return [user+", ", text, ts+", ", source] except IndexError: pass
return [user+", ", text, ts+", ", source]
def compose_quoted_tweet(quoted_tweet, original_tweet, show_screen_names=False):
""" It receives a tweet and returns a list with the user, text for the tweet or message, date and the client where user is.""" def compose_quoted_tweet(quoted_tweet, original_tweet, show_screen_names=False):
if quoted_tweet.has_key("full_text"): """ It receives a tweet and returns a list with the user, text for the tweet or message, date and the client where user is."""
value = "full_text" if "full_text" in quoted_tweet:
else: value = "full_text"
value = "text" else:
text = StripChars(quoted_tweet[value]) value = "text"
if show_screen_names: text = StripChars(quoted_tweet[value])
quoting_user = quoted_tweet["user"]["screen_name"] if show_screen_names:
else: quoting_user = quoted_tweet["user"]["screen_name"]
quoting_user = quoted_tweet["user"]["name"] else:
source = re.sub(r"(?s)<.*?>", "", quoted_tweet["source"]) quoting_user = quoted_tweet["user"]["name"]
try: text = "rt @%s: %s" % (quoted_tweet["retweeted_status"]["user"]["screen_name"], StripChars(quoted_tweet["retweeted_status"][value])) source = re.sub(r"(?s)<.*?>", "", quoted_tweet["source"])
except KeyError: text = "%s" % (StripChars(quoted_tweet[value])) try: text = "rt @%s: %s" % (quoted_tweet["retweeted_status"]["user"]["screen_name"], StripChars(quoted_tweet["retweeted_status"][value]))
if text[-1] in chars: text=text+"." except KeyError: text = "%s" % (StripChars(quoted_tweet[value]))
original_user = original_tweet["user"]["screen_name"] if text[-1] in chars: text=text+"."
if original_tweet.has_key("message"): original_user = original_tweet["user"]["screen_name"]
original_text = StripChars(original_tweet["message"]) if "message" in original_tweet:
elif original_tweet.has_key("full_text"): original_text = StripChars(original_tweet["message"])
original_text = StripChars(original_tweet["full_text"]) elif "full_text" in original_tweet:
else: original_text = StripChars(original_tweet["full_text"])
original_text = StripChars(original_tweet["text"]) else:
quoted_tweet["message"] = _(u"{0}. Quoted tweet from @{1}: {2}").format( quoted_tweet[value], original_user, original_text) original_text = StripChars(original_tweet["text"])
quoted_tweet = tweets.clear_url(quoted_tweet) quoted_tweet["message"] = _(u"{0}. Quoted tweet from @{1}: {2}").format( quoted_tweet[value], original_user, original_text)
return quoted_tweet quoted_tweet = tweets.clear_url(quoted_tweet)
return quoted_tweet
def compose_followers_list(tweet, db, relative_times=True, show_screen_names=False):
if system == "Windows": def compose_followers_list(tweet, db, relative_times=True, show_screen_names=False):
original_date = arrow.get(tweet["created_at"], "ddd MMM D H:m:s Z YYYY", locale="en") if system == "Windows":
if relative_times == True: original_date = arrow.get(tweet["created_at"], "ddd MMM D H:m:s Z YYYY", locale="en")
ts = original_date.humanize(locale=languageHandler.getLanguage()) if relative_times == True:
else: ts = original_date.humanize(locale=languageHandler.getLanguage())
ts = original_date.replace(seconds=db["utc_offset"]).format(_(u"dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.getLanguage()) else:
else: ts = original_date.replace(seconds=db["utc_offset"]).format(_(u"dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.getLanguage())
ts = tweet["created_at"] else:
if tweet.has_key("status"): ts = tweet["created_at"]
if len(tweet["status"]) > 4 and system == "Windows": if "status" in tweet:
original_date2 = arrow.get(tweet["status"]["created_at"], "ddd MMM D H:m:s Z YYYY", locale="en") if len(tweet["status"]) > 4 and system == "Windows":
if relative_times: original_date2 = arrow.get(tweet["status"]["created_at"], "ddd MMM D H:m:s Z YYYY", locale="en")
ts2 = original_date2.humanize(locale=languageHandler.getLanguage()) if relative_times:
else: ts2 = original_date2.humanize(locale=languageHandler.getLanguage())
ts2 = original_date2.replace(seconds=db["utc_offset"]).format(_(u"dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.getLanguage()) else:
else: ts2 = original_date2.replace(seconds=db["utc_offset"]).format(_(u"dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.getLanguage())
ts2 = _("Unavailable") else:
else: ts2 = _("Unavailable")
ts2 = _("Unavailable") else:
return [_(u"%s (@%s). %s followers, %s friends, %s tweets. Last tweeted %s. Joined Twitter %s") % (tweet["name"], tweet["screen_name"], tweet["followers_count"], tweet["friends_count"], tweet["statuses_count"], ts2, ts)] ts2 = _("Unavailable")
return [_(u"%s (@%s). %s followers, %s friends, %s tweets. Last tweeted %s. Joined Twitter %s") % (tweet["name"], tweet["screen_name"], tweet["followers_count"], tweet["friends_count"], tweet["statuses_count"], ts2, ts)]
def compose_event(data, username, show_screen_names=False):
if show_screen_names: def compose_event(data, username, show_screen_names=False):
value = "screen_name" if show_screen_names:
else: value = "screen_name"
value = "name" else:
if data["event"] == "block": value = "name"
event = _("You've blocked %s") % (data["target"][value]) if data["event"] == "block":
elif data["event"] == "unblock": event = _("You've blocked %s") % (data["target"][value])
event = _(u"You've unblocked %s") % (data["target"][value]) elif data["event"] == "unblock":
elif data["event"] == "follow": event = _(u"You've unblocked %s") % (data["target"][value])
if data["target"]["screen_name"] == username: elif data["event"] == "follow":
event = _(u"%s(@%s) has followed you") % (data["source"]["name"], data["source"]["screen_name"]) if data["target"]["screen_name"] == username:
elif data["source"]["screen_name"] == username: event = _(u"%s(@%s) has followed you") % (data["source"]["name"], data["source"]["screen_name"])
event = _(u"You've followed %s(@%s)") % (data["target"]["name"], data["target"]["screen_name"]) elif data["source"]["screen_name"] == username:
elif data["event"] == "unfollow": event = _(u"You've followed %s(@%s)") % (data["target"]["name"], data["target"]["screen_name"])
event = _(u"You've unfollowed %s (@%s)") % (data["target"]["name"], data["target"]["screen_name"]) elif data["event"] == "unfollow":
elif data["event"] == "favorite": event = _(u"You've unfollowed %s (@%s)") % (data["target"]["name"], data["target"]["screen_name"])
if data["source"]["screen_name"] == username: elif data["event"] == "favorite":
event = _(u"You've liked: %s, %s") % (data["target"][value], data["target_object"]["text"]) if data["source"]["screen_name"] == username:
else: event = _(u"You've liked: %s, %s") % (data["target"][value], data["target_object"]["text"])
event = _(u"%s(@%s) has liked: %s") % (data["source"]["name"], data["source"]["screen_name"], data["target_object"]["text"]) else:
elif data["event"] == "unfavorite": event = _(u"%s(@%s) has liked: %s") % (data["source"]["name"], data["source"]["screen_name"], data["target_object"]["text"])
if data["source"]["screen_name"] == username: event = _(u"You've unliked: %s, %s") % (data["target"][value], data["target_object"]["text"]) elif data["event"] == "unfavorite":
else: event = _(u"%s(@%s) has unliked: %s") % (data["source"]["name"], data["source"]["screen_name"], data["target_object"]["text"]) if data["source"]["screen_name"] == username: event = _(u"You've unliked: %s, %s") % (data["target"][value], data["target_object"]["text"])
elif data["event"] == "list_created": else: event = _(u"%s(@%s) has unliked: %s") % (data["source"]["name"], data["source"]["screen_name"], data["target_object"]["text"])
event = _(u"You've created the list %s") % (data["target_object"]["name"]) elif data["event"] == "list_created":
elif data["event"] == "list_destroyed": event = _(u"You've created the list %s") % (data["target_object"]["name"])
event = _("You've deleted the list %s") % (data["target_object"]["name"]) elif data["event"] == "list_destroyed":
elif data["event"] == "list_updated": event = _("You've deleted the list %s") % (data["target_object"]["name"])
event = _("You've updated the list %s") % (data["target_object"]["name"]) elif data["event"] == "list_updated":
elif data["event"] == "list_member_added": event = _("You've updated the list %s") % (data["target_object"]["name"])
if data["source"]["screen_name"] == username: event = _(u"You've added %s(@%s) to the list %s") % (data["target"]["name"], data["target"]["screen_name"], data["target_object"]["name"]) elif data["event"] == "list_member_added":
else: event = _(u"%s(@%s) has added you to the list %s") % (data["source"]["name"], data["source"]["screen_name"], data["target_object"]["name"]) if data["source"]["screen_name"] == username: event = _(u"You've added %s(@%s) to the list %s") % (data["target"]["name"], data["target"]["screen_name"], data["target_object"]["name"])
elif data["event"] == "list_member_removed": else: event = _(u"%s(@%s) has added you to the list %s") % (data["source"]["name"], data["source"]["screen_name"], data["target_object"]["name"])
if data["source"]["screen_name"] == username: event = _(u"You'be removed %s(@%s) from the list %s") % (data["target"]["name"], data["target"]["screen_name"], data["target_object"]["name"]) elif data["event"] == "list_member_removed":
else: event = _(u"%s(@%s) has removed you from the list %s") % (data["source"]["name"], data["source"]["screen_name"], data["target_object"]["name"]) if data["source"]["screen_name"] == username: event = _(u"You'be removed %s(@%s) from the list %s") % (data["target"]["name"], data["target"]["screen_name"], data["target_object"]["name"])
elif data["event"] == "list_user_subscribed": else: event = _(u"%s(@%s) has removed you from the list %s") % (data["source"]["name"], data["source"]["screen_name"], data["target_object"]["name"])
if data["source"]["screen_name"] == username: event = _(u"You've subscribed to the list %s, which is owned by %s(@%s)") % (data["target_object"]["name"], data["target"]["name"], data["target"]["screen_name"]) elif data["event"] == "list_user_subscribed":
else: event = _(u"%s(@%s) has suscribed you to the list %s") % (data["source"]["name"], data["source"]["screen_name"], data["target_object"]["name"]) if data["source"]["screen_name"] == username: event = _(u"You've subscribed to the list %s, which is owned by %s(@%s)") % (data["target_object"]["name"], data["target"]["name"], data["target"]["screen_name"])
elif data["event"] == "list_user_unsubscribed": else: event = _(u"%s(@%s) has suscribed you to the list %s") % (data["source"]["name"], data["source"]["screen_name"], data["target_object"]["name"])
if data["source"]["screen_name"] == username: event = _(u"You've unsubscribed from the list %s, which is owned by %s(@%s)") % (data["target_object"]["name"], data["target"]["name"], data["target"]["screen_name"]) elif data["event"] == "list_user_unsubscribed":
else: event = _("You've been unsubscribed from the list %s, which is owned by %s(@%s)") % (data["target_object"]["name"], data["source"]["name"], data["source"]["screen_name"]) if data["source"]["screen_name"] == username: event = _(u"You've unsubscribed from the list %s, which is owned by %s(@%s)") % (data["target_object"]["name"], data["target"]["name"], data["target"]["screen_name"])
elif data["event"] == "retweeted_retweet": else: event = _("You've been unsubscribed from the list %s, which is owned by %s(@%s)") % (data["target_object"]["name"], data["source"]["name"], data["source"]["screen_name"])
if data["source"]["screen_name"] == username: event = _(u"You have retweeted a retweet from %s(@%s): %s") % (data["target"]["name"], data["target"]["screen_name"], data["target_object"]["retweeted_status"]["text"]) elif data["event"] == "retweeted_retweet":
else: event = _(u"%s(@%s) has retweeted your retweet: %s") % (data["source"]["name"], data["source"]["screen_name"], data["target_object"]["retweeted_status"]["text"]) if data["source"]["screen_name"] == username: event = _(u"You have retweeted a retweet from %s(@%s): %s") % (data["target"]["name"], data["target"]["screen_name"], data["target_object"]["retweeted_status"]["text"])
elif data["event"] == "quoted_tweet": else: event = _(u"%s(@%s) has retweeted your retweet: %s") % (data["source"]["name"], data["source"]["screen_name"], data["target_object"]["retweeted_status"]["text"])
event = _(u"@{0} quoted your tweet: {1}").format(data["source"]["screen_name"], data["target_object"]["text"]) elif data["event"] == "quoted_tweet":
else: event = _(u"@{0} quoted your tweet: {1}").format(data["source"]["screen_name"], data["target_object"]["text"])
event = _("Unknown") else:
log.error("event: %s\n target: %s\n source: %s\n target_object: %s" % (data["event"], data["target"], data["source"], data["target_object"])) event = _("Unknown")
return [time.strftime("%I:%M %p"), event] log.error("event: %s\n target: %s\n source: %s\n target_object: %s" % (data["event"], data["target"], data["source"], data["target_object"]))
return [time.strftime("%I:%M %p"), event]
def compose_list(list):
name = list["name"] def compose_list(list):
if list["description"] == None: description = _(u"No description available") name = list["name"]
else: description = list["description"] if list["description"] == None: description = _(u"No description available")
user = list["user"]["name"] else: description = list["description"]
members = str(list["member_count"]) user = list["user"]["name"]
if list["mode"] == "private": status = _(u"private") members = str(list["member_count"])
else: status = _(u"public") if list["mode"] == "private": status = _(u"private")
return [name, description, user, members, status] else: status = _(u"public")
return [name, description, user, members, status]

View File

@ -1,38 +1,39 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import config from __future__ import absolute_import
import random import config
import BaseHTTPServer import random
import webbrowser import BaseHTTPServer
from twython import Twython, TwythonError import webbrowser
from keys import keyring from twython import Twython, TwythonError
import authorisationHandler from keys import keyring
from requests import certs from . import authorisationHandler
import logging from requests import certs
log = logging.getLogger("sessionTwitter") import logging
log = logging.getLogger("sessionTwitter")
class twitter(object):
class twitter(object):
def login(self, user_key, user_secret, verify_credentials):
self.twitter = Twython(keyring.get("api_key"), keyring.get("api_secret"), user_key, user_secret) def login(self, user_key, user_secret, verify_credentials):
if verify_credentials == True: self.twitter = Twython(keyring.get("api_key"), keyring.get("api_secret"), user_key, user_secret)
self.credentials = self.twitter.verify_credentials() if verify_credentials == True:
self.credentials = self.twitter.verify_credentials()
def authorise(self, settings):
authorisationHandler.logged = False def authorise(self, settings):
port = random.randint(30000, 65535) authorisationHandler.logged = False
httpd = BaseHTTPServer.HTTPServer(('127.0.0.1', port), authorisationHandler.handler) port = random.randint(30000, 65535)
twitter = Twython(keyring.get("api_key"), keyring.get("api_secret"), auth_endpoint='authorize') httpd = BaseHTTPServer.HTTPServer(('127.0.0.1', port), authorisationHandler.handler)
auth = twitter.get_authentication_tokens("http://127.0.0.1:{0}".format(port,)) twitter = Twython(keyring.get("api_key"), keyring.get("api_secret"), auth_endpoint='authorize')
webbrowser.open_new_tab(auth['auth_url']) auth = twitter.get_authentication_tokens("http://127.0.0.1:{0}".format(port,))
while authorisationHandler.logged == False: webbrowser.open_new_tab(auth['auth_url'])
httpd.handle_request() while authorisationHandler.logged == False:
self.twitter = Twython(keyring.get("api_key"), keyring.get("api_secret"), auth['oauth_token'], auth['oauth_token_secret']) httpd.handle_request()
final = self.twitter.get_authorized_tokens(authorisationHandler.verifier) self.twitter = Twython(keyring.get("api_key"), keyring.get("api_secret"), auth['oauth_token'], auth['oauth_token_secret'])
self.save_configuration(settings, final["oauth_token"], final["oauth_token_secret"]) final = self.twitter.get_authorized_tokens(authorisationHandler.verifier)
httpd.server_close() self.save_configuration(settings, final["oauth_token"], final["oauth_token_secret"])
httpd.server_close()
def save_configuration(self, settings, user_key, user_secret):
settings["twitter"]["user_key"] = user_key def save_configuration(self, settings, user_key, user_secret):
settings["twitter"]["user_secret"] = user_secret settings["twitter"]["user_key"] = user_key
settings.write() settings["twitter"]["user_secret"] = user_secret
settings.write()

View File

@ -1,144 +1,145 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import url_shortener, re from __future__ import print_function
import output import url_shortener, re
from twython import TwythonError import output
import config from twython import TwythonError
import logging import config
import requests import logging
import time import requests
import sound import time
log = logging.getLogger("twitter.utils") import sound
""" Some utilities for the twitter interface.""" log = logging.getLogger("twitter.utils")
""" Some utilities for the twitter interface."""
__version__ = 0.1
__doc__ = "Find urls in tweets and #audio hashtag." __version__ = 0.1
__doc__ = "Find urls in tweets and #audio hashtag."
url_re = re.compile(r"(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'\".,<>?«»“”‘’]))")
url_re = re.compile(r"(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'\".,<>?«»“”‘’]))")
url_re2 = re.compile("(?:\w+://|www\.)[^ ,.?!#%=+][^ ]*")
bad_chars = '\'\\.,[](){}:;"' url_re2 = re.compile("(?:\w+://|www\.)[^ ,.?!#%=+][^ ]*")
bad_chars = '\'\\.,[](){}:;"'
def find_urls_in_text(text):
return [s.strip(bad_chars) for s in url_re2.findall(text)] def find_urls_in_text(text):
return [s.strip(bad_chars) for s in url_re2.findall(text)]
def find_urls (tweet):
urls = [] def find_urls (tweet):
if tweet.has_key("message"): urls = []
i = "message" if "message" in tweet:
elif tweet.has_key("full_text"): i = "message"
i = "full_text" elif "full_text" in tweet:
else: i = "full_text"
i = "text" else:
return [s[0] for s in url_re.findall(tweet[i])] i = "text"
return [s[0] for s in url_re.findall(tweet[i])]
def find_item(id, listItem):
for i in range(0, len(listItem)): def find_item(id, listItem):
if listItem[i]["id"] == id: return i for i in range(0, len(listItem)):
return None if listItem[i]["id"] == id: return i
return None
def find_list(name, lists):
for i in range(0, len(lists)): def find_list(name, lists):
if lists[i]["name"] == name: return lists[i]["id"] for i in range(0, len(lists)):
if lists[i]["name"] == name: return lists[i]["id"]
def find_previous_reply(id, listItem):
for i in range(0, len(listItem)): def find_previous_reply(id, listItem):
if listItem[i]["id_str"] == str(id): return i for i in range(0, len(listItem)):
return None if listItem[i]["id_str"] == str(id): return i
return None
def find_next_reply(id, listItem):
for i in range(0, len(listItem)): def find_next_reply(id, listItem):
if listItem[i]["in_reply_to_status_id_str"] == str(id): return i for i in range(0, len(listItem)):
return None if listItem[i]["in_reply_to_status_id_str"] == str(id): return i
return None
def is_audio(tweet):
try: def is_audio(tweet):
if len(find_urls(tweet)) < 1: try:
return False if len(find_urls(tweet)) < 1:
if len(tweet["entities"]["hashtags"]) > 0: return False
for i in tweet["entities"]["hashtags"]: if len(tweet["entities"]["hashtags"]) > 0:
if i["text"] == "audio": for i in tweet["entities"]["hashtags"]:
return True if i["text"] == "audio":
except: return True
print tweet["entities"]["hashtags"] except:
log.exception("Exception while executing is_audio hashtag algorithm") print(tweet["entities"]["hashtags"])
log.exception("Exception while executing is_audio hashtag algorithm")
def is_geocoded(tweet):
if tweet.has_key("coordinates") and tweet["coordinates"] != None: def is_geocoded(tweet):
return True if "coordinates" in tweet and tweet["coordinates"] != None:
return True
def is_media(tweet):
if tweet["entities"].has_key("media") == False: def is_media(tweet):
return False if ("media" in tweet["entities"]) == False:
for i in tweet["entities"]["media"]: return False
if i.has_key("type") and i["type"] == "photo": for i in tweet["entities"]["media"]:
return True if "type" in i and i["type"] == "photo":
return False return True
return False
def get_all_mentioned(tweet, conf, field="screen_name"):
""" Gets all users that has been mentioned.""" def get_all_mentioned(tweet, conf, field="screen_name"):
results = [] """ Gets all users that has been mentioned."""
for i in tweet["entities"]["user_mentions"]: results = []
if i["screen_name"] != conf["user_name"] and i["screen_name"] != tweet["user"]["screen_name"]: for i in tweet["entities"]["user_mentions"]:
if i[field] not in results: if i["screen_name"] != conf["user_name"] and i["screen_name"] != tweet["user"]["screen_name"]:
results.append(i[field]) if i[field] not in results:
return results results.append(i[field])
return results
def get_all_users(tweet, conf):
string = [] def get_all_users(tweet, conf):
if tweet.has_key("retweeted_status"): string = []
string.append(tweet["user"]["screen_name"]) if "retweeted_status" in tweet:
tweet = tweet["retweeted_status"] string.append(tweet["user"]["screen_name"])
if tweet.has_key("sender"): tweet = tweet["retweeted_status"]
string.append(tweet["sender"]["screen_name"]) if "sender" in tweet:
else: string.append(tweet["sender"]["screen_name"])
if tweet["user"]["screen_name"] != conf["user_name"]: else:
string.append(tweet["user"]["screen_name"]) if tweet["user"]["screen_name"] != conf["user_name"]:
for i in tweet["entities"]["user_mentions"]: string.append(tweet["user"]["screen_name"])
if i["screen_name"] != conf["user_name"] and i["screen_name"] != tweet["user"]["screen_name"]: for i in tweet["entities"]["user_mentions"]:
if i["screen_name"] not in string: if i["screen_name"] != conf["user_name"] and i["screen_name"] != tweet["user"]["screen_name"]:
string.append(i["screen_name"]) if i["screen_name"] not in string:
if len(string) == 0: string.append(i["screen_name"])
string.append(tweet["user"]["screen_name"]) if len(string) == 0:
return string string.append(tweet["user"]["screen_name"])
return string
def if_user_exists(twitter, user):
try: def if_user_exists(twitter, user):
data = twitter.show_user(screen_name=user) try:
return data data = twitter.show_user(screen_name=user)
except TwythonError as err: return data
if err.error_code == 404: except TwythonError as err:
return None if err.error_code == 404:
else: return None
return user else:
return user
def api_call(parent=None, call_name=None, preexec_message="", success="", success_snd="", *args, **kwargs):
if preexec_message: def api_call(parent=None, call_name=None, preexec_message="", success="", success_snd="", *args, **kwargs):
output.speak(preexec_message, True) if preexec_message:
try: output.speak(preexec_message, True)
val = getattr(parent.twitter.twitter, call_name)(*args, **kwargs) try:
output.speak(success) val = getattr(parent.twitter.twitter, call_name)(*args, **kwargs)
parent.parent.sound.play(success_snd) output.speak(success)
except TwythonError as e: parent.parent.sound.play(success_snd)
output.speak("Error %s: %s" % (e.error_code, e.msg), True) except TwythonError as e:
parent.parent.sound.play("error.ogg") output.speak("Error %s: %s" % (e.error_code, e.msg), True)
return val parent.parent.sound.play("error.ogg")
return val
def is_allowed(tweet, clients):
if tweet.has_key("sender"): return True def is_allowed(tweet, clients):
allowed = True if "sender" in tweet: return True
if tweet.has_key("retweeted_status"): tweet = tweet["retweeted_status"] allowed = True
source = re.sub(r"(?s)<.*?>", "", tweet["source"]) if "retweeted_status" in tweet: tweet = tweet["retweeted_status"]
for i in clients: source = re.sub(r"(?s)<.*?>", "", tweet["source"])
if i.lower() == source.lower(): for i in clients:
allowed = False if i.lower() == source.lower():
# log.exception("Tuit not allowed: %r" % (tweet,)) allowed = False
return allowed # log.exception("Tuit not allowed: %r" % (tweet,))
return allowed
def twitter_error(error):
if error.error_code == 403: def twitter_error(error):
msg = _(u"Sorry, you are not authorised to see this status.") if error.error_code == 403:
elif error.error_code == 404: msg = _(u"Sorry, you are not authorised to see this status.")
msg = _(u"No status found with that ID") elif error.error_code == 404:
else: msg = _(u"No status found with that ID")
msg = _(u"Error code {0}").format(error.error_code,) else:
msg = _(u"Error code {0}").format(error.error_code,)
output.speak(msg) output.speak(msg)

View File

@ -1,20 +1,21 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import application from __future__ import absolute_import
import update import application
import platform from . import update
import logging import platform
import output import logging
from requests.exceptions import ConnectionError import output
from wxUpdater import * from requests.exceptions import ConnectionError
logger = logging.getLogger("updater") from .wxUpdater import *
logger = logging.getLogger("updater")
def do_update(endpoint=application.update_url):
try: def do_update(endpoint=application.update_url):
update.perform_update(endpoint=endpoint, current_version=application.version, app_name=application.name, update_available_callback=available_update_dialog, progress_callback=progress_callback, update_complete_callback=update_finished) try:
except: update.perform_update(endpoint=endpoint, current_version=application.version, app_name=application.name, update_available_callback=available_update_dialog, progress_callback=progress_callback, update_complete_callback=update_finished)
if endpoint == application.update_url: except:
logger.error("Update failed! Using mirror URL...") if endpoint == application.update_url:
return do_update(endpoint=application.mirror_update_url) logger.error("Update failed! Using mirror URL...")
else: return do_update(endpoint=application.mirror_update_url)
logger.exception("Update failed.") else:
logger.exception("Update failed.")
output.speak("An exception occurred while attempting to update " + application.name + ". If this message persists, contact the " + application.name + " developers. More information about the exception has been written to the error log.",True) output.speak("An exception occurred while attempting to update " + application.name + ". If this message persists, contact the " + application.name + " developers. More information about the exception has been written to the error log.",True)

View File

@ -1,30 +1,31 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import wx from __future__ import absolute_import
import application import wx
import utils import application
from . import utils
progress_dialog = None
progress_dialog = None
def available_update_dialog(version, description, date):
dialog = wx.MessageDialog(None, _(u"There's a new %s version available, released on %s. Would you like to download it now?\n\n %s version: %s\n\nChanges:\n%s") % (application.name, date, application.name, version, description), _(u"New version for %s") % application.name, style=wx.YES|wx.NO|wx.ICON_WARNING) def available_update_dialog(version, description, date):
if dialog.ShowModal() == wx.ID_YES: dialog = wx.MessageDialog(None, _(u"There's a new %s version available, released on %s. Would you like to download it now?\n\n %s version: %s\n\nChanges:\n%s") % (application.name, date, application.name, version, description), _(u"New version for %s") % application.name, style=wx.YES|wx.NO|wx.ICON_WARNING)
return True if dialog.ShowModal() == wx.ID_YES:
else: return True
return False else:
return False
def create_progress_dialog():
return wx.ProgressDialog(_(u"Download in Progress"), _(u"Downloading the new version..."), parent=None, maximum=100) def create_progress_dialog():
return wx.ProgressDialog(_(u"Download in Progress"), _(u"Downloading the new version..."), parent=None, maximum=100)
def progress_callback(total_downloaded, total_size):
global progress_dialog def progress_callback(total_downloaded, total_size):
if progress_dialog == None: global progress_dialog
progress_dialog = create_progress_dialog() if progress_dialog == None:
progress_dialog.Show() progress_dialog = create_progress_dialog()
if total_downloaded == total_size: progress_dialog.Show()
progress_dialog.Destroy() if total_downloaded == total_size:
else: progress_dialog.Destroy()
progress_dialog.Update((total_downloaded*100)/total_size, _(u"Updating... %s of %s") % (str(utils.convert_bytes(total_downloaded)), str(utils.convert_bytes(total_size)))) else:
progress_dialog.Update((total_downloaded*100)/total_size, _(u"Updating... %s of %s") % (str(utils.convert_bytes(total_downloaded)), str(utils.convert_bytes(total_size))))
def update_finished():
def update_finished():
ms = wx.MessageDialog(None, _(u"The update has been downloaded and installed successfully. Press OK to continue."), _(u"Done!")).ShowModal() ms = wx.MessageDialog(None, _(u"The update has been downloaded and installed successfully. Press OK to continue."), _(u"Done!")).ShowModal()

View File

@ -1,2 +1,3 @@
import shorteners from __future__ import absolute_import
from __main__ import * from . import shorteners
from .__main__ import *

View File

@ -1,45 +1,46 @@
from functools import wraps from __future__ import absolute_import
import shorteners from functools import wraps
from . import shorteners
def service_selecter (func):
@wraps(func) def service_selecter (func):
def wrapper (*args, **kwargs): @wraps(func)
tmp = dict(kwargs) def wrapper (*args, **kwargs):
if 'service' in tmp: tmp = dict(kwargs)
del(tmp['service']) if 'service' in tmp:
kwargs['service'] = find_service(kwargs['service'], **tmp) or default_service() del(tmp['service'])
else: kwargs['service'] = find_service(kwargs['service'], **tmp) or default_service()
kwargs['service'] = default_service() else:
return func(*args, **kwargs) kwargs['service'] = default_service()
return wrapper return func(*args, **kwargs)
return wrapper
@service_selecter
def shorten (url, service=None, **kwargs): @service_selecter
return service(**kwargs).shorten(url) def shorten (url, service=None, **kwargs):
return service(**kwargs).shorten(url)
@service_selecter
def unshorten (url, service=None, **kwargs): @service_selecter
return service(**kwargs).unshorten(url) def unshorten (url, service=None, **kwargs):
return service(**kwargs).unshorten(url)
def default_service ():
return shorteners.TinyurlShortener def default_service ():
return shorteners.TinyurlShortener
def find_service (service, **kwargs):
for i in shorteners.__all__: def find_service (service, **kwargs):
obj = getattr(shorteners, i)(**kwargs) for i in shorteners.__all__:
if obj.name.lower() == service.lower(): obj = getattr(shorteners, i)(**kwargs)
return getattr(shorteners, i) if obj.name.lower() == service.lower():
return getattr(shorteners, i)
def list_services ():
return [getattr(shorteners, i)().name for i in shorteners.__all__] def list_services ():
return [getattr(shorteners, i)().name for i in shorteners.__all__]
def unshorten_any (url):
"""Unshortens an URL using any available unshortener. Check to see if unshortened URL was created by a shortener (nested) and unshorten if so.""" def unshorten_any (url):
unshortened_url = shorteners.URLShortener().unshorten(url) """Unshortens an URL using any available unshortener. Check to see if unshortened URL was created by a shortener (nested) and unshorten if so."""
# None is returned if URL not unshortened unshortened_url = shorteners.URLShortener().unshorten(url)
if unshortened_url: # None is returned if URL not unshortened
return unshorten_any(unshortened_url) if unshortened_url:
return url return unshorten_any(unshortened_url)
return url

View File

@ -1,9 +1,10 @@
from url_shortener import URLShortener from __future__ import absolute_import
from hkcim import HKCShortener from .url_shortener import URLShortener
from isgd import IsgdShortener from .hkcim import HKCShortener
from onjme import OnjmeShortener from .isgd import IsgdShortener
from tinyarrows import TinyArrowsShortener from .onjme import OnjmeShortener
from tinyurl import TinyurlShortener from .tinyarrows import TinyArrowsShortener
from xedcc import XedccShortener from .tinyurl import TinyurlShortener
from clckru import ClckruShortener from .xedcc import XedccShortener
__all__ = ["HKCShortener", "IsgdShortener", "OnjmeShortener", "TinyArrowsShortener", "TinyurlShortener", "XedccShortener", "ClckruShortener"] from .clckru import ClckruShortener
__all__ = ["HKCShortener", "IsgdShortener", "OnjmeShortener", "TinyArrowsShortener", "TinyurlShortener", "XedccShortener", "ClckruShortener"]

View File

@ -1,20 +1,21 @@
import urllib from __future__ import absolute_import
import urllib
from url_shortener import URLShortener
from .url_shortener import URLShortener
class ClckruShortener (URLShortener):
def __init__ (self, *args, **kwargs): class ClckruShortener (URLShortener):
self.name = "clck.ru" def __init__ (self, *args, **kwargs):
return super(ClckruShortener, self).__init__(*args, **kwargs) self.name = "clck.ru"
return super(ClckruShortener, self).__init__(*args, **kwargs)
def _shorten (self, url):
answer = url def _shorten (self, url):
api = urllib.urlopen ("http://clck.ru/--?url=" + urllib.quote(url)) answer = url
if api.getcode() == 200: api = urllib.urlopen ("http://clck.ru/--?url=" + urllib.quote(url))
answer = api.read() if api.getcode() == 200:
api.close() answer = api.read()
return answer api.close()
return answer
def created_url (self, url):
return 'clck.ru' in url def created_url (self, url):
return 'clck.ru' in url

View File

@ -1,19 +1,20 @@
import urllib from __future__ import absolute_import
import urllib
from url_shortener import URLShortener
from .url_shortener import URLShortener
class HKCShortener (URLShortener):
def __init__ (self, *args, **kwargs): class HKCShortener (URLShortener):
self.name = "HKC.im" def __init__ (self, *args, **kwargs):
super(HKCShortener, self).__init__(*args, **kwargs) self.name = "HKC.im"
super(HKCShortener, self).__init__(*args, **kwargs)
def _shorten (self, url):
answer = url def _shorten (self, url):
api = urllib.urlopen ("http://hkc.im/yourls-api.php?action=shorturl&format=simple&url=" + urllib.quote(url)) answer = url
if api.getcode() == 200: api = urllib.urlopen ("http://hkc.im/yourls-api.php?action=shorturl&format=simple&url=" + urllib.quote(url))
answer = api.read() if api.getcode() == 200:
api.close() answer = api.read()
return answer api.close()
return answer
def created_url (self, url):
return 'hkc.im' in url.lower() def created_url (self, url):
return 'hkc.im' in url.lower()

View File

@ -1,20 +1,21 @@
import urllib from __future__ import absolute_import
import urllib
from url_shortener import URLShortener
from .url_shortener import URLShortener
class IsgdShortener (URLShortener):
def __init__ (self, *args, **kwargs): class IsgdShortener (URLShortener):
self.name = "Is.gd" def __init__ (self, *args, **kwargs):
return super(IsgdShortener, self).__init__(*args, **kwargs) self.name = "Is.gd"
return super(IsgdShortener, self).__init__(*args, **kwargs)
def _shorten (self, url):
answer = url def _shorten (self, url):
api = urllib.urlopen ("http://is.gd/api.php?longurl=" + urllib.quote(url)) answer = url
if api.getcode() == 200: api = urllib.urlopen ("http://is.gd/api.php?longurl=" + urllib.quote(url))
answer = api.read() if api.getcode() == 200:
api.close() answer = api.read()
return answer api.close()
return answer
def created_url (self, url):
return 'is.gd' in url def created_url (self, url):
return 'is.gd' in url

View File

@ -1,19 +1,20 @@
import urllib from __future__ import absolute_import
import urllib
from url_shortener import URLShortener
from .url_shortener import URLShortener
class OnjmeShortener (URLShortener):
def __init__ (self, *args, **kwargs): class OnjmeShortener (URLShortener):
self.name = "Onj.me" def __init__ (self, *args, **kwargs):
super(OnjmeShortener, self).__init__(*args, **kwargs) self.name = "Onj.me"
super(OnjmeShortener, self).__init__(*args, **kwargs)
def _shorten (self, url):
answer = url def _shorten (self, url):
api = urllib.urlopen ("http://onj.me/yourls-api.php?action=shorturl&format=simple&url=" + urllib.quote(url)) answer = url
if api.getcode() == 200: api = urllib.urlopen ("http://onj.me/yourls-api.php?action=shorturl&format=simple&url=" + urllib.quote(url))
answer = api.read() if api.getcode() == 200:
api.close() answer = api.read()
return answer api.close()
return answer
def created_url (self, url):
return 'onj.me' in url.lower() def created_url (self, url):
return 'onj.me' in url.lower()

View File

@ -1,16 +1,17 @@
import urllib from __future__ import absolute_import
import urllib
from url_shortener import URLShortener
from .url_shortener import URLShortener
class TinyArrowsShortener (URLShortener):
def __init__ (self, *args, **kwargs): class TinyArrowsShortener (URLShortener):
self.name = "TinyArro.ws" def __init__ (self, *args, **kwargs):
super(TinyArrowsShortener, self).__init__(*args, **kwargs) self.name = "TinyArro.ws"
super(TinyArrowsShortener, self).__init__(*args, **kwargs)
def _shorten (self, url):
answer = url def _shorten (self, url):
answer = urllib.urlopen("http://tinyarro.ws/api-create.php?utfpure=1&url=%s" % urllib.quote(url)).read() answer = url
return answer.decode('UTF-8') answer = urllib.urlopen("http://tinyarro.ws/api-create.php?utfpure=1&url=%s" % urllib.quote(url)).read()
return answer.decode('UTF-8')
def created_url(self, url):
return False def created_url(self, url):
return False

View File

@ -1,18 +1,19 @@
from url_shortener import URLShortener from __future__ import absolute_import
import urllib from .url_shortener import URLShortener
class TinyurlShortener (URLShortener): import urllib
def __init__(self, *args, **kwargs): class TinyurlShortener (URLShortener):
self.name = "TinyURL.com" def __init__(self, *args, **kwargs):
super(TinyurlShortener, self).__init__(*args, **kwargs) self.name = "TinyURL.com"
super(TinyurlShortener, self).__init__(*args, **kwargs)
def _shorten (self, url):
def _shorten (self, url):
answer = url
api = urllib.urlopen ("http://tinyurl.com/api-create.php?url=" + urllib.quote(url)) answer = url
if api.getcode() == 200: api = urllib.urlopen ("http://tinyurl.com/api-create.php?url=" + urllib.quote(url))
answer = api.read() if api.getcode() == 200:
api.close() answer = api.read()
return answer api.close()
return answer
def created_url (self, url):
return 'tinyurl.com' in url def created_url (self, url):
return 'tinyurl.com' in url

View File

@ -1,33 +1,33 @@
from httplib import HTTPConnection from httplib import HTTPConnection
from urlparse import urlparse from urlparse import urlparse
class URLShortener (object): class URLShortener (object):
def __init__ (self, *args, **kwargs): def __init__ (self, *args, **kwargs):
#Stub out arguments, silly object. :( #Stub out arguments, silly object. :(
return super(URLShortener, self).__init__() return super(URLShortener, self).__init__()
def shorten (self, url): def shorten (self, url):
if self.created_url(url): if self.created_url(url):
return url return url
else: else:
return self._shorten(url) return self._shorten(url)
def _shorten (self, url): def _shorten (self, url):
raise NotImplementedError raise NotImplementedError
def created_url (self, url): def created_url (self, url):
"""Returns a boolean indicating whether or not this shortener created a provided url""" """Returns a boolean indicating whether or not this shortener created a provided url"""
raise NotImplementedError raise NotImplementedError
def unshorten(self, url): def unshorten(self, url):
working = urlparse(url) working = urlparse(url)
if not working.netloc: if not working.netloc:
raise TypeError, "Unable to parse URL." raise TypeError("Unable to parse URL.")
con = HTTPConnection(working.netloc) con = HTTPConnection(working.netloc)
con.connect() con.connect()
con.request('GET', working.path) con.request('GET', working.path)
resp = con.getresponse() resp = con.getresponse()
con.close() con.close()
return resp.getheader('location') return resp.getheader('location')

View File

@ -1,19 +1,20 @@
import urllib from __future__ import absolute_import
import urllib
from url_shortener import URLShortener
from .url_shortener import URLShortener
class XedccShortener (URLShortener):
def __init__ (self, *args, **kwargs): class XedccShortener (URLShortener):
self.name = "Xed.cc" def __init__ (self, *args, **kwargs):
super(XedccShortener, self).__init__(*args, **kwargs) self.name = "Xed.cc"
super(XedccShortener, self).__init__(*args, **kwargs)
def _shorten (self, url):
answer = url def _shorten (self, url):
api = urllib.urlopen ("http://xed.cc/yourls-api.php?action=shorturl&format=simple&url=" + urllib.quote(url)) answer = url
if api.getcode() == 200: api = urllib.urlopen ("http://xed.cc/yourls-api.php?action=shorturl&format=simple&url=" + urllib.quote(url))
answer = api.read() if api.getcode() == 200:
api.close() answer = api.read()
return answer api.close()
return answer
def created_url (self, url):
return 'xed.cc' in url.lower() def created_url (self, url):
return 'xed.cc' in url.lower()

View File

@ -1,5 +1,6 @@
import platform from __future__ import absolute_import
if platform.system() == "Windows": import platform
from wxUtils import * if platform.system() == "Windows":
#elif platform.system() == "Linux": from .wxUtils import *
# from gtkUtils import * #elif platform.system() == "Linux":
# from gtkUtils import *

View File

@ -1,11 +1,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from base import basePanel from __future__ import absolute_import
from dm import dmPanel from .base import basePanel
from events import eventsPanel from .dm import dmPanel
from favourites import favsPanel from .events import eventsPanel
from lists import listPanel from .favourites import favsPanel
from panels import accountPanel, emptyPanel from .lists import listPanel
from people import peoplePanel from .panels import accountPanel, emptyPanel
from trends import trendsPanel from .people import peoplePanel
from tweet_searches import searchPanel from .trends import trendsPanel
from user_searches import searchUsersPanel from .tweet_searches import searchPanel
from .user_searches import searchUsersPanel

View File

@ -1,11 +1,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import wx from __future__ import absolute_import
from base import basePanel import wx
from .base import basePanel
class dmPanel(basePanel):
def __init__(self, parent, name): class dmPanel(basePanel):
""" Class to DM'S. Reply and retweet buttons are not showed and they have your delete method for dm's.""" def __init__(self, parent, name):
super(dmPanel, self).__init__(parent, name) """ Class to DM'S. Reply and retweet buttons are not showed and they have your delete method for dm's."""
self.retweet.Disable() super(dmPanel, self).__init__(parent, name)
self.reply.Disable() self.retweet.Disable()
self.reply.Disable()
self.type = "dm" self.type = "dm"

View File

@ -1,8 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import wx from __future__ import absolute_import
from base import basePanel import wx
from .base import basePanel
class favsPanel(basePanel):
def __init__(self, parent, name): class favsPanel(basePanel):
super(favsPanel, self).__init__(parent, name) def __init__(self, parent, name):
super(favsPanel, self).__init__(parent, name)
self.type = "favourites_timeline" self.type = "favourites_timeline"

View File

@ -1,8 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import wx from __future__ import absolute_import
from base import basePanel import wx
from .base import basePanel
class listPanel(basePanel):
def __init__(self, parent, name): class listPanel(basePanel):
super(listPanel, self).__init__(parent, name) def __init__(self, parent, name):
self.type = "list" super(listPanel, self).__init__(parent, name)
self.type = "list"

View File

@ -1,16 +1,17 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import wx from __future__ import absolute_import
from multiplatform_widgets import widgets import wx
from base import basePanel from multiplatform_widgets import widgets
from .base import basePanel
class peoplePanel(basePanel):
""" Buffer used to show people.""" class peoplePanel(basePanel):
""" Buffer used to show people."""
def create_list(self):
self.list = widgets.list(self, _(u"User"), style=wx.LC_REPORT|wx.LC_SINGLE_SEL, size=(800, 800)) def create_list(self):
self.list = widgets.list(self, _(u"User"), style=wx.LC_REPORT|wx.LC_SINGLE_SEL, size=(800, 800))
def __init__(self, parent, name):
super(peoplePanel, self).__init__(parent, name) def __init__(self, parent, name):
self.type = "people" super(peoplePanel, self).__init__(parent, name)
self.reply.SetLabel(_(u"Mention")) self.type = "people"
self.retweet.Disable() self.reply.SetLabel(_(u"Mention"))
self.retweet.Disable()

View File

@ -1,8 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import wx from __future__ import absolute_import
from base import basePanel import wx
from .base import basePanel
class searchPanel(basePanel):
def __init__(self, parent, name): class searchPanel(basePanel):
super(searchPanel, self).__init__(parent, name) def __init__(self, parent, name):
self.type = "search" super(searchPanel, self).__init__(parent, name)
self.type = "search"

View File

@ -1,14 +1,15 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import wx from __future__ import absolute_import
from tweet_searches import searchPanel import wx
from multiplatform_widgets import widgets from .tweet_searches import searchPanel
from multiplatform_widgets import widgets
class searchUsersPanel(searchPanel):
def create_list(self): class searchUsersPanel(searchPanel):
""" Returns the list for put the tweets here.""" def create_list(self):
self.list = widgets.list(self, _(u"User"), style=wx.LC_REPORT|wx.LC_SINGLE_SEL, size=(800, 800)) """ Returns the list for put the tweets here."""
self.list = widgets.list(self, _(u"User"), style=wx.LC_REPORT|wx.LC_SINGLE_SEL, size=(800, 800))
def __init__(self, parent, name):
super(searchUsersPanel, self).__init__(parent, name) def __init__(self, parent, name):
self.create_list() super(searchUsersPanel, self).__init__(parent, name)
self.create_list()
self.type = "user_searches" self.type = "user_searches"

View File

@ -1 +1,2 @@
import baseDialog, trends, configuration, lists, message, search, find, show_user, update_profile, urlList, userSelection, utils from __future__ import absolute_import
from . import baseDialog, trends, configuration, lists, message, search, find, show_user, update_profile, urlList, userSelection, utils

View File

@ -1,377 +1,379 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import baseDialog from __future__ import absolute_import
import wx # -*- coding: utf-8 -*-
import logging as original_logger from . import baseDialog
import application import wx
from multiplatform_widgets import widgets import logging as original_logger
import output import application
import config from multiplatform_widgets import widgets
import output
class general(wx.Panel, baseDialog.BaseWXDialog): import config
def __init__(self, parent, languages,keymaps):
super(general, self).__init__(parent) class general(wx.Panel, baseDialog.BaseWXDialog):
sizer = wx.BoxSizer(wx.VERTICAL) def __init__(self, parent, languages,keymaps):
language = wx.StaticText(self, -1, _(u"Language")) super(general, self).__init__(parent)
self.language = wx.ListBox(self, -1, choices=languages) sizer = wx.BoxSizer(wx.VERTICAL)
self.language.SetSize(self.language.GetBestSize()) language = wx.StaticText(self, -1, _(u"Language"))
langBox = wx.BoxSizer(wx.HORIZONTAL) self.language = wx.ListBox(self, -1, choices=languages)
langBox.Add(language, 0, wx.ALL, 5) self.language.SetSize(self.language.GetBestSize())
langBox.Add(self.language, 0, wx.ALL, 5) langBox = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(langBox, 0, wx.ALL, 5) langBox.Add(language, 0, wx.ALL, 5)
self.autostart = wx.CheckBox(self, -1, _(u"Run {0} at Windows startup").format(application.name,)) langBox.Add(self.language, 0, wx.ALL, 5)
self.ask_at_exit = wx.CheckBox(self, -1, _(U"ask before exiting {0}").format(application.name,)) sizer.Add(langBox, 0, wx.ALL, 5)
sizer.Add(self.autostart, 0, wx.ALL, 5) self.autostart = wx.CheckBox(self, -1, _(u"Run {0} at Windows startup").format(application.name,))
sizer.Add(self.ask_at_exit, 0, wx.ALL, 5) self.ask_at_exit = wx.CheckBox(self, -1, _(U"ask before exiting {0}").format(application.name,))
self.play_ready_sound = wx.CheckBox(self, -1, _(U"Play a sound when {0} launches").format(application.name,)) sizer.Add(self.autostart, 0, wx.ALL, 5)
sizer.Add(self.play_ready_sound, 0, wx.ALL, 5) sizer.Add(self.ask_at_exit, 0, wx.ALL, 5)
self.speak_ready_msg = wx.CheckBox(self, -1, _(U"Speak a message when {0} launches").format(application.name,)) self.play_ready_sound = wx.CheckBox(self, -1, _(U"Play a sound when {0} launches").format(application.name,))
sizer.Add(self.speak_ready_msg, 0, wx.ALL, 5) sizer.Add(self.play_ready_sound, 0, wx.ALL, 5)
self.use_invisible_shorcuts = wx.CheckBox(self, -1, _(u"Use invisible interface's keyboard shortcuts while GUI is visible")) self.speak_ready_msg = wx.CheckBox(self, -1, _(U"Speak a message when {0} launches").format(application.name,))
sizer.Add(self.use_invisible_shorcuts, 0, wx.ALL, 5) sizer.Add(self.speak_ready_msg, 0, wx.ALL, 5)
self.disable_sapi5 = wx.CheckBox(self, -1, _(u"Activate Sapi5 when any other screen reader is not being run")) self.use_invisible_shorcuts = wx.CheckBox(self, -1, _(u"Use invisible interface's keyboard shortcuts while GUI is visible"))
sizer.Add(self.disable_sapi5, 0, wx.ALL, 5) sizer.Add(self.use_invisible_shorcuts, 0, wx.ALL, 5)
self.hide_gui = wx.CheckBox(self, -1, _(u"Hide GUI on launch")) self.disable_sapi5 = wx.CheckBox(self, -1, _(u"Activate Sapi5 when any other screen reader is not being run"))
sizer.Add(self.hide_gui, 0, wx.ALL, 5) sizer.Add(self.disable_sapi5, 0, wx.ALL, 5)
self.handle_longtweets = wx.CheckBox(self, wx.NewId(), _(u"Use Codeofdusk's longtweet handlers (may decrease client performance)")) self.hide_gui = wx.CheckBox(self, -1, _(u"Hide GUI on launch"))
sizer.Add(self.handle_longtweets, 0, wx.ALL, 5) sizer.Add(self.hide_gui, 0, wx.ALL, 5)
kmbox = wx.BoxSizer(wx.VERTICAL) self.handle_longtweets = wx.CheckBox(self, wx.NewId(), _(u"Use Codeofdusk's longtweet handlers (may decrease client performance)"))
km_label = wx.StaticText(self, -1, _(u"Keymap")) sizer.Add(self.handle_longtweets, 0, wx.ALL, 5)
self.km = wx.ComboBox(self, -1, choices=keymaps, style=wx.CB_READONLY) kmbox = wx.BoxSizer(wx.VERTICAL)
self.km.SetSize(self.km.GetBestSize()) km_label = wx.StaticText(self, -1, _(u"Keymap"))
kmbox.Add(km_label, 0, wx.ALL, 5) self.km = wx.ComboBox(self, -1, choices=keymaps, style=wx.CB_READONLY)
kmbox.Add(self.km, 0, wx.ALL, 5) self.km.SetSize(self.km.GetBestSize())
self.check_for_updates = wx.CheckBox(self, -1, _(U"Check for updates when {0} launches").format(application.name,)) kmbox.Add(km_label, 0, wx.ALL, 5)
sizer.Add(self.check_for_updates, 0, wx.ALL, 5) kmbox.Add(self.km, 0, wx.ALL, 5)
sizer.Add(kmbox, 0, wx.ALL, 5) self.check_for_updates = wx.CheckBox(self, -1, _(U"Check for updates when {0} launches").format(application.name,))
self.SetSizer(sizer) sizer.Add(self.check_for_updates, 0, wx.ALL, 5)
sizer.Add(kmbox, 0, wx.ALL, 5)
class proxy(wx.Panel, baseDialog.BaseWXDialog): self.SetSizer(sizer)
def __init__(self, parent, proxyTypes): class proxy(wx.Panel, baseDialog.BaseWXDialog):
super(proxy, self).__init__(parent)
sizer = wx.BoxSizer(wx.VERTICAL) def __init__(self, parent, proxyTypes):
type=wx.StaticText(self, wx.NewId(), _(u"Proxy type: ")) super(proxy, self).__init__(parent)
self.type=wx.ComboBox(self, -1, choices=proxyTypes, style=wx.CB_READONLY) sizer = wx.BoxSizer(wx.VERTICAL)
self.type.SetSize(self.type.GetBestSize()) type=wx.StaticText(self, wx.NewId(), _(u"Proxy type: "))
typeBox = wx.BoxSizer(wx.HORIZONTAL) self.type=wx.ComboBox(self, -1, choices=proxyTypes, style=wx.CB_READONLY)
typeBox.Add(type, 0, wx.ALL, 5) self.type.SetSize(self.type.GetBestSize())
typeBox.Add(self.type, 0, wx.ALL, 5) typeBox = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(typeBox, 0, wx.ALL, 5) typeBox.Add(type, 0, wx.ALL, 5)
lbl = wx.StaticText(self, wx.NewId(), _(u"Proxy server: ")) typeBox.Add(self.type, 0, wx.ALL, 5)
self.server = wx.TextCtrl(self, -1) sizer.Add(typeBox, 0, wx.ALL, 5)
serverBox = wx.BoxSizer(wx.HORIZONTAL) lbl = wx.StaticText(self, wx.NewId(), _(u"Proxy server: "))
serverBox.Add(lbl, 0, wx.ALL, 5) self.server = wx.TextCtrl(self, -1)
serverBox.Add(self.server, 0, wx.ALL, 5) serverBox = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(serverBox, 0, wx.ALL, 5) serverBox.Add(lbl, 0, wx.ALL, 5)
lbl = wx.StaticText(self, wx.NewId(), _(u"Port: ")) serverBox.Add(self.server, 0, wx.ALL, 5)
self.port = wx.TextCtrl(self, wx.NewId()) sizer.Add(serverBox, 0, wx.ALL, 5)
portBox = wx.BoxSizer(wx.HORIZONTAL) lbl = wx.StaticText(self, wx.NewId(), _(u"Port: "))
portBox.Add(lbl, 0, wx.ALL, 5) self.port = wx.TextCtrl(self, wx.NewId())
portBox.Add(self.port, 0, wx.ALL, 5) portBox = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(portBox, 0, wx.ALL, 5) portBox.Add(lbl, 0, wx.ALL, 5)
lbl = wx.StaticText(self, wx.NewId(), _(u"User: ")) portBox.Add(self.port, 0, wx.ALL, 5)
self.user = wx.TextCtrl(self, wx.NewId()) sizer.Add(portBox, 0, wx.ALL, 5)
userBox = wx.BoxSizer(wx.HORIZONTAL) lbl = wx.StaticText(self, wx.NewId(), _(u"User: "))
userBox.Add(lbl, 0, wx.ALL, 5) self.user = wx.TextCtrl(self, wx.NewId())
userBox.Add(self.user, 0, wx.ALL, 5) userBox = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(userBox, 0, wx.ALL, 5) userBox.Add(lbl, 0, wx.ALL, 5)
lbl = wx.StaticText(self, wx.NewId(), _(u"Password: ")) userBox.Add(self.user, 0, wx.ALL, 5)
self.password = wx.TextCtrl(self, wx.NewId(), style=wx.TE_PASSWORD) sizer.Add(userBox, 0, wx.ALL, 5)
passwordBox = wx.BoxSizer(wx.HORIZONTAL) lbl = wx.StaticText(self, wx.NewId(), _(u"Password: "))
passwordBox.Add(lbl, 0, wx.ALL, 5) self.password = wx.TextCtrl(self, wx.NewId(), style=wx.TE_PASSWORD)
passwordBox.Add(self.password, 0, wx.ALL, 5) passwordBox = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(serverBox, 0, wx.ALL, 5) passwordBox.Add(lbl, 0, wx.ALL, 5)
self.SetSizer(sizer) passwordBox.Add(self.password, 0, wx.ALL, 5)
sizer.Add(serverBox, 0, wx.ALL, 5)
class generalAccount(wx.Panel, baseDialog.BaseWXDialog): self.SetSizer(sizer)
def __init__(self, parent):
super(generalAccount, self).__init__(parent) class generalAccount(wx.Panel, baseDialog.BaseWXDialog):
sizer = wx.BoxSizer(wx.VERTICAL) def __init__(self, parent):
self.au = wx.Button(self, wx.NewId(), _(u"Autocompletion settings...")) super(generalAccount, self).__init__(parent)
sizer.Add(self.au, 0, wx.ALL, 5) sizer = wx.BoxSizer(wx.VERTICAL)
self.relative_time = wx.CheckBox(self, wx.NewId(), _(U"Relative timestamps")) self.au = wx.Button(self, wx.NewId(), _(u"Autocompletion settings..."))
sizer.Add(self.relative_time, 0, wx.ALL, 5) sizer.Add(self.au, 0, wx.ALL, 5)
apiCallsBox = wx.BoxSizer(wx.HORIZONTAL) self.relative_time = wx.CheckBox(self, wx.NewId(), _(U"Relative timestamps"))
apiCallsBox.Add(wx.StaticText(self, -1, _(u"API calls (One API call = 200 tweets, two API calls = 400 tweets, etc):")), 0, wx.ALL, 5) sizer.Add(self.relative_time, 0, wx.ALL, 5)
self.apiCalls = wx.SpinCtrl(self, wx.NewId()) apiCallsBox = wx.BoxSizer(wx.HORIZONTAL)
self.apiCalls.SetRange(1, 10) apiCallsBox.Add(wx.StaticText(self, -1, _(u"API calls (One API call = 200 tweets, two API calls = 400 tweets, etc):")), 0, wx.ALL, 5)
self.apiCalls.SetSize(self.apiCalls.GetBestSize()) self.apiCalls = wx.SpinCtrl(self, wx.NewId())
apiCallsBox.Add(self.apiCalls, 0, wx.ALL, 5) self.apiCalls.SetRange(1, 10)
sizer.Add(apiCallsBox, 0, wx.ALL, 5) self.apiCalls.SetSize(self.apiCalls.GetBestSize())
tweetsPerCallBox = wx.BoxSizer(wx.HORIZONTAL) apiCallsBox.Add(self.apiCalls, 0, wx.ALL, 5)
tweetsPerCallBox.Add(wx.StaticText(self, -1, _(u"Items on each API call")), 0, wx.ALL, 5) sizer.Add(apiCallsBox, 0, wx.ALL, 5)
self.itemsPerApiCall = wx.SpinCtrl(self, wx.NewId()) tweetsPerCallBox = wx.BoxSizer(wx.HORIZONTAL)
self.itemsPerApiCall.SetRange(0, 200) tweetsPerCallBox.Add(wx.StaticText(self, -1, _(u"Items on each API call")), 0, wx.ALL, 5)
self.itemsPerApiCall.SetSize(self.itemsPerApiCall.GetBestSize()) self.itemsPerApiCall = wx.SpinCtrl(self, wx.NewId())
tweetsPerCallBox.Add(self.itemsPerApiCall, 0, wx.ALL, 5) self.itemsPerApiCall.SetRange(0, 200)
sizer.Add(tweetsPerCallBox, 0, wx.ALL, 5) self.itemsPerApiCall.SetSize(self.itemsPerApiCall.GetBestSize())
self.reverse_timelines = wx.CheckBox(self, wx.NewId(), _(u"Inverted buffers: The newest tweets will be shown at the beginning while the oldest at the end")) tweetsPerCallBox.Add(self.itemsPerApiCall, 0, wx.ALL, 5)
sizer.Add(self.reverse_timelines, 0, wx.ALL, 5) sizer.Add(tweetsPerCallBox, 0, wx.ALL, 5)
lbl = wx.StaticText(self, wx.NewId(), _(u"Retweet mode")) self.reverse_timelines = wx.CheckBox(self, wx.NewId(), _(u"Inverted buffers: The newest tweets will be shown at the beginning while the oldest at the end"))
self.retweet_mode = wx.ComboBox(self, wx.NewId(), choices=[_(u"Ask"), _(u"Retweet without comments"), _(u"Retweet with comments")], style=wx.CB_READONLY) sizer.Add(self.reverse_timelines, 0, wx.ALL, 5)
rMode = wx.BoxSizer(wx.HORIZONTAL) lbl = wx.StaticText(self, wx.NewId(), _(u"Retweet mode"))
rMode.Add(lbl, 0, wx.ALL, 5) self.retweet_mode = wx.ComboBox(self, wx.NewId(), choices=[_(u"Ask"), _(u"Retweet without comments"), _(u"Retweet with comments")], style=wx.CB_READONLY)
rMode.Add(self.retweet_mode, 0, wx.ALL, 5) rMode = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(rMode, 0, wx.ALL, 5) rMode.Add(lbl, 0, wx.ALL, 5)
self.show_screen_names = wx.CheckBox(self, wx.NewId(), _(U"Show screen names instead of full names")) rMode.Add(self.retweet_mode, 0, wx.ALL, 5)
sizer.Add(self.show_screen_names, 0, wx.ALL, 5) sizer.Add(rMode, 0, wx.ALL, 5)
PersistSizeLabel = wx.StaticText(self, -1, _(u"Number of items per buffer to cache in database (0 to disable caching, blank for unlimited)")) self.show_screen_names = wx.CheckBox(self, wx.NewId(), _(U"Show screen names instead of full names"))
self.persist_size = wx.TextCtrl(self, -1) sizer.Add(self.show_screen_names, 0, wx.ALL, 5)
sizer.Add(PersistSizeLabel, 0, wx.ALL, 5) PersistSizeLabel = wx.StaticText(self, -1, _(u"Number of items per buffer to cache in database (0 to disable caching, blank for unlimited)"))
sizer.Add(self.persist_size, 0, wx.ALL, 5) self.persist_size = wx.TextCtrl(self, -1)
self.SetSizer(sizer) sizer.Add(PersistSizeLabel, 0, wx.ALL, 5)
sizer.Add(self.persist_size, 0, wx.ALL, 5)
class other_buffers(wx.Panel): self.SetSizer(sizer)
def __init__(self, parent):
super(other_buffers, self).__init__(parent) class other_buffers(wx.Panel):
sizer = wx.BoxSizer(wx.VERTICAL) def __init__(self, parent):
self.buffers = widgets.list(self, _(u"Buffer"), _(u"Name"), _(u"Status"), style=wx.LC_SINGLE_SEL|wx.LC_REPORT) super(other_buffers, self).__init__(parent)
sizer.Add(self.buffers.list, 0, wx.ALL, 5) sizer = wx.BoxSizer(wx.VERTICAL)
btnSizer = wx.BoxSizer(wx.HORIZONTAL) self.buffers = widgets.list(self, _(u"Buffer"), _(u"Name"), _(u"Status"), style=wx.LC_SINGLE_SEL|wx.LC_REPORT)
self.toggle_state = wx.Button(self, -1, _(u"Show/hide")) sizer.Add(self.buffers.list, 0, wx.ALL, 5)
self.up = wx.Button(self, -1, _(u"Move up")) btnSizer = wx.BoxSizer(wx.HORIZONTAL)
self.down = wx.Button(self, -1, _(u"Move down")) self.toggle_state = wx.Button(self, -1, _(u"Show/hide"))
btnSizer.Add(self.toggle_state, 0, wx.ALL, 5) self.up = wx.Button(self, -1, _(u"Move up"))
btnSizer.Add(self.up, 0, wx.ALL, 5) self.down = wx.Button(self, -1, _(u"Move down"))
btnSizer.Add(self.down, 0, wx.ALL, 5) btnSizer.Add(self.toggle_state, 0, wx.ALL, 5)
sizer.Add(btnSizer, 0, wx.ALL, 5) btnSizer.Add(self.up, 0, wx.ALL, 5)
self.SetSizer(sizer) btnSizer.Add(self.down, 0, wx.ALL, 5)
sizer.Add(btnSizer, 0, wx.ALL, 5)
def insert_buffers(self, buffers): self.SetSizer(sizer)
for i in buffers:
if i[2] == True: def insert_buffers(self, buffers):
self.buffers.insert_item(False, *[i[0], i[1], _(u"Show")]) for i in buffers:
else: if i[2] == True:
self.buffers.insert_item(False, *[i[0], i[1], _(u"Hide")]) self.buffers.insert_item(False, *[i[0], i[1], _(u"Show")])
else:
def connect_hook_func(self, func): self.buffers.insert_item(False, *[i[0], i[1], _(u"Hide")])
self.buffers.list.Bind(wx.EVT_CHAR_HOOK, func)
def connect_hook_func(self, func):
def move_up(self, *args, **kwargs): self.buffers.list.Bind(wx.EVT_CHAR_HOOK, func)
current = self.buffers.get_selected()
if current == -1: def move_up(self, *args, **kwargs):
output.speak(_(u"Select a buffer first."), True) current = self.buffers.get_selected()
return False if current == -1:
if self.buffers.get_text_column(current, 2) == _(u"Hide"): output.speak(_(u"Select a buffer first."), True)
output.speak(_(u"The buffer is hidden, show it first."), True) return False
return False if self.buffers.get_text_column(current, 2) == _(u"Hide"):
if current <= 0: output.speak(_(u"The buffer is hidden, show it first."), True)
output.speak(_(u"The buffer is already at the top of the list."), True) return False
return False if current <= 0:
current_text = self.buffers.get_text_column(self.buffers.get_selected(), 0) output.speak(_(u"The buffer is already at the top of the list."), True)
current_name = self.buffers.get_text_column(self.buffers.get_selected(), 1) return False
current_text_state = self.buffers.get_text_column(self.buffers.get_selected(), 2) current_text = self.buffers.get_text_column(self.buffers.get_selected(), 0)
text_above = self.buffers.get_text_column(self.buffers.get_selected()-1, 0) current_name = self.buffers.get_text_column(self.buffers.get_selected(), 1)
name_above = self.buffers.get_text_column(self.buffers.get_selected()-1, 1) current_text_state = self.buffers.get_text_column(self.buffers.get_selected(), 2)
text_above_state = self.buffers.get_text_column(self.buffers.get_selected()-1, 2) text_above = self.buffers.get_text_column(self.buffers.get_selected()-1, 0)
self.buffers.set_text_column(self.buffers.get_selected()-1, 0, current_text) name_above = self.buffers.get_text_column(self.buffers.get_selected()-1, 1)
self.buffers.set_text_column(self.buffers.get_selected()-1, 1, current_name) text_above_state = self.buffers.get_text_column(self.buffers.get_selected()-1, 2)
self.buffers.set_text_column(self.buffers.get_selected()-1, 2, current_text_state) self.buffers.set_text_column(self.buffers.get_selected()-1, 0, current_text)
self.buffers.set_text_column(self.buffers.get_selected(), 0, text_above) self.buffers.set_text_column(self.buffers.get_selected()-1, 1, current_name)
self.buffers.set_text_column(self.buffers.get_selected(), 1, name_above) self.buffers.set_text_column(self.buffers.get_selected()-1, 2, current_text_state)
self.buffers.set_text_column(self.buffers.get_selected(), 2, text_above_state) self.buffers.set_text_column(self.buffers.get_selected(), 0, text_above)
self.buffers.set_text_column(self.buffers.get_selected(), 1, name_above)
def move_down(self, *args, **kwargs): self.buffers.set_text_column(self.buffers.get_selected(), 2, text_above_state)
current = self.buffers.get_selected()
if current == -1: def move_down(self, *args, **kwargs):
output.speak(_(u"Select a buffer first."), True) current = self.buffers.get_selected()
return False if current == -1:
if self.buffers.get_text_column(current, 2) == _(u"Hide"): output.speak(_(u"Select a buffer first."), True)
output.speak(_(u"The buffer is hidden, show it first."), True) return False
return False if self.buffers.get_text_column(current, 2) == _(u"Hide"):
if current+1 >= self.buffers.get_count(): output.speak(_(u"The buffer is hidden, show it first."), True)
output.speak(_(u"The buffer is already at the bottom of the list."), True) return False
return False if current+1 >= self.buffers.get_count():
current_text = self.buffers.get_text_column(self.buffers.get_selected(), 0) output.speak(_(u"The buffer is already at the bottom of the list."), True)
current_name = self.buffers.get_text_column(self.buffers.get_selected(), 1) return False
current_text_state = self.buffers.get_text_column(self.buffers.get_selected(), 2) current_text = self.buffers.get_text_column(self.buffers.get_selected(), 0)
text_below = self.buffers.get_text_column(self.buffers.get_selected()+1, 0) current_name = self.buffers.get_text_column(self.buffers.get_selected(), 1)
name_below = self.buffers.get_text_column(self.buffers.get_selected()+1, 1) current_text_state = self.buffers.get_text_column(self.buffers.get_selected(), 2)
text_below_state = self.buffers.get_text_column(self.buffers.get_selected()+1, 2) text_below = self.buffers.get_text_column(self.buffers.get_selected()+1, 0)
self.buffers.set_text_column(self.buffers.get_selected()+1, 0, current_text) name_below = self.buffers.get_text_column(self.buffers.get_selected()+1, 1)
self.buffers.set_text_column(self.buffers.get_selected()+1, 1, current_name) text_below_state = self.buffers.get_text_column(self.buffers.get_selected()+1, 2)
self.buffers.set_text_column(self.buffers.get_selected()+1, 2, current_text_state) self.buffers.set_text_column(self.buffers.get_selected()+1, 0, current_text)
self.buffers.set_text_column(self.buffers.get_selected(), 0, text_below) self.buffers.set_text_column(self.buffers.get_selected()+1, 1, current_name)
self.buffers.set_text_column(self.buffers.get_selected(), 1, name_below) self.buffers.set_text_column(self.buffers.get_selected()+1, 2, current_text_state)
self.buffers.set_text_column(self.buffers.get_selected(), 2, text_below_state) self.buffers.set_text_column(self.buffers.get_selected(), 0, text_below)
self.buffers.set_text_column(self.buffers.get_selected(), 1, name_below)
def get_event(self, ev): self.buffers.set_text_column(self.buffers.get_selected(), 2, text_below_state)
if ev.GetKeyCode() == wx.WXK_SPACE:
return True def get_event(self, ev):
else: if ev.GetKeyCode() == wx.WXK_SPACE:
ev.Skip() return True
return False else:
ev.Skip()
def change_selected_item(self): return False
current = self.buffers.get_selected()
text = self.buffers.get_text_column(current, 2) def change_selected_item(self):
if text == _(u"Show"): current = self.buffers.get_selected()
self.buffers.set_text_column(current, 2, _(u"Hide")) text = self.buffers.get_text_column(current, 2)
else: if text == _(u"Show"):
self.buffers.set_text_column(current, 2, _(u"Show")) self.buffers.set_text_column(current, 2, _(u"Hide"))
output.speak(self.buffers.get_text_column(current, 2),True) else:
def get_list(self): self.buffers.set_text_column(current, 2, _(u"Show"))
buffers_list = [] output.speak(self.buffers.get_text_column(current, 2),True)
for i in xrange(0, self.buffers.get_count()): def get_list(self):
if self.buffers.get_text_column(i, 2) == _(u"Show"): buffers_list = []
buffers_list.append(self.buffers.get_text_column(i, 0)) for i in xrange(0, self.buffers.get_count()):
return buffers_list if self.buffers.get_text_column(i, 2) == _(u"Show"):
buffers_list.append(self.buffers.get_text_column(i, 0))
class ignoredClients(wx.Panel): return buffers_list
def __init__(self, parent, choices):
super(ignoredClients, self).__init__(parent=parent) class ignoredClients(wx.Panel):
sizer = wx.BoxSizer(wx.VERTICAL) def __init__(self, parent, choices):
label = wx.StaticText(self, -1, _(u"Ignored clients")) super(ignoredClients, self).__init__(parent=parent)
self.clients = wx.ListBox(self, -1, choices=choices) sizer = wx.BoxSizer(wx.VERTICAL)
self.clients.SetSize(self.clients.GetBestSize()) label = wx.StaticText(self, -1, _(u"Ignored clients"))
clientsBox = wx.BoxSizer(wx.HORIZONTAL) self.clients = wx.ListBox(self, -1, choices=choices)
clientsBox.Add(label, 0, wx.ALL, 5) self.clients.SetSize(self.clients.GetBestSize())
clientsBox.Add(self.clients, 0, wx.ALL, 5) clientsBox = wx.BoxSizer(wx.HORIZONTAL)
self.add = wx.Button(self, -1, _(u"Add client")) clientsBox.Add(label, 0, wx.ALL, 5)
self.remove = wx.Button(self, -1, _(u"Remove client")) clientsBox.Add(self.clients, 0, wx.ALL, 5)
btnBox = wx.BoxSizer(wx.HORIZONTAL) self.add = wx.Button(self, -1, _(u"Add client"))
btnBox.Add(self.add, 0, wx.ALL, 5) self.remove = wx.Button(self, -1, _(u"Remove client"))
btnBox.Add(self.remove, 0, wx.ALL, 5) btnBox = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(clientsBox, 0, wx.ALL, 5) btnBox.Add(self.add, 0, wx.ALL, 5)
sizer.Add(btnBox, 0, wx.ALL, 5) btnBox.Add(self.remove, 0, wx.ALL, 5)
self.SetSizer(sizer) sizer.Add(clientsBox, 0, wx.ALL, 5)
sizer.Add(btnBox, 0, wx.ALL, 5)
def append(self, client): self.SetSizer(sizer)
self.clients.Append(client)
def append(self, client):
def get_clients(self): self.clients.Append(client)
return self.clients.GetCount()
def get_clients(self):
def get_client_id(self): return self.clients.GetCount()
return self.clients.GetSelection()
def get_client_id(self):
def remove_(self, id): return self.clients.GetSelection()
self.clients.Delete(id)
def remove_(self, id):
class sound(wx.Panel): self.clients.Delete(id)
def __init__(self, parent, input_devices, output_devices, soundpacks):
wx.Panel.__init__(self, parent) class sound(wx.Panel):
sizer = wx.BoxSizer(wx.VERTICAL) def __init__(self, parent, input_devices, output_devices, soundpacks):
volume = wx.StaticText(self, -1, _(u"Volume")) wx.Panel.__init__(self, parent)
self.volumeCtrl = wx.Slider(self) sizer = wx.BoxSizer(wx.VERTICAL)
self.volumeCtrl.SetRange(0, 100) volume = wx.StaticText(self, -1, _(u"Volume"))
self.volumeCtrl.SetSize(self.volumeCtrl.GetBestSize()) self.volumeCtrl = wx.Slider(self)
volumeBox = wx.BoxSizer(wx.HORIZONTAL) self.volumeCtrl.SetRange(0, 100)
volumeBox.Add(volume, 0, wx.ALL, 5) self.volumeCtrl.SetSize(self.volumeCtrl.GetBestSize())
volumeBox.Add(self.volumeCtrl, 0, wx.ALL, 5) volumeBox = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(volumeBox, 0, wx.ALL, 5) volumeBox.Add(volume, 0, wx.ALL, 5)
self.session_mute = wx.CheckBox(self, -1, _(u"Session mute")) volumeBox.Add(self.volumeCtrl, 0, wx.ALL, 5)
sizer.Add(self.session_mute, 0, wx.ALL, 5) sizer.Add(volumeBox, 0, wx.ALL, 5)
output_label = wx.StaticText(self, -1, _(u"Output device")) self.session_mute = wx.CheckBox(self, -1, _(u"Session mute"))
self.output = wx.ComboBox(self, -1, choices=output_devices, style=wx.CB_READONLY) sizer.Add(self.session_mute, 0, wx.ALL, 5)
self.output.SetSize(self.output.GetBestSize()) output_label = wx.StaticText(self, -1, _(u"Output device"))
outputBox = wx.BoxSizer(wx.HORIZONTAL) self.output = wx.ComboBox(self, -1, choices=output_devices, style=wx.CB_READONLY)
outputBox.Add(output_label, 0, wx.ALL, 5) self.output.SetSize(self.output.GetBestSize())
outputBox.Add(self.output, 0, wx.ALL, 5) outputBox = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(outputBox, 0, wx.ALL, 5) outputBox.Add(output_label, 0, wx.ALL, 5)
input_label = wx.StaticText(self, -1, _(u"Input device")) outputBox.Add(self.output, 0, wx.ALL, 5)
self.input = wx.ComboBox(self, -1, choices=input_devices, style=wx.CB_READONLY) sizer.Add(outputBox, 0, wx.ALL, 5)
self.input.SetSize(self.input.GetBestSize()) input_label = wx.StaticText(self, -1, _(u"Input device"))
inputBox = wx.BoxSizer(wx.HORIZONTAL) self.input = wx.ComboBox(self, -1, choices=input_devices, style=wx.CB_READONLY)
inputBox.Add(input_label, 0, wx.ALL, 5) self.input.SetSize(self.input.GetBestSize())
inputBox.Add(self.input, 0, wx.ALL, 5) inputBox = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(inputBox, 0, wx.ALL, 5) inputBox.Add(input_label, 0, wx.ALL, 5)
soundBox = wx.BoxSizer(wx.VERTICAL) inputBox.Add(self.input, 0, wx.ALL, 5)
soundpack_label = wx.StaticText(self, -1, _(u"Sound pack")) sizer.Add(inputBox, 0, wx.ALL, 5)
self.soundpack = wx.ComboBox(self, -1, choices=soundpacks, style=wx.CB_READONLY) soundBox = wx.BoxSizer(wx.VERTICAL)
self.soundpack.SetSize(self.soundpack.GetBestSize()) soundpack_label = wx.StaticText(self, -1, _(u"Sound pack"))
soundBox.Add(soundpack_label, 0, wx.ALL, 5) self.soundpack = wx.ComboBox(self, -1, choices=soundpacks, style=wx.CB_READONLY)
soundBox.Add(self.soundpack, 0, wx.ALL, 5) self.soundpack.SetSize(self.soundpack.GetBestSize())
sizer.Add(soundBox, 0, wx.ALL, 5) soundBox.Add(soundpack_label, 0, wx.ALL, 5)
self.indicate_audio = wx.CheckBox(self, -1, _(u"Indicate audio tweets with sound")) soundBox.Add(self.soundpack, 0, wx.ALL, 5)
sizer.Add(self.indicate_audio, 0, wx.ALL, 5) sizer.Add(soundBox, 0, wx.ALL, 5)
self.indicate_geo = wx.CheckBox(self, -1, _(u"Indicate geotweets with sound")) self.indicate_audio = wx.CheckBox(self, -1, _(u"Indicate audio tweets with sound"))
sizer.Add(self.indicate_geo, 0, wx.ALL, 5) sizer.Add(self.indicate_audio, 0, wx.ALL, 5)
self.indicate_img = wx.CheckBox(self, -1, _(u"Indicate tweets containing images with sound")) self.indicate_geo = wx.CheckBox(self, -1, _(u"Indicate geotweets with sound"))
sizer.Add(self.indicate_img, 0, wx.ALL, 5) sizer.Add(self.indicate_geo, 0, wx.ALL, 5)
self.SetSizer(sizer) self.indicate_img = wx.CheckBox(self, -1, _(u"Indicate tweets containing images with sound"))
sizer.Add(self.indicate_img, 0, wx.ALL, 5)
def get(self, control): self.SetSizer(sizer)
return getattr(self, control).GetStringSelection()
def get(self, control):
class extrasPanel(wx.Panel): return getattr(self, control).GetStringSelection()
def __init__(self, parent, ocr_languages=[], translation_languages=[]):
super(extrasPanel, self).__init__(parent) class extrasPanel(wx.Panel):
mainSizer = wx.BoxSizer(wx.VERTICAL) def __init__(self, parent, ocr_languages=[], translation_languages=[]):
OCRBox = wx.StaticBox(self, label=_(u"Language for OCR")) super(extrasPanel, self).__init__(parent)
self.ocr_lang = wx.ListBox(self, -1, choices=ocr_languages) mainSizer = wx.BoxSizer(wx.VERTICAL)
self.ocr_lang.SetSize(self.ocr_lang.GetBestSize()) OCRBox = wx.StaticBox(self, label=_(u"Language for OCR"))
ocrLanguageSizer = wx.StaticBoxSizer(OCRBox, wx.HORIZONTAL) self.ocr_lang = wx.ListBox(self, -1, choices=ocr_languages)
ocrLanguageSizer.Add(self.ocr_lang, 0, wx.ALL, 5) self.ocr_lang.SetSize(self.ocr_lang.GetBestSize())
mainSizer.Add(ocrLanguageSizer, 0, wx.ALL, 5) ocrLanguageSizer = wx.StaticBoxSizer(OCRBox, wx.HORIZONTAL)
lbl = wx.StaticText(self, wx.NewId(), _(u"API Key for SndUp")) ocrLanguageSizer.Add(self.ocr_lang, 0, wx.ALL, 5)
self.sndup_apiKey = wx.TextCtrl(self, -1) mainSizer.Add(ocrLanguageSizer, 0, wx.ALL, 5)
sndupBox = wx.BoxSizer(wx.HORIZONTAL) lbl = wx.StaticText(self, wx.NewId(), _(u"API Key for SndUp"))
sndupBox.Add(lbl, 0, wx.ALL, 5) self.sndup_apiKey = wx.TextCtrl(self, -1)
sndupBox.Add(self.sndup_apiKey, 0, wx.ALL, 5) sndupBox = wx.BoxSizer(wx.HORIZONTAL)
mainSizer.Add(sndupBox, 0, wx.ALL, 5) sndupBox.Add(lbl, 0, wx.ALL, 5)
self.SetSizer(mainSizer) sndupBox.Add(self.sndup_apiKey, 0, wx.ALL, 5)
mainSizer.Add(sndupBox, 0, wx.ALL, 5)
class configurationDialog(baseDialog.BaseWXDialog): self.SetSizer(mainSizer)
def set_title(self, title):
self.SetTitle(title) class configurationDialog(baseDialog.BaseWXDialog):
def set_title(self, title):
def __init__(self): self.SetTitle(title)
super(configurationDialog, self).__init__(None, -1)
self.panel = wx.Panel(self) def __init__(self):
self.SetTitle(_(u"{0} preferences").format(application.name,)) super(configurationDialog, self).__init__(None, -1)
self.sizer = wx.BoxSizer(wx.VERTICAL) self.panel = wx.Panel(self)
self.notebook = wx.Notebook(self.panel) self.SetTitle(_(u"{0} preferences").format(application.name,))
self.sizer = wx.BoxSizer(wx.VERTICAL)
def create_general(self, languageList,keymaps): self.notebook = wx.Notebook(self.panel)
self.general = general(self.notebook, languageList,keymaps)
self.notebook.AddPage(self.general, _(u"General")) def create_general(self, languageList,keymaps):
self.general.SetFocus() self.general = general(self.notebook, languageList,keymaps)
self.notebook.AddPage(self.general, _(u"General"))
def create_proxy(self, proxyTypes): self.general.SetFocus()
self.proxy = proxy(self.notebook, proxyTypes)
self.notebook.AddPage(self.proxy, _(u"Proxy")) def create_proxy(self, proxyTypes):
self.proxy = proxy(self.notebook, proxyTypes)
def create_general_account(self): self.notebook.AddPage(self.proxy, _(u"Proxy"))
self.general = generalAccount(self.notebook)
self.notebook.AddPage(self.general, _(u"General")) def create_general_account(self):
self.general.SetFocus() self.general = generalAccount(self.notebook)
self.notebook.AddPage(self.general, _(u"General"))
def create_other_buffers(self): self.general.SetFocus()
self.buffers = other_buffers(self.notebook)
self.notebook.AddPage(self.buffers, _(u"Buffers")) def create_other_buffers(self):
self.buffers = other_buffers(self.notebook)
def create_ignored_clients(self, ignored_clients_list): self.notebook.AddPage(self.buffers, _(u"Buffers"))
self.ignored_clients = ignoredClients(self.notebook, ignored_clients_list)
self.notebook.AddPage(self.ignored_clients, _(u"Ignored clients")) def create_ignored_clients(self, ignored_clients_list):
self.ignored_clients = ignoredClients(self.notebook, ignored_clients_list)
def create_sound(self, output_devices, input_devices, soundpacks): self.notebook.AddPage(self.ignored_clients, _(u"Ignored clients"))
self.sound = sound(self.notebook, output_devices, input_devices, soundpacks)
self.notebook.AddPage(self.sound, _(u"Sound")) def create_sound(self, output_devices, input_devices, soundpacks):
self.sound = sound(self.notebook, output_devices, input_devices, soundpacks)
def create_extras(self, ocr_languages=[], translator_languages=[]): self.notebook.AddPage(self.sound, _(u"Sound"))
self.extras = extrasPanel(self.notebook, ocr_languages, translator_languages)
self.notebook.AddPage(self.extras, _(u"Extras")) def create_extras(self, ocr_languages=[], translator_languages=[]):
self.extras = extrasPanel(self.notebook, ocr_languages, translator_languages)
def realize(self): self.notebook.AddPage(self.extras, _(u"Extras"))
self.sizer.Add(self.notebook, 0, wx.ALL, 5)
ok_cancel_box = wx.BoxSizer(wx.HORIZONTAL) def realize(self):
ok = wx.Button(self.panel, wx.ID_OK, _(u"Save")) self.sizer.Add(self.notebook, 0, wx.ALL, 5)
ok.SetDefault() ok_cancel_box = wx.BoxSizer(wx.HORIZONTAL)
cancel = wx.Button(self.panel, wx.ID_CANCEL, _(u"Close")) ok = wx.Button(self.panel, wx.ID_OK, _(u"Save"))
self.SetEscapeId(cancel.GetId()) ok.SetDefault()
ok_cancel_box.Add(ok, 0, wx.ALL, 5) cancel = wx.Button(self.panel, wx.ID_CANCEL, _(u"Close"))
ok_cancel_box.Add(cancel, 0, wx.ALL, 5) self.SetEscapeId(cancel.GetId())
self.sizer.Add(ok_cancel_box, 0, wx.ALL, 5) ok_cancel_box.Add(ok, 0, wx.ALL, 5)
self.panel.SetSizer(self.sizer) ok_cancel_box.Add(cancel, 0, wx.ALL, 5)
self.SetClientSize(self.sizer.CalcMin()) self.sizer.Add(ok_cancel_box, 0, wx.ALL, 5)
self.panel.SetSizer(self.sizer)
def get_value(self, panel, key): self.SetClientSize(self.sizer.CalcMin())
p = getattr(self, panel)
return getattr(p, key).GetValue() def get_value(self, panel, key):
p = getattr(self, panel)
def set_value(self, panel, key, value): return getattr(p, key).GetValue()
p = getattr(self, panel)
control = getattr(p, key) def set_value(self, panel, key, value):
getattr(control, "SetValue")(value) p = getattr(self, panel)
control = getattr(p, key)
getattr(control, "SetValue")(value)

View File

@ -1,26 +1,28 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import baseDialog from __future__ import absolute_import
import wx # -*- coding: utf-8 -*-
from . import baseDialog
class findDialog(baseDialog.BaseWXDialog): import wx
def __init__(self, value=""):
super(findDialog, self).__init__(None, -1) class findDialog(baseDialog.BaseWXDialog):
panel = wx.Panel(self) def __init__(self, value=""):
sizer = wx.BoxSizer(wx.VERTICAL) super(findDialog, self).__init__(None, -1)
self.SetTitle(_(u"Find in current buffer")) panel = wx.Panel(self)
label = wx.StaticText(panel, -1, _(u"String")) sizer = wx.BoxSizer(wx.VERTICAL)
self.string = wx.TextCtrl(panel, -1, value) self.SetTitle(_(u"Find in current buffer"))
dc = wx.WindowDC(self.string) label = wx.StaticText(panel, -1, _(u"String"))
dc.SetFont(self.string.GetFont()) self.string = wx.TextCtrl(panel, -1, value)
self.string.SetSize(dc.GetTextExtent("0"*40)) dc = wx.WindowDC(self.string)
sizer.Add(label, 0, wx.ALL, 5) dc.SetFont(self.string.GetFont())
sizer.Add(self.string, 0, wx.ALL, 5) self.string.SetSize(dc.GetTextExtent("0"*40))
ok = wx.Button(panel, wx.ID_OK, _(u"OK")) sizer.Add(label, 0, wx.ALL, 5)
ok.SetDefault() sizer.Add(self.string, 0, wx.ALL, 5)
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"Cancel")) ok = wx.Button(panel, wx.ID_OK, _(u"OK"))
btnsizer = wx.BoxSizer() ok.SetDefault()
btnsizer.Add(ok, 0, wx.ALL, 5) cancel = wx.Button(panel, wx.ID_CANCEL, _(u"Cancel"))
btnsizer.Add(cancel, 0, wx.ALL, 5) btnsizer = wx.BoxSizer()
sizer.Add(btnsizer, 0, wx.ALL, 5) btnsizer.Add(ok, 0, wx.ALL, 5)
panel.SetSizer(sizer) btnsizer.Add(cancel, 0, wx.ALL, 5)
sizer.Add(btnsizer, 0, wx.ALL, 5)
panel.SetSizer(sizer)
self.SetClientSize(sizer.CalcMin()) self.SetClientSize(sizer.CalcMin())

View File

@ -1,68 +1,69 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import widgetUtils from __future__ import absolute_import
import baseDialog import widgetUtils
import wx from . import baseDialog
from extra import translator import wx
from extra import translator
class searchDialog(baseDialog.BaseWXDialog):
def __init__(self, value=""): class searchDialog(baseDialog.BaseWXDialog):
super(searchDialog, self).__init__(None, -1) def __init__(self, value=""):
panel = wx.Panel(self) super(searchDialog, self).__init__(None, -1)
sizer = wx.BoxSizer(wx.VERTICAL) panel = wx.Panel(self)
self.SetTitle(_(u"Search on Twitter")) sizer = wx.BoxSizer(wx.VERTICAL)
label = wx.StaticText(panel, -1, _(u"&Search")) self.SetTitle(_(u"Search on Twitter"))
self.term = wx.TextCtrl(panel, -1, value) label = wx.StaticText(panel, -1, _(u"&Search"))
dc = wx.WindowDC(self.term) self.term = wx.TextCtrl(panel, -1, value)
dc.SetFont(self.term.GetFont()) dc = wx.WindowDC(self.term)
self.term.SetSize(dc.GetTextExtent("0"*40)) dc.SetFont(self.term.GetFont())
sizer.Add(label, 0, wx.ALL, 5) self.term.SetSize(dc.GetTextExtent("0"*40))
sizer.Add(self.term, 0, wx.ALL, 5) sizer.Add(label, 0, wx.ALL, 5)
self.tweets = wx.RadioButton(panel, -1, _(u"Tweets"), style=wx.RB_GROUP) sizer.Add(self.term, 0, wx.ALL, 5)
self.users = wx.RadioButton(panel, -1, _(u"Users")) self.tweets = wx.RadioButton(panel, -1, _(u"Tweets"), style=wx.RB_GROUP)
widgetUtils.connect_event(self.tweets, widgetUtils.RADIOBUTTON, self.show_advanced_search) self.users = wx.RadioButton(panel, -1, _(u"Users"))
widgetUtils.connect_event(self.users, widgetUtils.RADIOBUTTON, self.hide_advanced_search) widgetUtils.connect_event(self.tweets, widgetUtils.RADIOBUTTON, self.show_advanced_search)
radioSizer = wx.BoxSizer(wx.HORIZONTAL) widgetUtils.connect_event(self.users, widgetUtils.RADIOBUTTON, self.hide_advanced_search)
radioSizer.Add(self.tweets, 0, wx.ALL, 5) radioSizer = wx.BoxSizer(wx.HORIZONTAL)
radioSizer.Add(self.users, 0, wx.ALL, 5) radioSizer.Add(self.tweets, 0, wx.ALL, 5)
sizer.Add(radioSizer, 0, wx.ALL, 5) radioSizer.Add(self.users, 0, wx.ALL, 5)
lang = wx.StaticText(panel, -1, _(u"&Language for results: ")) sizer.Add(radioSizer, 0, wx.ALL, 5)
langs = [x[1] for x in translator.translator.available_languages()] lang = wx.StaticText(panel, -1, _(u"&Language for results: "))
langs[:] = langs[1:] langs = [x[1] for x in translator.translator.available_languages()]
langs.insert(0, _(u"any")) langs[:] = langs[1:]
self.lang = wx.ComboBox(panel, -1, choices=langs, value=langs[0], style = wx.CB_READONLY) langs.insert(0, _(u"any"))
langBox = wx.BoxSizer(wx.HORIZONTAL) self.lang = wx.ComboBox(panel, -1, choices=langs, value=langs[0], style = wx.CB_READONLY)
langBox.Add(lang, 0, wx.ALL, 5) langBox = wx.BoxSizer(wx.HORIZONTAL)
langBox.Add(self.lang, 0, wx.ALL, 5) langBox.Add(lang, 0, wx.ALL, 5)
sizer.Add(langBox, 0, wx.ALL, 5) langBox.Add(self.lang, 0, wx.ALL, 5)
resulttype = wx.StaticText(panel, -1, _(U"Results &type: ")) sizer.Add(langBox, 0, wx.ALL, 5)
self.resultstype = wx.ComboBox(panel, -1, choices=[_(u"Mixed"), _(u"Recent"), _(u"Popular")], value=_(u"Mixed"), style=wx.CB_READONLY) resulttype = wx.StaticText(panel, -1, _(U"Results &type: "))
rBox = wx.BoxSizer(wx.HORIZONTAL) self.resultstype = wx.ComboBox(panel, -1, choices=[_(u"Mixed"), _(u"Recent"), _(u"Popular")], value=_(u"Mixed"), style=wx.CB_READONLY)
rBox.Add(resulttype, 0, wx.ALL, 5) rBox = wx.BoxSizer(wx.HORIZONTAL)
rBox.Add(self.resultstype, 0, wx.ALL, 5) rBox.Add(resulttype, 0, wx.ALL, 5)
sizer.Add(rBox, 0, wx.ALL, 5) rBox.Add(self.resultstype, 0, wx.ALL, 5)
ok = wx.Button(panel, wx.ID_OK, _(u"&OK")) sizer.Add(rBox, 0, wx.ALL, 5)
ok.SetDefault() ok = wx.Button(panel, wx.ID_OK, _(u"&OK"))
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"&Close")) ok.SetDefault()
btnsizer = wx.BoxSizer() cancel = wx.Button(panel, wx.ID_CANCEL, _(u"&Close"))
btnsizer.Add(ok, 0, wx.ALL, 5) btnsizer = wx.BoxSizer()
btnsizer.Add(cancel, 0, wx.ALL, 5) btnsizer.Add(ok, 0, wx.ALL, 5)
sizer.Add(btnsizer, 0, wx.ALL, 5) btnsizer.Add(cancel, 0, wx.ALL, 5)
panel.SetSizer(sizer) sizer.Add(btnsizer, 0, wx.ALL, 5)
self.SetClientSize(sizer.CalcMin()) panel.SetSizer(sizer)
self.SetClientSize(sizer.CalcMin())
def get_language(self):
return [x[0] for x in translator.translator.available_languages()][self.lang.GetSelection()] def get_language(self):
return [x[0] for x in translator.translator.available_languages()][self.lang.GetSelection()]
def get_result_type(self):
r = self.resultstype.GetValue() def get_result_type(self):
if r == _(u"Mixed"): return "mixed" r = self.resultstype.GetValue()
elif r == _(u"Recent"): return "recent" if r == _(u"Mixed"): return "mixed"
elif r == _(u"Popular"): return "popular" elif r == _(u"Recent"): return "recent"
elif r == _(u"Popular"): return "popular"
def hide_advanced_search(self, *args, **kwargs):
self.lang.Hide() def hide_advanced_search(self, *args, **kwargs):
self.resultstype.Hide() self.lang.Hide()
self.resultstype.Hide()
def show_advanced_search(self, *args, **kwargs):
self.lang.Show() def show_advanced_search(self, *args, **kwargs):
self.resultstype.Show() self.lang.Show()
self.resultstype.Show()

View File

@ -1,26 +1,27 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import wx from __future__ import absolute_import
import baseDialog import wx
from . import baseDialog
class showUserProfile(baseDialog.BaseWXDialog):
def __init__(self): class showUserProfile(baseDialog.BaseWXDialog):
super(showUserProfile, self).__init__(parent=None, id=wx.NewId()) def __init__(self):
panel = wx.Panel(self) super(showUserProfile, self).__init__(parent=None, id=wx.NewId())
sizer = wx.BoxSizer(wx.VERTICAL) panel = wx.Panel(self)
static = wx.StaticText(panel, -1, _(u"Details")) sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(static, 0, wx.ALL, 5) static = wx.StaticText(panel, -1, _(u"Details"))
self.text = wx.TextCtrl(panel, -1, style=wx.TE_MULTILINE|wx.TE_READONLY, size=(350, 250)) sizer.Add(static, 0, wx.ALL, 5)
self.text.SetFocus() self.text = wx.TextCtrl(panel, -1, style=wx.TE_MULTILINE|wx.TE_READONLY, size=(350, 250))
sizer.Add(self.text, 0, wx.ALL|wx.EXPAND, 5) self.text.SetFocus()
self.url = wx.Button(panel, -1, _(u"&Go to URL"), size=wx.DefaultSize) sizer.Add(self.text, 0, wx.ALL|wx.EXPAND, 5)
self.url.Disable() self.url = wx.Button(panel, -1, _(u"&Go to URL"), size=wx.DefaultSize)
close = wx.Button(panel, wx.ID_CANCEL, _(u"&Close")) self.url.Disable()
btnSizer = wx.BoxSizer(wx.HORIZONTAL) close = wx.Button(panel, wx.ID_CANCEL, _(u"&Close"))
btnSizer.Add(self.url, 0, wx.ALL, 5) btnSizer = wx.BoxSizer(wx.HORIZONTAL)
btnSizer.Add(close, 0, wx.ALL, 5) btnSizer.Add(self.url, 0, wx.ALL, 5)
sizer.Add(btnSizer, 0, wx.ALL, 5) btnSizer.Add(close, 0, wx.ALL, 5)
panel.SetSizer(sizer) sizer.Add(btnSizer, 0, wx.ALL, 5)
self.SetClientSize(sizer.CalcMin()) panel.SetSizer(sizer)
self.SetClientSize(sizer.CalcMin())
def enable_url(self, enabled=True):
def enable_url(self, enabled=True):
self.url.Enable(enabled) self.url.Enable(enabled)

View File

@ -1,46 +1,48 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import baseDialog from __future__ import absolute_import
import wx # -*- coding: utf-8 -*-
from . import baseDialog
class trendingTopicsDialog(baseDialog.BaseWXDialog): import wx
def __init__(self):
super(trendingTopicsDialog, self).__init__(None, -1) class trendingTopicsDialog(baseDialog.BaseWXDialog):
panel = wx.Panel(self) def __init__(self):
sizer = wx.BoxSizer(wx.VERTICAL) super(trendingTopicsDialog, self).__init__(None, -1)
self.SetTitle(_(u"View trending topics")) panel = wx.Panel(self)
label = wx.StaticText(panel, -1, _(u"Trending topics by")) sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(label, 0, wx.ALL, 5) self.SetTitle(_(u"View trending topics"))
self.country = wx.RadioButton(panel, -1, _(u"Country"), style=wx.RB_GROUP) label = wx.StaticText(panel, -1, _(u"Trending topics by"))
self.city = wx.RadioButton(panel, -1, _(u"City")) sizer.Add(label, 0, wx.ALL, 5)
radioSizer = wx.BoxSizer(wx.HORIZONTAL) self.country = wx.RadioButton(panel, -1, _(u"Country"), style=wx.RB_GROUP)
radioSizer.Add(label, 0, wx.ALL, 5) self.city = wx.RadioButton(panel, -1, _(u"City"))
radioSizer.Add(self.country, 0, wx.ALL, 5) radioSizer = wx.BoxSizer(wx.HORIZONTAL)
radioSizer.Add(self.city, 0, wx.ALL, 5) radioSizer.Add(label, 0, wx.ALL, 5)
sizer.Add(radioSizer, 0, wx.ALL, 5) radioSizer.Add(self.country, 0, wx.ALL, 5)
label = wx.StaticText(panel, -1, _(u"&Location")) radioSizer.Add(self.city, 0, wx.ALL, 5)
self.location = wx.ListBox(panel, -1, choices=[], style=wx.CB_READONLY) sizer.Add(radioSizer, 0, wx.ALL, 5)
locationBox = wx.BoxSizer(wx.HORIZONTAL) label = wx.StaticText(panel, -1, _(u"&Location"))
locationBox.Add(label, 0, wx.ALL, 5) self.location = wx.ListBox(panel, -1, choices=[], style=wx.CB_READONLY)
locationBox.Add(self.location, 0, wx.ALL, 5) locationBox = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(locationBox, 0, wx.ALL, 5) locationBox.Add(label, 0, wx.ALL, 5)
ok = wx.Button(panel, wx.ID_OK, _(u"&OK")) locationBox.Add(self.location, 0, wx.ALL, 5)
ok.SetDefault() sizer.Add(locationBox, 0, wx.ALL, 5)
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"&Close")) ok = wx.Button(panel, wx.ID_OK, _(u"&OK"))
btnsizer = wx.BoxSizer() ok.SetDefault()
btnsizer.Add(ok, 0, wx.ALL, 5) cancel = wx.Button(panel, wx.ID_CANCEL, _(u"&Close"))
btnsizer.Add(cancel, 0, wx.ALL, 5) btnsizer = wx.BoxSizer()
sizer.Add(btnsizer, 0, wx.ALL, 5) btnsizer.Add(ok, 0, wx.ALL, 5)
panel.SetSizer(sizer) btnsizer.Add(cancel, 0, wx.ALL, 5)
self.SetClientSize(sizer.CalcMin()) sizer.Add(btnsizer, 0, wx.ALL, 5)
panel.SetSizer(sizer)
def get_active(self): self.SetClientSize(sizer.CalcMin())
if self.country.GetValue() == True:
return "country" def get_active(self):
else: if self.country.GetValue() == True:
return "city" return "country"
else:
def get_item(self): return "city"
return self.location.GetStringSelection()
def get_item(self):
def set(self, values): return self.location.GetStringSelection()
def set(self, values):
self.location.Set(values) self.location.Set(values)

View File

@ -1,98 +1,99 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import wx from __future__ import absolute_import
import baseDialog import wx
from . import baseDialog
class updateProfileDialog(baseDialog.BaseWXDialog):
def __init__(self): class updateProfileDialog(baseDialog.BaseWXDialog):
super(updateProfileDialog, self).__init__(parent=None, id=-1) def __init__(self):
self.SetTitle(_(u"Update your profile")) super(updateProfileDialog, self).__init__(parent=None, id=-1)
panel = wx.Panel(self) self.SetTitle(_(u"Update your profile"))
labelName = wx.StaticText(panel, -1, _(u"&Name (20 characters maximum)")) panel = wx.Panel(self)
self.name = wx.TextCtrl(panel, -1) labelName = wx.StaticText(panel, -1, _(u"&Name (20 characters maximum)"))
self.name.SetFocus() self.name = wx.TextCtrl(panel, -1)
dc = wx.WindowDC(self.name) self.name.SetFocus()
dc.SetFont(self.name.GetFont()) dc = wx.WindowDC(self.name)
self.name.SetSize(dc.GetTextExtent("0"*20)) dc.SetFont(self.name.GetFont())
labelLocation = wx.StaticText(panel, -1, _(u"&Location")) self.name.SetSize(dc.GetTextExtent("0"*20))
self.location = wx.TextCtrl(panel, -1) labelLocation = wx.StaticText(panel, -1, _(u"&Location"))
dc = wx.WindowDC(self.location) self.location = wx.TextCtrl(panel, -1)
dc.SetFont(self.location.GetFont()) dc = wx.WindowDC(self.location)
self.location.SetSize(dc.GetTextExtent("0"*35)) dc.SetFont(self.location.GetFont())
labelUrl = wx.StaticText(panel, -1, _(u"&Website")) self.location.SetSize(dc.GetTextExtent("0"*35))
self.url = wx.TextCtrl(panel, -1) labelUrl = wx.StaticText(panel, -1, _(u"&Website"))
dc = wx.WindowDC(self.url) self.url = wx.TextCtrl(panel, -1)
dc.SetFont(self.url.GetFont()) dc = wx.WindowDC(self.url)
self.url.SetSize(dc.GetTextExtent("0"*22)) dc.SetFont(self.url.GetFont())
labelDescription = wx.StaticText(panel, -1, _(u"&Bio (160 characters maximum)")) self.url.SetSize(dc.GetTextExtent("0"*22))
self.description = wx.TextCtrl(panel, -1, size=(400, 400)) labelDescription = wx.StaticText(panel, -1, _(u"&Bio (160 characters maximum)"))
dc = wx.WindowDC(self.description) self.description = wx.TextCtrl(panel, -1, size=(400, 400))
dc.SetFont(self.description.GetFont()) dc = wx.WindowDC(self.description)
self.description.SetSize(dc.GetTextExtent("0"*160)) dc.SetFont(self.description.GetFont())
self.image = None self.description.SetSize(dc.GetTextExtent("0"*160))
self.upload_image = wx.Button(panel, -1, _(u"Upload a &picture")) self.image = None
self.ok = wx.Button(panel, wx.ID_OK, _(u"&Update profile")) self.upload_image = wx.Button(panel, -1, _(u"Upload a &picture"))
self.ok.SetDefault() self.ok = wx.Button(panel, wx.ID_OK, _(u"&Update profile"))
close = wx.Button(panel, wx.ID_CANCEL, _("&Close")) self.ok.SetDefault()
sizer = wx.BoxSizer(wx.VERTICAL) close = wx.Button(panel, wx.ID_CANCEL, _("&Close"))
nameBox = wx.BoxSizer(wx.HORIZONTAL) sizer = wx.BoxSizer(wx.VERTICAL)
nameBox.Add(labelName, 0, wx.ALL, 5) nameBox = wx.BoxSizer(wx.HORIZONTAL)
nameBox.Add(self.name, 0, wx.ALL, 5) nameBox.Add(labelName, 0, wx.ALL, 5)
sizer.Add(nameBox, 0, wx.ALL, 5) nameBox.Add(self.name, 0, wx.ALL, 5)
locationBox = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(nameBox, 0, wx.ALL, 5)
locationBox.Add(labelLocation, 0, wx.ALL, 5) locationBox = wx.BoxSizer(wx.HORIZONTAL)
locationBox.Add(self.location, 0, wx.ALL, 5) locationBox.Add(labelLocation, 0, wx.ALL, 5)
sizer.Add(locationBox, 0, wx.ALL, 5) locationBox.Add(self.location, 0, wx.ALL, 5)
urlBox = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(locationBox, 0, wx.ALL, 5)
urlBox.Add(labelUrl, 0, wx.ALL, 5) urlBox = wx.BoxSizer(wx.HORIZONTAL)
urlBox.Add(self.url, 0, wx.ALL, 5) urlBox.Add(labelUrl, 0, wx.ALL, 5)
sizer.Add(urlBox, 0, wx.ALL, 5) urlBox.Add(self.url, 0, wx.ALL, 5)
descriptionBox = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(urlBox, 0, wx.ALL, 5)
descriptionBox.Add(labelDescription, 0, wx.ALL, 5) descriptionBox = wx.BoxSizer(wx.HORIZONTAL)
descriptionBox.Add(self.description, 0, wx.ALL, 5) descriptionBox.Add(labelDescription, 0, wx.ALL, 5)
sizer.Add(descriptionBox, 0, wx.ALL, 5) descriptionBox.Add(self.description, 0, wx.ALL, 5)
sizer.Add(self.upload_image, 5, wx.CENTER, 5) sizer.Add(descriptionBox, 0, wx.ALL, 5)
btnBox = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(self.upload_image, 5, wx.CENTER, 5)
btnBox.Add(self.ok, 0, wx.ALL, 5) btnBox = wx.BoxSizer(wx.HORIZONTAL)
btnBox.Add(close, 0, wx.ALL, 5) btnBox.Add(self.ok, 0, wx.ALL, 5)
sizer.Add(btnBox, 0, wx.ALL, 5) btnBox.Add(close, 0, wx.ALL, 5)
panel.SetSizer(sizer) sizer.Add(btnBox, 0, wx.ALL, 5)
self.SetClientSize(sizer.CalcMin()) panel.SetSizer(sizer)
self.SetClientSize(sizer.CalcMin())
def set_name(self, name):
self.set("name", name) def set_name(self, name):
self.set("name", name)
def set_description(self, description):
self.set("description", description) def set_description(self, description):
self.set("description", description)
def set_location(self, location):
self.set("location", location) def set_location(self, location):
self.set("location", location)
def set_url(self, url):
self.set("url", url) def set_url(self, url):
self.set("url", url)
def change_upload_button(self, uploaded=False):
if uploaded == False: def change_upload_button(self, uploaded=False):
self.upload_image.SetLabel(_(u"Upload a picture")) if uploaded == False:
else: self.upload_image.SetLabel(_(u"Upload a picture"))
self.upload_image.SetLabel(_(u"Discard image")) else:
self.upload_image.SetLabel(_(u"Discard image"))
def upload_picture(self):
openFileDialog = wx.FileDialog(self, _(u"Select the picture to be uploaded"), "", "", _("Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) def upload_picture(self):
if openFileDialog.ShowModal() == wx.ID_CANCEL: openFileDialog = wx.FileDialog(self, _(u"Select the picture to be uploaded"), "", "", _("Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
return None if openFileDialog.ShowModal() == wx.ID_CANCEL:
return openFileDialog.GetPath() return None
return openFileDialog.GetPath()
def hide_upload_button(self, hide):
self.upload_image.Enable(hide) def hide_upload_button(self, hide):
self.upload_image.Enable(hide)
def set_readonly(self):
self.name.style = wx.TE_READONLY def set_readonly(self):
self.name.Refresh() self.name.style = wx.TE_READONLY
self.description.style = wx.TE_READONLY self.name.Refresh()
self.description.Refresh() self.description.style = wx.TE_READONLY
self.location.style = wx.TE_READONLY self.description.Refresh()
self.location.Refresh() self.location.style = wx.TE_READONLY
self.url.style = wx.TE_READONLY self.location.Refresh()
self.url.Refresh() self.url.style = wx.TE_READONLY
self.hide_upload_button(False) self.url.Refresh()
self.hide_upload_button(False)
self.ok.Enable(False) self.ok.Enable(False)

View File

@ -1,48 +1,49 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
############################################################ ############################################################
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net> # Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or # the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
############################################################ ############################################################
import wx from __future__ import absolute_import
import baseDialog import wx
from . import baseDialog
class selectUserDialog(baseDialog.BaseWXDialog):
def __init__(self, title, users): class selectUserDialog(baseDialog.BaseWXDialog):
super(selectUserDialog, self).__init__(parent=None, id=wx.NewId(), title=title) def __init__(self, title, users):
panel = wx.Panel(self) super(selectUserDialog, self).__init__(parent=None, id=wx.NewId(), title=title)
userSizer = wx.BoxSizer() panel = wx.Panel(self)
self.cb = wx.ComboBox(panel, -1, choices=users, value=users[0], size=wx.DefaultSize) userSizer = wx.BoxSizer()
self.cb.SetFocus() self.cb = wx.ComboBox(panel, -1, choices=users, value=users[0], size=wx.DefaultSize)
self.autocompletion = wx.Button(panel, -1, _(u"&Autocomplete users")) self.cb.SetFocus()
userSizer.Add(wx.StaticText(panel, -1, _(u"User")), 0, wx.ALL, 5) self.autocompletion = wx.Button(panel, -1, _(u"&Autocomplete users"))
userSizer.Add(self.cb, 0, wx.ALL, 5) userSizer.Add(wx.StaticText(panel, -1, _(u"User")), 0, wx.ALL, 5)
userSizer.Add(self.autocompletion, 0, wx.ALL, 5) userSizer.Add(self.cb, 0, wx.ALL, 5)
sizer = wx.BoxSizer(wx.VERTICAL) userSizer.Add(self.autocompletion, 0, wx.ALL, 5)
ok = wx.Button(panel, wx.ID_OK, _(u"OK")) sizer = wx.BoxSizer(wx.VERTICAL)
ok.SetDefault() ok = wx.Button(panel, wx.ID_OK, _(u"OK"))
# ok.Bind(wx.EVT_BUTTON, self.onok) ok.SetDefault()
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"Close")) # ok.Bind(wx.EVT_BUTTON, self.onok)
btnsizer = wx.BoxSizer() cancel = wx.Button(panel, wx.ID_CANCEL, _(u"Close"))
btnsizer.Add(ok, 0, wx.ALL, 5) btnsizer = wx.BoxSizer()
btnsizer.Add(cancel, 0, wx.ALL, 5) btnsizer.Add(ok, 0, wx.ALL, 5)
sizer.Add(userSizer, 0, wx.ALL, 5) btnsizer.Add(cancel, 0, wx.ALL, 5)
sizer.Add(btnsizer, 0, wx.ALL, 5) sizer.Add(userSizer, 0, wx.ALL, 5)
panel.SetSizer(sizer) sizer.Add(btnsizer, 0, wx.ALL, 5)
self.SetClientSize(sizer.CalcMin()) panel.SetSizer(sizer)
self.SetClientSize(sizer.CalcMin())
def get_user(self):
return self.cb.GetValue() def get_user(self):
return self.cb.GetValue()