# -*- 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."))