From e2352ea3f25d114aac1c1824b6ee26b1a6e1a217 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Cort=C3=A9z?= Date: Wed, 8 Apr 2015 13:34:50 -0500 Subject: [PATCH] Long retweets support. Read a long retweet by showing the tweet --- src/controller/buffersController.py | 21 ++++++---- src/controller/mainController.py | 17 ++++++-- src/controller/messages.py | 28 +++++++++----- src/gtkUI/buffers/panels.py | 2 + src/gtkUI/dialogs/message.py | 1 + src/long_tweets/tweets.py | 28 ++++++++++++++ src/wxUI/dialogs/message.py | 60 ++++++++++++++++++++++++++++- 7 files changed, 135 insertions(+), 22 deletions(-) create mode 100644 src/long_tweets/tweets.py diff --git a/src/controller/buffersController.py b/src/controller/buffersController.py index ac97d78e..c45c34ff 100644 --- a/src/controller/buffersController.py +++ b/src/controller/buffersController.py @@ -150,10 +150,12 @@ class accountPanel(bufferController): def setup_account(self): widgetUtils.connect_event(self.buffer, widgetUtils.CHECKBOX, self.autostart, menuitem=self.buffer.autostart_account) - if self.account_id not in config.app["sessions"]["ignored_sessions"]: - self.buffer.change_autostart(True) - elif self.account_id in config.app["sessions"]["ignored_sessions"]: + if self.account_id in config.app["sessions"]["ignored_sessions"]: + print "true" self.buffer.change_autostart(False) + else: + self.buffer.change_autostart(True) + print "false" if not hasattr(self, "logged"): self.buffer.change_login(login=False) widgetUtils.connect_event(self.buffer.login, widgetUtils.BUTTON_PRESSED, self.logout) @@ -360,12 +362,17 @@ class baseBufferController(bufferController): id = tweet["id"] answer = commonMessageDialogs.retweet_question(self.buffer) if answer == widgetUtils.YES: - retweet = messages.tweet(self.session, _(u"Retweet"), _(u"Add your comment to the tweet"), u"“@%s: %s ”" % (tweet["user"]["screen_name"], tweet["text"])) + retweet = messages.tweet(self.session, _(u"Retweet"), _(u"Add your comment to the tweet"), u"“@%s: %s ”" % (tweet["user"]["screen_name"], tweet["text"]), max=116, messageType="retweet") if retweet.message.get_response() == widgetUtils.OK: - if retweet.image == None: - call_threaded(self.session.api_call, call_name="update_status", _sound="retweet_send.ogg", status=retweet.message.get_text(), in_reply_to_status_id=id) + text = retweet.message.get_text() + if len(text+ u"“@%s: %s ”" % (tweet["user"]["screen_name"], tweet["text"])) < 140: + text = text+u"“@%s: %s ”" % (tweet["user"]["screen_name"], tweet["text"]) else: - call_threaded(self.session.api_call, call_name="update_status", _sound="retweet_send.ogg", status=retweet.message.get_text(), in_reply_to_status_id=id, media=retweet.image) + text = text+" https://twitter.com/{0}/status/{1}".format(tweet["user"]["screen_name"], id) + if retweet.image == None: + call_threaded(self.session.api_call, call_name="update_status", _sound="retweet_send.ogg", status=text, in_reply_to_status_id=id) + else: + call_threaded(self.session.api_call, call_name="update_status", _sound="retweet_send.ogg", status=text, media=retweet.image) if hasattr(retweet.message, "destroy"): retweet.message.destroy() elif answer == widgetUtils.NO: call_threaded(self.session.api_call, call_name="retweet", _sound="retweet_send.ogg", id=id) diff --git a/src/controller/mainController.py b/src/controller/mainController.py index af1a5541..0f6a452d 100644 --- a/src/controller/mainController.py +++ b/src/controller/mainController.py @@ -34,7 +34,7 @@ import pygeocoder from pygeolib import GeocoderError import logging import webbrowser -from long_tweets import twishort +from long_tweets import twishort, tweets log = logging.getLogger("mainController") @@ -613,6 +613,7 @@ class Controller(object): if buffer.type == "baseBuffer" or buffer.type == "favourites_timeline" or buffer.type == "list" or buffer.type == "search": try: tweet = buffer.get_right_tweet() + tweetsList = [] tweet_id = tweet["id"] uri = None if tweet.has_key("long_uri"): @@ -620,15 +621,23 @@ class Controller(object): tweet = buffer.session.twitter.twitter.show_status(id=tweet_id) if uri != None: tweet["text"] = twishort.get_full_text(uri) - msg = messages.viewTweet(tweet, ) + l = tweets.is_long(tweet) + while l != False: + tweetsList.append(tweet) + id = tweets.get_id(l) + tweet = buffer.session.twitter.twitter.show_status(id=id) + l = tweets.is_long(tweet) + if l == False: + tweetsList.append(tweet) + msg = messages.viewTweet(tweet, tweetsList) except TwythonError: non_tweet = buffer.get_formatted_message() - msg = messages.viewTweet(non_tweet, False) + msg = messages.viewTweet(non_tweet, [], False) elif buffer.type == "account" or buffer.type == "empty": return else: non_tweet = buffer.get_formatted_message() - msg = messages.viewTweet(non_tweet, False) + msg = messages.viewTweet(non_tweet, [], False) def open_favs_timeline(self, *args, **kwargs): self.open_timeline(default="favourites") diff --git a/src/controller/messages.py b/src/controller/messages.py index 176b4457..94993875 100644 --- a/src/controller/messages.py +++ b/src/controller/messages.py @@ -16,8 +16,9 @@ from 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"): + def __init__(self, session, title, caption, text, messageType="tweet", max=140): super(basicTweet, self).__init__() + self.max = max self.title = title self.session = session self.message = getattr(message, messageType)(title, caption, text) @@ -81,14 +82,14 @@ class basicTweet(object): self.message.text_focus() def text_processor(self, *args, **kwargs): - self.message.set_title(_(u"%s - %s of 140 characters") % (self.title, len(self.message.get_text()))) + 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()) > 1: self.message.enable_button("shortenButton") self.message.enable_button("unshortenButton") else: self.message.disable_button("shortenButton") self.message.disable_button("unshortenButton") - if len(self.message.get_text()) > 140: + if len(self.message.get_text()) > self.max: self.session.sound.play("max_length.ogg") def spellcheck(self, event=None): @@ -110,8 +111,8 @@ class basicTweet(object): dlg = audioUploader.audioUploader(self.session.settings, completed_callback) class tweet(basicTweet): - def __init__(self, session, title, caption, text, messageType="tweet"): - super(tweet, self).__init__(session, title, caption, text, messageType) + def __init__(self, session, title, caption, text, messageType="tweet", max=140): + super(tweet, self).__init__(session, title, caption, text, messageType, max) self.image = None widgetUtils.connect_event(self.message.upload_image, widgetUtils.BUTTON_PRESSED, self.upload_image) widgetUtils.connect_event(self.message.autocompletionButton, widgetUtils.BUTTON_PRESSED, self.autocomplete_users) @@ -155,14 +156,21 @@ class dm(basicTweet): c.show_menu("dm") class viewTweet(basicTweet): - def __init__(self, tweet, is_tweet=True): + def __init__(self, tweet, tweetList, is_tweet=True): if is_tweet == True: - if tweet.has_key("retweeted_status"): - text = "rt @%s: %s" % (tweet["retweeted_status"]["user"]["screen_name"], tweet["retweeted_status"]["text"]) - else: - text = tweet["text"] + text = "" + for i in xrange(0, len(tweetList)): + if tweetList[i].has_key("retweeted_status"): + text = text + "rt @%s: %s\n\n" % (tweetList[i]["retweeted_status"]["user"]["screen_name"], tweetList[i]["retweeted_status"]["text"]) + else: + text = text + "@%s: %s\n\n" % (tweetList[i]["user"]["screen_name"], tweetList[i]["text"]) rt_count = str(tweet["retweet_count"]) favs_count = str(tweet["favorite_count"]) + if text == "": + if tweet.has_key("retweeted_status"): + text = "rt @%s: %s" % (tweet["retweeted_status"]["user"]["screen_name"], tweet["retweeted_status"]["text"]) + else: + text = tweet["text"] self.message = message.viewTweet(text, rt_count, favs_count) self.message.set_title(len(text)) else: diff --git a/src/gtkUI/buffers/panels.py b/src/gtkUI/buffers/panels.py index 1a3916af..9594ea1b 100644 --- a/src/gtkUI/buffers/panels.py +++ b/src/gtkUI/buffers/panels.py @@ -22,6 +22,8 @@ class accountPanel(Gtk.VBox): self.autostart_account.set_active(autostart) def get_autostart(self): + print "actived" + print self.autostart_account.get_active() return self.autostart_account.get_active() class emptyPanel(Gtk.VBox): diff --git a/src/gtkUI/dialogs/message.py b/src/gtkUI/dialogs/message.py index 2013464d..18500043 100644 --- a/src/gtkUI/dialogs/message.py +++ b/src/gtkUI/dialogs/message.py @@ -10,6 +10,7 @@ class textLimited(widgetUtils.baseDialog): self.label = Gtk.Label(message) self.set_title(message, titleWindow=True) self.text = Gtk.Entry() + self.text.set_max_length(140) self.text.set_text(text) self.text.set_placeholder_text(message) self.set_title(str(len(text))) diff --git a/src/long_tweets/tweets.py b/src/long_tweets/tweets.py new file mode 100644 index 00000000..a2d97828 --- /dev/null +++ b/src/long_tweets/tweets.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +############################################################ +# Copyright (c) 2015 Manuel Eduardo Cortéz Vallejo +# +# 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 +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +############################################################ + +def get_id(url): + return url.split("/")[-1] + +def is_long(tweet): + long = False + for url in range(0, len(tweet["entities"]["urls"])): + if "twitter.com" in tweet["entities"]["urls"][url]["expanded_url"]: + long = get_id(tweet["entities"]["urls"][url]["expanded_url"]) + return long \ No newline at end of file diff --git a/src/wxUI/dialogs/message.py b/src/wxUI/dialogs/message.py index c50f468c..fc79b94e 100644 --- a/src/wxUI/dialogs/message.py +++ b/src/wxUI/dialogs/message.py @@ -107,7 +107,65 @@ class tweet(textLimited): if openFileDialog.ShowModal() == wx.ID_CANCEL: return None return open(openFileDialog.GetPath(), "rb") - + +class retweet(tweet): + def createControls(self, title, message, text): + self.mainBox = wx.BoxSizer(wx.VERTICAL) + self.createTextArea(message, "") + label = wx.StaticText(self.panel, -1, _(u"Retweet")) + self.text2 = wx.TextCtrl(self.panel, -1, text, size=(439, -1), style=wx.TE_MULTILINE|wx.TE_READONLY) + self.retweetBox = wx.BoxSizer(wx.HORIZONTAL) + self.retweetBox.Add(label, 0, wx.ALL, 5) + self.retweetBox.Add(self.text2, 0, wx.ALL, 5) + self.mainBox.Add(self.textBox, 0, wx.ALL, 5) + self.mainBox.Add(self.retweetBox, 0, wx.ALL, 5) + self.upload_image = wx.Button(self.panel, -1, _(u"Upload a picture"), size=wx.DefaultSize) + self.spellcheck = wx.Button(self.panel, -1, _("Spelling correction"), size=wx.DefaultSize) + self.attach = wx.Button(self.panel, -1, _(u"Attach audio"), size=wx.DefaultSize) + self.shortenButton = wx.Button(self.panel, -1, _(u"Shorten URL"), size=wx.DefaultSize) + self.unshortenButton = wx.Button(self.panel, -1, _(u"Expand URL"), size=wx.DefaultSize) + self.shortenButton.Disable() + self.unshortenButton.Disable() + self.translateButton = wx.Button(self.panel, -1, _(u"Translate message"), size=wx.DefaultSize) + self.autocompletionButton = wx.Button(self.panel, -1, _(u"&Autocomplete users")) + self.okButton = wx.Button(self.panel, wx.ID_OK, _(u"Send"), size=wx.DefaultSize) + self.okButton.SetDefault() + cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _(u"Close"), size=wx.DefaultSize) + self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL) + self.buttonsBox1.Add(self.upload_image, 0, wx.ALL, 10) + self.buttonsBox1.Add(self.spellcheck, 0, wx.ALL, 10) + self.buttonsBox1.Add(self.attach, 0, wx.ALL, 10) + self.mainBox.Add(self.buttonsBox1, 0, wx.ALL, 10) + self.buttonsBox2 = wx.BoxSizer(wx.HORIZONTAL) + self.buttonsBox2.Add(self.shortenButton, 0, wx.ALL, 10) + self.buttonsBox2.Add(self.unshortenButton, 0, wx.ALL, 10) + self.buttonsBox2.Add(self.translateButton, 0, wx.ALL, 10) + self.mainBox.Add(self.buttonsBox2, 0, wx.ALL, 10) + self.ok_cancelSizer = wx.BoxSizer(wx.HORIZONTAL) + self.ok_cancelSizer.Add(self.autocompletionButton, 0, wx.ALL, 10) + self.ok_cancelSizer.Add(self.okButton, 0, wx.ALL, 10) + self.ok_cancelSizer.Add(cancelButton, 0, wx.ALL, 10) + self.mainBox.Add(self.ok_cancelSizer) + selectId = wx.NewId() + self.Bind(wx.EVT_MENU, self.onSelect, id=selectId) + self.accel_tbl = wx.AcceleratorTable([ +(wx.ACCEL_CTRL, ord('A'), selectId), +]) + self.SetAcceleratorTable(self.accel_tbl) + self.panel.SetSizer(self.mainBox) + + def __init__(self, title, message, text): + super(tweet, self).__init__() + self.createControls(message, title, text) +# self.onTimer(wx.EVT_CHAR_HOOK) + self.SetClientSize(self.mainBox.CalcMin()) + + def get_image(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) + if openFileDialog.ShowModal() == wx.ID_CANCEL: + return None + return open(openFileDialog.GetPath(), "rb") + class dm(textLimited): def createControls(self, title, message, users): self.panel = wx.Panel(self)