mirror of
https://github.com/MCV-Software/TWBlue.git
synced 2025-08-25 17:39:23 +00:00
Compare commits
88 Commits
Author | SHA1 | Date | |
---|---|---|---|
375cdd2528 | |||
![]() |
836675bfa1 | ||
![]() |
2b3c7601f2 | ||
eb2c315abb | |||
e12f440cf2 | |||
![]() |
57dc271fb0 | ||
193cafcc9d | |||
![]() |
e7b6c39f76 | ||
7df2441442 | |||
![]() |
aa687450f6 | ||
6e0ae38d4e | |||
![]() |
fa8c9f639c | ||
9502cef251 | |||
![]() |
982dd78f81 | ||
![]() |
4b98f27968 | ||
![]() |
ecb0fa8f2b | ||
ef2ff9dbfc | |||
![]() |
1fe94642a2 | ||
b232a0b0ad | |||
2ce59cf208 | |||
![]() |
ceb8266828 | ||
![]() |
21970f2c94 | ||
14965f73d3 | |||
![]() |
267b454fc6 | ||
c3dc00c241 | |||
![]() |
9fb67f01ae | ||
6d1cd0b1fc | |||
a7ef572d05 | |||
403784b77a | |||
d032a6d8f7 | |||
![]() |
231d43ab22 | ||
5e3bcfc82e | |||
8e92d97260 | |||
bb1ffa9ff1 | |||
104bc4ec8c | |||
![]() |
6ae555fe72 | ||
![]() |
dd51516c30 | ||
![]() |
4e18bb0721 | ||
![]() |
0492e65aa0 | ||
![]() |
a5fb59d7a7 | ||
f2fab29cb7 | |||
![]() |
f36accf89b | ||
a13536233e | |||
bc2d448464 | |||
60ec9ab215 | |||
20b5fc079b | |||
80e231b689 | |||
7137d437bd | |||
![]() |
a07b3c1829 | ||
![]() |
c062c10542 | ||
![]() |
0e7c070bd4 | ||
![]() |
9f35d079b1 | ||
![]() |
a3fca4d2a0 | ||
ada6f1fb0d | |||
79124810b0 | |||
fee7254d55 | |||
![]() |
c12902d011 | ||
2f7eb12104 | |||
855cefeb8d | |||
e649b883c6 | |||
![]() |
1a61f2d790 | ||
![]() |
6abfba317a | ||
![]() |
18ce92daab | ||
![]() |
84f729f42b | ||
![]() |
4e7666cf52 | ||
88e0fbb531 | |||
af32b3ceb6 | |||
94dc083650 | |||
acb3cce1d6 | |||
![]() |
2b3e1099f6 | ||
![]() |
60507e8f6b | ||
![]() |
75bfc17bb1 | ||
acb8c5acd3 | |||
![]() |
5bcf04fc94 | ||
0f2fbc775a | |||
1b684cd12c | |||
9d64901791 | |||
18f7cb6c96 | |||
7f673fb9de | |||
![]() |
f6f542fbec | ||
![]() |
a211e2e5e4 | ||
3ec8ac31a5 | |||
![]() |
dacbb19586 | ||
![]() |
55691cca20 | ||
0104b97df0 | |||
aa58e61e5e | |||
![]() |
fae204f3c2 | ||
d8149a4c96 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,12 +1,8 @@
|
|||||||
*.pyc
|
*.pyc
|
||||||
*~
|
*~
|
||||||
windows-dependencies/*
|
|
||||||
src/build/
|
src/build/
|
||||||
src/dist/
|
src/dist/
|
||||||
src/config/
|
src/config/
|
||||||
src/config1/
|
|
||||||
src/config2/
|
|
||||||
src/config3/
|
|
||||||
src/dropbox/
|
src/dropbox/
|
||||||
src/logs/
|
src/logs/
|
||||||
src/documentation/
|
src/documentation/
|
||||||
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "windows-dependencies"]
|
||||||
|
path = windows-dependencies
|
||||||
|
url = https://github.com/jmdaweb/TWBlue_deps_windows.git
|
56
README.md
56
README.md
@@ -15,4 +15,58 @@ TW Blue is an app designed to use Twitter in a simple and fast way and avoiding,
|
|||||||
* Play various file and URL types which contain audio
|
* Play various file and URL types which contain audio
|
||||||
* and more!
|
* and more!
|
||||||
|
|
||||||
See the [TWBlue's webpage](http://twblue.com.mx) for more details.
|
See the [TWBlue's webpage](http://twblue.com.mx) for more details.
|
||||||
|
|
||||||
|
## Using TWBlue from sources
|
||||||
|
|
||||||
|
This document describes how to run tw blue from source, and, after that, how to build a binary version, which doesn't need Python and the other dependencies to run.
|
||||||
|
|
||||||
|
### Required dependencies.
|
||||||
|
|
||||||
|
The following dependencies need to be installed in your system. If you want to build tw blue for 32-bit versions of Windows, you will find the required software in the x86 folder, inside windows-dependencies directory. If you want to build tw blue for 64-bit windows versions, use the x64 folder.
|
||||||
|
|
||||||
|
In this document you will also find links to each dependency website.
|
||||||
|
|
||||||
|
If you want to build manually some of the following libraries, you need Microsoft Visual studio 2008 professional.
|
||||||
|
|
||||||
|
Dependencies list:
|
||||||
|
|
||||||
|
* [Python,](http://python.org) version 2.7.8
|
||||||
|
* [wxPython](http://www.wxpython.org) for Python 2.7, version 3.0.0 (2.9.5 to avoid problems in windows xp)
|
||||||
|
* [Python windows extensions (pywin32)](http://www.sourceforge.net/projects/pywin32/) for python 2.7, build 218
|
||||||
|
* [ConfigObj,](http://www.voidspace.org.uk/python/configobj.html) version 4.7.2
|
||||||
|
* [oauthlib](https://pypi.python.org/pypi/oauthlib/0.6.1) 0.6.1
|
||||||
|
* [Pycurl](http://pycurl.sourceforge.net) 7.19.3.1 for Python 2.7: [32-bit downloads,](https://pypi.python.org/pypi/pycurl/7.19.3.1) [64-bit downloads](http://www.lfd.uci.edu/~gohlke/pythonlibs/)
|
||||||
|
* [Requests](http://www.python-requests.org/en/latest/) 2.2.1: [Recommended download site](https://pypi.python.org/pypi/requests/2.2.1)
|
||||||
|
* [Requests-oauthlib](https://github.com/requests/requests-oauthlib) 0.4.0
|
||||||
|
* [Suds](https://fedorahosted.org/suds) 0.4: [Recommended download site](https://pypi.python.org/pypi/suds/0.4)
|
||||||
|
* [Pygeocoder: ](http://code.xster.net/pygeocoder/wiki/Home) You can install this dependency by using pip or easy_install.
|
||||||
|
* Bootstrap 1.2.1: included in dependencies directory.
|
||||||
|
Copy the bootstrap.exe file corresponding to the desired platform in the windows folder, inside this repository.
|
||||||
|
This dependency has been built using pure basic 4.61. Its source can be found at http://hg.q-continuum.net/updater
|
||||||
|
* [oggenc2.exe,](http://www.rarewares.org/ogg-oggenc.php) version 2.87
|
||||||
|
Copy the oggenc2.exe file corresponding to the desired platform in the windows folder, inside this repository.
|
||||||
|
* Visual C++ 2008 dlls, included in vcredist-x86.7z and vcredist-x64.7z:
|
||||||
|
Extract the file corresponding to your platform to the src folder.
|
||||||
|
|
||||||
|
If you want to build the binary version:
|
||||||
|
|
||||||
|
* [Py2exe](http://www.sourceforge.net/projects/py2exe/) for Python 2.7, version 0.6.9
|
||||||
|
* [Setuptools](https://pypi.python.org/pypi/setuptools) 2.1
|
||||||
|
- [7-zip](http://7-zip.org)
|
||||||
|
|
||||||
|
### How to run tw blue from source
|
||||||
|
|
||||||
|
Run the file main.py located in the src folder. If you have a x64 system, you can install both 32-bit and 64-bit python versions, and test tw blue in these platforms.
|
||||||
|
|
||||||
|
### How to build a binary version
|
||||||
|
|
||||||
|
You must type the following command. In this example, we will assume that python is the path to the python executable (x86 or x64) and that you have navigated to the src directory:
|
||||||
|
|
||||||
|
python setup.py py2exe
|
||||||
|
|
||||||
|
You will find the binary version in the dist directory. You can compress this folder using 7-zip and you will get the zip version.
|
||||||
|
|
||||||
|
### How to generate a translation template
|
||||||
|
|
||||||
|
You must run the gen_pot.bat file, located in the tools directory. Your python installation should be in your path environment variable. The pot file will appear in the tools directory too.
|
@@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
documentation = []
|
documentation = []
|
||||||
documentation.append(_(u"""Documentation for TW Blue 0.46"""))
|
documentation.append(_(u"""Documentation for TW Blue 0.50"""))
|
||||||
# Translators: This is the new line character, don't change it in the translations.
|
# Translators: This is the new line character, don't change it in the translations.
|
||||||
documentation.append(_(u"""
|
documentation.append(_(u"""
|
||||||
"""))
|
"""))
|
||||||
@@ -47,16 +47,16 @@ documentation.append(_(u"""
|
|||||||
documentation.append(_(u"""First off, it's necessary to authorise the program so it can access your Twitter account and act on your behalf. The authorisation process is quite simple, and the program never gets data such as your username and password. In order to authorise the application, you just need to run the main executable file, called TWBlue.exe (on some computers it may appear simply as TWBlue)."""))
|
documentation.append(_(u"""First off, it's necessary to authorise the program so it can access your Twitter account and act on your behalf. The authorisation process is quite simple, and the program never gets data such as your username and password. In order to authorise the application, you just need to run the main executable file, called TWBlue.exe (on some computers it may appear simply as TWBlue)."""))
|
||||||
documentation.append(_(u"""
|
documentation.append(_(u"""
|
||||||
"""))
|
"""))
|
||||||
documentation.append(_(u"""When executed, if you have not previously configured the program, it will show a dialogue box where it tells you'll be taken to Twitter in order to authorise the application as soon as you press OK. To begin the authorisation process, press the only available button on the box."""))
|
#$documentation.append(_(u"""When executed, if you have not previously configured the program, it will show a dialogue box where it tells you'll be taken to Twitter in order to authorise the application as soon as you press OK. To begin the authorisation process, press the only available button on the box."""))
|
||||||
documentation.append(_(u"""
|
documentation.append(_(u"""
|
||||||
"""))
|
"""))
|
||||||
documentation.append(_(u"""Your default browser will open on the Twitter page to request authorisation. Enter your user name and password if you're not already logged in, look for the authorise button, and press it."""))
|
documentation.append(_(u"""Your default browser will open on the Twitter page to request authorisation. Enter your user name and password if you're not already logged in, look for the authorise button, and press it."""))
|
||||||
documentation.append(_(u"""
|
documentation.append(_(u"""
|
||||||
"""))
|
"""))
|
||||||
documentation.append(_(u"""Read the instructions you will get if the process is successful. In summary, you will be given a numeric code with several digits you must paste on an edit field open by the application on another window."""))
|
#$documentation.append(_(u"""Read the instructions you will get if the process is successful. In summary, you will be given a numeric code with several digits you must paste on an edit field open by the application on another window."""))
|
||||||
documentation.append(_(u"""
|
documentation.append(_(u"""
|
||||||
"""))
|
"""))
|
||||||
documentation.append(_(u"""Paste the verification code, and press the enter key. """))
|
#$documentation.append(_(u"""Paste the verification code, and press the enter key. """))
|
||||||
documentation.append(_(u"""
|
documentation.append(_(u"""
|
||||||
"""))
|
"""))
|
||||||
documentation.append(_(u"""If all went well, the application will start playing sounds, indicating your data are being updated."""))
|
documentation.append(_(u"""If all went well, the application will start playing sounds, indicating your data are being updated."""))
|
||||||
@@ -65,10 +65,10 @@ documentation.append(_(u"""
|
|||||||
documentation.append(_(u"""When the process is finished,the program will play another sound, and the screen reader will say "ready"."""))
|
documentation.append(_(u"""When the process is finished,the program will play another sound, and the screen reader will say "ready"."""))
|
||||||
documentation.append(_(u"""
|
documentation.append(_(u"""
|
||||||
"""))
|
"""))
|
||||||
documentation.append(_(u"""## The program's interface {#interface}"""))
|
documentation.append(_(u"""## The program's interface"""))
|
||||||
documentation.append(_(u"""
|
documentation.append(_(u"""
|
||||||
"""))
|
"""))
|
||||||
documentation.append(_(u"""The easiest way to describe the graphical interface of the application is a window with a menu bar with four menus (application, tweet, user and help), a list with several elements, and, in most cases, three buttons: tweet, retweet and reply. The actions available for each element are described below."""))
|
documentation.append(_(u"""The easiest way to describe the graphical interface of the application is a window with a menu bar with five menus (application, tweet, user, buffer and help), a list with several elements, and, in most cases, three buttons: tweet, retweet and reply. The actions available for each element are described below."""))
|
||||||
documentation.append(_(u"""
|
documentation.append(_(u"""
|
||||||
"""))
|
"""))
|
||||||
documentation.append(_(u"""Elements on the lists may be tweets, direct messages or users. TW Blue creates different tabs for each list, which can be sent tweets, main timeline tweets, favourites, or direct messages, and each tab contains a single type of tweet. These tabs are called lists or buffers."""))
|
documentation.append(_(u"""Elements on the lists may be tweets, direct messages or users. TW Blue creates different tabs for each list, which can be sent tweets, main timeline tweets, favourites, or direct messages, and each tab contains a single type of tweet. These tabs are called lists or buffers."""))
|
||||||
|
@@ -1,60 +0,0 @@
|
|||||||
tw blue build instructions for Windows
|
|
||||||
|
|
||||||
Introduction.
|
|
||||||
This document describes how to run tw blue from source, and, after that, how to build a binary version, which doesn't need Python and the other dependencies to run.
|
|
||||||
|
|
||||||
Required dependencies.
|
|
||||||
The following dependencies need to be installed in your system. If you want to build tw blue for 32-bit versions of Windows, you will find the required software in the x86 folder, inside dependencies directory. If you want to build tw blue for 64-bit windows versions, use the x64 folder.
|
|
||||||
In this document you will also find links to each dependency website.
|
|
||||||
If you want to build manually some of the following libraries, you need Microsoft Visual studio 2008 professional.
|
|
||||||
|
|
||||||
Dependencies list:
|
|
||||||
- Python, version 2.7.6: http://www.python.org
|
|
||||||
- wxPython for Python 2.7, version 3.0.0 (2.9.5 to avoid problems in windows xp): http://www.wxpython.org
|
|
||||||
-Python windows extensions (pywin32) for python 2.7, build 218: http://www.sourceforge.net/projects/pywin32/
|
|
||||||
- ConfigObj, version 4.7.2: http://www.voidspace.org.uk/python/configobj.html
|
|
||||||
- oauthlib 0.6.1: https://pypi.python.org/pypi/oauthlib/0.6.1
|
|
||||||
- Pycurl 7.19.3.1 for Python 2.7:
|
|
||||||
Official website: http://pycurl.sourceforge.net/
|
|
||||||
32-bit downloads: https://pypi.python.org/pypi/pycurl/7.19.3.1
|
|
||||||
64-bit downloads: http://www.lfd.uci.edu/~gohlke/pythonlibs/
|
|
||||||
- Requests 2.2.1:
|
|
||||||
Official website: http://www.python-requests.org/en/latest/
|
|
||||||
Recommended download site: https://pypi.python.org/pypi/requests/2.2.1
|
|
||||||
- Requests-oauthlib 0.4.0: https://github.com/requests/requests-oauthlib
|
|
||||||
- Suds 0.4:
|
|
||||||
Official website: https://fedorahosted.org/suds
|
|
||||||
Recommended download site: https://pypi.python.org/pypi/suds/0.4
|
|
||||||
- Twython 3.1.2: https://pypi.python.org/pypi/twython/3.1.2
|
|
||||||
- Bootstrap 1.2.1: included in dependencies directory.
|
|
||||||
Copy the bootstrap.exe file corresponding to the desired platform in the windows folder, inside this repository.
|
|
||||||
This dependency has been built using pure basic 4.61. Its source can be found at http://hg.q-continuum.net/updater
|
|
||||||
- oggenc2.exe, version 2.87: http://www.rarewares.org/ogg-oggenc.php
|
|
||||||
Copy the oggenc2.exe file corresponding to the desired platform in the windows folder, inside this repository.
|
|
||||||
-Visual C++ 2008 dlls, included in vcredist-x86.7z and vcredist-x64.7z:
|
|
||||||
Extract the file corresponding to your platform to the windows folder.
|
|
||||||
|
|
||||||
To build the binary version:
|
|
||||||
- Py2exe for Python 2.7, version 0.6.9: http://www.sourceforge.net/projects/py2exe/
|
|
||||||
- Setuptools 2.1: https://pypi.python.org/pypi/setuptools
|
|
||||||
- 7-zip: http://7-zip.org
|
|
||||||
|
|
||||||
To generate the documentation:
|
|
||||||
- Pandoc, version 1.12.3:
|
|
||||||
Official website: http://johnmacfarlane.net/pandoc/
|
|
||||||
Downloads site: http://code.google.com/p/pandoc/downloads/list
|
|
||||||
|
|
||||||
How to run tw blue from source
|
|
||||||
Run the file main.py located in windows folder. If you have a x64 system, you can install both 32-bit and 64-bit python versions, and test tw blue in these platforms.
|
|
||||||
|
|
||||||
How to generate the documentation
|
|
||||||
To generate quickly the documentation, a bash console is required. You can find bash in git for windows, cygwin, or MSYS, for example.
|
|
||||||
You must navigate to the tools directory and run the script gen_doc.sh. It will generate and place all html documentation in windows\documentation directory.
|
|
||||||
|
|
||||||
How to build a binary version
|
|
||||||
You must type the following command. In the following example, we will assume that python is the path to the python executable (x86 or x64) and that you have navigated to the windows directory:
|
|
||||||
python setup.py py2exe
|
|
||||||
You will find the binary version in the dist directory. You can compress this folder using 7-zip and you will get the zip version.
|
|
||||||
|
|
||||||
How to generate a translation template
|
|
||||||
You must run the gen_pot.bat file, located in the tools directory. Your python installation should be in your path environment variable. The pot file will appear in the tools directory too.
|
|
@@ -1,83 +1,88 @@
|
|||||||
!include "MUI2.nsh"
|
!include "MUI2.nsh"
|
||||||
!include "LogicLib.nsh"
|
!include "LogicLib.nsh"
|
||||||
!include "x64.nsh"
|
!include "x64.nsh"
|
||||||
CRCCheck on
|
CRCCheck on
|
||||||
XPStyle on
|
XPStyle on
|
||||||
Name "TW Blue"
|
Name "TW Blue"
|
||||||
OutFile "TWBlue_setup.exe"
|
OutFile "TWBlue_setup.exe"
|
||||||
InstallDir "$PROGRAMFILES\twblue"
|
InstallDir "$PROGRAMFILES\twblue"
|
||||||
InstallDirRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "InstallLocation"
|
InstallDirRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "InstallLocation"
|
||||||
RequestExecutionLevel admin
|
RequestExecutionLevel admin
|
||||||
SetCompress auto
|
SetCompress auto
|
||||||
SetCompressor /solid lzma
|
SetCompressor /solid lzma
|
||||||
SetDatablockOptimize on
|
SetDatablockOptimize on
|
||||||
VIAddVersionKey ProductName "TW Blue"
|
VIAddVersionKey ProductName "TW Blue"
|
||||||
VIAddVersionKey LegalCopyright "Copyright 2014 Manuel Cortez."
|
VIAddVersionKey LegalCopyright "Copyright 2014 Manuel Cortez."
|
||||||
VIAddVersionKey ProductVersion "0.48"
|
VIAddVersionKey ProductVersion "0.50"
|
||||||
VIAddVersionKey FileVersion "0.48"
|
VIAddVersionKey FileVersion "0.50"
|
||||||
VIProductVersion "0.48.0.0"
|
VIProductVersion "0.50.0.0"
|
||||||
!insertmacro MUI_PAGE_WELCOME
|
!insertmacro MUI_PAGE_WELCOME
|
||||||
!insertmacro MUI_PAGE_LICENSE "license.txt"
|
!define MUI_LICENSEPAGE_RADIOBUTTONS
|
||||||
!insertmacro MUI_PAGE_DIRECTORY
|
!insertmacro MUI_PAGE_LICENSE "license.txt"
|
||||||
var StartMenuFolder
|
!insertmacro MUI_PAGE_DIRECTORY
|
||||||
!insertmacro MUI_PAGE_STARTMENU startmenu $StartMenuFolder
|
var StartMenuFolder
|
||||||
!insertmacro MUI_PAGE_INSTFILES
|
!insertmacro MUI_PAGE_STARTMENU startmenu $StartMenuFolder
|
||||||
!insertmacro MUI_PAGE_FINISH
|
!insertmacro MUI_PAGE_INSTFILES
|
||||||
!insertmacro MUI_UNPAGE_CONFIRM
|
!define MUI_FINISHPAGE_LINK "Visit TW Blue website"
|
||||||
!insertmacro MUI_UNPAGE_INSTFILES
|
!define MUI_FINISHPAGE_LINK_LOCATION "http://twblue.com.mx"
|
||||||
!insertmacro MUI_LANGUAGE "English"
|
!define MUI_FINISHPAGE_RUN "$INSTDIR\TWBlue.exe"
|
||||||
!insertmacro MUI_LANGUAGE "French"
|
!define MUI_FINISHPAGE_RUN_PARAMETERS "-i"
|
||||||
!insertmacro MUI_LANGUAGE "Spanish"
|
!insertmacro MUI_PAGE_FINISH
|
||||||
!insertmacro MUI_LANGUAGE "Italian"
|
!insertmacro MUI_UNPAGE_CONFIRM
|
||||||
!insertmacro MUI_LANGUAGE "Finnish"
|
!insertmacro MUI_UNPAGE_INSTFILES
|
||||||
!insertmacro MUI_LANGUAGE "Russian"
|
!insertmacro MUI_LANGUAGE "English"
|
||||||
!insertmacro MUI_LANGUAGE "PortugueseBR"
|
!insertmacro MUI_LANGUAGE "French"
|
||||||
!insertmacro MUI_LANGUAGE "Polish"
|
!insertmacro MUI_LANGUAGE "Spanish"
|
||||||
!insertmacro MUI_LANGUAGE "Hungarian"
|
!insertmacro MUI_LANGUAGE "Italian"
|
||||||
!insertmacro MUI_LANGUAGE "Turkish"
|
!insertmacro MUI_LANGUAGE "Finnish"
|
||||||
!insertmacro MUI_LANGUAGE "Arabic"
|
!insertmacro MUI_LANGUAGE "Russian"
|
||||||
!insertmacro MUI_LANGUAGE "Galician"
|
!insertmacro MUI_LANGUAGE "PortugueseBR"
|
||||||
!insertmacro MUI_LANGUAGE "Catalan"
|
!insertmacro MUI_LANGUAGE "Polish"
|
||||||
!insertmacro MUI_LANGUAGE "Basque"
|
!insertmacro MUI_LANGUAGE "Hungarian"
|
||||||
!insertmacro MUI_RESERVEFILE_LANGDLL
|
!insertmacro MUI_LANGUAGE "Turkish"
|
||||||
Section
|
!insertmacro MUI_LANGUAGE "Arabic"
|
||||||
SetShellVarContext All
|
!insertmacro MUI_LANGUAGE "Galician"
|
||||||
SetOutPath "$INSTDIR"
|
!insertmacro MUI_LANGUAGE "Catalan"
|
||||||
${If} ${RunningX64}
|
!insertmacro MUI_LANGUAGE "Basque"
|
||||||
File /r TWBlue64\*
|
!insertmacro MUI_RESERVEFILE_LANGDLL
|
||||||
${Else}
|
Section
|
||||||
File /r TWBlue\*
|
SetShellVarContext All
|
||||||
${EndIf}
|
SetOutPath "$INSTDIR"
|
||||||
CreateShortCut "$DESKTOP\TW Blue.lnk" "$INSTDIR\TWBlue.exe" "-i"
|
${If} ${RunningX64}
|
||||||
!insertmacro MUI_STARTMENU_WRITE_BEGIN startmenu
|
File /r TWBlue64\*
|
||||||
CreateDirectory "$SMPROGRAMS\$StartMenuFolder"
|
${Else}
|
||||||
CreateShortCut "$SMPROGRAMS\$StartMenuFolder\TW Blue.lnk" "$INSTDIR\TWBlue.exe" "-i"
|
File /r TWBlue\*
|
||||||
CreateShortCut "$SMPROGRAMS\$StartMenuFolder\TW Blue on the web.lnk" "http://twblue.com.mx"
|
${EndIf}
|
||||||
CreateShortCut "$SMPROGRAMS\$StartMenuFolder\Uninstall.lnk" "$INSTDIR\Uninstall.exe"
|
CreateShortCut "$DESKTOP\TW Blue.lnk" "$INSTDIR\TWBlue.exe" "-i"
|
||||||
!insertmacro MUI_STARTMENU_WRITE_END
|
!insertmacro MUI_STARTMENU_WRITE_BEGIN startmenu
|
||||||
WriteUninstaller "$INSTDIR\Uninstall.exe"
|
CreateDirectory "$SMPROGRAMS\$StartMenuFolder"
|
||||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "DisplayName" "TW Blue"
|
CreateShortCut "$SMPROGRAMS\$StartMenuFolder\TW Blue.lnk" "$INSTDIR\TWBlue.exe" "-i"
|
||||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "UninstallString" '"$INSTDIR\uninstall.exe"'
|
CreateShortCut "$SMPROGRAMS\$StartMenuFolder\TW Blue on the web.lnk" "http://twblue.com.mx"
|
||||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall" "InstallLocation" $INSTDIR
|
CreateShortCut "$SMPROGRAMS\$StartMenuFolder\Uninstall.lnk" "$INSTDIR\Uninstall.exe"
|
||||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall" "Publisher" "Manuel Cortez"
|
!insertmacro MUI_STARTMENU_WRITE_END
|
||||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "DisplayVersion" "0.47"
|
WriteUninstaller "$INSTDIR\Uninstall.exe"
|
||||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "URLInfoAbout" "http://twblue.com.mx"
|
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "DisplayName" "TW Blue"
|
||||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "VersionMajor" 0
|
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "UninstallString" '"$INSTDIR\uninstall.exe"'
|
||||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "VersionMinor" 47
|
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall" "InstallLocation" $INSTDIR
|
||||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "NoModify" 1
|
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall" "Publisher" "Manuel Cortez"
|
||||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "NoRepair" 1
|
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "DisplayVersion" "0.50"
|
||||||
SectionEnd
|
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "URLInfoAbout" "http://twblue.com.mx"
|
||||||
Section "Uninstall"
|
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "VersionMajor" 0
|
||||||
SetShellVarContext All
|
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "VersionMinor" 50
|
||||||
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue"
|
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "NoModify" 1
|
||||||
RMDir /r /REBOOTOK $INSTDIR
|
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "NoRepair" 1
|
||||||
Delete "$DESKTOP\TW Blue.lnk"
|
SectionEnd
|
||||||
!insertmacro MUI_STARTMENU_GETFOLDER startmenu $StartMenuFolder
|
Section "Uninstall"
|
||||||
RMDir /r "$SMPROGRAMS\$StartMenuFolder"
|
SetShellVarContext All
|
||||||
SectionEnd
|
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue"
|
||||||
Function .onInit
|
RMDir /r /REBOOTOK $INSTDIR
|
||||||
${If} ${RunningX64}
|
Delete "$DESKTOP\TW Blue.lnk"
|
||||||
StrCpy $instdir "$programfiles64\twblue"
|
!insertmacro MUI_STARTMENU_GETFOLDER startmenu $StartMenuFolder
|
||||||
${EndIf}
|
RMDir /r "$SMPROGRAMS\$StartMenuFolder"
|
||||||
!insertmacro MUI_LANGDLL_DISPLAY
|
SectionEnd
|
||||||
FunctionEnd
|
Function .onInit
|
||||||
|
${If} ${RunningX64}
|
||||||
|
StrCpy $instdir "$programfiles64\twblue"
|
||||||
|
${EndIf}
|
||||||
|
!insertmacro MUI_LANGDLL_DISPLAY
|
||||||
|
FunctionEnd
|
||||||
|
@@ -15,6 +15,7 @@ reverse_timelines = boolean(default=False)
|
|||||||
time_to_check_streams = integer(default=30)
|
time_to_check_streams = integer(default=30)
|
||||||
announce_stream_status = boolean(default=True)
|
announce_stream_status = boolean(default=True)
|
||||||
ask_at_exit = boolean(default=True)
|
ask_at_exit = boolean(default=True)
|
||||||
|
use_invisible_keyboard_shorcuts = boolean(default=False)
|
||||||
|
|
||||||
[sound]
|
[sound]
|
||||||
volume = float(default=1.0)
|
volume = float(default=1.0)
|
||||||
@@ -35,11 +36,14 @@ 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())
|
||||||
|
trending_topic_buffers = list(default=list())
|
||||||
muted_buffers = list(default=list())
|
muted_buffers = list(default=list())
|
||||||
autoread_buffers = list(default=list())
|
autoread_buffers = list(default=list())
|
||||||
|
|
||||||
[mysc]
|
[mysc]
|
||||||
spelling_language = string(default="")
|
spelling_language = string(default="")
|
||||||
|
save_followers_in_autocompletion_db = boolean(default=False)
|
||||||
|
save_friends_in_autocompletion_db = boolean(default=False)
|
||||||
|
|
||||||
[services]
|
[services]
|
||||||
dropbox_token=string(default="")
|
dropbox_token=string(default="")
|
||||||
@@ -86,3 +90,6 @@ search = string(default="control+win+-")
|
|||||||
edit_keystrokes = string(default="control+win+k")
|
edit_keystrokes = string(default="control+win+k")
|
||||||
view_user_lists = string(default="control+win+l")
|
view_user_lists = string(default="control+win+l")
|
||||||
get_more_items = string(default="alt+win+pageup")
|
get_more_items = string(default="alt+win+pageup")
|
||||||
|
reverse_geocode = string(default="control+win+g")
|
||||||
|
view_reverse_geocode = string(default="control+win+shift+g")
|
||||||
|
get_trending_topics = string(default="control+win+t")
|
@@ -2,19 +2,19 @@
|
|||||||
name = 'TW Blue'
|
name = 'TW Blue'
|
||||||
snapshot = False
|
snapshot = False
|
||||||
if snapshot == False:
|
if snapshot == False:
|
||||||
version = "0.48"
|
version = "0.50"
|
||||||
update_url = 'http://twblue.com.mx/updates/tw_blue.json'
|
update_url = 'http://twblue.com.mx/updates/tw_blue.json'
|
||||||
else:
|
else:
|
||||||
version = "4"
|
version = "6"
|
||||||
update_url = 'http://twblue.com.mx/updates/snapshots.json'
|
update_url = 'http://twblue.com.mx/updates/snapshots.json'
|
||||||
author = u"Manuel Cortéz"
|
author = u"Manuel Cortéz"
|
||||||
authorEmail = "info@twblue.com.mx"
|
authorEmail = "manuel@manuelcortez.net"
|
||||||
copyright = u"copyright (C) 2013-2014, Manuel cortéz"
|
copyright = u"copyright (C) 2013-2014, Manuel cortéz"
|
||||||
description = u"TW Blue is an app designed to use Twitter in a simple and fast way and avoiding, as far as possible, the consumtion of excessive resources of the machine where it’s running. With this app you’ll have access to most twitter features."
|
description = u"TW Blue is an app designed to use Twitter in a simple and fast way and avoiding, as far as possible, the consumtion of excessive resources of the machine where it’s running. With this app you’ll have access to most twitter features."
|
||||||
translators = [u"Bryner Villalobos (English)", u"Mohammed Al Shara (Arabic)", u"Salva Doménech, Juan Carlos Rivilla(Catalan)", u"Manuel cortéz(Spanish)", u"Sukil Etxenike Arizaleta(Basque)", u"Jani Kinnunen(finnish)", u"Javier Currás, José Manuel Delicado, Alba Quinteiro(Galician)", u"Robert Osztolykan(Hungarian)", u"Paweł Masarczyk(Polish)", u"Odenilton Júnior Santos(Portuguese)", u"Alexander Jaszyn(Russian)", u"Burak (Turkish)"]
|
translators = [u"Bryner Villalobos (English)", u"Mohammed Al Shara (Arabic)", u"Joan Rabat, Juan Carlos Rivilla(Catalan)", u"Manuel cortéz(Spanish)", u"Sukil Etxenike Arizaleta(Basque)", u"Jani Kinnunen(finnish)", u"Alba Quinteiro(Galician)", u"Robert Osztolykan(Hungarian)", u"Paweł Masarczyk(Polish)", u"Odenilton Júnior Santos(Portuguese)", u"Alexander Jaszyn(Russian)", u"Burak (Turkish)"]
|
||||||
url = u"http://twblue.com.mx"
|
url = u"http://twblue.com.mx"
|
||||||
#report_bugs_url = "http://twblue.com.mx/errores/api/soap/mantisconnect.php?wsdl"
|
report_bugs_url = "http://twblue.com.mx/bugs/api/soap/mantisconnect.php?wsdl"
|
||||||
|
|
||||||
# Tokens
|
# Tokens
|
||||||
app_key = '8pDLbyOW3saYnvSZ4uLFg'
|
app_key = '8pDLbyOW3saYnvSZ4uLFg'
|
||||||
app_secret = 'YsgdrzY9B4yyYvYsyee78rKI3GshjHpenVS9LnFJXY'
|
app_secret = 'YsgdrzY9B4yyYvYsyee78rKI3GshjHpenVS9LnFJXY'
|
@@ -8,7 +8,9 @@ group.add_argument("-p", "--portable", help="Use TW Blue as a portable aplicatio
|
|||||||
group.add_argument("-i", "--installed", help="Use TW Blue as an installed application. Config files will be saved on the user data directory", action="store_true")
|
group.add_argument("-i", "--installed", help="Use TW Blue as an installed application. Config files will be saved on the user data directory", action="store_true")
|
||||||
parser.add_argument("-d", "--data-directory", action="store", dest="directory", help="Specifies the directory where TW Blue saves the data files")
|
parser.add_argument("-d", "--data-directory", action="store", dest="directory", help="Specifies the directory where TW Blue saves the data files")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
if args.installed == True: paths.mode = "installed"
|
if args.installed == True:
|
||||||
|
paths.mode = "installed"
|
||||||
elif args.portable == True:
|
elif args.portable == True:
|
||||||
paths.mode = "portable"
|
paths.mode = "portable"
|
||||||
if args.directory != None: paths.directory = args.directory
|
if args.directory != None: paths.directory = args.directory
|
||||||
|
|
||||||
|
@@ -16,6 +16,7 @@ class soundsTutorial(wx.Dialog):
|
|||||||
_(u"A bug has happened"),
|
_(u"A bug has happened"),
|
||||||
_(u"You've added a tweet to your favourites"),
|
_(u"You've added a tweet to your favourites"),
|
||||||
_(u"Someone's favourites have been updated"),
|
_(u"Someone's favourites have been updated"),
|
||||||
|
_(u"The tweet has coordinates to determine its location"),
|
||||||
_(u"There are no more tweets to read"),
|
_(u"There are no more tweets to read"),
|
||||||
_(u"A list has a new tweet"),
|
_(u"A list has a new tweet"),
|
||||||
_(u"You can't add any more characters on the tweet"),
|
_(u"You can't add any more characters on the tweet"),
|
||||||
|
1
src/extra/autocompletionUsers/__init__.py
Normal file
1
src/extra/autocompletionUsers/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
31
src/extra/autocompletionUsers/completion.py
Normal file
31
src/extra/autocompletionUsers/completion.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import storage
|
||||||
|
import output
|
||||||
|
import wx_menu
|
||||||
|
|
||||||
|
class autocompletionUsers(object):
|
||||||
|
def __init__(self, window):
|
||||||
|
super(autocompletionUsers, self).__init__()
|
||||||
|
self.window = window
|
||||||
|
|
||||||
|
def show_menu(self):
|
||||||
|
position = self.window.text.GetInsertionPoint()
|
||||||
|
text = self.window.text.GetValue()
|
||||||
|
text = text[:position]
|
||||||
|
try:
|
||||||
|
pattern = text.split()[-1]
|
||||||
|
except IndexError:
|
||||||
|
output.speak(_(u"You have to start writing"))
|
||||||
|
return
|
||||||
|
if pattern.startswith("@") == True:
|
||||||
|
db = storage.storage()
|
||||||
|
menu = wx_menu.menu(self.window.text, pattern[1:])
|
||||||
|
users = db.get_users(pattern[1:])
|
||||||
|
if len(users) > 0:
|
||||||
|
menu.append_options(users)
|
||||||
|
self.window.PopupMenu(menu, self.window.text.GetPosition())
|
||||||
|
menu.Destroy()
|
||||||
|
else:
|
||||||
|
output.speak(_(u"There are not results in your users database"))
|
||||||
|
else:
|
||||||
|
output.speak(_(u"Autocompletion only works for users."))
|
43
src/extra/autocompletionUsers/manage.py
Normal file
43
src/extra/autocompletionUsers/manage.py
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import storage
|
||||||
|
import wx
|
||||||
|
import wx_manage
|
||||||
|
|
||||||
|
class autocompletionManage(object):
|
||||||
|
def __init__(self, window):
|
||||||
|
super(autocompletionManage, self).__init__()
|
||||||
|
self.window = window
|
||||||
|
self.dialog = wx_manage.autocompletionManageDialog()
|
||||||
|
self.database = storage.storage()
|
||||||
|
self.users = self.database.get_all_users()
|
||||||
|
self.dialog.put_users(self.users)
|
||||||
|
self.dialog.add.Bind(wx.EVT_BUTTON, self.add_user)
|
||||||
|
self.dialog.remove.Bind(wx.EVT_BUTTON, self.remove_user)
|
||||||
|
self.dialog.ShowModal()
|
||||||
|
|
||||||
|
def update_list(self):
|
||||||
|
item = self.dialog.users.get_selected()
|
||||||
|
self.dialog.users.clear()
|
||||||
|
self.users = self.database.get_all_users()
|
||||||
|
self.dialog.put_users(self.users)
|
||||||
|
self.dialog.users.select_item(item)
|
||||||
|
|
||||||
|
def add_user(self, event=None):
|
||||||
|
usr = self.dialog.get_user()
|
||||||
|
if usr == False:
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
data = self.window.twitter.twitter.show_user(screen_name=usr)
|
||||||
|
except:
|
||||||
|
self.dialog.show_invalid_user_error()
|
||||||
|
return
|
||||||
|
self.database.set_user(data["screen_name"], data["name"], 0)
|
||||||
|
self.update_list()
|
||||||
|
|
||||||
|
def remove_user(self, ev):
|
||||||
|
ask = wx.MessageDialog(None, _(u"Are you sure you want to delete this user from the database? This user will not appear on the autocomplete results anymore."), _(u"Confirm"), wx.YES_NO|wx.ICON_QUESTION)
|
||||||
|
if ask.ShowModal() == wx.ID_YES:
|
||||||
|
item = self.dialog.users.get_selected()
|
||||||
|
user = self.users[item]
|
||||||
|
self.database.remove_user(user[0])
|
||||||
|
self.update_list()
|
58
src/extra/autocompletionUsers/settings.py
Normal file
58
src/extra/autocompletionUsers/settings.py
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import storage
|
||||||
|
import wx
|
||||||
|
import config
|
||||||
|
import wx_settings
|
||||||
|
import manage
|
||||||
|
import output
|
||||||
|
from mysc.thread_utils import call_threaded
|
||||||
|
|
||||||
|
class autocompletionSettings(object):
|
||||||
|
def __init__(self, window):
|
||||||
|
super(autocompletionSettings, self).__init__()
|
||||||
|
self.window = window
|
||||||
|
self.dialog = wx_settings.autocompletionSettingsDialog()
|
||||||
|
self.dialog.friends_buffer.SetValue(config.main["mysc"]["save_friends_in_autocompletion_db"])
|
||||||
|
self.dialog.followers_buffer.SetValue(config.main["mysc"]["save_followers_in_autocompletion_db"])
|
||||||
|
self.dialog.viewList.Bind(wx.EVT_BUTTON, self.view_list)
|
||||||
|
if self.dialog.ShowModal() == wx.ID_OK:
|
||||||
|
call_threaded(self.add_users_to_database)
|
||||||
|
|
||||||
|
def add_users_to_database(self):
|
||||||
|
config.main["mysc"]["save_friends_in_autocompletion_db"] = self.dialog.friends_buffer.GetValue()
|
||||||
|
config.main["mysc"]["save_followers_in_autocompletion_db"] = self.dialog.friends_buffer.GetValue()
|
||||||
|
output.speak(_(u"Updating database... You can close this window now. A message will tell you when the process finishes."))
|
||||||
|
database = storage.storage()
|
||||||
|
if self.dialog.followers_buffer.GetValue() == True:
|
||||||
|
buffer = self.window.search_buffer("people", "followers")
|
||||||
|
for i in buffer.db.settings[buffer.name_buffer]:
|
||||||
|
database.set_user(i["screen_name"], i["name"], 1)
|
||||||
|
else:
|
||||||
|
database.remove_by_buffer(1)
|
||||||
|
if self.dialog.friends_buffer.GetValue() == True:
|
||||||
|
buffer = self.window.search_buffer("people", "friends")
|
||||||
|
for i in buffer.db.settings[buffer.name_buffer]:
|
||||||
|
database.set_user(i["screen_name"], i["name"], 2)
|
||||||
|
else:
|
||||||
|
database.remove_by_buffer(2)
|
||||||
|
wx_settings.show_success_dialog()
|
||||||
|
self.dialog.Destroy()
|
||||||
|
|
||||||
|
def view_list(self, ev):
|
||||||
|
q = manage.autocompletionManage(self.window)
|
||||||
|
|
||||||
|
|
||||||
|
def execute_at_startup(window):
|
||||||
|
database = storage.storage()
|
||||||
|
if config.main["mysc"]["save_followers_in_autocompletion_db"] == True and config.main["other_buffers"]["show_followers"] == True:
|
||||||
|
buffer = window.search_buffer("people", "followers")
|
||||||
|
for i in buffer.db.settings[buffer.name_buffer]:
|
||||||
|
database.set_user(i["screen_name"], i["name"], 1)
|
||||||
|
else:
|
||||||
|
database.remove_by_buffer(1)
|
||||||
|
if config.main["mysc"]["save_friends_in_autocompletion_db"] == True and config.main["other_buffers"]["show_friends"] == True:
|
||||||
|
buffer = window.search_buffer("people", "friends")
|
||||||
|
for i in buffer.db.settings[buffer.name_buffer]:
|
||||||
|
database.set_user(i["screen_name"], i["name"], 2)
|
||||||
|
else:
|
||||||
|
database.remove_by_buffer(2)
|
53
src/extra/autocompletionUsers/storage.py
Normal file
53
src/extra/autocompletionUsers/storage.py
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import sqlite3, paths
|
||||||
|
from sessionmanager import manager
|
||||||
|
|
||||||
|
class storage(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.connection = sqlite3.connect(paths.config_path("%s/autocompletionUsers.dat" % (manager.manager.get_current_session())))
|
||||||
|
self.cursor = self.connection.cursor()
|
||||||
|
if self.table_exist("users") == False:
|
||||||
|
self.create_table()
|
||||||
|
|
||||||
|
def table_exist(self, table):
|
||||||
|
ask = self.cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='%s'" % (table))
|
||||||
|
answer = ask.fetchone()
|
||||||
|
if answer == None:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
def get_all_users(self):
|
||||||
|
self.cursor.execute("""select * from users""")
|
||||||
|
return self.cursor.fetchall()
|
||||||
|
|
||||||
|
def get_users(self, term):
|
||||||
|
self.cursor.execute("""SELECT * FROM users WHERE user LIKE ?""", ('{}%'.format(term),))
|
||||||
|
return self.cursor.fetchall()
|
||||||
|
|
||||||
|
def set_user(self, screen_name, user_name, from_a_buffer):
|
||||||
|
self.cursor.execute("""insert or ignore into users values(?, ?, ?)""", (screen_name, user_name, from_a_buffer))
|
||||||
|
self.connection.commit()
|
||||||
|
|
||||||
|
def remove_user(self, user):
|
||||||
|
self.cursor.execute("""DELETE FROM users WHERE user = ?""", (user,))
|
||||||
|
self.connection.commit()
|
||||||
|
return self.cursor.fetchone()
|
||||||
|
|
||||||
|
def remove_by_buffer(self, bufferType):
|
||||||
|
""" Removes all users saved on a buffer. BufferType is 0 for no buffer, 1 for friends and 2 for followers"""
|
||||||
|
self.cursor.execute("""DELETE FROM users WHERE from_a_buffer = ?""", (bufferType,))
|
||||||
|
self.connection.commit()
|
||||||
|
return self.cursor.fetchone()
|
||||||
|
|
||||||
|
def create_table(self):
|
||||||
|
self.cursor.execute("""
|
||||||
|
create table users(
|
||||||
|
user TEXT UNIQUE,
|
||||||
|
name TEXT,
|
||||||
|
from_a_buffer INTEGER
|
||||||
|
)""")
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
self.cursor.close()
|
||||||
|
self.connection.close()
|
42
src/extra/autocompletionUsers/wx_manage.py
Normal file
42
src/extra/autocompletionUsers/wx_manage.py
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import wx
|
||||||
|
from multiplatform_widgets import widgets
|
||||||
|
|
||||||
|
class autocompletionManageDialog(wx.Dialog):
|
||||||
|
def __init__(self):
|
||||||
|
super(autocompletionManageDialog, self).__init__(parent=None, id=-1, title=_(u"Manage Autocomplete users’ database"))
|
||||||
|
panel = wx.Panel(self)
|
||||||
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
|
label = wx.StaticText(panel, -1, _(u"Editing TWBlue users database"))
|
||||||
|
self.users = widgets.list(panel, _(u"Username"), _(u"Name"), style=wx.LC_REPORT)
|
||||||
|
sizer.Add(label, 0, wx.ALL, 5)
|
||||||
|
sizer.Add(self.users.list, 0, wx.ALL, 5)
|
||||||
|
self.add = wx.Button(panel, -1, _(u"Add user"))
|
||||||
|
self.remove = wx.Button(panel, -1, _(u"Remove user"))
|
||||||
|
optionsBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
optionsBox.Add(self.add, 0, wx.ALL, 5)
|
||||||
|
optionsBox.Add(self.remove, 0, wx.ALL, 5)
|
||||||
|
sizer.Add(optionsBox, 0, wx.ALL, 5)
|
||||||
|
ok = wx.Button(panel, wx.ID_OK)
|
||||||
|
cancel = wx.Button(panel, wx.ID_CANCEL)
|
||||||
|
sizerBtn = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
sizerBtn.Add(ok, 0, wx.ALL, 5)
|
||||||
|
sizer.Add(cancel, 0, wx.ALL, 5)
|
||||||
|
sizer.Add(sizerBtn, 0, wx.ALL, 5)
|
||||||
|
panel.SetSizer(sizer)
|
||||||
|
self.SetClientSize(sizer.CalcMin())
|
||||||
|
|
||||||
|
def put_users(self, users):
|
||||||
|
for i in users:
|
||||||
|
j = [i[0], i[1]]
|
||||||
|
self.users.insert_item(False, *j)
|
||||||
|
|
||||||
|
def get_user(self):
|
||||||
|
usr = False
|
||||||
|
userDlg = wx.TextEntryDialog(None, _(u"Twitter username"), _(u"Add user to database"))
|
||||||
|
if userDlg.ShowModal() == wx.ID_OK:
|
||||||
|
usr = userDlg.GetValue()
|
||||||
|
return usr
|
||||||
|
|
||||||
|
def show_invalid_user_error(self):
|
||||||
|
wx.MessageDialog(None, _(u"The user does not exist"), _(u"Error!"), wx.ICON_ERROR).ShowModal()
|
18
src/extra/autocompletionUsers/wx_menu.py
Normal file
18
src/extra/autocompletionUsers/wx_menu.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import wx
|
||||||
|
|
||||||
|
class menu(wx.Menu):
|
||||||
|
def __init__(self, window, pattern):
|
||||||
|
super(menu, self).__init__()
|
||||||
|
self.window = window
|
||||||
|
self.pattern = pattern
|
||||||
|
|
||||||
|
def append_options(self, options):
|
||||||
|
for i in options:
|
||||||
|
item = wx.MenuItem(self, wx.NewId(), "%s (@%s)" % (i[1], i[0]))
|
||||||
|
self.AppendItem(item)
|
||||||
|
self.Bind(wx.EVT_MENU, lambda evt, temp=i[0]: self.select_text(evt, temp), item)
|
||||||
|
|
||||||
|
def select_text(self, ev, text):
|
||||||
|
self.window.ChangeValue(self.window.GetValue().replace(self.pattern, text+" "))
|
||||||
|
self.window.SetInsertionPointEnd()
|
25
src/extra/autocompletionUsers/wx_settings.py
Normal file
25
src/extra/autocompletionUsers/wx_settings.py
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import wx
|
||||||
|
|
||||||
|
class autocompletionSettingsDialog(wx.Dialog):
|
||||||
|
def __init__(self):
|
||||||
|
super(autocompletionSettingsDialog, self).__init__(parent=None, id=-1, title=_(u"Autocomplete users’ settings"))
|
||||||
|
panel = wx.Panel(self)
|
||||||
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
|
self.followers_buffer = wx.CheckBox(panel, -1, _(u"Add users from followers buffer"))
|
||||||
|
self.friends_buffer = wx.CheckBox(panel, -1, _(u"Add users from friends buffer"))
|
||||||
|
sizer.Add(self.followers_buffer, 0, wx.ALL, 5)
|
||||||
|
sizer.Add(self.friends_buffer, 0, wx.ALL, 5)
|
||||||
|
self.viewList = wx.Button(panel, -1, _(u"See the users list"))
|
||||||
|
sizer.Add(self.viewList, 0, wx.ALL, 5)
|
||||||
|
ok = wx.Button(panel, wx.ID_OK)
|
||||||
|
cancel = wx.Button(panel, wx.ID_CANCEL)
|
||||||
|
sizerBtn = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
sizerBtn.Add(ok, 0, wx.ALL, 5)
|
||||||
|
sizer.Add(cancel, 0, wx.ALL, 5)
|
||||||
|
sizer.Add(sizerBtn, 0, wx.ALL, 5)
|
||||||
|
panel.SetSizer(sizer)
|
||||||
|
self.SetClientSize(sizer.CalcMin())
|
||||||
|
|
||||||
|
def show_success_dialog():
|
||||||
|
wx.MessageDialog(None, _(u"TWBlue's database of users has been updated."), _(u"Done"), wx.OK).ShowModal()
|
@@ -7,4 +7,5 @@ from favourites import *
|
|||||||
from lists import *
|
from lists import *
|
||||||
from people import *
|
from people import *
|
||||||
from tweet_searches import *
|
from tweet_searches import *
|
||||||
from user_searches import *
|
from user_searches import *
|
||||||
|
from trends import *
|
@@ -27,6 +27,7 @@ import logging as original_logger
|
|||||||
import output
|
import output
|
||||||
import platform
|
import platform
|
||||||
import datetime
|
import datetime
|
||||||
|
import menus
|
||||||
from twitter import prettydate
|
from twitter import prettydate
|
||||||
from multiplatform_widgets import widgets
|
from multiplatform_widgets import widgets
|
||||||
from mysc import event
|
from mysc import event
|
||||||
@@ -39,6 +40,8 @@ class basePanel(wx.Panel):
|
|||||||
def bind_events(self):
|
def bind_events(self):
|
||||||
self.Bind(event.MyEVT_OBJECT, self.update)
|
self.Bind(event.MyEVT_OBJECT, self.update)
|
||||||
self.Bind(event.MyEVT_DELETED, self.Remove)
|
self.Bind(event.MyEVT_DELETED, self.Remove)
|
||||||
|
self.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.showMenu, self.list.list)
|
||||||
|
self.Bind(wx.EVT_LIST_KEY_DOWN, self.showMenuByKey, self.list.list)
|
||||||
self.list.list.Bind(wx.EVT_CHAR_HOOK, self.interact)
|
self.list.list.Bind(wx.EVT_CHAR_HOOK, self.interact)
|
||||||
if self.system == "Windows":
|
if self.system == "Windows":
|
||||||
self.list.list.Bind(wx.EVT_LIST_ITEM_FOCUSED, self.onFocus)
|
self.list.list.Bind(wx.EVT_LIST_ITEM_FOCUSED, self.onFocus)
|
||||||
@@ -147,7 +150,7 @@ class basePanel(wx.Panel):
|
|||||||
if config.main["general"]["relative_times"] == True:
|
if config.main["general"]["relative_times"] == True:
|
||||||
# On windows we need only put the new date on the column, but under linux and mac it isn't possible.
|
# On windows we need only put the new date on the column, but under linux and mac it isn't possible.
|
||||||
if self.system == "Windows":
|
if self.system == "Windows":
|
||||||
original_date = datetime.datetime.strptime(tweet["created_at"], "%a %b %d %H:%M:%S +0000 %Y")
|
original_date = datetime.datetime.strptime(self.db.settings[self.name_buffer][self.list.get_selected()]["created_at"], "%a %b %d %H:%M:%S +0000 %Y")
|
||||||
date = original_date-datetime.timedelta(seconds=-self.db.settings["utc_offset"])
|
date = original_date-datetime.timedelta(seconds=-self.db.settings["utc_offset"])
|
||||||
ts = prettydate(original_date)
|
ts = prettydate(original_date)
|
||||||
self.list.list.SetStringItem(self.list.get_selected(), 2, ts)
|
self.list.list.SetStringItem(self.list.get_selected(), 2, ts)
|
||||||
@@ -155,6 +158,8 @@ class basePanel(wx.Panel):
|
|||||||
self.list.list.SetString(self.list.get_selected(), " ".join(self.compose_function(self.db.settings[self.name_buffer][self.list.get_selected()], self.db)))
|
self.list.list.SetString(self.list.get_selected(), " ".join(self.compose_function(self.db.settings[self.name_buffer][self.list.get_selected()], self.db)))
|
||||||
if twitter.utils.is_audio(tweet):
|
if twitter.utils.is_audio(tweet):
|
||||||
sound.player.play("audio.ogg", False)
|
sound.player.play("audio.ogg", False)
|
||||||
|
if twitter.utils.is_geocoded(tweet):
|
||||||
|
sound.player.play("geo.ogg", False)
|
||||||
|
|
||||||
def start_streams(self):
|
def start_streams(self):
|
||||||
if self.name_buffer == "sent":
|
if self.name_buffer == "sent":
|
||||||
@@ -181,18 +186,21 @@ class basePanel(wx.Panel):
|
|||||||
except TwythonError as e:
|
except TwythonError as e:
|
||||||
output.speak(e.message)
|
output.speak(e.message)
|
||||||
for i in items:
|
for i in items:
|
||||||
if config.main["general"]["reverse_timelines"] == False:
|
if twitter.utils.is_allowed(i) == True:
|
||||||
self.db.settings[self.name_buffer].insert(0, i)
|
if config.main["general"]["reverse_timelines"] == False:
|
||||||
else:
|
self.db.settings[self.name_buffer].insert(0, i)
|
||||||
self.db.settings[self.name_buffer].append(i)
|
else:
|
||||||
|
self.db.settings[self.name_buffer].append(i)
|
||||||
if config.main["general"]["reverse_timelines"] == False:
|
if config.main["general"]["reverse_timelines"] == False:
|
||||||
for i in items:
|
for i in items:
|
||||||
tweet = self.compose_function(i, self.db)
|
if twitter.utils.is_allowed(i) == True:
|
||||||
self.list.insert_item(True, *tweet)
|
tweet = self.compose_function(i, self.db)
|
||||||
|
self.list.insert_item(True, *tweet)
|
||||||
else:
|
else:
|
||||||
for i in items:
|
for i in items:
|
||||||
tweet = self.compose_function(i, self.db)
|
if twitter.utils.is_allowed(i) == True:
|
||||||
self.list.insert_item(False, *tweet)
|
tweet = self.compose_function(i, self.db)
|
||||||
|
self.list.insert_item(False, *tweet)
|
||||||
output.speak(_(u"%s items retrieved") % (len(items)))
|
output.speak(_(u"%s items retrieved") % (len(items)))
|
||||||
|
|
||||||
def put_items(self, num):
|
def put_items(self, num):
|
||||||
@@ -200,7 +208,7 @@ class basePanel(wx.Panel):
|
|||||||
for i in self.db.settings[self.name_buffer]:
|
for i in self.db.settings[self.name_buffer]:
|
||||||
tweet = self.compose_function(i, self.db)
|
tweet = self.compose_function(i, self.db)
|
||||||
self.list.insert_item(False, *tweet)
|
self.list.insert_item(False, *tweet)
|
||||||
self.set_list_position()
|
self.set_list_position()
|
||||||
elif self.list.get_count() > 0:
|
elif self.list.get_count() > 0:
|
||||||
if config.main["general"]["reverse_timelines"] == False:
|
if config.main["general"]["reverse_timelines"] == False:
|
||||||
for i in self.db.settings[self.name_buffer][:num]:
|
for i in self.db.settings[self.name_buffer][:num]:
|
||||||
@@ -278,10 +286,15 @@ class basePanel(wx.Panel):
|
|||||||
if self.name_buffer in config.main["other_buffers"]["autoread_buffers"]:
|
if self.name_buffer in config.main["other_buffers"]["autoread_buffers"]:
|
||||||
output.speak(" ".join(tweet[:2]))
|
output.speak(" ".join(tweet[:2]))
|
||||||
|
|
||||||
|
def get_tweet(self):
|
||||||
|
""" Gets a tweet or retweet."""
|
||||||
|
if self.db.settings[self.name_buffer][self.list.get_selected()].has_key("retweeted_status"): tweet = self.db.settings[self.name_buffer][self.list.get_selected()]["retweeted_status"]
|
||||||
|
else: tweet = self.db.settings[self.name_buffer][self.list.get_selected()]
|
||||||
|
return tweet
|
||||||
|
|
||||||
def interact(self, ev):
|
def interact(self, ev):
|
||||||
try:
|
try:
|
||||||
if self.db.settings[self.name_buffer][self.list.get_selected()].has_key("retweeted_status"): tweet = self.db.settings[self.name_buffer][self.list.get_selected()]["retweeted_status"]
|
tweet = self.get_tweet()
|
||||||
else: tweet = self.db.settings[self.name_buffer][self.list.get_selected()]
|
|
||||||
urls = twitter.utils.find_urls_in_text(tweet["text"])
|
urls = twitter.utils.find_urls_in_text(tweet["text"])
|
||||||
except:
|
except:
|
||||||
urls = []
|
urls = []
|
||||||
@@ -297,14 +310,21 @@ class basePanel(wx.Panel):
|
|||||||
ev.Skip()
|
ev.Skip()
|
||||||
return
|
return
|
||||||
if event == "audio" and len(urls) > 0:
|
if event == "audio" and len(urls) > 0:
|
||||||
self.streamer(urls[0])
|
if len(urls) == 1:
|
||||||
|
self.streamer(urls[0])
|
||||||
|
elif len(urls) > 1:
|
||||||
|
urlList = gui.dialogs.urlList.urlList(urls)
|
||||||
|
if urlList.ShowModal() == wx.ID_OK:
|
||||||
|
self.streamer(urls[urlList.lista.GetSelection()])
|
||||||
elif event == "url":
|
elif event == "url":
|
||||||
if len(urls) == 0: return
|
if len(urls) == 0: return
|
||||||
elif len(urls) == 1:
|
elif len(urls) == 1:
|
||||||
output.speak(_(u"Opening URL..."), True)
|
output.speak(_(u"Opening URL..."), True)
|
||||||
webbrowser.open(urls[0])
|
webbrowser.open(urls[0])
|
||||||
elif len(urls) > 1:
|
elif len(urls) > 1:
|
||||||
gui.dialogs.urlList.urlList(urls).ShowModal()
|
urlList = gui.dialogs.urlList.urlList(urls)
|
||||||
|
if urlList.ShowModal() == wx.ID_OK:
|
||||||
|
webbrowser.open_new_tab(urls[urlList.lista.GetSelection()])
|
||||||
elif event == "volume_down":
|
elif event == "volume_down":
|
||||||
if config.main["sound"]["volume"] > 0.05:
|
if config.main["sound"]["volume"] > 0.05:
|
||||||
config.main["sound"]["volume"] = config.main["sound"]["volume"]-0.05
|
config.main["sound"]["volume"] = config.main["sound"]["volume"]-0.05
|
||||||
@@ -362,3 +382,18 @@ class basePanel(wx.Panel):
|
|||||||
self.list.select_item(len(self.db.settings[self.name_buffer])-1)
|
self.list.select_item(len(self.db.settings[self.name_buffer])-1)
|
||||||
else:
|
else:
|
||||||
self.list.select_item(0)
|
self.list.select_item(0)
|
||||||
|
|
||||||
|
def showMenu(self, ev):
|
||||||
|
if self.list.get_count() == 0: return
|
||||||
|
if self.name_buffer == "sent":
|
||||||
|
self.PopupMenu(menus.sentPanelMenu(self), ev.GetPosition())
|
||||||
|
else:
|
||||||
|
self.PopupMenu(menus.basePanelMenu(self), ev.GetPosition())
|
||||||
|
|
||||||
|
def showMenuByKey(self, ev):
|
||||||
|
if self.list.get_count() == 0: return
|
||||||
|
if ev.GetKeyCode() == wx.WXK_WINDOWS_MENU:
|
||||||
|
if self.name_buffer == "sent":
|
||||||
|
self.PopupMenu(menus.sentPanelMenu(self), self.list.list.GetPosition())
|
||||||
|
else:
|
||||||
|
self.PopupMenu(menus.basePanelMenu(self), self.list.list.GetPosition())
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
import wx
|
import wx
|
||||||
import sound
|
import sound
|
||||||
import gui.dialogs
|
import gui.dialogs
|
||||||
|
import menus
|
||||||
import logging as original_logger
|
import logging as original_logger
|
||||||
from base import basePanel
|
from base import basePanel
|
||||||
from mysc.thread_utils import call_threaded
|
from mysc.thread_utils import call_threaded
|
||||||
@@ -30,6 +31,7 @@ class dmPanel(basePanel):
|
|||||||
super(dmPanel, self).__init__(parent, window, name_buffer, function, argumento=argumento, sound=sound)
|
super(dmPanel, self).__init__(parent, window, name_buffer, function, argumento=argumento, sound=sound)
|
||||||
self.retweetBtn.Disable()
|
self.retweetBtn.Disable()
|
||||||
self.responseBtn.Disable()
|
self.responseBtn.Disable()
|
||||||
|
self.type = "direct_message"
|
||||||
|
|
||||||
def destroy_status(self, ev):
|
def destroy_status(self, ev):
|
||||||
index = self.list.get_selected()
|
index = self.list.get_selected()
|
||||||
@@ -45,4 +47,13 @@ class dmPanel(basePanel):
|
|||||||
if dlg.ShowModal() == wx.ID_OK:
|
if dlg.ShowModal() == wx.ID_OK:
|
||||||
call_threaded(self.twitter.api_call, call_name="send_direct_message", _sound="dm_sent.ogg", text=dlg.text.GetValue(), screen_name=dlg.cb.GetValue())
|
call_threaded(self.twitter.api_call, call_name="send_direct_message", _sound="dm_sent.ogg", text=dlg.text.GetValue(), screen_name=dlg.cb.GetValue())
|
||||||
if ev != None:
|
if ev != None:
|
||||||
self.list.list.SetFocus()
|
self.list.list.SetFocus()
|
||||||
|
|
||||||
|
def showMenu(self, ev):
|
||||||
|
if self.list.get_count() == 0: return
|
||||||
|
self.PopupMenu(menus.dmPanelMenu(self), ev.GetPosition())
|
||||||
|
|
||||||
|
def showMenuByKey(self, ev):
|
||||||
|
if self.list.get_count() == 0: return
|
||||||
|
if ev.GetKeyCode() == wx.WXK_WINDOWS_MENU:
|
||||||
|
self.PopupMenu(menus.dmPanelMenu(self), self.list.list.GetPosition())
|
||||||
|
@@ -21,6 +21,7 @@ import sound
|
|||||||
import config
|
import config
|
||||||
import platform
|
import platform
|
||||||
import gui.dialogs
|
import gui.dialogs
|
||||||
|
import menus
|
||||||
import output
|
import output
|
||||||
import logging as original_logger
|
import logging as original_logger
|
||||||
from multiplatform_widgets import widgets
|
from multiplatform_widgets import widgets
|
||||||
@@ -36,6 +37,8 @@ class eventsPanel(wx.Panel):
|
|||||||
|
|
||||||
def bind_events(self):
|
def bind_events(self):
|
||||||
self.Bind(event.MyEVT_OBJECT, self.update)
|
self.Bind(event.MyEVT_OBJECT, self.update)
|
||||||
|
self.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.showMenu, self.list.list)
|
||||||
|
self.Bind(wx.EVT_LIST_KEY_DOWN, self.showMenuByKey, self.list.list)
|
||||||
|
|
||||||
def put_items(self, items):
|
def put_items(self, items):
|
||||||
pass
|
pass
|
||||||
@@ -131,4 +134,13 @@ class eventsPanel(wx.Panel):
|
|||||||
try:
|
try:
|
||||||
ev.Skip()
|
ev.Skip()
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def showMenu(self, ev):
|
||||||
|
if self.list.get_count() == 0: return
|
||||||
|
self.PopupMenu(menus.eventsPanelMenu(self), ev.GetPosition())
|
||||||
|
|
||||||
|
def showMenuByKey(self, ev):
|
||||||
|
if self.list.get_count() == 0: return
|
||||||
|
if ev.GetKeyCode() == wx.WXK_WINDOWS_MENU:
|
||||||
|
self.PopupMenu(menus.eventsPanelMenu(self), self.list.list.GetPosition())
|
||||||
|
@@ -30,7 +30,7 @@ class favsPanel(basePanel):
|
|||||||
self.type = "favourites_timeline"
|
self.type = "favourites_timeline"
|
||||||
|
|
||||||
def start_streams(self):
|
def start_streams(self):
|
||||||
num = twitter.starting.get_favourites_timeline(self.db, self.twitter, self.name_buffer, param=self.argumento, count=200)
|
num = twitter.starting.get_favourites_timeline(self.db, self.twitter, self.name_buffer, param=self.argumento, count=config.main["general"]["max_tweets_per_call"])
|
||||||
if self.sound != "" and num > 0:
|
if self.sound != "" and num > 0:
|
||||||
sound.player.play(self.sound)
|
sound.player.play(self.sound)
|
||||||
if self.list.get_count() > 0: self.put_items(num)
|
if self.list.get_count() > 0: self.put_items(num)
|
||||||
|
@@ -35,7 +35,7 @@ class listPanel(basePanel):
|
|||||||
|
|
||||||
def start_streams(self):
|
def start_streams(self):
|
||||||
self.retrieve_ids()
|
self.retrieve_ids()
|
||||||
num = twitter.starting.start_list(self.db, self.twitter, self.name_buffer, list_id=self.argumento)
|
num = twitter.starting.start_list(self.db, self.twitter, self.name_buffer, list_id=self.argumento, count=config.main["general"]["max_tweets_per_call"])
|
||||||
return num
|
return num
|
||||||
|
|
||||||
def retrieve_ids(self):
|
def retrieve_ids(self):
|
||||||
|
134
src/gui/buffers/menus.py
Normal file
134
src/gui/buffers/menus.py
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import wx
|
||||||
|
|
||||||
|
class basePanelMenu(wx.Menu):
|
||||||
|
def __init__(self, parent):
|
||||||
|
super(basePanelMenu, self).__init__()
|
||||||
|
self.window = parent
|
||||||
|
retweet = wx.MenuItem(self, wx.NewId(), _(u"&Retweet"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.onRetweet, retweet)
|
||||||
|
self.AppendItem(retweet)
|
||||||
|
reply = wx.MenuItem(self, wx.NewId(), _(u"Re&ply"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.onResponse, reply)
|
||||||
|
self.AppendItem(reply)
|
||||||
|
fav = wx.MenuItem(self, wx.NewId(), _(u"Add to &favourites"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.parent.fav, fav)
|
||||||
|
self.AppendItem(fav)
|
||||||
|
unfav = wx.MenuItem(self, wx.NewId(), _(u"Remove from favo&urites"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.parent.unfav, unfav)
|
||||||
|
self.AppendItem(unfav)
|
||||||
|
openUrl = wx.MenuItem(self, wx.NewId(), _(u"&Open URL"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.parent.url, openUrl)
|
||||||
|
self.AppendItem(openUrl)
|
||||||
|
play = wx.MenuItem(self, wx.NewId(), _(u"&Play audio"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.parent.audio, play)
|
||||||
|
self.AppendItem(play)
|
||||||
|
view = wx.MenuItem(self, wx.NewId(), _(u"&Show tweet"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.parent.view, view)
|
||||||
|
self.AppendItem(view)
|
||||||
|
copy = wx.MenuItem(self, wx.NewId(), _(u"&Copy to clipboard"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.parent.copy_to_clipboard, copy)
|
||||||
|
self.AppendItem(copy)
|
||||||
|
remove = wx.MenuItem(self, wx.NewId(), _(u"&Delete"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.parent.delete, remove)
|
||||||
|
self.AppendItem(remove)
|
||||||
|
userActions = wx.MenuItem(self, wx.NewId(), _(u"&User actions..."))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.parent.onFollow, userActions)
|
||||||
|
self.AppendItem(userActions)
|
||||||
|
|
||||||
|
class dmPanelMenu(wx.Menu):
|
||||||
|
def __init__(self, parent):
|
||||||
|
super(dmPanelMenu, self).__init__()
|
||||||
|
self.window = parent
|
||||||
|
reply = wx.MenuItem(self, wx.NewId(), _(u"Re&ply"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.onResponse, reply)
|
||||||
|
self.AppendItem(reply)
|
||||||
|
openUrl = wx.MenuItem(self, wx.NewId(), _(u"&Open URL"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.parent.url, openUrl)
|
||||||
|
self.AppendItem(openUrl)
|
||||||
|
play = wx.MenuItem(self, wx.NewId(), _(u"&Play audio"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.parent.audio, play)
|
||||||
|
self.AppendItem(play)
|
||||||
|
view = wx.MenuItem(self, wx.NewId(), _(u"&Show direct message"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.parent.view, view)
|
||||||
|
self.AppendItem(view)
|
||||||
|
copy = wx.MenuItem(self, wx.NewId(), _(u"&Copy to clipboard"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.parent.copy_to_clipboard, copy)
|
||||||
|
self.AppendItem(copy)
|
||||||
|
remove = wx.MenuItem(self, wx.NewId(), _(u"&Delete"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.parent.delete, remove)
|
||||||
|
self.AppendItem(remove)
|
||||||
|
userActions = wx.MenuItem(self, wx.NewId(), _(u"&User actions..."))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.parent.onFollow, userActions)
|
||||||
|
self.AppendItem(userActions)
|
||||||
|
|
||||||
|
class sentPanelMenu(wx.Menu):
|
||||||
|
def __init__(self, parent):
|
||||||
|
super(sentPanelMenu, self).__init__()
|
||||||
|
self.window = parent
|
||||||
|
openUrl = wx.MenuItem(self, wx.NewId(), _(u"&Open URL"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.parent.url, openUrl)
|
||||||
|
self.AppendItem(openUrl)
|
||||||
|
play = wx.MenuItem(self, wx.NewId(), _(u"&Play audio"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.parent.audio, play)
|
||||||
|
self.AppendItem(play)
|
||||||
|
view = wx.MenuItem(self, wx.NewId(), _(u"&Show tweet"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.parent.view, view)
|
||||||
|
self.AppendItem(view)
|
||||||
|
copy = wx.MenuItem(self, wx.NewId(), _(u"&Copy to clipboard"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.parent.copy_to_clipboard, copy)
|
||||||
|
self.AppendItem(copy)
|
||||||
|
remove = wx.MenuItem(self, wx.NewId(), _(u"&Delete"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.parent.delete, remove)
|
||||||
|
self.AppendItem(remove)
|
||||||
|
|
||||||
|
class eventsPanelMenu(wx.Menu):
|
||||||
|
def __init__(self, parent):
|
||||||
|
super(eventsPanelMenu, self).__init__()
|
||||||
|
self.window = parent
|
||||||
|
view = wx.MenuItem(self, wx.NewId(), _(u"&Show event"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.parent.view, view)
|
||||||
|
self.AppendItem(view)
|
||||||
|
copy = wx.MenuItem(self, wx.NewId(), _(u"&Copy to clipboard"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.parent.copy_to_clipboard, copy)
|
||||||
|
self.AppendItem(copy)
|
||||||
|
remove = wx.MenuItem(self, wx.NewId(), _(u"&Delete"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.parent.delete, remove)
|
||||||
|
self.AppendItem(remove)
|
||||||
|
|
||||||
|
class peoplePanelMenu(wx.Menu):
|
||||||
|
def __init__(self, parent):
|
||||||
|
super(peoplePanelMenu, self).__init__()
|
||||||
|
self.window = parent
|
||||||
|
reply = wx.MenuItem(self, wx.NewId(), _(u"&Mention"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.onResponse, reply)
|
||||||
|
self.AppendItem(reply)
|
||||||
|
lists = wx.MenuItem(self, wx.NewId(), _(u"&View lists"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.parent.view_user_lists, lists)
|
||||||
|
self.AppendItem(lists)
|
||||||
|
details = wx.MenuItem(self, wx.NewId(), _(u"Show user &profile"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.parent.details, details)
|
||||||
|
self.AppendItem(details)
|
||||||
|
view = wx.MenuItem(self, wx.NewId(), _(u"&Show user"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.parent.view, view)
|
||||||
|
self.AppendItem(view)
|
||||||
|
copy = wx.MenuItem(self, wx.NewId(), _(u"&Copy to clipboard"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.parent.copy_to_clipboard, copy)
|
||||||
|
self.AppendItem(copy)
|
||||||
|
userActions = wx.MenuItem(self, wx.NewId(), _(u"&User actions..."))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.parent.onFollow, userActions)
|
||||||
|
self.AppendItem(userActions)
|
||||||
|
|
||||||
|
class trendsPanelMenu(wx.Menu):
|
||||||
|
def __init__(self, parent):
|
||||||
|
super(trendsPanelMenu, self).__init__()
|
||||||
|
self.window = parent
|
||||||
|
tweetThisTrend = wx.MenuItem(self, wx.NewId(), _(u"&Tweet about this trend"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.onResponse, tweetThisTrend)
|
||||||
|
self.AppendItem(tweetThisTrend)
|
||||||
|
view = wx.MenuItem(self, wx.NewId(), _(u"&Show item"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.parent.view, view)
|
||||||
|
self.AppendItem(view)
|
||||||
|
copy = wx.MenuItem(self, wx.NewId(), _(u"&Copy to clipboard"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.window.parent.copy_to_clipboard, copy)
|
||||||
|
self.AppendItem(copy)
|
@@ -20,18 +20,20 @@ import wx
|
|||||||
from multiplatform_widgets import widgets
|
from multiplatform_widgets import widgets
|
||||||
|
|
||||||
class accountPanel(wx.Panel):
|
class accountPanel(wx.Panel):
|
||||||
def __init__(self, parent):
|
def __init__(self, parent, name_buffer):
|
||||||
super(accountPanel, self).__init__(parent=parent)
|
super(accountPanel, self).__init__(parent=parent)
|
||||||
self.type = "account"
|
self.type = "account"
|
||||||
|
self.name_buffer = name_buffer
|
||||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
self.list = widgets.list(self, _(u"Announce"))
|
self.list = widgets.list(self, _(u"Announce"))
|
||||||
sizer.Add(self.list.list, 0, wx.ALL, 5)
|
sizer.Add(self.list.list, 0, wx.ALL, 5)
|
||||||
self.SetSizer(sizer)
|
self.SetSizer(sizer)
|
||||||
|
|
||||||
|
def get_more_items(self):
|
||||||
|
output.speak(_(u"This action is not supported for this buffer"))
|
||||||
|
|
||||||
class emptyPanel(accountPanel):
|
class emptyPanel(accountPanel):
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
super(emptyPanel, self).__init__(parent=parent)
|
super(emptyPanel, self).__init__(parent=parent, name_buffer="")
|
||||||
self.type = "empty"
|
self.type = "empty"
|
||||||
|
|
||||||
def get_more_items(self):
|
|
||||||
output.speak(_(u"This action is not supported for this buffer"))
|
|
@@ -21,6 +21,7 @@ import sound
|
|||||||
import config
|
import config
|
||||||
import twitter
|
import twitter
|
||||||
import gui.dialogs
|
import gui.dialogs
|
||||||
|
import menus
|
||||||
import logging as original_logger
|
import logging as original_logger
|
||||||
import output
|
import output
|
||||||
from multiplatform_widgets import widgets
|
from multiplatform_widgets import widgets
|
||||||
@@ -36,13 +37,15 @@ class peoplePanel(basePanel):
|
|||||||
self.Bind(event.MyEVT_OBJECT, self.update)
|
self.Bind(event.MyEVT_OBJECT, self.update)
|
||||||
self.Bind(event.MyEVT_DELETED, self.Remove)
|
self.Bind(event.MyEVT_DELETED, self.Remove)
|
||||||
self.list.list.Bind(wx.EVT_CHAR_HOOK, self.interact)
|
self.list.list.Bind(wx.EVT_CHAR_HOOK, self.interact)
|
||||||
|
self.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.showMenu, self.list.list)
|
||||||
|
self.Bind(wx.EVT_LIST_KEY_DOWN, self.showMenuByKey, self.list.list)
|
||||||
|
|
||||||
def create_list(self):
|
def create_list(self):
|
||||||
self.list = widgets.list(self, _(u"User"), style=wx.LC_REPORT|wx.LC_SINGLE_SEL, size=(800, 800))
|
self.list = widgets.list(self, _(u"User"), style=wx.LC_REPORT|wx.LC_SINGLE_SEL, size=(800, 800))
|
||||||
|
|
||||||
def __init__(self, parent, window, name_buffer, function, argumento=None, sound="", timeline=False):
|
def __init__(self, parent, window, name_buffer, function, argumento=None, sound="", timeline=False):
|
||||||
self.type = "people"
|
|
||||||
super(peoplePanel, self).__init__(parent, window, name_buffer, function, argumento=argumento, sound=sound)
|
super(peoplePanel, self).__init__(parent, window, name_buffer, function, argumento=argumento, sound=sound)
|
||||||
|
self.type = "people"
|
||||||
self.responseBtn.SetLabel(_(u"Mention"))
|
self.responseBtn.SetLabel(_(u"Mention"))
|
||||||
self.retweetBtn.Disable()
|
self.retweetBtn.Disable()
|
||||||
self.compose_function = twitter.compose.compose_followers_list
|
self.compose_function = twitter.compose.compose_followers_list
|
||||||
@@ -140,3 +143,18 @@ class peoplePanel(basePanel):
|
|||||||
def remove_buffer(self):
|
def remove_buffer(self):
|
||||||
pos = None
|
pos = None
|
||||||
return pos
|
return pos
|
||||||
|
|
||||||
|
def get_message(self, dialog=False):
|
||||||
|
if dialog == False: return " ".join(self.compose_function(self.db.settings[self.name_buffer][self.list.get_selected()], self.db))
|
||||||
|
else:
|
||||||
|
list = self.compose_function(self.db.settings[self.name_buffer][self.list.get_selected()], self.db)
|
||||||
|
return " ".join(list)
|
||||||
|
|
||||||
|
def showMenu(self, ev):
|
||||||
|
if self.list.get_count() == 0: return
|
||||||
|
self.PopupMenu(menus.peoplePanelMenu(self), ev.GetPosition())
|
||||||
|
|
||||||
|
def showMenuByKey(self, ev):
|
||||||
|
if self.list.get_count() == 0: return
|
||||||
|
if ev.GetKeyCode() == wx.WXK_WINDOWS_MENU:
|
||||||
|
self.PopupMenu(menus.peoplePanelMenu(self), self.list.list.GetPosition())
|
||||||
|
@@ -17,35 +17,155 @@
|
|||||||
#
|
#
|
||||||
############################################################
|
############################################################
|
||||||
import wx
|
import wx
|
||||||
import sound
|
|
||||||
import config
|
|
||||||
import twitter
|
|
||||||
import gui.dialogs
|
import gui.dialogs
|
||||||
|
import twitter
|
||||||
|
import config
|
||||||
|
import sound
|
||||||
import logging as original_logger
|
import logging as original_logger
|
||||||
from base import basePanel
|
import output
|
||||||
|
import platform
|
||||||
|
import menus
|
||||||
|
from multiplatform_widgets import widgets
|
||||||
|
from mysc.thread_utils import call_threaded
|
||||||
log = original_logger.getLogger("buffers.base")
|
log = original_logger.getLogger("buffers.base")
|
||||||
|
|
||||||
class trendPanel(basePanel):
|
class trendsPanel(wx.Panel):
|
||||||
def __init__(self, parent, window, name_buffer, *args, **kwargs):
|
|
||||||
super(searchPanel, self).__init__(parent, window, name_buffer, sound)
|
def compose_function(self, trend):
|
||||||
self.type = "trend"
|
return [trend["name"]]
|
||||||
self.args = kwargs
|
|
||||||
|
|
||||||
def start_streams(self):
|
def bind_events(self):
|
||||||
num = twitter.starting.search(self.db, self.twitter, self.name_buffer, **self.args)
|
self.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.showMenu, self.list.list)
|
||||||
if num > 0: sound.player.play("search_updated.ogg")
|
self.Bind(wx.EVT_LIST_KEY_DOWN, self.showMenuByKey, self.list.list)
|
||||||
self.put_items(num)
|
self.list.list.Bind(wx.EVT_CHAR_HOOK, self.interact)
|
||||||
return num
|
|
||||||
|
def get_message(self, dialog=False):
|
||||||
|
return self.compose_function(self.trends[self.list.get_selected()])[0]
|
||||||
|
|
||||||
|
|
||||||
|
def create_list(self):
|
||||||
|
self.list = widgets.list(self, _(u"Trending topic"), style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_VRULES)
|
||||||
|
if self.system == "Windows":
|
||||||
|
self.list.set_windows_size(0, 30)
|
||||||
|
self.list.set_size()
|
||||||
|
|
||||||
|
def __init__(self, parent, window, name_buffer, argumento=None, sound=""):
|
||||||
|
self.type = "trends"
|
||||||
|
self.twitter = window.twitter
|
||||||
|
self.name_buffer = name_buffer
|
||||||
|
self.argumento = argumento
|
||||||
|
self.sound = sound
|
||||||
|
self.parent = window
|
||||||
|
self.system = platform.system()
|
||||||
|
wx.Panel.__init__(self, parent)
|
||||||
|
self.trends = []
|
||||||
|
self.sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
|
self.create_list()
|
||||||
|
self.btn = wx.Button(self, -1, _(u"Tweet"))
|
||||||
|
self.btn.Bind(wx.EVT_BUTTON, self.post_status)
|
||||||
|
self.tweetTrendBtn = wx.Button(self, -1, _(u"Tweet about this trend"))
|
||||||
|
self.tweetTrendBtn.Bind(wx.EVT_BUTTON, self.onResponse)
|
||||||
|
btnSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
btnSizer.Add(self.btn, 0, wx.ALL, 5)
|
||||||
|
btnSizer.Add(self.tweetTrendBtn, 0, wx.ALL, 5)
|
||||||
|
self.sizer.Add(btnSizer, 0, wx.ALL, 5)
|
||||||
|
self.sizer.Add(self.list.list, 0, wx.ALL, 5)
|
||||||
|
self.bind_events()
|
||||||
|
self.SetSizer(self.sizer)
|
||||||
|
|
||||||
def remove_buffer(self):
|
def remove_buffer(self):
|
||||||
dlg = wx.MessageDialog(self, _(u"Do you really want to delete this search term?"), _(u"Attention"), style=wx.ICON_QUESTION|wx.YES_NO)
|
dlg = wx.MessageDialog(self, _(u"Do you really want to delete this buffer?"), _(u"Attention"), style=wx.ICON_QUESTION|wx.YES_NO)
|
||||||
if dlg.ShowModal() == wx.ID_YES:
|
if dlg.ShowModal() == wx.ID_YES:
|
||||||
names = config.main["other_buffers"]["tweet_searches"]
|
topics = config.main["other_buffers"]["trending_topic_buffers"]
|
||||||
user = self.name_buffer[:-7]
|
topic = self.name_buffer[:-3]
|
||||||
log.info(u"Deleting %s's search term" % user)
|
log.info(u"Deleting %s's trending topics buffer" % topic)
|
||||||
if user in names:
|
if topic in topics:
|
||||||
names.remove(user)
|
topics.remove(topic)
|
||||||
self.db.settings.pop(self.name_buffer)
|
return 0
|
||||||
pos = self.db.settings["buffers"].index(self.name_buffer)
|
|
||||||
self.db.settings["buffers"].remove(self.name_buffer)
|
def start_streams(self):
|
||||||
return pos
|
data = self.twitter.twitter.get_place_trends(id=self.argumento)
|
||||||
|
if not hasattr(self, "name"):
|
||||||
|
self.name = data[0]["locations"][0]["name"]
|
||||||
|
self.trends = data[0]["trends"]
|
||||||
|
sound.player.play(self.sound)
|
||||||
|
return len(self.trends)
|
||||||
|
|
||||||
|
def get_more_items(self):
|
||||||
|
output.speak(_(u"This action is not supported for this buffer"))
|
||||||
|
|
||||||
|
def put_items(self, num):
|
||||||
|
selected_item = self.list.get_selected()
|
||||||
|
self.list.clear()
|
||||||
|
for i in self.trends:
|
||||||
|
tweet = self.compose_function(i)
|
||||||
|
self.list.insert_item(False, *tweet)
|
||||||
|
self.set_list_position()
|
||||||
|
self.list.select_item(selected_item)
|
||||||
|
|
||||||
|
def post_status(self, ev=None):
|
||||||
|
text = gui.dialogs.message.tweet(_(u"Write the tweet here"), _(u"Tweet"), "", self)
|
||||||
|
if text.ShowModal() == wx.ID_OK:
|
||||||
|
if text.image == None:
|
||||||
|
call_threaded(self.twitter.api_call, call_name="update_status", _sound="tweet_send.ogg", status=text.text.GetValue())
|
||||||
|
else:
|
||||||
|
call_threaded(self.twitter.api_call, call_name="update_status_with_media", _sound="tweet_send.ogg", status=text.text.GetValue(), media=text.file)
|
||||||
|
if ev != None: self.list.list.SetFocus()
|
||||||
|
|
||||||
|
def onRetweet(self, event=None): pass
|
||||||
|
|
||||||
|
def onResponse(self, ev):
|
||||||
|
trend = self.trends[self.list.get_selected()]["name"]
|
||||||
|
text = gui.dialogs.message.tweet(_(u"Write the tweet here"), _(u"Tweet"), trend+" ", self)
|
||||||
|
if text.ShowModal() == wx.ID_OK:
|
||||||
|
if text.image == None:
|
||||||
|
call_threaded(self.twitter.api_call, call_name="update_status", _sound="tweet_send.ogg", status=text.text.GetValue())
|
||||||
|
else:
|
||||||
|
call_threaded(self.twitter.api_call, call_name="update_status_with_media", _sound="tweet_send.ogg", status=text.text.GetValue(), media=text.file)
|
||||||
|
if ev != None: self.list.list.SetFocus()
|
||||||
|
|
||||||
|
def interact(self, ev):
|
||||||
|
if type(ev) is str: event = ev
|
||||||
|
else:
|
||||||
|
if ev.GetKeyCode() == wx.WXK_F5: event = "volume_down"
|
||||||
|
elif ev.GetKeyCode() == wx.WXK_F6: event = "volume_up"
|
||||||
|
elif ev.GetKeyCode() == wx.WXK_DELETE and ev.ShiftDown(): event = "clear_list"
|
||||||
|
else:
|
||||||
|
ev.Skip()
|
||||||
|
return
|
||||||
|
if event == "volume_down":
|
||||||
|
if config.main["sound"]["volume"] > 0.05:
|
||||||
|
config.main["sound"]["volume"] = config.main["sound"]["volume"]-0.05
|
||||||
|
sound.player.play("volume_changed.ogg", False)
|
||||||
|
if hasattr(self.parent, "audioStream"):
|
||||||
|
self.parent.audioStream.stream.volume = config.main["sound"]["volume"]
|
||||||
|
elif event == "volume_up":
|
||||||
|
if config.main["sound"]["volume"] < 0.95:
|
||||||
|
config.main["sound"]["volume"] = config.main["sound"]["volume"]+0.05
|
||||||
|
sound.player.play("volume_changed.ogg", False)
|
||||||
|
if hasattr(self.parent, "audioStream"):
|
||||||
|
self.parent.audioStream.stream.volume = config.main["sound"]["volume"]
|
||||||
|
elif event == "clear_list" and self.list.get_count() > 0:
|
||||||
|
dlg = wx.MessageDialog(self, _(u"Do you really want to empty this buffer? It's items will be removed from the list"), _(u"Empty buffer"), wx.ICON_QUESTION|wx.YES_NO)
|
||||||
|
if dlg.ShowModal() == wx.ID_YES:
|
||||||
|
self.trends = []
|
||||||
|
self.list.clear()
|
||||||
|
try:
|
||||||
|
ev.Skip()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def set_list_position(self):
|
||||||
|
if config.main["general"]["reverse_timelines"] == False:
|
||||||
|
self.list.select_item(len(self.trends)-1)
|
||||||
|
else:
|
||||||
|
self.list.select_item(0)
|
||||||
|
|
||||||
|
def showMenu(self, ev):
|
||||||
|
if self.list.get_count() == 0: return
|
||||||
|
self.PopupMenu(menus.trendsPanelMenu(self), ev.GetPosition())
|
||||||
|
|
||||||
|
def showMenuByKey(self, ev):
|
||||||
|
if self.list.get_count() == 0: return
|
||||||
|
if ev.GetKeyCode() == wx.WXK_WINDOWS_MENU:
|
||||||
|
self.PopupMenu(menus.trendsPanelMenu(self), self.list.list.GetPosition())
|
||||||
|
@@ -40,7 +40,7 @@ class searchUsersPanel(peoplePanel):
|
|||||||
self.create_list()
|
self.create_list()
|
||||||
self.args = args
|
self.args = args
|
||||||
self.kwargs = kwargs
|
self.kwargs = kwargs
|
||||||
self.type = "timeline"
|
self.type = "user_search"
|
||||||
|
|
||||||
def start_streams(self):
|
def start_streams(self):
|
||||||
num = twitter.starting.search_users(self.db, self.twitter, self.name_buffer, **self.kwargs)
|
num = twitter.starting.search_users(self.db, self.twitter, self.name_buffer, **self.kwargs)
|
||||||
|
@@ -1 +1 @@
|
|||||||
import message, urlList, follow, utils, show_user, update_profile, configuration, lists, search
|
import message, urlList, follow, utils, show_user, update_profile, configuration, lists, search, trending
|
@@ -29,6 +29,7 @@ import webbrowser
|
|||||||
import paths
|
import paths
|
||||||
import platform
|
import platform
|
||||||
from mysc import restart
|
from mysc import restart
|
||||||
|
from extra.autocompletionUsers import settings
|
||||||
log = original_logger.getLogger("configuration")
|
log = original_logger.getLogger("configuration")
|
||||||
|
|
||||||
system = platform.system()
|
system = platform.system()
|
||||||
@@ -50,9 +51,13 @@ class general(wx.Panel):
|
|||||||
langBox.Add(language, 0, wx.ALL, 5)
|
langBox.Add(language, 0, wx.ALL, 5)
|
||||||
langBox.Add(self.language, 0, wx.ALL, 5)
|
langBox.Add(self.language, 0, wx.ALL, 5)
|
||||||
sizer.Add(langBox, 0, wx.ALL, 5)
|
sizer.Add(langBox, 0, wx.ALL, 5)
|
||||||
|
self.au = wx.Button(self, -1, _(u"Set the autocomplete function"))
|
||||||
self.ask_at_exit = wx.CheckBox(self, -1, _(U"ask before exiting TwBlue?"))
|
self.ask_at_exit = wx.CheckBox(self, -1, _(U"ask before exiting TwBlue?"))
|
||||||
self.ask_at_exit.SetValue(config.main["general"]["ask_at_exit"])
|
self.ask_at_exit.SetValue(config.main["general"]["ask_at_exit"])
|
||||||
sizer.Add(self.ask_at_exit, 0, wx.ALL, 5)
|
sizer.Add(self.ask_at_exit, 0, wx.ALL, 5)
|
||||||
|
self.use_invisible_shorcuts = wx.CheckBox(self, -1, _(u"Use invisible interface's keyboard shorcuts on the GUI"))
|
||||||
|
self.use_invisible_shorcuts.SetValue(config.main["general"]["use_invisible_keyboard_shorcuts"])
|
||||||
|
sizer.Add(self.use_invisible_shorcuts, 0, wx.ALL, 5)
|
||||||
self.relative_time = wx.CheckBox(self, -1, _(U"Relative times"))
|
self.relative_time = wx.CheckBox(self, -1, _(U"Relative times"))
|
||||||
self.relative_time.SetValue(config.main["general"]["relative_times"])
|
self.relative_time.SetValue(config.main["general"]["relative_times"])
|
||||||
sizer.Add(self.relative_time, 0, wx.ALL, 5)
|
sizer.Add(self.relative_time, 0, wx.ALL, 5)
|
||||||
@@ -84,6 +89,7 @@ class general(wx.Panel):
|
|||||||
sizer.Add(self.reverse_timelines, 0, wx.ALL, 5)
|
sizer.Add(self.reverse_timelines, 0, wx.ALL, 5)
|
||||||
self.SetSizer(sizer)
|
self.SetSizer(sizer)
|
||||||
|
|
||||||
|
|
||||||
class other_buffers(wx.Panel):
|
class other_buffers(wx.Panel):
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
wx.Panel.__init__(self, parent)
|
wx.Panel.__init__(self, parent)
|
||||||
@@ -264,6 +270,7 @@ class configurationDialog(wx.Dialog):
|
|||||||
self.general = general(notebook)
|
self.general = general(notebook)
|
||||||
notebook.AddPage(self.general, _(u"General"))
|
notebook.AddPage(self.general, _(u"General"))
|
||||||
self.general.SetFocus()
|
self.general.SetFocus()
|
||||||
|
self.Bind(wx.EVT_BUTTON, self.autocompletion, self.general.au)
|
||||||
self.buffers = other_buffers(notebook)
|
self.buffers = other_buffers(notebook)
|
||||||
notebook.AddPage(self.buffers, _(u"Show other buffers"))
|
notebook.AddPage(self.buffers, _(u"Show other buffers"))
|
||||||
self.ignored_clients = ignoredClients(notebook)
|
self.ignored_clients = ignoredClients(notebook)
|
||||||
@@ -285,6 +292,9 @@ class configurationDialog(wx.Dialog):
|
|||||||
panel.SetSizer(sizer)
|
panel.SetSizer(sizer)
|
||||||
self.SetClientSize(sizer.CalcMin())
|
self.SetClientSize(sizer.CalcMin())
|
||||||
|
|
||||||
|
def autocompletion(self, ev):
|
||||||
|
configuration = settings.autocompletionSettings(self.parent)
|
||||||
|
|
||||||
def check_followers_change(self):
|
def check_followers_change(self):
|
||||||
if self.buffers.followers.GetValue() != self.buffers.followers_value:
|
if self.buffers.followers.GetValue() != self.buffers.followers_value:
|
||||||
if self.buffers.followers.GetValue() == True:
|
if self.buffers.followers.GetValue() == True:
|
||||||
@@ -376,6 +386,13 @@ class configurationDialog(wx.Dialog):
|
|||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
config.main["general"]["voice_enabled"] = self.general.disable_sapi5.GetValue()
|
config.main["general"]["voice_enabled"] = self.general.disable_sapi5.GetValue()
|
||||||
config.main["general"]["ask_at_exit"] = self.general.ask_at_exit.GetValue()
|
config.main["general"]["ask_at_exit"] = self.general.ask_at_exit.GetValue()
|
||||||
|
if (self.general.use_invisible_shorcuts.GetValue() == True and config.main["general"]["use_invisible_keyboard_shorcuts"] != True) and self.parent.showing == True:
|
||||||
|
km = self.parent.create_invisible_keyboard_shorcuts()
|
||||||
|
self.parent.register_invisible_keyboard_shorcuts(km)
|
||||||
|
elif (self.general.use_invisible_shorcuts.GetValue() == False and config.main["general"]["use_invisible_keyboard_shorcuts"] != False) and self.parent.showing == True:
|
||||||
|
km = self.parent.create_invisible_keyboard_shorcuts()
|
||||||
|
self.parent.unregister_invisible_keyboard_shorcuts(km)
|
||||||
|
config.main["general"]["use_invisible_keyboard_shorcuts"] = self.general.use_invisible_shorcuts.GetValue()
|
||||||
config.main["general"]["hide_gui"] = self.general.show_gui.GetValue()
|
config.main["general"]["hide_gui"] = self.general.show_gui.GetValue()
|
||||||
config.main["general"]["max_api_calls"] = self.general.apiCalls.GetValue()
|
config.main["general"]["max_api_calls"] = self.general.apiCalls.GetValue()
|
||||||
config.main["general"]["max_tweets_per_call"] = self.general.itemsPerApiCall.GetValue()
|
config.main["general"]["max_tweets_per_call"] = self.general.itemsPerApiCall.GetValue()
|
||||||
|
@@ -23,6 +23,7 @@ import twitter
|
|||||||
from twitter import utils
|
from twitter import utils
|
||||||
from twython import TwythonError
|
from twython import TwythonError
|
||||||
import output
|
import output
|
||||||
|
import re
|
||||||
|
|
||||||
class follow(wx.Dialog):
|
class follow(wx.Dialog):
|
||||||
def __init__(self, parent, default="follow"):
|
def __init__(self, parent, default="follow"):
|
||||||
@@ -48,6 +49,7 @@ class follow(wx.Dialog):
|
|||||||
self.block = wx.RadioButton(panel, -1, _(u"Block"))
|
self.block = wx.RadioButton(panel, -1, _(u"Block"))
|
||||||
self.unblock = wx.RadioButton(panel, -1, _(u"Unblock"))
|
self.unblock = wx.RadioButton(panel, -1, _(u"Unblock"))
|
||||||
self.reportSpam = wx.RadioButton(panel, -1, _(u"Report as spam"))
|
self.reportSpam = wx.RadioButton(panel, -1, _(u"Report as spam"))
|
||||||
|
self.ignore_client = wx.RadioButton(panel, -1, _(u"Ignore tweets from this client"))
|
||||||
self.setup_default(default)
|
self.setup_default(default)
|
||||||
actionSizer.Add(label2)
|
actionSizer.Add(label2)
|
||||||
actionSizer.Add(self.follow)
|
actionSizer.Add(self.follow)
|
||||||
@@ -57,6 +59,7 @@ class follow(wx.Dialog):
|
|||||||
actionSizer.Add(self.block)
|
actionSizer.Add(self.block)
|
||||||
actionSizer.Add(self.unblock)
|
actionSizer.Add(self.unblock)
|
||||||
actionSizer.Add(self.reportSpam)
|
actionSizer.Add(self.reportSpam)
|
||||||
|
actionSizer.Add(self.ignore_client)
|
||||||
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"))
|
||||||
ok.Bind(wx.EVT_BUTTON, self.onok)
|
ok.Bind(wx.EVT_BUTTON, self.onok)
|
||||||
@@ -133,6 +136,16 @@ class follow(wx.Dialog):
|
|||||||
self.Destroy()
|
self.Destroy()
|
||||||
except TwythonError as err:
|
except TwythonError as err:
|
||||||
output.speak("Error %s: %s" % (err.error_code, err.msg), True)
|
output.speak("Error %s: %s" % (err.error_code, err.msg), True)
|
||||||
|
elif self.ignore_client.GetValue() == True:
|
||||||
|
tweet = self.parent.get_tweet()
|
||||||
|
if tweet.has_key("sender"):
|
||||||
|
output.speak(_(u"You can't ignore direct messages"))
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
client = re.sub(r"(?s)<.*?>", "", tweet["source"])
|
||||||
|
if client not in config.main["twitter"]["ignored_clients"]:
|
||||||
|
config.main["twitter"]["ignored_clients"].append(client)
|
||||||
|
self.Destroy()
|
||||||
|
|
||||||
def setup_default(self, default):
|
def setup_default(self, default):
|
||||||
if default == "follow":
|
if default == "follow":
|
||||||
|
@@ -127,7 +127,7 @@ class listViewer(wx.Dialog):
|
|||||||
output.speak(_(u"This list is arready opened."))
|
output.speak(_(u"This list is arready opened."))
|
||||||
return
|
return
|
||||||
listUI = gui.buffers.lists.listPanel(self.nb, self.parent, list_updated["slug"]+"-list", argumento=utils.find_list(list_updated["slug"], self.db.settings["lists"]))
|
listUI = gui.buffers.lists.listPanel(self.nb, self.parent, list_updated["slug"]+"-list", argumento=utils.find_list(list_updated["slug"], self.db.settings["lists"]))
|
||||||
self.nb.AddPage(listUI, _(u"List for %s") % (list_updated["slug"],))
|
self.nb.InsertSubPage(self.db.settings["buffers"].index("lists"), listUI, _(u"List for %s") % (list_updated["slug"],))
|
||||||
self.db.settings["buffers"].append(list_updated["slug"]+"-list")
|
self.db.settings["buffers"].append(list_updated["slug"]+"-list")
|
||||||
num = listUI.start_streams()
|
num = listUI.start_streams()
|
||||||
listUI.put_items(num)
|
listUI.put_items(num)
|
||||||
@@ -165,6 +165,14 @@ class userListViewer(listViewer):
|
|||||||
self.db.settings["lists"].append(list)
|
self.db.settings["lists"].append(list)
|
||||||
except TwythonError as e:
|
except TwythonError as e:
|
||||||
output.speak("error %s: %s" % (e.status_code, e.msg))
|
output.speak("error %s: %s" % (e.status_code, e.msg))
|
||||||
|
def onDelete(self, event=None):
|
||||||
|
list_id = self.lists[self.lista.get_selected()]["id"]
|
||||||
|
try:
|
||||||
|
list = self.twitter.twitter.unsubscribe_from_list(list_id=list_id)
|
||||||
|
item = utils.find_item(list["id"], self.db.settings["lists"])
|
||||||
|
self.db.settings["lists"].remove(list)
|
||||||
|
except TwythonError as e:
|
||||||
|
output.speak("error %s: %s" % (e.msg))
|
||||||
|
|
||||||
class createListDialog(wx.Dialog):
|
class createListDialog(wx.Dialog):
|
||||||
|
|
||||||
|
@@ -30,6 +30,7 @@ from twython import TwythonError
|
|||||||
from extra import translator, AudioUploader
|
from extra import translator, AudioUploader
|
||||||
import platform
|
import platform
|
||||||
from extra.AudioUploader import transfer
|
from extra.AudioUploader import transfer
|
||||||
|
from extra.autocompletionUsers import completion
|
||||||
if platform.system() != "Darwin":
|
if platform.system() != "Darwin":
|
||||||
from extra.AudioUploader import dropbox_transfer
|
from extra.AudioUploader import dropbox_transfer
|
||||||
from extra.SpellChecker import gui as spellCheckerGUI
|
from extra.SpellChecker import gui as spellCheckerGUI
|
||||||
@@ -183,6 +184,8 @@ class tweet(textLimited):
|
|||||||
self.okButton = wx.Button(self.panel, wx.ID_OK, _(u"Send"), size=wx.DefaultSize)
|
self.okButton = wx.Button(self.panel, wx.ID_OK, _(u"Send"), size=wx.DefaultSize)
|
||||||
self.okButton.Bind(wx.EVT_BUTTON, self.onSend)
|
self.okButton.Bind(wx.EVT_BUTTON, self.onSend)
|
||||||
self.okButton.SetDefault()
|
self.okButton.SetDefault()
|
||||||
|
autocompletionButton = wx.Button(self.panel, -1, _(u"&Autocomplete users"))
|
||||||
|
self.Bind(wx.EVT_BUTTON, self.autocompletion, autocompletionButton)
|
||||||
cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _(u"Close"), size=wx.DefaultSize)
|
cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _(u"Close"), size=wx.DefaultSize)
|
||||||
cancelButton.Bind(wx.EVT_BUTTON, self.onCancel)
|
cancelButton.Bind(wx.EVT_BUTTON, self.onCancel)
|
||||||
self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL)
|
self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
@@ -202,8 +205,11 @@ class tweet(textLimited):
|
|||||||
self.mainBox.Add(self.ok_cancelSizer)
|
self.mainBox.Add(self.ok_cancelSizer)
|
||||||
selectId = wx.NewId()
|
selectId = wx.NewId()
|
||||||
self.Bind(wx.EVT_MENU, self.onSelect, id=selectId)
|
self.Bind(wx.EVT_MENU, self.onSelect, id=selectId)
|
||||||
|
# autocompletionId = wx.NewId()
|
||||||
|
# self.Bind(wx.EVT_MENU, self.autocompletion, id=autocompletionId)
|
||||||
self.accel_tbl = wx.AcceleratorTable([
|
self.accel_tbl = wx.AcceleratorTable([
|
||||||
(wx.ACCEL_CTRL, ord('A'), selectId),
|
(wx.ACCEL_CTRL, ord('A'), selectId),
|
||||||
|
#(wx.ACCEL_ALT, ord('A'), autocompletionId),
|
||||||
])
|
])
|
||||||
self.SetAcceleratorTable(self.accel_tbl)
|
self.SetAcceleratorTable(self.accel_tbl)
|
||||||
self.panel.SetSizer(self.mainBox)
|
self.panel.SetSizer(self.mainBox)
|
||||||
@@ -215,6 +221,10 @@ class tweet(textLimited):
|
|||||||
self.onTimer(wx.EVT_CHAR_HOOK)
|
self.onTimer(wx.EVT_CHAR_HOOK)
|
||||||
self.SetClientSize(self.mainBox.CalcMin())
|
self.SetClientSize(self.mainBox.CalcMin())
|
||||||
|
|
||||||
|
def autocompletion(self, event=None):
|
||||||
|
c = completion.autocompletionUsers(self)
|
||||||
|
c.show_menu()
|
||||||
|
|
||||||
def onUpload_image(self, ev):
|
def onUpload_image(self, ev):
|
||||||
if self.upload_image.GetLabel() == _(u"Discard image"):
|
if self.upload_image.GetLabel() == _(u"Discard image"):
|
||||||
self.image = None
|
self.image = None
|
||||||
@@ -305,7 +315,7 @@ class reply(tweet):
|
|||||||
super(reply, self).__init__(message, title, text, parent)
|
super(reply, self).__init__(message, title, text, parent)
|
||||||
self.in_reply_to = parent.db.settings[parent.name_buffer][parent.list.get_selected()]["id"]
|
self.in_reply_to = parent.db.settings[parent.name_buffer][parent.list.get_selected()]["id"]
|
||||||
self.text.SetInsertionPoint(len(self.text.GetValue()))
|
self.text.SetInsertionPoint(len(self.text.GetValue()))
|
||||||
self.mentionAll = wx.Button(self, -1, _(u"Mention to all"), size=wx.DefaultSize)
|
self.mentionAll = wx.Button(self, -1, _(u"Men&tion all"), size=wx.DefaultSize)
|
||||||
self.mentionAll.Disable()
|
self.mentionAll.Disable()
|
||||||
self.mentionAll.Bind(wx.EVT_BUTTON, self.mentionAllUsers)
|
self.mentionAll.Bind(wx.EVT_BUTTON, self.mentionAllUsers)
|
||||||
self.buttonsBox1.Add(self.mentionAll, 0, wx.ALL, 5)
|
self.buttonsBox1.Add(self.mentionAll, 0, wx.ALL, 5)
|
||||||
@@ -332,10 +342,14 @@ class reply(tweet):
|
|||||||
class viewTweet(wx.Dialog):
|
class viewTweet(wx.Dialog):
|
||||||
def __init__(self, tweet):
|
def __init__(self, tweet):
|
||||||
super(viewTweet, self).__init__(None, size=(850,850))
|
super(viewTweet, self).__init__(None, size=(850,850))
|
||||||
self.SetTitle(_(u"Tweet - %i characters ") % (len(tweet)))
|
self.SetTitle(_(u"Tweet - %i characters ") % (len(tweet["text"])))
|
||||||
panel = wx.Panel(self)
|
panel = wx.Panel(self)
|
||||||
label = wx.StaticText(panel, -1, _(u"Tweet"))
|
label = wx.StaticText(panel, -1, _(u"Tweet"))
|
||||||
self.text = wx.TextCtrl(panel, -1, tweet, style=wx.TE_READONLY|wx.TE_MULTILINE, size=(250, 180))
|
if tweet.has_key("retweeted_status"):
|
||||||
|
text = "rt @%s: %s" % (tweet["retweeted_status"]["user"]["screen_name"], tweet["retweeted_status"]["text"])
|
||||||
|
else:
|
||||||
|
text = tweet["text"]
|
||||||
|
self.text = wx.TextCtrl(panel, -1, text, style=wx.TE_READONLY|wx.TE_MULTILINE, size=(250, 180))
|
||||||
dc = wx.WindowDC(self.text)
|
dc = wx.WindowDC(self.text)
|
||||||
dc.SetFont(self.text.GetFont())
|
dc.SetFont(self.text.GetFont())
|
||||||
(x, y, z) = dc.GetMultiLineTextExtent("0"*140)
|
(x, y, z) = dc.GetMultiLineTextExtent("0"*140)
|
||||||
@@ -346,6 +360,20 @@ class viewTweet(wx.Dialog):
|
|||||||
textBox.Add(self.text, 1, wx.EXPAND, 5)
|
textBox.Add(self.text, 1, wx.EXPAND, 5)
|
||||||
mainBox = wx.BoxSizer(wx.VERTICAL)
|
mainBox = wx.BoxSizer(wx.VERTICAL)
|
||||||
mainBox.Add(textBox, 0, wx.ALL, 5)
|
mainBox.Add(textBox, 0, wx.ALL, 5)
|
||||||
|
rtCountLabel = wx.StaticText(panel, -1, _(u"Retweets: "))
|
||||||
|
rtCount = wx.TextCtrl(panel, -1, str(tweet["retweet_count"]), size=wx.DefaultSize, style=wx.TE_READONLY|wx.TE_MULTILINE)
|
||||||
|
rtBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
rtBox.Add(rtCountLabel, 0, wx.ALL, 5)
|
||||||
|
rtBox.Add(rtCount, 0, wx.ALL, 5)
|
||||||
|
favsCountLabel = wx.StaticText(panel, -1, _(u"Favourites: "))
|
||||||
|
favsCount = wx.TextCtrl(panel, -1, str(tweet["favorite_count"]), size=wx.DefaultSize, style=wx.TE_READONLY|wx.TE_MULTILINE)
|
||||||
|
favsBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
favsBox.Add(favsCountLabel, 0, wx.ALL, 5)
|
||||||
|
favsBox.Add(favsCount, 0, wx.ALL, 5)
|
||||||
|
infoBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
infoBox.Add(rtBox, 0, wx.ALL, 5)
|
||||||
|
infoBox.Add(favsBox, 0, wx.ALL, 5)
|
||||||
|
mainBox.Add(infoBox, 0, wx.ALL, 5)
|
||||||
if platform.system() != "Darwin":
|
if platform.system() != "Darwin":
|
||||||
spellcheck = wx.Button(panel, -1, _("Spelling correction"), size=wx.DefaultSize)
|
spellcheck = wx.Button(panel, -1, _("Spelling correction"), size=wx.DefaultSize)
|
||||||
spellcheck.Bind(wx.EVT_BUTTON, self.onCheck)
|
spellcheck.Bind(wx.EVT_BUTTON, self.onCheck)
|
||||||
@@ -417,3 +445,87 @@ class viewTweet(wx.Dialog):
|
|||||||
urlList.unshorten(urls, self).ShowModal()
|
urlList.unshorten(urls, self).ShowModal()
|
||||||
self.text.SetFocus()
|
self.text.SetFocus()
|
||||||
|
|
||||||
|
class viewNonTweet(wx.Dialog):
|
||||||
|
def __init__(self, tweet):
|
||||||
|
super(viewNonTweet, self).__init__(None, size=(850,850))
|
||||||
|
self.SetTitle(_(u"View"))
|
||||||
|
panel = wx.Panel(self)
|
||||||
|
label = wx.StaticText(panel, -1, _(u"Item"))
|
||||||
|
self.text = wx.TextCtrl(parent=panel, id=-1, value=tweet, style=wx.TE_READONLY|wx.TE_MULTILINE, size=(250, 180))
|
||||||
|
dc = wx.WindowDC(self.text)
|
||||||
|
dc.SetFont(self.text.GetFont())
|
||||||
|
(x, y, z) = dc.GetMultiLineTextExtent("0"*140)
|
||||||
|
self.text.SetSize((x, y))
|
||||||
|
self.text.SetFocus()
|
||||||
|
textBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
textBox.Add(label, 0, wx.ALL, 5)
|
||||||
|
textBox.Add(self.text, 1, wx.EXPAND, 5)
|
||||||
|
mainBox = wx.BoxSizer(wx.VERTICAL)
|
||||||
|
mainBox.Add(textBox, 0, wx.ALL, 5)
|
||||||
|
spellcheck = wx.Button(panel, -1, _("Spelling correction"), size=wx.DefaultSize)
|
||||||
|
spellcheck.Bind(wx.EVT_BUTTON, self.onCheck)
|
||||||
|
self.unshortenButton = wx.Button(panel, -1, _(u"Expand URL"), size=wx.DefaultSize)
|
||||||
|
self.unshortenButton.Bind(wx.EVT_BUTTON, self.onUnshorten)
|
||||||
|
self.unshortenButton.Disable()
|
||||||
|
translateButton = wx.Button(panel, -1, _(u"Translate message"), size=wx.DefaultSize)
|
||||||
|
translateButton.Bind(wx.EVT_BUTTON, self.onTranslate)
|
||||||
|
cancelButton = wx.Button(panel, wx.ID_CANCEL, _(u"Close"), size=wx.DefaultSize)
|
||||||
|
cancelButton.SetDefault()
|
||||||
|
buttonsBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
buttonsBox.Add(spellcheck, 0, wx.ALL, 5)
|
||||||
|
buttonsBox.Add(self.unshortenButton, 0, wx.ALL, 5)
|
||||||
|
buttonsBox.Add(translateButton, 0, wx.ALL, 5)
|
||||||
|
buttonsBox.Add(cancelButton, 0, wx.ALL, 5)
|
||||||
|
mainBox.Add(buttonsBox, 0, wx.ALL, 5)
|
||||||
|
selectId = wx.NewId()
|
||||||
|
self.Bind(wx.EVT_MENU, self.onSelect, id=selectId)
|
||||||
|
self.accel_tbl = wx.AcceleratorTable([
|
||||||
|
(wx.ACCEL_CTRL, ord('A'), selectId),
|
||||||
|
])
|
||||||
|
self.SetAcceleratorTable(self.accel_tbl)
|
||||||
|
panel.SetSizer(mainBox)
|
||||||
|
self.SetClientSize(mainBox.CalcMin())
|
||||||
|
self.check_urls()
|
||||||
|
|
||||||
|
def check_urls(self):
|
||||||
|
if len(twitter.utils.find_urls_in_text(self.text.GetValue())) > 0:
|
||||||
|
self.unshortenButton.Enable()
|
||||||
|
|
||||||
|
def onCheck(self, ev):
|
||||||
|
text = self.text.GetValue()
|
||||||
|
dlg = spellCheckerGUI.spellCheckerDialog(text, "")
|
||||||
|
if dlg.ShowModal() == wx.ID_OK:
|
||||||
|
self.text.ChangeValue(dlg.checker.get_text())
|
||||||
|
dlg.Destroy()
|
||||||
|
|
||||||
|
def onTranslate(self, ev):
|
||||||
|
dlg = translator.gui.translateDialog()
|
||||||
|
selection = dlg.ShowModal()
|
||||||
|
if selection != wx.ID_CANCEL:
|
||||||
|
text_to_translate = self.text.GetValue().encode("utf-8")
|
||||||
|
source = [x[0] for x in translator.available_languages()][dlg.source_lang.GetSelection()]
|
||||||
|
dest = [x[0] for x in translator.available_languages()][dlg.dest_lang.GetSelection()]
|
||||||
|
t = translator.translator.Translator()
|
||||||
|
t.from_lang = source
|
||||||
|
t.to_lang = dest
|
||||||
|
msg = t.translate(text_to_translate)
|
||||||
|
self.text.ChangeValue(msg)
|
||||||
|
output.speak(_(u"Translated"))
|
||||||
|
self.text.SetFocus()
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
dlg.Destroy()
|
||||||
|
|
||||||
|
def onSelect(self, ev):
|
||||||
|
self.text.SelectAll()
|
||||||
|
|
||||||
|
def onUnshorten(self, ev):
|
||||||
|
urls = twitter.utils.find_urls_in_text(self.text.GetValue())
|
||||||
|
if len(urls) == 0:
|
||||||
|
output.speak(_(u"There's no URL to be expanded"))
|
||||||
|
elif len(urls) == 1:
|
||||||
|
self.text.SetValue(self.text.GetValue().replace(urls[0], url_shortener.unshorten(urls[0])))
|
||||||
|
output.speak(_(u"URL expanded"))
|
||||||
|
elif len(urls) > 1:
|
||||||
|
urlList.unshorten(urls, self).ShowModal()
|
||||||
|
self.text.SetFocus()
|
||||||
|
@@ -19,24 +19,34 @@
|
|||||||
import wx
|
import wx
|
||||||
|
|
||||||
class trendingTopicsDialog(wx.Dialog):
|
class trendingTopicsDialog(wx.Dialog):
|
||||||
def __init__(self):
|
def __init__(self, information):
|
||||||
super(searchDialog, self).__init__(None, -1)
|
super(trendingTopicsDialog, self).__init__(None, -1)
|
||||||
|
self.countries = {}
|
||||||
|
self.cities = {}
|
||||||
|
self.information = information
|
||||||
|
self.split_information()
|
||||||
panel = wx.Panel(self)
|
panel = wx.Panel(self)
|
||||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
self.SetTitle(_(u"Search on Twitter"))
|
self.SetTitle(_(u"View trending topics"))
|
||||||
label = wx.StaticText(panel, -1, _(u"Search"))
|
label = wx.StaticText(panel, -1, _(u"Trending topics by"))
|
||||||
self.term = wx.TextCtrl(panel, -1,)
|
|
||||||
dc = wx.WindowDC(self.term)
|
|
||||||
dc.SetFont(self.term.GetFont())
|
|
||||||
self.term.SetSize(dc.GetTextExtent("0"*40))
|
|
||||||
sizer.Add(label, 0, wx.ALL, 5)
|
sizer.Add(label, 0, wx.ALL, 5)
|
||||||
sizer.Add(self.term, 0, wx.ALL, 5)
|
self.country = wx.RadioButton(panel, -1, _(u"Country"), style=wx.RB_GROUP)
|
||||||
self.tweets = wx.RadioButton(panel, -1, _(u"Tweets"), style=wx.RB_GROUP)
|
self.city = wx.RadioButton(panel, -1, _(u"City"))
|
||||||
self.users = wx.RadioButton(panel, -1, _(u"Users"))
|
self.Bind(wx.EVT_RADIOBUTTON, self.get_places, self.country)
|
||||||
|
self.Bind(wx.EVT_RADIOBUTTON, self.get_places, self.city)
|
||||||
|
|
||||||
radioSizer = wx.BoxSizer(wx.HORIZONTAL)
|
radioSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
radioSizer.Add(self.tweets, 0, wx.ALL, 5)
|
radioSizer.Add(label, 0, wx.ALL, 5)
|
||||||
radioSizer.Add(self.users, 0, wx.ALL, 5)
|
radioSizer.Add(self.country, 0, wx.ALL, 5)
|
||||||
|
radioSizer.Add(self.city, 0, wx.ALL, 5)
|
||||||
sizer.Add(radioSizer, 0, wx.ALL, 5)
|
sizer.Add(radioSizer, 0, wx.ALL, 5)
|
||||||
|
label = wx.StaticText(panel, -1, _(u"Location"))
|
||||||
|
self.location = wx.ListBox(panel, -1, choices=[], style=wx.CB_READONLY)
|
||||||
|
self.get_places()
|
||||||
|
locationBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
locationBox.Add(label, 0, wx.ALL, 5)
|
||||||
|
locationBox.Add(self.location, 0, wx.ALL, 5)
|
||||||
|
sizer.Add(locationBox, 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"))
|
||||||
@@ -46,3 +56,25 @@ class trendingTopicsDialog(wx.Dialog):
|
|||||||
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 split_information(self):
|
||||||
|
# self.countries["World wide"] = 1
|
||||||
|
# self.cities["World wide"] = 1
|
||||||
|
for i in self.information:
|
||||||
|
if i["placeType"]["name"] == "Country":
|
||||||
|
self.countries[i["name"]] = i["woeid"]
|
||||||
|
else:
|
||||||
|
self.cities[i["name"]] = i["woeid"]
|
||||||
|
|
||||||
|
def get_places(self, event=None):
|
||||||
|
values = []
|
||||||
|
if self.country.GetValue() == True:
|
||||||
|
for i in self.information:
|
||||||
|
if i["placeType"]["name"] == "Country":
|
||||||
|
values.append(i["name"])
|
||||||
|
elif self.city.GetValue() == True:
|
||||||
|
for i in self.information:
|
||||||
|
if i["placeType"]["name"] != "Country":
|
||||||
|
values.append(i["name"])
|
||||||
|
self.location.Set(values)
|
||||||
|
|
@@ -46,8 +46,7 @@ class urlList(wx.Dialog):
|
|||||||
self.SetClientSize(sizer.CalcMin())
|
self.SetClientSize(sizer.CalcMin())
|
||||||
|
|
||||||
def onGo(self, ev):
|
def onGo(self, ev):
|
||||||
webbrowser.open(self.lista.GetStringSelection())
|
self.EndModal(wx.ID_OK)
|
||||||
self.Destroy()
|
|
||||||
|
|
||||||
def populate_list(self):
|
def populate_list(self):
|
||||||
for i in self.urls:
|
for i in self.urls:
|
||||||
|
182
src/gui/main.py
182
src/gui/main.py
@@ -32,10 +32,16 @@ import output
|
|||||||
import platform
|
import platform
|
||||||
import urllib2
|
import urllib2
|
||||||
import sysTrayIcon
|
import sysTrayIcon
|
||||||
|
import switchModule
|
||||||
|
from wx.lib.pubsub import pub
|
||||||
import languageHandler
|
import languageHandler
|
||||||
|
from extra.autocompletionUsers import settings as autocompletionUsersSettings
|
||||||
|
import pygeocoder
|
||||||
|
from pygeolib import GeocoderError
|
||||||
from sessionmanager import manager
|
from sessionmanager import manager
|
||||||
|
from issueReporter import gui as issueReporterGUI
|
||||||
from mysc import event
|
from mysc import event
|
||||||
from mysc.thread_utils import call_threaded
|
from mysc.thread_utils import call_threaded, stream_threaded
|
||||||
from twython import TwythonError
|
from twython import TwythonError
|
||||||
from urllib2 import URLError
|
from urllib2 import URLError
|
||||||
from mysc.repeating_timer import RepeatingTimer
|
from mysc.repeating_timer import RepeatingTimer
|
||||||
@@ -46,6 +52,7 @@ from extra import SoundsTutorial
|
|||||||
from keystrokeEditor import gui as keystrokeEditorGUI
|
from keystrokeEditor import gui as keystrokeEditorGUI
|
||||||
log = original_logger.getLogger("gui.main")
|
log = original_logger.getLogger("gui.main")
|
||||||
|
|
||||||
|
geocoder = pygeocoder.Geocoder()
|
||||||
class mainFrame(wx.Frame):
|
class mainFrame(wx.Frame):
|
||||||
""" Main class of the Frame. This is the Main Window."""
|
""" Main class of the Frame. This is the Main Window."""
|
||||||
|
|
||||||
@@ -56,12 +63,16 @@ class mainFrame(wx.Frame):
|
|||||||
|
|
||||||
# Application menu
|
# Application menu
|
||||||
app = wx.Menu()
|
app = wx.Menu()
|
||||||
|
switch_account = app.Append(wx.NewId(), _(u"S&witch account"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.switch_account, switch_account)
|
||||||
updateProfile = app.Append(wx.NewId(), _(u"&Update profile"))
|
updateProfile = app.Append(wx.NewId(), _(u"&Update profile"))
|
||||||
self.Bind(wx.EVT_MENU, self.update_profile, updateProfile)
|
self.Bind(wx.EVT_MENU, self.update_profile, updateProfile)
|
||||||
show_hide = app.Append(wx.NewId(), _(u"&Hide window"))
|
show_hide = app.Append(wx.NewId(), _(u"&Hide window"))
|
||||||
self.Bind(wx.EVT_MENU, self.show_hide, show_hide)
|
self.Bind(wx.EVT_MENU, self.show_hide, show_hide)
|
||||||
search = app.Append(wx.NewId(), _(u"&Search"))
|
search = app.Append(wx.NewId(), _(u"&Search"))
|
||||||
self.Bind(wx.EVT_MENU, self.search, search)
|
self.Bind(wx.EVT_MENU, self.search, search)
|
||||||
|
trends = app.Append(wx.NewId(), _(u"View &trending topics"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.get_trending_topics, trends)
|
||||||
lists = app.Append(wx.NewId(), _(u"&Lists manager"))
|
lists = app.Append(wx.NewId(), _(u"&Lists manager"))
|
||||||
self.Bind(wx.EVT_MENU, self.list_manager, lists)
|
self.Bind(wx.EVT_MENU, self.list_manager, lists)
|
||||||
sounds_tutorial = app.Append(wx.NewId(), _(u"Sounds &tutorial"))
|
sounds_tutorial = app.Append(wx.NewId(), _(u"Sounds &tutorial"))
|
||||||
@@ -87,6 +98,8 @@ class mainFrame(wx.Frame):
|
|||||||
self.Bind(wx.EVT_MENU, self.unfav, unfav)
|
self.Bind(wx.EVT_MENU, self.unfav, unfav)
|
||||||
view = tweet.Append(wx.NewId(), _(u"&Show tweet"))
|
view = tweet.Append(wx.NewId(), _(u"&Show tweet"))
|
||||||
self.Bind(wx.EVT_MENU, self.view, view)
|
self.Bind(wx.EVT_MENU, self.view, view)
|
||||||
|
view_coordinates = tweet.Append(wx.NewId(), _(u"View &address"))
|
||||||
|
self.Bind(wx.EVT_MENU, self.reverse_geocode, view_coordinates)
|
||||||
delete = tweet.Append(wx.NewId(), _(u"&Delete"))
|
delete = tweet.Append(wx.NewId(), _(u"&Delete"))
|
||||||
self.Bind(wx.EVT_MENU, self.delete, delete)
|
self.Bind(wx.EVT_MENU, self.delete, delete)
|
||||||
|
|
||||||
@@ -208,17 +221,17 @@ class mainFrame(wx.Frame):
|
|||||||
log.debug("Getting Twitter's Rest API...")
|
log.debug("Getting Twitter's Rest API...")
|
||||||
self.twitter = twitter.twitter.twitter()
|
self.twitter = twitter.twitter.twitter()
|
||||||
super(mainFrame, self).__init__(None, -1, "TW Blue", size=(1600, 1600))
|
super(mainFrame, self).__init__(None, -1, "TW Blue", size=(1600, 1600))
|
||||||
self.Bind(wx.EVT_QUERY_END_SESSION, self.exit)
|
wx.GetApp().Bind(wx.EVT_QUERY_END_SESSION, self.exit)
|
||||||
self.Bind(wx.EVT_END_SESSION, self.exit)
|
wx.GetApp().Bind(wx.EVT_END_SESSION, self.exit)
|
||||||
log.debug(u"Creating the system tray icon... ")
|
log.debug(u"Creating the system tray icon... ")
|
||||||
sysTray=sysTrayIcon.SysTrayIcon(self)
|
self.sysTray=sysTrayIcon.SysTrayIcon(self)
|
||||||
panel = wx.Panel(self)
|
panel = wx.Panel(self)
|
||||||
self.sizer = wx.BoxSizer(wx.VERTICAL)
|
self.sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
self.SetTitle("TW Blue")
|
self.SetTitle("TW Blue")
|
||||||
try:
|
try:
|
||||||
updater.update_manager.check_for_update()
|
updater.update_manager.check_for_update()
|
||||||
except:
|
except:
|
||||||
pass
|
wx.MessageDialog(self, _(u"An error occurred while looking for an update. It may be due to any problem either on our server or on your DNS servers. Please, try again later."), _(u"Error!"), wx.OK|wx.ICON_ERROR).ShowModal()
|
||||||
self.SetMenuBar(self.makeMenus())
|
self.SetMenuBar(self.makeMenus())
|
||||||
self.setup_twitter(panel)
|
self.setup_twitter(panel)
|
||||||
|
|
||||||
@@ -233,7 +246,7 @@ class mainFrame(wx.Frame):
|
|||||||
# Gets the tabs for home, mentions, send and direct messages.
|
# Gets the tabs for home, mentions, send and direct messages.
|
||||||
log.debug("Creating buffers...")
|
log.debug("Creating buffers...")
|
||||||
self.db.settings["buffers"] = []
|
self.db.settings["buffers"] = []
|
||||||
account = buffers.accountPanel(self.nb)
|
account = buffers.accountPanel(self.nb, self.db.settings["user_name"])
|
||||||
self.nb.AddPage(account, self.db.settings["user_name"])
|
self.nb.AddPage(account, self.db.settings["user_name"])
|
||||||
self.db.settings["buffers"].append(self.db.settings["user_name"])
|
self.db.settings["buffers"].append(self.db.settings["user_name"])
|
||||||
account_index = self.db.settings["buffers"].index(self.db.settings["user_name"])
|
account_index = self.db.settings["buffers"].index(self.db.settings["user_name"])
|
||||||
@@ -310,11 +323,23 @@ class mainFrame(wx.Frame):
|
|||||||
self.db.settings["buffers"].append(i+"favs")
|
self.db.settings["buffers"].append(i+"favs")
|
||||||
self.fav_stream = RepeatingTimer(180, self.get_fav_buffers)
|
self.fav_stream = RepeatingTimer(180, self.get_fav_buffers)
|
||||||
self.fav_stream.start()
|
self.fav_stream.start()
|
||||||
|
for i in config.main["other_buffers"]["trending_topic_buffers"]:
|
||||||
|
buff = buffers.trendsPanel(self.nb, self, "%s_tt" % (i,), argumento=i, sound="trends_updated.ogg")
|
||||||
|
timer = RepeatingTimer(300, buff.start_streams)
|
||||||
|
timer.start()
|
||||||
|
num = buff.start_streams()
|
||||||
|
buff.put_items(num)
|
||||||
|
self.nb.InsertSubPage(self.db.settings["buffers"].index(self.db.settings["user_name"]), buff, _(u"Trending topics for %s") % (buff.name,))
|
||||||
self.sizer.Add(self.nb, 0, wx.ALL, 5)
|
self.sizer.Add(self.nb, 0, wx.ALL, 5)
|
||||||
|
if config.main["general"]["use_invisible_keyboard_shorcuts"] == True:
|
||||||
|
km = self.create_invisible_keyboard_shorcuts()
|
||||||
|
self.register_invisible_keyboard_shorcuts(km)
|
||||||
panel.SetSizer(self.sizer)
|
panel.SetSizer(self.sizer)
|
||||||
self.SetClientSize(self.sizer.CalcMin())
|
self.SetClientSize(self.sizer.CalcMin())
|
||||||
self.Bind(event.MyEVT_STARTED, self.onInit)
|
self.Bind(event.MyEVT_STARTED, self.onInit)
|
||||||
self.Bind(event.EVT_RESULT, self.onMemberAdded)
|
self.Bind(event.EVT_RESULT, self.onMemberAdded)
|
||||||
|
pub.subscribe(self.listen_streamerror, "streamError")
|
||||||
|
pub.subscribe(self.listen_for_friends, "friendsReceived")
|
||||||
call_threaded(self.init, run_streams=True)
|
call_threaded(self.init, run_streams=True)
|
||||||
|
|
||||||
def init(self, run_streams=False):
|
def init(self, run_streams=False):
|
||||||
@@ -347,6 +372,7 @@ class mainFrame(wx.Frame):
|
|||||||
self.check_streams.start()
|
self.check_streams.start()
|
||||||
# If all it's done, then play a nice sound saying that all it's OK.
|
# If all it's done, then play a nice sound saying that all it's OK.
|
||||||
sound.player.play("ready.ogg")
|
sound.player.play("ready.ogg")
|
||||||
|
autocompletionUsersSettings.execute_at_startup(window=self)
|
||||||
|
|
||||||
def remove_list(self, id):
|
def remove_list(self, id):
|
||||||
for i in range(0, self.nb.GetPageCount()):
|
for i in range(0, self.nb.GetPageCount()):
|
||||||
@@ -369,21 +395,21 @@ class mainFrame(wx.Frame):
|
|||||||
|
|
||||||
def setup_twitter(self, panel):
|
def setup_twitter(self, panel):
|
||||||
""" Setting up the connection for twitter, or authenticate if the config file has valid credentials."""
|
""" Setting up the connection for twitter, or authenticate if the config file has valid credentials."""
|
||||||
try:
|
# try:
|
||||||
self.twitter.login(self.user_key, self.user_secret)
|
self.twitter.login(self.user_key, self.user_secret)
|
||||||
self.logging_in_twblue(panel)
|
self.logging_in_twblue(panel)
|
||||||
log.info("Authorized in Twitter.")
|
log.info("Authorized in Twitter.")
|
||||||
del self.user_key; del self.user_secret
|
del self.user_key; del self.user_secret
|
||||||
except:
|
# except:
|
||||||
dlg1 = wx.MessageDialog(panel, _(u"Connection error. Try again later."), _(u"Error!"), wx.ICON_ERROR)
|
# dlg1 = wx.MessageDialog(panel, _(u"Connection error. Try again later."), _(u"Error!"), wx.ICON_ERROR)
|
||||||
dlg1.ShowModal()
|
# dlg1.ShowModal()
|
||||||
self.Close(True)
|
# self.Close(True)
|
||||||
|
|
||||||
def get_home(self):
|
def get_home(self):
|
||||||
""" Gets the home stream, that manages home timeline, mentions, direct messages and sent."""
|
""" Gets the home stream, that manages home timeline, mentions, direct messages and sent."""
|
||||||
try:
|
try:
|
||||||
self.stream = twitter.buffers.stream.streamer(application.app_key, application.app_secret, config.main["twitter"]["user_key"], config.main["twitter"]["user_secret"], parent=self)
|
self.stream = twitter.buffers.stream.streamer(application.app_key, application.app_secret, config.main["twitter"]["user_key"], config.main["twitter"]["user_secret"], parent=self)
|
||||||
call_threaded(self.stream.user)
|
stream_threaded(self.stream.user)
|
||||||
except:
|
except:
|
||||||
self.stream.disconnect()
|
self.stream.disconnect()
|
||||||
|
|
||||||
@@ -406,13 +432,16 @@ class mainFrame(wx.Frame):
|
|||||||
ids+= str(z)+", "
|
ids+= str(z)+", "
|
||||||
if ids != "":
|
if ids != "":
|
||||||
# try:
|
# try:
|
||||||
call_threaded(self.stream2.statuses.filter, follow=ids)
|
stream_threaded(self.stream2.statuses.filter, follow=ids)
|
||||||
# except:
|
# except:
|
||||||
# pass
|
# pass
|
||||||
# except:
|
# except:
|
||||||
# self.stream2.disconnect()
|
# self.stream2.disconnect()
|
||||||
|
|
||||||
def check_stream_up(self):
|
def check_stream_up(self):
|
||||||
|
if not hasattr(self, "stream") and not hasattr(self, "stream2"):
|
||||||
|
self.init(run_streams=True)
|
||||||
|
return
|
||||||
try:
|
try:
|
||||||
urllib2.urlopen("http://74.125.228.231", timeout=5)
|
urllib2.urlopen("http://74.125.228.231", timeout=5)
|
||||||
except urllib2.URLError:
|
except urllib2.URLError:
|
||||||
@@ -501,7 +530,7 @@ class mainFrame(wx.Frame):
|
|||||||
dlg = dialogs.lists.removeUserListDialog(self)
|
dlg = dialogs.lists.removeUserListDialog(self)
|
||||||
if dlg.ShowModal() == wx.ID_OK:
|
if dlg.ShowModal() == wx.ID_OK:
|
||||||
try:
|
try:
|
||||||
list = self.twitter.twitter.delete_list_member(list_id=self.db.settings["lists"][dlg.get_selected()]["id"], screen_name=user)
|
list = self.twitter.twitter.delete_list_member(list_id=self.db.settings["lists"][dlg.lista.get_selected()]["id"], screen_name=user)
|
||||||
older_list = twitter.utils.find_item(self.db.settings["lists"][dlg.get_selected()]["id"], self.db.settings["lists"])
|
older_list = twitter.utils.find_item(self.db.settings["lists"][dlg.get_selected()]["id"], self.db.settings["lists"])
|
||||||
if list["mode"] == "private":
|
if list["mode"] == "private":
|
||||||
self.db.settings["lists"].pop(older_list)
|
self.db.settings["lists"].pop(older_list)
|
||||||
@@ -546,8 +575,7 @@ class mainFrame(wx.Frame):
|
|||||||
webbrowser.open("http://twblue.com.mx")
|
webbrowser.open("http://twblue.com.mx")
|
||||||
|
|
||||||
def onReportBug(self, ev):
|
def onReportBug(self, ev):
|
||||||
webbrowser.open("https://github.com/manuelcortez/TWBlue/issues")
|
issueReporterGUI.reportBug(self.db.settings["user_name"]).ShowModal()
|
||||||
# issueReporterGUI.reportBug(self.db.settings["user_name"]).ShowModal()
|
|
||||||
|
|
||||||
def onCheckForUpdates(self, ev):
|
def onCheckForUpdates(self, ev):
|
||||||
updater.update_manager.check_for_update(msg=True)
|
updater.update_manager.check_for_update(msg=True)
|
||||||
@@ -574,7 +602,7 @@ class mainFrame(wx.Frame):
|
|||||||
output.speak(self.nb.GetPageText(self.nb.GetSelection())+",", True)
|
output.speak(self.nb.GetPageText(self.nb.GetSelection())+",", True)
|
||||||
|
|
||||||
def skip_blank_pages(self, forward=True):
|
def skip_blank_pages(self, forward=True):
|
||||||
if self.nb.GetCurrentPage().type == "account" or self.nb.GetCurrentPage().type == "empty" and (self.showing == False or platform.system() == "Darwin"):
|
if self.nb.GetCurrentPage().type == "account" or self.nb.GetCurrentPage().type == "empty":
|
||||||
self.nb.AdvanceSelection(forward)
|
self.nb.AdvanceSelection(forward)
|
||||||
|
|
||||||
def close(self, ev=None):
|
def close(self, ev=None):
|
||||||
@@ -590,6 +618,8 @@ class mainFrame(wx.Frame):
|
|||||||
def exit(self, event=None):
|
def exit(self, event=None):
|
||||||
config.main.write()
|
config.main.write()
|
||||||
log.debug("Exiting...")
|
log.debug("Exiting...")
|
||||||
|
self.sysTray.RemoveIcon()
|
||||||
|
self.sysTray.Destroy()
|
||||||
try:
|
try:
|
||||||
self.check_streams.cancel()
|
self.check_streams.cancel()
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
@@ -661,8 +691,18 @@ class mainFrame(wx.Frame):
|
|||||||
self.nb.GetCurrentPage().onRetweet(ev)
|
self.nb.GetCurrentPage().onRetweet(ev)
|
||||||
|
|
||||||
def view(self, ev=None):
|
def view(self, ev=None):
|
||||||
tweet = self.nb.GetCurrentPage().get_message(dialog=True)
|
tp = self.nb.GetCurrentPage().type
|
||||||
dialogs.message.viewTweet(tweet).ShowModal()
|
if tp == "buffer" or tp == "timeline" or tp == "favourites_timeline" or tp == "list" or tp == "search":
|
||||||
|
try:
|
||||||
|
id = self.db.settings[self.nb.GetCurrentPage().name_buffer][self.nb.GetCurrentPage().list.get_selected()]["id"]
|
||||||
|
tweet = self.twitter.twitter.show_status(id=id)
|
||||||
|
dialogs.message.viewTweet(tweet).ShowModal()
|
||||||
|
except TwythonError as e:
|
||||||
|
non_tweet = self.nb.GetCurrentPage().get_message(dialog=True)
|
||||||
|
dialogs.message.viewNonTweet(non_tweet).ShowModal()
|
||||||
|
else:
|
||||||
|
non_tweet = self.nb.GetCurrentPage().get_message(dialog=True)
|
||||||
|
dialogs.message.viewNonTweet(non_tweet).ShowModal()
|
||||||
|
|
||||||
def fav(self, ev=None):
|
def fav(self, ev=None):
|
||||||
if self.nb.GetCurrentPage().name_buffer != "direct_messages" and self.nb.GetCurrentPage().name_buffer != "followers" and self.nb.GetCurrentPage().name_buffer != "friends":
|
if self.nb.GetCurrentPage().name_buffer != "direct_messages" and self.nb.GetCurrentPage().name_buffer != "followers" and self.nb.GetCurrentPage().name_buffer != "friends":
|
||||||
@@ -778,6 +818,8 @@ class mainFrame(wx.Frame):
|
|||||||
except:
|
except:
|
||||||
msg = _(u"%s. Empty") % (self.nb.GetPageText(self.nb.GetSelection()))
|
msg = _(u"%s. Empty") % (self.nb.GetPageText(self.nb.GetSelection()))
|
||||||
output.speak(msg, 1)
|
output.speak(msg, 1)
|
||||||
|
if self.showing == True:
|
||||||
|
self.nb.GetCurrentPage().list.list.SetFocus()
|
||||||
|
|
||||||
def right(self, event=None):
|
def right(self, event=None):
|
||||||
num = self.nb.GetSelection()
|
num = self.nb.GetSelection()
|
||||||
@@ -791,21 +833,37 @@ class mainFrame(wx.Frame):
|
|||||||
except:
|
except:
|
||||||
msg = _(u"%s. Empty") % (self.nb.GetPageText(self.nb.GetSelection()))
|
msg = _(u"%s. Empty") % (self.nb.GetPageText(self.nb.GetSelection()))
|
||||||
output.speak(msg, 1)
|
output.speak(msg, 1)
|
||||||
|
if self.showing == True:
|
||||||
|
self.nb.GetCurrentPage().list.list.SetFocus()
|
||||||
|
|
||||||
def show_hide(self, ev=None):
|
def create_invisible_keyboard_shorcuts(self):
|
||||||
# if platform.system() == "Linux" or platform.system() == "Darwin": return
|
|
||||||
keymap = {}
|
keymap = {}
|
||||||
for i in config.main["keymap"]:
|
for i in config.main["keymap"]:
|
||||||
if hasattr(self, i):
|
if hasattr(self, i):
|
||||||
keymap[config.main["keymap"][i]] = getattr(self, i)
|
keymap[config.main["keymap"][i]] = getattr(self, i)
|
||||||
|
return keymap
|
||||||
|
|
||||||
|
def register_invisible_keyboard_shorcuts(self, keymap):
|
||||||
|
self.keyboard_handler = WXKeyboardHandler(self)
|
||||||
|
self.keyboard_handler.register_keys(keymap)
|
||||||
|
|
||||||
|
def unregister_invisible_keyboard_shorcuts(self, keymap):
|
||||||
|
try:
|
||||||
|
self.keyboard_handler.unregister_keys(keymap)
|
||||||
|
del self.keyboard_handler
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def show_hide(self, ev=None):
|
||||||
|
km = self.create_invisible_keyboard_shorcuts()
|
||||||
if self.showing == True:
|
if self.showing == True:
|
||||||
self.keyboard_handler = WXKeyboardHandler(self)
|
if config.main["general"]["use_invisible_keyboard_shorcuts"] == False:
|
||||||
self.keyboard_handler.register_keys(keymap)
|
self.register_invisible_keyboard_shorcuts(km)
|
||||||
self.Hide()
|
self.Hide()
|
||||||
self.showing = False
|
self.showing = False
|
||||||
else:
|
else:
|
||||||
self.keyboard_handler.unregister_keys(keymap)
|
if config.main["general"]["use_invisible_keyboard_shorcuts"] == False:
|
||||||
del self.keyboard_handler
|
self.unregister_invisible_keyboard_shorcuts(km)
|
||||||
self.Show()
|
self.Show()
|
||||||
self.showing = True
|
self.showing = True
|
||||||
|
|
||||||
@@ -959,6 +1017,72 @@ class mainFrame(wx.Frame):
|
|||||||
return page
|
return page
|
||||||
return page
|
return page
|
||||||
|
|
||||||
|
def switch_account(self, ev):
|
||||||
|
switchModule.switcher(self)
|
||||||
|
|
||||||
|
def reverse_geocode(self, event=None):
|
||||||
|
try:
|
||||||
|
tweet = self.nb.GetCurrentPage().get_tweet()
|
||||||
|
if tweet["coordinates"] != None:
|
||||||
|
x = tweet["coordinates"]["coordinates"][0]
|
||||||
|
y = tweet["coordinates"]["coordinates"][1]
|
||||||
|
address = geocoder.reverse_geocode(y, x)
|
||||||
|
if event == None: output.speak(address[0].__str__().decode("utf-8"))
|
||||||
|
else: wx.MessageDialog(self, address[0].__str__().decode("utf-8"), _(u"Address"), wx.OK).ShowModal()
|
||||||
|
else:
|
||||||
|
output.speak(_(u"There are no coordinates in this tweet"))
|
||||||
|
except GeocoderError:
|
||||||
|
output.speak(_(u"There are no results for the coordinates in this tweet"))
|
||||||
|
except ValueError:
|
||||||
|
output.speak(_(u"Error decoding coordinates. Try again later."))
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def view_reverse_geocode(self, event=None):
|
||||||
|
try:
|
||||||
|
tweet = self.nb.GetCurrentPage().get_tweet()
|
||||||
|
if tweet["coordinates"] != None:
|
||||||
|
x = tweet["coordinates"]["coordinates"][0]
|
||||||
|
y = tweet["coordinates"]["coordinates"][1]
|
||||||
|
address = geocoder.reverse_geocode(y, x)
|
||||||
|
dialogs.message.viewNonTweet(address[0].__str__().decode("utf-8")).ShowModal()
|
||||||
|
else:
|
||||||
|
output.speak(_(u"There are no coordinates in this tweet"))
|
||||||
|
except GeocoderError:
|
||||||
|
output.speak(_(u"There are no results for the coordinates in this tweet"))
|
||||||
|
except ValueError:
|
||||||
|
output.speak(_(u"Error decoding coordinates. Try again later."))
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_trending_topics(self, event=None):
|
||||||
|
info = self.twitter.twitter.get_available_trends()
|
||||||
|
trendingDialog = dialogs.trending.trendingTopicsDialog(info)
|
||||||
|
if trendingDialog.ShowModal() == wx.ID_OK:
|
||||||
|
if trendingDialog.country.GetValue() == True:
|
||||||
|
woeid = trendingDialog.countries[trendingDialog.location.GetStringSelection()]
|
||||||
|
elif trendingDialog.city.GetValue() == True:
|
||||||
|
woeid = trendingDialog.cities[trendingDialog.location.GetStringSelection()]
|
||||||
|
buff = buffers.trendsPanel(self.nb, self, "%s_tt" % (woeid,), argumento=woeid, sound="trends_updated.ogg")
|
||||||
|
self.nb.InsertSubPage(self.db.settings["buffers"].index(self.db.settings["user_name"]), buff, _(u"Trending topics for %s") % (trendingDialog.location.GetStringSelection(),))
|
||||||
|
timer = RepeatingTimer(300, buff.start_streams)
|
||||||
|
timer.start()
|
||||||
|
num = buff.start_streams()
|
||||||
|
config.main["other_buffers"]["trending_topic_buffers"].append(woeid)
|
||||||
|
buff.put_items(num)
|
||||||
|
|
||||||
|
def listen_streamerror(self):
|
||||||
|
log.error("There is a connection error")
|
||||||
|
if hasattr(self, "stream"):
|
||||||
|
self.stream.disconnect()
|
||||||
|
del self.stream
|
||||||
|
if hasattr(self, "stream2"):
|
||||||
|
self.stream2.disconnect()
|
||||||
|
del self.stream2
|
||||||
|
|
||||||
|
def listen_for_friends(self):
|
||||||
|
self.stream2.set_friends(self.stream.friends)
|
||||||
|
|
||||||
### Close App
|
### Close App
|
||||||
def Destroy(self):
|
def Destroy(self):
|
||||||
self.sysTray.Destroy()
|
self.sysTray.Destroy()
|
||||||
|
23
src/gui/switchModule.py
Normal file
23
src/gui/switchModule.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import wx
|
||||||
|
import gui
|
||||||
|
import config
|
||||||
|
from sessionmanager import gui as sessionManagerUI
|
||||||
|
|
||||||
|
class switcher(object):
|
||||||
|
def __init__(self, window):
|
||||||
|
self.hold_window = window
|
||||||
|
self.hold_window.Hide()
|
||||||
|
sessionManagerWindow = sessionManagerUI.sessionManagerWindow()
|
||||||
|
if sessionManagerWindow.ShowModal() == wx.ID_OK:
|
||||||
|
self.hold_window.Destroy()
|
||||||
|
self.window = gui.main.mainFrame()
|
||||||
|
self.window.Show()
|
||||||
|
self.window.showing = True
|
||||||
|
if config.main != None and config.main["general"]["hide_gui"] == True:
|
||||||
|
self.window.show_hide()
|
||||||
|
self.window.Hide()
|
||||||
|
wx.GetApp().SetTopWindow(self.window)
|
||||||
|
else:
|
||||||
|
self.hold_window.Show()
|
||||||
|
|
@@ -55,7 +55,7 @@ class SysTrayIcon(wx.TaskBarIcon):
|
|||||||
if (self.frame.showing):
|
if (self.frame.showing):
|
||||||
self.frame.SetFocus()
|
self.frame.SetFocus()
|
||||||
else:
|
else:
|
||||||
self.frame.onShow_hide()
|
self.frame.show_hide()
|
||||||
|
|
||||||
def Destroy(self):
|
def Destroy(self):
|
||||||
self.menu.Destroy()
|
self.menu.Destroy()
|
||||||
|
0
src/issueReporter/__init__.py
Normal file
0
src/issueReporter/__init__.py
Normal file
21
src/issueReporter/constants.py
Normal file
21
src/issueReporter/constants.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
############################################################
|
||||||
|
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
############################################################
|
||||||
|
categories = ["General", "documentation", "translation"]
|
||||||
|
reproducibilities = ["always", "sometimes", "random", "have not tried", "unable to duplicate"]
|
||||||
|
severities = ["block", "crash", "major", "minor", "tweak", "text", "trivial", "feature"]
|
32
src/issueReporter/get_logs.py
Normal file
32
src/issueReporter/get_logs.py
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
############################################################
|
||||||
|
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
############################################################
|
||||||
|
import paths
|
||||||
|
import os
|
||||||
|
|
||||||
|
def get_logs_files():
|
||||||
|
files = {}
|
||||||
|
for i in os.listdir(paths.logs_path()):
|
||||||
|
if i == "debug.log": continue
|
||||||
|
f = open(paths.logs_path(i), "r")
|
||||||
|
files[i] = f.readlines()
|
||||||
|
f.close()
|
||||||
|
try: os.remove(paths.logs_path("tracebacks.log"))
|
||||||
|
except: pass
|
||||||
|
return files
|
||||||
|
|
124
src/issueReporter/gui.py
Normal file
124
src/issueReporter/gui.py
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
############################################################
|
||||||
|
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
############################################################
|
||||||
|
import wx
|
||||||
|
import application
|
||||||
|
from suds.client import Client
|
||||||
|
import constants
|
||||||
|
|
||||||
|
class reportBug(wx.Dialog):
|
||||||
|
def __init__(self, user_name):
|
||||||
|
self.user = "reporter1"
|
||||||
|
self.user_name = user_name
|
||||||
|
self.password = "contrasena"
|
||||||
|
self.url = application.report_bugs_url
|
||||||
|
self.categories = [_(u"General"), _(u"Documentation"), _(u"Translation")]
|
||||||
|
self.reproducibilities = [_(u"always"), _(u"sometimes"), _(u"random"), _(u"have not tried"), _(u"unable to duplicate")]
|
||||||
|
self.severities = [_(u"block"), _(u"crash"), _(u"major"), _(u"minor"), _(u"tweak"), _(u"text"), _(u"trivial"), _(u"feature")]
|
||||||
|
wx.Dialog.__init__(self, None, -1)
|
||||||
|
self.SetTitle(_(u"Report an error"))
|
||||||
|
panel = wx.Panel(self)
|
||||||
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
|
categoryLabel = wx.StaticText(panel, -1, _(u"Select a category"), size=wx.DefaultSize)
|
||||||
|
self.category = wx.ComboBox(panel, -1, choices=self.categories, style=wx.CB_READONLY)
|
||||||
|
self.category.SetSize(self.category.GetBestSize())
|
||||||
|
self.category.SetSelection(0)
|
||||||
|
categoryB = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
categoryB.Add(categoryLabel, 0, wx.ALL, 5)
|
||||||
|
categoryB.Add(self.category, 0, wx.ALL, 5)
|
||||||
|
self.category.SetFocus()
|
||||||
|
sizer.Add(categoryB, 0, wx.ALL, 5)
|
||||||
|
summaryLabel = wx.StaticText(panel, -1, _(u"Briefly describe what happened. You will be able to thoroughly explain it later"), size=wx.DefaultSize)
|
||||||
|
self.summary = wx.TextCtrl(panel, -1)
|
||||||
|
dc = wx.WindowDC(self.summary)
|
||||||
|
dc.SetFont(self.summary.GetFont())
|
||||||
|
self.summary.SetSize(dc.GetTextExtent("a"*80))
|
||||||
|
# self.summary.SetFocus()
|
||||||
|
summaryB = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
summaryB.Add(summaryLabel, 0, wx.ALL, 5)
|
||||||
|
summaryB.Add(self.summary, 0, wx.ALL, 5)
|
||||||
|
sizer.Add(summaryB, 0, wx.ALL, 5)
|
||||||
|
descriptionLabel = wx.StaticText(panel, -1, _(u"Here, you can describe the bug in detail"), size=wx.DefaultSize)
|
||||||
|
self.description = wx.TextCtrl(panel, -1, style=wx.TE_MULTILINE)
|
||||||
|
dc = wx.WindowDC(self.description)
|
||||||
|
dc.SetFont(self.description.GetFont())
|
||||||
|
(x, y, z) = dc.GetMultiLineTextExtent("0"*2000)
|
||||||
|
self.description.SetSize((x, y))
|
||||||
|
descBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
descBox.Add(descriptionLabel, 0, wx.ALL, 5)
|
||||||
|
descBox.Add(self.description, 0, wx.ALL, 5)
|
||||||
|
sizer.Add(descBox, 0, wx.ALL, 5)
|
||||||
|
reproducibilityLabel = wx.StaticText(panel, -1, _(u"how often does this bug happen?"), size=wx.DefaultSize)
|
||||||
|
self.reproducibility = wx.ComboBox(panel, -1, choices=self.reproducibilities, style=wx.CB_READONLY)
|
||||||
|
self.reproducibility.SetSelection(3)
|
||||||
|
self.reproducibility.SetSize(self.reproducibility.GetBestSize())
|
||||||
|
reprB = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
reprB.Add(reproducibilityLabel, 0, wx.ALL, 5)
|
||||||
|
reprB.Add(self.reproducibility, 0, wx.ALL, 5)
|
||||||
|
sizer.Add(reprB, 0, wx.ALL, 5)
|
||||||
|
severityLabel = wx.StaticText(panel, -1, _(u"Select the importance that you think this bug has"))
|
||||||
|
self.severity = wx.ComboBox(panel, -1, choices=self.severities, style=wx.CB_READONLY)
|
||||||
|
self.severity.SetSize(self.severity.GetBestSize())
|
||||||
|
self.severity.SetSelection(3)
|
||||||
|
severityB = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
severityB.Add(severityLabel, 0, wx.ALL, 5)
|
||||||
|
severityB.Add(self.severity, 0, wx.ALL, 5)
|
||||||
|
sizer.Add(severityB, 0, wx.ALL, 5)
|
||||||
|
self.agree = wx.CheckBox(panel, -1, _(u"I know that the TW Blue bug system will get my Twitter username to contact me and fix the bug quickly"))
|
||||||
|
self.agree.SetValue(False)
|
||||||
|
sizer.Add(self.agree, 0, wx.ALL, 5)
|
||||||
|
ok = wx.Button(panel, wx.ID_OK, _(u"Send report"))
|
||||||
|
ok.Bind(wx.EVT_BUTTON, self.onSend)
|
||||||
|
ok.SetDefault()
|
||||||
|
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"Cancel"))
|
||||||
|
btnBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
btnBox.Add(ok, 0, wx.ALL, 5)
|
||||||
|
btnBox.Add(cancel, 0, wx.ALL, 5)
|
||||||
|
sizer.Add(btnBox, 0, wx.ALL, 5)
|
||||||
|
panel.SetSizer(sizer)
|
||||||
|
self.SetClientSize(sizer.CalcMin())
|
||||||
|
|
||||||
|
def onSend(self, ev):
|
||||||
|
if self.summary.GetValue() == "" or self.description.GetValue() == "":
|
||||||
|
wx.MessageDialog(self, _(u"You must fill out both fields"), _(u"Error"), wx.OK|wx.ICON_ERROR).ShowModal()
|
||||||
|
return
|
||||||
|
if self.agree.GetValue() == False:
|
||||||
|
wx.MessageDialog(self, _(u"You need to mark the checkbox to provide us your twitter username to contact to you if is necessary."), _(u"Error"), wx.ICON_ERROR).ShowModal()
|
||||||
|
return
|
||||||
|
# try:
|
||||||
|
client = Client(self.url)
|
||||||
|
issue = client.factory.create('IssueData')
|
||||||
|
issue.project.name = "TWBlue"
|
||||||
|
issue.project.id = 0
|
||||||
|
issue.summary = self.summary.GetValue(),
|
||||||
|
issue.description = "Reported by @%s\n\n" % (self.user_name) + self.description.GetValue()
|
||||||
|
issue.category = constants.categories[self.category.GetSelection()]
|
||||||
|
issue.reproducibility.name = constants.reproducibilities[self.reproducibility.GetSelection()]
|
||||||
|
issue.severity.name = constants.severities[self.severity.GetSelection()]
|
||||||
|
issue.priority.name = "normal"
|
||||||
|
issue.view_state.name = "public"
|
||||||
|
issue.resolution.name = "open"
|
||||||
|
issue.projection.name = "none"
|
||||||
|
issue.eta.name = "eta"
|
||||||
|
issue.status.name = "new"
|
||||||
|
id = client.service.mc_issue_add(self.user, self.password, issue)
|
||||||
|
wx.MessageDialog(self, _(u"Thanks for reporting this bug! In future versions, you may be able to find it in the changes list. You've reported the bug number %i") % (id), _(u"reported"), wx.OK).ShowModal()
|
||||||
|
self.EndModal(wx.ID_OK)
|
||||||
|
# except:
|
||||||
|
# wx.MessageDialog(self, _(u"Something unexpected occurred while trying to report the bug. Please, try again later"), _(u"Error while reporting"), wx.ICON_ERROR|wx.OK).ShowModal()
|
||||||
|
# self.EndModal(wx.ID_CANCEL)
|
@@ -42,4 +42,7 @@ actions = {
|
|||||||
"edit_keystrokes": _(u"Shows the keystroke editor"),
|
"edit_keystrokes": _(u"Shows the keystroke editor"),
|
||||||
"view_user_lists": _(u"Show lists for a specified user"),
|
"view_user_lists": _(u"Show lists for a specified user"),
|
||||||
"get_more_items": _(u"loads previous items to any buffer"),
|
"get_more_items": _(u"loads previous items to any buffer"),
|
||||||
|
"reverse_geocode": _(u"Get location of any tweet"),
|
||||||
|
"view_reverse_geocode": _(u"Displays the tweet's location in a dialog"),
|
||||||
|
"get_trending_topics": _(u"Creates a buffer for displaying trends for a desired place"),
|
||||||
}
|
}
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
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
93
src/main.py
93
src/main.py
@@ -19,57 +19,68 @@ A twitter accessible, easy of use and cross platform application."""
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
############################################################
|
############################################################
|
||||||
|
import sys
|
||||||
|
from StringIO import StringIO
|
||||||
|
#redirect the original stdout and stderr
|
||||||
|
stdout=sys.stdout
|
||||||
|
stderr=sys.stderr
|
||||||
|
# Set a StringIO object as stdout and stderr to avoid problems using the installed version.
|
||||||
|
sys.stdout = StringIO()
|
||||||
|
sys.stderr = StringIO()
|
||||||
import wx
|
import wx
|
||||||
|
import os
|
||||||
ssmg = None
|
ssmg = None
|
||||||
import gui
|
import gui
|
||||||
import paths
|
import paths
|
||||||
import config
|
import config
|
||||||
import commandline
|
import commandline
|
||||||
import platform
|
import platform
|
||||||
if platform.system() == "Windows":
|
from logger import logger as logging
|
||||||
from logger import logger as logging
|
|
||||||
if platform.system() == "Darwin":
|
|
||||||
import osx_prepare
|
|
||||||
osx_prepare.setup()
|
|
||||||
from sessionmanager import manager
|
from sessionmanager import manager
|
||||||
from sessionmanager import gui as smGUI
|
from sessionmanager import gui as smGUI
|
||||||
manager.setup()
|
manager.setup()
|
||||||
import sys
|
import config
|
||||||
|
import output
|
||||||
|
import sound
|
||||||
|
import languageHandler
|
||||||
|
#close the memory buffers for stdout and stderr
|
||||||
|
sys.stdout.close()
|
||||||
|
sys.stderr.close()
|
||||||
|
#if it's a binary version
|
||||||
if hasattr(sys, 'frozen'):
|
if hasattr(sys, 'frozen'):
|
||||||
sys.stderr = open(paths.logs_path("stderr.log"), 'w')
|
sys.stderr = open(paths.logs_path("stderr.log"), 'w')
|
||||||
sys.stdout = open(paths.logs_path("stdout.log"), 'w')
|
sys.stdout = open(paths.logs_path("stdout.log"), 'w')
|
||||||
|
else:
|
||||||
class app(wx.App):
|
sys.stdout=stdout
|
||||||
def __init__(self, *args, **kwargs):
|
sys.stderr=stderr
|
||||||
super(app, self).__init__(*args, **kwargs)
|
|
||||||
if platform.system() != "Darwin":
|
app = wx.App()
|
||||||
self.start()
|
#app = wx.App(redirect=True, useBestVisual=True, filename=paths.logs_path('tracebacks.log'))
|
||||||
else:
|
configured = False
|
||||||
self.mac()
|
configs = []
|
||||||
|
for i in os.listdir(paths.config_path()):
|
||||||
def mac(self):
|
if os.path.isdir(paths.config_path(i)): configs.append(i)
|
||||||
self.hold_frame = wx.Frame(title="None", parent=None)
|
if len(configs) == 1:
|
||||||
self.hold_frame.Show()
|
manager.manager.set_current_session(configs[0])
|
||||||
wx.CallLater(10, self.start)
|
config.MAINFILE = "%s/session.conf" % (manager.manager.get_current_session())
|
||||||
|
config.setup()
|
||||||
def start(self):
|
lang=config.main['general']['language']
|
||||||
ssmg = smGUI.sessionManagerWindow()
|
languageHandler.setLanguage(lang)
|
||||||
if ssmg.ShowModal() == wx.ID_OK:
|
sound.setup()
|
||||||
frame = gui.main.mainFrame()
|
output.setup()
|
||||||
frame.Show()
|
configured = True
|
||||||
frame.showing = True
|
else:
|
||||||
if config.main != None and config.main["general"]["hide_gui"] == True and platform.system() == "Windows":
|
ssmg = smGUI.sessionManagerWindow()
|
||||||
frame.show_hide()
|
if configured == True or ssmg.ShowModal() == wx.ID_OK:
|
||||||
frame.Hide()
|
frame = gui.main.mainFrame()
|
||||||
self.SetTopWindow(frame)
|
frame.Show()
|
||||||
if hasattr(self, "frame"): self.hold_frame.Hide()
|
frame.showing = True
|
||||||
# If the user press on cancel.
|
if config.main != None and config.main["general"]["hide_gui"] == True and platform.system() == "Windows":
|
||||||
else:
|
frame.show_hide()
|
||||||
self.Exit()
|
frame.Hide()
|
||||||
|
app.SetTopWindow(frame)
|
||||||
ap = app()
|
else:
|
||||||
|
app.Exit()
|
||||||
### I should uncomment this
|
### I should uncomment this
|
||||||
#if platform.system() != "Windows":
|
#if platform.system() != "Windows":
|
||||||
# local = wx.Locale(wx.LANGUAGE_DEFAULT)
|
# local = wx.Locale(wx.LANGUAGE_DEFAULT)
|
||||||
@@ -77,5 +88,5 @@ ap = app()
|
|||||||
# local.AddCatalog("twblue")
|
# local.AddCatalog("twblue")
|
||||||
#ap = app(redirect=True, useBestVisual=True, filename=paths.logs_path('tracebacks.log'))
|
#ap = app(redirect=True, useBestVisual=True, filename=paths.logs_path('tracebacks.log'))
|
||||||
#wx.CallLater(10, start)
|
#wx.CallLater(10, start)
|
||||||
ap.MainLoop()
|
app.MainLoop()
|
||||||
|
|
||||||
|
@@ -3,6 +3,7 @@ import threading
|
|||||||
import wx
|
import wx
|
||||||
from twython import TwythonRateLimitError
|
from twython import TwythonRateLimitError
|
||||||
import time
|
import time
|
||||||
|
from wx.lib.pubsub import pub
|
||||||
|
|
||||||
def call_threaded(func, *args, **kwargs):
|
def call_threaded(func, *args, **kwargs):
|
||||||
#Call the given function in a daemonized thread and return the thread.
|
#Call the given function in a daemonized thread and return the thread.
|
||||||
@@ -19,3 +20,14 @@ def call_threaded(func, *args, **kwargs):
|
|||||||
thread.daemon = True
|
thread.daemon = True
|
||||||
thread.start()
|
thread.start()
|
||||||
return thread
|
return thread
|
||||||
|
|
||||||
|
def stream_threaded(func, *args, **kwargs):
|
||||||
|
def new_func(*a, **k):
|
||||||
|
try:
|
||||||
|
func(*a, **k)
|
||||||
|
except:
|
||||||
|
pub.sendMessage("streamError")
|
||||||
|
thread = threading.Thread(target=new_func, args=args, kwargs=kwargs)
|
||||||
|
thread.daemon = True
|
||||||
|
thread.start()
|
||||||
|
return thread
|
@@ -1,4 +1,5 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
import shutil
|
||||||
import time
|
import time
|
||||||
import wx
|
import wx
|
||||||
import manager
|
import manager
|
||||||
@@ -23,28 +24,26 @@ class sessionManagerWindow(wx.Dialog):
|
|||||||
label = wx.StaticText(panel, -1, _(u"Select a twitter account to start TW Blue"), size=wx.DefaultSize)
|
label = wx.StaticText(panel, -1, _(u"Select a twitter account to start TW Blue"), size=wx.DefaultSize)
|
||||||
listSizer = wx.BoxSizer(wx.HORIZONTAL)
|
listSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
self.list = widgets.list(panel, _(u"Account"), style=wx.LC_SINGLE_SEL|wx.LC_REPORT)
|
self.list = widgets.list(panel, _(u"Account"), style=wx.LC_SINGLE_SEL|wx.LC_REPORT)
|
||||||
self.fill_list()
|
|
||||||
listSizer.Add(label, 0, wx.ALL, 5)
|
listSizer.Add(label, 0, wx.ALL, 5)
|
||||||
listSizer.Add(self.list.list, 0, wx.ALL, 5)
|
listSizer.Add(self.list.list, 0, wx.ALL, 5)
|
||||||
sizer.Add(listSizer, 0, wx.ALL, 5)
|
sizer.Add(listSizer, 0, wx.ALL, 5)
|
||||||
new = wx.Button(panel, -1, _(u"New account"), size=wx.DefaultSize)
|
new = wx.Button(panel, -1, _(u"New account"), size=wx.DefaultSize)
|
||||||
new.Bind(wx.EVT_BUTTON, self.new_account)
|
new.Bind(wx.EVT_BUTTON, self.new_account)
|
||||||
|
self.removeSession = wx.Button(panel, -1, _(u"Remove session"))
|
||||||
|
self.removeSession.Disable()
|
||||||
|
self.removeSession.Bind(wx.EVT_BUTTON, self.remove)
|
||||||
ok = wx.Button(panel, wx.ID_OK, size=wx.DefaultSize)
|
ok = wx.Button(panel, wx.ID_OK, size=wx.DefaultSize)
|
||||||
ok.SetDefault()
|
ok.SetDefault()
|
||||||
ok.Bind(wx.EVT_BUTTON, self.ok)
|
ok.Bind(wx.EVT_BUTTON, self.ok)
|
||||||
cancel = wx.Button(panel, wx.ID_CANCEL, size=wx.DefaultSize)
|
cancel = wx.Button(panel, wx.ID_CANCEL, size=wx.DefaultSize)
|
||||||
buttons = wx.BoxSizer(wx.HORIZONTAL)
|
buttons = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
buttons.Add(new, 0, wx.ALL, 5)
|
buttons.Add(new, 0, wx.ALL, 5)
|
||||||
|
buttons.Add(self.removeSession, 0, wx.ALL, 5)
|
||||||
buttons.Add(ok, 0, wx.ALL, 5)
|
buttons.Add(ok, 0, wx.ALL, 5)
|
||||||
buttons.Add(cancel, 0, wx.ALL, 5)
|
buttons.Add(cancel, 0, wx.ALL, 5)
|
||||||
sizer.Add(buttons, 0, wx.ALL, 5)
|
sizer.Add(buttons, 0, wx.ALL, 5)
|
||||||
panel.SetSizer(sizer)
|
panel.SetSizer(sizer)
|
||||||
# sizer.Layout()
|
self.fill_list()
|
||||||
# self.Fit()
|
|
||||||
# self.SetSize(panel.GetBestSize())
|
|
||||||
# panelSizer.Add(panel)
|
|
||||||
# self.SetSizerAndFit(sizer)
|
|
||||||
# sizer.Layout()
|
|
||||||
min = sizer.CalcMin()
|
min = sizer.CalcMin()
|
||||||
self.SetClientSize(min)
|
self.SetClientSize(min)
|
||||||
|
|
||||||
@@ -55,12 +54,16 @@ class sessionManagerWindow(wx.Dialog):
|
|||||||
strconfig = "%s/session.conf" % (paths.config_path(i))
|
strconfig = "%s/session.conf" % (paths.config_path(i))
|
||||||
config_test = Configuration(strconfig)
|
config_test = Configuration(strconfig)
|
||||||
name = config_test["twitter"]["user_name"]
|
name = config_test["twitter"]["user_name"]
|
||||||
if name != "" and config_test["twitter"]["user_key"] != "" and config_test["twitter"]["user_secret"] != "":
|
if name != "" or (config_test["twitter"]["user_key"] != "" and config_test["twitter"]["user_secret"] != ""):
|
||||||
self.list.insert_item(False, name)
|
self.list.insert_item(False, name)
|
||||||
self.sessions.append(i)
|
self.sessions.append(i)
|
||||||
|
else:
|
||||||
|
del config_test
|
||||||
|
shutil.rmtree(path=paths.config_path(i), ignore_errors=True)
|
||||||
if self.list.get_count() > 0:
|
if self.list.get_count() > 0:
|
||||||
self.list.select_item(0)
|
self.list.select_item(0)
|
||||||
self.list.list.SetSize(self.list.list.GetBestSize())
|
self.list.list.SetSize(self.list.list.GetBestSize())
|
||||||
|
self.removeSession.Enable()
|
||||||
|
|
||||||
def ok(self, ev):
|
def ok(self, ev):
|
||||||
if self.list.get_count() == 0:
|
if self.list.get_count() == 0:
|
||||||
@@ -74,8 +77,6 @@ class sessionManagerWindow(wx.Dialog):
|
|||||||
languageHandler.setLanguage(lang)
|
languageHandler.setLanguage(lang)
|
||||||
sound.setup()
|
sound.setup()
|
||||||
output.setup()
|
output.setup()
|
||||||
# else:
|
|
||||||
# self.name = current_session
|
|
||||||
self.EndModal(wx.ID_OK)
|
self.EndModal(wx.ID_OK)
|
||||||
|
|
||||||
def new_account(self, ev):
|
def new_account(self, ev):
|
||||||
@@ -99,3 +100,12 @@ class sessionManagerWindow(wx.Dialog):
|
|||||||
if self.list.get_count() == 1:
|
if self.list.get_count() == 1:
|
||||||
self.list.select_item(0)
|
self.list.select_item(0)
|
||||||
self.sessions.append(location)
|
self.sessions.append(location)
|
||||||
|
|
||||||
|
def remove(self, ev):
|
||||||
|
selected_item = self.list.get_selected()
|
||||||
|
selected_session = self.sessions[selected_item]
|
||||||
|
ask = wx.MessageDialog(self, _(u"Do you really want delete this account?"), _(u"Remove account"), wx.YES_NO)
|
||||||
|
if ask.ShowModal() == wx.ID_YES:
|
||||||
|
self.sessions.remove(selected_session)
|
||||||
|
shutil.rmtree(path=paths.config_path(selected_session), ignore_errors=True)
|
||||||
|
self.list.remove_item(selected_item)
|
@@ -34,7 +34,7 @@ def get_architecture_files():
|
|||||||
("Microsoft.VC90.MFC", glob("../windows-dependencies/x86/Microsoft.VC90.MFC/*")),]
|
("Microsoft.VC90.MFC", glob("../windows-dependencies/x86/Microsoft.VC90.MFC/*")),]
|
||||||
elif platform.architecture()[0][:2] == "64":
|
elif platform.architecture()[0][:2] == "64":
|
||||||
return [
|
return [
|
||||||
("", ["../windows-dependencies/x64/oggenc2.exe", "../windows-dependencies/x86/bootstrap.exe"]),
|
("", ["../windows-dependencies/x64/oggenc2.exe", "../windows-dependencies/x64/bootstrap.exe"]),
|
||||||
("Microsoft.VC90.CRT", glob("../windows-dependencies/x64/Microsoft.VC90.CRT/*")),
|
("Microsoft.VC90.CRT", glob("../windows-dependencies/x64/Microsoft.VC90.CRT/*")),
|
||||||
("Microsoft.VC90.MFC", glob("../windows-dependencies/x64/Microsoft.VC90.MFC/*")),]
|
("Microsoft.VC90.MFC", glob("../windows-dependencies/x64/Microsoft.VC90.MFC/*")),]
|
||||||
|
|
||||||
@@ -90,7 +90,8 @@ data_files = get_data(),
|
|||||||
options = {
|
options = {
|
||||||
'py2exe': {
|
'py2exe': {
|
||||||
'optimize':2,
|
'optimize':2,
|
||||||
'dll_excludes': ["MPR.dll", "api-ms-win-core-apiquery-l1-1-0.dll", "api-ms-win-core-console-l1-1-0.dll", "api-ms-win-core-delayload-l1-1-1.dll", "api-ms-win-core-errorhandling-l1-1-1.dll", "api-ms-win-core-file-l1-2-0.dll", "api-ms-win-core-handle-l1-1-0.dll", "api-ms-win-core-heap-obsolete-l1-1-0.dll", "api-ms-win-core-libraryloader-l1-1-1.dll", "api-ms-win-core-localization-l1-2-0.dll", "api-ms-win-core-processenvironment-l1-2-0.dll", "api-ms-win-core-processthreads-l1-1-1.dll", "api-ms-win-core-profile-l1-1-0.dll", "api-ms-win-core-registry-l1-1-0.dll", "api-ms-win-core-synch-l1-2-0.dll", "api-ms-win-core-sysinfo-l1-2-0.dll", "api-ms-win-security-base-l1-2-0.dll", "api-ms-win-core-heap-l1-2-0.dll", "api-ms-win-core-interlocked-l1-2-0.dll", "api-ms-win-core-localization-obsolete-l1-1-0.dll", "api-ms-win-core-string-l1-1-0.dll", "api-ms-win-core-string-obsolete-l1-1-0.dll", "WLDAP32.dll", "MSVCP90.dll"],
|
'packages': ["wx.lib.pubsub", "wx.lib.pubsub.core", "wx.lib.pubsub.core.kwargs"],
|
||||||
|
'dll_excludes': ["MPR.dll", "api-ms-win-core-apiquery-l1-1-0.dll", "api-ms-win-core-console-l1-1-0.dll", "api-ms-win-core-delayload-l1-1-1.dll", "api-ms-win-core-errorhandling-l1-1-1.dll", "api-ms-win-core-file-l1-2-0.dll", "api-ms-win-core-handle-l1-1-0.dll", "api-ms-win-core-heap-obsolete-l1-1-0.dll", "api-ms-win-core-libraryloader-l1-1-1.dll", "api-ms-win-core-localization-l1-2-0.dll", "api-ms-win-core-processenvironment-l1-2-0.dll", "api-ms-win-core-processthreads-l1-1-1.dll", "api-ms-win-core-profile-l1-1-0.dll", "api-ms-win-core-registry-l1-1-0.dll", "api-ms-win-core-synch-l1-2-0.dll", "api-ms-win-core-sysinfo-l1-2-0.dll", "api-ms-win-security-base-l1-2-0.dll", "api-ms-win-core-heap-l1-2-0.dll", "api-ms-win-core-interlocked-l1-2-0.dll", "api-ms-win-core-localization-obsolete-l1-1-0.dll", "api-ms-win-core-string-l1-1-0.dll", "api-ms-win-core-string-obsolete-l1-1-0.dll", "WLDAP32.dll", "MSVCP90.dll", "MFC90.dll"],
|
||||||
'skip_archive': True
|
'skip_archive': True
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
BIN
src/sounds/default/geo.ogg
Normal file
BIN
src/sounds/default/geo.ogg
Normal file
Binary file not shown.
BIN
src/sounds/default/trends_updated.ogg
Normal file
BIN
src/sounds/default/trends_updated.ogg
Normal file
Binary file not shown.
@@ -1,5 +1,5 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from twitter import compose
|
from twitter import compose, utils
|
||||||
from twython import TwythonStreamer
|
from twython import TwythonStreamer
|
||||||
import sound
|
import sound
|
||||||
from mysc import event
|
from mysc import event
|
||||||
@@ -34,13 +34,20 @@ class streamer(TwythonStreamer):
|
|||||||
tweet_event.SetItem(data)
|
tweet_event.SetItem(data)
|
||||||
announce = _(u"One tweet from %s in the list %s") % (data["user"]["name"], self.parent.nb.GetPage(i).name_buffer[:-5])
|
announce = _(u"One tweet from %s in the list %s") % (data["user"]["name"], self.parent.nb.GetPage(i).name_buffer[:-5])
|
||||||
tweet_event.SetAnnounce(announce)
|
tweet_event.SetAnnounce(announce)
|
||||||
wx.PostEvent(self.parent.nb.GetPage(i), tweet_event)
|
usr = data["in_reply_to_user_id"]
|
||||||
|
if (usr != None and usr in self.friends) or data.has_key("retweeted_status"):
|
||||||
|
wx.PostEvent(self.parent.nb.GetPage(i), tweet_event)
|
||||||
|
elif usr == None:
|
||||||
|
wx.PostEvent(self.parent.nb.GetPage(i), tweet_event)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def set_friends(self, friends):
|
||||||
|
self.friends = friends
|
||||||
|
|
||||||
def on_success(self, data):
|
def on_success(self, data):
|
||||||
try:
|
try:
|
||||||
if data.has_key("text"):
|
if data.has_key("text") and utils.is_allowed(data):
|
||||||
self.check_tls(data)
|
self.check_tls(data)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
@@ -8,6 +8,7 @@ import config
|
|||||||
import logging as original_logger
|
import logging as original_logger
|
||||||
log = original_logger.getLogger("MainStream")
|
log = original_logger.getLogger("MainStream")
|
||||||
import output
|
import output
|
||||||
|
from wx.lib.pubsub import pub
|
||||||
|
|
||||||
class streamer(TwythonStreamer):
|
class streamer(TwythonStreamer):
|
||||||
def __init__(self, app_key, app_secret, oauth_token, oauth_token_secret, timeout=300, retry_count=None, retry_in=10, client_args=None, handlers=None, chunk_size=1, parent=None):
|
def __init__(self, app_key, app_secret, oauth_token, oauth_token_secret, timeout=300, retry_count=None, retry_in=10, client_args=None, handlers=None, chunk_size=1, parent=None):
|
||||||
@@ -51,7 +52,7 @@ class streamer(TwythonStreamer):
|
|||||||
wx.PostEvent(self.parent.search_buffer("buffer", "favs"), tweet_event)
|
wx.PostEvent(self.parent.search_buffer("buffer", "favs"), tweet_event)
|
||||||
|
|
||||||
def check_mentions(self, data):
|
def check_mentions(self, data):
|
||||||
if "@%s" % (self.db.settings["user_name"]) in data["text"]:
|
if "@%s" % (self.db.settings["user_name"].lower()) in data["text"].lower():
|
||||||
tweet_event = event.event(event.EVT_OBJECT, 1)
|
tweet_event = event.event(event.EVT_OBJECT, 1)
|
||||||
tweet_event.SetItem(data)
|
tweet_event.SetItem(data)
|
||||||
text = _(u"One mention from %s ") % (data["user"]["name"])
|
text = _(u"One mention from %s ") % (data["user"]["name"])
|
||||||
@@ -68,15 +69,14 @@ class streamer(TwythonStreamer):
|
|||||||
tweet_event.SetItem(data["direct_message"])
|
tweet_event.SetItem(data["direct_message"])
|
||||||
text = _(u"One direct message")
|
text = _(u"One direct message")
|
||||||
tweet_event.SetAnnounce(text)
|
tweet_event.SetAnnounce(text)
|
||||||
wx.PostEvent(self.parent.search_buffer("buffer", "direct_messages"), tweet_event)
|
wx.PostEvent(self.parent.search_buffer("direct_message", "direct_messages"), tweet_event)
|
||||||
|
|
||||||
def check_follower(self, data):
|
def check_follower(self, data):
|
||||||
if data["target"]["screen_name"] == self.db.settings["user_name"]:
|
if data["target"]["screen_name"] == self.db.settings["user_name"] and config.main["other_buffers"]["show_followers"] == True:
|
||||||
if config.main["other_buffers"]["show_followers"] == True:
|
tweet_event = event.event(event.EVT_OBJECT, 1)
|
||||||
tweet_event = event.event(event.EVT_OBJECT, 1)
|
tweet_event.SetItem(data["source"])
|
||||||
tweet_event.SetItem(data["source"])
|
wx.PostEvent(self.parent.search_buffer("people", "followers"), tweet_event)
|
||||||
wx.PostEvent(self.parent.search_buffer("people", "followers"), tweet_event)
|
elif data["source"]["screen_name"] == self.db.settings["user_name"]:
|
||||||
elif data["source"]["screen_name"] == self.db.settings["user_name"] and config.main["other_buffers"]["show_friends"] == True:
|
|
||||||
tweet_event = event.event(event.EVT_OBJECT, 1)
|
tweet_event = event.event(event.EVT_OBJECT, 1)
|
||||||
tweet_event.SetItem(data["target"])
|
tweet_event.SetItem(data["target"])
|
||||||
wx.PostEvent(self.parent.search_buffer("people", "friends"), tweet_event)
|
wx.PostEvent(self.parent.search_buffer("people", "friends"), tweet_event)
|
||||||
@@ -106,6 +106,7 @@ class streamer(TwythonStreamer):
|
|||||||
self.process_dm(data)
|
self.process_dm(data)
|
||||||
elif "friends" in data:
|
elif "friends" in data:
|
||||||
self.friends = data["friends"]
|
self.friends = data["friends"]
|
||||||
|
pub.sendMessage("friendsReceived")
|
||||||
elif "text" in data and utils.is_allowed(data) == True:
|
elif "text" in data and utils.is_allowed(data) == True:
|
||||||
if data["user"]["id"] in self.muted_users: return
|
if data["user"]["id"] in self.muted_users: return
|
||||||
self.check_mentions(data)
|
self.check_mentions(data)
|
||||||
@@ -119,7 +120,7 @@ class streamer(TwythonStreamer):
|
|||||||
self.check_favs(data)
|
self.check_favs(data)
|
||||||
elif "unfavorite" == data["event"] and config.main["other_buffers"]["show_favourites"] == True:
|
elif "unfavorite" == data["event"] and config.main["other_buffers"]["show_favourites"] == True:
|
||||||
self.remove_fav(data)
|
self.remove_fav(data)
|
||||||
elif "follow" == data["event"] and config.main["other_buffers"]["show_followers"] == True:
|
elif "follow" == data["event"]:
|
||||||
self.check_follower(data)
|
self.check_follower(data)
|
||||||
elif "unfollow" == data["event"] and config.main["other_buffers"]["show_followers"] == True:
|
elif "unfollow" == data["event"] and config.main["other_buffers"]["show_followers"] == True:
|
||||||
self.remove_friend(data)
|
self.remove_friend(data)
|
||||||
|
@@ -13,6 +13,8 @@ else:
|
|||||||
languageHandler.setLanguage("system")
|
languageHandler.setLanguage("system")
|
||||||
import platform
|
import platform
|
||||||
system = platform.system()
|
system = platform.system()
|
||||||
|
import logging as original_logger
|
||||||
|
log = original_logger.getLogger("events")
|
||||||
|
|
||||||
def prettydate(d):
|
def prettydate(d):
|
||||||
""" Converts a string to the relative time."""
|
""" Converts a string to the relative time."""
|
||||||
@@ -153,7 +155,7 @@ def compose_tweet(tweet, db):
|
|||||||
else: user = tweet["sender"]["name"]
|
else: user = tweet["sender"]["name"]
|
||||||
elif tweet.has_key("user"):
|
elif tweet.has_key("user"):
|
||||||
user = tweet["user"]["name"]
|
user = tweet["user"]["name"]
|
||||||
source = re.sub(r"(?s)<.*?>", " ", tweet["source"])
|
source = re.sub(r"(?s)<.*?>", "", tweet["source"])
|
||||||
try: text = "rt @%s: %s" % (tweet["retweeted_status"]["user"]["screen_name"], StripChars(tweet["retweeted_status"]["text"]))
|
try: text = "rt @%s: %s" % (tweet["retweeted_status"]["user"]["screen_name"], StripChars(tweet["retweeted_status"]["text"]))
|
||||||
except KeyError: text = "%s" % (StripChars(tweet["text"]))
|
except KeyError: text = "%s" % (StripChars(tweet["text"]))
|
||||||
if text[-1] in chars: text=text+"."
|
if text[-1] in chars: text=text+"."
|
||||||
@@ -224,7 +226,9 @@ def compose_event(data, username):
|
|||||||
elif data["event"] == "list_user_unsubscribed":
|
elif data["event"] == "list_user_unsubscribed":
|
||||||
if data["source"]["screen_name"] == username: event = _(u"You've unsubscribed from the list %s, which is owned by %s(@%s)") % (data["target_object"]["name"], data["target"]["name"], data["target"]["screen_name"])
|
if data["source"]["screen_name"] == username: event = _(u"You've unsubscribed from the list %s, which is owned by %s(@%s)") % (data["target_object"]["name"], data["target"]["name"], data["target"]["screen_name"])
|
||||||
else: event = _("You've been unsubscribed from the list %s, which is owned by %s(@%s)") % (data["target_object"]["name"], data["source"]["name"], data["source"]["screen_name"])
|
else: event = _("You've been unsubscribed from the list %s, which is owned by %s(@%s)") % (data["target_object"]["name"], data["source"]["name"], data["source"]["screen_name"])
|
||||||
else: event = _("Unknown")
|
else:
|
||||||
|
log.error("event: %s\n target: %s\n source: %s\n" % (data["event"], data["target"], data["source"]))
|
||||||
|
event = _("Unknown")
|
||||||
# output.speak(event)
|
# output.speak(event)
|
||||||
return [time.strftime("%I:%M %p"), event]
|
return [time.strftime("%I:%M %p"), event]
|
||||||
|
|
||||||
|
@@ -75,15 +75,16 @@ def start_stream(db, twitter, name, function, param=None):
|
|||||||
last_id = 0
|
last_id = 0
|
||||||
if len(db.settings[name]) > 0:
|
if len(db.settings[name]) > 0:
|
||||||
for i in tl:
|
for i in tl:
|
||||||
if int(i["id"]) > int(last_id):
|
if int(i["id"]) > int(last_id) and utils.is_allowed(i) == True:
|
||||||
if config.main["general"]["reverse_timelines"] == False: db.settings[name].append(i)
|
if config.main["general"]["reverse_timelines"] == False: db.settings[name].append(i)
|
||||||
else: db.settings[name].insert(0, i)
|
else: db.settings[name].insert(0, i)
|
||||||
num = num+1
|
num = num+1
|
||||||
elif len(db.settings[name]) == 0:
|
elif len(db.settings[name]) == 0:
|
||||||
for i in tl:
|
for i in tl:
|
||||||
if config.main["general"]["reverse_timelines"] == False: db.settings[name].append(i)
|
if utils.is_allowed(i) == True:
|
||||||
else: db.settings[name].insert(0, i)
|
if config.main["general"]["reverse_timelines"] == False: db.settings[name].append(i)
|
||||||
num = num+1
|
else: db.settings[name].insert(0, i)
|
||||||
|
num = num+1
|
||||||
# db.settings.update()
|
# db.settings.update()
|
||||||
return num
|
return num
|
||||||
|
|
||||||
@@ -121,7 +122,7 @@ def update_stream(config, twitter, name, function, param=None, sndFile=""):
|
|||||||
tl = function(sinze_id=config.settings[name][-1]["id"], screen_name=param, count=config.main["general"]["max_tweets_per_call"])
|
tl = function(sinze_id=config.settings[name][-1]["id"], screen_name=param, count=config.main["general"]["max_tweets_per_call"])
|
||||||
tl.reverse()
|
tl.reverse()
|
||||||
for i in tl:
|
for i in tl:
|
||||||
if i["id"] > config.settings[name][-1]["id"]:
|
if i["id"] > config.settings[name][-1]["id"] and utils.is_allowed(i) == True:
|
||||||
config.settings[name].append(i)
|
config.settings[name].append(i)
|
||||||
sounded = True
|
sounded = True
|
||||||
num = num+1
|
num = num+1
|
||||||
@@ -171,7 +172,7 @@ def start_sent(db, twitter, name, function, param=None):
|
|||||||
num = num+1
|
num = num+1
|
||||||
return num
|
return num
|
||||||
|
|
||||||
def start_list(db, twitter, name, list_id):
|
def start_list(db, twitter, name, list_id, *args, **kwargs):
|
||||||
num = 0
|
num = 0
|
||||||
if db.settings.has_key(name):
|
if db.settings.has_key(name):
|
||||||
try:
|
try:
|
||||||
@@ -181,23 +182,24 @@ def start_list(db, twitter, name, list_id):
|
|||||||
last_id = db.settings[name][-1]["id"]
|
last_id = db.settings[name][-1]["id"]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
pass
|
pass
|
||||||
tl = twitter.twitter.get_list_statuses(list_id=list_id, count=200)
|
tl = twitter.twitter.get_list_statuses(list_id=list_id, *args, **kwargs)
|
||||||
else:
|
else:
|
||||||
tl = twitter.twitter.get_list_statuses(list_id=list_id, count=200)
|
tl = twitter.twitter.get_list_statuses(list_id=list_id, *args, **kwargs)
|
||||||
tl.reverse()
|
tl.reverse()
|
||||||
db.settings[name] = []
|
db.settings[name] = []
|
||||||
last_id = 0
|
last_id = 0
|
||||||
if len(db.settings[name]) > 0:
|
if len(db.settings[name]) > 0:
|
||||||
for i in tl:
|
for i in tl:
|
||||||
if int(i["id"]) > int(last_id):
|
if int(i["id"]) > int(last_id) and utils.is_allowed(i) == True:
|
||||||
if config.main["general"]["reverse_timelines"] == False: db.settings[name].append(i)
|
if config.main["general"]["reverse_timelines"] == False: db.settings[name].append(i)
|
||||||
else: db.settings[name].insert(0, i)
|
else: db.settings[name].insert(0, i)
|
||||||
num = num+1
|
num = num+1
|
||||||
elif len(db.settings[name]) == 0:
|
elif len(db.settings[name]) == 0:
|
||||||
for i in tl:
|
for i in tl:
|
||||||
if config.main["general"]["reverse_timelines"] == False: db.settings[name].append(i)
|
if utils.is_allowed(i) == True:
|
||||||
else: db.settings[name].insert(0, i)
|
if config.main["general"]["reverse_timelines"] == False: db.settings[name].append(i)
|
||||||
num = num+1
|
else: db.settings[name].insert(0, i)
|
||||||
|
num = num+1
|
||||||
db.settings.update()
|
db.settings.update()
|
||||||
return num
|
return num
|
||||||
|
|
||||||
@@ -209,15 +211,16 @@ def search(db, twitter, name, *args, **kwargs):
|
|||||||
tl["statuses"].reverse()
|
tl["statuses"].reverse()
|
||||||
if len(db.settings[name]) > 0:
|
if len(db.settings[name]) > 0:
|
||||||
for i in tl["statuses"]:
|
for i in tl["statuses"]:
|
||||||
if utils.find_item(i["id"], db.settings[name]) == None:
|
if utils.find_item(i["id"], db.settings[name]) == None and utils.is_allowed(i):
|
||||||
if config.main["general"]["reverse_timelines"] == False: db.settings[name].append(i)
|
if config.main["general"]["reverse_timelines"] == False: db.settings[name].append(i)
|
||||||
else: db.settings[name].insert(0, i)
|
else: db.settings[name].insert(0, i)
|
||||||
num = num+1
|
num = num+1
|
||||||
elif len(db.settings[name]) == 0:
|
elif len(db.settings[name]) == 0:
|
||||||
for i in tl["statuses"]:
|
for i in tl["statuses"]:
|
||||||
if config.main["general"]["reverse_timelines"] == False: db.settings[name].append(i)
|
if utils.is_allowed(i) == True:
|
||||||
else: db.settings[name].insert(0, i)
|
if config.main["general"]["reverse_timelines"] == False: db.settings[name].append(i)
|
||||||
num = num+1
|
else: db.settings[name].insert(0, i)
|
||||||
|
num = num+1
|
||||||
return num
|
return num
|
||||||
|
|
||||||
def search_users(db, twitter, name, *args, **kwargs):
|
def search_users(db, twitter, name, *args, **kwargs):
|
||||||
@@ -247,13 +250,14 @@ def get_favourites_timeline(db, twitter, name, param, *args, **kwargs):
|
|||||||
tl.reverse()
|
tl.reverse()
|
||||||
if len(db.settings[name]) > 0:
|
if len(db.settings[name]) > 0:
|
||||||
for i in tl:
|
for i in tl:
|
||||||
if utils.find_item(i["id"], db.settings[name]) == None:
|
if utils.find_item(i["id"], db.settings[name]) == None and utils.is_allowed(i) == True:
|
||||||
if config.main["general"]["reverse_timelines"] == False: db.settings[name].append(i)
|
if config.main["general"]["reverse_timelines"] == False: db.settings[name].append(i)
|
||||||
else: db.settings[name].insert(0, i)
|
else: db.settings[name].insert(0, i)
|
||||||
num = num+1
|
num = num+1
|
||||||
elif len(db.settings[name]) == 0:
|
elif len(db.settings[name]) == 0:
|
||||||
for i in tl:
|
for i in tl:
|
||||||
if config.main["general"]["reverse_timelines"] == False: db.settings[name].append(i)
|
if utils.is_allowed(i) == True:
|
||||||
else: db.settings[name].insert(0, i)
|
if config.main["general"]["reverse_timelines"] == False: db.settings[name].append(i)
|
||||||
num = num+1
|
else: db.settings[name].insert(0, i)
|
||||||
|
num = num+1
|
||||||
return num
|
return num
|
@@ -25,6 +25,7 @@ class handler(BaseHTTPServer.BaseHTTPRequestHandler):
|
|||||||
verifier = params.get('oauth_verifier', [None])[0]
|
verifier = params.get('oauth_verifier', [None])[0]
|
||||||
self.wfile.write("You have successfully logged in to Twitter with TW Blue. "
|
self.wfile.write("You have successfully logged in to Twitter with TW Blue. "
|
||||||
"You can close this window now.")
|
"You can close this window now.")
|
||||||
|
self.wfile.close()
|
||||||
|
|
||||||
class twitter(object):
|
class twitter(object):
|
||||||
|
|
||||||
@@ -39,7 +40,7 @@ class twitter(object):
|
|||||||
|
|
||||||
def authorise(self):
|
def authorise(self):
|
||||||
httpd = BaseHTTPServer.HTTPServer(('127.0.0.1', 8080), handler)
|
httpd = BaseHTTPServer.HTTPServer(('127.0.0.1', 8080), handler)
|
||||||
twitter = Twython(application.app_key, application.app_secret)
|
twitter = Twython(application.app_key, application.app_secret, auth_endpoint='authorize')
|
||||||
auth = twitter.get_authentication_tokens("http://127.0.0.1:8080")
|
auth = twitter.get_authentication_tokens("http://127.0.0.1:8080")
|
||||||
webbrowser.open_new_tab(auth['auth_url'])
|
webbrowser.open_new_tab(auth['auth_url'])
|
||||||
global logged, verifier
|
global logged, verifier
|
||||||
@@ -48,6 +49,8 @@ class twitter(object):
|
|||||||
self.twitter = Twython(application.app_key, application.app_secret, auth['oauth_token'], auth['oauth_token_secret'])
|
self.twitter = Twython(application.app_key, application.app_secret, auth['oauth_token'], auth['oauth_token_secret'])
|
||||||
final = self.twitter.get_authorized_tokens(verifier)
|
final = self.twitter.get_authorized_tokens(verifier)
|
||||||
self.save_configuration(final["oauth_token"], final["oauth_token_secret"])
|
self.save_configuration(final["oauth_token"], final["oauth_token_secret"])
|
||||||
|
httpd.server_close()
|
||||||
|
|
||||||
|
|
||||||
def save_configuration(self, user_key=None, user_secret=None):
|
def save_configuration(self, user_key=None, user_secret=None):
|
||||||
if user_key != None and user_secret != None:
|
if user_key != None and user_secret != None:
|
||||||
|
@@ -58,9 +58,12 @@ def is_audio(tweet):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def is_geocoded(tweet):
|
||||||
|
if tweet.has_key("coordinates") and tweet["coordinates"] != None:
|
||||||
|
return True
|
||||||
|
|
||||||
def get_all_mentioned(tweet, config):
|
def get_all_mentioned(tweet, config):
|
||||||
""" Gets all users that has been mentioned."""
|
""" Gets all users that has been mentioned."""
|
||||||
if tweet.has_key("retweeted_status"): tweet = tweet["retweeted_status"]
|
|
||||||
string = []
|
string = []
|
||||||
for i in tweet["entities"]["user_mentions"]:
|
for i in tweet["entities"]["user_mentions"]:
|
||||||
if i["screen_name"] != config.settings["user_name"] and i["screen_name"] != tweet["user"]["screen_name"]:
|
if i["screen_name"] != config.settings["user_name"] and i["screen_name"] != tweet["user"]["screen_name"]:
|
||||||
@@ -106,9 +109,12 @@ def api_call(parent=None, call_name=None, preexec_message="", success="", succes
|
|||||||
return val
|
return val
|
||||||
|
|
||||||
def is_allowed(tweet):
|
def is_allowed(tweet):
|
||||||
allowed = True
|
try:
|
||||||
if tweet.has_key("retweeted_status"): tweet = tweet["retweeted_status"]
|
allowed = True
|
||||||
source = re.sub(r"(?s)<.*?>", "", tweet["source"])
|
if tweet.has_key("retweeted_status"): tweet = tweet["retweeted_status"]
|
||||||
for i in config.main["twitter"]["ignored_clients"]:
|
source = re.sub(r"(?s)<.*?>", "", tweet["source"])
|
||||||
if i.lower() == source.lower(): allowed = False
|
for i in config.main["twitter"]["ignored_clients"]:
|
||||||
return allowed
|
if i.lower() == source.lower(): allowed = False
|
||||||
|
return allowed
|
||||||
|
except KeyError:
|
||||||
|
return True
|
@@ -26,8 +26,9 @@ def check_for_update(msg=False):
|
|||||||
else:
|
else:
|
||||||
progress.Update(percent, _(u"Update"))
|
progress.Update(percent, _(u"Update"))
|
||||||
def update_complete():
|
def update_complete():
|
||||||
wx.MessageDialog(None, _(u"The new TW Blue version has been downloaded and installed. Press OK to start the application."), _(u"Done!")).ShowModal()
|
ms = wx.MessageDialog(None, _(u"The new TW Blue version has been downloaded and installed. Press OK to start the application."), _(u"Done!"))
|
||||||
sys.exit()
|
if ms.ShowModal() == wx.ID_OK:
|
||||||
|
sys.exit()
|
||||||
app_updater = updater.AutoUpdater(url, new_path, 'bootstrap.exe', app_path=paths.app_path(), postexecute=paths.app_path("TWBlue.exe"), finish_callback=update_complete, percentage_callback=update)
|
app_updater = updater.AutoUpdater(url, new_path, 'bootstrap.exe', app_path=paths.app_path(), postexecute=paths.app_path("TWBlue.exe"), finish_callback=update_complete, percentage_callback=update)
|
||||||
app_updater.start_update()
|
app_updater.start_update()
|
||||||
progress.ShowModal()
|
progress.ShowModal()
|
||||||
|
3
src/widgetUtils/__init__.py
Normal file
3
src/widgetUtils/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import platform
|
||||||
|
if platform.system() == "Windows":
|
||||||
|
from wxUtils import *
|
32
src/widgetUtils/wxUtils.py
Normal file
32
src/widgetUtils/wxUtils.py
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import wx
|
||||||
|
|
||||||
|
# Code responses for WX dialogs.
|
||||||
|
# this is when an user presses OK on a dialogue.
|
||||||
|
OK = wx.ID_OK
|
||||||
|
# This is when an user presses cancel on a dialogue.
|
||||||
|
CANCEL = wx.ID_CANCEL
|
||||||
|
# This is when an user closes the dialogue or an id to create the close button.
|
||||||
|
CLOSE = wx.ID_CLOSE
|
||||||
|
# The response for a "yes" Button pressed on a dialogue.
|
||||||
|
YES = wx.ID_YES
|
||||||
|
# This is when the user presses No on a default dialogue.
|
||||||
|
NO = wx.ID_NO
|
||||||
|
|
||||||
|
#events
|
||||||
|
# This is raised when the application must be closed.
|
||||||
|
CLOSE_EVENT = wx.EVT_CLOSE
|
||||||
|
# This is activated when a button is pressed.
|
||||||
|
BUTTON_PRESSED = wx.EVT_BUTTON
|
||||||
|
# This is activated when an user enter text on an edit box.
|
||||||
|
ENTERED_TEXT = wx.EVT_TEXT
|
||||||
|
|
||||||
|
def exit_application():
|
||||||
|
""" Closes the current window cleanly. """
|
||||||
|
wx.GetApp().ExitMainLoop()
|
||||||
|
|
||||||
|
def connect_event(parent, event, func):
|
||||||
|
""" Connects an event to a function.
|
||||||
|
parent wx.window: The widget that will listen for the event.
|
||||||
|
event widgetUtils.event: The event that will be listened for the parent. The event should be one of the widgetUtils events.
|
||||||
|
function func: The function that will be connected to the event."""
|
||||||
|
return getattr(parent, "Bind")(event, func)
|
57
tools/build_twblue.sh
Normal file
57
tools/build_twblue.sh
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Define paths for a regular use, if there are not paths for python32 or 64, these commands will be taken.
|
||||||
|
pythonpath32="/C/python27x86"
|
||||||
|
pythonpath64="/C/python27"
|
||||||
|
nsyspath=$PROGRAMFILES/NSIS
|
||||||
|
|
||||||
|
help () {
|
||||||
|
echo -e "$0 | usage:"
|
||||||
|
echo -e "$0 | \t./generate_installer.sh [-py32path <path to python for 32 bits> | -py64path <path for python on 64 bits> | -nsyspath <path to nsys> | -h]"
|
||||||
|
}
|
||||||
|
|
||||||
|
# parsing options from the command line
|
||||||
|
while [[ $# > 1 ]]
|
||||||
|
do
|
||||||
|
key="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
case $key in
|
||||||
|
-py32path)
|
||||||
|
pythonpath32="$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-py64path)
|
||||||
|
pythonpath64="$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-nsispath)
|
||||||
|
nsispath="$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-help)
|
||||||
|
help
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
help
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
cd ../src
|
||||||
|
if [ -d build/ ];
|
||||||
|
then
|
||||||
|
rm -rf build
|
||||||
|
fi
|
||||||
|
if [ -d dist/ ];
|
||||||
|
then
|
||||||
|
rm -rf dist
|
||||||
|
fi
|
||||||
|
$pythonpath32/python.exe "setup.py" "py2exe" "--quiet"
|
||||||
|
mv -f dist ../scripts/TWBlue
|
||||||
|
rm -rf build
|
||||||
|
$pythonpath64/python.exe "setup.py" "py2exe" "--quiet"
|
||||||
|
mv -f dist ../scripts/TWBlue64
|
||||||
|
rm -rf build
|
||||||
|
cd ../scripts
|
||||||
|
$nsispath/Unicode/makensis.exe "twblue.nsi"
|
||||||
|
rm -rf TWBlue
|
||||||
|
rm -rf TWBlue64
|
@@ -1,13 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
mkdir ../src/documentation
|
|
||||||
for i in `ls ../documentation`
|
|
||||||
do
|
|
||||||
if test -d ../documentation/$i
|
|
||||||
then
|
|
||||||
mkdir ../src/documentation/$i
|
|
||||||
pandoc -s ../documentation/$i/changes.md -o ../src/documentation/$i/changes.html
|
|
||||||
pandoc -s ../documentation/$i/manual.md -o ../src/documentation/$i/manual.html
|
|
||||||
cp ../documentation/license.txt ../src/documentation/license.txt
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
exit
|
|
File diff suppressed because it is too large
Load Diff
982
tools/twblue.pot
982
tools/twblue.pot
File diff suppressed because it is too large
Load Diff
1
windows-dependencies
Submodule
1
windows-dependencies
Submodule
Submodule windows-dependencies added at 739034e207
Reference in New Issue
Block a user