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