mirror of
https://github.com/MCV-Software/TWBlue.git
synced 2025-09-15 18:41:48 +00:00
Putting all the code from the current master branch of TWBlue
This commit is contained in:
3
src/gui/__init__.py
Normal file
3
src/gui/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import main, dialogs
|
||||
|
10
src/gui/buffers/__init__.py
Normal file
10
src/gui/buffers/__init__.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from panels import accountPanel, emptyPanel
|
||||
from base import *
|
||||
from dm import *
|
||||
from events import *
|
||||
from favourites import *
|
||||
from lists import *
|
||||
from people import *
|
||||
from tweet_searches import *
|
||||
from user_searches import *
|
364
src/gui/buffers/base.py
Normal file
364
src/gui/buffers/base.py
Normal file
@@ -0,0 +1,364 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
############################################################
|
||||
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
############################################################
|
||||
import wx
|
||||
import gui.dialogs
|
||||
import twitter
|
||||
import webbrowser
|
||||
import config
|
||||
import sound
|
||||
import url_shortener
|
||||
import logging as original_logger
|
||||
import output
|
||||
import platform
|
||||
import datetime
|
||||
from twitter import prettydate
|
||||
from multiplatform_widgets import widgets
|
||||
from mysc import event
|
||||
from mysc.thread_utils import call_threaded
|
||||
from twython import TwythonError
|
||||
log = original_logger.getLogger("buffers.base")
|
||||
|
||||
class basePanel(wx.Panel):
|
||||
|
||||
def bind_events(self):
|
||||
self.Bind(event.MyEVT_OBJECT, self.update)
|
||||
self.Bind(event.MyEVT_DELETED, self.Remove)
|
||||
self.list.list.Bind(wx.EVT_CHAR_HOOK, self.interact)
|
||||
if self.system == "Windows":
|
||||
self.list.list.Bind(wx.EVT_LIST_ITEM_FOCUSED, self.onFocus)
|
||||
else:
|
||||
self.list.list.Bind(wx.EVT_LISTBOX, self.onFocus)
|
||||
|
||||
def get_message(self, dialog=False):
|
||||
if dialog == False: return " ".join(self.compose_function(self.db.settings[self.name_buffer][self.list.get_selected()], self.db))
|
||||
else:
|
||||
list = self.compose_function(self.db.settings[self.name_buffer][self.list.get_selected()], self.db)
|
||||
return " ".join(list[1:-2])
|
||||
|
||||
def create_list(self):
|
||||
self.list = widgets.list(self, _(u"User"), _(u"Text"), _(u"Date"), _(u"Client"), style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_VRULES)
|
||||
if self.system == "Windows":
|
||||
self.list.set_windows_size(0, 30)
|
||||
self.list.set_windows_size(1, 160)
|
||||
self.list.set_windows_size(2, 55)
|
||||
self.list.set_windows_size(3, 42)
|
||||
self.list.set_size()
|
||||
|
||||
def __init__(self, parent, window, name_buffer, function=None, argumento=None, sound="", timeline=False):
|
||||
if timeline == False:
|
||||
self.type = "buffer"
|
||||
elif timeline == True:
|
||||
self.type = "timeline"
|
||||
self.db = window.db
|
||||
self.twitter = window.twitter
|
||||
self.name_buffer = name_buffer
|
||||
self.function = function
|
||||
self.argumento = argumento
|
||||
self.sound = sound
|
||||
self.parent = window
|
||||
self.compose_function = twitter.compose.compose_tweet
|
||||
self.system = platform.system()
|
||||
wx.Panel.__init__(self, parent)
|
||||
self.sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self.create_list()
|
||||
self.btn = wx.Button(self, -1, _(u"Tweet"))
|
||||
self.btn.Bind(wx.EVT_BUTTON, self.post_status)
|
||||
self.retweetBtn = wx.Button(self, -1, _(u"Retweet"))
|
||||
self.retweetBtn.Bind(wx.EVT_BUTTON, self.onRetweet)
|
||||
self.responseBtn = wx.Button(self, -1, _(u"Reply"))
|
||||
self.responseBtn.Bind(wx.EVT_BUTTON, self.onResponse)
|
||||
self.dmBtn = wx.Button(self, -1, _(u"Direct message"))
|
||||
self.dmBtn.Bind(wx.EVT_BUTTON, self.onDm)
|
||||
btnSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
btnSizer.Add(self.btn, 0, wx.ALL, 5)
|
||||
btnSizer.Add(self.retweetBtn, 0, wx.ALL, 5)
|
||||
btnSizer.Add(self.responseBtn, 0, wx.ALL, 5)
|
||||
btnSizer.Add(self.dmBtn, 0, wx.ALL, 5)
|
||||
self.sizer.Add(btnSizer, 0, wx.ALL, 5)
|
||||
self.sizer.Add(self.list.list, 0, wx.ALL, 5)
|
||||
self.bind_events()
|
||||
self.SetSizer(self.sizer)
|
||||
|
||||
def remove_buffer(self):
|
||||
if self.type == "timeline":
|
||||
dlg = wx.MessageDialog(self, _(u"Do you really want to delete this timeline?"), _(u"Attention"), style=wx.ICON_QUESTION|wx.YES_NO)
|
||||
if dlg.ShowModal() == wx.ID_YES:
|
||||
names = config.main["other_buffers"]["timelines"]
|
||||
user = self.name_buffer
|
||||
log.info(u"Deleting %s's timeline" % user)
|
||||
if user in names:
|
||||
names.remove(user)
|
||||
self.db.settings.pop(user)
|
||||
pos = self.db.settings["buffers"].index(user)
|
||||
self.db.settings["buffers"].remove(user)
|
||||
return pos
|
||||
elif self.type == "buffer":
|
||||
output.speak(_(u"This buffer is not a timeline; it can't be deleted."))
|
||||
return None
|
||||
|
||||
def remove_invalid_buffer(self):
|
||||
if self.type == "timeline":
|
||||
names = config.main["other_buffers"]["timelines"]
|
||||
user = self.name_buffer
|
||||
log.info(u"Deleting %s's timeline" % user)
|
||||
if user in names:
|
||||
names.remove(user)
|
||||
self.db.settings.pop(user)
|
||||
pos = self.db.settings["buffers"].index(user)
|
||||
self.db.settings["buffers"].remove(user)
|
||||
return pos
|
||||
|
||||
def Remove(self, ev):
|
||||
# try:
|
||||
self.list.remove_item(ev.GetItem())
|
||||
# except:
|
||||
# log.error(u"Cannot delete the %s item from list " % str(ev.GetItem()))
|
||||
|
||||
def destroy_status(self, ev):
|
||||
index = self.list.get_selected()
|
||||
try:
|
||||
self.twitter.twitter.destroy_status(id=self.db.settings[self.name_buffer][index]["id"])
|
||||
self.db.settings[self.name_buffer].pop(index)
|
||||
self.list.remove_item(index)
|
||||
if index > 0:
|
||||
self.list.select_item(index-1)
|
||||
except:
|
||||
sound.player.play("error.ogg")
|
||||
|
||||
def onFocus(self, ev):
|
||||
if self.db.settings[self.name_buffer][self.list.get_selected()].has_key("retweeted_status"): tweet = self.db.settings[self.name_buffer][self.list.get_selected()]["retweeted_status"]
|
||||
else: tweet = self.db.settings[self.name_buffer][self.list.get_selected()]
|
||||
if config.main["general"]["relative_times"] == True:
|
||||
# On windows we need only put the new date on the column, but under linux and mac it isn't possible.
|
||||
if self.system == "Windows":
|
||||
original_date = datetime.datetime.strptime(tweet["created_at"], "%a %b %d %H:%M:%S +0000 %Y")
|
||||
date = original_date-datetime.timedelta(seconds=-self.db.settings["utc_offset"])
|
||||
ts = prettydate(original_date)
|
||||
self.list.list.SetStringItem(self.list.get_selected(), 2, ts)
|
||||
else:
|
||||
self.list.list.SetString(self.list.get_selected(), " ".join(self.compose_function(self.db.settings[self.name_buffer][self.list.get_selected()], self.db)))
|
||||
if twitter.utils.is_audio(tweet):
|
||||
sound.player.play("audio.ogg", False)
|
||||
|
||||
def start_streams(self):
|
||||
if self.name_buffer == "sent":
|
||||
num = twitter.starting.start_sent(self.db, self.twitter, self.name_buffer, self.function, param=self.argumento)
|
||||
else:
|
||||
# try:
|
||||
if self.argumento != None:
|
||||
num = twitter.starting.start_stream(self.db, self.twitter, self.name_buffer, self.function, param=self.argumento)
|
||||
else:
|
||||
num = twitter.starting.start_stream(self.db, self.twitter, self.name_buffer, self.function)
|
||||
# except TwythonError:
|
||||
# raise TwythonError
|
||||
# self.parent.delete_invalid_timeline()
|
||||
if self.sound != "" and num > 0 and self.name_buffer != "home_timeline" and self.name_buffer != "sent": sound.player.play(self.sound)
|
||||
return num
|
||||
|
||||
def get_more_items(self):
|
||||
if config.main["general"]["reverse_timelines"] == False:
|
||||
last_id = self.db.settings[self.name_buffer][0]["id"]
|
||||
else:
|
||||
last_id = self.db.settings[self.name_buffer][-1]["id"]
|
||||
try:
|
||||
items = twitter.starting.get_more_items(self.function, self.twitter, count=config.main["general"]["max_tweets_per_call"], max_id=last_id)
|
||||
except TwythonError as e:
|
||||
output.speak(e.message)
|
||||
for i in items:
|
||||
if config.main["general"]["reverse_timelines"] == False:
|
||||
self.db.settings[self.name_buffer].insert(0, i)
|
||||
else:
|
||||
self.db.settings[self.name_buffer].append(i)
|
||||
if config.main["general"]["reverse_timelines"] == False:
|
||||
for i in items:
|
||||
tweet = self.compose_function(i, self.db)
|
||||
self.list.insert_item(True, *tweet)
|
||||
else:
|
||||
for i in items:
|
||||
tweet = self.compose_function(i, self.db)
|
||||
self.list.insert_item(False, *tweet)
|
||||
output.speak(_(u"%s items retrieved") % (len(items)))
|
||||
|
||||
def put_items(self, num):
|
||||
if self.list.get_count() == 0:
|
||||
for i in self.db.settings[self.name_buffer]:
|
||||
tweet = self.compose_function(i, self.db)
|
||||
self.list.insert_item(False, *tweet)
|
||||
self.set_list_position()
|
||||
elif self.list.get_count() > 0:
|
||||
if config.main["general"]["reverse_timelines"] == False:
|
||||
for i in self.db.settings[self.name_buffer][:num]:
|
||||
tweet = self.compose_function(i, self.db)
|
||||
self.list.insert_item(False, *tweet)
|
||||
else:
|
||||
for i in self.db.settings[self.name_buffer][0:num]:
|
||||
tweet = self.compose_function(i, self.db)
|
||||
self.list.insert_item(True, *tweet)
|
||||
|
||||
def onDm(self, ev):
|
||||
if self.name_buffer == "sent": return
|
||||
if self.name_buffer == "direct_messages":
|
||||
self.onResponse(ev)
|
||||
else:
|
||||
user = self.db.settings[self.name_buffer][self.list.get_selected()]["user"]["screen_name"]
|
||||
dlg = gui.dialogs.message.dm(_("Direct message to %s") % (user,), "", "", self)
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
call_threaded(self.twitter.api_call, call_name="send_direct_message", _sound="dm_sent.ogg", text=dlg.text.GetValue(), screen_name=dlg.cb.GetValue())
|
||||
# dlg.Destroy()
|
||||
if ev != None:
|
||||
self.list.list.SetFocus()
|
||||
|
||||
def post_status(self, ev=None):
|
||||
text = gui.dialogs.message.tweet(_(u"Write the tweet here"), _(u"Tweet"), "", self)
|
||||
if text.ShowModal() == wx.ID_OK:
|
||||
if text.image == None:
|
||||
call_threaded(self.twitter.api_call, call_name="update_status", _sound="tweet_send.ogg", status=text.text.GetValue())
|
||||
else:
|
||||
call_threaded(self.twitter.api_call, call_name="update_status_with_media", _sound="tweet_send.ogg", status=text.text.GetValue(), media=text.file)
|
||||
# text.Destroy()
|
||||
if ev != None: self.list.list.SetFocus()
|
||||
|
||||
def onRetweet(self, ev):
|
||||
if self.name_buffer != "direct_messages":
|
||||
id=self.db.settings[self.name_buffer][self.list.get_selected()]["id"]
|
||||
ask = wx.MessageDialog(self.parent, _(u"Would you like to add a comment to this tweet?"), _("Retweet"), wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION)
|
||||
response = ask.ShowModal()
|
||||
if response == wx.ID_YES:
|
||||
dlg = gui.dialogs.message.retweet(_(u"Add your comment to the tweet"), "", u"“@%s: %s ”" % (self.db.settings[self.name_buffer][self.list.get_selected()]["user"]["screen_name"], self.db.settings[self.name_buffer][self.list.get_selected()]["text"]), self)
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
if dlg.image == None:
|
||||
call_threaded(self.twitter.api_call, call_name="update_status", _sound="retweet_send.ogg", status=dlg.text.GetValue(), in_reply_to_status_id=dlg.in_reply_to)
|
||||
else:
|
||||
call_threaded(self.twitter.call_api, call_name="update_status_with_media", _sound="retweet_send.ogg", status=dlg.text.GetValue(), in_reply_to_status_id=text.in_reply_to, media=dlg.file)
|
||||
# dlg.Destroy()
|
||||
if ev != None:
|
||||
self.list.list.SetFocus()
|
||||
elif response == wx.ID_NO:
|
||||
call_threaded(self.twitter.api_call, call_name="retweet", _sound="retweet_send.ogg", id=id)
|
||||
if ev != None: self.list.list.SetFocus()
|
||||
ask.Destroy()
|
||||
|
||||
def onResponse(self, ev):
|
||||
if self.name_buffer == "sent": return
|
||||
dlg = gui.dialogs.message.reply(_(u"Reply to %s") % (self.db.settings[self.name_buffer][self.list.get_selected()]["user"]["screen_name"]), "", u"@%s " % (self.db.settings[self.name_buffer][self.list.get_selected()]["user"]["screen_name"]), self)
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
if dlg.image == None:
|
||||
call_threaded(self.twitter.api_call, call_name="update_status", _sound="reply_send.ogg", in_reply_to_status_id=dlg.in_reply_to, status=dlg.text.GetValue())
|
||||
else:
|
||||
call_threaded(self.twitter.api_call, call_name="update_status_with_media", _sound="reply_send.ogg", in_reply_to_status_id=dlg.in_reply_to, status=dlg.text.GetValue(), media=dlg.file)
|
||||
# dlg.Destroy()
|
||||
if ev != None: self.list.list.SetFocus()
|
||||
|
||||
def update(self, ev):
|
||||
data = ev.GetItem()
|
||||
announce = ev.GetAnnounce()
|
||||
if config.main["general"]["reverse_timelines"] == False: self.db.settings[self.name_buffer].append(data)
|
||||
else: self.db.settings[self.name_buffer].insert(0, data)
|
||||
tweet = self.compose_function(data, self.db)
|
||||
self.list.insert_item(config.main["general"]["reverse_timelines"], *tweet)
|
||||
if self.name_buffer not in config.main["other_buffers"]["muted_buffers"]:
|
||||
if self.sound != "": sound.player.play(self.sound)
|
||||
if announce != "": output.speak(announce)
|
||||
if self.name_buffer in config.main["other_buffers"]["autoread_buffers"]:
|
||||
output.speak(" ".join(tweet[:2]))
|
||||
|
||||
def interact(self, ev):
|
||||
try:
|
||||
if self.db.settings[self.name_buffer][self.list.get_selected()].has_key("retweeted_status"): tweet = self.db.settings[self.name_buffer][self.list.get_selected()]["retweeted_status"]
|
||||
else: tweet = self.db.settings[self.name_buffer][self.list.get_selected()]
|
||||
urls = twitter.utils.find_urls_in_text(tweet["text"])
|
||||
except:
|
||||
urls = []
|
||||
if type(ev) is str: event = ev
|
||||
else:
|
||||
if ev.GetKeyCode() == wx.WXK_RETURN and ev.ControlDown(): event = "audio"
|
||||
elif ev.GetKeyCode() == wx.WXK_RETURN: event = "url"
|
||||
elif ev.GetKeyCode() == wx.WXK_F5: event = "volume_down"
|
||||
elif ev.GetKeyCode() == wx.WXK_F6: event = "volume_up"
|
||||
elif ev.GetKeyCode() == wx.WXK_DELETE and ev.ShiftDown(): event = "clear_list"
|
||||
elif ev.GetKeyCode() == wx.WXK_DELETE: event = "delete_item"
|
||||
else:
|
||||
ev.Skip()
|
||||
return
|
||||
if event == "audio" and len(urls) > 0:
|
||||
self.streamer(urls[0])
|
||||
elif event == "url":
|
||||
if len(urls) == 0: return
|
||||
elif len(urls) == 1:
|
||||
output.speak(_(u"Opening URL..."), True)
|
||||
webbrowser.open(urls[0])
|
||||
elif len(urls) > 1:
|
||||
gui.dialogs.urlList.urlList(urls).ShowModal()
|
||||
elif event == "volume_down":
|
||||
if config.main["sound"]["volume"] > 0.05:
|
||||
config.main["sound"]["volume"] = config.main["sound"]["volume"]-0.05
|
||||
sound.player.play("volume_changed.ogg", False)
|
||||
if hasattr(self.parent, "audioStream"):
|
||||
self.parent.audioStream.stream.volume = config.main["sound"]["volume"]
|
||||
elif event == "volume_up":
|
||||
if config.main["sound"]["volume"] < 0.95:
|
||||
config.main["sound"]["volume"] = config.main["sound"]["volume"]+0.05
|
||||
sound.player.play("volume_changed.ogg", False)
|
||||
if hasattr(self.parent, "audioStream"):
|
||||
self.parent.audioStream.stream.volume = config.main["sound"]["volume"]
|
||||
elif event == "clear_list" and self.list.get_count() > 0:
|
||||
dlg = wx.MessageDialog(self, _(u"Do you really want to empty this buffer? It's tweets will be removed from the list but not from Twitter"), _(u"Empty buffer"), wx.ICON_QUESTION|wx.YES_NO)
|
||||
if dlg.ShowModal() == wx.ID_YES:
|
||||
self.db.settings[self.name_buffer] = []
|
||||
self.list.clear()
|
||||
elif event == "delete_item":
|
||||
dlg = wx.MessageDialog(self, _(u"Do you really want to delete this message?"), _(u"Delete"), wx.ICON_QUESTION|wx.YES_NO)
|
||||
if dlg.ShowModal() == wx.ID_YES:
|
||||
self.destroy_status(wx.EVT_MENU)
|
||||
else:
|
||||
return
|
||||
try:
|
||||
ev.Skip()
|
||||
except:
|
||||
pass
|
||||
|
||||
def streamer(self, url):
|
||||
if hasattr(self.parent, "audioStream"):
|
||||
if self.parent.audioStream.stream.is_active() == 0:
|
||||
output.speak(_(u"Playing..."))
|
||||
self.parent.audioStream = sound.urlStream(url)
|
||||
try:
|
||||
self.parent.audioStream.prepare()
|
||||
self.parent.audioStream.play()
|
||||
except:
|
||||
del self.parent.audioStream
|
||||
output.speak(_(u"Unable to play audio."))
|
||||
else:
|
||||
output.speak(_(u"Audio stopped."))
|
||||
self.parent.audioStream.stream.stop()
|
||||
else:
|
||||
output.speak(_(u"Playing..."))
|
||||
self.parent.audioStream = sound.urlStream(url)
|
||||
try:
|
||||
self.parent.audioStream.prepare()
|
||||
self.parent.audioStream.play()
|
||||
except:
|
||||
output.speak(_(u"Unable to play audio."))
|
||||
del self.parent.audioStream
|
||||
|
||||
def set_list_position(self):
|
||||
if config.main["general"]["reverse_timelines"] == False:
|
||||
self.list.select_item(len(self.db.settings[self.name_buffer])-1)
|
||||
else:
|
||||
self.list.select_item(0)
|
48
src/gui/buffers/dm.py
Normal file
48
src/gui/buffers/dm.py
Normal file
@@ -0,0 +1,48 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
############################################################
|
||||
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
############################################################
|
||||
import wx
|
||||
import sound
|
||||
import gui.dialogs
|
||||
import logging as original_logger
|
||||
from base import basePanel
|
||||
from mysc.thread_utils import call_threaded
|
||||
log = original_logger.getLogger("buffers.base")
|
||||
|
||||
class dmPanel(basePanel):
|
||||
def __init__(self, parent, window, name_buffer, function, argumento=None, sound=""):
|
||||
""" Class to DM'S. Reply and retweet buttons are not showed and they have your delete method for dm's."""
|
||||
super(dmPanel, self).__init__(parent, window, name_buffer, function, argumento=argumento, sound=sound)
|
||||
self.retweetBtn.Disable()
|
||||
self.responseBtn.Disable()
|
||||
|
||||
def destroy_status(self, ev):
|
||||
index = self.list.get_selected()
|
||||
try:
|
||||
self.twitter.twitter.destroy_direct_message(id=self.db.settings[self.name_buffer][index]["id"])
|
||||
self.db.settings[self.name_buffer].pop(index)
|
||||
self.remove_item(index)
|
||||
except:
|
||||
sound.player.play("error.ogg")
|
||||
|
||||
def onResponse(self, ev):
|
||||
dlg = gui.dialogs.message.dm(_("Direct message to %s") % (self.db.settings[self.name_buffer][self.list.get_selected()]["sender"]["screen_name"]), "", "", self)
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
call_threaded(self.twitter.api_call, call_name="send_direct_message", _sound="dm_sent.ogg", text=dlg.text.GetValue(), screen_name=dlg.cb.GetValue())
|
||||
if ev != None:
|
||||
self.list.list.SetFocus()
|
134
src/gui/buffers/events.py
Normal file
134
src/gui/buffers/events.py
Normal file
@@ -0,0 +1,134 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
############################################################
|
||||
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
############################################################
|
||||
import wx
|
||||
import sound
|
||||
import config
|
||||
import platform
|
||||
import gui.dialogs
|
||||
import output
|
||||
import logging as original_logger
|
||||
from multiplatform_widgets import widgets
|
||||
from mysc import event
|
||||
from mysc.thread_utils import call_threaded
|
||||
log = original_logger.getLogger("buffers.base")
|
||||
|
||||
class eventsPanel(wx.Panel):
|
||||
""" Buffer to show events. Different than tweets or people."""
|
||||
|
||||
def get_more_items(self):
|
||||
output.speak(_(u"This action is not supported for this buffer"))
|
||||
|
||||
def bind_events(self):
|
||||
self.Bind(event.MyEVT_OBJECT, self.update)
|
||||
|
||||
def put_items(self, items):
|
||||
pass
|
||||
|
||||
def get_selected_text(self):
|
||||
if self.list.get_count() == 0: return _(u"Empty")
|
||||
if self.system == "Windows":
|
||||
return "%s. %s" % (self.list.list.GetItemText(self.list.get_selected()), self.list.list.GetItemText(self.list.get_selected(), 1))
|
||||
else:
|
||||
return self.list.list.GetStringSelection()
|
||||
|
||||
def get_message(self, dialog=False):
|
||||
return self.get_selected_text()
|
||||
|
||||
def __init__(self, parent, window, sound=""):
|
||||
self.type = "event"
|
||||
self.system = platform.system()
|
||||
self.name_buffer = "events"
|
||||
self.parent = window
|
||||
self.sound = "new_event.ogg"
|
||||
wx.Panel.__init__(self, parent)
|
||||
sizer = wx.BoxSizer()
|
||||
self.list = widgets.list(self, _(u"Date"), _(u"Event"), size=(600,600), style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_VRULES)
|
||||
self.tweet = wx.Button(self, -1, _(u"Tweet"))
|
||||
self.tweet.Bind(wx.EVT_BUTTON, self.post_status)
|
||||
self.delete_event = wx.Button(self, -1, _(u"Remove event"))
|
||||
self.delete_event.Bind(wx.EVT_BUTTON, self.on_delete_event)
|
||||
self.bind_events()
|
||||
|
||||
def on_delete_event(self, ev):
|
||||
self.list.remove_item(self.get_selected())
|
||||
|
||||
def remove_buffer(self):
|
||||
return None
|
||||
|
||||
def start_streams(self):
|
||||
return 0
|
||||
|
||||
def post_status(self, ev=None):
|
||||
text = gui.dialogs.message.tweet(_(u"Write the tweet here"), _(u"Tweet"), "", self.parent)
|
||||
if text.ShowModal() == wx.ID_OK:
|
||||
if text.image == None:
|
||||
call_threaded(self.parent.twitter.api_call, call_name="update_status", _sound="tweet_send.ogg", status=text.text.GetValue())
|
||||
else:
|
||||
call_threaded(self.parent.twitter.api_call, call_name="update_status_with_media", _sound="tweet_send.ogg", status=text.text.GetValue(), media=text.file)
|
||||
# text.Destroy()
|
||||
if ev != None: self.list.list.SetFocus()
|
||||
|
||||
def update(self, ev):
|
||||
tweet = ev.GetItem()
|
||||
announce = ev.GetAnnounce()
|
||||
self.list.insert_item(config.main["general"]["reverse_timelines"], *tweet)
|
||||
if self.list.get_count() == 1:
|
||||
self.list.select_item(0)
|
||||
if self.name_buffer not in config.main["other_buffers"]["muted_buffers"]:
|
||||
if self.sound != "": sound.player.play(self.sound)
|
||||
# if announce != "": output.speak(announce)
|
||||
if self.name_buffer in config.main["other_buffers"]["autoread_buffers"]:
|
||||
output.speak(" ".join(tweet))
|
||||
|
||||
def interact(self, ev):
|
||||
if type(ev) is str: event = ev
|
||||
else:
|
||||
if ev.GetKeyCode() == wx.WXK_F5: event = "volume_down"
|
||||
elif ev.GetKeyCode() == wx.WXK_F6: event = "volume_up"
|
||||
elif ev.GetKeyCode() == wx.WXK_DELETE and ev.ShiftDown(): event = "clear_list"
|
||||
elif ev.GetKeyCode() == wx.WXK_DELETE: event = "delete_item"
|
||||
else:
|
||||
ev.Skip()
|
||||
return
|
||||
if event == "volume_down":
|
||||
if config.main["sound"]["volume"] > 0.05:
|
||||
config.main["sound"]["volume"] = config.main["sound"]["volume"]-0.05
|
||||
sound.player.play("volume_changed.ogg", False)
|
||||
if hasattr(self.parent, "audioStream"):
|
||||
self.parent.audioStream.stream.volume = config.main["sound"]["volume"]
|
||||
elif event == "volume_up":
|
||||
if config.main["sound"]["volume"] < 0.95:
|
||||
config.main["sound"]["volume"] = config.main["sound"]["volume"]+0.05
|
||||
sound.player.play("volume_changed.ogg", False)
|
||||
if hasattr(self.parent, "audioStream"):
|
||||
self.parent.audioStream.stream.volume = config.main["sound"]["volume"]
|
||||
elif event == "clear_list" and self.get_count() > 0:
|
||||
dlg = wx.MessageDialog(self, _(u"Do you really want to empty this buffer? It's tweets will be removed from the list but not from Twitter"), _(u"Empty buffer"), wx.ICON_QUESTION|wx.YES_NO)
|
||||
if dlg.ShowModal() == wx.ID_YES:
|
||||
self.list.clear()
|
||||
elif event == "delete_item":
|
||||
dlg = wx.MessageDialog(self, _(u"Do you really want to delete this message?"), _(u"Delete"), wx.ICON_QUESTION|wx.YES_NO)
|
||||
if dlg.ShowModal() == wx.ID_YES:
|
||||
self.list.remove_item(self.list.get_selected())
|
||||
else:
|
||||
return
|
||||
try:
|
||||
ev.Skip()
|
||||
except:
|
||||
pass
|
62
src/gui/buffers/favourites.py
Normal file
62
src/gui/buffers/favourites.py
Normal file
@@ -0,0 +1,62 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
############################################################
|
||||
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
############################################################
|
||||
import wx
|
||||
import twitter
|
||||
import config
|
||||
import sound
|
||||
import logging as original_logger
|
||||
from base import basePanel
|
||||
log = original_logger.getLogger("buffers.base")
|
||||
|
||||
class favsPanel(basePanel):
|
||||
def __init__(self, parent, window, name_buffer, argumento=None, sound=""):
|
||||
super(favsPanel, self).__init__(parent, window, name_buffer, function="", argumento=argumento, sound=sound)
|
||||
self.type = "favourites_timeline"
|
||||
|
||||
def start_streams(self):
|
||||
num = twitter.starting.get_favourites_timeline(self.db, self.twitter, self.name_buffer, param=self.argumento, count=200)
|
||||
if self.sound != "" and num > 0:
|
||||
sound.player.play(self.sound)
|
||||
if self.list.get_count() > 0: self.put_items(num)
|
||||
return num
|
||||
return num
|
||||
|
||||
def remove_buffer(self):
|
||||
dlg = wx.MessageDialog(self, _(u"Do you really want to delete this favourites timeline?"), _(u"Attention"), style=wx.ICON_QUESTION|wx.YES_NO)
|
||||
if dlg.ShowModal() == wx.ID_YES:
|
||||
names = config.main["other_buffers"]["favourites_timelines"]
|
||||
user = self.argumento
|
||||
log.info(u"Deleting %s's timeline" % user)
|
||||
if user in names:
|
||||
names.remove(user)
|
||||
self.db.settings.pop(self.name_buffer)
|
||||
pos = self.db.settings["buffers"].index(self.name_buffer)
|
||||
self.db.settings["buffers"].remove(self.name_buffer)
|
||||
return pos
|
||||
|
||||
def remove_invalid_buffer(self):
|
||||
names = config.main["other_buffers"]["favourites_timelines"]
|
||||
user = self.name_buffer[:-5]
|
||||
log.info(u"Deleting %s's timeline" % user)
|
||||
if user in names:
|
||||
names.remove(user)
|
||||
self.db.settings.pop(self.name_buffer)
|
||||
pos = self.db.settings["buffers"].index(self.name_buffer)
|
||||
self.db.settings["buffers"].remove(self.name_buffer)
|
||||
return pos
|
68
src/gui/buffers/lists.py
Normal file
68
src/gui/buffers/lists.py
Normal file
@@ -0,0 +1,68 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
############################################################
|
||||
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
############################################################
|
||||
import wx
|
||||
import sound
|
||||
import config
|
||||
import twitter
|
||||
import gui.dialogs
|
||||
import logging as original_logger
|
||||
from base import basePanel
|
||||
from mysc.thread_utils import call_threaded
|
||||
log = original_logger.getLogger("buffers.base")
|
||||
|
||||
class listPanel(basePanel):
|
||||
def __init__(self, parent, window, name_buffer, argumento="", sound=""):
|
||||
super(listPanel, self).__init__(parent, window, name_buffer, argumento=argumento, sound=sound)
|
||||
self.type = "list"
|
||||
self.users = []
|
||||
self.sound = "list_tweet.ogg"
|
||||
|
||||
def start_streams(self):
|
||||
self.retrieve_ids()
|
||||
num = twitter.starting.start_list(self.db, self.twitter, self.name_buffer, list_id=self.argumento)
|
||||
return num
|
||||
|
||||
def retrieve_ids(self):
|
||||
self.users = twitter.starting.get_users_list(self.twitter, self.argumento)
|
||||
|
||||
def remove_buffer(self):
|
||||
if self.type == "list":
|
||||
dlg = wx.MessageDialog(self, _(u"Do you really want to delete this list?"), _(u"Attention"), style=wx.ICON_QUESTION|wx.YES_NO)
|
||||
if dlg.ShowModal() == wx.ID_YES:
|
||||
names = config.main["other_buffers"]["lists"]
|
||||
user = self.name_buffer[:-5]
|
||||
log.info(u"Deleting %s's list" % user)
|
||||
if user in names:
|
||||
names.remove(user)
|
||||
self.db.settings.pop(self.name_buffer)
|
||||
pos = self.db.settings["buffers"].index(self.name_buffer)
|
||||
self.db.settings["buffers"].remove(self.name_buffer)
|
||||
return pos
|
||||
|
||||
def remove_invalid_buffer(self):
|
||||
if self.type == "list":
|
||||
names = config.main["other_buffers"]["lists"]
|
||||
user = self.name_buffer[:-5]
|
||||
log.info(u"Deleting %s's list" % user)
|
||||
if user in names:
|
||||
names.remove(user)
|
||||
self.db.settings.pop(self.name_buffer)
|
||||
pos = self.db.settings["buffers"].index(self.name_buffer)
|
||||
self.db.settings["buffers"].remove(self.name_buffer)
|
||||
return pos
|
37
src/gui/buffers/panels.py
Normal file
37
src/gui/buffers/panels.py
Normal file
@@ -0,0 +1,37 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
############################################################
|
||||
# Copyright (c) 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
############################################################
|
||||
import wx
|
||||
from multiplatform_widgets import widgets
|
||||
|
||||
class accountPanel(wx.Panel):
|
||||
def __init__(self, parent):
|
||||
super(accountPanel, self).__init__(parent=parent)
|
||||
self.type = "account"
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self.list = widgets.list(self, _(u"Announce"))
|
||||
sizer.Add(self.list.list, 0, wx.ALL, 5)
|
||||
self.SetSizer(sizer)
|
||||
|
||||
class emptyPanel(accountPanel):
|
||||
def __init__(self, parent):
|
||||
super(emptyPanel, self).__init__(parent=parent)
|
||||
self.type = "empty"
|
||||
|
||||
def get_more_items(self):
|
||||
output.speak(_(u"This action is not supported for this buffer"))
|
142
src/gui/buffers/people.py
Normal file
142
src/gui/buffers/people.py
Normal file
@@ -0,0 +1,142 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
############################################################
|
||||
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
############################################################
|
||||
import wx
|
||||
import sound
|
||||
import config
|
||||
import twitter
|
||||
import gui.dialogs
|
||||
import logging as original_logger
|
||||
import output
|
||||
from multiplatform_widgets import widgets
|
||||
from mysc import event
|
||||
from base import basePanel
|
||||
from mysc.thread_utils import call_threaded
|
||||
from twython import TwythonError
|
||||
log = original_logger.getLogger("buffers.base")
|
||||
|
||||
class peoplePanel(basePanel):
|
||||
""" Buffer used to show people."""
|
||||
def bind_events(self):
|
||||
self.Bind(event.MyEVT_OBJECT, self.update)
|
||||
self.Bind(event.MyEVT_DELETED, self.Remove)
|
||||
self.list.list.Bind(wx.EVT_CHAR_HOOK, self.interact)
|
||||
|
||||
def create_list(self):
|
||||
self.list = widgets.list(self, _(u"User"), style=wx.LC_REPORT|wx.LC_SINGLE_SEL, size=(800, 800))
|
||||
|
||||
def __init__(self, parent, window, name_buffer, function, argumento=None, sound="", timeline=False):
|
||||
self.type = "people"
|
||||
super(peoplePanel, self).__init__(parent, window, name_buffer, function, argumento=argumento, sound=sound)
|
||||
self.responseBtn.SetLabel(_(u"Mention"))
|
||||
self.retweetBtn.Disable()
|
||||
self.compose_function = twitter.compose.compose_followers_list
|
||||
|
||||
def onDm(self, ev):
|
||||
if self.name_buffer == "sent": return
|
||||
if self.name_buffer == "direct_messages":
|
||||
self.onResponse(ev)
|
||||
else:
|
||||
user = self.db.settings[self.name_buffer][self.list.get_selected()]["screen_name"]
|
||||
dlg = gui.dialogs.message.dm(_("Direct message to %s") % (user,), "", "", self)
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
call_threaded(self.twitter.api_call, call_name="send_direct_message", _sound="dm_sent.ogg", text=dlg.text.GetValue(), screen_name=dlg.cb.GetValue())
|
||||
# dlg.Destroy()
|
||||
if ev != None:
|
||||
self.list.list.SetFocus()
|
||||
|
||||
def onResponse(self, ev):
|
||||
dlg = gui.dialogs.message.reply(_(u"Reply to %s") % (self.db.settings[self.name_buffer][self.list.get_selected()]["screen_name"]), "", u"@%s " % (self.db.settings[self.name_buffer][self.list.get_selected()]["screen_name"]), self)
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
if dlg.image == None:
|
||||
call_threaded(self.twitter.api_call, call_name="update_status", _sound="reply_send.ogg", in_reply_to_status_id=dlg.in_reply_to, status=dlg.text.GetValue())
|
||||
else:
|
||||
call_threaded(self.twitter.api_call, call_name="update_status_with_media", _sound="reply_send.ogg", in_reply_to_status_id=dlg.in_reply_to, status=dlg.text.GetValue(), media=dlg.file)
|
||||
# dlg.Destroy()
|
||||
if ev != None: self.list.list.SetFocus()
|
||||
|
||||
def Remove(self, ev):
|
||||
try:
|
||||
index = self.list.get_selected()
|
||||
self.list.remove_item(ev.GetItem())
|
||||
except:
|
||||
log.error("Unable to delete element %s from the list %s" % (str(ev.GetItem(), self.name_buffer)))
|
||||
|
||||
def start_streams(self):
|
||||
num = twitter.starting.start_followers(self.db, self.twitter, self.name_buffer, self.function, param=self.argumento)
|
||||
# sound.player.play(self.sound)
|
||||
return num
|
||||
|
||||
def put_items(self, num):
|
||||
if self.list.get_count() > 0:
|
||||
self.list.clear()
|
||||
for i in self.db.settings[self.name_buffer]:
|
||||
f = self.compose_function(i, self.db)
|
||||
self.list.insert_item(False, *f)
|
||||
self.set_list_position()
|
||||
|
||||
def get_more_items(self):
|
||||
if self.name_buffer == "followers": cursor = twitter.starting.followers_cursor
|
||||
elif self.name_buffer == "friends": cursor = twitter.starting.friends_cursor
|
||||
try:
|
||||
items = twitter.starting.get_more_items(self.function, self.twitter, users=True, name=self.name_buffer, count=config.main["general"]["max_tweets_per_call"], cursor=cursor)
|
||||
except TwythonError as e:
|
||||
output.speak(e.message)
|
||||
return
|
||||
for i in items:
|
||||
if config.main["general"]["reverse_timelines"] == False:
|
||||
self.db.settings[self.name_buffer].insert(0, i)
|
||||
else:
|
||||
self.db.settings[self.name_buffer].append(i)
|
||||
if config.main["general"]["reverse_timelines"] == False:
|
||||
for i in items:
|
||||
tweet = self.compose_function(i, self.db)
|
||||
self.list.insert_item(True, *tweet)
|
||||
else:
|
||||
for i in items:
|
||||
tweet = self.compose_function(i, self.db)
|
||||
self.list.insert_item(False, *tweet)
|
||||
output.speak(_(u"%s items retrieved") % (len(items)))
|
||||
|
||||
def interact(self, ev):
|
||||
if type(ev) is str: event = ev
|
||||
else:
|
||||
if ev.GetKeyCode() == wx.WXK_RETURN:
|
||||
event = "url"
|
||||
elif ev.GetKeyCode() == wx.WXK_F5:
|
||||
event = "volume_down"
|
||||
elif ev.GetKeyCode() == wx.WXK_F6:
|
||||
event = "volume_down"
|
||||
else:
|
||||
ev.Skip()
|
||||
return
|
||||
if event == "url":
|
||||
gui.dialogs.show_user.showUserProfile(self.parent.twitter, self.db.settings[self.name_buffer][self.list.get_selected()]["screen_name"]).ShowModal()
|
||||
elif event == "volume_down":
|
||||
if config.main["sound"]["volume"] > 0.05:
|
||||
config.main["sound"]["volume"] = config.main["sound"]["volume"]-0.05
|
||||
sound.player.play("volume_changed.ogg")
|
||||
elif event == "volume_up":
|
||||
if config.main["sound"]["volume"] < 0.95:
|
||||
config.main["sound"]["volume"] = config.main["sound"]["volume"]+0.05
|
||||
sound.player.play("volume_changed.ogg")
|
||||
if type(ev) is not str: ev.Skip()
|
||||
|
||||
def remove_buffer(self):
|
||||
pos = None
|
||||
return pos
|
51
src/gui/buffers/trends.py
Normal file
51
src/gui/buffers/trends.py
Normal file
@@ -0,0 +1,51 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
############################################################
|
||||
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
############################################################
|
||||
import wx
|
||||
import sound
|
||||
import config
|
||||
import twitter
|
||||
import gui.dialogs
|
||||
import logging as original_logger
|
||||
from base import basePanel
|
||||
log = original_logger.getLogger("buffers.base")
|
||||
|
||||
class trendPanel(basePanel):
|
||||
def __init__(self, parent, window, name_buffer, *args, **kwargs):
|
||||
super(searchPanel, self).__init__(parent, window, name_buffer, sound)
|
||||
self.type = "trend"
|
||||
self.args = kwargs
|
||||
|
||||
def start_streams(self):
|
||||
num = twitter.starting.search(self.db, self.twitter, self.name_buffer, **self.args)
|
||||
if num > 0: sound.player.play("search_updated.ogg")
|
||||
self.put_items(num)
|
||||
return num
|
||||
|
||||
def remove_buffer(self):
|
||||
dlg = wx.MessageDialog(self, _(u"Do you really want to delete this search term?"), _(u"Attention"), style=wx.ICON_QUESTION|wx.YES_NO)
|
||||
if dlg.ShowModal() == wx.ID_YES:
|
||||
names = config.main["other_buffers"]["tweet_searches"]
|
||||
user = self.name_buffer[:-7]
|
||||
log.info(u"Deleting %s's search term" % user)
|
||||
if user in names:
|
||||
names.remove(user)
|
||||
self.db.settings.pop(self.name_buffer)
|
||||
pos = self.db.settings["buffers"].index(self.name_buffer)
|
||||
self.db.settings["buffers"].remove(self.name_buffer)
|
||||
return pos
|
58
src/gui/buffers/tweet_searches.py
Normal file
58
src/gui/buffers/tweet_searches.py
Normal file
@@ -0,0 +1,58 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
############################################################
|
||||
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
############################################################
|
||||
import wx
|
||||
import sound
|
||||
import config
|
||||
import twitter
|
||||
import gui.dialogs
|
||||
import output
|
||||
import logging as original_logger
|
||||
from base import basePanel
|
||||
log = original_logger.getLogger("buffers.base")
|
||||
|
||||
class searchPanel(basePanel):
|
||||
def __init__(self, parent, window, name_buffer, *args, **kwargs):
|
||||
super(searchPanel, self).__init__(parent, window, name_buffer, sound)
|
||||
self.type = "search"
|
||||
self.args = kwargs
|
||||
|
||||
def load_search(self):
|
||||
num = self.start_streams()
|
||||
self.put_items(num)
|
||||
|
||||
def start_streams(self):
|
||||
num = twitter.starting.search(self.db, self.twitter, self.name_buffer, **self.args)
|
||||
if num > 0: sound.player.play("search_updated.ogg")
|
||||
return num
|
||||
|
||||
def remove_buffer(self):
|
||||
dlg = wx.MessageDialog(self, _(u"Do you really want to delete this search term?"), _(u"Attention"), style=wx.ICON_QUESTION|wx.YES_NO)
|
||||
if dlg.ShowModal() == wx.ID_YES:
|
||||
names = config.main["other_buffers"]["tweet_searches"]
|
||||
user = self.name_buffer[:-7]
|
||||
log.info(u"Deleting %s's search term" % user)
|
||||
if user in names:
|
||||
names.remove(user)
|
||||
self.db.settings.pop(self.name_buffer)
|
||||
pos = self.db.settings["buffers"].index(self.name_buffer)
|
||||
self.db.settings["buffers"].remove(self.name_buffer)
|
||||
return pos
|
||||
|
||||
def get_more_items(self):
|
||||
output.speak(_(u"This action is not supported for this buffer"))
|
61
src/gui/buffers/user_searches.py
Normal file
61
src/gui/buffers/user_searches.py
Normal file
@@ -0,0 +1,61 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
############################################################
|
||||
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
############################################################
|
||||
import wx
|
||||
import twitter
|
||||
import logging as original_logger
|
||||
import sound
|
||||
from people import peoplePanel
|
||||
from mysc import event
|
||||
from multiplatform_widgets import widgets
|
||||
log = original_logger.getLogger("buffers.base")
|
||||
|
||||
class searchUsersPanel(peoplePanel):
|
||||
def create_list(self):
|
||||
""" Returns the list for put the tweets here."""
|
||||
self.list = widgets.list(self, _(u"User"), style=wx.LC_REPORT|wx.LC_SINGLE_SEL, size=(800, 800))
|
||||
|
||||
# def bind_events(self):
|
||||
# self.Bind(event.MyEVT_OBJECT, self.update)
|
||||
# self.list.list.Bind(wx.EVT_CHAR_HOOK, self.interact)
|
||||
|
||||
def __init__(self, parent, window, name_buffer, *args, **kwargs):
|
||||
super(searchUsersPanel, self).__init__(parent, window, name_buffer, function=None)
|
||||
self.compose_function = twitter.compose.compose_followers_list
|
||||
self.create_list()
|
||||
self.args = args
|
||||
self.kwargs = kwargs
|
||||
self.type = "timeline"
|
||||
|
||||
def start_streams(self):
|
||||
num = twitter.starting.search_users(self.db, self.twitter, self.name_buffer, **self.kwargs)
|
||||
if num > 0: sound.player.play("search_updated.ogg")
|
||||
# self.put_items(num)
|
||||
return num
|
||||
|
||||
def load_search(self):
|
||||
num = self.start_streams()
|
||||
self.put_items(num)
|
||||
|
||||
def remove_buffer(self):
|
||||
dlg = wx.MessageDialog(self, _(u"Do you really want to delete this search term?"), _(u"Attention"), style=wx.ICON_QUESTION|wx.YES_NO)
|
||||
if dlg.ShowModal() == wx.ID_YES:
|
||||
self.db.settings.pop(self.name_buffer)
|
||||
pos = self.db.settings["buffers"].index(self.name_buffer)
|
||||
self.db.settings["buffers"].remove(self.name_buffer)
|
||||
return pos
|
1
src/gui/dialogs/__init__.py
Normal file
1
src/gui/dialogs/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
import message, urlList, follow, utils, show_user, update_profile, configuration, lists, search
|
420
src/gui/dialogs/configuration.py
Normal file
420
src/gui/dialogs/configuration.py
Normal file
@@ -0,0 +1,420 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
############################################################
|
||||
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
############################################################
|
||||
import wx
|
||||
import config
|
||||
#import gui
|
||||
from gui import buffers
|
||||
import sound as snd
|
||||
import sound_lib
|
||||
import languageHandler
|
||||
import logging as original_logger
|
||||
import os
|
||||
import webbrowser
|
||||
import paths
|
||||
import platform
|
||||
from mysc import restart
|
||||
log = original_logger.getLogger("configuration")
|
||||
|
||||
system = platform.system()
|
||||
class general(wx.Panel):
|
||||
def __init__(self, parent):
|
||||
wx.Panel.__init__(self, parent)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
language = wx.StaticText(self, -1, _(u"Language"))
|
||||
self.langs = languageHandler.getAvailableLanguages()
|
||||
langs = []
|
||||
[langs.append(i[1]) for i in self.langs]
|
||||
self.codes = []
|
||||
[self.codes.append(i[0]) for i in self.langs]
|
||||
self.language = wx.ListBox(self, -1, choices=langs)
|
||||
id = self.codes.index(config.main["general"]["language"])
|
||||
self.language.SetSelection(id)
|
||||
self.language.SetSize(self.language.GetBestSize())
|
||||
langBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
langBox.Add(language, 0, wx.ALL, 5)
|
||||
langBox.Add(self.language, 0, wx.ALL, 5)
|
||||
sizer.Add(langBox, 0, wx.ALL, 5)
|
||||
self.relative_time = wx.CheckBox(self, -1, _(U"Relative times"))
|
||||
self.relative_time.SetValue(config.main["general"]["relative_times"])
|
||||
sizer.Add(self.relative_time, 0, wx.ALL, 5)
|
||||
if platform.system() == "Windows":
|
||||
self.disable_sapi5 = wx.CheckBox(self, -1, _(u"Activate Sapi5 when any other screen reader is not being run"))
|
||||
self.disable_sapi5.SetValue(config.main["general"]["voice_enabled"])
|
||||
sizer.Add(self.disable_sapi5, 0, wx.ALL, 5)
|
||||
self.show_gui = wx.CheckBox(self, -1, _(u"Activate the auto-start of the invisible interface"))
|
||||
self.show_gui.SetValue(config.main["general"]["hide_gui"])
|
||||
sizer.Add(self.show_gui, 0, wx.ALL, 5)
|
||||
apiCallsBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
apiCallsBox.Add(wx.StaticText(self, -1, _(u"API calls when the stream is started (One API call equals to 200 tweetts, two API calls equals 400 tweets, etc):")), 0, wx.ALL, 5)
|
||||
self.apiCalls = wx.SpinCtrl(self, -1)
|
||||
self.apiCalls.SetRange(1, 10)
|
||||
self.apiCalls.SetValue(config.main["general"]["max_api_calls"])
|
||||
self.apiCalls.SetSize(self.apiCalls.GetBestSize())
|
||||
apiCallsBox.Add(self.apiCalls, 0, wx.ALL, 5)
|
||||
sizer.Add(apiCallsBox, 0, wx.ALL, 5)
|
||||
tweetsPerCallBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
tweetsPerCallBox.Add(wx.StaticText(self, -1, _(u"Items on each API call")), 0, wx.ALL, 5)
|
||||
self.itemsPerApiCall = wx.SpinCtrl(self, -1)
|
||||
self.itemsPerApiCall.SetRange(0, 200)
|
||||
self.itemsPerApiCall.SetValue(config.main["general"]["max_tweets_per_call"])
|
||||
self.itemsPerApiCall.SetSize(self.itemsPerApiCall.GetBestSize())
|
||||
tweetsPerCallBox.Add(self.itemsPerApiCall, 0, wx.ALL, 5)
|
||||
sizer.Add(tweetsPerCallBox, 0, wx.ALL, 5)
|
||||
self.reverse_timelines = wx.CheckBox(self, -1, _(u"Inverted buffers: The newest tweets will be shown at the beginning of the lists while the oldest at the end"))
|
||||
self.reverse_timelines.SetValue(config.main["general"]["reverse_timelines"])
|
||||
sizer.Add(self.reverse_timelines, 0, wx.ALL, 5)
|
||||
self.SetSizer(sizer)
|
||||
|
||||
class other_buffers(wx.Panel):
|
||||
def __init__(self, parent):
|
||||
wx.Panel.__init__(self, parent)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self.followers_value = config.main["other_buffers"]["show_followers"]
|
||||
self.friends_value = config.main["other_buffers"]["show_friends"]
|
||||
self.favs_value = config.main["other_buffers"]["show_favourites"]
|
||||
self.events_value = config.main["other_buffers"]["show_events"]
|
||||
self.blocks_value = config.main["other_buffers"]["show_blocks"]
|
||||
self.mutes_value = config.main["other_buffers"]["show_muted_users"]
|
||||
self.followers = wx.CheckBox(self, -1, _(u"Show followers"))
|
||||
self.followers.SetValue(config.main["other_buffers"]["show_followers"])
|
||||
sizer.Add(self.followers, 0, wx.ALL, 5)
|
||||
self.friends = wx.CheckBox(self, -1, _(u"Show friends"))
|
||||
self.friends.SetValue(config.main["other_buffers"]["show_friends"])
|
||||
sizer.Add(self.friends, 0, wx.ALL, 5)
|
||||
self.favs = wx.CheckBox(self, -1, _(u"Show favourites"))
|
||||
self.favs.SetValue(config.main["other_buffers"]["show_favourites"])
|
||||
sizer.Add(self.favs, 0, wx.ALL, 5)
|
||||
self.blocks = wx.CheckBox(self, -1, _(u"Show blocked users"))
|
||||
self.blocks.SetValue(config.main["other_buffers"]["show_blocks"])
|
||||
sizer.Add(self.blocks, 0, wx.ALL, 5)
|
||||
self.mutes = wx.CheckBox(self, -1, _(u"Show muted users"))
|
||||
self.mutes.SetValue(config.main["other_buffers"]["show_muted_users"])
|
||||
sizer.Add(self.mutes, 0, wx.ALL, 5)
|
||||
self.events = wx.CheckBox(self, -1, _(u"Show events"))
|
||||
self.events.SetValue(config.main["other_buffers"]["show_events"])
|
||||
sizer.Add(self.events, 0, wx.ALL, 5)
|
||||
self.SetSizer(sizer)
|
||||
|
||||
class ignoredClients(wx.Panel):
|
||||
def __init__(self, parent):
|
||||
super(ignoredClients, self).__init__(parent=parent)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
choices = config.main["twitter"]["ignored_clients"]
|
||||
label = wx.StaticText(self, -1, _(u"Ignored clients"))
|
||||
self.clients = wx.ListBox(self, -1, choices=choices)
|
||||
self.clients.SetSize(self.clients.GetBestSize())
|
||||
clientsBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
clientsBox.Add(label, 0, wx.ALL, 5)
|
||||
clientsBox.Add(self.clients, 0, wx.ALL, 5)
|
||||
add = wx.Button(self, -1, _(u"Add client"))
|
||||
remove = wx.Button(self, -1, _(u"Remove client"))
|
||||
self.Bind(wx.EVT_BUTTON, self.add, add)
|
||||
self.Bind(wx.EVT_BUTTON, self.remove, remove)
|
||||
btnBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
btnBox.Add(add, 0, wx.ALL, 5)
|
||||
btnBox.Add(remove, 0, wx.ALL, 5)
|
||||
sizer.Add(clientsBox, 0, wx.ALL, 5)
|
||||
sizer.Add(btnBox, 0, wx.ALL, 5)
|
||||
self.SetSizer(sizer)
|
||||
|
||||
def add(self, ev):
|
||||
entry = wx.TextEntryDialog(self, _(u"Enter the name of the client here"), _(u"Add a new ignored client"))
|
||||
if entry.ShowModal() == wx.ID_OK:
|
||||
client = entry.GetValue()
|
||||
if client not in config.main["twitter"]["ignored_clients"]:
|
||||
config.main["twitter"]["ignored_clients"].append(client)
|
||||
self.clients.Append(client)
|
||||
|
||||
def remove(self, ev):
|
||||
if self.clients.GetCount() == 0: return
|
||||
id = self.clients.GetSelection()
|
||||
config.main["twitter"]["ignored_clients"].pop(id)
|
||||
self.clients.Delete(id)
|
||||
|
||||
class sound(wx.Panel):
|
||||
def __init__(self, parent):
|
||||
wx.Panel.__init__(self, parent)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
volume = wx.StaticText(self, -1, _(u"Volume"))
|
||||
self.volumeCtrl = wx.Slider(self)
|
||||
self.volumeCtrl.SetRange(0, 100)
|
||||
self.volumeCtrl.SetValue(config.main["sound"]["volume"]*100)
|
||||
self.volumeCtrl.SetSize(self.volumeCtrl.GetBestSize())
|
||||
volumeBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
volumeBox.Add(volume, 0, wx.ALL, 5)
|
||||
volumeBox.Add(self.volumeCtrl, 0, wx.ALL, 5)
|
||||
sizer.Add(volumeBox, 0, wx.ALL, 5)
|
||||
self.global_mute = wx.CheckBox(self, -1, _(u"Global mute"))
|
||||
self.global_mute.SetValue(config.main["sound"]["global_mute"])
|
||||
sizer.Add(self.global_mute, 0, wx.ALL, 5)
|
||||
self.output_devices = sound_lib.output.Output.get_device_names()
|
||||
output_label = wx.StaticText(self, -1, _(u"Output device"))
|
||||
self.output = wx.ComboBox(self, -1, choices=self.output_devices, style=wx.CB_READONLY)
|
||||
self.output.SetValue(config.main["sound"]["output_device"])
|
||||
self.output.SetSize(self.output.GetBestSize())
|
||||
outputBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
outputBox.Add(output_label, 0, wx.ALL, 5)
|
||||
outputBox.Add(self.output, 0, wx.ALL, 5)
|
||||
sizer.Add(outputBox, 0, wx.ALL, 5)
|
||||
self.input_devices = sound_lib.input.Input.get_device_names()
|
||||
input_label = wx.StaticText(self, -1, _(u"Input device"))
|
||||
self.input = wx.ComboBox(self, -1, choices=self.input_devices, style=wx.CB_READONLY)
|
||||
self.input.SetValue(config.main["sound"]["input_device"])
|
||||
self.input.SetSize(self.input.GetBestSize())
|
||||
inputBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
inputBox.Add(input_label, 0, wx.ALL, 5)
|
||||
inputBox.Add(self.input, 0, wx.ALL, 5)
|
||||
sizer.Add(inputBox, 0, wx.ALL, 5)
|
||||
soundBox = wx.BoxSizer(wx.VERTICAL)
|
||||
self.soundpacks = []
|
||||
[self.soundpacks.append(i) for i in os.listdir(paths.sound_path()) if os.path.isdir(paths.sound_path(i)) == True ]
|
||||
soundpack_label = wx.StaticText(self, -1, _(u"Sound pack"))
|
||||
self.soundpack = wx.ComboBox(self, -1, choices=self.soundpacks, style=wx.CB_READONLY)
|
||||
self.soundpack.SetValue(config.main["sound"]["current_soundpack"])
|
||||
self.soundpack.SetSize(self.soundpack.GetBestSize())
|
||||
soundBox.Add(soundpack_label, 0, wx.ALL, 5)
|
||||
soundBox.Add(self.soundpack, 0, wx.ALL, 5)
|
||||
sizer.Add(soundBox, 0, wx.ALL, 5)
|
||||
self.SetSizer(sizer)
|
||||
|
||||
class audioServicesPanel(wx.Panel):
|
||||
def __init__(self, parent):
|
||||
super(audioServicesPanel, self).__init__(parent)
|
||||
mainSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
apiKeyLabel = wx.StaticText(self, -1, _(u"If you've got a SndUp account, enter your API Key here. Whether the API Key is wrong, the App will fail to upload anything to the server. Whether there's no API Key here, then the audio files will be uploaded anonimously"))
|
||||
self.apiKey = wx.TextCtrl(self, -1)
|
||||
self.apiKey.SetValue(config.main["sound"]["sndup_api_key"])
|
||||
dc = wx.WindowDC(self.apiKey)
|
||||
dc.SetFont(self.apiKey.GetFont())
|
||||
self.apiKey.SetSize(dc.GetTextExtent("0"*100))
|
||||
apiKeyBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
apiKeyBox.Add(apiKeyLabel, 0, wx.ALL, 5)
|
||||
apiKeyBox.Add(self.apiKey, 0, wx.ALL, 5)
|
||||
mainSizer.Add(apiKeyBox, 0, wx.ALL, 5)
|
||||
first_sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
self.dropbox = wx.Button(self, -1)
|
||||
if len(config.main["services"]["dropbox_token"]) > 0:
|
||||
self.dropbox.SetLabel(_(u"Unlink your Dropbox account"))
|
||||
else:
|
||||
self.dropbox.SetLabel(_(u"Link your Dropbox account"))
|
||||
self.dropbox.Bind(wx.EVT_BUTTON, self.onLink_unlink)
|
||||
first_sizer.Add(self.dropbox, 0, wx.ALL, 5)
|
||||
mainSizer.Add(first_sizer, 0, wx.ALL, 5)
|
||||
self.SetSizer(mainSizer)
|
||||
|
||||
def setup_dropbox(self):
|
||||
from extra.AudioUploader import dropbox_transfer
|
||||
auth = dropbox_transfer.dropboxLogin()
|
||||
url = auth.get_url()
|
||||
wx.MessageDialog(self, _(u"The authorisation request will be shown on your browser. Copy the code tat Dropbox will provide and, in the text box that will appear on TW Blue, paste it. This code is necessary to continue. You only need to do it once."), _(u"Authorisation"), wx.OK).ShowModal()
|
||||
webbrowser.open(url)
|
||||
dlg = wx.TextEntryDialog(self, _(u"Enter the code here."), _(u"Verification code"))
|
||||
if dlg.ShowModal() == wx.ID_CANCEL:
|
||||
return False
|
||||
resp = dlg.GetValue()
|
||||
if resp == "":
|
||||
self.dropbox.SetLabel(_(u"Link your Dropbox account"))
|
||||
return False
|
||||
else:
|
||||
try:
|
||||
auth.authorise(resp)
|
||||
self.dropbox.SetLabel(_(u"Unlink your Dropbox account"))
|
||||
except:
|
||||
wx.MessageDialog(self, _(u"Error during authorisation. Try again later."), _(u"Error!"), wx.ICON_ERROR).ShowModal()
|
||||
self.dropbox.SetLabel(_(u"Link your Dropbox account"))
|
||||
return False
|
||||
|
||||
def onLink_unlink(self, ev):
|
||||
if self.dropbox.GetLabel() == _(u"Link your Dropbox account"):
|
||||
self.setup_dropbox()
|
||||
else:
|
||||
self.disconnect_dropbox()
|
||||
|
||||
def disconnect_dropbox(self):
|
||||
config.main["services"]["dropbox_token"] = ""
|
||||
self.dropbox.SetLabel(_(u"Link your Dropbox account"))
|
||||
|
||||
class configurationDialog(wx.Dialog):
|
||||
def __init__(self, parent):
|
||||
self.parent = parent
|
||||
wx.Dialog.__init__(self, None, -1)
|
||||
panel = wx.Panel(self)
|
||||
self.SetTitle(_(u"TW Blue preferences"))
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
notebook = wx.Notebook(panel)
|
||||
self.general = general(notebook)
|
||||
notebook.AddPage(self.general, _(u"General"))
|
||||
self.general.SetFocus()
|
||||
self.buffers = other_buffers(notebook)
|
||||
notebook.AddPage(self.buffers, _(u"Show other buffers"))
|
||||
self.ignored_clients = ignoredClients(notebook)
|
||||
notebook.AddPage(self.ignored_clients, _(u"Ignored clients"))
|
||||
self.sound = sound(notebook)
|
||||
notebook.AddPage(self.sound, _(u"Sound"))
|
||||
self.services = audioServicesPanel(notebook)
|
||||
notebook.AddPage(self.services, _(u"Audio Services"))
|
||||
sizer.Add(notebook, 0, wx.ALL, 5)
|
||||
ok_cancel_box = wx.BoxSizer(wx.HORIZONTAL)
|
||||
ok = wx.Button(panel, wx.ID_OK, _(u"Save"))
|
||||
ok.Bind(wx.EVT_BUTTON, self.onSave)
|
||||
ok.SetDefault()
|
||||
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"Close"))
|
||||
self.SetEscapeId(cancel.GetId())
|
||||
ok_cancel_box.Add(ok, 0, wx.ALL, 5)
|
||||
ok_cancel_box.Add(cancel, 0, wx.ALL, 5)
|
||||
sizer.Add(ok_cancel_box, 0, wx.ALL, 5)
|
||||
panel.SetSizer(sizer)
|
||||
self.SetClientSize(sizer.CalcMin())
|
||||
|
||||
def check_followers_change(self):
|
||||
if self.buffers.followers.GetValue() != self.buffers.followers_value:
|
||||
if self.buffers.followers.GetValue() == True:
|
||||
log.debug("Creating followers list...")
|
||||
followers = buffers.peoplePanel(self.parent.nb, self.parent, "followers", self.parent.twitter.twitter.get_followers_list, argumento=self.parent.db.settings["user_name"])
|
||||
self.parent.nb.InsertSubPage(self.parent.db.settings["buffers"].index(self.parent.db.settings["user_name"]), followers, _(u"Followers"))
|
||||
num = followers.start_streams()
|
||||
followers.put_items(num)
|
||||
self.parent.db.settings["buffers"].append("followers")
|
||||
elif self.buffers.followers.GetValue() == False:
|
||||
self.parent.nb.DeletePage(self.parent.db.settings["buffers"].index("followers"))
|
||||
self.parent.db.settings.pop("followers")
|
||||
self.parent.db.settings["buffers"].remove("followers")
|
||||
|
||||
def check_friends_change(self):
|
||||
if self.buffers.friends.GetValue() != self.buffers.friends_value:
|
||||
if self.buffers.friends.GetValue() == True:
|
||||
log.debug("Creating friends list...")
|
||||
friends = buffers.peoplePanel(self.parent.nb, self.parent, "friends", self.parent.twitter.twitter.get_friends_list, argumento=self.parent.db.settings["user_name"])
|
||||
self.parent.nb.InsertSubPage(self.parent.db.settings["buffers"].index(self.parent.db.settings["user_name"]), friends, _(u"friends"))
|
||||
num = friends.start_streams()
|
||||
friends.put_items(num)
|
||||
self.parent.db.settings["buffers"].append("friends")
|
||||
elif self.buffers.friends.GetValue() == False:
|
||||
self.parent.nb.DeletePage(self.parent.db.settings["buffers"].index("friends"))
|
||||
self.parent.db.settings.pop("friends")
|
||||
self.parent.db.settings["buffers"].remove("friends")
|
||||
|
||||
def check_favs_change(self):
|
||||
if self.buffers.favs.GetValue() != self.buffers.favs_value:
|
||||
if self.buffers.favs.GetValue() == True:
|
||||
log.debug("Creating favorites...")
|
||||
favs = buffers.basePanel(self.parent.nb, self.parent, "favs", self.parent.twitter.twitter.get_favorites)
|
||||
self.parent.nb.InsertSubPage(self.parent.db.settings["buffers"].index(self.parent.db.settings["user_name"]), favs, _(u"Favorites"))
|
||||
num = favs.start_streams()
|
||||
favs.put_items(num)
|
||||
self.parent.db.settings["buffers"].append("favs")
|
||||
elif self.buffers.favs.GetValue() == False:
|
||||
self.parent.nb.DeletePage(self.parent.db.settings["buffers"].index("favs"))
|
||||
self.parent.db.settings.pop("favs")
|
||||
self.parent.db.settings["buffers"].remove("favs")
|
||||
|
||||
def check_events_change(self):
|
||||
if self.buffers.events.GetValue() != self.buffers.events_value:
|
||||
if self.buffers.events.GetValue() == True:
|
||||
log.debug("Creating events...")
|
||||
events = buffers.eventsPanel(self.parent.nb, self.parent)
|
||||
self.parent.nb.InsertSubPage(self.parent.db.settings["buffers"].index(self.parent.db.settings["user_name"]), events, _(u"Events"))
|
||||
self.parent.db.settings["buffers"].append("events")
|
||||
elif self.buffers.events.GetValue() == False:
|
||||
self.parent.nb.DeletePage(self.parent.db.settings["buffers"].index("events"))
|
||||
self.parent.db.settings["buffers"].remove("events")
|
||||
|
||||
def check_blocks_change(self):
|
||||
if self.buffers.blocks.GetValue() != self.buffers.blocks_value:
|
||||
if self.buffers.blocks.GetValue() == True:
|
||||
log.debug("Creating blocked users list...")
|
||||
blocks = buffers.peoplePanel(self.parent.nb, self.parent, "blocks", self.parent.twitter.twitter.list_blocks)
|
||||
self.parent.nb.InsertSubPage(self.parent.db.settings["buffers"].index(self.parent.db.settings["user_name"]), blocks, _(u"Blocked users"))
|
||||
num = blocks.start_streams()
|
||||
blocks.put_items(num)
|
||||
self.parent.db.settings["buffers"].append("blocks")
|
||||
elif self.buffers.blocks.GetValue() == False:
|
||||
self.parent.nb.DeletePage(self.parent.db.settings["buffers"].index("blocks"))
|
||||
self.parent.db.settings.pop("blocks")
|
||||
self.parent.db.settings["buffers"].remove("blocks")
|
||||
|
||||
def check_mutes_change(self):
|
||||
if self.buffers.mutes.GetValue() != self.buffers.mutes_value:
|
||||
if self.buffers.mutes.GetValue() == True:
|
||||
log.debug("Creating muted users list...")
|
||||
mutes = buffers.peoplePanel(self.parent.nb, self.parent, "muteds", self.parent.twitter.twitter.get_muted_users_list)
|
||||
self.parent.nb.InsertSubPage(self.parent.db.settings["buffers"].index(self.parent.db.settings["user_name"]), mutes, _(u"Muted users"))
|
||||
num = mutes.start_streams()
|
||||
mutes.put_items(num)
|
||||
self.parent.db.settings["buffers"].append("muteds")
|
||||
elif self.buffers.mutes.GetValue() == False:
|
||||
self.parent.nb.DeletePage(self.parent.db.settings["buffers"].index("muteds"))
|
||||
self.parent.db.settings.pop("muteds")
|
||||
self.parent.db.settings["buffers"].remove("muteds")
|
||||
|
||||
def onSave(self, ev):
|
||||
need_restart = False
|
||||
# Check general settings
|
||||
if config.main["general"]["language"] != self.general.langs[self.general.language.GetSelection()][0]:
|
||||
if self.general.langs[self.general.language.GetSelection()][0] in self.general.codes: config.main["general"]["language"] = self.general.langs[self.general.language.GetSelection()][0]
|
||||
languageHandler.setLanguage(config.main["general"]["language"])
|
||||
need_restart = True
|
||||
if platform.system() == "Windows":
|
||||
config.main["general"]["voice_enabled"] = self.general.disable_sapi5.GetValue()
|
||||
config.main["general"]["hide_gui"] = self.general.show_gui.GetValue()
|
||||
config.main["general"]["max_api_calls"] = self.general.apiCalls.GetValue()
|
||||
config.main["general"]["max_tweets_per_call"] = self.general.itemsPerApiCall.GetValue()
|
||||
if config.main["general"]["relative_times"] != self.general.relative_time.GetValue():
|
||||
config.main["general"]["relative_times"] = self.general.relative_time.GetValue()
|
||||
need_restart = True
|
||||
if config.main["general"]["reverse_timelines"] != self.general.reverse_timelines.GetValue():
|
||||
config.main["general"]["reverse_timelines"] = self.general.reverse_timelines.GetValue()
|
||||
need_restart = True
|
||||
|
||||
## Check buffers settings
|
||||
config.main["other_buffers"]["show_followers"] = self.buffers.followers.GetValue()
|
||||
self.check_followers_change()
|
||||
config.main["other_buffers"]["show_friends"] = self.buffers.friends.GetValue()
|
||||
self.check_friends_change()
|
||||
config.main["other_buffers"]["show_favourites"] = self.buffers.favs.GetValue()
|
||||
self.check_favs_change()
|
||||
config.main["other_buffers"]["show_events"] = self.buffers.events.GetValue()
|
||||
self.check_events_change()
|
||||
config.main["other_buffers"]["show_blocks"] = self.buffers.blocks.GetValue()
|
||||
self.check_blocks_change()
|
||||
config.main["other_buffers"]["show_muted_users"] = self.buffers.mutes.GetValue()
|
||||
self.check_mutes_change()
|
||||
|
||||
## Check sound settings
|
||||
config.main["sound"]["volume"] = self.sound.volumeCtrl.GetValue()/100.0
|
||||
config.main["sound"]["global_mute"] = self.sound.global_mute.GetValue()
|
||||
if system == "Windows":
|
||||
config.main["sound"]["output_device"] = self.sound.output.GetStringSelection()
|
||||
config.main["sound"]["input_device"] = self.sound.input.GetValue()
|
||||
try:
|
||||
snd.player.input.set_device(snd.player.input.find_device_by_name(config.main["sound"]["input_device"]))
|
||||
snd.player.output.set_device(snd.player.output.find_device_by_name(config.main["sound"]["output_device"]))
|
||||
except:
|
||||
config.main["sound"]["output_device"] = "Default"
|
||||
config.main["sound"]["input_device"] = "Default"
|
||||
config.main["sound"]["sndup_api_key"] = self.services.apiKey.GetValue()
|
||||
config.main["sound"]["current_soundpack"] = self.sound.soundpack.GetStringSelection()
|
||||
snd.player.check_soundpack()
|
||||
if need_restart == True:
|
||||
config.main.write()
|
||||
wx.MessageDialog(None, _(u"The application requires to be restarted to save these changes. Press OK to do it now."), _("Restart TW Blue"), wx.OK).ShowModal()
|
||||
restart.restart_program()
|
||||
|
||||
config.main.write()
|
||||
self.EndModal(wx.ID_OK)
|
151
src/gui/dialogs/follow.py
Normal file
151
src/gui/dialogs/follow.py
Normal file
@@ -0,0 +1,151 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
############################################################
|
||||
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
############################################################
|
||||
import wx
|
||||
import config
|
||||
from mysc import event
|
||||
import twitter
|
||||
from twitter import utils
|
||||
from twython import TwythonError
|
||||
import output
|
||||
|
||||
class follow(wx.Dialog):
|
||||
def __init__(self, parent, default="follow"):
|
||||
self.parent = parent
|
||||
wx.Dialog.__init__(self, None, -1)
|
||||
panel = wx.Panel(self)
|
||||
userSizer = wx.BoxSizer()
|
||||
self.SetTitle(_(u"Action"))
|
||||
if self.parent.name_buffer == "followers" or self.parent.name_buffer == "friends":
|
||||
list = [self.parent.db.settings[self.parent.name_buffer][self.parent.list.get_selected()]["screen_name"]]
|
||||
else:
|
||||
try: list =twitter.utils.get_all_users(self.parent.db.settings[self.parent.name_buffer][self.parent.list.get_selected()], self.parent.db)
|
||||
except KeyError: list = [self.parent.db.settings[self.parent.name_buffer][self.parent.list.get_selected()]["screen_name"]]
|
||||
self.cb = wx.ComboBox(panel, -1, choices=list, value=list[0])
|
||||
self.cb.SetFocus()
|
||||
userSizer.Add(self.cb)
|
||||
actionSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
label2 = wx.StaticText(panel, -1, _(u"Action"))
|
||||
self.follow = wx.RadioButton(panel, -1, _(u"Follow"), style=wx.RB_GROUP)
|
||||
self.unfollow = wx.RadioButton(panel, -1, _(u"Unfollow"))
|
||||
self.mute = wx.RadioButton(panel, -1, _(u"Mute"))
|
||||
self.unmute = wx.RadioButton(panel, -1, _(u"Unmute"))
|
||||
self.block = wx.RadioButton(panel, -1, _(u"Block"))
|
||||
self.unblock = wx.RadioButton(panel, -1, _(u"Unblock"))
|
||||
self.reportSpam = wx.RadioButton(panel, -1, _(u"Report as spam"))
|
||||
self.setup_default(default)
|
||||
actionSizer.Add(label2)
|
||||
actionSizer.Add(self.follow)
|
||||
actionSizer.Add(self.unfollow)
|
||||
actionSizer.Add(self.mute)
|
||||
actionSizer.Add(self.unmute)
|
||||
actionSizer.Add(self.block)
|
||||
actionSizer.Add(self.unblock)
|
||||
actionSizer.Add(self.reportSpam)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
ok = wx.Button(panel, wx.ID_OK, _(u"OK"))
|
||||
ok.Bind(wx.EVT_BUTTON, self.onok)
|
||||
ok.SetDefault()
|
||||
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"Close"))
|
||||
btnsizer = wx.BoxSizer()
|
||||
btnsizer.Add(ok)
|
||||
btnsizer.Add(cancel)
|
||||
sizer.Add(userSizer)
|
||||
sizer.Add(actionSizer)
|
||||
sizer.Add(btnsizer)
|
||||
panel.SetSizer(sizer)
|
||||
self.Bind(wx.EVT_CHAR_HOOK, self.onEscape, self.cb)
|
||||
|
||||
def onEscape(self, ev):
|
||||
if ev.GetKeyCode() == wx.WXK_RETURN:
|
||||
self.onok(wx.EVT_BUTTON)
|
||||
ev.Skip()
|
||||
|
||||
def onok(self, ev):
|
||||
if self.follow.GetValue() == True:
|
||||
try:
|
||||
self.parent.twitter.twitter.create_friendship(screen_name=self.cb.GetValue())
|
||||
self.Destroy()
|
||||
except TwythonError as err:
|
||||
output.speak("Error %s: %s" % (err.error_code, err.msg), True)
|
||||
elif self.unfollow.GetValue() == True:
|
||||
try:
|
||||
id = self.parent.twitter.twitter.destroy_friendship(screen_name=self.cb.GetValue())
|
||||
self.Destroy()
|
||||
except TwythonError as err:
|
||||
output.speak("Error %s: %s" % (err.error_code, err.msg), True)
|
||||
elif self.mute.GetValue() == True:
|
||||
try:
|
||||
id = self.parent.twitter.twitter.create_mute(screen_name=self.cb.GetValue())
|
||||
if config.main["other_buffers"]["show_muted_users"] == True:
|
||||
tweet_event = event.event(event.EVT_OBJECT, 1)
|
||||
tweet_event.SetItem(id)
|
||||
wx.PostEvent(self.parent.parent.nb.GetPage(self.parent.db.settings["buffers"].index("muteds")), tweet_event)
|
||||
self.parent.db.settings["muted_users"].append(id["id"])
|
||||
self.Destroy()
|
||||
output.speak(_(u"You've muted to %s") % (id["screen_name"]))
|
||||
except TwythonError as err:
|
||||
output.speak("Error %s: %s" % (err.error_code, err.msg), True)
|
||||
elif self.unmute.GetValue() == True:
|
||||
try:
|
||||
id = self.parent.twitter.twitter.destroy_mute(screen_name=self.cb.GetValue())
|
||||
if config.main["other_buffers"]["show_muted_users"] == True:
|
||||
item = utils.find_item(id, self.parent.db.settings["muteds"])
|
||||
if item > 0:
|
||||
deleted_event = event.event(event.EVT_DELETED, 1)
|
||||
deleted_event.SetItem(item)
|
||||
wx.PostEvent(self.parent.parent.nb.GetPage(self.parent.db.settings["buffers"].index("muteds")), deleted_event)
|
||||
if id["id"] in self.parent.db.settings["muted_users"]: self.parent.db.settings["muted_users"].remove(id["id"])
|
||||
self.Destroy()
|
||||
output.speak(_(u"You've unmuted to %s") % (id["screen_name"]))
|
||||
except TwythonError as err:
|
||||
output.speak("Error %s: %s" % (err.error_code, err.msg), True)
|
||||
elif self.reportSpam.GetValue() == True:
|
||||
try:
|
||||
self.parent.twitter.twitter.report_spam(screen_name=self.cb.GetValue())
|
||||
self.Destroy()
|
||||
except TwythonError as err:
|
||||
output.speak("Error %s: %s" % (err.error_code, err.msg), True)
|
||||
elif self.block.GetValue() == True:
|
||||
try:
|
||||
self.parent.twitter.twitter.create_block(screen_name=self.cb.GetValue())
|
||||
self.Destroy()
|
||||
except TwythonError as err:
|
||||
output.speak("Error %s: %s" % (err.error_code, err.msg), True)
|
||||
elif self.unblock.GetValue() == True:
|
||||
try:
|
||||
self.parent.twitter.twitter.destroy_block(screen_name=self.cb.GetValue())
|
||||
self.Destroy()
|
||||
except TwythonError as err:
|
||||
output.speak("Error %s: %s" % (err.error_code, err.msg), True)
|
||||
|
||||
def setup_default(self, default):
|
||||
if default == "follow":
|
||||
self.follow.SetValue(True)
|
||||
elif default == "unfollow":
|
||||
self.unfollow.SetValue(True)
|
||||
elif default == "mute":
|
||||
self.mute.SetValue(True)
|
||||
elif default == "unmute":
|
||||
self.unmute.SetValue(True)
|
||||
elif default == "report":
|
||||
self.reportSpam.SetValue(True)
|
||||
elif default == "block":
|
||||
self.block.SetValue(True)
|
||||
elif default == "unblock":
|
||||
self.unblock.SetValue(True)
|
244
src/gui/dialogs/lists.py
Normal file
244
src/gui/dialogs/lists.py
Normal file
@@ -0,0 +1,244 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
############################################################
|
||||
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
############################################################
|
||||
import wx
|
||||
import platform
|
||||
import output
|
||||
import config
|
||||
import gui
|
||||
from multiplatform_widgets import widgets
|
||||
from twython import TwythonError
|
||||
from twitter import compose, utils
|
||||
|
||||
class listViewer(wx.Dialog):
|
||||
|
||||
def __init__(self, parent):
|
||||
self.twitter = parent.twitter
|
||||
self.db = parent.db
|
||||
self.nb = parent.nb
|
||||
self.parent = parent
|
||||
wx.Dialog.__init__(self, None)
|
||||
self.SetTitle(_(u"Lists manager"))
|
||||
panel = wx.Panel(self)
|
||||
label = wx.StaticText(panel, -1, _(u"Lists"))
|
||||
self.lista = widgets.list(panel, _(u"List"), _(u"Description"), _(u"Owner"), _(u"Members"), _(u"mode"), size=(800, 800), style=wx.LC_REPORT|wx.LC_SINGLE_SEL)
|
||||
self.lista.list.SetFocus()
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
sizer.Add(label)
|
||||
sizer.Add(self.lista.list)
|
||||
self.createBtn = wx.Button(panel, wx.NewId(), _(u"Create a new list"))
|
||||
self.createBtn.Bind(wx.EVT_BUTTON, self.onGo)
|
||||
self.editBtn = wx.Button(panel, -1, _(u"Edit"))
|
||||
self.Bind(wx.EVT_BUTTON, self.onEdit, self.editBtn)
|
||||
self.deleteBtn = wx.Button(panel, -1, _(u"Remove"))
|
||||
self.Bind(wx.EVT_BUTTON, self.onDelete, self.deleteBtn)
|
||||
self.view = wx.Button(panel, -1, _(u"Open in buffer"))
|
||||
self.Bind(wx.EVT_BUTTON, self.onView, self.view)
|
||||
# self.members = wx.Button(panel, -1, _(u"View members"))
|
||||
# self.members.Disable()
|
||||
# self.subscriptors = wx.Button(panel, -1, _(u"View subscribers"))
|
||||
# self.subscriptors.Disable()
|
||||
# self.get_linkBtn = wx.Button(panel, -1, _(u"Get link for the list"))
|
||||
# self.get_linkBtn.Bind(wx.EVT_BUTTON, self.onGetLink)
|
||||
self.cancelBtn = wx.Button(panel, wx.ID_CANCEL)
|
||||
btnSizer = wx.BoxSizer()
|
||||
btnSizer.Add(self.createBtn)
|
||||
btnSizer.Add(self.editBtn)
|
||||
btnSizer.Add(self.cancelBtn)
|
||||
panel.SetSizer(sizer)
|
||||
self.populate_list()
|
||||
self.lista.select_item(0)
|
||||
|
||||
def onGo(self, ev):
|
||||
ev.Skip()
|
||||
dlg = createListDialog()
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
name = dlg.name.GetValue()
|
||||
description = dlg.description.GetValue()
|
||||
if dlg.public.GetValue() == True: mode = "public"
|
||||
else: mode = "private"
|
||||
try:
|
||||
new_list = self.twitter.twitter.create_list(name=name, description=description, mode=mode)
|
||||
self.db.settings["lists"].append(new_list)
|
||||
self.lista.insert_item(False, *compose.compose_list(new_list))
|
||||
except TwythonError as e:
|
||||
output.speak("error %s: %s" % (e.status_code, e.msg))
|
||||
else:
|
||||
return
|
||||
dlg.Destroy()
|
||||
|
||||
def onEdit(self, ev):
|
||||
ev.Skip()
|
||||
if self.lista.get_count() == 0: return
|
||||
list = self.db.settings["lists"][self.lista.get_selected()]
|
||||
dlg = editListDialog(list)
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
name = dlg.name.GetValue()
|
||||
description = dlg.description.GetValue()
|
||||
if dlg.public.GetValue() == True: mode = "public"
|
||||
else: mode = "private"
|
||||
try:
|
||||
self.twitter.twitter.update_list(list_id=self.lists[self.get_selected()]["id"], name=name, description=description, mode=mode)
|
||||
except TwythonError as e:
|
||||
output.speak("error %s: %s" % (e.error_code, e.msg))
|
||||
else:
|
||||
return
|
||||
dlg.Destroy()
|
||||
|
||||
def onDelete(self, ev):
|
||||
ev.Skip()
|
||||
if self.lista.get_count() == 0: return
|
||||
list = self.db.settings["lists"][self.lista.get_selected()]["id"]
|
||||
dlg = wx.MessageDialog(self, _("Do you really want to delete this list?"), _("Delete"), wx.YES_NO)
|
||||
if dlg.ShowModal() == wx.ID_YES:
|
||||
try:
|
||||
self.twitter.twitter.delete_list(list_id=list)
|
||||
self.db.settings["lists"].pop(self.lista.get_selected())
|
||||
self.remove_item(self.lista.get_selected())
|
||||
except TwythonError as e:
|
||||
output.speak("error %s: %s" % (e.error_code, e.msg))
|
||||
dlg.Destroy()
|
||||
|
||||
def onView(self, ev):
|
||||
ev.Skip()
|
||||
if self.lista.get_count() == 0: return
|
||||
list_id = self.db.settings["lists"][self.lista.get_selected()]["id"]
|
||||
list_updated = self.twitter.twitter.get_specific_list(list_id=list_id)
|
||||
self.db.settings["lists"][self.lista.get_selected()] = list_updated
|
||||
if list_updated["slug"] not in config.main["other_buffers"]["lists"]:
|
||||
config.main["other_buffers"]["lists"].append(list_updated["slug"])
|
||||
output.speak(_(u"List opened"))
|
||||
else:
|
||||
output.speak(_(u"This list is arready opened."))
|
||||
return
|
||||
listUI = gui.buffers.lists.listPanel(self.nb, self.parent, list_updated["slug"]+"-list", argumento=utils.find_list(list_updated["slug"], self.db.settings["lists"]))
|
||||
self.nb.AddPage(listUI, _(u"List for %s") % (list_updated["slug"],))
|
||||
self.db.settings["buffers"].append(list_updated["slug"]+"-list")
|
||||
num = listUI.start_streams()
|
||||
listUI.put_items(num)
|
||||
listUI.sound = "tweet_timeline.wav"
|
||||
self.parent.stream2.disconnect()
|
||||
del self.parent.stream2
|
||||
self.parent.get_tls()
|
||||
|
||||
def populate_list(self):
|
||||
for i in self.db.settings["lists"]:
|
||||
item = compose.compose_list(i)
|
||||
self.lista.insert_item(False, *item)
|
||||
|
||||
class userListViewer(listViewer):
|
||||
def __init__(self, parent, username):
|
||||
self.username = username
|
||||
super(userListViewer, self).__init__(parent)
|
||||
self.SetTitle(_(u"Viewing lists for %s") % (self.username))
|
||||
self.createBtn.SetLabel(_(u"Subscribe"))
|
||||
self.deleteBtn.SetLabel(_(u"Unsubscribe"))
|
||||
self.editBtn.Disable()
|
||||
self.view.Disable()
|
||||
|
||||
def populate_list(self):
|
||||
self.lists = self.twitter.twitter.show_owned_lists(screen_name=self.username, count=200)["lists"]
|
||||
for i in self.lists:
|
||||
item = compose.compose_list(i)
|
||||
self.lista.insert_item(False, *item)
|
||||
|
||||
def onGo(self, ev):
|
||||
list_id = self.lists[self.lista.get_selected()]["id"]
|
||||
try:
|
||||
list = self.twitter.twitter.subscribe_to_list(list_id=list_id)
|
||||
item = utils.find_item(list["id"], self.db.settings["lists"])
|
||||
self.db.settings["lists"].append(list)
|
||||
except TwythonError as e:
|
||||
output.speak("error %s: %s" % (e.status_code, e.msg))
|
||||
|
||||
class createListDialog(wx.Dialog):
|
||||
|
||||
def __init__(self):
|
||||
wx.Dialog.__init__(self, None, size=(450, 400))
|
||||
self.SetTitle(_(u"Create a new list"))
|
||||
panel = wx.Panel(self)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
name = wx.StaticText(panel, -1, _(u"Name (20 characters maximun)"))
|
||||
self.name = wx.TextCtrl(panel, -1)
|
||||
nameSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
nameSizer.Add(name)
|
||||
nameSizer.Add(self.name)
|
||||
description = wx.StaticText(panel, -1, _(u"Description"))
|
||||
self.description = wx.TextCtrl(panel, -1)
|
||||
descriptionSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
descriptionSizer.Add(description)
|
||||
descriptionSizer.Add(self.description)
|
||||
mode = wx.StaticText(panel, -1, _(u"Mode"))
|
||||
self.public = wx.RadioButton(panel, -1, _(u"Public"), style=wx.RB_GROUP)
|
||||
self.private = wx.RadioButton(panel, -1, _(u"Private"))
|
||||
modeBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
modeBox.Add(mode)
|
||||
modeBox.Add(self.public)
|
||||
modeBox.Add(self.private)
|
||||
ok = wx.Button(panel, wx.ID_OK)
|
||||
ok.SetDefault()
|
||||
cancel = wx.Button(panel, wx.ID_CANCEL)
|
||||
btnBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
btnBox.Add(ok)
|
||||
btnBox.Add(cancel)
|
||||
sizer.Add(nameSizer)
|
||||
sizer.Add(descriptionSizer)
|
||||
sizer.Add(modeBox)
|
||||
sizer.Add(btnBox)
|
||||
|
||||
class editListDialog(createListDialog):
|
||||
|
||||
def __init__(self, list):
|
||||
createListDialog.__init__(self)
|
||||
self.SetTitle(_(u"Editing the list %s") % (list["name"]))
|
||||
self.name.ChangeValue(list["name"])
|
||||
self.description.ChangeValue(list["description"])
|
||||
if list["mode"] == "public":
|
||||
self.public.SetValue(True)
|
||||
else:
|
||||
self.private.SetValue(True)
|
||||
|
||||
class addUserListDialog(listViewer):
|
||||
def __init__(self, parent):
|
||||
listViewer.__init__(self, parent)
|
||||
self.SetTitle(_(u"Select a list to add the user"))
|
||||
self.createBtn.SetLabel(_(u"Add"))
|
||||
self.createBtn.SetDefault()
|
||||
self.editBtn.Disable()
|
||||
self.view.Disable()
|
||||
# self.subscriptors.Disable()
|
||||
# self.members.Disable()
|
||||
self.deleteBtn.Disable()
|
||||
|
||||
def onGo(self, ev):
|
||||
self.EndModal(wx.ID_OK)
|
||||
|
||||
class removeUserListDialog(listViewer):
|
||||
def __init__(self, parent):
|
||||
listViewer.__init__(self, parent)
|
||||
self.SetTitle(_(u"Select a list to remove the user"))
|
||||
self.createBtn.SetLabel(_(u"Remove"))
|
||||
self.createBtn.SetDefault()
|
||||
self.editBtn.Disable()
|
||||
self.view.Disable()
|
||||
# self.subscriptors.Disable()
|
||||
# self.members.Disable()
|
||||
self.deleteBtn.Disable()
|
||||
|
||||
def onGo(self, ev):
|
||||
self.EndModal(wx.ID_OK)
|
415
src/gui/dialogs/message.py
Normal file
415
src/gui/dialogs/message.py
Normal file
@@ -0,0 +1,415 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
############################################################
|
||||
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
############################################################
|
||||
import wx
|
||||
import twitter
|
||||
import config
|
||||
import output
|
||||
import sound
|
||||
import urlList
|
||||
import url_shortener
|
||||
import json
|
||||
from mysc.thread_utils import call_threaded
|
||||
from mysc.repeating_timer import RepeatingTimer
|
||||
from twython import TwythonError
|
||||
from extra import translator, AudioUploader
|
||||
import platform
|
||||
from extra.AudioUploader import transfer
|
||||
if platform.system() != "Darwin":
|
||||
from extra.AudioUploader import dropbox_transfer
|
||||
from extra.SpellChecker import gui as spellCheckerGUI
|
||||
|
||||
class textLimited(wx.Dialog):
|
||||
def __init__(self, message, title, text, parent):
|
||||
wx.Dialog.__init__(self, parent)
|
||||
self.twitter = parent.twitter
|
||||
self.parent = parent
|
||||
self.SetTitle(_(u"New tweet"))
|
||||
self.panel = wx.Panel(self)
|
||||
|
||||
def createTextArea(self, message, text):
|
||||
self.label = wx.StaticText(self.panel, -1, str(len(text)))
|
||||
self.text = wx.TextCtrl(self.panel, -1, text)
|
||||
font = self.text.GetFont()
|
||||
dc = wx.WindowDC(self.text)
|
||||
dc.SetFont(font)
|
||||
x, y = dc.GetTextExtent("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
|
||||
self.text.SetSize((x, y))
|
||||
self.text.SetFocus()
|
||||
if platform.system() != "Darwin":
|
||||
self.text.Bind(wx.EVT_TEXT, self.onTimer)
|
||||
self.textBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
self.textBox.Add(self.label, 0, wx.ALL, 5)
|
||||
self.textBox.Add(self.text, 0, wx.ALL, 5)
|
||||
|
||||
def onCheck(self, ev):
|
||||
if platform.system() == "Darwin":
|
||||
return
|
||||
text = self.text.GetValue()
|
||||
dlg = spellCheckerGUI.spellCheckerDialog(text, "")
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
self.text.ChangeValue(dlg.checker.get_text())
|
||||
dlg.Destroy()
|
||||
|
||||
def onAttach(self, ev):
|
||||
ev.Skip()
|
||||
self.recording = AudioUploader.gui.audioDialog(self.parent)
|
||||
if self.recording.ShowModal() != wx.ID_OK:
|
||||
self.recording.cleanup()
|
||||
return
|
||||
self.recording.postprocess()
|
||||
output.speak(_(u"Attaching..."))
|
||||
self.uploaderDialog = AudioUploader.transfer_dialogs.UploadDialog(parent=self.parent, title=_(u"Uploading..."), filename=self.recording.file)
|
||||
if self.recording.services.GetValue() == "Dropbox" and platform.system() != "Darwin":
|
||||
self.uploader = dropbox_transfer.dropboxUploader(filename=self.recording.file, completed_callback=self.upload_completed, wxDialog=self.uploaderDialog)
|
||||
elif self.recording.services.GetValue() == "SNDUp":
|
||||
base_url = 'http://sndup.net/post.php'
|
||||
if len(config.main["sound"]["sndup_api_key"]) > 0:
|
||||
url = base_url + '?apikey=' + config.main['sound']['sndup_api_key']
|
||||
else:
|
||||
url = base_url
|
||||
self.uploader = transfer.Upload(field='file', url=url, filename=self.recording.file, completed_callback=self.upload_completed, wxDialog=self.uploaderDialog)
|
||||
self.uploaderDialog.Show()
|
||||
self.uploader.perform_threaded()
|
||||
|
||||
def upload_completed(self):
|
||||
url = self.uploader.get_url()
|
||||
self.uploaderDialog.Destroy()
|
||||
if url != 0:
|
||||
self.text.SetValue(self.text.GetValue()+url+" #audio")
|
||||
else:
|
||||
output.speak(_(u"Unable to upload the audio"))
|
||||
|
||||
def onTranslate(self, ev):
|
||||
dlg = translator.gui.translateDialog()
|
||||
selection = dlg.ShowModal()
|
||||
if selection != wx.ID_CANCEL:
|
||||
text_to_translate = self.text.GetValue().encode("utf-8")
|
||||
source = [x[0] for x in translator.available_languages()][dlg.source_lang.GetSelection()]
|
||||
dest = [x[0] for x in translator.available_languages()][dlg.dest_lang.GetSelection()]
|
||||
t = translator.translator.Translator()
|
||||
t.from_lang = source
|
||||
t.to_lang = dest
|
||||
msg = t.translate(text_to_translate)
|
||||
self.text.ChangeValue(msg)
|
||||
output.speak(_(u"Translated"))
|
||||
self.text.SetFocus()
|
||||
else:
|
||||
return
|
||||
dlg.Destroy()
|
||||
|
||||
def onSelect(self, ev):
|
||||
self.text.SelectAll()
|
||||
|
||||
def onShorten(self, ev):
|
||||
urls = twitter.utils.find_urls_in_text(self.text.GetValue())
|
||||
if len(urls) == 0:
|
||||
output.speak(_(u"There's no URL to be shortened"))
|
||||
elif len(urls) == 1:
|
||||
self.text.SetValue(self.text.GetValue().replace(urls[0], url_shortener.shorten(urls[0])))
|
||||
output.speak(_(u"URL shortened"))
|
||||
elif len(urls) > 1:
|
||||
urlList.shorten(urls, self).ShowModal()
|
||||
self.text.SetFocus()
|
||||
|
||||
def onUnshorten(self, ev):
|
||||
urls = twitter.utils.find_urls_in_text(self.text.GetValue())
|
||||
if len(urls) == 0:
|
||||
output.speak(_(u"There's no URL to be expanded"))
|
||||
elif len(urls) == 1:
|
||||
self.text.SetValue(self.text.GetValue().replace(urls[0], url_shortener.unshorten(urls[0])))
|
||||
output.speak(_(u"URL expanded"))
|
||||
elif len(urls) > 1:
|
||||
urlList.unshorten(urls, self).ShowModal()
|
||||
self.text.SetFocus()
|
||||
|
||||
def onTimer(self, ev):
|
||||
self.label.SetLabel(str(len(self.text.GetValue())))
|
||||
if len(self.text.GetValue()) > 1:
|
||||
self.shortenButton.Enable()
|
||||
self.unshortenButton.Enable()
|
||||
else:
|
||||
self.shortenButton.Disable()
|
||||
self.unshortenButton.Disable()
|
||||
if len(self.text.GetValue()) > 140:
|
||||
sound.player.play("max_length.ogg")
|
||||
self.okButton.Disable()
|
||||
elif len(self.text.GetValue()) <= 140:
|
||||
self.okButton.Enable()
|
||||
|
||||
def onCancel(self, ev):
|
||||
self.Destroy()
|
||||
|
||||
|
||||
class tweet(textLimited):
|
||||
def createControls(self, message, title, text):
|
||||
self.mainBox = wx.BoxSizer(wx.VERTICAL)
|
||||
self.createTextArea(message, text)
|
||||
self.mainBox.Add(self.textBox, 0, wx.ALL, 5)
|
||||
self.upload_image = wx.Button(self.panel, -1, _(u"Upload a picture"), size=wx.DefaultSize)
|
||||
self.upload_image.Bind(wx.EVT_BUTTON, self.onUpload_image)
|
||||
if platform.system() != "Darwin":
|
||||
self.spellcheck = wx.Button(self.panel, -1, _("Spelling correction"), size=wx.DefaultSize)
|
||||
self.spellcheck.Bind(wx.EVT_BUTTON, self.onCheck)
|
||||
self.attach = wx.Button(self.panel, -1, _(u"Attach audio"), size=wx.DefaultSize)
|
||||
self.attach.Bind(wx.EVT_BUTTON, self.onAttach)
|
||||
self.shortenButton = wx.Button(self.panel, -1, _(u"Shorten URL"), size=wx.DefaultSize)
|
||||
self.shortenButton.Bind(wx.EVT_BUTTON, self.onShorten)
|
||||
self.unshortenButton = wx.Button(self.panel, -1, _(u"Expand URL"), size=wx.DefaultSize)
|
||||
self.unshortenButton.Bind(wx.EVT_BUTTON, self.onUnshorten)
|
||||
self.shortenButton.Disable()
|
||||
self.unshortenButton.Disable()
|
||||
self.translateButton = wx.Button(self.panel, -1, _(u"Translate message"), size=wx.DefaultSize)
|
||||
self.translateButton.Bind(wx.EVT_BUTTON, self.onTranslate)
|
||||
self.okButton = wx.Button(self.panel, wx.ID_OK, _(u"Send"), size=wx.DefaultSize)
|
||||
self.okButton.Bind(wx.EVT_BUTTON, self.onSend)
|
||||
self.okButton.SetDefault()
|
||||
cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _(u"Close"), size=wx.DefaultSize)
|
||||
cancelButton.Bind(wx.EVT_BUTTON, self.onCancel)
|
||||
self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL)
|
||||
self.buttonsBox1.Add(self.upload_image, 0, wx.ALL, 5)
|
||||
if platform.system() != "Darwin":
|
||||
self.buttonsBox1.Add(self.spellcheck, 0, wx.ALL, 5)
|
||||
self.buttonsBox1.Add(self.attach, 0, wx.ALL, 5)
|
||||
self.mainBox.Add(self.buttonsBox1, 0, wx.ALL, 5)
|
||||
self.buttonsBox2 = wx.BoxSizer(wx.HORIZONTAL)
|
||||
self.buttonsBox2.Add(self.shortenButton, 0, wx.ALL, 5)
|
||||
self.buttonsBox2.Add(self.unshortenButton, 0, wx.ALL, 5)
|
||||
self.buttonsBox2.Add(self.translateButton, 0, wx.ALL, 5)
|
||||
self.mainBox.Add(self.buttonsBox2, 0, wx.ALL, 5)
|
||||
self.ok_cancelSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
self.ok_cancelSizer.Add(self.okButton, 0, wx.ALL, 5)
|
||||
self.ok_cancelSizer.Add(cancelButton, 0, wx.ALL, 5)
|
||||
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, message, title, text, parent):
|
||||
super(tweet, self).__init__(message, title, text, parent)
|
||||
self.image = None
|
||||
self.createControls(message, title, text)
|
||||
self.onTimer(wx.EVT_CHAR_HOOK)
|
||||
self.SetClientSize(self.mainBox.CalcMin())
|
||||
|
||||
def onUpload_image(self, ev):
|
||||
if self.upload_image.GetLabel() == _(u"Discard image"):
|
||||
self.image = None
|
||||
del self.file
|
||||
output.speak(_(u"Discarded"))
|
||||
self.upload_image.SetLabel(_(u"Upload a picture"))
|
||||
else:
|
||||
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
|
||||
self.file = open(openFileDialog.GetPath(), "rb")
|
||||
self.image = True
|
||||
self.upload_image.SetLabel(_(u"Discard image"))
|
||||
ev.Skip()
|
||||
|
||||
def onSend(self, ev):
|
||||
self.EndModal(wx.ID_OK)
|
||||
|
||||
class retweet(tweet):
|
||||
def __init__(self, message, title, text, parent):
|
||||
super(retweet, self).__init__(message, title, text, parent)
|
||||
# self.createControls(message, title, text)
|
||||
self.in_reply_to = parent.db.settings[parent.name_buffer][parent.list.get_selected()]["id"]
|
||||
self.text.SetInsertionPoint(0)
|
||||
|
||||
def onSend(self, ev):
|
||||
self.EndModal(wx.ID_OK)
|
||||
|
||||
class dm(textLimited):
|
||||
def createControls(self, message, title, text):
|
||||
self.mainBox = wx.BoxSizer(wx.VERTICAL)
|
||||
if self.parent.name_buffer == "followers" or self.parent.name_buffer == "friends":
|
||||
list = [self.parent.db.settings[self.parent.name_buffer][self.parent.list.get_selected()]["screen_name"]]
|
||||
else:
|
||||
list =twitter.utils.get_all_users(self.parent.db.settings[self.parent.name_buffer][self.parent.list.get_selected()], self.parent.db)
|
||||
label = wx.StaticText(self.panel, -1, _(u"Recipient"))
|
||||
self.cb = wx.ComboBox(self.panel, -1, choices=list, value=list[0], size=wx.DefaultSize)
|
||||
self.createTextArea(message, text)
|
||||
self.mainBox.Add(self.cb, 0, wx.ALL, 5)
|
||||
self.mainBox.Add(self.textBox, 0, wx.ALL, 5)
|
||||
if platform.system() != "Darwin":
|
||||
self.spellcheck = wx.Button(self.panel, -1, _("Spelling correction"), size=wx.DefaultSize)
|
||||
self.spellcheck.Bind(wx.EVT_BUTTON, self.onCheck)
|
||||
self.attach = wx.Button(self.panel, -1, _(u"Attach audio"), size=wx.DefaultSize)
|
||||
self.attach.Bind(wx.EVT_BUTTON, self.onAttach)
|
||||
self.shortenButton = wx.Button(self.panel, -1, _(u"Shorten URL"), size=wx.DefaultSize)
|
||||
self.shortenButton.Bind(wx.EVT_BUTTON, self.onShorten)
|
||||
self.unshortenButton = wx.Button(self.panel, -1, _(u"Expand URL"), size=wx.DefaultSize)
|
||||
self.unshortenButton.Bind(wx.EVT_BUTTON, self.onUnshorten)
|
||||
self.shortenButton.Disable()
|
||||
self.unshortenButton.Disable()
|
||||
self.translateButton = wx.Button(self.panel, -1, _(u"Translate message"), size=wx.DefaultSize)
|
||||
self.translateButton.Bind(wx.EVT_BUTTON, self.onTranslate)
|
||||
self.okButton = wx.Button(self.panel, wx.ID_OK, _(u"Send"), size=wx.DefaultSize)
|
||||
self.okButton.Bind(wx.EVT_BUTTON, self.onSend)
|
||||
self.okButton.SetDefault()
|
||||
cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _(u"Close"), size=wx.DefaultSize)
|
||||
cancelButton.Bind(wx.EVT_BUTTON, self.onCancel)
|
||||
self.buttonsBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
if platform.system() != "Darwin":
|
||||
self.buttonsBox.Add(self.spellcheck, 0, wx.ALL, 5)
|
||||
self.buttonsBox.Add(self.attach, 0, wx.ALL, 5)
|
||||
self.mainBox.Add(self.buttonsBox, 0, wx.ALL, 5)
|
||||
self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL)
|
||||
self.buttonsBox1.Add(self.shortenButton, 0, wx.ALL, 5)
|
||||
self.buttonsBox1.Add(self.unshortenButton, 0, wx.ALL, 5)
|
||||
self.buttonsBox1.Add(self.translateButton, 0, wx.ALL, 5)
|
||||
self.mainBox.Add(self.buttonsBox1, 0, wx.ALL, 5)
|
||||
self.buttonsBox3 = wx.BoxSizer(wx.HORIZONTAL)
|
||||
self.buttonsBox3.Add(self.okButton, 0, wx.ALL, 5)
|
||||
self.buttonsBox3.Add(cancelButton, 0, wx.ALL, 5)
|
||||
self.mainBox.Add(self.buttonsBox3, 0, wx.ALL, 5)
|
||||
self.panel.SetSizer(self.mainBox)
|
||||
|
||||
def __init__(self, message, title, text, parent):
|
||||
super(dm, self).__init__(message, title, text, parent)
|
||||
self.parent = parent
|
||||
self.image = None
|
||||
self.createControls(message, title, text)
|
||||
self.onTimer(wx.EVT_CHAR_HOOK)
|
||||
self.SetClientSize(self.mainBox.CalcMin())
|
||||
|
||||
def onSend(self, ev):
|
||||
self.EndModal(wx.ID_OK)
|
||||
|
||||
class reply(tweet):
|
||||
def __init__(self, message, title, text, parent):
|
||||
super(reply, self).__init__(message, title, text, parent)
|
||||
self.in_reply_to = parent.db.settings[parent.name_buffer][parent.list.get_selected()]["id"]
|
||||
self.text.SetInsertionPoint(len(self.text.GetValue()))
|
||||
self.mentionAll = wx.Button(self, -1, _(u"Mention to all"), size=wx.DefaultSize)
|
||||
self.mentionAll.Disable()
|
||||
self.mentionAll.Bind(wx.EVT_BUTTON, self.mentionAllUsers)
|
||||
self.buttonsBox1.Add(self.mentionAll, 0, wx.ALL, 5)
|
||||
self.buttonsBox1.Layout()
|
||||
self.mainBox.Layout()
|
||||
self.check_if_users()
|
||||
self.SetClientSize(self.mainBox.CalcMin())
|
||||
|
||||
def check_if_users(self):
|
||||
try:
|
||||
if len(self.parent.db.settings[self.parent.name_buffer][self.parent.list.get_selected()]["entities"]["user_mentions"]) > 0:
|
||||
self.mentionAll.Enable()
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
def mentionAllUsers(self, ev):
|
||||
self.text.SetValue(self.text.GetValue()+twitter.utils.get_all_mentioned(self.parent.db.settings[self.parent.name_buffer][self.parent.list.get_selected()], self.parent.db))
|
||||
self.text.SetInsertionPoint(len(self.text.GetValue()))
|
||||
self.text.SetFocus()
|
||||
|
||||
def onSend(self, ev):
|
||||
self.EndModal(wx.ID_OK)
|
||||
|
||||
class viewTweet(wx.Dialog):
|
||||
def __init__(self, tweet):
|
||||
super(viewTweet, self).__init__(None, size=(850,850))
|
||||
self.SetTitle(_(u"Tweet - %i characters ") % (len(tweet)))
|
||||
panel = wx.Panel(self)
|
||||
label = wx.StaticText(panel, -1, _(u"Tweet"))
|
||||
self.text = wx.TextCtrl(panel, -1, tweet, style=wx.TE_READONLY|wx.TE_MULTILINE, size=(250, 180))
|
||||
dc = wx.WindowDC(self.text)
|
||||
dc.SetFont(self.text.GetFont())
|
||||
(x, y, z) = dc.GetMultiLineTextExtent("0"*140)
|
||||
self.text.SetSize((x, y))
|
||||
self.text.SetFocus()
|
||||
textBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
textBox.Add(label, 0, wx.ALL, 5)
|
||||
textBox.Add(self.text, 1, wx.EXPAND, 5)
|
||||
mainBox = wx.BoxSizer(wx.VERTICAL)
|
||||
mainBox.Add(textBox, 0, wx.ALL, 5)
|
||||
if platform.system() != "Darwin":
|
||||
spellcheck = wx.Button(panel, -1, _("Spelling correction"), size=wx.DefaultSize)
|
||||
spellcheck.Bind(wx.EVT_BUTTON, self.onCheck)
|
||||
self.unshortenButton = wx.Button(panel, -1, _(u"Expand URL"), size=wx.DefaultSize)
|
||||
self.unshortenButton.Bind(wx.EVT_BUTTON, self.onUnshorten)
|
||||
self.unshortenButton.Disable()
|
||||
translateButton = wx.Button(panel, -1, _(u"Translate message"), size=wx.DefaultSize)
|
||||
translateButton.Bind(wx.EVT_BUTTON, self.onTranslate)
|
||||
cancelButton = wx.Button(panel, wx.ID_CANCEL, _(u"Close"), size=wx.DefaultSize)
|
||||
cancelButton.SetDefault()
|
||||
buttonsBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
if platform.system() != "Darwin":
|
||||
buttonsBox.Add(spellcheck, 0, wx.ALL, 5)
|
||||
buttonsBox.Add(self.unshortenButton, 0, wx.ALL, 5)
|
||||
buttonsBox.Add(translateButton, 0, wx.ALL, 5)
|
||||
buttonsBox.Add(cancelButton, 0, wx.ALL, 5)
|
||||
mainBox.Add(buttonsBox, 0, wx.ALL, 5)
|
||||
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)
|
||||
panel.SetSizer(mainBox)
|
||||
self.check_urls()
|
||||
self.SetClientSize(mainBox.CalcMin())
|
||||
|
||||
def check_urls(self):
|
||||
if len(twitter.utils.find_urls_in_text(self.text.GetValue())) > 0:
|
||||
self.unshortenButton.Enable()
|
||||
|
||||
def onCheck(self, ev):
|
||||
if platform.system() != "Darwin": return
|
||||
text = self.text.GetValue()
|
||||
dlg = spellCheckerGUI.spellCheckerDialog(text, "")
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
self.text.ChangeValue(dlg.checker.get_text())
|
||||
dlg.Destroy()
|
||||
|
||||
def onTranslate(self, ev):
|
||||
dlg = translator.gui.translateDialog()
|
||||
selection = dlg.ShowModal()
|
||||
if selection != wx.ID_CANCEL:
|
||||
text_to_translate = self.text.GetValue().encode("utf-8")
|
||||
source = [x[0] for x in translator.available_languages()][dlg.source_lang.GetSelection()]
|
||||
dest = [x[0] for x in translator.available_languages()][dlg.dest_lang.GetSelection()]
|
||||
t = translator.translator.Translator()
|
||||
t.from_lang = source
|
||||
t.to_lang = dest
|
||||
msg = t.translate(text_to_translate)
|
||||
self.text.ChangeValue(msg)
|
||||
output.speak(_(u"Translated"))
|
||||
self.text.SetFocus()
|
||||
else:
|
||||
return
|
||||
dlg.Destroy()
|
||||
|
||||
def onSelect(self, ev):
|
||||
self.text.SelectAll()
|
||||
|
||||
def onUnshorten(self, ev):
|
||||
urls = twitter.utils.find_urls_in_text(self.text.GetValue())
|
||||
if len(urls) == 0:
|
||||
output.speak(_(u"There's no URL to be expanded"))
|
||||
elif len(urls) == 1:
|
||||
self.text.SetValue(self.text.GetValue().replace(urls[0], url_shortener.unshorten(urls[0])))
|
||||
output.speak(_(u"URL expanded"))
|
||||
elif len(urls) > 1:
|
||||
urlList.unshorten(urls, self).ShowModal()
|
||||
self.text.SetFocus()
|
||||
|
48
src/gui/dialogs/search.py
Normal file
48
src/gui/dialogs/search.py
Normal file
@@ -0,0 +1,48 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
############################################################
|
||||
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
############################################################
|
||||
import wx
|
||||
|
||||
class searchDialog(wx.Dialog):
|
||||
def __init__(self):
|
||||
super(searchDialog, self).__init__(None, -1)
|
||||
panel = wx.Panel(self)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self.SetTitle(_(u"Search on Twitter"))
|
||||
label = wx.StaticText(panel, -1, _(u"Search"))
|
||||
self.term = wx.TextCtrl(panel, -1,)
|
||||
dc = wx.WindowDC(self.term)
|
||||
dc.SetFont(self.term.GetFont())
|
||||
self.term.SetSize(dc.GetTextExtent("0"*40))
|
||||
sizer.Add(label, 0, wx.ALL, 5)
|
||||
sizer.Add(self.term, 0, wx.ALL, 5)
|
||||
self.tweets = wx.RadioButton(panel, -1, _(u"Tweets"), style=wx.RB_GROUP)
|
||||
self.users = wx.RadioButton(panel, -1, _(u"Users"))
|
||||
radioSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
radioSizer.Add(self.tweets, 0, wx.ALL, 5)
|
||||
radioSizer.Add(self.users, 0, wx.ALL, 5)
|
||||
sizer.Add(radioSizer, 0, wx.ALL, 5)
|
||||
ok = wx.Button(panel, wx.ID_OK, _(u"OK"))
|
||||
ok.SetDefault()
|
||||
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"Close"))
|
||||
btnsizer = wx.BoxSizer()
|
||||
btnsizer.Add(ok, 0, wx.ALL, 5)
|
||||
btnsizer.Add(cancel, 0, wx.ALL, 5)
|
||||
sizer.Add(btnsizer, 0, wx.ALL, 5)
|
||||
panel.SetSizer(sizer)
|
||||
self.SetClientSize(sizer.CalcMin())
|
83
src/gui/dialogs/show_user.py
Normal file
83
src/gui/dialogs/show_user.py
Normal file
@@ -0,0 +1,83 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
############################################################
|
||||
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
############################################################
|
||||
import wx, twitter, config, gui.dialogs, sound, webbrowser
|
||||
|
||||
class showUserProfile(wx.Dialog):
|
||||
def __init__(self, twitter, screen_name):
|
||||
self.twitter = twitter
|
||||
self.screen_name = screen_name
|
||||
wx.Dialog.__init__(self, None, -1)
|
||||
self.SetTitle(_(u"Information for %s") % (screen_name))
|
||||
panel = wx.Panel(self)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self.get_data()
|
||||
static = wx.StaticText(panel, -1, _(u"Details"))
|
||||
sizer.Add(static, 0, wx.ALL, 5)
|
||||
text = wx.TextCtrl(panel, -1, style=wx.TE_MULTILINE|wx.TE_READONLY)
|
||||
# dc = wx.WindowDC(text)
|
||||
# dc.SetFont(text.GetFont())
|
||||
# (x, y, z) = dc.GetMultiLineTextExtent("0"*10000)
|
||||
# text.SetSize((x, y))
|
||||
text.SetFocus()
|
||||
sizer.Add(text, 0, wx.ALL|wx.EXPAND, 5)
|
||||
self.url = wx.Button(panel, -1, _(u"Go to URL"), size=wx.DefaultSize)
|
||||
self.url.Bind(wx.EVT_BUTTON, self.onUrl)
|
||||
self.url.Disable()
|
||||
close = wx.Button(panel, wx.ID_CANCEL, _(u"Close"))
|
||||
close.Bind(wx.EVT_BUTTON, self.onClose)
|
||||
btnSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
btnSizer.Add(self.url, 0, wx.ALL, 5)
|
||||
btnSizer.Add(close, 0, wx.ALL, 5)
|
||||
sizer.Add(btnSizer, 0, wx.ALL, 5)
|
||||
text.ChangeValue(self.compose_string())
|
||||
text.SetSize(text.GetBestSize())
|
||||
panel.SetSizer(sizer)
|
||||
self.SetClientSize(sizer.CalcMin())
|
||||
|
||||
def onUrl(self, ev):
|
||||
webbrowser.open(self.data["url"])
|
||||
|
||||
def onClose(self, ev):
|
||||
self.Destroy()
|
||||
|
||||
def get_data(self):
|
||||
try:
|
||||
self.data = self.twitter.twitter.show_user(screen_name=self.screen_name)
|
||||
except:
|
||||
wx.MessageDialog(self, _(u"This user does not exist on Twitter"), _(u"Error"), wx.ICON_ERROR).ShowModal()
|
||||
self.EndModal()
|
||||
|
||||
def compose_string(self):
|
||||
string = u""
|
||||
string = string + _(u"Username: @%s\n") % (self.data["screen_name"])
|
||||
string = string + _(u"Name: %s\n") % (self.data["name"])
|
||||
if self.data["location"] != "":
|
||||
string = string + _(u"Location: %s\n") % (self.data["location"])
|
||||
if self.data["url"] != None:
|
||||
string = string+ _(u"URL: %s\n") % (self.data["url"])
|
||||
self.url.Enable()
|
||||
if self.data["description"] != "":
|
||||
string = string+ _(u"Bio: %s\n") % (self.data["description"])
|
||||
if self.data["protected"] == True: protected = _(u"Yes")
|
||||
else: protected = _(u"No")
|
||||
string = string+ _(u"Protected: %s\n") % (protected)
|
||||
string = string+_(u"Followers: %s\n Friends: %s\n") % (self.data["followers_count"], self.data["friends_count"])
|
||||
string = string+ _(u"Tweets: %s\n") % (self.data["statuses_count"])
|
||||
string = string+ _(u"Favourites: %s") % (self.data["favourites_count"])
|
||||
return string
|
119
src/gui/dialogs/update_profile.py
Normal file
119
src/gui/dialogs/update_profile.py
Normal file
@@ -0,0 +1,119 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
############################################################
|
||||
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
############################################################
|
||||
import wx
|
||||
from twython import TwythonError
|
||||
|
||||
class updateProfile(wx.Dialog):
|
||||
def __init__(self, parent):
|
||||
self.twitter = parent.twitter
|
||||
self.parent = parent
|
||||
super(updateProfile, self).__init__(parent=None, id=-1)
|
||||
self.SetTitle(_(u"Update your profile"))
|
||||
panel = wx.Panel(self)
|
||||
labelName = wx.StaticText(panel, -1, _(u"Name (20 characters maximum)"))
|
||||
self.name = wx.TextCtrl(panel, -1)
|
||||
self.name.SetFocus()
|
||||
dc = wx.WindowDC(self.name)
|
||||
dc.SetFont(self.name.GetFont())
|
||||
self.name.SetSize(dc.GetTextExtent("0"*20))
|
||||
labelLocation = wx.StaticText(panel, -1, _(u"Location"))
|
||||
self.location = wx.TextCtrl(panel, -1)
|
||||
dc = wx.WindowDC(self.location)
|
||||
dc.SetFont(self.location.GetFont())
|
||||
self.location.SetSize(dc.GetTextExtent("0"*35))
|
||||
labelUrl = wx.StaticText(panel, -1, _(u"Website"))
|
||||
self.url = wx.TextCtrl(panel, -1)
|
||||
dc = wx.WindowDC(self.url)
|
||||
dc.SetFont(self.url.GetFont())
|
||||
self.url.SetSize(dc.GetTextExtent("0"*22))
|
||||
labelDescription = wx.StaticText(panel, -1, _(u"Bio (160 characters maximum)"))
|
||||
self.description = wx.TextCtrl(panel, -1, size=(400, 400))
|
||||
dc = wx.WindowDC(self.description)
|
||||
dc.SetFont(self.description.GetFont())
|
||||
self.description.SetSize(dc.GetTextExtent("0"*160))
|
||||
self.image = None
|
||||
self.upload_image = wx.Button(panel, -1, _(u"Upload a picture"))
|
||||
self.upload_image.Bind(wx.EVT_BUTTON, self.onUpload_picture)
|
||||
ok = wx.Button(panel, wx.ID_OK, _(u"Update profile"))
|
||||
ok.Bind(wx.EVT_BUTTON, self.onUpdateProfile)
|
||||
ok.SetDefault()
|
||||
close = wx.Button(panel, wx.ID_CANCEL, _("Close"))
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
nameBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
nameBox.Add(labelName, 0, wx.ALL, 5)
|
||||
nameBox.Add(self.name, 0, wx.ALL, 5)
|
||||
sizer.Add(nameBox, 0, wx.ALL, 5)
|
||||
locationBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
locationBox.Add(labelLocation, 0, wx.ALL, 5)
|
||||
locationBox.Add(self.location, 0, wx.ALL, 5)
|
||||
sizer.Add(locationBox, 0, wx.ALL, 5)
|
||||
urlBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
urlBox.Add(labelUrl, 0, wx.ALL, 5)
|
||||
urlBox.Add(self.url, 0, wx.ALL, 5)
|
||||
sizer.Add(urlBox, 0, wx.ALL, 5)
|
||||
descriptionBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
descriptionBox.Add(labelDescription, 0, wx.ALL, 5)
|
||||
descriptionBox.Add(self.description, 0, wx.ALL, 5)
|
||||
sizer.Add(descriptionBox, 0, wx.ALL, 5)
|
||||
sizer.Add(self.upload_image, 5, wx.CENTER, 5)
|
||||
btnBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
btnBox.Add(ok, 0, wx.ALL, 5)
|
||||
btnBox.Add(close, 0, wx.ALL, 5)
|
||||
sizer.Add(btnBox, 0, wx.ALL, 5)
|
||||
panel.SetSizer(sizer)
|
||||
self.SetClientSize(sizer.CalcMin())
|
||||
self.get_data()
|
||||
|
||||
def onUpload_picture(self, ev):
|
||||
if self.upload_image.GetLabel() == _(u"Discard image"):
|
||||
self.image = None
|
||||
del self.file
|
||||
output.speak(_(u"Discarded"))
|
||||
self.upload_image.SetLabel(_(u"Upload a picture"))
|
||||
else:
|
||||
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
|
||||
self.file = open(openFileDialog.GetPath(), "rb")
|
||||
self.image = True
|
||||
self.upload_image.SetLabel(_(u"Discard image"))
|
||||
ev.Skip()
|
||||
|
||||
def onUpdateProfile(self, ev):
|
||||
try:
|
||||
if self.image != None:
|
||||
self.twitter.twitter.update_profile_image(image=self.file)
|
||||
except TwythonError as e:
|
||||
output.speak(u"Error %s. %s" % (e.error_code, e.msg))
|
||||
try:
|
||||
f = self.twitter.twitter.update_profile(name=self.name.GetValue(), location=self.location.GetValue(), url=self.url.GetValue(), description=self.description.GetValue())
|
||||
self.EndModal(wx.ID_OK)
|
||||
except TwythonError as e:
|
||||
output.speak(u"Error %s. %s" % (e.error_code, e.msg))
|
||||
return
|
||||
|
||||
def get_data(self):
|
||||
data = self.twitter.twitter.show_user(screen_name=self.parent.db.settings["user_name"])
|
||||
self.name.ChangeValue(data["name"])
|
||||
if data["url"] != None:
|
||||
self.url.ChangeValue(data["url"])
|
||||
if len(data["location"]) > 0:
|
||||
self.location.ChangeValue(data["location"])
|
||||
if len(data["description"]) > 0:
|
||||
self.description.ChangeValue(data["description"])
|
71
src/gui/dialogs/urlList.py
Normal file
71
src/gui/dialogs/urlList.py
Normal file
@@ -0,0 +1,71 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
############################################################
|
||||
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
############################################################
|
||||
import wx
|
||||
import webbrowser
|
||||
import url_shortener
|
||||
|
||||
class urlList(wx.Dialog):
|
||||
def __init__(self, urls):
|
||||
self.urls = urls
|
||||
super(urlList, self).__init__(parent=None, title=_(u"Select an URL"))
|
||||
panel = wx.Panel(self)
|
||||
# label = wx.StaticText(panel, -1, _(u"Select a URL"))
|
||||
self.lista = wx.ListBox(panel, -1)
|
||||
self.lista.SetFocus()
|
||||
self.populate_list()
|
||||
self.lista.SetSelection(0)
|
||||
self.lista.SetSize(self.lista.GetBestSize())
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
# sizer.Add(label, 0, wx.ALL, 5)
|
||||
sizer.Add(self.lista, 0, wx.ALL, 5)
|
||||
goBtn = wx.Button(panel, wx.ID_OK)
|
||||
goBtn.SetDefault()
|
||||
goBtn.Bind(wx.EVT_BUTTON, self.onGo)
|
||||
cancelBtn = wx.Button(panel, wx.ID_CANCEL)
|
||||
btnSizer = wx.BoxSizer()
|
||||
btnSizer.Add(goBtn, 0, wx.ALL, 5)
|
||||
btnSizer.Add(cancelBtn, 0, wx.ALL, 5)
|
||||
sizer.Add(btnSizer, 0, wx.ALL, 5)
|
||||
panel.SetSizer(sizer)
|
||||
self.SetClientSize(sizer.CalcMin())
|
||||
|
||||
def onGo(self, ev):
|
||||
webbrowser.open(self.lista.GetStringSelection())
|
||||
self.Destroy()
|
||||
|
||||
def populate_list(self):
|
||||
for i in self.urls:
|
||||
self.lista.Append(i)
|
||||
|
||||
class shorten(urlList):
|
||||
def __init__(self, urls, parent):
|
||||
urlList.__init__(self, urls)
|
||||
self.parent = parent
|
||||
|
||||
def onGo(self, ev):
|
||||
self.parent.text.SetValue(self.parent.text.GetValue().replace(self.lista.GetStringSelection(), url_shortener.shorten(self.lista.GetStringSelection())))
|
||||
self.Destroy()
|
||||
|
||||
class unshorten(shorten):
|
||||
def __init__(self, urls, parent):
|
||||
shorten.__init__(self, urls, parent)
|
||||
|
||||
def onGo(self, ev):
|
||||
self.parent.text.SetValue(self.parent.text.GetValue().replace(self.lista.GetStringSelection(), url_shortener.unshorten(self.lista.GetStringSelection())))
|
||||
self.Destroy()
|
49
src/gui/dialogs/utils.py
Normal file
49
src/gui/dialogs/utils.py
Normal file
@@ -0,0 +1,49 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
############################################################
|
||||
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
############################################################
|
||||
import wx, twitter, gui.dialogs, sound, config
|
||||
from mysc.repeating_timer import RepeatingTimer
|
||||
|
||||
class selectUserDialog(wx.Dialog):
|
||||
def __init__(self, parent, title):
|
||||
self.parent = parent
|
||||
wx.Dialog.__init__(self, None, -1)
|
||||
panel = wx.Panel(self)
|
||||
userSizer = wx.BoxSizer()
|
||||
self.SetTitle(title)
|
||||
if self.parent.nb.GetCurrentPage().name_buffer == "followers" or self.parent.nb.GetCurrentPage().name_buffer == "friends":
|
||||
list = [self.parent.db.settings[self.parent.nb.GetCurrentPage().name_buffer][self.parent.nb.GetCurrentPage().list.get_selected()]["screen_name"]]
|
||||
else:
|
||||
try: list =twitter.utils.get_all_users(self.parent.db.settings[self.parent.nb.GetCurrentPage().name_buffer][self.parent.nb.GetCurrentPage().list.get_selected()], self.parent.db)
|
||||
except KeyError: list = [self.parent.db.settings[self.parent.nb.GetCurrentPage().name_buffer][self.parent.nb.GetCurrentPage().list.get_selected()]["screen_name"]]
|
||||
self.cb = wx.ComboBox(panel, -1, choices=list, value=list[0], size=wx.DefaultSize)
|
||||
self.cb.SetFocus()
|
||||
userSizer.Add(wx.StaticText(panel, -1, _(u"User")), 0, wx.ALL, 5)
|
||||
userSizer.Add(self.cb)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
ok = wx.Button(panel, wx.ID_OK, _(u"OK"))
|
||||
ok.SetDefault()
|
||||
# ok.Bind(wx.EVT_BUTTON, self.onok)
|
||||
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"Close"))
|
||||
btnsizer = wx.BoxSizer()
|
||||
btnsizer.Add(ok, 0, wx.ALL, 5)
|
||||
btnsizer.Add(cancel, 0, wx.ALL, 5)
|
||||
sizer.Add(userSizer, 0, wx.ALL, 5)
|
||||
sizer.Add(btnsizer, 0, wx.ALL, 5)
|
||||
panel.SetSizer(sizer)
|
||||
self.SetClientSize(sizer.CalcMin())
|
969
src/gui/main.py
Normal file
969
src/gui/main.py
Normal file
@@ -0,0 +1,969 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
############################################################
|
||||
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
############################################################
|
||||
import wx
|
||||
import dialogs
|
||||
import buffers
|
||||
import config
|
||||
import twitter
|
||||
import db
|
||||
import webbrowser
|
||||
import sound
|
||||
import updater
|
||||
import application
|
||||
import os
|
||||
import logging as original_logger
|
||||
import output
|
||||
import platform
|
||||
import urllib2
|
||||
import sysTrayIcon
|
||||
import languageHandler
|
||||
from issueReporter import gui as issueReporterGUI
|
||||
from sessionmanager import manager
|
||||
from mysc import event
|
||||
from mysc.thread_utils import call_threaded
|
||||
from twython import TwythonError
|
||||
from urllib2 import URLError
|
||||
from mysc.repeating_timer import RepeatingTimer
|
||||
from mysc import localization
|
||||
if platform.system() == "Windows" or platform.system() == "Linux":
|
||||
from keyboard_handler.wx_handler import WXKeyboardHandler
|
||||
from extra import SoundsTutorial
|
||||
from keystrokeEditor import gui as keystrokeEditorGUI
|
||||
log = original_logger.getLogger("gui.main")
|
||||
|
||||
class mainFrame(wx.Frame):
|
||||
""" Main class of the Frame. This is the Main Window."""
|
||||
|
||||
### MENU
|
||||
def makeMenus(self):
|
||||
""" Creates, bind and returns the menu bar for the application. Also in this function, the accel table is created."""
|
||||
menuBar = wx.MenuBar()
|
||||
|
||||
# Application menu
|
||||
app = wx.Menu()
|
||||
updateProfile = app.Append(wx.NewId(), _(u"&Update profile"))
|
||||
self.Bind(wx.EVT_MENU, self.update_profile, updateProfile)
|
||||
show_hide = app.Append(wx.NewId(), _(u"&Hide window"))
|
||||
self.Bind(wx.EVT_MENU, self.show_hide, show_hide)
|
||||
search = app.Append(wx.NewId(), _(u"&Search"))
|
||||
self.Bind(wx.EVT_MENU, self.search, search)
|
||||
lists = app.Append(wx.NewId(), _(u"&Lists manager"))
|
||||
self.Bind(wx.EVT_MENU, self.list_manager, lists)
|
||||
sounds_tutorial = app.Append(wx.NewId(), _(u"Sounds &tutorial"))
|
||||
self.Bind(wx.EVT_MENU, self.learn_sounds, sounds_tutorial)
|
||||
keystroke_editor = app.Append(wx.NewId(), _(u"&Edit keystrokes"))
|
||||
self.Bind(wx.EVT_MENU, self.edit_keystrokes, keystroke_editor)
|
||||
prefs = app.Append(wx.ID_PREFERENCES, _(u"&Preferences"))
|
||||
self.Bind(wx.EVT_MENU, self.preferences, prefs)
|
||||
close = app.Append(wx.ID_EXIT, _(u"E&xit"))
|
||||
self.Bind(wx.EVT_MENU, self.close, close)
|
||||
|
||||
# Tweet menu
|
||||
tweet = wx.Menu()
|
||||
compose = tweet.Append(wx.NewId(), _(u"&Tweet"))
|
||||
self.Bind(wx.EVT_MENU, self.compose, compose)
|
||||
response = tweet.Append(wx.NewId(), _(u"Re&ply"))
|
||||
self.Bind(wx.EVT_MENU, self.reply, response)
|
||||
retweet = tweet.Append(wx.NewId(), _(u"&Retweet"))
|
||||
self.Bind(wx.EVT_MENU, self.retweet, retweet)
|
||||
fav = tweet.Append(wx.NewId(), _(u"Add to &favourites"))
|
||||
self.Bind(wx.EVT_MENU, self.fav, fav)
|
||||
unfav = tweet.Append(wx.NewId(), _(u"Remove from favo&urites"))
|
||||
self.Bind(wx.EVT_MENU, self.unfav, unfav)
|
||||
view = tweet.Append(wx.NewId(), _(u"&Show tweet"))
|
||||
self.Bind(wx.EVT_MENU, self.view, view)
|
||||
delete = tweet.Append(wx.NewId(), _(u"&Delete"))
|
||||
self.Bind(wx.EVT_MENU, self.delete, delete)
|
||||
|
||||
# User menu
|
||||
user = wx.Menu()
|
||||
follow = user.Append(wx.NewId(), _(u"&Follow"))
|
||||
self.Bind(wx.EVT_MENU, self.onFollow, follow)
|
||||
unfollow = user.Append(wx.NewId(), _(u"&Unfollow"))
|
||||
self.Bind(wx.EVT_MENU, self.onUnfollow, unfollow)
|
||||
mute = user.Append(wx.NewId(), _(u"&Mute"))
|
||||
self.Bind(wx.EVT_MENU, self.onMute, mute)
|
||||
unmute = user.Append(wx.NewId(), _(u"U&nmute"))
|
||||
self.Bind(wx.EVT_MENU, self.onUnmute, unmute)
|
||||
report = user.Append(wx.NewId(), _(u"&Report as spam"))
|
||||
self.Bind(wx.EVT_MENU, self.onReport, report)
|
||||
block = user.Append(wx.NewId(), _(u"&Block"))
|
||||
self.Bind(wx.EVT_MENU, self.onBlock, block)
|
||||
unblock = user.Append(wx.NewId(), _(u"Unb&lock"))
|
||||
self.Bind(wx.EVT_MENU, self.onUnblock, unblock)
|
||||
dm = user.Append(wx.NewId(), _(u"Direct me&ssage"))
|
||||
self.Bind(wx.EVT_MENU, self.dm, dm)
|
||||
addToList = user.Append(wx.NewId(), _(u"&Add to list"))
|
||||
self.Bind(wx.EVT_MENU, self.add_to_list, addToList)
|
||||
removeFromList = user.Append(wx.NewId(), _(u"R&emove from list"))
|
||||
self.Bind(wx.EVT_MENU, self.remove_from_list, removeFromList)
|
||||
viewLists = user.Append(wx.NewId(), _(u"&View lists"))
|
||||
self.Bind(wx.EVT_MENU, self.view_user_lists, viewLists)
|
||||
details = user.Append(wx.NewId(), _(u"Show user &profile"))
|
||||
self.Bind(wx.EVT_MENU, self.details, details)
|
||||
timeline = user.Append(wx.NewId(), _(u"&Timeline"))
|
||||
self.Bind(wx.EVT_MENU, self.open_timeline, timeline)
|
||||
favs = user.Append(wx.NewId(), _(u"V&iew favourites"))
|
||||
self.Bind(wx.EVT_MENU, self.favs_timeline, favs)
|
||||
|
||||
# buffer menu
|
||||
buffer = wx.Menu()
|
||||
mute = buffer.Append(wx.NewId(), _(u"&Mute"))
|
||||
self.Bind(wx.EVT_MENU, self.toggle_mute, mute)
|
||||
autoread = buffer.Append(wx.NewId(), _(u"&Autoread tweets for this buffer"))
|
||||
self.Bind(wx.EVT_MENU, self.toggle_autoread, autoread)
|
||||
clear = buffer.Append(wx.NewId(), _(u"&Clear buffer"))
|
||||
self.Bind(wx.EVT_MENU, self.clear_list, clear)
|
||||
deleteTl = buffer.Append(wx.NewId(), _(u"&Remove buffer"))
|
||||
self.Bind(wx.EVT_MENU, self.delete_buffer, deleteTl)
|
||||
|
||||
# Help Menu
|
||||
help = wx.Menu()
|
||||
doc = help.Append(-1, _(u"&Documentation"))
|
||||
self.Bind(wx.EVT_MENU, self.onManual, doc)
|
||||
changelog = help.Append(wx.NewId(), _(u"&What's new in this version?"))
|
||||
self.Bind(wx.EVT_MENU, self.onChangelog, changelog)
|
||||
check_for_updates = help.Append(wx.NewId(), _(u"&Check for updates"))
|
||||
self.Bind(wx.EVT_MENU, self.onCheckForUpdates, check_for_updates)
|
||||
reportError = help.Append(wx.NewId(), _(u"&Report an error"))
|
||||
self.Bind(wx.EVT_MENU, self.onReportBug, reportError)
|
||||
visit_website = help.Append(-1, _(u"TW Blue &website"))
|
||||
self.Bind(wx.EVT_MENU, self.onVisit_website, visit_website)
|
||||
about = help.Append(-1, _(u"About &TW Blue"))
|
||||
self.Bind(wx.EVT_MENU, self.onAbout, about)
|
||||
|
||||
# Add all to the menu Bar
|
||||
menuBar.Append(app, _(u"&Application"))
|
||||
menuBar.Append(tweet, _(u"&Tweet"))
|
||||
menuBar.Append(user, _(u"&User"))
|
||||
menuBar.Append(buffer, _(u"&Buffer"))
|
||||
menuBar.Append(help, _(u"&Help"))
|
||||
|
||||
downID = wx.NewId()
|
||||
upID = wx.NewId()
|
||||
leftID = wx.NewId()
|
||||
rightID = wx.NewId()
|
||||
if platform.system() == "Darwin":
|
||||
self.Bind(wx.EVT_MENU, self.down, id=downID)
|
||||
self.Bind(wx.EVT_MENU, self.up, id=upID)
|
||||
self.Bind(wx.EVT_MENU, self.left, id=leftID)
|
||||
self.Bind(wx.EVT_MENU, self.right, id=rightID)
|
||||
|
||||
# Creates the acceleration table.
|
||||
self.accel_tbl = wx.AcceleratorTable([
|
||||
(wx.ACCEL_CTRL, ord('N'), compose.GetId()),
|
||||
(wx.ACCEL_CTRL, ord('R'), response.GetId()),
|
||||
(wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('R'), retweet.GetId()),
|
||||
(wx.ACCEL_CTRL, ord('F'), fav.GetId()),
|
||||
(wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('F'), unfav.GetId()),
|
||||
(wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('V'), view.GetId()),
|
||||
(wx.ACCEL_CTRL, ord('D'), dm.GetId()),
|
||||
|
||||
(wx.ACCEL_CTRL, ord('Q'), close.GetId()),
|
||||
(wx.ACCEL_CTRL, ord('S'), follow.GetId()),
|
||||
(wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('S'), unfollow.GetId()),
|
||||
(wx.ACCEL_CTRL, ord('K'), block.GetId()),
|
||||
(wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('K'), report.GetId()),
|
||||
(wx.ACCEL_CTRL, ord('I'), timeline.GetId()),
|
||||
(wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('I'), deleteTl.GetId()),
|
||||
(wx.ACCEL_CTRL, ord('M'), show_hide.GetId()),
|
||||
(wx.ACCEL_CTRL, ord('P'), updateProfile.GetId()),
|
||||
(wx.ACCEL_CTRL, wx.WXK_DOWN, downID),
|
||||
(wx.ACCEL_CTRL, wx.WXK_UP, upID),
|
||||
(wx.ACCEL_CTRL, wx.WXK_LEFT, leftID),
|
||||
(wx.ACCEL_CTRL, wx.WXK_RIGHT, rightID),
|
||||
])
|
||||
|
||||
self.SetAcceleratorTable(self.accel_tbl)
|
||||
return menuBar
|
||||
|
||||
### MAIN
|
||||
def __init__(self, authorised=True, user_key=None, user_secret=None):
|
||||
""" Main function of this class."""
|
||||
if authorised == False:
|
||||
self.user_key = user_key
|
||||
self.user_secret = user_secret
|
||||
else:
|
||||
self.user_key = self.user_secret = None
|
||||
log.debug("Loading temporal database...")
|
||||
self.db = db.db()
|
||||
# Gets the twitter object for future calls to the twitter Rest API.
|
||||
log.debug("Getting Twitter's Rest API...")
|
||||
self.twitter = twitter.twitter.twitter()
|
||||
super(mainFrame, self).__init__(None, -1, "TW Blue", size=(1600, 1600))
|
||||
self.Bind(wx.EVT_QUERY_END_SESSION, self.exit)
|
||||
self.Bind(wx.EVT_END_SESSION, self.exit)
|
||||
log.debug(u"Creating the system tray icon... ")
|
||||
sysTray=sysTrayIcon.SysTrayIcon(self)
|
||||
panel = wx.Panel(self)
|
||||
self.sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self.SetTitle("TW Blue")
|
||||
try:
|
||||
updater.update_manager.check_for_update()
|
||||
except:
|
||||
pass
|
||||
self.SetMenuBar(self.makeMenus())
|
||||
self.setup_twitter(panel)
|
||||
|
||||
def logging_in_twblue(self, panel):
|
||||
log.debug("Retrieving username...")
|
||||
twitter.starting.start_user_info(config=self.db, twitter=self.twitter)
|
||||
config.main["twitter"]["user_name"] = self.db.settings["user_name"]
|
||||
self.SetTitle(u"@%s. - TW Blue" % (self.db.settings["user_name"]))
|
||||
self.nb = wx.Treebook(panel, -1)
|
||||
self.Bind(wx.EVT_CLOSE, self.close)
|
||||
self.nb.Bind(wx.EVT_TREEBOOK_PAGE_CHANGED, self.onPageChanged)
|
||||
# Gets the tabs for home, mentions, send and direct messages.
|
||||
log.debug("Creating buffers...")
|
||||
self.db.settings["buffers"] = []
|
||||
account = buffers.accountPanel(self.nb)
|
||||
self.nb.AddPage(account, self.db.settings["user_name"])
|
||||
self.db.settings["buffers"].append(self.db.settings["user_name"])
|
||||
account_index = self.db.settings["buffers"].index(self.db.settings["user_name"])
|
||||
home = buffers.basePanel(self.nb, self, "home_timeline", self.twitter.twitter.get_home_timeline, sound="tweet_received.ogg")
|
||||
self.nb.InsertSubPage(account_index, home, _(u"Home"))
|
||||
self.db.settings["buffers"].append("home_timeline")
|
||||
self.nb.SetSelection(1)
|
||||
self.nb.GetPage(1).list.list.SetFocus()
|
||||
mentionsP = buffers.basePanel(self.nb, self, "mentions", self.twitter.twitter.get_mentions_timeline, sound="mention_received.ogg")
|
||||
self.nb.InsertSubPage(account_index, mentionsP, _("Mentions"))
|
||||
self.db.settings["buffers"].append("mentions")
|
||||
dms = buffers.dmPanel(self.nb, self, "direct_messages", self.twitter.twitter.get_direct_messages, sound="dm_received.ogg")
|
||||
self.nb.InsertSubPage(account_index, dms, _(u"Direct messages"))
|
||||
self.db.settings["buffers"].append("direct_messages")
|
||||
sent = buffers.basePanel(self.nb, self, "sent", self.twitter.twitter.get_user_timeline, argumento=self.db.settings["user_name"])
|
||||
self.nb.InsertSubPage(account_index, sent, _(u"Sent"))
|
||||
self.db.settings["buffers"].append("sent")
|
||||
# If the user has enabled favs from config.
|
||||
if config.main["other_buffers"]["show_favourites"] == True:
|
||||
log.debug("Getting Favorited tweets...")
|
||||
favs = buffers.basePanel(self.nb, self, "favs", self.twitter.twitter.get_favorites)
|
||||
self.nb.InsertSubPage(account_index, favs, _(u"Favourites"))
|
||||
self.db.settings["buffers"].append("favs")
|
||||
# If followers are enabled from config.
|
||||
if config.main["other_buffers"]["show_followers"] == True:
|
||||
log.debug("Getting followers...")
|
||||
followers = buffers.peoplePanel(self.nb, self, "followers", self.twitter.twitter.get_followers_list, argumento=self.db.settings["user_name"], sound="update_followers.ogg")
|
||||
self.nb.InsertSubPage(account_index, followers, _(u"Followers"))
|
||||
self.db.settings["buffers"].append("followers")
|
||||
# Same here but for friends.
|
||||
if config.main["other_buffers"]["show_friends"] == True:
|
||||
log.debug("Getting friends...")
|
||||
friends = buffers.peoplePanel(self.nb, self, "friends", self.twitter.twitter.get_friends_list, argumento=self.db.settings["user_name"])
|
||||
self.nb.InsertSubPage(account_index, friends, _(u"Friends"))
|
||||
self.db.settings["buffers"].append("friends")
|
||||
if config.main["other_buffers"]["show_blocks"] == True:
|
||||
blocked = buffers.peoplePanel(self.nb, self, "blocks", self.twitter.twitter.list_blocks)
|
||||
self.nb.InsertSubPage(account_index, blocked, _(u"Blocked users"))
|
||||
self.db.settings["buffers"].append("blocks")
|
||||
if config.main["other_buffers"]["show_muted_users"] == True:
|
||||
muteds = buffers.peoplePanel(self.nb, self, "muteds", self.twitter.twitter.get_muted_users_list)
|
||||
self.nb.InsertSubPage(account_index, muteds, _(u"Muted users"))
|
||||
self.db.settings["buffers"].append("muteds")
|
||||
if config.main["other_buffers"]["show_events"] == True:
|
||||
evt = buffers.eventsPanel(self.nb, self, sound="new_event.ogg")
|
||||
self.nb.InsertSubPage(account_index, evt, _(u"Events"))
|
||||
self.db.settings["buffers"].append("events")
|
||||
searches = buffers.emptyPanel(self.nb)
|
||||
self.nb.InsertSubPage(account_index, searches, _(u"Searches"))
|
||||
self.db.settings["buffers"].append("searches")
|
||||
|
||||
for i in config.main["other_buffers"]["tweet_searches"]:
|
||||
self.nb.InsertSubPage(self.db.settings["buffers"].index("searches"), buffers.searchPanel(self.nb, self, "%s-search" % (i,), q=i, count=100), _(u"Search for %s" % (i,)))
|
||||
self.db.settings["buffers"].append("%s-search" % (i,))
|
||||
timelines = buffers.emptyPanel(self.nb)
|
||||
self.nb.InsertSubPage(account_index, timelines, _(u"Timelines"))
|
||||
self.db.settings["buffers"].append("timelines")
|
||||
for i in config.main["other_buffers"]["timelines"]:
|
||||
self.nb.InsertSubPage(self.db.settings["buffers"].index("timelines"), buffers.basePanel(self.nb, self, i, self.twitter.twitter.get_user_timeline, argumento=i, timeline=True, sound="tweet_timeline.ogg"), _(u"Timeline for %s") % i)
|
||||
self.db.settings["buffers"].append(i)
|
||||
lists = buffers.emptyPanel(self.nb)
|
||||
self.nb.InsertSubPage(account_index, lists, _(u"Lists"))
|
||||
self.db.settings["buffers"].append("lists")
|
||||
for i in config.main["other_buffers"]["lists"]:
|
||||
self.nb.InsertSubPage(self.db.settings["buffers"].index("lists"), buffers.listPanel(self.nb, self, i+"-list", argumento=twitter.utils.find_list(i, self.db.settings["lists"])), _(u"List for %s") % i)
|
||||
self.db.settings["buffers"].append(i+"-list")
|
||||
|
||||
## favourites timelines
|
||||
favs_timelines = buffers.emptyPanel(self.nb)
|
||||
self.nb.InsertSubPage(account_index, favs_timelines, _(U"Favourites timelines"))
|
||||
self.db.settings["buffers"].append("favourites_timelines")
|
||||
for i in config.main["other_buffers"]["favourites_timelines"]:
|
||||
self.nb.InsertSubPage(self.db.settings["buffers"].index("favourites_timelines"), buffers.favsPanel(self.nb, self, i+"favs", argumento=i, sound="favourites_timeline_updated.ogg"), _(u"Favourites for %s") % i,)
|
||||
self.db.settings["buffers"].append(i+"favs")
|
||||
self.fav_stream = RepeatingTimer(180, self.get_fav_buffers)
|
||||
self.fav_stream.start()
|
||||
self.sizer.Add(self.nb, 0, wx.ALL, 5)
|
||||
panel.SetSizer(self.sizer)
|
||||
self.SetClientSize(self.sizer.CalcMin())
|
||||
self.Bind(event.MyEVT_STARTED, self.onInit)
|
||||
self.Bind(event.EVT_RESULT, self.onMemberAdded)
|
||||
call_threaded(self.init, run_streams=True)
|
||||
|
||||
def init(self, run_streams=False):
|
||||
""" Calls the start_stream function for each stream tab."""
|
||||
deleted = 0
|
||||
for i in range(0, self.nb.GetPageCount()):
|
||||
if self.nb.GetPage(i).type == "account" or self.nb.GetPage(i).type == "empty": continue
|
||||
if i == self.nb.GetPageCount() and deleted > 0:
|
||||
i = i-1
|
||||
deleted = deleted-1
|
||||
log.debug("Starting stream for %s..." % self.nb.GetPage(i).name_buffer)
|
||||
info_event = event.infoEvent(event.EVT_STARTED, 1)
|
||||
try:
|
||||
if self.nb.GetPage(i).type == "search":
|
||||
self.nb.GetPage(i).timer = RepeatingTimer(180, self.nb.GetPage(i).load_search)
|
||||
self.nb.GetPage(i).timer.start()
|
||||
num = self.nb.GetPage(i).start_streams()
|
||||
info_event.SetItem(i, num)
|
||||
wx.PostEvent(self, info_event)
|
||||
except TwythonError as e:
|
||||
continue
|
||||
except UnicodeDecodeError: # This happens when there is a bad internet connection
|
||||
continue
|
||||
output.speak(_(u"Ready"))
|
||||
|
||||
if run_streams == True:
|
||||
self.get_home()
|
||||
self.get_tls()
|
||||
self.check_streams = RepeatingTimer(config.main["general"]["time_to_check_streams"], self.check_stream_up)
|
||||
self.check_streams.start()
|
||||
# If all it's done, then play a nice sound saying that all it's OK.
|
||||
sound.player.play("ready.ogg")
|
||||
|
||||
def remove_list(self, id):
|
||||
for i in range(0, self.nb.GetPageCount()):
|
||||
if self.nb.GetPage(i).type == "list":
|
||||
if self.nb.GetPage(i).argumento == id:
|
||||
pos = self.nb.GetCurrentPage().remove_invalid_buffer()
|
||||
if pos != None:
|
||||
self.nb.DeletePage(pos)
|
||||
self.onMemberAdded()
|
||||
|
||||
def onMemberAdded(self, ev):
|
||||
self.stream2.disconnect()
|
||||
del self.stream2
|
||||
self.get_tls()
|
||||
|
||||
def get_fav_buffers(self):
|
||||
for i in config.main["other_buffers"]["favourites_timelines"]:
|
||||
num = self.nb.GetPage(self.db.settings["buffers"].index(i+"favs")).start_streams()
|
||||
if num > 0: output.speak(_(u"%s favourites from %s") % (nun, i))
|
||||
|
||||
def setup_twitter(self, panel):
|
||||
""" Setting up the connection for twitter, or authenticate if the config file has valid credentials."""
|
||||
# try:
|
||||
self.twitter.login(self.user_key, self.user_secret)
|
||||
self.logging_in_twblue(panel)
|
||||
log.info("Authorized in Twitter.")
|
||||
del self.user_key; del self.user_secret
|
||||
# except:
|
||||
# dlg1 = wx.MessageDialog(panel, _(u"Connection error. Try again later."), _(u"Error!"), wx.ICON_ERROR)
|
||||
# dlg1.ShowModal()
|
||||
# self.Close(True)
|
||||
|
||||
def get_home(self):
|
||||
""" Gets the home stream, that manages home timeline, mentions, direct messages and sent."""
|
||||
try:
|
||||
self.stream = twitter.buffers.stream.streamer(application.app_key, application.app_secret, config.main["twitter"]["user_key"], config.main["twitter"]["user_secret"], parent=self)
|
||||
call_threaded(self.stream.user)
|
||||
except:
|
||||
self.stream.disconnect()
|
||||
|
||||
def start_lists(self):
|
||||
for i in range(0, self.nb.GetPageCount()):
|
||||
if self.nb.GetPage(i).type == "list": self.nb.GetPage(i).retrieve_ids()
|
||||
|
||||
def get_tls(self):
|
||||
""" Setting the stream for individual user timelines."""
|
||||
try:
|
||||
self.stream2 = twitter.buffers.indibidual.streamer(application.app_key, application.app_secret, config.main["twitter"]["user_key"], config.main["twitter"]["user_secret"], parent=self)
|
||||
# The self.ids contains all IDS for the follow argument of the stream.
|
||||
ids = ""
|
||||
# If we have more than 0 items on a list, then.
|
||||
for i in config.main["other_buffers"]["timelines"]:
|
||||
ids = ids+self.db.settings[i][0]["user"]["id_str"]+", "
|
||||
for i in range(0, self.nb.GetPageCount()):
|
||||
if self.nb.GetPage(i).type == "list":
|
||||
for z in self.nb.GetPage(i).users:
|
||||
ids+= str(z)+", "
|
||||
if ids != "":
|
||||
# try:
|
||||
call_threaded(self.stream2.statuses.filter, follow=ids)
|
||||
# except:
|
||||
# pass
|
||||
except:
|
||||
self.stream2.disconnect()
|
||||
|
||||
def check_stream_up(self):
|
||||
try:
|
||||
urllib2.urlopen("http://74.125.228.231", timeout=5)
|
||||
except urllib2.URLError:
|
||||
if self.stream.connected == True: self.stream.disconnect()
|
||||
if hasattr(self, "stream2") and self.stream2.connected: self.stream2.disconnect()
|
||||
if config.main["general"]["announce_stream_status"] == True: output.speak(_(u"Streams disconnected. TW Blue will try to reconnect in a minute."))
|
||||
return
|
||||
if self.stream.connected == False:
|
||||
del self.stream
|
||||
if config.main["general"]["announce_stream_status"] == True: output.speak(_(u"Reconnecting streams..."))
|
||||
call_threaded(self.init)
|
||||
self.get_home()
|
||||
if hasattr(self, "stream2") and self.stream2.connected == False:
|
||||
log.debug("Trying reconnects the timelines stream...")
|
||||
del self.stream2
|
||||
self.get_tls()
|
||||
|
||||
### Events
|
||||
|
||||
def edit_keystrokes(self, ev=None):
|
||||
if hasattr(self, "keyboard_handler"):
|
||||
dlg = keystrokeEditorGUI.keystrokeEditor(parent=self, keyboard_handler=self.keyboard_handler)
|
||||
else:
|
||||
dlg = keystrokeEditorGUI.keystrokeEditor(parent=self)
|
||||
dlg.ShowModal()
|
||||
dlg.Destroy()
|
||||
|
||||
def search(self, ev=None):
|
||||
dlg = dialogs.search.searchDialog()
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
term = dlg.term.GetValue()
|
||||
if dlg.tweets.GetValue() == True:
|
||||
search =buffers.searchPanel(self.nb, self, "%s-search" % (term,), q=term, count=100)
|
||||
self.nb.InsertSubPage(self.db.settings["buffers"].index("searches"), search, _(u"search for %s") % (term,))
|
||||
self.db.settings["buffers"].append("%s-search" % (term,))
|
||||
config.main["other_buffers"]["tweet_searches"].append(term)
|
||||
elif dlg.users.GetValue() == True:
|
||||
search =buffers.searchUsersPanel(self.nb, self, "%s_search" % (term,), q=term, count=20)
|
||||
self.nb.InsertSubPage(self.db.settings["buffers"].index("searches"), search, _(u"search users for %s") % (term,))
|
||||
self.db.settings["buffers"].append("%s_search" % (term,))
|
||||
timer = RepeatingTimer(180, search.load_search)
|
||||
timer.start()
|
||||
num = search.start_streams()
|
||||
search.put_items(num)
|
||||
dlg.Destroy()
|
||||
|
||||
def learn_sounds(self, ev):
|
||||
SoundsTutorial.gui.soundsTutorial().ShowModal()
|
||||
|
||||
def view_user_lists(self, ev=None):
|
||||
userDlg = dialogs.utils.selectUserDialog(parent=self, title=_(u"Select the user"))
|
||||
if userDlg.ShowModal() == wx.ID_OK:
|
||||
user = userDlg.cb.GetValue()
|
||||
else:
|
||||
return
|
||||
dlg = dialogs.lists.userListViewer(self, user)
|
||||
dlg.ShowModal()
|
||||
userDlg.Destroy()
|
||||
dlg.Destroy()
|
||||
|
||||
def add_to_list(self, ev=None):
|
||||
userDlg = dialogs.utils.selectUserDialog(parent=self, title=_(u"Select the user"))
|
||||
if userDlg.ShowModal() == wx.ID_OK:
|
||||
user = userDlg.cb.GetValue()
|
||||
else:
|
||||
return
|
||||
dlg = dialogs.lists.addUserListDialog(self)
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
try:
|
||||
list = self.twitter.twitter.add_list_member(list_id=self.db.settings["lists"][dlg.lista.get_selected()]["id"], screen_name=user)
|
||||
older_list = twitter.utils.find_item(self.db.settings["lists"][dlg.lista.get_selected()]["id"], self.db.settings["lists"])
|
||||
if list["mode"] == "private":
|
||||
self.db.settings["lists"].pop(older_list)
|
||||
self.db.settings["lists"].append(list)
|
||||
except TwythonError as e:
|
||||
output.speak("error %s: %s" % (e.error_code, e.msg))
|
||||
userDlg.Destroy()
|
||||
dlg.Destroy()
|
||||
|
||||
def remove_from_list(self, ev=None):
|
||||
userDlg = dialogs.utils.selectUserDialog(parent=self, title=_(u"Select the user"))
|
||||
if userDlg.ShowModal() == wx.ID_OK:
|
||||
user = userDlg.cb.GetValue()
|
||||
else:
|
||||
return
|
||||
dlg = dialogs.lists.removeUserListDialog(self)
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
try:
|
||||
list = self.twitter.twitter.delete_list_member(list_id=self.db.settings["lists"][dlg.get_selected()]["id"], screen_name=user)
|
||||
older_list = twitter.utils.find_item(self.db.settings["lists"][dlg.get_selected()]["id"], self.db.settings["lists"])
|
||||
if list["mode"] == "private":
|
||||
self.db.settings["lists"].pop(older_list)
|
||||
self.db.settings["lists"].append(list)
|
||||
except TwythonError as e:
|
||||
output.speak("error %s: %s" % (e.error_code, e.msg))
|
||||
userDlg.Destroy()
|
||||
dlg.Destroy()
|
||||
|
||||
def list_manager(self, ev):
|
||||
dlg = dialogs.lists.listViewer(self)
|
||||
dlg.ShowModal()
|
||||
self.stream2.disconnect()
|
||||
del self.stream2
|
||||
self.get_tls()
|
||||
dlg.Destroy()
|
||||
|
||||
def onInit(self, ev):
|
||||
if self.nb.GetPage(ev.GetItem()[0]).type != "search" or self.nb.GetPage(ev.GetItem()[0]).type != "favourites_timeline": self.nb.GetPage(ev.GetItem()[0]).put_items(ev.GetItem()[1])
|
||||
|
||||
def preferences(self, ev=None):
|
||||
dlg = dialogs.configuration.configurationDialog(self)
|
||||
dlg.ShowModal()
|
||||
dlg.Destroy()
|
||||
|
||||
def update_profile(self, ev=None):
|
||||
dialogs.update_profile.updateProfile(self).ShowModal()
|
||||
|
||||
def onManual(self, ev):
|
||||
lang = localization.get("documentation")
|
||||
os.chdir("documentation/%s" % (lang,))
|
||||
webbrowser.open("manual.html")
|
||||
os.chdir("../../")
|
||||
|
||||
def onChangelog(self, ev):
|
||||
lang = localization.get("documentation")
|
||||
os.chdir("documentation/%s" % (lang,))
|
||||
webbrowser.open("changes.html")
|
||||
os.chdir("../../")
|
||||
|
||||
def onVisit_website(self, ev):
|
||||
webbrowser.open("http://twblue.com.mx")
|
||||
|
||||
def onReportBug(self, ev):
|
||||
issueReporterGUI.reportBug(self.db.settings["user_name"]).ShowModal()
|
||||
|
||||
def onCheckForUpdates(self, ev):
|
||||
updater.update_manager.check_for_update(msg=True)
|
||||
|
||||
def details(self, ev=None):
|
||||
""" This function shows details for the selected user."""
|
||||
dlg = dialogs.utils.selectUserDialog(parent=self, title=_(u"User details"))
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
dialogs.show_user.showUserProfile(self.twitter, dlg.cb.GetValue()).ShowModal()
|
||||
dlg.Destroy()
|
||||
|
||||
def delete(self, ev=None):
|
||||
""" Deleting a tweet or direct message."""
|
||||
if self.nb.GetCurrentPage().name_buffer != "followers" and self.nb.GetCurrentPage() != "friends" and self.nb.GetCurrentPage().name_buffer != "events":
|
||||
dlg = wx.MessageDialog(self, _(u"Do you really want to delete this message? It will be eliminated from Twitter as well."), _(u"Delete"), wx.ICON_QUESTION|wx.YES_NO)
|
||||
if dlg.ShowModal() == wx.ID_YES:
|
||||
self.nb.GetCurrentPage().destroy_status(wx.EVT_MENU)
|
||||
else:
|
||||
return
|
||||
|
||||
def onPageChanged(self, ev):
|
||||
""" Announces the new title for the tab."""
|
||||
if platform.system() == "Darwin":
|
||||
output.speak(self.nb.GetPageText(self.nb.GetSelection())+",", True)
|
||||
|
||||
def skip_blank_pages(self, forward=True):
|
||||
if self.nb.GetCurrentPage().type == "account" or self.nb.GetCurrentPage().type == "empty" and (self.showing == False or platform.system() == "Darwin"):
|
||||
self.nb.AdvanceSelection(forward)
|
||||
|
||||
def close(self, ev=None):
|
||||
# if ev == None or hasattr(ev, "GetLoggingOff") == False:
|
||||
dlg = wx.MessageDialog(self, _(u"Do you really want to close TW Blue?"), _(u"Exit"), wx.YES_NO|wx.ICON_QUESTION)
|
||||
if dlg.ShowModal() == wx.ID_YES:
|
||||
self.exit()
|
||||
dlg.Destroy()
|
||||
# elif hasattr(ev, "GetLoggingOff") == True:
|
||||
# self.exit()
|
||||
|
||||
def exit(self, event=None):
|
||||
config.main.write()
|
||||
log.debug("Exiting...")
|
||||
try:
|
||||
self.check_streams.cancel()
|
||||
except AttributeError:
|
||||
pass
|
||||
sound.player.cleaner.cancel()
|
||||
try:
|
||||
self.stream.disconnect()
|
||||
log.debug("Stream disconnected.")
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
self.stream2.disconnect()
|
||||
log.debug(u"Timelines stream disconnected.")
|
||||
except:
|
||||
pass
|
||||
wx.GetApp().ExitMainLoop()
|
||||
|
||||
def onFollow(self, ev=None):
|
||||
""" Opens the follow dialog."""
|
||||
dialogs.follow.follow(self.nb.GetCurrentPage(), "follow").ShowModal()
|
||||
|
||||
def onUnfollow(self, ev=None):
|
||||
""" Opens the unfollow dialog."""
|
||||
dialogs.follow.follow(self.nb.GetCurrentPage(), "unfollow").ShowModal()
|
||||
|
||||
def onMute(self, ev=None):
|
||||
""" Opens the unfollow dialog."""
|
||||
dialogs.follow.follow(self.nb.GetCurrentPage(), "mute").ShowModal()
|
||||
|
||||
def onUnmute(self, ev=None):
|
||||
""" Opens the unfollow dialog."""
|
||||
dialogs.follow.follow(self.nb.GetCurrentPage(), "unmute").ShowModal()
|
||||
|
||||
def onReport(self, ev=None):
|
||||
""" Opens the report dialog, to report as spam to the specified user."""
|
||||
dialogs.follow.follow(self.nb.GetCurrentPage(), "report").ShowModal()
|
||||
|
||||
def onBlock(self, ev=None):
|
||||
""" Opens the "block" dialog, to block the user that you want."""
|
||||
dialogs.follow.follow(self.nb.GetCurrentPage(), "block").ShowModal()
|
||||
|
||||
def onUnblock(self, ev=None):
|
||||
""" Opens the "block" dialog, to block the user that you want."""
|
||||
dialogs.follow.follow(self.nb.GetCurrentPage(), "unblock").ShowModal()
|
||||
|
||||
def action(self, ev=None):
|
||||
dialogs.follow.follow(self.nb.GetCurrentPage()).ShowModal()
|
||||
|
||||
def compose(self, ev=None):
|
||||
""" Opens the new tweet dialog."""
|
||||
self.nb.GetCurrentPage().post_status(ev)
|
||||
|
||||
def reply(self, ev=None):
|
||||
""" Opens the response dialog."""
|
||||
self.nb.GetCurrentPage().onResponse(ev)
|
||||
|
||||
def dm(self, ev=None):
|
||||
""" Opens the DM Dialog."""
|
||||
# The direct_messages buffer has a method to post a diret messages while the other tabs does has not it.
|
||||
if self.nb.GetCurrentPage().name_buffer == "direct_messages":
|
||||
self.nb.GetCurrentPage().onResponse(ev)
|
||||
elif self.nb.GetCurrentPage().name_buffer == "events": return
|
||||
else:
|
||||
# dialogs.message.dm(_(u"Direct message to %s ") % (self.db.settings[self.nb.GetCurrentPage().name_buffer][self.nb.GetCurrentPage().get_selected()]["user"]["screen_name"]), "", "", self.nb.GetCurrentPage()).ShowModal()
|
||||
self.nb.GetCurrentPage().onDm(ev)
|
||||
|
||||
def retweet(self, ev=None):
|
||||
if self.nb.GetCurrentPage().name_buffer != "direct_messages" and self.nb.GetCurrentPage().name_buffer != "followers" and self.nb.GetCurrentPage().name_buffer != "friends" and self.nb.GetCurrentPage().name_buffer != "events":
|
||||
self.nb.GetCurrentPage().onRetweet(ev)
|
||||
|
||||
def view(self, ev=None):
|
||||
tweet = self.nb.GetCurrentPage().get_message(dialog=True)
|
||||
dialogs.message.viewTweet(tweet).ShowModal()
|
||||
|
||||
def fav(self, ev=None):
|
||||
if self.nb.GetCurrentPage().name_buffer != "direct_messages" and self.nb.GetCurrentPage().name_buffer != "followers" and self.nb.GetCurrentPage().name_buffer != "friends":
|
||||
try:
|
||||
self.twitter.twitter.create_favorite(id=self.db.settings[self.nb.GetCurrentPage().name_buffer][self.nb.GetCurrentPage().list.get_selected()]["id"])
|
||||
sound.player.play("favourite.ogg")
|
||||
except TwythonError as e:
|
||||
output.speak(_(u"Error while adding to favourites."), True)
|
||||
sound.player.play("error.ogg")
|
||||
|
||||
def unfav(self, ev=None):
|
||||
if self.nb.GetCurrentPage().name_buffer != "direct_messages" and self.nb.GetCurrentPage().name_buffer != "followers" and self.nb.GetCurrentPage().name_buffer != "friends":
|
||||
try:
|
||||
self.twitter.twitter.destroy_favorite(id=self.db.settings[self.nb.GetCurrentPage().name_buffer][self.nb.GetCurrentPage().list.get_selected()]["id"])
|
||||
except TwythonError as e:
|
||||
output.speak(_(u"Error while removing from favourites."), True)
|
||||
sound.player.play("error.ogg")
|
||||
|
||||
def open_timeline(self, ev=None):
|
||||
dlg = dialogs.utils.selectUserDialog(self, _(u"Individual timeline"))
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
user = twitter.utils.if_user_exists(self.twitter.twitter, dlg.cb.GetValue())
|
||||
if user == None:
|
||||
wx.MessageDialog(None, _(u"The user does not exist"), _(u"Error"), wx.ICON_ERROR).ShowModal()
|
||||
dlg.Destroy()
|
||||
return
|
||||
if user not in config.main["other_buffers"]["timelines"]:
|
||||
config.main["other_buffers"]["timelines"].append(user)
|
||||
else:
|
||||
wx.MessageDialog(None, _(u"There's currently a timeline for this user. You are not able to open another"), _(u"Existing timeline"), wx.ICON_ERROR).ShowModal()
|
||||
dlg.Destroy()
|
||||
return
|
||||
sound.player.play("create_timeline.ogg")
|
||||
st = buffers.basePanel(self.nb, self, user, self.twitter.twitter.get_user_timeline, argumento=user, sound="ready.ogg", timeline=True)
|
||||
num = st.start_streams()
|
||||
self.db.settings["buffers"].append(user)
|
||||
if num == 0:
|
||||
wx.MessageDialog(None, _(u"This user has no tweets. You can't open a timeline for this user"), _(u"Error!"), wx.ICON_ERROR).ShowModal()
|
||||
self.db.settings.pop(user)
|
||||
# self.nb.DeletePage(self.db.settings["buffers"].index(user))
|
||||
self.db.settings["buffers"].remove(user)
|
||||
else:
|
||||
self.nb.InsertSubPage(self.db.settings["buffers"].index("timelines"), st, _(u"Timeline for %s") % (user))
|
||||
st.put_items(num)
|
||||
st.sound = "tweet_timeline.ogg"
|
||||
self.stream2.disconnect()
|
||||
del self.stream2
|
||||
self.get_tls()
|
||||
dlg.Destroy()
|
||||
|
||||
def favs_timeline(self, ev=None):
|
||||
dlg = dialogs.utils.selectUserDialog(self, _(u"List of favourites"))
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
user = twitter.utils.if_user_exists(self.twitter.twitter, dlg.cb.GetValue())
|
||||
if user == None:
|
||||
wx.MessageDialog(None, _(u"The user does not exist"), _(u"Error"), wx.ICON_ERROR).ShowModal()
|
||||
dlg.Destroy()
|
||||
return
|
||||
if user not in config.main["other_buffers"]["favourites_timelines"]:
|
||||
config.main["other_buffers"]["favourites_timelines"].append(user)
|
||||
else:
|
||||
wx.MessageDialog(None, _(u"There's already a list of favourites for this user. You can't create another."), _(u"Existing list"), wx.ICON_ERROR).ShowModal()
|
||||
dlg.Destroy()
|
||||
return
|
||||
sound.player.play("create_timeline.ogg")
|
||||
st = buffers.favsPanel(self.nb, self, user+"-favs", argumento=user, sound="favourites_timeline_updated.ogg")
|
||||
self.nb.InsertSubPage(self.db.settings["buffers"].index("favourites_timelines"), st, _(u"Favourites for %s") % (user))
|
||||
num = st.start_streams()
|
||||
self.db.settings["buffers"].append(user+"-favs")
|
||||
if num == 0:
|
||||
wx.MessageDialog(None, _(u"This user has no favourites. You can't create a list of favourites for this user."), _(u"Error!"), wx.ICON_ERROR).ShowModal()
|
||||
self.db.settings.pop(user+"-favs")
|
||||
self.nb.DeletePage(self.db.settings["buffers"].index(user+"-favs"))
|
||||
self.db.settings["buffers"].remove(user+"-favs")
|
||||
st.put_items(num)
|
||||
dlg.Destroy()
|
||||
|
||||
def onAbout(self, ev=None):
|
||||
info = wx.AboutDialogInfo()
|
||||
info.SetName(application.name)
|
||||
info.SetVersion(application.version)
|
||||
info.SetDescription(application.description)
|
||||
info.SetCopyright(application.copyright)
|
||||
info.SetTranslators(application.translators)
|
||||
# info.SetLicence(application.licence)
|
||||
info.AddDeveloper(application.author)
|
||||
wx.AboutBox(info)
|
||||
|
||||
def delete_buffer(self, ev=None):
|
||||
pos = self.nb.GetCurrentPage().remove_buffer()
|
||||
if pos != None:
|
||||
self.stream2.disconnect()
|
||||
del self.stream2
|
||||
self.nb.DeletePage(self.nb.GetSelection())
|
||||
sound.player.play("delete_timeline.ogg")
|
||||
self.get_tls()
|
||||
|
||||
def delete_invalid_timeline(self):
|
||||
pos = self.nb.GetCurrentPage().remove_invalid_buffer()
|
||||
if pos != None:
|
||||
self.nb.DeletePage(self.nb.GetSelection())
|
||||
|
||||
### Hidden Window
|
||||
def left(self, event=None):
|
||||
num = self.nb.GetSelection()
|
||||
if num == 0:
|
||||
self.nb.ChangeSelection(self.nb.GetPageCount()-1)
|
||||
else:
|
||||
self.nb.SetSelection(num-1)
|
||||
while self.nb.GetCurrentPage().type == "account" or self.nb.GetCurrentPage().type == "empty": self.skip_blank_pages(False)
|
||||
try:
|
||||
msg = _(u"%s, %s of %s") % (self.nb.GetPageText(self.nb.GetSelection()), self.nb.GetCurrentPage().list.get_selected()+1, self.nb.GetCurrentPage().list.get_count())
|
||||
except:
|
||||
msg = _(u"%s. Empty") % (self.nb.GetPageText(self.nb.GetSelection()))
|
||||
output.speak(msg, 1)
|
||||
|
||||
def right(self, event=None):
|
||||
num = self.nb.GetSelection()
|
||||
if num+1 == self.nb.GetPageCount():
|
||||
self.nb.SetSelection(0)
|
||||
else:
|
||||
self.nb.SetSelection(num+1)
|
||||
while self.nb.GetCurrentPage().type == "account" or self.nb.GetCurrentPage().type == "empty": self.skip_blank_pages(True)
|
||||
try:
|
||||
msg = _(u"%s, %s of %s") % (self.nb.GetPageText(self.nb.GetSelection()), self.nb.GetCurrentPage().list.get_selected()+1, self.nb.GetCurrentPage().list.get_count())
|
||||
except:
|
||||
msg = _(u"%s. Empty") % (self.nb.GetPageText(self.nb.GetSelection()))
|
||||
output.speak(msg, 1)
|
||||
|
||||
def show_hide(self, ev=None):
|
||||
# if platform.system() == "Linux" or platform.system() == "Darwin": return
|
||||
keymap = {}
|
||||
for i in config.main["keymap"]:
|
||||
if hasattr(self, i):
|
||||
keymap[config.main["keymap"][i]] = getattr(self, i)
|
||||
if self.showing == True:
|
||||
self.keyboard_handler = WXKeyboardHandler(self)
|
||||
self.keyboard_handler.register_keys(keymap)
|
||||
self.Hide()
|
||||
self.showing = False
|
||||
else:
|
||||
self.keyboard_handler.unregister_keys(keymap)
|
||||
del self.keyboard_handler
|
||||
self.Show()
|
||||
self.showing = True
|
||||
|
||||
def toggle_global_mute(self, event=None):
|
||||
if config.main["sound"]["global_mute"] == False:
|
||||
config.main["sound"]["global_mute"] = True
|
||||
output.speak(_(u"Global mute on"))
|
||||
elif config.main["sound"]["global_mute"] == True:
|
||||
config.main["sound"]["global_mute"] = False
|
||||
output.speak(_(u"Global mute off"))
|
||||
|
||||
def toggle_mute(self, event=None):
|
||||
buffer = self.nb.GetCurrentPage().name_buffer
|
||||
if buffer not in config.main["other_buffers"]["muted_buffers"]:
|
||||
config.main["other_buffers"]["muted_buffers"].append(buffer)
|
||||
output.speak(_(u"Buffer mute on"))
|
||||
elif buffer in config.main["other_buffers"]["muted_buffers"]:
|
||||
config.main["other_buffers"]["muted_buffers"].remove(buffer)
|
||||
output.speak(_(u"Buffer mute off"))
|
||||
|
||||
def toggle_autoread(self, event=None):
|
||||
buffer = self.nb.GetCurrentPage().name_buffer
|
||||
if buffer not in config.main["other_buffers"]["autoread_buffers"]:
|
||||
config.main["other_buffers"]["autoread_buffers"].append(buffer)
|
||||
output.speak(_(u"The auto-reading of new tweets is enabled for this buffer"))
|
||||
elif buffer in config.main["other_buffers"]["autoread_buffers"]:
|
||||
config.main["other_buffers"]["autoread_buffers"].remove(buffer)
|
||||
output.speak(_(u"The auto-reading of new tweets is disabled for this buffer"))
|
||||
|
||||
def repeat_item(self):
|
||||
output.speak(self.nb.GetCurrentPage().get_message(), 1)
|
||||
|
||||
def copy_to_clipboard(self, event=None):
|
||||
output.Copy(self.nb.GetCurrentPage().get_message())
|
||||
output.speak(_(u"Copied"))
|
||||
|
||||
def clear_list(self, event=None):
|
||||
self.nb.GetCurrentPage().interact("clear_list")
|
||||
|
||||
def conversation_up(self, evt=None):
|
||||
if config.main["general"]["reverse_timelines"] == True and evt == None:
|
||||
self.conversation_down("down")
|
||||
return
|
||||
id = self.db.settings[self.nb.GetCurrentPage().name_buffer][self.nb.GetCurrentPage().list.get_selected()]["in_reply_to_status_id_str"]
|
||||
pos = twitter.utils.find_previous_reply(id, self.db.settings["home_timeline"])
|
||||
if pos != None:
|
||||
self.nb.ChangeSelection(1)
|
||||
self.nb.GetCurrentPage().list.select_item(pos)
|
||||
msg = _(u"%s") % (self.nb.GetCurrentPage().get_message())
|
||||
output.speak(msg)
|
||||
|
||||
def conversation_down(self, evt=None):
|
||||
if config.main["general"]["reverse_timelines"] == True and evt == None:
|
||||
self.conversation_up("up")
|
||||
return
|
||||
id = self.db.settings[self.nb.GetCurrentPage().name_buffer][self.nb.GetCurrentPage().list.get_selected()]["id_str"]
|
||||
# pos = twitter.utils.find_next_reply(id, self.db.settings["home_timeline"])
|
||||
pos = twitter.utils.find_next_reply(id, self.db.settings["home_timeline"])
|
||||
if pos != None:
|
||||
self.nb.ChangeSelection(1)
|
||||
self.nb.GetCurrentPage().list.select_item(pos)
|
||||
msg = _(u"%s") % (self.nb.GetCurrentPage().get_message())
|
||||
output.speak(msg)
|
||||
|
||||
def go_home(self):
|
||||
self.nb.GetCurrentPage().list.select_item(0)
|
||||
try:
|
||||
output.speak(self.nb.GetCurrentPage().get_message(), 1)
|
||||
except:
|
||||
pass
|
||||
|
||||
def go_end(self):
|
||||
self.nb.GetCurrentPage().list.select_item(self.nb.GetCurrentPage().list.get_count()-1)
|
||||
try:
|
||||
output.speak(self.nb.GetCurrentPage().get_message(), 1)
|
||||
except:
|
||||
pass
|
||||
|
||||
def go_page_up(self):
|
||||
if self.nb.GetCurrentPage().list.get_selected <= 20:
|
||||
index = 0
|
||||
else:
|
||||
index = self.nb.GetCurrentPage().list.get_selected() - 20
|
||||
self.nb.GetCurrentPage().list.select_item(index)
|
||||
try:
|
||||
output.speak(self.nb.GetCurrentPage().get_message(), 1)
|
||||
except:
|
||||
pass
|
||||
|
||||
def go_page_down(self):
|
||||
if self.nb.GetCurrentPage().list.get_selected() >= self.nb.GetCurrentPage().list.get_count() - 20:
|
||||
index = self.nb.GetCurrentPage().list.get_count()-1
|
||||
else:
|
||||
index = self.nb.GetCurrentPage().list.get_selected() + 20
|
||||
self.nb.GetCurrentPage().list.select_item(index)
|
||||
try:
|
||||
output.speak(self.nb.GetCurrentPage().get_message(), 1)
|
||||
except:
|
||||
pass
|
||||
|
||||
def volume_up(self):
|
||||
self.nb.GetCurrentPage().interact("volume_up")
|
||||
|
||||
def volume_down(self):
|
||||
self.nb.GetCurrentPage().interact("volume_down")
|
||||
|
||||
def url(self):
|
||||
self.nb.GetCurrentPage().interact("url")
|
||||
|
||||
def audio(self):
|
||||
self.nb.GetCurrentPage().interact("audio")
|
||||
|
||||
def up(self, event=None):
|
||||
pos = self.nb.GetCurrentPage().list.get_selected()
|
||||
index = self.nb.GetCurrentPage().list.get_selected()-1
|
||||
try:
|
||||
self.nb.GetCurrentPage().list.select_item(index)
|
||||
except:
|
||||
pass
|
||||
if pos == self.nb.GetCurrentPage().list.get_selected():
|
||||
sound.player.play("limit.ogg", False)
|
||||
try:
|
||||
output.speak(self.nb.GetCurrentPage().get_message(), 1)
|
||||
except:
|
||||
pass
|
||||
|
||||
def down(self, event=None):
|
||||
index = self.nb.GetCurrentPage().list.get_selected()+1
|
||||
pos = self.nb.GetCurrentPage().list.get_selected()
|
||||
try:
|
||||
self.nb.GetCurrentPage().list.select_item(index)
|
||||
except:
|
||||
pass
|
||||
if pos == self.nb.GetCurrentPage().list.get_selected():
|
||||
sound.player.play("limit.ogg", False)
|
||||
try:
|
||||
output.speak(self.nb.GetCurrentPage().get_message(), 1)
|
||||
except:
|
||||
pass
|
||||
|
||||
def get_more_items(self):
|
||||
self.nb.GetCurrentPage().get_more_items()
|
||||
|
||||
def connect_streams(self):
|
||||
disconnect = False
|
||||
if self.stream.connected == False:
|
||||
output.speak(_(u"Trying to reconnect the main stream"))
|
||||
disconnect = True
|
||||
del self.stream
|
||||
call_threaded(self.init)
|
||||
self.get_home()
|
||||
if hasattr(self, "stream2") and self.stream2.connected == False:
|
||||
output.speak(_(u"Trying to reconnect the buffers stream"))
|
||||
disconnect = True
|
||||
log.debug("Trying reconnects the timelines stream...")
|
||||
del self.stream2
|
||||
self.get_tls()
|
||||
if disconnect == False:
|
||||
output.speak(_(u"All streams are working properly"))
|
||||
|
||||
### Close App
|
||||
def Destroy(self):
|
||||
self.sysTray.Destroy()
|
||||
super(mainFrame, self).Destroy()
|
62
src/gui/sysTrayIcon.py
Normal file
62
src/gui/sysTrayIcon.py
Normal file
@@ -0,0 +1,62 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
""" A systray for TW Blue """
|
||||
############################################################
|
||||
# Copyright (c) 2014 José Manuel Delicado Alcolea <jmdaweb@gmail.com>
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
############################################################
|
||||
|
||||
import wx
|
||||
import application
|
||||
import paths
|
||||
import os
|
||||
|
||||
class SysTrayIcon(wx.TaskBarIcon):
|
||||
|
||||
def __init__(self, frame):
|
||||
super(SysTrayIcon, self).__init__()
|
||||
self.frame=frame
|
||||
icon=wx.Icon(os.path.join(paths.app_path(), "icon.ico"), wx.BITMAP_TYPE_ICO)
|
||||
self.SetIcon(icon, application.name)
|
||||
self.menu=wx.Menu()
|
||||
item=self.menu.Append(wx.ID_ANY, _(u"Tweet"))
|
||||
self.Bind(wx.EVT_MENU, frame.compose, item)
|
||||
item=self.menu.Append(wx.ID_ANY, _(u"Preferences"))
|
||||
self.Bind(wx.EVT_MENU, frame.preferences, item)
|
||||
item=self.menu.Append(wx.ID_ANY, _(u"Update profile"))
|
||||
self.Bind(wx.EVT_MENU, frame.update_profile, item)
|
||||
item=self.menu.Append(wx.ID_ANY, _(u"Show / hide"))
|
||||
self.Bind(wx.EVT_MENU, frame.show_hide, item)
|
||||
item=self.menu.Append(wx.ID_ANY, _(u"Documentation"))
|
||||
self.Bind(wx.EVT_MENU, frame.onManual, item)
|
||||
item=self.menu.Append(wx.ID_ANY, _(u"Check for updates"))
|
||||
self.Bind(wx.EVT_MENU, frame.onCheckForUpdates, item)
|
||||
item=self.menu.Append(wx.ID_ANY, _(u"Exit"))
|
||||
self.Bind(wx.EVT_MENU, frame.close, item)
|
||||
self.Bind(wx.EVT_TASKBAR_RIGHT_DOWN, self.onRightClick)
|
||||
self.Bind(wx.EVT_TASKBAR_LEFT_DOWN, self.onLeftClick)
|
||||
|
||||
def onRightClick(self, evt):
|
||||
self.PopupMenu(self.menu)
|
||||
|
||||
def onLeftClick(self, evt):
|
||||
if (self.frame.showing):
|
||||
self.frame.SetFocus()
|
||||
else:
|
||||
self.frame.onShow_hide()
|
||||
|
||||
def Destroy(self):
|
||||
self.menu.Destroy()
|
||||
super(SysTrayIcon, self).Destroy()
|
Reference in New Issue
Block a user