mirror of
https://github.com/MCV-Software/TWBlue.git
synced 2025-08-25 17:39:23 +00:00
Compare commits
42 Commits
snapshot10
...
snapshot10
Author | SHA1 | Date | |
---|---|---|---|
ce1f8b2cc3 | |||
5933323beb | |||
22b1b0a149 | |||
e71afeb10f | |||
98f026156d | |||
cbee57aa30 | |||
fd9e4dc05d | |||
6022cecad1 | |||
89e39e2168 | |||
a69bf99c1a | |||
d34ef81324 | |||
a3c050195a | |||
3623eafacd | |||
![]() |
2bd3f0a1d1 | ||
f1f828522e | |||
51e4898346 | |||
c4478198b6 | |||
f468924b85 | |||
158b48e4d5 | |||
756a58e443 | |||
85ce5b0791 | |||
![]() |
e534d1cd20 | ||
2d35304ef0 | |||
4f0e6d758b | |||
bd4aa89c2b | |||
b046360293 | |||
6971fb3999 | |||
7b840f29c4 | |||
71fed7300b | |||
57315c3b6e | |||
3d3abc90e1 | |||
de7882e4cf | |||
![]() |
10190d61c0 | ||
bb6fa7cb46 | |||
80cb70c9a6 | |||
77d51aa51a | |||
![]() |
ebb4e22d02 | ||
4344a0df0c | |||
34ad0c5e47 | |||
704ade560a | |||
a4892cf847 | |||
e59661775a |
25
README.md
25
README.md
@@ -39,7 +39,7 @@ If you want to build both x86 and x64 binaries, you can install python x86 to C:
|
||||
* [Pycurl](http://pycurl.sourceforge.net) 7.19.5.1 for Python 2.7: [32-bit downloads,](https://pypi.python.org/pypi/pycurl/7.19.5.1) [64-bit downloads](http://www.lfd.uci.edu/~gohlke/pythonlibs/)
|
||||
Note: the x64 version is in wheel format instead of executable installer, so you have to install it using pip. For example: C:\python27x64\scripts\pip install pycurl-7.19.5.1-cp27-none-win_amd64.whl
|
||||
* [PyEnchant,](http://pythonhosted.org/pyenchant/) version 1.6.6.
|
||||
x64 version has been built by TW Blue developers, so you only will find it in windows-dependencies folder
|
||||
x64 version has been built by TWBlue developers, so you only will find it in windows-dependencies folder
|
||||
|
||||
The windows installers are available only in the windows-dependencies folder
|
||||
|
||||
@@ -71,8 +71,11 @@ setuptools install a script, called easy_install. You can find it in the python
|
||||
* arrow
|
||||
* goslate
|
||||
* markdown
|
||||
* pocket
|
||||
|
||||
easy_install will automatically get the additional libraries that these packages need to work properly.
|
||||
Run the following command to quickly install and upgrade all packages and their dependencies:
|
||||
easy_install -Z --upgrade six configobj goslate markdown future pocket suds requests oauthlib requests-oauthlib pypubsub pygeocoder arrow
|
||||
|
||||
#### Other dependencies
|
||||
|
||||
@@ -95,9 +98,16 @@ Now that you have installed all these packages, you can run TW Blue from source
|
||||
|
||||
If necessary, change the first part of the command to reflect the location of your python executable. You can run TW Blue using python x86 and x64
|
||||
|
||||
### Generating the documentation
|
||||
|
||||
To generate the documentation in html format, navigate to the doc folder inside this repo. After that, run this command:
|
||||
python generator.py
|
||||
The documentation will be generated, placing each language in a separate folder in the doc directory. Move these folders (for example de, en, es, fr, it, ...) to src/documentation, creating the directory if necesary.
|
||||
Also, copy the license.txt located in the root of the repo to the documentation folder.
|
||||
|
||||
### Building a binary version
|
||||
|
||||
A binary version doesn't need python and the other dependencies to run, it's the same version that you will find on the TW Blue website if you download the zip files.
|
||||
A binary version doesn't need python and the other dependencies to run, it's the same version that you will find on the TW Blue website if you download the zip files or the snapshot versions.
|
||||
|
||||
To build it, run the following command from the src folder:
|
||||
|
||||
@@ -105,6 +115,17 @@ To build it, run the following command from the src folder:
|
||||
|
||||
You will find the binaries in the dist directory.
|
||||
|
||||
### Building an installer
|
||||
|
||||
If you want to install TWBlue in your computer, you must create the installer first. Follow these steps:
|
||||
|
||||
* Navigate to the src directory, and create a binary version for x86: C:\python27\python setup.py py2exe
|
||||
* Move the dist directory to the scripts folder in this repo, and rename it to twblue
|
||||
* Repeat these steps with Python for x64: C:\python27x64\python setup.py py2exe
|
||||
* Move the new dist directory to the scripts folder, and rename it to twblue64
|
||||
* Go to the scripts folder, right click on the twblue.nsi file, and choose compyle unicode NSIS script
|
||||
* This may take a while. After the process, you will find the installer in the scripts folder
|
||||
|
||||
### How to generate a translation template
|
||||
|
||||
Run the gen_pot.bat file, located in the tools directory. Your python installation must be in your path environment variable. The pot file will appear in the tools directory.
|
||||
|
@@ -405,19 +405,21 @@ documentation.append(_(u"""We would also like to thank the translators of TWBlue
|
||||
documentation.append(_(u"""
|
||||
"""))
|
||||
documentation.append(_(u"""* English: [Bryner Villalobos](https://twitter.com/Bry_StarkCR) and [Bill Dengler](https://twitter.com/codeofdusk)."""))
|
||||
documentation.append(_(u"""* Arabic: Mohammed Al Shara."""))
|
||||
documentation.append(_(u"""* Arabic: [Mohammed Al Shara](https://twitter.com/mohammed0204)."""))
|
||||
documentation.append(_(u"""* Catalan: [Joan Rabat](https://twitter.com/joanrabat) and Juan Carlos Rivilla."""))
|
||||
documentation.append(_(u"""* Spanish: [Manuel Cortéz](https://twitter.com/manuelcortez00)."""))
|
||||
documentation.append(_(u"""* Basque: [Sukil Etxenike](https://twitter.com/sukil2011)."""))
|
||||
documentation.append(_(u"""* Finnish: Jani Kinnunen."""))
|
||||
documentation.append(_(u"""* French: Rémi Ruiz."""))
|
||||
documentation.append(_(u"""* Finnish: [Jani Kinnunen](https://twitter.com/jani_kinnunen)."""))
|
||||
documentation.append(_(u"""* French: [Rémi Ruiz](https://twitter.com/blindhelp38)."""))
|
||||
documentation.append(_(u"""* Galician: [Alba Kinteiro](https://twitter.com/albasmileforeve)."""))
|
||||
documentation.append(_(u"""* German: Steffen Schultz."""))
|
||||
documentation.append(_(u"""* German: [Steffen Schultz](https://twitter.com/schulle4u)."""))
|
||||
documentation.append(_(u"""* Croatian: [Zvonimir Stanečić](https://twitter.com/zvonimirek222)."""))
|
||||
documentation.append(_(u"""* Hungarian: Robert Osztolykan."""))
|
||||
documentation.append(_(u"""* Italian: [Christian Leo Mameli](https://twitter.com/llajta2012)."""))
|
||||
documentation.append(_(u"""* Polish: Pawel Masarczyk."""))
|
||||
documentation.append(_(u"""* Portuguese: Odenilton Júnior Santos."""))
|
||||
documentation.append(_(u"""* Russian: Alexander Jaszyn."""))
|
||||
documentation.append(_(u"""* Turkish: Burak."""))
|
||||
documentation.append(_(u"""* Russian: [Александр Яшин](https://twitter.com/radovest)."""))
|
||||
documentation.append(_(u"""* Turkish: [Burak Yüksek](https://twitter.com/burakyuksek)."""))
|
||||
documentation.append(_(u"""
|
||||
"""))
|
||||
documentation.append(_(u"""Many thanks also to the people who worked on the documentation. Initially, [Manuel Cortez](https://twitter.com/manuelcortez00) did the documentation in Spanish, and translated to English by [Bryner Villalobos](https://twitter.com/Bry_StarkCR), [Robert Spangler](https://twitter.com/glasscity1837), [Sussan Rey](https://twitter.com/sussanrey17), [Anibal Hernandez](https://twitter.com/anibalmetal), and [Holly Scott-Gardner](https://twitter.com/holly1994). It was updated by [Sukil Etxenike](https://twitter.com/sukil2011), with some valuable corrections by [Brian Hartgen](https://twitter.com/brianhartgen) and [Bill Dengler](https://twitter.com/codeofdusk)."""))
|
||||
|
@@ -8,7 +8,7 @@ language = string(default="system")
|
||||
hide_gui = boolean(default=False)
|
||||
voice_enabled = boolean(default=False)
|
||||
ask_at_exit = boolean(default=True)
|
||||
handle_longtweets = boolean(default=False)
|
||||
handle_longtweets = boolean(default=True)
|
||||
use_invisible_keyboard_shorcuts = boolean(default=True)
|
||||
play_ready_sound = boolean(default=True)
|
||||
speak_ready_msg = boolean(default=True)
|
||||
|
@@ -5,7 +5,7 @@ if snapshot == False:
|
||||
version = "0.80"
|
||||
update_url = 'http://twblue.es/updates/twblue_ngen.json'
|
||||
else:
|
||||
version = "10.2"
|
||||
version = "10.8"
|
||||
update_url = 'http://twblue.es/updates/snapshots_ngen.json'
|
||||
author = u"Manuel Cortéz, Bill Dengler"
|
||||
authorEmail = "manuel@manuelcortez.net"
|
||||
|
@@ -2,7 +2,7 @@
|
||||
import platform
|
||||
if platform.system() == "Windows":
|
||||
import wx
|
||||
from wxUI import buffers, dialogs, commonMessageDialogs
|
||||
from wxUI import buffers, dialogs, commonMessageDialogs, menus
|
||||
import user
|
||||
elif platform.system() == "Linux":
|
||||
from gi.repository import Gtk
|
||||
@@ -142,6 +142,13 @@ class bufferController(object):
|
||||
call_threaded(self.session.api_call, call_name="update_status_with_media", status=text, media=tweet.image)
|
||||
if hasattr(tweet.message, "destroy"): tweet.message.destroy()
|
||||
|
||||
def save_positions(self):
|
||||
try:
|
||||
self.session.db[self.name+"_pos"]=self.buffer.list.get_selected()
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
|
||||
class accountPanel(bufferController):
|
||||
def __init__(self, parent, name, account, account_id):
|
||||
super(accountPanel, self).__init__(parent, None, name)
|
||||
@@ -224,7 +231,8 @@ class baseBufferController(bufferController):
|
||||
return self.get_message()
|
||||
|
||||
def get_message(self):
|
||||
return " ".join(self.compose_function(self.get_right_tweet(), self.session.db, self.session.settings["general"]["relative_times"]))
|
||||
tweet = self.get_right_tweet()
|
||||
return " ".join(self.compose_function(tweet, self.session.db, self.session.settings["general"]["relative_times"]))
|
||||
|
||||
def get_full_tweet(self):
|
||||
tweet = self.get_right_tweet()
|
||||
@@ -235,6 +243,10 @@ class baseBufferController(bufferController):
|
||||
uri = tweet["long_uri"]
|
||||
try:
|
||||
tweet = self.session.twitter.twitter.show_status(id=tweet_id)
|
||||
urls = utils.find_urls_in_text(tweet["text"])
|
||||
for url in range(0, len(urls)):
|
||||
try: tweet["text"] = tweet["text"].replace(urls[url], tweet["entities"]["urls"][url]["expanded_url"])
|
||||
except IndexError: pass
|
||||
except TwythonError as e:
|
||||
utils.twitter_error(e)
|
||||
return
|
||||
@@ -246,6 +258,10 @@ class baseBufferController(bufferController):
|
||||
id = tweets.get_id(l)
|
||||
try:
|
||||
tweet = self.session.twitter.twitter.show_status(id=id)
|
||||
urls = utils.find_urls_in_text(tweet["text"])
|
||||
for url in range(0, len(urls)):
|
||||
try: tweet["text"] = tweet["text"].replace(urls[url], tweet["entities"]["urls"][url]["expanded_url"])
|
||||
except IndexError: pass
|
||||
except TwythonError as e:
|
||||
utils.twitter_error(e)
|
||||
return
|
||||
@@ -357,6 +373,61 @@ class baseBufferController(bufferController):
|
||||
widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.retweet, self.buffer.retweet)
|
||||
widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.direct_message, self.buffer.dm)
|
||||
widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.reply, self.buffer.reply)
|
||||
# Replace for the correct way in other platforms.
|
||||
widgetUtils.connect_event(self.buffer.list.list, wx.EVT_LIST_ITEM_RIGHT_CLICK, self.show_menu)
|
||||
widgetUtils.connect_event(self.buffer.list.list, wx.EVT_LIST_KEY_DOWN, self.show_menu_by_key)
|
||||
|
||||
def show_menu(self, ev, pos=0, *args, **kwargs):
|
||||
if self.buffer.list.get_count() == 0: return
|
||||
if self.name == "sent_tweets" or self.name == "sent_direct_messages":
|
||||
menu = menus.sentPanelMenu()
|
||||
elif self.name == "direct_messages":
|
||||
menu = menus.dmPanelMenu()
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.direct_message, menuitem=menu.reply)
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.user_actions, menuitem=menu.userActions)
|
||||
else:
|
||||
menu = menus.basePanelMenu()
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.reply, menuitem=menu.reply)
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.user_actions, menuitem=menu.userActions)
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.retweet, menuitem=menu.retweet)
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.fav, menuitem=menu.fav)
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.unfav, menuitem=menu.unfav)
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.url_, menuitem=menu.openUrl)
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.audio, menuitem=menu.play)
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.view, menuitem=menu.view)
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.copy, menuitem=menu.copy)
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.destroy_status, menuitem=menu.remove)
|
||||
if pos != 0:
|
||||
self.buffer.PopupMenu(menu, pos)
|
||||
else:
|
||||
self.buffer.PopupMenu(menu, ev.GetPosition())
|
||||
|
||||
def view(self, *args, **kwargs):
|
||||
pub.sendMessage("execute-action", action="view_item")
|
||||
|
||||
def copy(self, *args, **kwargs):
|
||||
pub.sendMessage("execute-action", action="copy_to_clipboard")
|
||||
|
||||
def user_actions(self, *args, **kwargs):
|
||||
pub.sendMessage("execute-action", action="follow")
|
||||
|
||||
def fav(self, *args, **kwargs):
|
||||
pub.sendMessage("execute-action", action="add_to_favourites")
|
||||
|
||||
def unfav(self, *args, **kwargs):
|
||||
pub.sendMessage("execute-action", action="remove_from_favourites")
|
||||
|
||||
def delete_item_(self, *args, **kwargs):
|
||||
pub.sendMessage("execute-action", action="delete_item")
|
||||
|
||||
def url_(self, *args, **kwargs):
|
||||
self.url()
|
||||
|
||||
def show_menu_by_key(self, ev):
|
||||
if self.buffer.list.get_count() == 0:
|
||||
return
|
||||
if ev.GetKeyCode() == wx.WXK_WINDOWS_MENU:
|
||||
self.show_menu(widgetUtils.MENU, pos=self.buffer.list.list.GetPosition())
|
||||
|
||||
def get_tweet(self):
|
||||
if self.session.db[self.name][self.buffer.list.get_selected()].has_key("retweeted_status"):
|
||||
@@ -423,7 +494,7 @@ class baseBufferController(bufferController):
|
||||
self._retweet_with_comment(tweet, id)
|
||||
|
||||
def _retweet_with_comment(self, tweet, id, comment=''):
|
||||
retweet = messages.tweet(self.session, _(u"Retweet"), _(u"Add your comment to the tweet"), u"“@%s: %s ”" % (tweet["user"]["screen_name"], tweet["text"]), max=116-len("@%s " % (tweet["user"]["screen_name"],)), messageType="retweet", twishort_enabled=self.session.settings["mysc"]["twishort_enabled"])
|
||||
retweet = messages.tweet(self.session, _(u"Retweet"), _(u"Add your comment to the tweet"), u"“@%s: %s ”" % (tweet["user"]["screen_name"], tweet["text"]), max=116, messageType="retweet", twishort_enabled=self.session.settings["mysc"]["twishort_enabled"])
|
||||
if comment != '':
|
||||
retweet.message.set_text(comment)
|
||||
if retweet.message.get_response() == widgetUtils.OK:
|
||||
@@ -457,10 +528,9 @@ class baseBufferController(bufferController):
|
||||
self.session.sound.play("audio.ogg")
|
||||
if utils.is_geocoded(tweet):
|
||||
self.session.sound.play("geo.ogg")
|
||||
self.session.db[self.name+"_pos"]=self.buffer.list.get_selected()
|
||||
|
||||
@_tweets_exist
|
||||
def audio(self,url=''):
|
||||
# @_tweets_exist
|
||||
def audio(self, url='', *args, **kwargs):
|
||||
if hasattr(sound.URLPlayer,'stream'):
|
||||
return sound.URLPlayer.stop_audio(delete=True)
|
||||
tweet = self.get_tweet()
|
||||
@@ -480,8 +550,8 @@ class baseBufferController(bufferController):
|
||||
except:
|
||||
log.error("Exception while executing audio method.")
|
||||
|
||||
@_tweets_exist
|
||||
def url(self,url='',announce=True):
|
||||
# @_tweets_exist
|
||||
def url(self, url='', announce=True, *args, **kwargs):
|
||||
if url == '':
|
||||
tweet = self.get_tweet()
|
||||
urls = utils.find_urls(tweet)
|
||||
@@ -535,6 +605,26 @@ class baseBufferController(bufferController):
|
||||
user.profileController(session=self.session, user=dlg.get_user())
|
||||
if hasattr(dlg, "destroy"): dlg.destroy()
|
||||
|
||||
def get_quoted_tweet(self, tweet):
|
||||
# try:
|
||||
quoted_tweet = self.session.twitter.twitter.show_status(id=tweet["id"])
|
||||
urls = utils.find_urls_in_text(quoted_tweet["text"])
|
||||
for url in range(0, len(urls)):
|
||||
try: quoted_tweet["text"] = quoted_tweet["text"].replace(urls[url], quoted_tweet["entities"]["urls"][url]["expanded_url"])
|
||||
except IndexError: pass
|
||||
# except TwythonError as e:
|
||||
# utils.twitter_error(e)
|
||||
# return
|
||||
l = tweets.is_long(quoted_tweet)
|
||||
id = tweets.get_id(l)
|
||||
# try:
|
||||
original_tweet = self.session.twitter.twitter.show_status(id=id)
|
||||
urls = utils.find_urls_in_text(original_tweet["text"])
|
||||
for url in range(0, len(urls)):
|
||||
try: original_tweet["text"] = original_tweet["text"].replace(urls[url], original_tweet["entities"]["urls"][url]["expanded_url"])
|
||||
except IndexError: pass
|
||||
return compose.compose_quoted_tweet(quoted_tweet, original_tweet, self.session.db, self.session.settings["general"]["relative_times"])
|
||||
|
||||
class listBufferController(baseBufferController):
|
||||
def __init__(self, parent, function, name, sessionObject, account, sound=None, bufferType=None, list_id=None, *args, **kwargs):
|
||||
super(listBufferController, self).__init__(parent, function, name, sessionObject, account, sound=None, bufferType=None, *args, **kwargs)
|
||||
@@ -599,6 +689,23 @@ class eventsBufferController(bufferController):
|
||||
if dlg == widgetUtils.YES:
|
||||
self.buffer.list.clear()
|
||||
|
||||
def show_menu(self, ev, pos=0, *args, **kwargs):
|
||||
if self.buffer.list.get_count() == 0: return
|
||||
menu = menus.eventsPanelMenu()
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.view, menuitem=menu.view)
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.copy, menuitem=menu.copy)
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.destroy_status, menuitem=menu.remove)
|
||||
if pos != 0:
|
||||
self.buffer.PopupMenu(menu, pos)
|
||||
else:
|
||||
self.buffer.PopupMenu(menu, ev.GetPosition())
|
||||
|
||||
def view(self, *args, **kwargs):
|
||||
pub.sendMessage("execute-action", action="view_item")
|
||||
|
||||
def copy(self, *args, **kwargs):
|
||||
pub.sendMessage("execute-action", action="copy_to_clipboard")
|
||||
|
||||
class peopleBufferController(baseBufferController):
|
||||
def __init__(self, parent, function, name, sessionObject, account, bufferType=None, *args, **kwargs):
|
||||
super(peopleBufferController, self).__init__(parent, function, name, sessionObject, account, bufferType="peoplePanel")
|
||||
@@ -709,6 +816,22 @@ class peopleBufferController(baseBufferController):
|
||||
def interact(self):
|
||||
user.profileController(self.session, user=self.get_right_tweet()["screen_name"])
|
||||
|
||||
def show_menu(self, ev, pos=0, *args, **kwargs):
|
||||
menu = menus.peoplePanelMenu()
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.direct_message, menuitem=menu.reply)
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.user_actions, menuitem=menu.userActions)
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.details, menuitem=menu.details)
|
||||
# widgetUtils.connect_event(menu, widgetUtils.MENU, self.lists, menuitem=menu.lists)
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.view, menuitem=menu.view)
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.copy, menuitem=menu.copy)
|
||||
if pos != 0:
|
||||
self.buffer.PopupMenu(menu, pos)
|
||||
else:
|
||||
self.buffer.PopupMenu(menu, ev.GetPosition())
|
||||
|
||||
def details(self, *args, **kwargs):
|
||||
pub.sendMessage("execute-action", action="user_details")
|
||||
|
||||
class searchBufferController(baseBufferController):
|
||||
def start_stream(self):
|
||||
log.debug("Starting stream for %s buffer, %s account and %s type" % (self.name, self.account, self.type))
|
||||
@@ -785,6 +908,7 @@ class trendsBufferController(bufferController):
|
||||
self.buffer.name = name
|
||||
self.compose_function = self.compose_function_
|
||||
self.get_formatted_message = self.get_message
|
||||
self.reply = self.search_topic
|
||||
|
||||
def start_stream(self):
|
||||
try:
|
||||
@@ -811,10 +935,14 @@ class trendsBufferController(bufferController):
|
||||
def bind_events(self):
|
||||
log.debug("Binding events...")
|
||||
self.buffer.list.list.Bind(wx.EVT_CHAR_HOOK, self.get_event)
|
||||
# widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.post_tweet, self.buffer.tweet)
|
||||
widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.post_tweet, self.buffer.tweet)
|
||||
widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.tweet_about_this_trend, self.buffer.tweetTrendBtn)
|
||||
|
||||
# widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.retweet, self.buffer.retweet)
|
||||
# widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.direct_message, self.buffer.dm)
|
||||
# widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.reply, self.buffer.reply)
|
||||
widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.search_topic, self.buffer.search_topic)
|
||||
widgetUtils.connect_event(self.buffer.list.list, wx.EVT_LIST_ITEM_RIGHT_CLICK, self.show_menu)
|
||||
widgetUtils.connect_event(self.buffer.list.list, wx.EVT_LIST_KEY_DOWN, self.show_menu_by_key)
|
||||
|
||||
def get_message(self):
|
||||
return self.compose_function(self.trends[self.buffer.list.get_selected()])[0]
|
||||
@@ -829,8 +957,52 @@ class trendsBufferController(bufferController):
|
||||
elif dlg == widgetUtils.NO:
|
||||
return False
|
||||
|
||||
def interact(self, *args, **kwargs):
|
||||
self.searchfunction(value=self.get_message())
|
||||
def search_topic(self, *args, **kwargs):
|
||||
topic = self.trends[self.buffer.list.get_selected()]["name"]
|
||||
pub.sendMessage("search", term=topic)
|
||||
|
||||
def show_menu(self, ev, pos=0, *args, **kwargs):
|
||||
menu = menus.trendsPanelMenu()
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.search_topic, menuitem=menu.search_topic)
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.tweet_about_this_trend, menuitem=menu.tweetThisTrend)
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.view, menuitem=menu.view)
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.copy, menuitem=menu.copy)
|
||||
if pos != 0:
|
||||
self.buffer.PopupMenu(menu, pos)
|
||||
else:
|
||||
self.buffer.PopupMenu(menu, ev.GetPosition())
|
||||
|
||||
def view(self, *args, **kwargs):
|
||||
pub.sendMessage("execute-action", action="view_item")
|
||||
|
||||
def copy(self, *args, **kwargs):
|
||||
pub.sendMessage("execute-action", action="copy_to_clipboard")
|
||||
|
||||
def tweet_about_this_trend(self, *args, **kwargs):
|
||||
if self.buffer.list.get_count() == 0: return
|
||||
title = _(u"Tweet")
|
||||
caption = _(u"Write the tweet here")
|
||||
tweet = messages.tweet(self.session, title, caption, self.get_message()+ " ", twishort_enabled=self.session.settings["mysc"]["twishort_enabled"])
|
||||
tweet.message.set_cursor_at_end()
|
||||
if tweet.message.get_response() == widgetUtils.OK:
|
||||
self.session.settings["mysc"]["twishort_enabled"] = tweet.message.long_tweet.GetValue()
|
||||
text = tweet.message.get_text()
|
||||
if len(text) > 140 and tweet.message.get("long_tweet") == True:
|
||||
if tweet.image == None:
|
||||
text = twishort.create_tweet(self.session.settings["twitter"]["user_key"], self.session.settings["twitter"]["user_secret"], text)
|
||||
else:
|
||||
text = twishort.create_tweet(self.session.settings["twitter"]["user_key"], self.session.settings["twitter"]["user_secret"], text, 1)
|
||||
if tweet.image == None:
|
||||
call_threaded(self.session.api_call, call_name="update_status", status=text)
|
||||
else:
|
||||
call_threaded(self.session.api_call, call_name="update_status_with_media", status=text, media=tweet.image)
|
||||
if hasattr(tweet.message, "destroy"): tweet.message.destroy()
|
||||
|
||||
def show_menu_by_key(self, ev):
|
||||
if self.buffer.list.get_count() == 0:
|
||||
return
|
||||
if ev.GetKeyCode() == wx.WXK_WINDOWS_MENU:
|
||||
self.show_menu(widgetUtils.MENU, pos=self.buffer.list.list.GetPosition())
|
||||
|
||||
class conversationBufferController(searchBufferController):
|
||||
|
||||
|
@@ -15,12 +15,22 @@ class listsController(object):
|
||||
self.dialog.populate_list(self.get_all_lists())
|
||||
widgetUtils.connect_event(self.dialog.createBtn, widgetUtils.BUTTON_PRESSED, self.create_list)
|
||||
widgetUtils.connect_event(self.dialog.editBtn, widgetUtils.BUTTON_PRESSED, self.edit_list)
|
||||
widgetUtils.connect_event(self.dialog.deleteBtn, widgetUtils.BUTTON_PRESSED, self.remove_list)
|
||||
widgetUtils.connect_event(self.dialog.view, widgetUtils.BUTTON_PRESSED, self.open_list_as_buffer)
|
||||
else:
|
||||
self.dialog = lists.userListViewer(user)
|
||||
self.dialog.populate_list(self.get_user_lists(user))
|
||||
widgetUtils.connect_event(self.dialog.createBtn, widgetUtils.BUTTON_PRESSED, self.subscribe)
|
||||
widgetUtils.connect_event(self.dialog.deleteBtn, widgetUtils.BUTTON_PRESSED, self.unsubscribe)
|
||||
self.dialog.get_response()
|
||||
|
||||
def get_all_lists(self):
|
||||
return [compose.compose_list(item) for item in self.session.db["lists"]]
|
||||
|
||||
def get_user_lists(self, user):
|
||||
self.lists = self.session.twitter.twitter.show_lists(reverse=True, screen_name=user)
|
||||
return [compose.compose_list(item) for item in self.lists]
|
||||
|
||||
def create_list(self, *args, **kwargs):
|
||||
dialog = lists.createListDialog()
|
||||
if dialog.get_response() == widgetUtils.OK:
|
||||
@@ -74,3 +84,22 @@ class listsController(object):
|
||||
if self.dialog.lista.get_count() == 0: return
|
||||
list = self.session.db["lists"][self.dialog.get_item()]
|
||||
pub.sendMessage("create-new-buffer", buffer="list", account=self.session.db["user_name"], create=list["name"])
|
||||
|
||||
def subscribe(self, *args, **kwargs):
|
||||
if self.dialog.lista.get_count() == 0: return
|
||||
list_id = self.lists[self.dialog.get_item()]["id"]
|
||||
try:
|
||||
list = self.session.twitter.twitter.subscribe_to_list(list_id=list_id)
|
||||
item = utils.find_item(list["id"], self.session.db["lists"])
|
||||
self.session.db.settings["lists"].append(list)
|
||||
except TwythonError as e:
|
||||
output.speak("error %s: %s" % (e.status_code, e.msg))
|
||||
|
||||
def unsubscribe(self, *args, **kwargs):
|
||||
if self.dialog.lista.get_count() == 0: return
|
||||
list_id = self.lists[self.dialog.get_item()]["id"]
|
||||
try:
|
||||
list = self.session.twitter.twitter.unsubscribe_from_list(list_id=list_id)
|
||||
self.session.db.settings["lists"].remove(list)
|
||||
except TwythonError as e:
|
||||
output.speak("error %s: %s" % (e.status_code, e.msg))
|
||||
|
@@ -97,7 +97,7 @@ class Controller(object):
|
||||
def get_buffers_for_account(self, account):
|
||||
results = []
|
||||
buffers = self.view.get_buffers()
|
||||
[results.append(self.search_buffer(i.name, i.account)) for i in buffers if i.account == account]
|
||||
[results.append(self.search_buffer(i.name, i.account)) for i in buffers if i.account == account and (i.type != "account")]
|
||||
return results
|
||||
|
||||
def bind_stream_events(self):
|
||||
@@ -125,10 +125,11 @@ class Controller(object):
|
||||
log.debug("Binding other application events...")
|
||||
pub.subscribe(self.logout_account, "logout")
|
||||
pub.subscribe(self.login_account, "login")
|
||||
pub.subscribe(self.manage_stream_errors, "stream-error")
|
||||
pub.subscribe(self.manage_stream_errors, "streamError")
|
||||
pub.subscribe(self.create_new_buffer, "create-new-buffer")
|
||||
pub.subscribe(self.restart_streams, "restart-streams")
|
||||
|
||||
pub.subscribe(self.execute_action, "execute-action")
|
||||
pub.subscribe(self.search_topic, "search")
|
||||
if system == "Windows":
|
||||
pub.subscribe(self.invisible_shorcuts_changed, "invisible-shorcuts-changed")
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.show_hide, menuitem=self.view.show_hide)
|
||||
@@ -156,6 +157,7 @@ class Controller(object):
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.delete, self.view.delete)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.follow, menuitem=self.view.follow)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.send_dm, self.view.dm)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.view_user_lists, menuitem=self.view.viewLists)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.get_more_items, menuitem=self.view.load_previous_items)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.clear_buffer, menuitem=self.view.clear)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.remove_buffer, self.view.deleteTl)
|
||||
@@ -174,6 +176,8 @@ class Controller(object):
|
||||
widgetUtils.connect_event(self.view.nb, widgetUtils.NOTEBOOK_PAGE_CHANGED, self.buffer_changed)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.report_error, self.view.reportError)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.view_documentation, self.view.doc)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.add_to_list, self.view.addToList)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.remove_from_list, self.view.removeFromList)
|
||||
|
||||
def set_systray_icon(self):
|
||||
self.systrayIcon = sysTrayIcon.SysTrayIcon()
|
||||
@@ -235,7 +239,6 @@ class Controller(object):
|
||||
self.create_ignored_session_buffer(session_.sessions[i])
|
||||
continue
|
||||
self.create_buffers(session_.sessions[i])
|
||||
self.set_buffer_positions(session_.sessions[i])
|
||||
|
||||
# Connection checker executed each minute.
|
||||
self.checker_function = RepeatingTimer(60, self.check_connection)
|
||||
@@ -246,6 +249,7 @@ class Controller(object):
|
||||
for i in session_.sessions:
|
||||
if session_.sessions[i].is_logged == False: continue
|
||||
self.start_buffers(session_.sessions[i])
|
||||
self.set_buffer_positions(session_.sessions[i])
|
||||
if config.app["app-settings"]["play_ready_sound"] == True:
|
||||
session_.sessions[session_.sessions.keys()[0]].sound.play("ready.ogg")
|
||||
if config.app["app-settings"]["speak_ready_msg"] == True:
|
||||
@@ -263,6 +267,7 @@ class Controller(object):
|
||||
for i in session_.sessions:
|
||||
if session_.sessions[i].session_id == session_id: session = session_.sessions[i]
|
||||
session.login()
|
||||
session.db = dict()
|
||||
self.create_buffers(session, False)
|
||||
self.start_buffers(session)
|
||||
|
||||
@@ -286,11 +291,11 @@ class Controller(object):
|
||||
self.buffers.append(mentions)
|
||||
self.view.insert_buffer(mentions.buffer, name=_(u"Mentions"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||
elif i == 'dm':
|
||||
dm = buffersController.baseBufferController(self.view.nb, "get_direct_messages", "direct_messages", session, session.db["user_name"], bufferType="dmPanel", sound="dm_received.ogg")
|
||||
dm = buffersController.baseBufferController(self.view.nb, "get_direct_messages", "direct_messages", session, session.db["user_name"], bufferType="dmPanel", sound="dm_received.ogg", full_text=True)
|
||||
self.buffers.append(dm)
|
||||
self.view.insert_buffer(dm.buffer, name=_(u"Direct messages"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||
elif i == 'sent_dm':
|
||||
sent_dm = buffersController.baseBufferController(self.view.nb, "get_sent_messages", "sent_direct_messages", session, session.db["user_name"], bufferType="dmPanel")
|
||||
sent_dm = buffersController.baseBufferController(self.view.nb, "get_sent_messages", "sent_direct_messages", session, session.db["user_name"], bufferType="dmPanel", full_text=True)
|
||||
self.buffers.append(sent_dm)
|
||||
self.view.insert_buffer(sent_dm.buffer, name=_(u"Sent direct messages"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||
elif i == 'sent_tweets':
|
||||
@@ -360,40 +365,27 @@ class Controller(object):
|
||||
buffer.start_stream()
|
||||
buffer.searchfunction = self.search
|
||||
self.buffers.append(buffer)
|
||||
self.view.insert_buffer(buffer.buffer, name=_(u"Trending topics for %s") % (buffer.name_), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||
buffer.timer = RepeatingTimer(300, buffer.start_stream)
|
||||
buffer.timer.start()
|
||||
self.view.insert_buffer(buffer.buffer, name=_(u"Trending topics for %s") % (buffer.name_), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||
|
||||
def set_buffer_positions(self,session):
|
||||
"Sets positions for buffers if values exist in the database."
|
||||
for i in self.buffers:
|
||||
if i.name+"_pos" in session.db and hasattr(i.buffer,'list'):
|
||||
if i.account == session.db["user_name"] and session.db.has_key(i.name+"_pos") and hasattr(i.buffer,'list'):
|
||||
i.buffer.list.select_item(session.db[str(i.name+"_pos")])
|
||||
|
||||
def logout_account(self, session_id):
|
||||
for i in session_.sessions:
|
||||
if session_.sessions[i].session_id == session_id: session = session_.sessions[i]
|
||||
user = session.db["user_name"]
|
||||
self.destroy_buffer("home_timeline", user)
|
||||
self.destroy_buffer("mentions", user)
|
||||
self.destroy_buffer("direct_messages", user)
|
||||
self.destroy_buffer("sent_direct_messages", user)
|
||||
self.destroy_buffer("sent_tweets", user)
|
||||
self.destroy_buffer("favourites", user)
|
||||
self.destroy_buffer("followers", user)
|
||||
self.destroy_buffer("friends", user)
|
||||
self.destroy_buffer("blocked", user)
|
||||
self.destroy_buffer("muted", user)
|
||||
self.destroy_buffer("events", user)
|
||||
self.destroy_buffer("timelines", user)
|
||||
for i in session.settings["other_buffers"]["timelines"]:
|
||||
self.destroy_buffer("%s-timeline" % (i,), user)
|
||||
self.destroy_buffer("favs_timelines", user)
|
||||
self.destroy_buffer("searches", user)
|
||||
for i in session.settings["other_buffers"]["tweet_searches"]:
|
||||
self.destroy_buffer("%s-searchterm" % (i,), user)
|
||||
for i in session.settings["other_buffers"]["trending_topic_buffers"]:
|
||||
self.destroy_buffer("%s_tt" % (i,), user)
|
||||
delete_buffers = []
|
||||
for i in self.buffers:
|
||||
if i.account == user and i.name != user:
|
||||
delete_buffers.append(i.name)
|
||||
for i in delete_buffers:
|
||||
self.destroy_buffer(i, user)
|
||||
session.db = None
|
||||
|
||||
def destroy_buffer(self, buffer_name, account):
|
||||
buffer = self.search_buffer(buffer_name, account)
|
||||
@@ -404,7 +396,11 @@ class Controller(object):
|
||||
self.buffers.remove(buffer)
|
||||
del buffer
|
||||
|
||||
def search(self, value="", *args, **kwargs):
|
||||
def search_topic(self, term):
|
||||
self.search(value=term)
|
||||
|
||||
|
||||
def search(self, event=None, value="", *args, **kwargs):
|
||||
""" Searches words or users in twitter. This creates a new buffer containing the search results."""
|
||||
log.debug("Creating a new search...")
|
||||
dlg = dialogs.search.searchDialog(value)
|
||||
@@ -478,8 +474,20 @@ class Controller(object):
|
||||
buffer = self.get_best_buffer()
|
||||
SoundsTutorial.soundsTutorial(buffer.session)
|
||||
|
||||
def view_user_lists(self, users):
|
||||
pass
|
||||
def view_user_lists(self, *args, **kwargs):
|
||||
buff = self.get_best_buffer()
|
||||
if not hasattr(buff, "get_right_tweet"): return
|
||||
tweet = buff.get_right_tweet()
|
||||
if buff.type != "people":
|
||||
users = utils.get_all_users(tweet, buff.session.db)
|
||||
else:
|
||||
users = [tweet["screen_name"]]
|
||||
dlg = dialogs.utils.selectUserDialog(_(u"Select the user"), users)
|
||||
if dlg.get_response() == widgetUtils.OK:
|
||||
user = dlg.get_user()
|
||||
else:
|
||||
return
|
||||
l = listsController.listsController(buff.session, user=user)
|
||||
|
||||
def add_to_list(self, *args, **kwargs):
|
||||
buff = self.get_best_buffer()
|
||||
@@ -508,8 +516,32 @@ class Controller(object):
|
||||
except TwythonError as e:
|
||||
output.speak("error %s: %s" % (e.error_code, e.msg))
|
||||
|
||||
def remove_from_list(self, user):
|
||||
pass
|
||||
def remove_from_list(self, *args, **kwargs):
|
||||
buff = self.get_best_buffer()
|
||||
if not hasattr(buff, "get_right_tweet"): return
|
||||
tweet = buff.get_right_tweet()
|
||||
if buff.type != "people":
|
||||
users = utils.get_all_users(tweet, buff.session.db)
|
||||
else:
|
||||
users = [tweet["screen_name"]]
|
||||
dlg = dialogs.utils.selectUserDialog(_(u"Select the user"), users)
|
||||
if dlg.get_response() == widgetUtils.OK:
|
||||
user = dlg.get_user()
|
||||
else:
|
||||
return
|
||||
dlg = dialogs.lists.removeUserListDialog()
|
||||
dlg.populate_list([compose.compose_list(item) for item in buff.session.db["lists"]])
|
||||
if dlg.get_response() == widgetUtils.OK:
|
||||
try:
|
||||
list = buff.session.twitter.twitter.delete_list_member(list_id=buff.session.db["lists"][dlg.get_item()]["id"], screen_name=user)
|
||||
older_list = utils.find_item(buff.session.db["lists"][dlg.get_item()]["id"], buff.session.db["lists"])
|
||||
listBuffer = self.search_buffer("%s-list" % (buff.session.db["lists"][dlg.get_item()]["name"].lower()), buff.session.db["user_name"])
|
||||
if listBuffer != None: listBuffer.get_user_ids()
|
||||
buff.session.db["lists"].pop(older_list)
|
||||
buff.session.db["lists"].append(list)
|
||||
if listBuffer != None: pub.sendMessage("restart-streams", streams=["timelinesStream"], session=buff.session)
|
||||
except TwythonError as e:
|
||||
output.speak("error %s: %s" % (e.error_code, e.msg))
|
||||
|
||||
def list_manager(self, *args, **kwargs):
|
||||
s = self.get_best_buffer().session
|
||||
@@ -561,6 +593,7 @@ class Controller(object):
|
||||
self.exit_()
|
||||
|
||||
def exit_(self, *args, **kwargs):
|
||||
for i in self.buffers: i.save_positions()
|
||||
log.debug("Exiting...")
|
||||
log.debug("Saving global configuration...")
|
||||
config.app.write()
|
||||
@@ -718,8 +751,7 @@ class Controller(object):
|
||||
users = [tweet["screen_name"]]
|
||||
dlg = dialogs.userSelection.selectUserDialog(users=users, default=default)
|
||||
if dlg.get_response() == widgetUtils.OK:
|
||||
buffer = self.get_best_buffer()
|
||||
usr = utils.if_user_exists(buffer.session.twitter.twitter, dlg.get_user())
|
||||
usr = utils.if_user_exists(buff.session.twitter.twitter, dlg.get_user())
|
||||
if usr != None:
|
||||
if usr["protected"] == True:
|
||||
if usr["following"] == False:
|
||||
@@ -728,32 +760,38 @@ class Controller(object):
|
||||
answer = commonMessageDialogs.protected_user()
|
||||
if answer == widgetUtils.NO: return
|
||||
if dlg.get_action() == "tweets":
|
||||
if dlg.get_user() in buffer.session.settings["other_buffers"]["timelines"]:
|
||||
if usr["statuses_count"] == 0:
|
||||
commonMessageDialogs.no_tweets()
|
||||
return
|
||||
if dlg.get_user() in buff.session.settings["other_buffers"]["timelines"]:
|
||||
commonMessageDialogs.timeline_exist()
|
||||
return
|
||||
tl = buffersController.baseBufferController(self.view.nb, "get_user_timeline", "%s-timeline" % (dlg.get_user(),), buffer.session, buffer.session.db["user_name"], bufferType=None, screen_name=dlg.get_user())
|
||||
tl = buffersController.baseBufferController(self.view.nb, "get_user_timeline", "%s-timeline" % (dlg.get_user(),), buff.session, buff.session.db["user_name"], bufferType=None, screen_name=dlg.get_user())
|
||||
tl.start_stream()
|
||||
pos=self.view.search("timelines", buffer.session.db["user_name"])
|
||||
pos=self.view.search("timelines", buff.session.db["user_name"])
|
||||
self.insert_buffer(tl, pos+1)
|
||||
# self.buffers.insert(pos+1, tl)
|
||||
self.view.insert_buffer(tl.buffer, name=_(u"Timeline for {}").format(dlg.get_user()), pos=pos)
|
||||
buffer.session.settings["other_buffers"]["timelines"].append(dlg.get_user())
|
||||
pub.sendMessage("restart-streams", streams=["timelinesStream"], session=buffer.session)
|
||||
buffer.session.sound.play("create_timeline.ogg")
|
||||
buff.session.settings["other_buffers"]["timelines"].append(dlg.get_user())
|
||||
pub.sendMessage("restart-streams", streams=["timelinesStream"], session=buff.session)
|
||||
buff.session.sound.play("create_timeline.ogg")
|
||||
else:
|
||||
if usr["favourites_count"] == 0:
|
||||
commonMessageDialogs.no_favs()
|
||||
return
|
||||
if dlg.get_user() in buffer.session.settings["other_buffers"]["favourites_timelines"]:
|
||||
commonMessageDialogs.timeline_exist()
|
||||
return
|
||||
tl = buffersController.baseBufferController(self.view.nb, "get_favorites", "%s-favorite" % (dlg.get_user(),), buffer.session, buffer.session.db["user_name"], bufferType=None, screen_name=dlg.get_user())
|
||||
pos=self.view.search("favs_timelines", buffer.session.db["user_name"])
|
||||
tl = buffersController.baseBufferController(self.view.nb, "get_favorites", "%s-favorite" % (dlg.get_user(),), buff.session, buff.session.db["user_name"], bufferType=None, screen_name=dlg.get_user())
|
||||
pos=self.view.search("favs_timelines", buff.session.db["user_name"])
|
||||
self.insert_buffer(tl, pos+1)
|
||||
# self.buffers.insert(pos+1, tl)
|
||||
self.view.insert_buffer(buffer=tl.buffer, name=_(u"Favourites timeline for {}").format(dlg.get_user()), pos=pos)
|
||||
tl.start_stream()
|
||||
tl.timer = RepeatingTimer(300, tl.start_stream)
|
||||
tl.timer.start()
|
||||
buffer.session.settings["other_buffers"]["favourites_timelines"].append(dlg.get_user())
|
||||
buffer.session.sound.play("create_timeline.ogg")
|
||||
buff.session.settings["other_buffers"]["favourites_timelines"].append(dlg.get_user())
|
||||
buff.session.sound.play("create_timeline.ogg")
|
||||
else:
|
||||
commonMessageDialogs.user_not_exist()
|
||||
|
||||
@@ -1202,11 +1240,15 @@ class Controller(object):
|
||||
log.debug("Starting the streaming endpoint")
|
||||
session.start_streaming()
|
||||
|
||||
def set_positions(self):
|
||||
for i in session_.sessions:
|
||||
self.set_buffer_positions(i)
|
||||
|
||||
def manage_stream_errors(self, session):
|
||||
log.error("An error ocurred with the stream for the %s session. It will be destroyed" % (session,))
|
||||
log.debug(" Restarting %s session streams. It will be destroyed" % (session,))
|
||||
s = session_.sessions[session]
|
||||
for i in self.buffers:
|
||||
if i.invisible == True and i.session.session_id == s.session_id:
|
||||
if i.invisible == True and i.session.session_id == s.session_id and i.type != "people":
|
||||
i.start_stream()
|
||||
s.listen_stream_error()
|
||||
|
||||
@@ -1350,5 +1392,9 @@ class Controller(object):
|
||||
def repeat_item(self, *args, **kwargs):
|
||||
output.speak(self.get_current_buffer().get_message())
|
||||
|
||||
def execute_action(self, action):
|
||||
if hasattr(self, action):
|
||||
getattr(self, action)()
|
||||
|
||||
def __del__(self):
|
||||
config.app.write()
|
@@ -25,6 +25,7 @@ class basicTweet(object):
|
||||
widgetUtils.connect_event(self.message.spellcheck, widgetUtils.BUTTON_PRESSED, self.spellcheck)
|
||||
widgetUtils.connect_event(self.message.attach, widgetUtils.BUTTON_PRESSED, self.attach)
|
||||
# if system == "Windows":
|
||||
# if messageType != "dm":
|
||||
widgetUtils.connect_event(self.message.text, widgetUtils.ENTERED_TEXT, self.text_processor)
|
||||
self.text_processor()
|
||||
widgetUtils.connect_event(self.message.shortenButton, widgetUtils.BUTTON_PRESSED, self.shorten)
|
||||
@@ -97,6 +98,7 @@ class basicTweet(object):
|
||||
checker = SpellChecker.spellchecker.spellChecker(text, "")
|
||||
if hasattr(checker, "fixed_text"):
|
||||
self.message.set_text(checker.fixed_text)
|
||||
self.message.text_focus()
|
||||
|
||||
def attach(self, *args, **kwargs):
|
||||
def completed_callback():
|
||||
@@ -109,6 +111,7 @@ class basicTweet(object):
|
||||
output.speak(_(u"Unable to upload the audio"))
|
||||
dlg.cleanup()
|
||||
dlg = audioUploader.audioUploader(self.session.settings, completed_callback)
|
||||
self.message.text_focus()
|
||||
|
||||
class tweet(basicTweet):
|
||||
def __init__(self, session, title, caption, text, twishort_enabled, messageType="tweet", max=140):
|
||||
@@ -130,6 +133,7 @@ class tweet(basicTweet):
|
||||
self.image = self.message.get_image()
|
||||
if self.image != None:
|
||||
self.message.set("upload_image", _(u"Discard image"))
|
||||
self.message.text_focus()
|
||||
|
||||
def autocomplete_users(self, *args, **kwargs):
|
||||
c = autocompletionUsers.completion.autocompletionUsers(self.message, self.session.session_id)
|
||||
@@ -151,7 +155,7 @@ class reply(tweet):
|
||||
|
||||
class dm(basicTweet):
|
||||
def __init__(self, session, title, caption, text):
|
||||
super(dm, self).__init__(session, title, caption, text, messageType="dm")
|
||||
super(dm, self).__init__(session, title, caption, text, messageType="dm", max=10000)
|
||||
widgetUtils.connect_event(self.message.autocompletionButton, widgetUtils.BUTTON_PRESSED, self.autocomplete_users)
|
||||
|
||||
def autocomplete_users(self, *args, **kwargs):
|
||||
|
@@ -74,10 +74,10 @@ class audioUploader(object):
|
||||
def on_pause(self, *args, **kwargs):
|
||||
if self.dialog.get("pause") == _(u"Pause"):
|
||||
self.recording.pause()
|
||||
self.dialog.set("pause", _(u"Resume"))
|
||||
self.dialog.set("pause", _(u"&Resume"))
|
||||
elif self.dialog.get("pause") == _(u"Resume"):
|
||||
self.recording.play()
|
||||
self.dialog.set("pause", _(U"Pause"))
|
||||
self.dialog.set("pause", _(U"&Pause"))
|
||||
|
||||
def on_record(self, *args, **kwargs):
|
||||
if self.recording != None:
|
||||
@@ -92,7 +92,7 @@ class audioUploader(object):
|
||||
self.file = tempfile.mktemp(suffix='.wav')
|
||||
self.recording = sound.recording(self.file)
|
||||
self.recording.play()
|
||||
self.dialog.set("record", _(u"Stop"))
|
||||
self.dialog.set("record", _(u"&Stop"))
|
||||
output.speak(_(u"Recording"))
|
||||
|
||||
def stop_recording(self):
|
||||
@@ -100,11 +100,11 @@ class audioUploader(object):
|
||||
self.recording.free()
|
||||
output.speak(_(u"Stopped"))
|
||||
self.recorded = True
|
||||
self.dialog.set("record", _(u"Record"))
|
||||
self.dialog.set("record", _(u"&Record"))
|
||||
self.file_attached()
|
||||
|
||||
def file_attached(self):
|
||||
self.dialog.set("pause", _(u"Pause"))
|
||||
self.dialog.set("pause", _(u"&Pause"))
|
||||
self.dialog.disable_control("record")
|
||||
self.dialog.enable_control("play")
|
||||
self.dialog.enable_control("discard")
|
||||
@@ -137,11 +137,11 @@ class audioUploader(object):
|
||||
# try:
|
||||
self.playing = sound_lib.stream.FileStream(file=unicode(self.file), flags=sound_lib.stream.BASS_UNICODE)
|
||||
self.playing.play()
|
||||
self.dialog.set("play", _(u"Stop"))
|
||||
self.dialog.set("play", _(u"&Stop"))
|
||||
try:
|
||||
while self.playing.is_playing:
|
||||
pass
|
||||
self.dialog.set("play", _(u"Play"))
|
||||
self.dialog.set("play", _(u"&Play"))
|
||||
self.playing.free()
|
||||
self.playing = None
|
||||
except:
|
||||
@@ -151,7 +151,7 @@ class audioUploader(object):
|
||||
output.speak(_(u"Stopped"))
|
||||
self.playing.stop()
|
||||
self.playing.free()
|
||||
self.dialog.set("play", _(u"Play"))
|
||||
self.dialog.set("play", _(u"&Play"))
|
||||
self.playing = None
|
||||
|
||||
def postprocess(self):
|
||||
|
@@ -31,14 +31,14 @@ class audioDialog(widgetUtils.BaseDialog):
|
||||
btnSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
btnSizer2 = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
self.play = wx.Button(panel, -1, _(u"Play"))
|
||||
self.play = wx.Button(panel, -1, _(u"&Play"))
|
||||
self.play.Disable()
|
||||
self.pause = wx.Button(panel, -1, _(u"Pause"))
|
||||
self.pause = wx.Button(panel, -1, _(u"&Pause"))
|
||||
self.pause.Disable()
|
||||
self.record = wx.Button(panel, -1, _(u"Record"))
|
||||
self.record = wx.Button(panel, -1, _(u"&Record"))
|
||||
self.record.SetFocus()
|
||||
self.attach_exists = wx.Button(panel, -1, _(u"Add an existing file"))
|
||||
self.discard = wx.Button(panel, -1, _(u"Discard"))
|
||||
self.attach_exists = wx.Button(panel, -1, _(u"&Add an existing file"))
|
||||
self.discard = wx.Button(panel, -1, _(u"&Discard"))
|
||||
self.discard.Disable()
|
||||
label = wx.StaticText(panel, -1, _(u"Upload to"))
|
||||
self.services = wx.ComboBox(panel, -1, choices=services, value=services[0], style=wx.CB_READONLY)
|
||||
@@ -47,7 +47,7 @@ class audioDialog(widgetUtils.BaseDialog):
|
||||
servicesBox.Add(self.services, 0, wx.ALL, 5)
|
||||
self.attach = wx.Button(panel, wx.ID_OK, _(u"Attach"))
|
||||
self.attach.Disable()
|
||||
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"Cancel"))
|
||||
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"&Cancel"))
|
||||
btnSizer.Add(self.play, 0, wx.ALL, 5)
|
||||
btnSizer.Add(self.pause, 0, wx.ALL, 5)
|
||||
btnSizer.Add(self.record, 0, wx.ALL, 5)
|
||||
|
@@ -11,9 +11,17 @@ def fix():
|
||||
locales.BasqueLocale = BasqueLocale
|
||||
locales.TurkishLocale.names[-1] = "tr_tr"
|
||||
locales.ArabicLocale.names[-1] = "ar_eg"
|
||||
# insert a modified function so if there is no language available in arrow, returns English locale.
|
||||
locales.get_locale = get_locale
|
||||
# We need to reassign the locales list for updating the list with our new contents.
|
||||
locales._locales = locales._map_locales()
|
||||
|
||||
def get_locale(name):
|
||||
locale_cls = locales._locales.get(name.lower())
|
||||
if locale_cls is None:
|
||||
return locales.EnglishLocale()
|
||||
return locale_cls()
|
||||
|
||||
class CatalaLocale(Locale):
|
||||
names = ['ca', 'ca_ca']
|
||||
past = 'Fa {0}'
|
||||
|
@@ -1,6 +1,5 @@
|
||||
import win32com.client
|
||||
|
||||
|
||||
def fix():
|
||||
if win32com.client.gencache.is_readonly == True:
|
||||
win32com.client.gencache.is_readonly = False
|
||||
|
@@ -3,6 +3,7 @@ import widgetUtils
|
||||
import config
|
||||
import wx_ui
|
||||
import constants
|
||||
from pubsub import pub
|
||||
|
||||
class KeystrokeEditor(object):
|
||||
def __init__(self):
|
||||
@@ -14,6 +15,7 @@ class KeystrokeEditor(object):
|
||||
self.hold_map = self.map.copy()
|
||||
self.dialog.put_keystrokes(constants.actions, self.map)
|
||||
widgetUtils.connect_event(self.dialog.edit, widgetUtils.BUTTON_PRESSED, self.edit_keystroke)
|
||||
widgetUtils.connect_event(self.dialog.execute, widgetUtils.BUTTON_PRESSED, self.execute_action)
|
||||
self.dialog.get_response()
|
||||
|
||||
def edit_keystroke(self, *args, **kwargs):
|
||||
@@ -52,3 +54,7 @@ class KeystrokeEditor(object):
|
||||
wx_ui.no_key()
|
||||
return
|
||||
return "+".join(keys)
|
||||
|
||||
def execute_action(self, *args, **kwargs):
|
||||
action = self.dialog.actions[self.dialog.get_action()]
|
||||
pub.sendMessage("execute-action", action=action)
|
@@ -13,18 +13,20 @@ class keystrokeEditorDialog(baseDialog.BaseWXDialog):
|
||||
self.keys = widgets.list(self, _(u"Action"), _(u"Keystroke"), style=wx.LC_REPORT|wx.LC_SINGLE_SEL, size=(400, 450))
|
||||
self.keys.list.SetFocus()
|
||||
firstSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
firstSizer.Add(keysText)
|
||||
firstSizer.Add(self.keys.list)
|
||||
firstSizer.Add(keysText, 0, wx.ALL, 5)
|
||||
firstSizer.Add(self.keys.list, 0, wx.ALL, 5)
|
||||
self.edit = wx.Button(panel, -1, _(u"Edit"))
|
||||
self.edit.SetDefault()
|
||||
|
||||
self.execute = wx.Button(panel, -1, _(u"Execute action"))
|
||||
close = wx.Button(panel, wx.ID_CANCEL, _(u"Close"))
|
||||
secondSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
secondSizer.Add(self.edit)
|
||||
secondSizer.Add(close)
|
||||
sizer.Add(firstSizer)
|
||||
sizer.Add(secondSizer)
|
||||
panel.SetSizerAndFit(sizer)
|
||||
secondSizer.Add(self.edit, 0, wx.ALL, 5)
|
||||
secondSizer.Add(self.execute, 0, wx.ALL, 5)
|
||||
secondSizer.Add(close, 0, wx.ALL, 5)
|
||||
sizer.Add(firstSizer, 0, wx.ALL, 5)
|
||||
sizer.Add(secondSizer, 0, wx.ALL, 5)
|
||||
panel.SetSizer(sizer)
|
||||
self.SetClientSize(sizer.CalcMin())
|
||||
|
||||
def put_keystrokes(self, actions, keystrokes):
|
||||
for i in keystrokes:
|
||||
|
@@ -69,6 +69,7 @@ def getLanguageDescription(language):
|
||||
"ar":pgettext("languageName","Arabic"),
|
||||
"ne":pgettext("languageName","Nepali"),
|
||||
"sr":pgettext("languageName","Serbian (Latin)"),
|
||||
"ja":pgettext("languageName","Japanese"),
|
||||
}.get(language,None)
|
||||
return desc
|
||||
|
||||
@@ -195,10 +196,13 @@ def langToWindowsLocale(lang):
|
||||
"gl": "glc",
|
||||
"eu": "euq",
|
||||
"hu": "hun",
|
||||
"hr": "hrv",
|
||||
"it": "ita",
|
||||
"ja": "jpn",
|
||||
"pl": "plk",
|
||||
"pt": "ptb",
|
||||
"ru": "rus",
|
||||
"tr": "trk"
|
||||
"tr": "trk",
|
||||
"sr": "eng",
|
||||
}
|
||||
return languages[lang]
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
src/locales/EU/LC_MESSAGES/twblue_old.mo
Normal file
BIN
src/locales/EU/LC_MESSAGES/twblue_old.mo
Normal file
Binary file not shown.
2896
src/locales/EU/LC_MESSAGES/twblue_old.po
Normal file
2896
src/locales/EU/LC_MESSAGES/twblue_old.po
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
src/locales/de/LC_MESSAGES/twblue_old.mo
Normal file
BIN
src/locales/de/LC_MESSAGES/twblue_old.mo
Normal file
Binary file not shown.
2854
src/locales/de/LC_MESSAGES/twblue_old.po
Normal file
2854
src/locales/de/LC_MESSAGES/twblue_old.po
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
2871
src/locales/fi/LC_MESSAGES/twblue_old.po
Normal file
2871
src/locales/fi/LC_MESSAGES/twblue_old.po
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
src/locales/ja/lc_messages/twblue.mo
Normal file
BIN
src/locales/ja/lc_messages/twblue.mo
Normal file
Binary file not shown.
2794
src/locales/ja/lc_messages/twblue.po
Normal file
2794
src/locales/ja/lc_messages/twblue.po
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
BIN
src/locales/sr/LC_MESSAGES/twblue.mo
Normal file
BIN
src/locales/sr/LC_MESSAGES/twblue.mo
Normal file
Binary file not shown.
2794
src/locales/sr/LC_MESSAGES/twblue.po
Normal file
2794
src/locales/sr/LC_MESSAGES/twblue.po
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
2882
src/locales/tr/LC_MESSAGES/twblue_old.po
Normal file
2882
src/locales/tr/LC_MESSAGES/twblue_old.po
Normal file
File diff suppressed because it is too large
Load Diff
@@ -16,6 +16,7 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
############################################################
|
||||
from twitter import utils
|
||||
|
||||
def get_id(url):
|
||||
return url.split("/")[-1]
|
||||
@@ -26,3 +27,8 @@ def is_long(tweet):
|
||||
if "twitter.com" in tweet["entities"]["urls"][url]["expanded_url"]:
|
||||
long = get_id(tweet["entities"]["urls"][url]["expanded_url"])
|
||||
return long
|
||||
|
||||
def clear_url(tweet):
|
||||
urls = utils.find_urls_in_text(tweet["text"])
|
||||
tweet["message"] = tweet["message"].replace(urls[-1]+".", "")
|
||||
return tweet
|
@@ -9,7 +9,7 @@ import output
|
||||
import time
|
||||
import sound
|
||||
import logging
|
||||
from twitter import utils
|
||||
from twitter import utils, compose
|
||||
from twython import TwythonError, TwythonRateLimitError, TwythonAuthError
|
||||
import config_utils
|
||||
import shelve
|
||||
@@ -18,6 +18,7 @@ import os
|
||||
from mysc.thread_utils import stream_threaded
|
||||
from pubsub import pub
|
||||
log = logging.getLogger("sessionmanager.session")
|
||||
from long_tweets import tweets
|
||||
|
||||
sessions = {}
|
||||
|
||||
@@ -61,6 +62,7 @@ class Session(object):
|
||||
self.db[name] = []
|
||||
for i in data:
|
||||
if utils.find_item(i["id"], self.db[name]) == None and utils.is_allowed(i, self.settings["twitter"]["ignored_clients"]) == True:
|
||||
i = self.check_quoted_status(i)
|
||||
if self.settings["general"]["reverse_timelines"] == False: self.db[name].append(i)
|
||||
else: self.db[name].insert(0, i)
|
||||
num = num+1
|
||||
@@ -119,7 +121,8 @@ class Session(object):
|
||||
# self.settings = None
|
||||
|
||||
def init_sound(self):
|
||||
self.sound = sound.soundSystem(self.settings["sound"])
|
||||
try: self.sound = sound.soundSystem(self.settings["sound"])
|
||||
except: pass
|
||||
|
||||
@_require_configuration
|
||||
def login(self, verify_credentials=True):
|
||||
@@ -344,6 +347,7 @@ class Session(object):
|
||||
self.logged = False
|
||||
self.twitter = twitter.twitter.twitter()
|
||||
self.login(False)
|
||||
pub.sendMessage("streamError", session=self.session_id)
|
||||
if self.reconnection_function_active == True: return
|
||||
self.reconnection_function_active = True
|
||||
if not hasattr(self, "main_stream"):
|
||||
@@ -411,3 +415,27 @@ class Session(object):
|
||||
os.remove(shelfname)
|
||||
except:
|
||||
pass
|
||||
|
||||
def check_quoted_status(self, tweet):
|
||||
status = tweets.is_long(tweet)
|
||||
if status != False:
|
||||
tweet["quoted"] = 1
|
||||
tweet = self.get_quoted_tweet(tweet)
|
||||
return tweet
|
||||
|
||||
|
||||
def get_quoted_tweet(self, tweet):
|
||||
quoted_tweet = self.twitter.twitter.show_status(id=tweet["id"])
|
||||
urls = utils.find_urls_in_text(quoted_tweet["text"])
|
||||
for url in range(0, len(urls)):
|
||||
try: quoted_tweet["text"] = quoted_tweet["text"].replace(urls[url], quoted_tweet["entities"]["urls"][url]["expanded_url"])
|
||||
except IndexError: pass
|
||||
l = tweets.is_long(quoted_tweet)
|
||||
id = tweets.get_id(l)
|
||||
original_tweet = self.twitter.twitter.show_status(id=id)
|
||||
urls = utils.find_urls_in_text(original_tweet["text"])
|
||||
for url in range(0, len(urls)):
|
||||
try: original_tweet["text"] = original_tweet["text"].replace(urls[url], original_tweet["entities"]["urls"][url]["expanded_url"])
|
||||
except IndexError: pass
|
||||
return compose.compose_quoted_tweet(quoted_tweet, original_tweet)
|
||||
|
||||
|
@@ -30,6 +30,10 @@ class timelinesStreamer(TwythonStreamer):
|
||||
def check_tls(self, data):
|
||||
for i in self.session.settings["other_buffers"]["timelines"]:
|
||||
if data["user"]["screen_name"] == i:
|
||||
if utils.find_item(data["id"], self.session.db["%s-timeline" % (i,)]) != None:
|
||||
log.error("duplicated tweet. Ignoring it...")
|
||||
return
|
||||
data = self.session.check_quoted_status(data)
|
||||
if self.session.settings["general"]["reverse_timelines"] == False: self.session.db["%s-timeline" % (i,)].append(data)
|
||||
else: self.session.db["%s-timeline" % (i,)].insert(0, data)
|
||||
pub.sendMessage("item-in-timeline", data= data, user= self.session.db["user_name"], who= i)
|
||||
@@ -38,6 +42,7 @@ class timelinesStreamer(TwythonStreamer):
|
||||
i.users.index(data["user"]["id"])
|
||||
usr = data["in_reply_to_user_id"]
|
||||
if (usr != None and usr in self.friends) or data.has_key("retweeted_status"):
|
||||
data = self.session.check_quoted_status(data)
|
||||
if self.session.settings["general"]["reverse_timelines"] == False: self.session.db["%s" % (i.name,)].append(data)
|
||||
else: self.session.db["%s" % (i,)].insert(0, data)
|
||||
pub.sendMessage("item-in-list", data= data, user= self.session.db["user_name"], where= i.name)
|
||||
|
@@ -33,6 +33,10 @@ class streamer(TwythonStreamer):
|
||||
|
||||
def put_data(self, place, data):
|
||||
if self.session.db.has_key(place):
|
||||
if utils.find_item(data["id"], self.session.db[place]) != None:
|
||||
log.error("duplicated tweet. Ignoring it...")
|
||||
return
|
||||
data = self.session.check_quoted_status(data)
|
||||
if self.session.settings["general"]["reverse_timelines"] == False:
|
||||
self.session.db[place].append(data)
|
||||
else:
|
||||
|
@@ -10,7 +10,7 @@ import languageHandler
|
||||
import arrow
|
||||
import logging
|
||||
import config
|
||||
from long_tweets import twishort
|
||||
from long_tweets import twishort, tweets
|
||||
log = logging.getLogger("compose")
|
||||
|
||||
def StripChars(s):
|
||||
@@ -60,11 +60,33 @@ def compose_tweet(tweet, db, relative_times):
|
||||
try:
|
||||
oldtext=text
|
||||
text=twishort.get_full_text(tweet['long_uri'])
|
||||
try: text = "rt @%s: %s" % (tweet["retweeted_status"]["user"]["screen_name"], StripChars(text))
|
||||
except KeyError: pass
|
||||
except:
|
||||
text=oldtext
|
||||
if tweet.has_key("message"):
|
||||
text = tweet["message"]
|
||||
return [user+", ", text, ts+", ", source]
|
||||
|
||||
tweet["text"] = text
|
||||
return [user+", ", tweet["text"], ts+", ", source]
|
||||
|
||||
def compose_quoted_tweet(quoted_tweet, original_tweet):
|
||||
""" It receives a tweet and returns a list with the user, text for the tweet or message, date and the client where user is."""
|
||||
text = StripChars(quoted_tweet["text"])
|
||||
quoting_user = quoted_tweet["user"]["name"]
|
||||
source = re.sub(r"(?s)<.*?>", "", quoted_tweet["source"])
|
||||
try: text = "rt @%s: %s" % (quoted_tweet["retweeted_status"]["user"]["screen_name"], StripChars(quoted_tweet["retweeted_status"]["text"]))
|
||||
except KeyError: text = "%s" % (StripChars(quoted_tweet["text"]))
|
||||
if text[-1] in chars: text=text+"."
|
||||
original_user = original_tweet["user"]["screen_name"]
|
||||
original_text = StripChars(original_tweet["text"])
|
||||
try: original_text = "rt @%s: %s" % (original_tweet["retweeted_status"]["user"]["screen_name"], StripChars(original_tweet["retweeted_status"]["text"]))
|
||||
except KeyError: original_text = "%s" % (StripChars(original_tweet["text"]))
|
||||
quoted_tweet["message"] = _(u"{0}. Quoted tweet from @{1}: {2}").format( quoted_tweet["text"], original_user, original_text)
|
||||
quoted_tweet = tweets.clear_url(quoted_tweet)
|
||||
return quoted_tweet
|
||||
|
||||
def compose_followers_list(tweet, db, relative_times=True):
|
||||
if system == "Windows":
|
||||
original_date = arrow.get(tweet["created_at"], "ddd MMM D H:m:s Z YYYY", locale="en")
|
||||
|
@@ -1,4 +1,7 @@
|
||||
import wx
|
||||
import paths
|
||||
import languageHandler
|
||||
import sys
|
||||
|
||||
toolkit = "wx"
|
||||
|
||||
@@ -108,6 +111,15 @@ class mainLoopObject(wx.App):
|
||||
|
||||
def __init__(self):
|
||||
self.app = wx.App()
|
||||
self.lc = wx.Locale()
|
||||
lang=languageHandler.getLanguage()
|
||||
wxLang=self.lc.FindLanguageInfo(lang)
|
||||
if not wxLang and '_' in lang:
|
||||
wxLang=self.lc.FindLanguageInfo(lang.split('_')[0])
|
||||
if hasattr(sys,'frozen'):
|
||||
self.lc.AddCatalogLookupPathPrefix(paths.app_path("locales"))
|
||||
if wxLang:
|
||||
self.lc.Init(wxLang.Language)
|
||||
|
||||
def run(self):
|
||||
self.app.MainLoop()
|
||||
|
@@ -16,9 +16,11 @@ class trendsPanel(wx.Panel):
|
||||
self.create_list()
|
||||
self.tweet = wx.Button(self, -1, _(u"Tweet"))
|
||||
self.tweetTrendBtn = wx.Button(self, -1, _(u"Tweet about this trend"))
|
||||
self.search_topic = wx.Button(self, -1, _(u"Search topic"))
|
||||
btnSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
btnSizer.Add(self.tweet, 0, wx.ALL, 5)
|
||||
btnSizer.Add(self.tweetTrendBtn, 0, wx.ALL, 5)
|
||||
btnSizer.Add(self.search_topic, 0, wx.ALL, 5)
|
||||
self.sizer.Add(btnSizer, 0, wx.ALL, 5)
|
||||
self.sizer.Add(self.list.list, 0, wx.ALL, 5)
|
||||
self.SetSizer(self.sizer)
|
||||
|
@@ -52,3 +52,9 @@ def no_following():
|
||||
def donation():
|
||||
dlg = wx.MessageDialog(None, _(u"If you like {0} we need your help to keep it going. Help us by donating to the project. This will help us pay for the server, the domain and some other things to ensure that {0} will be actively maintained. Your donation will give us the means to continue the development of {0}, and to keep {0} free. Would you like to donate now?").format(application.name), _(u"We need your help"), wx.ICON_QUESTION|wx.YES_NO)
|
||||
return dlg.ShowModal()
|
||||
|
||||
def no_tweets():
|
||||
return wx.MessageDialog(None, _(u"This user has no tweets. {0} can't create a timeline.").format(application.name), _(u"Error"), wx.ICON_ERROR).ShowModal()
|
||||
|
||||
def no_favs():
|
||||
return wx.MessageDialog(None, _(u"This user has no favorited tweets. {0} can't create a timeline.").format(application.name), _(u"Error"), wx.ICON_ERROR).ShowModal()
|
||||
|
@@ -123,6 +123,7 @@ class removeUserListDialog(listViewer):
|
||||
self.SetTitle(_(u"Select a list to remove the user"))
|
||||
self.createBtn.SetLabel(_(u"Remove"))
|
||||
self.createBtn.SetDefault()
|
||||
self.createBtn.SetId(wx.ID_OK)
|
||||
self.editBtn.Disable()
|
||||
self.view.Disable()
|
||||
# self.subscriptors.Disable()
|
||||
|
@@ -216,6 +216,7 @@ class dm(textLimited):
|
||||
self.buttonsBox3.Add(cancelButton, 0, wx.ALL, 5)
|
||||
self.mainBox.Add(self.buttonsBox3, 0, wx.ALL, 5)
|
||||
self.panel.SetSizer(self.mainBox)
|
||||
# self.SetClientSize(self.mainBox.CalcMin())
|
||||
|
||||
def __init__(self, title, message, users):
|
||||
super(dm, self).__init__()
|
||||
|
97
src/wxUI/menus.py
Normal file
97
src/wxUI/menus.py
Normal file
@@ -0,0 +1,97 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import wx
|
||||
|
||||
class basePanelMenu(wx.Menu):
|
||||
def __init__(self):
|
||||
super(basePanelMenu, self).__init__()
|
||||
self.retweet = wx.MenuItem(self, wx.NewId(), _(u"&Retweet"))
|
||||
self.AppendItem(self.retweet)
|
||||
self.reply = wx.MenuItem(self, wx.NewId(), _(u"Re&ply"))
|
||||
self.AppendItem(self.reply)
|
||||
self.fav = wx.MenuItem(self, wx.NewId(), _(u"Add to &favourites"))
|
||||
self.AppendItem(self.fav)
|
||||
self.unfav = wx.MenuItem(self, wx.NewId(), _(u"Remove from favo&urites"))
|
||||
self.AppendItem(self.unfav)
|
||||
self.openUrl = wx.MenuItem(self, wx.NewId(), _(u"&Open URL"))
|
||||
self.AppendItem(self.openUrl)
|
||||
self.play = wx.MenuItem(self, wx.NewId(), _(u"&Play audio"))
|
||||
self.AppendItem(self.play)
|
||||
self.view = wx.MenuItem(self, wx.NewId(), _(u"&Show tweet"))
|
||||
self.AppendItem(self.view)
|
||||
self.copy = wx.MenuItem(self, wx.NewId(), _(u"&Copy to clipboard"))
|
||||
self.AppendItem(self.copy)
|
||||
self.remove = wx.MenuItem(self, wx.NewId(), _(u"&Delete"))
|
||||
self.AppendItem(self.remove)
|
||||
self.userActions = wx.MenuItem(self, wx.NewId(), _(u"&User actions..."))
|
||||
self.AppendItem(self.userActions)
|
||||
|
||||
class dmPanelMenu(wx.Menu):
|
||||
def __init__(self):
|
||||
super(dmPanelMenu, self).__init__()
|
||||
self.reply = wx.MenuItem(self, wx.NewId(), _(u"Re&ply"))
|
||||
self.AppendItem(self.reply)
|
||||
self.openUrl = wx.MenuItem(self, wx.NewId(), _(u"&Open URL"))
|
||||
self.AppendItem(self.openUrl)
|
||||
self.play = wx.MenuItem(self, wx.NewId(), _(u"&Play audio"))
|
||||
self.AppendItem(self.play)
|
||||
self.view = wx.MenuItem(self, wx.NewId(), _(u"&Show direct message"))
|
||||
self.AppendItem(self.view)
|
||||
self.copy = wx.MenuItem(self, wx.NewId(), _(u"&Copy to clipboard"))
|
||||
self.AppendItem(self.copy)
|
||||
self.remove = wx.MenuItem(self, wx.NewId(), _(u"&Delete"))
|
||||
self.AppendItem(self.remove)
|
||||
self.userActions = wx.MenuItem(self, wx.NewId(), _(u"&User actions..."))
|
||||
self.AppendItem(self.userActions)
|
||||
|
||||
class sentPanelMenu(wx.Menu):
|
||||
def __init__(self):
|
||||
super(sentPanelMenu, self).__init__()
|
||||
self.openUrl = wx.MenuItem(self, wx.NewId(), _(u"&Open URL"))
|
||||
self.AppendItem(self.openUrl)
|
||||
self.play = wx.MenuItem(self, wx.NewId(), _(u"&Play audio"))
|
||||
self.AppendItem(self.play)
|
||||
self.view = wx.MenuItem(self, wx.NewId(), _(u"&Show tweet"))
|
||||
self.AppendItem(self.view)
|
||||
self.copy = wx.MenuItem(self, wx.NewId(), _(u"&Copy to clipboard"))
|
||||
self.AppendItem(self.copy)
|
||||
self.remove = wx.MenuItem(self, wx.NewId(), _(u"&Delete"))
|
||||
self.AppendItem(self.remove)
|
||||
|
||||
class eventsPanelMenu(wx.Menu):
|
||||
def __init__(self):
|
||||
super(eventsPanelMenu, self).__init__()
|
||||
self.view = wx.MenuItem(self, wx.NewId(), _(u"&Show event"))
|
||||
self.AppendItem(self.view)
|
||||
self.copy = wx.MenuItem(self, wx.NewId(), _(u"&Copy to clipboard"))
|
||||
self.AppendItem(self.copy)
|
||||
self.remove = wx.MenuItem(self, wx.NewId(), _(u"&Delete"))
|
||||
self.AppendItem(self.remove)
|
||||
|
||||
class peoplePanelMenu(wx.Menu):
|
||||
def __init__(self):
|
||||
super(peoplePanelMenu, self).__init__()
|
||||
self.reply = wx.MenuItem(self, wx.NewId(), _(u"Direct &message"))
|
||||
self.AppendItem(self.reply)
|
||||
self.lists = wx.MenuItem(self, wx.NewId(), _(u"&View lists"))
|
||||
self.AppendItem(self.lists)
|
||||
self.lists.Enable(False)
|
||||
self.details = wx.MenuItem(self, wx.NewId(), _(u"Show user &profile"))
|
||||
self.AppendItem(self.details)
|
||||
self.view = wx.MenuItem(self, wx.NewId(), _(u"&Show user"))
|
||||
self.AppendItem(self.view)
|
||||
self.copy = wx.MenuItem(self, wx.NewId(), _(u"&Copy to clipboard"))
|
||||
self.AppendItem(self.copy)
|
||||
self.userActions = wx.MenuItem(self, wx.NewId(), _(u"&User actions..."))
|
||||
self.AppendItem(self.userActions)
|
||||
|
||||
class trendsPanelMenu(wx.Menu):
|
||||
def __init__(self):
|
||||
super(trendsPanelMenu, self).__init__()
|
||||
self.search_topic = wx.MenuItem(self, wx.NewId(), _(u"Search topic"))
|
||||
self.AppendItem(self.search_topic)
|
||||
self.tweetThisTrend = wx.MenuItem(self, wx.NewId(), _(u"&Tweet about this trend"))
|
||||
self.AppendItem(self.tweetThisTrend)
|
||||
self.view = wx.MenuItem(self, wx.NewId(), _(u"&Show item"))
|
||||
self.AppendItem(self.view)
|
||||
self.copy = wx.MenuItem(self, wx.NewId(), _(u"&Copy to clipboard"))
|
||||
self.AppendItem(self.copy)
|
@@ -41,9 +41,7 @@ class mainFrame(wx.Frame):
|
||||
self.dm = user.Append(wx.NewId(), _(u"Direct me&ssage"))
|
||||
self.addToList = user.Append(wx.NewId(), _(u"&Add to list"))
|
||||
self.removeFromList = user.Append(wx.NewId(), _(u"R&emove from list"))
|
||||
self.removeFromList.Enable(False)
|
||||
self.viewLists = user.Append(wx.NewId(), _(u"&View lists"))
|
||||
self.viewLists.Enable(False)
|
||||
self.details = user.Append(wx.NewId(), _(u"Show user &profile"))
|
||||
self.favs = user.Append(wx.NewId(), _(u"V&iew favourites"))
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2015-08-04 13:37+Hora de verano central (M<>xico)\n"
|
||||
"POT-Creation-Date: 2015-09-29 09:37+Hora de verano central (M<>xico)\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -51,7 +51,7 @@ msgstr ""
|
||||
#: ../doc\strings.py:378 ../doc\strings.py:381 ../doc\strings.py:384
|
||||
#: ../doc\strings.py:387 ../doc\strings.py:390 ../doc\strings.py:393
|
||||
#: ../doc\strings.py:396 ../doc\strings.py:399 ../doc\strings.py:402
|
||||
#: ../doc\strings.py:405 ../doc\strings.py:421 ../doc\strings.py:424
|
||||
#: ../doc\strings.py:405 ../doc\strings.py:423 ../doc\strings.py:426
|
||||
msgid ""
|
||||
"\n"
|
||||
msgstr ""
|
||||
@@ -361,7 +361,7 @@ msgid "* Global settings: Opens a dialogue which lets you configure settings for
|
||||
msgstr ""
|
||||
|
||||
#: ../doc\strings.py:166
|
||||
msgid "* Quit: asks whether you want to exit the program. If the answer is yes, it closes the application. If you do not want to be asked for confirmation before exiting, uncheck the checkbox from the global settings dialogue box."
|
||||
msgid "* Exit: asks whether you want to exit the program. If the answer is yes, it closes the application. If you do not want to be asked for confirmation before exiting, uncheck the checkbox from the global settings dialogue box."
|
||||
msgstr ""
|
||||
|
||||
#: ../doc\strings.py:169
|
||||
@@ -973,7 +973,7 @@ msgid "* English: [Bryner Villalobos](https://twitter.com/Bry_StarkCR) and [Bill
|
||||
msgstr ""
|
||||
|
||||
#: ../doc\strings.py:408
|
||||
msgid "* Arabic: Mohammed Al Shara."
|
||||
msgid "* Arabic: [Mohammed Al Shara](https://twitter.com/mohammed0204)."
|
||||
msgstr ""
|
||||
|
||||
#: ../doc\strings.py:409
|
||||
@@ -989,11 +989,11 @@ msgid "* Basque: [Sukil Etxenike](https://twitter.com/sukil2011)."
|
||||
msgstr ""
|
||||
|
||||
#: ../doc\strings.py:412
|
||||
msgid "* Finnish: Jani Kinnunen."
|
||||
msgid "* Finnish: [Jani Kinnunen](https://twitter.com/jani_kinnunen)."
|
||||
msgstr ""
|
||||
|
||||
#: ../doc\strings.py:413
|
||||
msgid "* French: R\303\251mi Ruiz."
|
||||
msgid "* French: [R\303\251mi Ruiz](https://twitter.com/blindhelp38)."
|
||||
msgstr ""
|
||||
|
||||
#: ../doc\strings.py:414
|
||||
@@ -1001,38 +1001,46 @@ msgid "* Galician: [Alba Kinteiro](https://twitter.com/albasmileforeve)."
|
||||
msgstr ""
|
||||
|
||||
#: ../doc\strings.py:415
|
||||
msgid "* German: Steffen Schultz."
|
||||
msgid "* German: [Steffen Schultz](https://twitter.com/schulle4u)."
|
||||
msgstr ""
|
||||
|
||||
#: ../doc\strings.py:416
|
||||
msgid "* Hungarian: Robert Osztolykan."
|
||||
msgid "* Croatian: [Zvonimir Stane\304\215i\304\207](https://twitter.com/zvonimirek222)."
|
||||
msgstr ""
|
||||
|
||||
#: ../doc\strings.py:417
|
||||
msgid "* Polish: Pawel Masarczyk."
|
||||
msgid "* Hungarian: Robert Osztolykan."
|
||||
msgstr ""
|
||||
|
||||
#: ../doc\strings.py:418
|
||||
msgid "* Portuguese: Odenilton J\303\272nior Santos."
|
||||
msgid "* Italian: [Christian Leo Mameli](https://twitter.com/llajta2012)."
|
||||
msgstr ""
|
||||
|
||||
#: ../doc\strings.py:419
|
||||
msgid "* Russian: Alexander Jaszyn."
|
||||
msgid "* Polish: Pawel Masarczyk."
|
||||
msgstr ""
|
||||
|
||||
#: ../doc\strings.py:420
|
||||
msgid "* Turkish: Burak."
|
||||
msgid "* Portuguese: Odenilton J\303\272nior Santos."
|
||||
msgstr ""
|
||||
|
||||
#: ../doc\strings.py:423
|
||||
#: ../doc\strings.py:421
|
||||
msgid "* Russian: [\320\220\320\273\320\265\320\272\321\201\320\260\320\275\320\264\321\200 \320\257\321\210\320\270\320\275](https://twitter.com/radovest)."
|
||||
msgstr ""
|
||||
|
||||
#: ../doc\strings.py:422
|
||||
msgid "* Turkish: [Burak Y\303\274ksek](https://twitter.com/burakyuksek)."
|
||||
msgstr ""
|
||||
|
||||
#: ../doc\strings.py:425
|
||||
msgid "Many thanks also to the people who worked on the documentation. Initially, [Manuel Cortez](https://twitter.com/manuelcortez00) did the documentation in Spanish, and translated to English by [Bryner Villalobos](https://twitter.com/Bry_StarkCR), [Robert Spangler](https://twitter.com/glasscity1837), [Sussan Rey](https://twitter.com/sussanrey17), [Anibal Hernandez](https://twitter.com/anibalmetal), and [Holly Scott-Gardner](https://twitter.com/holly1994). It was updated by [Sukil Etxenike](https://twitter.com/sukil2011), with some valuable corrections by [Brian Hartgen](https://twitter.com/brianhartgen) and [Bill Dengler](https://twitter.com/codeofdusk)."
|
||||
msgstr ""
|
||||
|
||||
#: ../doc\strings.py:426
|
||||
#: ../doc\strings.py:428
|
||||
msgid "---"
|
||||
msgstr ""
|
||||
|
||||
#: ../doc\strings.py:427
|
||||
#: ../doc\strings.py:429
|
||||
msgid "Copyright \302\251 2013-2015. Manuel Cort\303\251z"
|
||||
msgstr ""
|
||||
|
||||
|
562
tools/twblue.pot
562
tools/twblue.pot
File diff suppressed because it is too large
Load Diff
Submodule windows-dependencies updated: 0f65f42c9f...4d106f04f7
Reference in New Issue
Block a user