2014-11-12 20:41:29 -06:00
|
|
|
# -*- coding: utf-8 -*-
|
2016-01-09 00:45:52 -06:00
|
|
|
import re
|
2015-04-03 16:57:08 -06:00
|
|
|
import platform
|
2016-07-15 12:29:48 -05:00
|
|
|
import attach
|
2015-04-03 16:57:08 -06:00
|
|
|
system = platform.system()
|
2014-11-12 20:41:29 -06:00
|
|
|
import widgetUtils
|
2014-11-12 22:37:52 -06:00
|
|
|
import output
|
2014-11-15 19:40:19 -06:00
|
|
|
import url_shortener
|
|
|
|
import sound
|
2014-12-29 20:58:30 -06:00
|
|
|
from pubsub import pub
|
2015-04-03 16:57:08 -06:00
|
|
|
if system == "Windows":
|
|
|
|
from wxUI.dialogs import message, urlList
|
|
|
|
from extra import translator, SpellChecker, autocompletionUsers
|
|
|
|
from extra.AudioUploader import audioUploader
|
|
|
|
elif system == "Linux":
|
|
|
|
from gtkUI.dialogs import message
|
2014-11-15 19:40:19 -06:00
|
|
|
from twitter import utils
|
2014-11-12 20:41:29 -06:00
|
|
|
|
2014-12-31 00:07:27 -06:00
|
|
|
class basicTweet(object):
|
|
|
|
""" This class handles the tweet main features. Other classes should derive from this class."""
|
2016-12-09 10:15:39 -06:00
|
|
|
def __init__(self, session, title, caption, text, messageType="tweet", max=140, *args, **kwargs):
|
2014-12-31 00:07:27 -06:00
|
|
|
super(basicTweet, self).__init__()
|
2015-04-08 13:34:50 -05:00
|
|
|
self.max = max
|
2015-01-02 09:38:44 -06:00
|
|
|
self.title = title
|
2014-12-29 20:58:30 -06:00
|
|
|
self.session = session
|
2016-12-09 10:15:39 -06:00
|
|
|
self.message = getattr(message, messageType)(title, caption, text, *args, **kwargs)
|
2014-11-16 22:30:58 -06:00
|
|
|
widgetUtils.connect_event(self.message.spellcheck, widgetUtils.BUTTON_PRESSED, self.spellcheck)
|
2014-12-29 20:58:30 -06:00
|
|
|
widgetUtils.connect_event(self.message.attach, widgetUtils.BUTTON_PRESSED, self.attach)
|
2015-04-03 16:57:08 -06:00
|
|
|
# if system == "Windows":
|
2015-08-12 15:57:29 -05:00
|
|
|
# if messageType != "dm":
|
2014-11-15 19:40:19 -06:00
|
|
|
widgetUtils.connect_event(self.message.text, widgetUtils.ENTERED_TEXT, self.text_processor)
|
|
|
|
widgetUtils.connect_event(self.message.shortenButton, widgetUtils.BUTTON_PRESSED, self.shorten)
|
|
|
|
widgetUtils.connect_event(self.message.unshortenButton, widgetUtils.BUTTON_PRESSED, self.unshorten)
|
2014-11-12 22:37:52 -06:00
|
|
|
widgetUtils.connect_event(self.message.translateButton, widgetUtils.BUTTON_PRESSED, self.translate)
|
2016-07-28 12:45:06 -05:00
|
|
|
if hasattr(self.message, "long_tweet"):
|
|
|
|
widgetUtils.connect_event(self.message.long_tweet, widgetUtils.CHECKBOX, self.text_processor)
|
2016-07-15 12:29:48 -05:00
|
|
|
self.attachments = []
|
2014-11-12 22:37:52 -06:00
|
|
|
|
|
|
|
def translate(self, event=None):
|
|
|
|
dlg = translator.gui.translateDialog()
|
|
|
|
if dlg.get_response() == widgetUtils.OK:
|
2015-12-23 09:48:50 -06:00
|
|
|
text_to_translate = self.message.get_text()
|
2014-11-12 22:37:52 -06:00
|
|
|
source = [x[0] for x in translator.translator.available_languages()][dlg.get("source_lang")]
|
|
|
|
dest = [x[0] for x in translator.translator.available_languages()][dlg.get("dest_lang")]
|
2015-11-03 04:40:05 -06:00
|
|
|
msg = translator.translator.translate(text=text_to_translate, source=source, target=dest)
|
2014-11-12 22:37:52 -06:00
|
|
|
self.message.set_text(msg)
|
2016-07-28 05:35:28 -05:00
|
|
|
self.text_processor()
|
2015-02-12 13:10:42 -06:00
|
|
|
self.message.text_focus()
|
2014-11-12 22:37:52 -06:00
|
|
|
output.speak(_(u"Translated"))
|
|
|
|
else:
|
|
|
|
return
|
2014-11-15 19:40:19 -06:00
|
|
|
|
|
|
|
def shorten(self, event=None):
|
|
|
|
urls = utils.find_urls_in_text(self.message.get_text())
|
|
|
|
if len(urls) == 0:
|
|
|
|
output.speak(_(u"There's no URL to be shortened"))
|
2015-02-12 13:10:42 -06:00
|
|
|
self.message.text_focus()
|
2014-11-15 19:40:19 -06:00
|
|
|
elif len(urls) == 1:
|
|
|
|
self.message.set_text(self.message.get_text().replace(urls[0], url_shortener.shorten(urls[0])))
|
|
|
|
output.speak(_(u"URL shortened"))
|
2016-07-28 05:35:28 -05:00
|
|
|
self.text_processor()
|
2015-02-12 13:10:42 -06:00
|
|
|
self.message.text_focus()
|
2014-11-15 19:40:19 -06:00
|
|
|
elif len(urls) > 1:
|
|
|
|
list_urls = urlList.urlList()
|
|
|
|
list_urls.populate_list(urls)
|
|
|
|
if list_urls.get_response() == widgetUtils.OK:
|
|
|
|
self.message.set_text(self.message.get_text().replace(urls[list_urls.get_item()], url_shortener.shorten(list_urls.get_string())))
|
|
|
|
output.speak(_(u"URL shortened"))
|
2016-07-28 05:35:28 -05:00
|
|
|
self.text_processor()
|
2015-02-12 13:10:42 -06:00
|
|
|
self.message.text_focus()
|
2014-11-15 19:40:19 -06:00
|
|
|
|
|
|
|
def unshorten(self, event=None):
|
|
|
|
urls = utils.find_urls_in_text(self.message.get_text())
|
|
|
|
if len(urls) == 0:
|
2015-03-15 18:24:15 -06:00
|
|
|
output.speak(_(u"There's no URL to be expanded"))
|
2015-02-12 13:10:42 -06:00
|
|
|
self.message.text_focus()
|
2014-11-15 19:40:19 -06:00
|
|
|
elif len(urls) == 1:
|
|
|
|
self.message.set_text(self.message.get_text().replace(urls[0], url_shortener.unshorten(urls[0])))
|
|
|
|
output.speak(_(u"URL expanded"))
|
2016-07-28 05:35:28 -05:00
|
|
|
self.text_processor()
|
2015-02-12 13:10:42 -06:00
|
|
|
self.message.text_focus()
|
2014-11-15 19:40:19 -06:00
|
|
|
elif len(urls) > 1:
|
|
|
|
list_urls = urlList.urlList()
|
|
|
|
list_urls.populate_list(urls)
|
|
|
|
if list_urls.get_response() == widgetUtils.OK:
|
|
|
|
self.message.set_text(self.message.get_text().replace(urls[list_urls.get_item()], url_shortener.unshorten(list_urls.get_string())))
|
|
|
|
output.speak(_(u"URL expanded"))
|
2016-07-28 05:35:28 -05:00
|
|
|
self.text_processor()
|
2015-02-12 13:10:42 -06:00
|
|
|
self.message.text_focus()
|
2014-11-15 19:40:19 -06:00
|
|
|
|
2015-01-02 09:38:44 -06:00
|
|
|
def text_processor(self, *args, **kwargs):
|
2014-11-15 19:40:19 -06:00
|
|
|
if len(self.message.get_text()) > 1:
|
|
|
|
self.message.enable_button("shortenButton")
|
|
|
|
self.message.enable_button("unshortenButton")
|
|
|
|
else:
|
|
|
|
self.message.disable_button("shortenButton")
|
|
|
|
self.message.disable_button("unshortenButton")
|
2015-07-13 05:47:26 -05:00
|
|
|
if self.message.get("long_tweet") == False:
|
|
|
|
self.message.set_title(_(u"%s - %s of %d characters") % (self.title, len(self.message.get_text()), self.max))
|
|
|
|
if len(self.message.get_text()) > self.max:
|
|
|
|
self.session.sound.play("max_length.ogg")
|
|
|
|
else:
|
|
|
|
self.message.set_title(_(u"%s - %s characters") % (self.title, len(self.message.get_text())))
|
2014-11-16 22:30:58 -06:00
|
|
|
|
|
|
|
def spellcheck(self, event=None):
|
|
|
|
text = self.message.get_text()
|
|
|
|
checker = SpellChecker.spellchecker.spellChecker(text, "")
|
|
|
|
if hasattr(checker, "fixed_text"):
|
2014-12-29 20:58:30 -06:00
|
|
|
self.message.set_text(checker.fixed_text)
|
2016-07-28 05:35:28 -05:00
|
|
|
self.text_processor()
|
2015-08-24 10:00:34 -05:00
|
|
|
self.message.text_focus()
|
2014-12-29 20:58:30 -06:00
|
|
|
|
|
|
|
def attach(self, *args, **kwargs):
|
2016-04-30 06:16:16 -05:00
|
|
|
def completed_callback(dlg):
|
2014-12-29 20:58:30 -06:00
|
|
|
url = dlg.uploaderFunction.get_url()
|
|
|
|
pub.unsubscribe(dlg.uploaderDialog.update, "uploading")
|
|
|
|
dlg.uploaderDialog.destroy()
|
|
|
|
if url != 0:
|
|
|
|
self.message.set_text(self.message.get_text()+url+" #audio")
|
2016-07-28 05:35:28 -05:00
|
|
|
self.text_processor()
|
2014-12-29 20:58:30 -06:00
|
|
|
else:
|
|
|
|
output.speak(_(u"Unable to upload the audio"))
|
|
|
|
dlg.cleanup()
|
|
|
|
dlg = audioUploader.audioUploader(self.session.settings, completed_callback)
|
2015-08-24 10:00:34 -05:00
|
|
|
self.message.text_focus()
|
2014-12-31 00:07:27 -06:00
|
|
|
|
|
|
|
class tweet(basicTweet):
|
2016-12-09 10:15:39 -06:00
|
|
|
def __init__(self, session, title, caption, text, twishort_enabled, messageType="tweet", max=140, *args, **kwargs):
|
|
|
|
super(tweet, self).__init__(session, title, caption, text, messageType, max, *args, **kwargs)
|
2014-12-31 00:07:27 -06:00
|
|
|
self.image = None
|
|
|
|
widgetUtils.connect_event(self.message.upload_image, widgetUtils.BUTTON_PRESSED, self.upload_image)
|
2015-01-27 17:09:28 -06:00
|
|
|
widgetUtils.connect_event(self.message.autocompletionButton, widgetUtils.BUTTON_PRESSED, self.autocomplete_users)
|
2015-07-29 14:47:14 -05:00
|
|
|
if twishort_enabled == False:
|
2015-07-30 11:19:20 -05:00
|
|
|
try: self.message.long_tweet.SetValue(False)
|
|
|
|
except AttributeError: pass
|
2016-07-28 12:45:06 -05:00
|
|
|
self.text_processor()
|
2014-12-31 00:07:27 -06:00
|
|
|
|
|
|
|
def upload_image(self, *args, **kwargs):
|
2016-07-15 12:29:48 -05:00
|
|
|
a = attach.attach()
|
|
|
|
if len(a.attachments) != 0:
|
|
|
|
self.attachments = a.attachments
|
2015-01-02 09:38:44 -06:00
|
|
|
|
2015-01-27 17:09:28 -06:00
|
|
|
def autocomplete_users(self, *args, **kwargs):
|
|
|
|
c = autocompletionUsers.completion.autocompletionUsers(self.message, self.session.session_id)
|
|
|
|
c.show_menu()
|
|
|
|
|
2015-01-02 09:38:44 -06:00
|
|
|
class reply(tweet):
|
2016-12-09 10:15:39 -06:00
|
|
|
def __init__(self, session, title, caption, text, twishort_enabled, users=[], ids=[]):
|
|
|
|
super(reply, self).__init__(session, title, caption, text, twishort_enabled, messageType="reply", users=users)
|
2017-03-25 07:54:28 -06:00
|
|
|
self.ids = ids
|
|
|
|
self.users = users
|
2016-12-09 10:15:39 -06:00
|
|
|
if len(users) > 0:
|
|
|
|
widgetUtils.connect_event(self.message.mentionAll, widgetUtils.CHECKBOX, self.mention_all)
|
2015-01-02 09:38:44 -06:00
|
|
|
self.message.enable_button("mentionAll")
|
2016-10-04 03:55:36 -05:00
|
|
|
self.message.mentionAll.SetValue(self.session.settings["mysc"]["mention_all"])
|
2016-12-09 10:15:39 -06:00
|
|
|
if self.message.mentionAll.GetValue() == True:
|
|
|
|
self.mention_all()
|
2015-01-02 09:38:44 -06:00
|
|
|
self.message.set_cursor_at_end()
|
2016-07-28 12:45:06 -05:00
|
|
|
self.text_processor()
|
2015-01-02 09:38:44 -06:00
|
|
|
|
|
|
|
def mention_all(self, *args, **kwargs):
|
2016-12-09 10:15:39 -06:00
|
|
|
if self.message.mentionAll.GetValue() == True:
|
|
|
|
for i in self.message.checkboxes:
|
|
|
|
i.SetValue(True)
|
|
|
|
i.Hide()
|
|
|
|
else:
|
|
|
|
for i in self.message.checkboxes:
|
|
|
|
i.SetValue(False)
|
|
|
|
i.Show()
|
|
|
|
|
|
|
|
|
|
|
|
def get_ids(self):
|
|
|
|
excluded_ids = ""
|
|
|
|
for i in xrange(0, len(self.message.checkboxes)):
|
|
|
|
if self.message.checkboxes[i].GetValue() == False:
|
|
|
|
excluded_ids = excluded_ids + "{0},".format(self.ids[i],)
|
|
|
|
return excluded_ids
|
2015-01-02 09:38:44 -06:00
|
|
|
|
2016-12-19 11:43:32 -06:00
|
|
|
def get_people(self):
|
|
|
|
people = ""
|
|
|
|
for i in xrange(0, len(self.message.checkboxes)):
|
|
|
|
if self.message.checkboxes[i].GetValue() == True:
|
|
|
|
people = people + "{0} ".format(self.message.checkboxes[i].GetLabel(),)
|
|
|
|
return people
|
|
|
|
|
2015-01-02 09:38:44 -06:00
|
|
|
class dm(basicTweet):
|
|
|
|
def __init__(self, session, title, caption, text):
|
2015-08-12 15:57:29 -05:00
|
|
|
super(dm, self).__init__(session, title, caption, text, messageType="dm", max=10000)
|
2015-03-12 12:24:34 -06:00
|
|
|
widgetUtils.connect_event(self.message.autocompletionButton, widgetUtils.BUTTON_PRESSED, self.autocomplete_users)
|
2016-07-28 12:45:06 -05:00
|
|
|
self.text_processor()
|
2015-03-12 12:24:34 -06:00
|
|
|
|
|
|
|
def autocomplete_users(self, *args, **kwargs):
|
|
|
|
c = autocompletionUsers.completion.autocompletionUsers(self.message, self.session.session_id)
|
|
|
|
c.show_menu("dm")
|
2015-01-05 05:33:09 -06:00
|
|
|
|
|
|
|
class viewTweet(basicTweet):
|
2015-04-08 13:34:50 -05:00
|
|
|
def __init__(self, tweet, tweetList, is_tweet=True):
|
2016-06-25 19:48:21 -05:00
|
|
|
""" This represents a tweet displayer. However it could be used for showing something wich is not a tweet, like a direct message or an event.
|
|
|
|
param tweet: A dictionary that represents a full tweet or a string for non-tweets.
|
|
|
|
param tweetList: If is_tweet is set to True, this could be a list of quoted tweets.
|
|
|
|
param is_tweet: True or false, depending wether the passed object is a tweet or not."""
|
2015-01-05 05:33:09 -06:00
|
|
|
if is_tweet == True:
|
2016-03-29 15:12:16 -06:00
|
|
|
image_description = []
|
2015-04-08 13:34:50 -05:00
|
|
|
text = ""
|
|
|
|
for i in xrange(0, len(tweetList)):
|
2016-06-25 19:48:21 -05:00
|
|
|
# tweets with message keys are longer tweets, the message value is the full messaje taken from twishort.
|
2016-06-27 09:44:36 -05:00
|
|
|
if tweetList[i].has_key("message") and tweetList[i]["is_quote_status"] == False:
|
2016-04-28 13:54:06 -05:00
|
|
|
value = "message"
|
|
|
|
else:
|
2016-09-28 17:25:03 -05:00
|
|
|
value = "full_text"
|
2016-06-27 09:44:36 -05:00
|
|
|
if tweetList[i].has_key("retweeted_status") and tweetList[i]["is_quote_status"] == False:
|
|
|
|
if tweetList[i].has_key("message") == False:
|
2016-09-28 17:25:03 -05:00
|
|
|
text = text + "rt @%s: %s\n" % (tweetList[i]["retweeted_status"]["user"]["screen_name"], tweetList[i]["retweeted_status"]["full_text"])
|
2016-06-27 09:44:36 -05:00
|
|
|
else:
|
|
|
|
text = text + "rt @%s: %s\n" % (tweetList[i]["retweeted_status"]["user"]["screen_name"], tweetList[i][value])
|
2015-04-08 13:34:50 -05:00
|
|
|
else:
|
2016-07-15 12:29:48 -05:00
|
|
|
text = text + " @%s: %s\n" % (tweetList[i]["user"]["screen_name"], tweetList[i][value])
|
2016-06-25 19:48:21 -05:00
|
|
|
# tweets with extended_entities could include image descriptions.
|
2016-03-29 15:12:16 -06:00
|
|
|
if tweetList[i].has_key("extended_entities") and tweetList[i]["extended_entities"].has_key("media"):
|
|
|
|
for z in tweetList[i]["extended_entities"]["media"]:
|
|
|
|
if z.has_key("ext_alt_text") and z["ext_alt_text"] != None:
|
|
|
|
image_description.append(z["ext_alt_text"])
|
2017-02-24 08:49:54 -06:00
|
|
|
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"):
|
|
|
|
for z in tweetList[i]["retweeted_status"]["extended_entities"]["media"]:
|
|
|
|
if z.has_key("ext_alt_text") and z["ext_alt_text"] != None:
|
|
|
|
image_description.append(z["ext_alt_text"])
|
2016-06-25 19:48:21 -05:00
|
|
|
# set rt and likes counters.
|
2015-01-05 05:33:09 -06:00
|
|
|
rt_count = str(tweet["retweet_count"])
|
|
|
|
favs_count = str(tweet["favorite_count"])
|
2016-06-25 19:48:21 -05:00
|
|
|
# Gets the client from where this tweet was made.
|
2016-03-28 17:35:00 -06:00
|
|
|
source = str(re.sub(r"(?s)<.*?>", "", tweet["source"].encode("utf-8")))
|
2015-04-08 13:34:50 -05:00
|
|
|
if text == "":
|
2016-04-28 13:54:06 -05:00
|
|
|
if tweet.has_key("message"):
|
|
|
|
value = "message"
|
|
|
|
else:
|
2016-09-28 17:25:03 -05:00
|
|
|
value = "full_text"
|
2015-04-08 13:34:50 -05:00
|
|
|
if tweet.has_key("retweeted_status"):
|
2016-06-27 09:44:36 -05:00
|
|
|
if tweet.has_key("message") == False:
|
2016-09-28 17:25:03 -05:00
|
|
|
text = "rt @%s: %s" % (tweet["retweeted_status"]["user"]["screen_name"], tweet["retweeted_status"]["full_text"])
|
2016-06-27 09:44:36 -05:00
|
|
|
else:
|
|
|
|
text = "rt @%s: %s" % (tweet["retweeted_status"]["user"]["screen_name"], tweet[value])
|
2015-04-08 13:34:50 -05:00
|
|
|
else:
|
2016-04-28 13:54:06 -05:00
|
|
|
text = tweet[value]
|
2015-11-03 10:07:06 -06:00
|
|
|
text = self.clear_text(text)
|
2016-03-29 15:12:16 -06:00
|
|
|
if tweet.has_key("extended_entities") and tweet["extended_entities"].has_key("media"):
|
|
|
|
for z in tweet["extended_entities"]["media"]:
|
|
|
|
if z.has_key("ext_alt_text") and z["ext_alt_text"] != None:
|
2017-02-24 08:49:54 -06:00
|
|
|
image_description.append(z["ext_alt_text"])
|
|
|
|
if tweet.has_key("retweeted_status") and tweet["retweeted_status"].has_key("extended_entities") and tweet["retweeted_status"]["extended_entities"].has_key("media"):
|
|
|
|
for z in tweet["retweeted_status"]["extended_entities"]["media"]:
|
|
|
|
if z.has_key("ext_alt_text") and z["ext_alt_text"] != None:
|
2016-03-29 15:12:16 -06:00
|
|
|
image_description.append(z["ext_alt_text"])
|
2016-03-28 17:35:00 -06:00
|
|
|
self.message = message.viewTweet(text, rt_count, favs_count, source.decode("utf-8"))
|
2015-01-05 05:33:09 -06:00
|
|
|
self.message.set_title(len(text))
|
2016-03-29 15:12:16 -06:00
|
|
|
[self.message.set_image_description(i) for i in image_description]
|
2015-01-05 05:33:09 -06:00
|
|
|
else:
|
|
|
|
text = tweet
|
|
|
|
self.message = message.viewNonTweet(text)
|
|
|
|
widgetUtils.connect_event(self.message.spellcheck, widgetUtils.BUTTON_PRESSED, self.spellcheck)
|
|
|
|
widgetUtils.connect_event(self.message.translateButton, widgetUtils.BUTTON_PRESSED, self.translate)
|
|
|
|
if self.contain_urls() == True:
|
2015-03-12 11:45:53 -06:00
|
|
|
self.message.enable_button("unshortenButton")
|
2015-01-05 05:33:09 -06:00
|
|
|
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:
|
|
|
|
return True
|
2015-04-03 16:57:08 -06:00
|
|
|
return False
|
2015-11-03 10:07:06 -06:00
|
|
|
|
|
|
|
def clear_text(self, text):
|
|
|
|
urls = utils.find_urls_in_text(text)
|
|
|
|
for i in urls:
|
|
|
|
if "https://twitter.com/" in i:
|
2016-07-15 12:29:48 -05:00
|
|
|
text = text.replace(i, "\n")
|
2015-11-03 10:07:06 -06:00
|
|
|
return text
|