Reply and direct message are supported, updated locales and code improvements

This commit is contained in:
Manuel Cortez 2015-01-02 09:38:44 -06:00
parent 186f70afc3
commit 29d434bcd4
37 changed files with 12588 additions and 5450 deletions

1
.gitignore vendored
View File

@ -15,3 +15,4 @@ src/bootstrap.exe
src/Microsoft.VC90.CRT src/Microsoft.VC90.CRT
src/Microsoft.VC90.MFC src/Microsoft.VC90.MFC
src/launcher.bat src/launcher.bat
src/sounds/iOs

View File

@ -6,8 +6,10 @@ import webbrowser
import output import output
import config import config
import sound import sound
import messages
from twitter import compose, prettydate, utils from twitter import compose, prettydate, utils
from wxUI import buffers, dialogs from wxUI import buffers, dialogs
from mysc.thread_utils import call_threaded
class bufferController(object): class bufferController(object):
def __init__(self, parent=None, function=None, session=None, *args, **kwargs): def __init__(self, parent=None, function=None, session=None, *args, **kwargs):
@ -80,6 +82,12 @@ class bufferController(object):
else: else:
self.buffer.list.select_item(0) self.buffer.list.select_item(0)
def reply(self):
pass
def direct_message(self):
pass
class accountPanel(bufferController): class accountPanel(bufferController):
def __init__(self, parent, name, account): def __init__(self, parent, name, account):
super(accountPanel, self).__init__(parent, None, name) super(accountPanel, self).__init__(parent, None, name)
@ -105,6 +113,7 @@ class emptyPanel(bufferController):
self.name = name self.name = name
self.session = None self.session = None
self.needs_init = True self.needs_init = True
class baseBufferController(bufferController): class baseBufferController(bufferController):
def __init__(self, parent, function, name, sessionObject, account, bufferType=None, *args, **kwargs): def __init__(self, parent, function, name, sessionObject, account, bufferType=None, *args, **kwargs):
super(baseBufferController, self).__init__(parent, function, *args, **kwargs) super(baseBufferController, self).__init__(parent, function, *args, **kwargs)
@ -160,6 +169,37 @@ class baseBufferController(bufferController):
tweet = self.session.db[self.name][self.buffer.list.get_selected()] tweet = self.session.db[self.name][self.buffer.list.get_selected()]
return tweet return tweet
def get_right_tweet(self):
tweet = self.session.db[self.name][self.buffer.list.get_selected()]
return tweet
def reply(self):
tweet = self.get_right_tweet()
screen_name = tweet["user"]["screen_name"]
id = tweet["id"]
users = utils.get_all_mentioned(tweet, self.session.db)
message = messages.reply(self.session, _(u"Reply"), _(u"Reply to %s") % (screen_name,), "@%s" % (screen_name,), users)
if message.message.get_response() == widgetUtils.OK:
if message.image == None:
call_threaded(self.session.twitter.api_call, call_name="update_status", _sound="reply_send.ogg", in_reply_to_status_id=id, status=message.message.get_text())
else:
call_threaded(self.session.twitter.api_call, call_name="update_status_with_media", _sound="reply_send.ogg", in_reply_to_status_id=id, status=message.message.get_text(), media=message.file)
def direct_message(self):
tweet = self.get_tweet()
if self.type == "dm":
screen_name = tweet["sender"]["screen_name"]
users = utils.get_all_users(tweet, self.session.db)
elif self.type == "people":
screen_name = tweet["screen_name"]
users = [screen_name]
else:
screen_name = tweet["user"]["screen_name"]
users = utils.get_all_users(tweet, self.session.db)
dm = messages.dm(self.session, _(u"Direct message to %s") % (screen_name,), _(u"New direct message"), users)
if dm.message.get_response() == widgetUtils.OK:
call_threaded(self.session.api_call, call_name="send_direct_message", _sound="dm_sent.ogg", text=dm.message.get_text(), screen_name=dm.message.get("cb"))
def onFocus(self, ev): def onFocus(self, ev):
tweet = self.get_tweet() tweet = self.get_tweet()
if self.session.settings["general"]["relative_times"] == True: if self.session.settings["general"]["relative_times"] == True:
@ -220,6 +260,7 @@ class eventsBufferController(bufferController):
self.name = name self.name = name
self.account = account self.account = account
self.id = self.buffer.GetId() self.id = self.buffer.GetId()
self.buffer.account = self.account
self.compose_function = compose.compose_event self.compose_function = compose.compose_event
self.session = session self.session = session
@ -234,6 +275,7 @@ class peopleBufferController(baseBufferController):
def __init__(self, parent, function, name, sessionObject, account, bufferType=None, *args, **kwargs): def __init__(self, parent, function, name, sessionObject, account, bufferType=None, *args, **kwargs):
super(peopleBufferController, self).__init__(parent, function, name, sessionObject, account, bufferType="peoplePanel") super(peopleBufferController, self).__init__(parent, function, name, sessionObject, account, bufferType="peoplePanel")
self.compose_function = compose.compose_followers_list self.compose_function = compose.compose_followers_list
self.get_tweet = self.get_right_tweet
def onFocus(self, ev): def onFocus(self, ev):
pass pass
@ -261,6 +303,10 @@ class peopleBufferController(baseBufferController):
tweet = self.compose_function(i, self.session.db) tweet = self.compose_function(i, self.session.db)
self.buffer.list.insert_item(True, *tweet) self.buffer.list.insert_item(True, *tweet)
def get_right_tweet(self):
tweet = self.session.db[self.name]["items"][self.buffer.list.get_selected()]
return tweet
class searchBufferController(baseBufferController): class searchBufferController(baseBufferController):
def start_stream(self): def start_stream(self):
val = getattr(self.session.twitter.twitter, self.function)(*self.args, **self.kwargs) val = getattr(self.session.twitter.twitter, self.function)(*self.args, **self.kwargs)

View File

@ -62,6 +62,8 @@ class Controller(object):
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.learn_sounds, menuitem=self.view.sounds_tutorial) widgetUtils.connect_event(self.view, widgetUtils.MENU, self.learn_sounds, menuitem=self.view.sounds_tutorial)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.exit, menuitem=self.view.close) widgetUtils.connect_event(self.view, widgetUtils.MENU, self.exit, menuitem=self.view.close)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.post_tweet, self.view.compose) widgetUtils.connect_event(self.view, widgetUtils.MENU, self.post_tweet, self.view.compose)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.post_reply, self.view.reply)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.send_dm, self.view.dm)
def __init__(self): def __init__(self):
super(Controller, self).__init__() super(Controller, self).__init__()
@ -217,7 +219,9 @@ class Controller(object):
def post_tweet(self, event=None): def post_tweet(self, event=None):
buffer = self.get_best_buffer() buffer = self.get_best_buffer()
tweet = messages.tweet(buffer.session) title = _(u"Tweet")
caption = _(u"Write the tweet here")
tweet = messages.tweet(buffer.session, title, caption, "")
if tweet.message.get_response() == widgetUtils.OK: if tweet.message.get_response() == widgetUtils.OK:
text = tweet.message.get_text() text = tweet.message.get_text()
if tweet.image == None: if tweet.image == None:
@ -225,11 +229,19 @@ class Controller(object):
else: else:
call_threaded(buffer.session.api_call, call_name="update_status_with_media", _sound="tweet_send.ogg", status=text, media=tweet.image) call_threaded(buffer.session.api_call, call_name="update_status_with_media", _sound="tweet_send.ogg", status=text, media=tweet.image)
def post_reply(self): def post_reply(self, *args, **kwargs):
pass buffer = self.get_best_buffer()
if buffer.name == "sent_direct_messages" or buffer.name == "sent-tweets": return
elif buffer.name == "direct_messages":
buffer.direct_message()
else:
buffer.reply()
def send_dm(self, user): def send_dm(self, user):
pass buffer = self.get_best_buffer()
if buffer.name == "sent_direct_messages" or buffer.name == "sent-tweets": return
else:
buffer.direct_message()
def post_retweet(self): def post_retweet(self):
pass pass

View File

@ -11,16 +11,18 @@ from twitter import utils
class basicTweet(object): class basicTweet(object):
""" This class handles the tweet main features. Other classes should derive from this class.""" """ This class handles the tweet main features. Other classes should derive from this class."""
def __init__(self, session): def __init__(self, session, title, caption, text, messageType="tweet"):
super(basicTweet, self).__init__() super(basicTweet, self).__init__()
self.title = title
self.session = session self.session = session
self.message = message.tweet(_(u"Write the tweet here"), _(u"tweet - 0 characters"), "") self.message = getattr(message, messageType)(title, caption, text)
widgetUtils.connect_event(self.message.spellcheck, widgetUtils.BUTTON_PRESSED, self.spellcheck) widgetUtils.connect_event(self.message.spellcheck, widgetUtils.BUTTON_PRESSED, self.spellcheck)
widgetUtils.connect_event(self.message.attach, widgetUtils.BUTTON_PRESSED, self.attach) widgetUtils.connect_event(self.message.attach, widgetUtils.BUTTON_PRESSED, self.attach)
widgetUtils.connect_event(self.message.text, widgetUtils.ENTERED_TEXT, self.text_processor) 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.shortenButton, widgetUtils.BUTTON_PRESSED, self.shorten)
widgetUtils.connect_event(self.message.unshortenButton, widgetUtils.BUTTON_PRESSED, self.unshorten) widgetUtils.connect_event(self.message.unshortenButton, widgetUtils.BUTTON_PRESSED, self.unshorten)
widgetUtils.connect_event(self.message.translateButton, widgetUtils.BUTTON_PRESSED, self.translate) widgetUtils.connect_event(self.message.translateButton, widgetUtils.BUTTON_PRESSED, self.translate)
self.text_processor()
def translate(self, event=None): def translate(self, event=None):
dlg = translator.gui.translateDialog() dlg = translator.gui.translateDialog()
@ -65,8 +67,8 @@ class basicTweet(object):
self.message.set_text(self.message.get_text().replace(urls[list_urls.get_item()], url_shortener.unshorten(list_urls.get_string()))) 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")) output.speak(_(u"URL expanded"))
def text_processor(self, event=None): def text_processor(self, *args, **kwargs):
self.message.set_title("%s of 140 characters" % (len(self.message.get_text()))) self.message.set_title(_(u"%s - %s of 140 characters") % (self.title, len(self.message.get_text())))
if len(self.message.get_text()) > 1: if len(self.message.get_text()) > 1:
self.message.enable_button("shortenButton") self.message.enable_button("shortenButton")
self.message.enable_button("unshortenButton") self.message.enable_button("unshortenButton")
@ -95,8 +97,8 @@ class basicTweet(object):
dlg = audioUploader.audioUploader(self.session.settings, completed_callback) dlg = audioUploader.audioUploader(self.session.settings, completed_callback)
class tweet(basicTweet): class tweet(basicTweet):
def __init__(self, session): def __init__(self, session, title, caption, text, messageType="tweet"):
super(tweet, self).__init__(session) super(tweet, self).__init__(session, title, caption, text, messageType)
self.image = None self.image = None
widgetUtils.connect_event(self.message.upload_image, widgetUtils.BUTTON_PRESSED, self.upload_image) widgetUtils.connect_event(self.message.upload_image, widgetUtils.BUTTON_PRESSED, self.upload_image)
@ -109,3 +111,20 @@ class tweet(basicTweet):
else: else:
self.image = self.message.get_image() self.image = self.message.get_image()
self.message.set("upload_image", _(u"Discard image")) self.message.set("upload_image", _(u"Discard image"))
class reply(tweet):
def __init__(self, session, title, caption, text, users=None):
super(reply, self).__init__(session, title, caption, text, messageType="reply")
self.users = users
if self.users != None:
widgetUtils.connect_event(self.message.mentionAll, widgetUtils.BUTTON_PRESSED, self.mention_all)
self.message.enable_button("mentionAll")
self.message.set_cursor_at_end()
def mention_all(self, *args, **kwargs):
self.message.set_text(self.message.get_text()+self.users)
self.message.set_cursor_at_end()
class dm(basicTweet):
def __init__(self, session, title, caption, text):
super(dm, self).__init__(session, title, caption, text, messageType="dm")

View File

@ -1,5 +0,0 @@
# -*- coding: utf-8 -*-
""" Handles storage from a durus database """
class db(object):
def __init__(self):
self.settings = {}

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,6 @@
""" 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 twitter import twitter
import application import application
import db
import session_exceptions as Exceptions import session_exceptions as Exceptions
import paths import paths
import output import output

View File

@ -46,17 +46,16 @@ def is_audio(tweet):
return True return True
return False return False
def get_all_mentioned(tweet, config): def get_all_mentioned(tweet, conf):
""" Gets all users that has been mentioned.""" """ Gets all users that has been mentioned."""
if tweet.has_key("retweeted_status"): tweet = tweet["retweeted_status"]
string = [] string = []
for i in tweet["entities"]["user_mentions"]: for i in tweet["entities"]["user_mentions"]:
if i["screen_name"] != config.settings["user_name"] and i["screen_name"] != tweet["user"]["screen_name"]: if i["screen_name"] != conf["user_name"] and i["screen_name"] != tweet["user"]["screen_name"]:
if "@"+i["screen_name"] not in string: if "@"+i["screen_name"] not in string:
string.append("@"+i["screen_name"]) string.append("@"+i["screen_name"])
return " ".join(string)+" " return " ".join(string)+" "
def get_all_users(tweet, config): def get_all_users(tweet, conf):
string = [] string = []
if tweet.has_key("retweeted_status"): if tweet.has_key("retweeted_status"):
string.append(tweet["user"]["screen_name"]) string.append(tweet["user"]["screen_name"])
@ -64,10 +63,10 @@ def get_all_users(tweet, config):
if tweet.has_key("sender"): if tweet.has_key("sender"):
string.append(tweet["sender"]["screen_name"]) string.append(tweet["sender"]["screen_name"])
else: else:
if tweet["user"]["screen_name"] != config.settings["user_name"]: if tweet["user"]["screen_name"] != conf["user_name"]:
string.append(tweet["user"]["screen_name"]) string.append(tweet["user"]["screen_name"])
for i in tweet["entities"]["user_mentions"]: for i in tweet["entities"]["user_mentions"]:
if i["screen_name"] != config.settings["user_name"] and i["screen_name"] != tweet["user"]["screen_name"]: if i["screen_name"] != conf["user_name"] and i["screen_name"] != tweet["user"]["screen_name"]:
if i["screen_name"] not in string: if i["screen_name"] not in string:
string.append(i["screen_name"]) string.append(i["screen_name"])
if len(string) == 0: if len(string) == 0:

View File

@ -44,8 +44,15 @@ class textLimited(widgetUtils.BaseDialog):
def onSelect(self, ev): def onSelect(self, ev):
self.text.SelectAll() self.text.SelectAll()
def set_cursor_at_end(self):
self.text.SetInsertionPoint(len(self.text.GetValue()))
def set_cursor_at_position(self, position):
self.text.SetInsertionPoint(position)
class tweet(textLimited): class tweet(textLimited):
def createControls(self, message, title, text): def createControls(self, title, message, text):
self.mainBox = wx.BoxSizer(wx.VERTICAL) self.mainBox = wx.BoxSizer(wx.VERTICAL)
self.createTextArea(message, text) self.createTextArea(message, text)
self.mainBox.Add(self.textBox, 0, wx.ALL, 5) self.mainBox.Add(self.textBox, 0, wx.ALL, 5)
@ -82,7 +89,7 @@ class tweet(textLimited):
self.SetAcceleratorTable(self.accel_tbl) self.SetAcceleratorTable(self.accel_tbl)
self.panel.SetSizer(self.mainBox) self.panel.SetSizer(self.mainBox)
def __init__(self, message, title, text): def __init__(self, title, message, text):
super(tweet, self).__init__() super(tweet, self).__init__()
self.createControls(message, title, text) self.createControls(message, title, text)
# self.onTimer(wx.EVT_CHAR_HOOK) # self.onTimer(wx.EVT_CHAR_HOOK)
@ -95,7 +102,7 @@ class tweet(textLimited):
return open(openFileDialog.GetPath(), "rb") return open(openFileDialog.GetPath(), "rb")
class dm(textLimited): class dm(textLimited):
def createControls(self, message, title, users): def createControls(self, title, message, users):
self.panel = wx.Panel(self) self.panel = wx.Panel(self)
self.mainBox = wx.BoxSizer(wx.VERTICAL) self.mainBox = wx.BoxSizer(wx.VERTICAL)
label = wx.StaticText(self.panel, -1, _(u"Recipient")) label = wx.StaticText(self.panel, -1, _(u"Recipient"))
@ -128,14 +135,17 @@ class dm(textLimited):
self.mainBox.Add(self.buttonsBox3, 0, wx.ALL, 5) self.mainBox.Add(self.buttonsBox3, 0, wx.ALL, 5)
self.panel.SetSizer(self.mainBox) self.panel.SetSizer(self.mainBox)
def __init__(self, message, title, users): def __init__(self, title, message, users):
super(dm, self).__init__() super(dm, self).__init__()
self.createControls(message, title, users) self.createControls(message, title, users)
# self.onTimer(wx.EVT_CHAR_HOOK) # self.onTimer(wx.EVT_CHAR_HOOK)
self.SetClientSize(self.mainBox.CalcMin()) self.SetClientSize(self.mainBox.CalcMin())
def get_user(self):
return self.cb.GetValue()
class reply(tweet): class reply(tweet):
def __init__(self, message, title, text): def __init__(self, title, message, text):
super(reply, self).__init__(message, title, text) super(reply, self).__init__(message, title, text)
self.text.SetInsertionPoint(len(self.text.GetValue())) self.text.SetInsertionPoint(len(self.text.GetValue()))
self.mentionAll = wx.Button(self, -1, _(u"Mention to all"), size=wx.DefaultSize) self.mentionAll = wx.Button(self, -1, _(u"Mention to all"), size=wx.DefaultSize)