mirror of
https://github.com/MCV-Software/TWBlue.git
synced 2025-08-26 09:59:23 +00:00
Compare commits
21 Commits
Author | SHA1 | Date | |
---|---|---|---|
214b9a8809 | |||
e85f54e15c | |||
![]() |
d2245c33ce | ||
ff6695bba3 | |||
cdcdc86627 | |||
b4addf9329 | |||
9d0c9cfdb5 | |||
0afba81c71 | |||
0882e4707d | |||
78079e142f | |||
00a4203e1a | |||
c4fae3b70b | |||
b8dfa4a5e8 | |||
1ca1862a08 | |||
ba76c74324 | |||
![]() |
dda37f0083 | ||
65c353450e | |||
2bfb53abe1 | |||
ab08eada81 | |||
![]() |
5fcc1de9a5 | ||
![]() |
baeb0f7ae8 |
32
README.md
32
README.md
@@ -1,4 +1,4 @@
|
|||||||
TWBlue -
|
TWBlue -
|
||||||
======
|
======
|
||||||
|
|
||||||
Copyright (C) 2015. [Technow S.L.](https://www.technow.es)
|
Copyright (C) 2015. [Technow S.L.](https://www.technow.es)
|
||||||
@@ -32,12 +32,11 @@ Although most dependencies can be found in the windows-dependencies directory, w
|
|||||||
|
|
||||||
#### Dependencies packaged in windows installers
|
#### Dependencies packaged in windows installers
|
||||||
|
|
||||||
* [Python,](http://python.org) version 2.7.10
|
* [Python,](http://python.org) version 2.7.11
|
||||||
If you want to build both x86 and x64 binaries, you can install python x86 to C:\python27 and python x64 to C:\python27x64, for example.
|
If you want to build both x86 and x64 binaries, you can install python x86 to C:\python27 and python x64 to C:\python27x64, for example.
|
||||||
* [wxPython](http://www.wxpython.org) for Python 2.7, version 3.0.2.0
|
* [wxPython](http://www.wxpython.org) for Python 2.7, version 3.0.2.0
|
||||||
* [Python windows extensions (pywin32)](http://www.sourceforge.net/projects/pywin32/) for python 2.7, build 219
|
* [Python windows extensions (pywin32)](http://www.sourceforge.net/projects/pywin32/) for python 2.7, build 219
|
||||||
* [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/)
|
* [Pycurl](http://pycurl.sourceforge.net) 7.19.5.3 for Python 2.7: [downloads](https://pypi.python.org/pypi/pycurl/7.19.5.3)
|
||||||
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.
|
* [PyEnchant,](http://pythonhosted.org/pyenchant/) version 1.6.6.
|
||||||
x64 version has been built by TWBlue 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
|
||||||
|
|
||||||
@@ -68,14 +67,14 @@ setuptools install a script, called easy_install. You can find it in the python
|
|||||||
* future
|
* future
|
||||||
* pygeocoder
|
* pygeocoder
|
||||||
* suds
|
* suds
|
||||||
* arrow
|
* arrow==0.6
|
||||||
* goslate
|
|
||||||
* markdown
|
* markdown
|
||||||
* pocket
|
* winpaths
|
||||||
|
* microsofttranslator
|
||||||
|
|
||||||
easy_install will automatically get the additional libraries that these packages need to work properly.
|
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:
|
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 python-dateutil futures
|
easy_install -Z --upgrade six configobj goslate markdown future suds requests oauthlib requests-oauthlib pypubsub pygeocoder arrow python-dateutil futures markdown microsofttranslator
|
||||||
|
|
||||||
#### Other dependencies
|
#### Other dependencies
|
||||||
|
|
||||||
@@ -90,6 +89,11 @@ This dependency has been built using pure basic 4.61. Its source can be found at
|
|||||||
|
|
||||||
* [NSIS unicode,](http://www.scratchpaper.com/) version 2.46.5
|
* [NSIS unicode,](http://www.scratchpaper.com/) version 2.46.5
|
||||||
|
|
||||||
|
#### Dependencies required to build the portableApps.com format archive
|
||||||
|
|
||||||
|
* [PortableApps.com Launcher,](http://portableapps.com/apps/development/portableapps.com_launcher) version 2.2
|
||||||
|
* [PortableApps.com Installer,](http://portableapps.com/apps/development/portableapps.com_installer) version 3.0.20
|
||||||
|
|
||||||
### Running TW Blue from source
|
### Running TW Blue from source
|
||||||
|
|
||||||
Now that you have installed all these packages, you can run TW Blue from source using a command prompt. Navigate to the repo's src directory, and type the following command:
|
Now that you have installed all these packages, you can run TW Blue from source using a command prompt. Navigate to the repo's src directory, and type the following command:
|
||||||
@@ -129,3 +133,15 @@ If you want to install TWBlue in your computer, you must create the installer fi
|
|||||||
### How to generate a translation template
|
### 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.
|
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.
|
||||||
|
|
||||||
|
### How to build the portableApps.com archive
|
||||||
|
|
||||||
|
If you want to have TWBlue in your PortableApps.com platform, 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 misc\pa.c format\app 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 misc\pa.c format\app folder, and rename it to twblue64
|
||||||
|
* Run the PortableApps.com Launcher Generator, and follow the wizard. Choose the pa.c format folder and continue to generate the launcher. If the wizard is completed, you will see a file named TWBlue portable.exe inside the pa.c format folder.
|
||||||
|
* Run the PortableApps.com Installer, and follow the wizard. As in the above step, choose the pa.c format folder. When it completes, you will see a file named TWBluePortable_x.y.paf.exe inside the misc folder, where x.y is the version number.
|
||||||
|
|
||||||
|
@@ -3,9 +3,9 @@ Type=PortableApps.comFormat
|
|||||||
Version=3.0
|
Version=3.0
|
||||||
|
|
||||||
[Details]
|
[Details]
|
||||||
Name=TWBlue portable
|
Name=tw blue portable
|
||||||
AppID=TWBluePortable
|
AppID=TWBluePortable
|
||||||
Publisher=jmdaweb & TWBlue & PortableApps.com
|
Publisher=jmdaweb & TW blue & PortableApps.com
|
||||||
Homepage=PortableApps.com/TWBluePortable
|
Homepage=PortableApps.com/TWBluePortable
|
||||||
Category=Internet
|
Category=Internet
|
||||||
Description=A portable, fast and accessible Twitter client with many options.
|
Description=A portable, fast and accessible Twitter client with many options.
|
||||||
|
@@ -8,10 +8,14 @@ FINNISH=true
|
|||||||
FRENCH=true
|
FRENCH=true
|
||||||
GALICIAN=true
|
GALICIAN=true
|
||||||
GERMAN=true
|
GERMAN=true
|
||||||
|
CROATIAN=true
|
||||||
HUNGARIAN=true
|
HUNGARIAN=true
|
||||||
ITALIAN=true
|
ITALIAN=true
|
||||||
|
JAPANESE=true
|
||||||
POLISH=true
|
POLISH=true
|
||||||
PORTUGUESEBR=true
|
PORTUGUESEBR=true
|
||||||
|
ROMANIAN=true
|
||||||
RUSSIAN=true
|
RUSSIAN=true
|
||||||
|
SERBIAN=true
|
||||||
SPANISHINTERNATIONAL=true
|
SPANISHINTERNATIONAL=true
|
||||||
TURKISH=true
|
TURKISH=true
|
@@ -2,7 +2,7 @@
|
|||||||
<html lang="en-US">
|
<html lang="en-US">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>TWBlue Portable Help</title>
|
<title>tw blue Portable Help</title>
|
||||||
<link rel="alternate" href="http://portableapps.com/feeds/general" type="application/rss+xml" title="PortableApps.com">
|
<link rel="alternate" href="http://portableapps.com/feeds/general" type="application/rss+xml" title="PortableApps.com">
|
||||||
<link rel="shortcut icon" href="Other/Help/Images/Favicon.ico">
|
<link rel="shortcut icon" href="Other/Help/Images/Favicon.ico">
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
@@ -125,13 +125,13 @@
|
|||||||
<body>
|
<body>
|
||||||
<div class="logo"><a href="http://portableapps.com/"><img src="Other/Help/Images/Help_Logo_Top.png" alt="PortableApps.com - Your Digital Life, Anywhere"></a></div>
|
<div class="logo"><a href="http://portableapps.com/"><img src="Other/Help/Images/Help_Logo_Top.png" alt="PortableApps.com - Your Digital Life, Anywhere"></a></div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<h1 class="hastagline">TWBlue Portable Help</h1>
|
<h1 class="hastagline">tw blue Portable Help</h1>
|
||||||
<h2 class="tagline">A powerful and accessible Twitter client</h2>
|
<h2 class="tagline">A powerful and accessible Twitter client</h2>
|
||||||
<p>TWBlue Portable is the TWBlue whatever it is packaged with a PortableApps.com launcher as a <a href="http://portableapps.com/about/what_is_a_portable_app">portable app</a>, so you can view and send tweets on your iPod, USB flash drive, portable hard drive, etc. It has all the same features as TWBlue, plus, it leaves no personal information behind on the machine you run it on, so you can take it with you wherever you go. <a href="http://twblue.es">Learn more about TWBlue...</a></p>
|
<p>tw blue Portable is the tw blue whatever it is packaged with a PortableApps.com launcher as a <a href="http://portableapps.com/about/what_is_a_portable_app">portable app</a>, so you can view and send tweets on your iPod, USB flash drive, portable hard drive, etc. It has all the same features as tw blue, plus, it leaves no personal information behind on the machine you run it on, so you can take it with you wherever you go. <a href="http://twblue.es">Learn more about tw blue...</a></p>
|
||||||
|
|
||||||
<p><a href="http://portableapps.com/donate"><img src="Other/Help/Images/Donation_Button.png" style="vertical-align:middle" alt="Make a Donation"></a> - Support PortableApps.com's Hosting and Development</p>
|
<p><a href="http://portableapps.com/donate"><img src="Other/Help/Images/Donation_Button.png" style="vertical-align:middle" alt="Make a Donation"></a> - Support PortableApps.com's Hosting and Development</p>
|
||||||
|
|
||||||
<p><a href="http://portableapps.com/node/*Node ID*">Go to the TWBlue Portable Homepage >></a></p>
|
<p><a href="http://portableapps.com/node/*Node ID*">Go to the tw blue Portable Homepage >></a></p>
|
||||||
<p><a href="http://portableapps.com/">Get more portable apps at PortableApps.com</a></p>
|
<p><a href="http://portableapps.com/">Get more portable apps at PortableApps.com</a></p>
|
||||||
|
|
||||||
<p>This software is OSI Certified Open Source Software. OSI Certified is a certification mark of the Open Source Initiative.</p>
|
<p>This software is OSI Certified Open Source Software. OSI Certified is a certification mark of the Open Source Initiative.</p>
|
||||||
|
@@ -48,6 +48,7 @@ var StartMenuFolder
|
|||||||
!insertmacro MUI_LANGUAGE "Croatian"
|
!insertmacro MUI_LANGUAGE "Croatian"
|
||||||
!insertmacro MUI_LANGUAGE "Japanese"
|
!insertmacro MUI_LANGUAGE "Japanese"
|
||||||
!insertmacro MUI_LANGUAGE "SerbianLatin"
|
!insertmacro MUI_LANGUAGE "SerbianLatin"
|
||||||
|
!insertmacro MUI_LANGUAGE "Romanian"
|
||||||
!insertmacro MUI_RESERVEFILE_LANGDLL
|
!insertmacro MUI_RESERVEFILE_LANGDLL
|
||||||
Section
|
Section
|
||||||
SetShellVarContext All
|
SetShellVarContext All
|
||||||
|
@@ -28,6 +28,8 @@ timelines = list(default=list())
|
|||||||
tweet_searches = list(default=list())
|
tweet_searches = list(default=list())
|
||||||
lists = list(default=list())
|
lists = list(default=list())
|
||||||
favourites_timelines = list(default=list())
|
favourites_timelines = list(default=list())
|
||||||
|
followers_timelines = list(default=list())
|
||||||
|
friends_timelines = list(default=list())
|
||||||
trending_topic_buffers = list(default=list())
|
trending_topic_buffers = list(default=list())
|
||||||
muted_buffers = list(default=list())
|
muted_buffers = list(default=list())
|
||||||
autoread_buffers = list(default=list(mentions, direct_messages, events))
|
autoread_buffers = list(default=list(mentions, direct_messages, events))
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
name = 'TWBlue'
|
name = 'TWBlue'
|
||||||
snapshot = False
|
snapshot = True
|
||||||
if snapshot == False:
|
if snapshot == False:
|
||||||
version = "0.80"
|
version = "0.80"
|
||||||
update_url = 'http://twblue.es/updates/twblue_ngen.json'
|
update_url = 'http://twblue.es/updates/twblue_ngen.json'
|
||||||
else:
|
else:
|
||||||
version = "10.97"
|
version = "10.98"
|
||||||
update_url = 'http://twblue.es/updates/snapshots_ngen.json'
|
update_url = 'http://twblue.es/updates/snapshots_ngen.json'
|
||||||
author = u"Manuel Cortéz"
|
author = u"Manuel Cortéz"
|
||||||
authorEmail = "manuel@manuelcortez.net"
|
authorEmail = "manuel@manuelcortez.net"
|
||||||
|
@@ -84,7 +84,9 @@ class bufferController(object):
|
|||||||
sound.URLPlayer.stream.volume = self.session.settings["sound"]["volume"]
|
sound.URLPlayer.stream.volume = self.session.settings["sound"]["volume"]
|
||||||
self.session.sound.play("volume_changed.ogg")
|
self.session.sound.play("volume_changed.ogg")
|
||||||
|
|
||||||
def start_stream(self):
|
def start_stream(self, mandatory=False):
|
||||||
|
if mandatory == True:
|
||||||
|
output.speak(_(u"Unable to update this buffer."))
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def get_more_items(self):
|
def get_more_items(self):
|
||||||
@@ -272,10 +274,10 @@ class baseBufferController(bufferController):
|
|||||||
tweetsList.append(tweet)
|
tweetsList.append(tweet)
|
||||||
return (tweet, tweetsList)
|
return (tweet, tweetsList)
|
||||||
|
|
||||||
def start_stream(self):
|
def start_stream(self, mandatory=False):
|
||||||
# starts stream every 3 minutes.
|
# starts stream every 3 minutes.
|
||||||
current_time = time.time()
|
current_time = time.time()
|
||||||
if self.execution_time == 0 or current_time-self.execution_time >= 180:
|
if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory==True:
|
||||||
self.execution_time = current_time
|
self.execution_time = current_time
|
||||||
log.debug("Starting stream for buffer %s, account %s and type %s" % (self.name, self.account, self.type))
|
log.debug("Starting stream for buffer %s, account %s and type %s" % (self.name, self.account, self.type))
|
||||||
log.debug("args: %s, kwargs: %s" % (self.args, self.kwargs))
|
log.debug("args: %s, kwargs: %s" % (self.args, self.kwargs))
|
||||||
@@ -283,9 +285,9 @@ class baseBufferController(bufferController):
|
|||||||
number_of_items = self.session.order_buffer(self.name, val)
|
number_of_items = self.session.order_buffer(self.name, val)
|
||||||
log.debug("Number of items retrieved: %d" % (number_of_items,))
|
log.debug("Number of items retrieved: %d" % (number_of_items,))
|
||||||
self.put_items_on_list(number_of_items)
|
self.put_items_on_list(number_of_items)
|
||||||
if self.sound == None: return
|
if number_of_items > 0 and self.name != "sent_tweets" and self.name != "sent_direct_messages" and self.sound != None:
|
||||||
if number_of_items > 0 and self.name != "sent_tweets" and self.name != "sent_direct_messages":
|
|
||||||
self.session.sound.play(self.sound)
|
self.session.sound.play(self.sound)
|
||||||
|
return number_of_items
|
||||||
|
|
||||||
def get_more_items(self):
|
def get_more_items(self):
|
||||||
elements = []
|
elements = []
|
||||||
@@ -481,7 +483,13 @@ class baseBufferController(bufferController):
|
|||||||
users = utils.get_all_users(tweet, self.session.db)
|
users = utils.get_all_users(tweet, self.session.db)
|
||||||
dm = messages.dm(self.session, _(u"Direct message to %s") % (screen_name,), _(u"New direct message"), users)
|
dm = messages.dm(self.session, _(u"Direct message to %s") % (screen_name,), _(u"New direct message"), users)
|
||||||
if dm.message.get_response() == widgetUtils.OK:
|
if dm.message.get_response() == widgetUtils.OK:
|
||||||
call_threaded(self.session.api_call, call_name="send_direct_message", text=dm.message.get_text(), screen_name=dm.message.get("cb"))
|
val = self.session.api_call(call_name="send_direct_message", text=dm.message.get_text(), screen_name=dm.message.get("cb"))
|
||||||
|
if val != None:
|
||||||
|
if self.session.settings["general"]["reverse_timelines"] == False:
|
||||||
|
self.session.db["sent_direct_messages"].append(val)
|
||||||
|
else:
|
||||||
|
self.session.db["sent_direct_messages"].insert(0, val)
|
||||||
|
pub.sendMessage("sent-dm", data=val, user=self.session.db["user_name"])
|
||||||
if hasattr(dm.message, "destroy"): dm.message.destroy()
|
if hasattr(dm.message, "destroy"): dm.message.destroy()
|
||||||
|
|
||||||
@_tweets_exist
|
@_tweets_exist
|
||||||
@@ -638,9 +646,9 @@ class listBufferController(baseBufferController):
|
|||||||
self.list_id = list_id
|
self.list_id = list_id
|
||||||
self.kwargs["list_id"] = list_id
|
self.kwargs["list_id"] = list_id
|
||||||
|
|
||||||
def start_stream(self):
|
def start_stream(self, mandatory=False):
|
||||||
self.get_user_ids()
|
self.get_user_ids()
|
||||||
super(listBufferController, self).start_stream()
|
super(listBufferController, self).start_stream(mandatory)
|
||||||
|
|
||||||
def get_user_ids(self):
|
def get_user_ids(self):
|
||||||
self.users = []
|
self.users = []
|
||||||
@@ -714,7 +722,7 @@ class eventsBufferController(bufferController):
|
|||||||
|
|
||||||
class peopleBufferController(baseBufferController):
|
class peopleBufferController(baseBufferController):
|
||||||
def __init__(self, parent, function, name, sessionObject, account, bufferType=None, *args, **kwargs):
|
def __init__(self, parent, function, name, sessionObject, account, bufferType=None, *args, **kwargs):
|
||||||
super(peopleBufferController, self).__init__(parent, function, name, sessionObject, account, bufferType="peoplePanel")
|
super(peopleBufferController, self).__init__(parent, function, name, sessionObject, account, bufferType="peoplePanel", *args, **kwargs)
|
||||||
log.debug("Initializing buffer %s, account %s" % (name, account,))
|
log.debug("Initializing buffer %s, account %s" % (name, account,))
|
||||||
self.compose_function = compose.compose_followers_list
|
self.compose_function = compose.compose_followers_list
|
||||||
log.debug("Compose_function: %s" % (self.compose_function,))
|
log.debug("Compose_function: %s" % (self.compose_function,))
|
||||||
@@ -722,6 +730,24 @@ class peopleBufferController(baseBufferController):
|
|||||||
self.url = self.interact
|
self.url = self.interact
|
||||||
|
|
||||||
def remove_buffer(self):
|
def remove_buffer(self):
|
||||||
|
if "-followers" in self.name:
|
||||||
|
dlg = commonMessageDialogs.remove_buffer()
|
||||||
|
if dlg == widgetUtils.YES:
|
||||||
|
if self.name[:-10] in self.session.settings["other_buffers"]["followers_timelines"]:
|
||||||
|
self.session.settings["other_buffers"]["followers_timelines"].remove(self.name[:-10])
|
||||||
|
return True
|
||||||
|
elif dlg == widgetUtils.NO:
|
||||||
|
return False
|
||||||
|
elif "-friends" in self.name:
|
||||||
|
dlg = commonMessageDialogs.remove_buffer()
|
||||||
|
if dlg == widgetUtils.YES:
|
||||||
|
if self.name[:-8] in self.session.settings["other_buffers"]["friends_timelines"]:
|
||||||
|
self.session.settings["other_buffers"]["friends_timelines"].remove(self.name[:-9])
|
||||||
|
return True
|
||||||
|
elif dlg == widgetUtils.NO:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
output.speak(_(u"This buffer is not a timeline; it can't be deleted."), True)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def onFocus(self, ev):
|
def onFocus(self, ev):
|
||||||
@@ -744,15 +770,16 @@ class peopleBufferController(baseBufferController):
|
|||||||
call_threaded(self.session.api_call, call_name="update_status_with_media", _sound="reply_send.ogg", status=message.message.get_text(), media=message.file)
|
call_threaded(self.session.api_call, call_name="update_status_with_media", _sound="reply_send.ogg", status=message.message.get_text(), media=message.file)
|
||||||
if hasattr(message.message, "destroy"): message.message.destroy()
|
if hasattr(message.message, "destroy"): message.message.destroy()
|
||||||
|
|
||||||
def start_stream(self):
|
def start_stream(self, mandatory=False):
|
||||||
# starts stream every 3 minutes.
|
# starts stream every 3 minutes.
|
||||||
current_time = time.time()
|
current_time = time.time()
|
||||||
if self.execution_time == 0 or current_time-self.execution_time >= 180:
|
if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory==True:
|
||||||
self.execution_time = current_time
|
self.execution_time = current_time
|
||||||
log.debug("Starting stream for %s buffer, %s account" % (self.name, self.account,))
|
log.debug("Starting stream for %s buffer, %s account" % (self.name, self.account,))
|
||||||
log.debug("args: %s, kwargs: %s" % (self.args, self.kwargs))
|
log.debug("args: %s, kwargs: %s" % (self.args, self.kwargs))
|
||||||
val = self.session.get_cursored_stream(self.name, self.function, *self.args, **self.kwargs)
|
val = self.session.get_cursored_stream(self.name, self.function, *self.args, **self.kwargs)
|
||||||
self.put_items_on_list(val)
|
self.put_items_on_list(val)
|
||||||
|
return val
|
||||||
|
|
||||||
def get_more_items(self):
|
def get_more_items(self):
|
||||||
try:
|
try:
|
||||||
@@ -841,10 +868,10 @@ class peopleBufferController(baseBufferController):
|
|||||||
pub.sendMessage("execute-action", action="user_details")
|
pub.sendMessage("execute-action", action="user_details")
|
||||||
|
|
||||||
class searchBufferController(baseBufferController):
|
class searchBufferController(baseBufferController):
|
||||||
def start_stream(self):
|
def start_stream(self, mandatory=False):
|
||||||
# starts stream every 3 minutes.
|
# starts stream every 3 minutes.
|
||||||
current_time = time.time()
|
current_time = time.time()
|
||||||
if self.execution_time == 0 or current_time-self.execution_time >= 180:
|
if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory==True:
|
||||||
self.execution_time = current_time
|
self.execution_time = current_time
|
||||||
log.debug("Starting stream for %s buffer, %s account and %s type" % (self.name, self.account, self.type))
|
log.debug("Starting stream for %s buffer, %s account and %s type" % (self.name, self.account, self.type))
|
||||||
log.debug("args: %s, kwargs: %s" % (self.args, self.kwargs))
|
log.debug("args: %s, kwargs: %s" % (self.args, self.kwargs))
|
||||||
@@ -857,6 +884,7 @@ class searchBufferController(baseBufferController):
|
|||||||
self.put_items_on_list(num)
|
self.put_items_on_list(num)
|
||||||
if num > 0:
|
if num > 0:
|
||||||
self.session.sound.play("search_updated.ogg")
|
self.session.sound.play("search_updated.ogg")
|
||||||
|
return num
|
||||||
|
|
||||||
def remove_buffer(self):
|
def remove_buffer(self):
|
||||||
dlg = commonMessageDialogs.remove_buffer()
|
dlg = commonMessageDialogs.remove_buffer()
|
||||||
@@ -879,10 +907,10 @@ class searchPeopleBufferController(peopleBufferController):
|
|||||||
self.kwargs = kwargs
|
self.kwargs = kwargs
|
||||||
self.function = function
|
self.function = function
|
||||||
|
|
||||||
def start_stream(self):
|
def start_stream(self, mandatory=False):
|
||||||
# starts stream every 3 minutes.
|
# starts stream every 3 minutes.
|
||||||
current_time = time.time()
|
current_time = time.time()
|
||||||
if self.execution_time == 0 or current_time-self.execution_time >= 180:
|
if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory==True:
|
||||||
self.execution_time = current_time
|
self.execution_time = current_time
|
||||||
log.debug("starting stream for %s buffer, %s account and %s type" % (self.name, self.account, self.type))
|
log.debug("starting stream for %s buffer, %s account and %s type" % (self.name, self.account, self.type))
|
||||||
log.debug("args: %s, kwargs: %s" % (self.args, self.kwargs))
|
log.debug("args: %s, kwargs: %s" % (self.args, self.kwargs))
|
||||||
@@ -896,6 +924,7 @@ class searchPeopleBufferController(peopleBufferController):
|
|||||||
self.put_items_on_list(number_of_items)
|
self.put_items_on_list(number_of_items)
|
||||||
if number_of_items > 0:
|
if number_of_items > 0:
|
||||||
self.session.sound.play("search_updated.ogg")
|
self.session.sound.play("search_updated.ogg")
|
||||||
|
return number_of_items
|
||||||
|
|
||||||
def remove_buffer(self):
|
def remove_buffer(self):
|
||||||
dlg = commonMessageDialogs.remove_buffer()
|
dlg = commonMessageDialogs.remove_buffer()
|
||||||
@@ -1052,6 +1081,7 @@ class conversationBufferController(searchBufferController):
|
|||||||
self.put_items_on_list(number_of_items)
|
self.put_items_on_list(number_of_items)
|
||||||
if number_of_items > 0:
|
if number_of_items > 0:
|
||||||
self.session.sound.play("search_updated.ogg")
|
self.session.sound.play("search_updated.ogg")
|
||||||
|
return number_of_items
|
||||||
|
|
||||||
def remove_buffer(self):
|
def remove_buffer(self):
|
||||||
dlg = commonMessageDialogs.remove_buffer()
|
dlg = commonMessageDialogs.remove_buffer()
|
||||||
|
@@ -118,6 +118,7 @@ class Controller(object):
|
|||||||
pub.subscribe(self.manage_unblocked_user, "unblocked-user")
|
pub.subscribe(self.manage_unblocked_user, "unblocked-user")
|
||||||
pub.subscribe(self.manage_item_in_timeline, "item-in-timeline")
|
pub.subscribe(self.manage_item_in_timeline, "item-in-timeline")
|
||||||
pub.subscribe(self.manage_item_in_list, "item-in-list")
|
pub.subscribe(self.manage_item_in_list, "item-in-list")
|
||||||
|
pub.subscribe(self.restart_streams_, "restart_streams")
|
||||||
widgetUtils.connect_event(self.view, widgetUtils.CLOSE_EVENT, self.exit_)
|
widgetUtils.connect_event(self.view, widgetUtils.CLOSE_EVENT, self.exit_)
|
||||||
|
|
||||||
def bind_other_events(self):
|
def bind_other_events(self):
|
||||||
@@ -179,6 +180,7 @@ class Controller(object):
|
|||||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.view_documentation, self.view.doc)
|
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.add_to_list, self.view.addToList)
|
||||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.remove_from_list, self.view.removeFromList)
|
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.remove_from_list, self.view.removeFromList)
|
||||||
|
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.update_buffer, self.view.update_buffer)
|
||||||
|
|
||||||
def set_systray_icon(self):
|
def set_systray_icon(self):
|
||||||
self.systrayIcon = sysTrayIcon.SysTrayIcon()
|
self.systrayIcon = sysTrayIcon.SysTrayIcon()
|
||||||
@@ -344,6 +346,24 @@ class Controller(object):
|
|||||||
self.view.insert_buffer(tl.buffer, name=_(u"Likes for {}").format(i,), pos=self.view.search("favs_timelines", session.db["user_name"]))
|
self.view.insert_buffer(tl.buffer, name=_(u"Likes for {}").format(i,), pos=self.view.search("favs_timelines", session.db["user_name"]))
|
||||||
tl.timer = RepeatingTimer(300, tl.start_stream)
|
tl.timer = RepeatingTimer(300, tl.start_stream)
|
||||||
tl.timer.start()
|
tl.timer.start()
|
||||||
|
followers_timelines = buffersController.emptyPanel(self.view.nb, "followers_timelines", session.db["user_name"])
|
||||||
|
self.buffers.append(followers_timelines)
|
||||||
|
self.view.insert_buffer(followers_timelines.buffer , name=_(u"Followers' Timelines"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||||
|
for i in session.settings["other_buffers"]["followers_timelines"]:
|
||||||
|
tl = buffersController.peopleBufferController(self.view.nb, "get_followers_list", "%s-followers" % (i,), session, session.db["user_name"], screen_name=i)
|
||||||
|
self.buffers.append(tl)
|
||||||
|
self.view.insert_buffer(tl.buffer, name=_(u"Followers for {}").format(i,), pos=self.view.search("favs_timelines", session.db["user_name"]))
|
||||||
|
tl.timer = RepeatingTimer(300, tl.start_stream)
|
||||||
|
tl.timer.start()
|
||||||
|
friends_timelines = buffersController.emptyPanel(self.view.nb, "friends_timelines", session.db["user_name"])
|
||||||
|
self.buffers.append(friends_timelines)
|
||||||
|
self.view.insert_buffer(friends_timelines.buffer , name=_(u"Followers' Timelines"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||||
|
for i in session.settings["other_buffers"]["friends_timelines"]:
|
||||||
|
tl = buffersController.peopleBufferController(self.view.nb, "get_friends_list", "%s-friends" % (i,), session, session.db["user_name"], screen_name=i)
|
||||||
|
self.buffers.append(tl)
|
||||||
|
self.view.insert_buffer(tl.buffer, name=_(u"Friends for {}").format(i,), pos=self.view.search("favs_timelines", session.db["user_name"]))
|
||||||
|
tl.timer = RepeatingTimer(300, tl.start_stream)
|
||||||
|
tl.timer.start()
|
||||||
lists = buffersController.emptyPanel(self.view.nb, "lists", session.db["user_name"])
|
lists = buffersController.emptyPanel(self.view.nb, "lists", session.db["user_name"])
|
||||||
self.buffers.append(lists)
|
self.buffers.append(lists)
|
||||||
self.view.insert_buffer(lists.buffer , name=_(u"Lists"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
self.view.insert_buffer(lists.buffer , name=_(u"Lists"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||||
@@ -410,13 +430,14 @@ class Controller(object):
|
|||||||
if dlg.get("tweets") == True:
|
if dlg.get("tweets") == True:
|
||||||
if term not in buffer.session.settings["other_buffers"]["tweet_searches"]:
|
if term not in buffer.session.settings["other_buffers"]["tweet_searches"]:
|
||||||
buffer.session.settings["other_buffers"]["tweet_searches"].append(term)
|
buffer.session.settings["other_buffers"]["tweet_searches"].append(term)
|
||||||
search = buffersController.searchBufferController(self.view.nb, "search", "%s-searchterm" % (term,), buffer.session, buffer.session.db["user_name"], bufferType="searchPanel", q=term, count=buffer.session.settings["general"]["max_tweets_per_call"])
|
args = {"lang": dlg.get_language(), "result_type": dlg.get_result_type()}
|
||||||
|
search = buffersController.searchBufferController(self.view.nb, "search", "%s-searchterm" % (term,), buffer.session, buffer.session.db["user_name"], bufferType="searchPanel", q=term, count=buffer.session.settings["general"]["max_tweets_per_call"], **args)
|
||||||
else:
|
else:
|
||||||
log.error("A buffer for the %s search term is already created. You can't create a duplicate buffer." % (term,))
|
log.error("A buffer for the %s search term is already created. You can't create a duplicate buffer." % (term,))
|
||||||
return
|
return
|
||||||
elif dlg.get("users") == True:
|
elif dlg.get("users") == True:
|
||||||
search = buffersController.searchPeopleBufferController(self.view.nb, "search_users", "%s-searchUser" % (term,), buffer.session, buffer.session.db["user_name"], bufferType=None, q=term)
|
search = buffersController.searchPeopleBufferController(self.view.nb, "search_users", "%s-searchUser" % (term,), buffer.session, buffer.session.db["user_name"], bufferType=None, q=term)
|
||||||
search.start_stream()
|
search.start_stream(mandatory=True)
|
||||||
pos=self.view.search("searches", buffer.session.db["user_name"])
|
pos=self.view.search("searches", buffer.session.db["user_name"])
|
||||||
self.insert_buffer(search, pos)
|
self.insert_buffer(search, pos)
|
||||||
self.view.insert_buffer(search.buffer, name=_(u"Search for {}").format(term), pos=pos)
|
self.view.insert_buffer(search.buffer, name=_(u"Search for {}").format(term), pos=pos)
|
||||||
@@ -759,7 +780,8 @@ class Controller(object):
|
|||||||
return
|
return
|
||||||
answer = commonMessageDialogs.protected_user()
|
answer = commonMessageDialogs.protected_user()
|
||||||
if answer == widgetUtils.NO: return
|
if answer == widgetUtils.NO: return
|
||||||
if dlg.get_action() == "tweets":
|
tl_type = dlg.get_action()
|
||||||
|
if tl_type == "tweets":
|
||||||
if usr["statuses_count"] == 0:
|
if usr["statuses_count"] == 0:
|
||||||
commonMessageDialogs.no_tweets()
|
commonMessageDialogs.no_tweets()
|
||||||
return
|
return
|
||||||
@@ -775,7 +797,7 @@ class Controller(object):
|
|||||||
buff.session.settings["other_buffers"]["timelines"].append(dlg.get_user())
|
buff.session.settings["other_buffers"]["timelines"].append(dlg.get_user())
|
||||||
pub.sendMessage("restart-streams", streams=["timelinesStream"], session=buff.session)
|
pub.sendMessage("restart-streams", streams=["timelinesStream"], session=buff.session)
|
||||||
buff.session.sound.play("create_timeline.ogg")
|
buff.session.sound.play("create_timeline.ogg")
|
||||||
else:
|
elif tl_type == "favourites":
|
||||||
if usr["favourites_count"] == 0:
|
if usr["favourites_count"] == 0:
|
||||||
commonMessageDialogs.no_favs()
|
commonMessageDialogs.no_favs()
|
||||||
return
|
return
|
||||||
@@ -792,6 +814,40 @@ class Controller(object):
|
|||||||
tl.timer.start()
|
tl.timer.start()
|
||||||
buff.session.settings["other_buffers"]["favourites_timelines"].append(dlg.get_user())
|
buff.session.settings["other_buffers"]["favourites_timelines"].append(dlg.get_user())
|
||||||
buff.session.sound.play("create_timeline.ogg")
|
buff.session.sound.play("create_timeline.ogg")
|
||||||
|
elif tl_type == "followers":
|
||||||
|
if usr["followers_count"] == 0:
|
||||||
|
commonMessageDialogs.no_followers()
|
||||||
|
return
|
||||||
|
if dlg.get_user() in buff.session.settings["other_buffers"]["followers_timelines"]:
|
||||||
|
commonMessageDialogs.timeline_exist()
|
||||||
|
return
|
||||||
|
tl = buffersController.peopleBufferController(self.view.nb, "get_followers_list", "%s-followers" % (dlg.get_user(),), buff.session, buff.session.db["user_name"], screen_name=dlg.get_user())
|
||||||
|
pos=self.view.search("followers_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"Followers for {}").format(dlg.get_user()), pos=pos)
|
||||||
|
tl.start_stream()
|
||||||
|
tl.timer = RepeatingTimer(300, tl.start_stream)
|
||||||
|
tl.timer.start()
|
||||||
|
buff.session.settings["other_buffers"]["followers_timelines"].append(dlg.get_user())
|
||||||
|
buff.session.sound.play("create_timeline.ogg")
|
||||||
|
|
||||||
|
elif tl_type == "friends":
|
||||||
|
if usr["friends_count"] == 0:
|
||||||
|
commonMessageDialogs.no_friends()
|
||||||
|
return
|
||||||
|
if dlg.get_user() in buff.session.settings["other_buffers"]["friends_timelines"]:
|
||||||
|
commonMessageDialogs.timeline_exist()
|
||||||
|
return
|
||||||
|
tl = buffersController.peopleBufferController(self.view.nb, "get_friends_list", "%s-friends" % (dlg.get_user(),), buff.session, buff.session.db["user_name"], screen_name=dlg.get_user())
|
||||||
|
pos=self.view.search("friends_timelines", buff.session.db["user_name"])
|
||||||
|
self.insert_buffer(tl, pos+1)
|
||||||
|
self.view.insert_buffer(buffer=tl.buffer, name=_(u"Friends for {}").format(dlg.get_user()), pos=pos)
|
||||||
|
tl.start_stream()
|
||||||
|
tl.timer = RepeatingTimer(300, tl.start_stream)
|
||||||
|
tl.timer.start()
|
||||||
|
buff.session.settings["other_buffers"]["friends_timelines"].append(dlg.get_user())
|
||||||
|
buff.session.sound.play("create_timeline.ogg")
|
||||||
else:
|
else:
|
||||||
commonMessageDialogs.user_not_exist()
|
commonMessageDialogs.user_not_exist()
|
||||||
|
|
||||||
@@ -1405,5 +1461,21 @@ class Controller(object):
|
|||||||
if hasattr(self, action):
|
if hasattr(self, action):
|
||||||
getattr(self, action)()
|
getattr(self, action)()
|
||||||
|
|
||||||
|
def restart_streams_(self, session):
|
||||||
|
for i in self.buffers:
|
||||||
|
if i.session != None and i.session.session_id == session:
|
||||||
|
i.start_stream()
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
config.app.write()
|
config.app.write()
|
||||||
|
|
||||||
|
def update_buffer(self, *args, **kwargs):
|
||||||
|
bf = self.get_current_buffer()
|
||||||
|
if not hasattr(bf, "start_stream"):
|
||||||
|
output.speak(_(u"Unable to update this buffer."))
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
output.speak(_(u"Updating buffer..."))
|
||||||
|
n = bf.start_stream(mandatory=True)
|
||||||
|
if n != None:
|
||||||
|
output.speak(_(u"{0} items retrieved").format(n,))
|
@@ -35,7 +35,7 @@ class basicTweet(object):
|
|||||||
def translate(self, event=None):
|
def translate(self, event=None):
|
||||||
dlg = translator.gui.translateDialog()
|
dlg = translator.gui.translateDialog()
|
||||||
if dlg.get_response() == widgetUtils.OK:
|
if dlg.get_response() == widgetUtils.OK:
|
||||||
text_to_translate = self.message.get_text().encode("utf-8")
|
text_to_translate = self.message.get_text()
|
||||||
source = [x[0] for x in translator.translator.available_languages()][dlg.get("source_lang")]
|
source = [x[0] for x in translator.translator.available_languages()][dlg.get("source_lang")]
|
||||||
dest = [x[0] for x in translator.translator.available_languages()][dlg.get("dest_lang")]
|
dest = [x[0] for x in translator.translator.available_languages()][dlg.get("dest_lang")]
|
||||||
msg = translator.translator.translate(text=text_to_translate, source=source, target=dest)
|
msg = translator.translator.translate(text=text_to_translate, source=source, target=dest)
|
||||||
|
@@ -1,153 +1,10 @@
|
|||||||
# encoding: utf-8
|
# -*- coding: utf-8 -*-
|
||||||
#
|
from microsofttranslator import Translator
|
||||||
# Copyright (C) 2013 Mesar Hameed <mhameed@src.gnome.org>
|
|
||||||
# This file is covered by the GNU General Public License.
|
|
||||||
|
|
||||||
import os
|
def translate(text="", source="auto", target="en"):
|
||||||
import re
|
t = Translator("twblue", "4KZA26GYIfmVAqQA/z16Hlucbg64hVSDTIpRjT2FqIU=")
|
||||||
import sys
|
return t.translate(text, target)
|
||||||
import threading
|
|
||||||
from time import sleep
|
|
||||||
from random import randint
|
|
||||||
import logging
|
|
||||||
log = logging.getLogger("translator")
|
|
||||||
import urllib2
|
|
||||||
|
|
||||||
# Each group has to be a class of possible breaking points for the writing script.
|
|
||||||
# Usually this is the major syntax marks, such as:
|
|
||||||
# full stop, comma, exclaim, question, etc.
|
|
||||||
arabicBreaks = u'[،؛؟]'
|
|
||||||
# Thanks to Talori in the NVDA irc room:
|
|
||||||
# U+3000 to U+303F, U+FE10 to U+FE1F, U+FE30 to U+FE6F, U+FF01 to U+FF60
|
|
||||||
chineseBreaks = u'[ -〿︐-︰-!-⦆]'
|
|
||||||
latinBreaks = r'[.,!?;:\n]'
|
|
||||||
splitReg = re.compile(u"{arabic}|{chinese}|{latin}".format(arabic=arabicBreaks, chinese=chineseBreaks, latin=latinBreaks))
|
|
||||||
|
|
||||||
def translate(text, source="auto", target="en"):
|
|
||||||
if source == "": source = "auto"
|
|
||||||
t = Translator(lang_from=source, lang_to=target, text=text)
|
|
||||||
t.start()
|
|
||||||
while t.isAlive():
|
|
||||||
sleep(0.1)
|
|
||||||
t.join()
|
|
||||||
return t.translation
|
|
||||||
|
|
||||||
def splitChunks(text, chunksize):
|
|
||||||
pos = 0
|
|
||||||
potentialPos = 0
|
|
||||||
for splitMark in splitReg.finditer(text):
|
|
||||||
if (splitMark.start() - pos +1) < chunksize:
|
|
||||||
potentialPos = splitMark.start()
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
yield text[pos:potentialPos+1]
|
|
||||||
pos = potentialPos + 1
|
|
||||||
potentialPos = splitMark.start()
|
|
||||||
yield text[pos:]
|
|
||||||
|
|
||||||
class Translator(threading.Thread):
|
|
||||||
|
|
||||||
def __init__(self, lang_from, lang_to, text, lang_swap=None, chunksize=350, *args, **kwargs):
|
|
||||||
super(Translator, self).__init__(*args, **kwargs)
|
|
||||||
self._stop = threading.Event()
|
|
||||||
self.text = text
|
|
||||||
self.chunksize = chunksize
|
|
||||||
self.lang_to = lang_to
|
|
||||||
self.lang_from = lang_from
|
|
||||||
self.lang_swap = lang_swap
|
|
||||||
self.translation = ''
|
|
||||||
self.lang_translated = ''
|
|
||||||
self.firstChunk = True
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
self._stop.set()
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
for chunk in splitChunks(self.text, self.chunksize):
|
|
||||||
# Make sure we don't send requests to google too often.
|
|
||||||
# Try to simulate a human.
|
|
||||||
if not self.firstChunk:
|
|
||||||
sleep(randint(1, 10))
|
|
||||||
req = self.buildRequest(chunk, self.lang_from, self.lang_to)
|
|
||||||
try:
|
|
||||||
response = urllib2.urlopen(req)
|
|
||||||
translation, lang_translated = self.parseData(response)
|
|
||||||
if self.firstChunk and self.lang_from == "auto" and lang_translated == self.lang_to and self.lang_swap is not None:
|
|
||||||
self.lang_to = self.lang_swap
|
|
||||||
self.firstChunk = False
|
|
||||||
req = self.buildRequest(chunk.encode('utf-8'), self.lang_from, self.lang_to)
|
|
||||||
response = urllib2.urlopen(req)
|
|
||||||
translation, lang_translated = self.parseData(response)
|
|
||||||
except Exception as e:
|
|
||||||
log.exception("Can not translate text '%s'" %chunk)
|
|
||||||
# We have probably been blocked, so stop trying to translate.
|
|
||||||
raise e
|
|
||||||
self.translation += translation
|
|
||||||
# some adjustment, better to do on full text
|
|
||||||
self.translation = self.fixNewlines(self.translation)
|
|
||||||
self.lang_translated = lang_translated
|
|
||||||
|
|
||||||
def buildRequest(self, text, lang_from, lang_to):
|
|
||||||
"""Build POST request which will be sent to Google."""
|
|
||||||
urlTemplate = 'http://translate.google.com/translate_a/single?client=t&sl={lang_from}&tl={lang_to}&ie=utf-8&oe=utf-8&dt=t&dt=bd&tk='
|
|
||||||
url = urlTemplate.format(lang_from=lang_from, lang_to=lang_to)
|
|
||||||
header = {'User-agent': 'Mozilla/5.0', 'Content-Type': 'application/x-www-form-urlencoded'}
|
|
||||||
data = 'text=%s' %urllib2.quote(text)
|
|
||||||
req = urllib2.Request(url, data, header)
|
|
||||||
return req
|
|
||||||
|
|
||||||
def parseData(self, response):
|
|
||||||
"""Parse unstructured response."""
|
|
||||||
data = response.readlines()[0]
|
|
||||||
# get segments with couples ["translation","original text"]
|
|
||||||
l1, l2 = data.split(']],', 1)
|
|
||||||
translation = l1[3:]
|
|
||||||
if l2.startswith('[[\"'):
|
|
||||||
# get list of synonyms
|
|
||||||
syn = l2[l2.find(',[')+1:l2.find(']')].split(',')
|
|
||||||
temp = ', '.join([x.replace('\"', '') for x in syn])
|
|
||||||
else:
|
|
||||||
# get a list with each couple as item
|
|
||||||
sentences = translation.split('],[')
|
|
||||||
temp = ''
|
|
||||||
# get translation, removing first char (quote symbol)
|
|
||||||
for item in sentences:
|
|
||||||
item = item.split('\",\"', 1)[0][1:]
|
|
||||||
# join all translations
|
|
||||||
temp = ' '.join([temp, item])
|
|
||||||
translation = temp.decode('string-escape').decode('utf-8')
|
|
||||||
translation = self.fixPunctuation(translation)
|
|
||||||
# get the language of original text
|
|
||||||
tempLang = data.partition(']],,\"')[2]
|
|
||||||
lang = tempLang[:tempLang.find('\"')]
|
|
||||||
if lang == '':
|
|
||||||
lang = _("unavailable")
|
|
||||||
return translation, lang
|
|
||||||
|
|
||||||
def fixPunctuation(self, translation):
|
|
||||||
"""Clean text from space before punctuation symbol."""
|
|
||||||
# list of potentially positions of spaces to remove
|
|
||||||
spacePos = []
|
|
||||||
for puncMark in splitReg.finditer(translation):
|
|
||||||
spacePos.append(puncMark.start()-1)
|
|
||||||
if len(spacePos) == 0:
|
|
||||||
return translation
|
|
||||||
fixedTranslation = ''
|
|
||||||
for n in xrange(0,len(translation)):
|
|
||||||
temp = translation[n]
|
|
||||||
if n in spacePos and temp == ' ':
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
fixedTranslation += temp
|
|
||||||
return fixedTranslation
|
|
||||||
|
|
||||||
def fixNewlines(self, translation):
|
|
||||||
"""Adjust newlines and (subsequent or double) spaces."""
|
|
||||||
fixes = [('\r\n ', '\r\n'), ('\n ', '\r\n'), (' ', ' ')]
|
|
||||||
for fix in fixes:
|
|
||||||
translation = translation.replace(fix[0], fix[1])
|
|
||||||
# first char is a space, so...
|
|
||||||
return translation[1:]
|
|
||||||
|
|
||||||
languages = {
|
languages = {
|
||||||
"af": _(u"Afrikaans"),
|
"af": _(u"Afrikaans"),
|
||||||
|
@@ -32,3 +32,4 @@ check_for_updates = string(default="alt+win+u)
|
|||||||
list_manager = string(default="control+win+shift+l")
|
list_manager = string(default="control+win+shift+l")
|
||||||
configuration = string(default="control+win+o")
|
configuration = string(default="control+win+o")
|
||||||
accountConfiguration = string(default="control+win+shift+o")
|
accountConfiguration = string(default="control+win+shift+o")
|
||||||
|
update_buffer = string(default="control+win+shift+u")
|
@@ -51,3 +51,4 @@ check_for_updates = string(default="control+win+u")
|
|||||||
list_manager = string(default="control+win+shift+l")
|
list_manager = string(default="control+win+shift+l")
|
||||||
configuration = string(default="control+win+o")
|
configuration = string(default="control+win+o")
|
||||||
accountConfiguration = string(default="control+win+shift+o")
|
accountConfiguration = string(default="control+win+shift+o")
|
||||||
|
update_buffer = string(default="control+win+shift+u")
|
@@ -30,8 +30,8 @@ volume_up = string(default="alt+win+shift+up")
|
|||||||
go_home = string(default="alt+win+home")
|
go_home = string(default="alt+win+home")
|
||||||
volume_down = string(default="alt+win+shift+down")
|
volume_down = string(default="alt+win+shift+down")
|
||||||
go_end = string(default="alt+win+end")
|
go_end = string(default="alt+win+end")
|
||||||
go_page_up = string(default="alt+win+pageup")
|
go_page_up = string(default="control+win+pageup")
|
||||||
go_page_down = string(default="alt+win+pagedown")
|
go_page_down = string(default="control+win+pagedown")
|
||||||
update_profile = string(default="alt+win+p")
|
update_profile = string(default="alt+win+p")
|
||||||
delete = string(default="alt+win+delete")
|
delete = string(default="alt+win+delete")
|
||||||
clear_buffer = string(default="alt+win+shift+delete")
|
clear_buffer = string(default="alt+win+shift+delete")
|
||||||
@@ -53,3 +53,4 @@ check_for_updates = string(default="alt+win+u")
|
|||||||
list_manager = string(default="alt+win+shift+l")
|
list_manager = string(default="alt+win+shift+l")
|
||||||
configuration = string(default="control+win+o")
|
configuration = string(default="control+win+o")
|
||||||
accountConfiguration = string(default="control+win+shift+o")
|
accountConfiguration = string(default="control+win+shift+o")
|
||||||
|
update_buffer = string(default="control+alt+shift+u")
|
@@ -54,3 +54,4 @@ check_for_updates = string(default="control+win+u")
|
|||||||
list_manager = string(default="control+win+shift+l")
|
list_manager = string(default="control+win+shift+l")
|
||||||
configuration = string(default="control+win+o")
|
configuration = string(default="control+win+o")
|
||||||
accountConfiguration = string(default="control+win+shift+o")
|
accountConfiguration = string(default="control+win+shift+o")
|
||||||
|
update_buffer = string(default="control+win+shift+u")
|
@@ -54,3 +54,4 @@ check_for_updates = string(default="control+win+u")
|
|||||||
list_manager = string(default="control+win+shift+l")
|
list_manager = string(default="control+win+shift+l")
|
||||||
configuration = string(default="control+win+o")
|
configuration = string(default="control+win+o")
|
||||||
accountConfiguration = string(default="control+win+shift+o")
|
accountConfiguration = string(default="control+win+shift+o")
|
||||||
|
update_buffer = string(default="control+win+shift+u")
|
@@ -50,4 +50,6 @@ actions = {
|
|||||||
"lists_manager": _(u"Opens the list manager, which allows you to create, edit, delete and open lists in buffers."),
|
"lists_manager": _(u"Opens the list manager, which allows you to create, edit, delete and open lists in buffers."),
|
||||||
"configuration": _(u"Opens the global settings dialogue"),
|
"configuration": _(u"Opens the global settings dialogue"),
|
||||||
"accountConfiguration": _(u"Opens the account settings dialogue"),
|
"accountConfiguration": _(u"Opens the account settings dialogue"),
|
||||||
|
"audio": _(u"Try to play an audio file"),
|
||||||
|
"update_buffer": _(u"Updates the buffer and retrieves possible lost items there."),
|
||||||
}
|
}
|
@@ -37,12 +37,9 @@ class KeystrokeEditor(object):
|
|||||||
|
|
||||||
def get_edited_keystroke(self, dialog):
|
def get_edited_keystroke(self, dialog):
|
||||||
keys = []
|
keys = []
|
||||||
if dialog.get("win") == False:
|
|
||||||
wx_ui.no_win_message()
|
|
||||||
return
|
|
||||||
if dialog.get("control") == True:
|
if dialog.get("control") == True:
|
||||||
keys.append("control")
|
keys.append("control")
|
||||||
# if dialog.get("win") == True:
|
if dialog.get("win") == True:
|
||||||
keys.append("win")
|
keys.append("win")
|
||||||
if dialog.get("alt") == True:
|
if dialog.get("alt") == True:
|
||||||
keys.append("alt")
|
keys.append("alt")
|
||||||
|
@@ -55,7 +55,8 @@ def data_path(app_name='TW blue'):
|
|||||||
# data_path = os.path.join(shlobj.SHGetFolderPath(0, shlobj.CSIDL_APPDATA), app_name)
|
# data_path = os.path.join(shlobj.SHGetFolderPath(0, shlobj.CSIDL_APPDATA), app_name)
|
||||||
# else:
|
# else:
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
data_path = os.path.join(os.getenv("AppData"), app_name)
|
import winpaths
|
||||||
|
data_path = os.path.join(winpaths.get_appdata(), app_name)
|
||||||
else:
|
else:
|
||||||
data_path = os.path.join(os.environ['HOME'], ".%s" % app_name)
|
data_path = os.path.join(os.environ['HOME'], ".%s" % app_name)
|
||||||
if not os.path.exists(data_path):
|
if not os.path.exists(data_path):
|
||||||
|
@@ -194,6 +194,7 @@ class Session(object):
|
|||||||
if report_success:
|
if report_success:
|
||||||
output.speak(_("%s succeeded.") % action)
|
output.speak(_("%s succeeded.") % action)
|
||||||
if _sound != None: self.sound.play(_sound)
|
if _sound != None: self.sound.play(_sound)
|
||||||
|
return val
|
||||||
|
|
||||||
def search(self, name, *args, **kwargs):
|
def search(self, name, *args, **kwargs):
|
||||||
tl = self.twitter.twitter.search(*args, **kwargs)
|
tl = self.twitter.twitter.search(*args, **kwargs)
|
||||||
@@ -278,8 +279,7 @@ class Session(object):
|
|||||||
tl = self.call_paged(function, sinze_id=last_id, *args, **kwargs)
|
tl = self.call_paged(function, sinze_id=last_id, *args, **kwargs)
|
||||||
self.order_buffer(name, tl)
|
self.order_buffer(name, tl)
|
||||||
|
|
||||||
@_require_login
|
def get_cursored_stream(self, name, function, items="users", get_previous=False, *args, **kwargs):
|
||||||
def get_cursored_stream(self, name, function, items="users", *args, **kwargs):
|
|
||||||
|
|
||||||
""" Gets items for API calls that require using cursors to paginate the results.
|
""" Gets items for API calls that require using cursors to paginate the results.
|
||||||
name str: Name to save it in the database.
|
name str: Name to save it in the database.
|
||||||
@@ -289,7 +289,7 @@ class Session(object):
|
|||||||
|
|
||||||
items_ = []
|
items_ = []
|
||||||
try:
|
try:
|
||||||
if self.db[name].has_key("cursor"):
|
if self.db[name].has_key("cursor") and get_previous:
|
||||||
cursor = self.db[name]["cursor"]
|
cursor = self.db[name]["cursor"]
|
||||||
else:
|
else:
|
||||||
cursor = -1
|
cursor = -1
|
||||||
@@ -352,7 +352,7 @@ class Session(object):
|
|||||||
self.logged = False
|
self.logged = False
|
||||||
self.twitter = twitter.twitter.twitter()
|
self.twitter = twitter.twitter.twitter()
|
||||||
self.login(False)
|
self.login(False)
|
||||||
# pub.sendMessage("streamError", session=self.session_id)
|
pub.sendMessage("restart_streams", session=self.session_id)
|
||||||
if self.reconnection_function_active == True: return
|
if self.reconnection_function_active == True: return
|
||||||
self.reconnection_function_active = True
|
self.reconnection_function_active = True
|
||||||
if not hasattr(self, "main_stream"):
|
if not hasattr(self, "main_stream"):
|
||||||
|
@@ -87,11 +87,11 @@ class streamer(TwythonStreamer):
|
|||||||
pub.sendMessage("mention", data=data, user=self.get_user())
|
pub.sendMessage("mention", data=data, user=self.get_user())
|
||||||
|
|
||||||
def process_dm(self, data):
|
def process_dm(self, data):
|
||||||
if self.session.db["user_name"] == data["direct_message"]["sender"]["screen_name"]:
|
if self.session.db["user_name"] != data["direct_message"]["sender"]["screen_name"]:
|
||||||
d = self.put_data("sent_direct_messages", data["direct_message"])
|
# d = self.put_data("sent_direct_messages", data["direct_message"])
|
||||||
if d != False:
|
# if d != False:
|
||||||
pub.sendMessage("sent-dm", data=data["direct_message"], user=self.get_user())
|
# pub.sendMessage("sent-dm", data=data["direct_message"], user=self.get_user())
|
||||||
else:
|
# else:
|
||||||
d = self.put_data("direct_messages", data["direct_message"])
|
d = self.put_data("direct_messages", data["direct_message"])
|
||||||
if d != False:
|
if d != False:
|
||||||
pub.sendMessage("direct-message", data=data["direct_message"], user=self.get_user())
|
pub.sendMessage("direct-message", data=data["direct_message"], user=self.get_user())
|
||||||
|
@@ -58,3 +58,9 @@ def no_tweets():
|
|||||||
|
|
||||||
def no_favs():
|
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()
|
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()
|
||||||
|
|
||||||
|
def no_followers():
|
||||||
|
return wx.MessageDialog(None, _(u"This user has no followers. {0} can't create a timeline.").format(application.name), _(u"Error"), wx.ICON_ERROR).ShowModal()
|
||||||
|
|
||||||
|
def no_friends():
|
||||||
|
return wx.MessageDialog(None, _(u"This user has no friends. {0} can't create a timeline.").format(application.name), _(u"Error"), wx.ICON_ERROR).ShowModal()
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
import widgetUtils
|
||||||
import baseDialog
|
import baseDialog
|
||||||
import wx
|
import wx
|
||||||
|
from extra import translator
|
||||||
|
|
||||||
class searchDialog(baseDialog.BaseWXDialog):
|
class searchDialog(baseDialog.BaseWXDialog):
|
||||||
def __init__(self, value=""):
|
def __init__(self, value=""):
|
||||||
@@ -17,10 +19,27 @@ class searchDialog(baseDialog.BaseWXDialog):
|
|||||||
sizer.Add(self.term, 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.tweets = wx.RadioButton(panel, -1, _(u"Tweets"), style=wx.RB_GROUP)
|
||||||
self.users = wx.RadioButton(panel, -1, _(u"Users"))
|
self.users = wx.RadioButton(panel, -1, _(u"Users"))
|
||||||
|
widgetUtils.connect_event(self.tweets, widgetUtils.RADIOBUTTON, self.show_advanced_search)
|
||||||
|
widgetUtils.connect_event(self.users, widgetUtils.RADIOBUTTON, self.hide_advanced_search)
|
||||||
radioSizer = wx.BoxSizer(wx.HORIZONTAL)
|
radioSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
radioSizer.Add(self.tweets, 0, wx.ALL, 5)
|
radioSizer.Add(self.tweets, 0, wx.ALL, 5)
|
||||||
radioSizer.Add(self.users, 0, wx.ALL, 5)
|
radioSizer.Add(self.users, 0, wx.ALL, 5)
|
||||||
sizer.Add(radioSizer, 0, wx.ALL, 5)
|
sizer.Add(radioSizer, 0, wx.ALL, 5)
|
||||||
|
lang = wx.StaticText(panel, -1, _(u"Language for results: "))
|
||||||
|
langs = [x[1] for x in translator.translator.available_languages()]
|
||||||
|
langs[:] = langs[1:]
|
||||||
|
langs.insert(0, _(u"any"))
|
||||||
|
self.lang = wx.ComboBox(panel, -1, choices=langs, value=langs[0], style = wx.CB_READONLY)
|
||||||
|
langBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
langBox.Add(lang, 0, wx.ALL, 5)
|
||||||
|
langBox.Add(self.lang, 0, wx.ALL, 5)
|
||||||
|
sizer.Add(langBox, 0, wx.ALL, 5)
|
||||||
|
resulttype = wx.StaticText(panel, -1, _(U"Results type: "))
|
||||||
|
self.resultstype = wx.ComboBox(panel, -1, choices=[_(u"Mixed"), _(u"Recent"), _(u"Popular")], value=_(u"Mixed"), style=wx.CB_READONLY)
|
||||||
|
rBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
rBox.Add(resulttype, 0, wx.ALL, 5)
|
||||||
|
rBox.Add(self.resultstype, 0, wx.ALL, 5)
|
||||||
|
sizer.Add(rBox, 0, wx.ALL, 5)
|
||||||
ok = wx.Button(panel, wx.ID_OK, _(u"OK"))
|
ok = wx.Button(panel, wx.ID_OK, _(u"OK"))
|
||||||
ok.SetDefault()
|
ok.SetDefault()
|
||||||
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"Close"))
|
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"Close"))
|
||||||
@@ -30,3 +49,20 @@ class searchDialog(baseDialog.BaseWXDialog):
|
|||||||
sizer.Add(btnsizer, 0, wx.ALL, 5)
|
sizer.Add(btnsizer, 0, wx.ALL, 5)
|
||||||
panel.SetSizer(sizer)
|
panel.SetSizer(sizer)
|
||||||
self.SetClientSize(sizer.CalcMin())
|
self.SetClientSize(sizer.CalcMin())
|
||||||
|
|
||||||
|
def get_language(self):
|
||||||
|
return [x[0] for x in translator.translator.available_languages()][self.lang.GetSelection()]
|
||||||
|
|
||||||
|
def get_result_type(self):
|
||||||
|
r = self.resultstype.GetValue()
|
||||||
|
if r == _(u"Mixed"): return "mixed"
|
||||||
|
elif r == _(u"Recent"): return "recent"
|
||||||
|
elif r == _(u"Popular"): return "popular"
|
||||||
|
|
||||||
|
def hide_advanced_search(self, *args, **kwargs):
|
||||||
|
self.lang.Hide()
|
||||||
|
self.resultstype.Hide()
|
||||||
|
|
||||||
|
def show_advanced_search(self, *args, **kwargs):
|
||||||
|
self.lang.Show()
|
||||||
|
self.resultstype.Show()
|
||||||
|
@@ -18,11 +18,15 @@ class selectUserDialog(wx.Dialog):
|
|||||||
label2 = wx.StaticText(panel, -1, _(u"Buffer type"))
|
label2 = wx.StaticText(panel, -1, _(u"Buffer type"))
|
||||||
self.tweets = wx.RadioButton(panel, -1, _(u"Tweets"), style=wx.RB_GROUP)
|
self.tweets = wx.RadioButton(panel, -1, _(u"Tweets"), style=wx.RB_GROUP)
|
||||||
self.favourites = wx.RadioButton(panel, -1, _(u"Likes"))
|
self.favourites = wx.RadioButton(panel, -1, _(u"Likes"))
|
||||||
|
self.followers = wx.RadioButton(panel, -1, _(u"Followers"))
|
||||||
|
self.friends = wx.RadioButton(panel, -1, _(u"Friends"))
|
||||||
self.setup_default(default)
|
self.setup_default(default)
|
||||||
hSizer = wx.BoxSizer(wx.HORIZONTAL)
|
hSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
hSizer.Add(label2, 0, wx.ALL, 5)
|
hSizer.Add(label2, 0, wx.ALL, 5)
|
||||||
actionSizer.Add(self.tweets, 0, wx.ALL, 5)
|
actionSizer.Add(self.tweets, 0, wx.ALL, 5)
|
||||||
actionSizer.Add(self.favourites, 0, wx.ALL, 5)
|
actionSizer.Add(self.favourites, 0, wx.ALL, 5)
|
||||||
|
actionSizer.Add(self.followers, 0, wx.ALL, 5)
|
||||||
|
actionSizer.Add(self.friends, 0, wx.ALL, 5)
|
||||||
hSizer.Add(actionSizer, 0, wx.ALL, 5)
|
hSizer.Add(actionSizer, 0, wx.ALL, 5)
|
||||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
ok = wx.Button(panel, wx.ID_OK, _(u"OK"))
|
ok = wx.Button(panel, wx.ID_OK, _(u"OK"))
|
||||||
@@ -39,6 +43,8 @@ class selectUserDialog(wx.Dialog):
|
|||||||
def get_action(self):
|
def get_action(self):
|
||||||
if self.tweets.GetValue() == True: return "tweets"
|
if self.tweets.GetValue() == True: return "tweets"
|
||||||
elif self.favourites.GetValue() == True: return "favourites"
|
elif self.favourites.GetValue() == True: return "favourites"
|
||||||
|
elif self.followers.GetValue() == True: return "followers"
|
||||||
|
elif self.friends.GetValue() == True: return "friends"
|
||||||
|
|
||||||
def setup_default(self, default):
|
def setup_default(self, default):
|
||||||
if default == "tweets":
|
if default == "tweets":
|
||||||
|
@@ -47,6 +47,7 @@ class mainFrame(wx.Frame):
|
|||||||
|
|
||||||
# buffer menu
|
# buffer menu
|
||||||
buffer = wx.Menu()
|
buffer = wx.Menu()
|
||||||
|
self.update_buffer = buffer.Append(wx.NewId(), _(u"&Update buffer"))
|
||||||
self.trends = buffer.Append(wx.NewId(), _(u"New &trending topics buffer..."))
|
self.trends = buffer.Append(wx.NewId(), _(u"New &trending topics buffer..."))
|
||||||
self.find = buffer.Append(wx.NewId(), _(u"Find a string in the currently focused buffer..."))
|
self.find = buffer.Append(wx.NewId(), _(u"Find a string in the currently focused buffer..."))
|
||||||
self.load_previous_items = buffer.Append(wx.NewId(), _(u"&Load previous items"))
|
self.load_previous_items = buffer.Append(wx.NewId(), _(u"&Load previous items"))
|
||||||
|
Submodule windows-dependencies updated: 571c37bbc1...baa04ec845
Reference in New Issue
Block a user