mirror of
https://github.com/MCV-Software/TWBlue.git
synced 2025-08-25 09:29:22 +00:00
Compare commits
101 Commits
alpha9
...
v2021.10.3
Author | SHA1 | Date | |
---|---|---|---|
5a6dc23524 | |||
0e2ff4de8a | |||
36340d0596 | |||
92ec178754 | |||
5eb942981c | |||
6739045cce | |||
307ed093af | |||
d11fc44772 | |||
a3e5eec6de | |||
41a0935121 | |||
0b03e7505f | |||
![]() |
81c364c4e1 | ||
![]() |
483b196203 | ||
![]() |
b512c69447 | ||
2c1608322e | |||
c6bb851bce | |||
![]() |
66581f8b1c | ||
![]() |
c6a3a44c21 | ||
bd25cfa59b | |||
![]() |
39a02ea33a | ||
f672dca1cb | |||
19c63b7b07 | |||
e23a52e38f | |||
![]() |
d888563fda | ||
a5ba80feee | |||
528ecc2a33 | |||
3519746078 | |||
ef79e0696e | |||
b9ee0dae5b | |||
f31575a733 | |||
e451bbd5e9 | |||
f7f303929e | |||
9f48784ce4 | |||
cb1312d0c9 | |||
a82efd4dcc | |||
72e6d030d5 | |||
d222740887 | |||
2b059ee42e | |||
daac312658 | |||
b23be9c896 | |||
61b0dc34b8 | |||
c5d13369eb | |||
856ecf5eb9 | |||
e3e0ac9457 | |||
fccf02794c | |||
34c1f69ec1 | |||
7326ff88f9 | |||
![]() |
a8d876a7b7 | ||
![]() |
89fa6435b4 | ||
![]() |
d1bd393be2 | ||
301bd5fd39 | |||
![]() |
a2f25bfbb5 | ||
286e030f40 | |||
d8fca3b31a | |||
0c27427843 | |||
dfdbe3c5f4 | |||
![]() |
2222a97451 | ||
fbe93ea4be | |||
4bcae1aa97 | |||
4cabf5b9cd | |||
a9a4189295 | |||
c7b6d69518 | |||
65512a9862 | |||
![]() |
17ea8af050 | ||
![]() |
43578a32eb | ||
7c34204d17 | |||
3a5c1c10d3 | |||
f9864a887d | |||
3d8519313e | |||
f4ecf10885 | |||
c67b415934 | |||
10511d3022 | |||
![]() |
ddc80a29fd | ||
9ea36a26d2 | |||
97286496fc | |||
![]() |
6436af76f5 | ||
![]() |
576b5064c0 | ||
![]() |
342265b3c0 | ||
![]() |
54938ecb6c | ||
![]() |
7aff8252d2 | ||
![]() |
9c680130f7 | ||
24d1ad093d | |||
b2b9cd810f | |||
582be54dea | |||
ff0fbeafa3 | |||
e314cf0599 | |||
![]() |
e7b72112cf | ||
![]() |
70c095febe | ||
6119b029f8 | |||
b74cd9a73d | |||
8ff6809f08 | |||
39af9d8623 | |||
3688d7548c | |||
07f9afb14e | |||
de12dadac2 | |||
877c909482 | |||
![]() |
1206aba83b | ||
![]() |
fcd631b2de | ||
![]() |
86130954d7 | ||
![]() |
23a56c637d | ||
![]() |
d5ac0db67b |
@@ -1,6 +1,6 @@
|
||||
variables:
|
||||
GIT_SUBMODULE_STRATEGY: recursive
|
||||
PYTHON: "C:\\python38\\python.exe"
|
||||
PYTHON: "C:\\python37\\python.exe"
|
||||
NSIS: "C:\\program files (x86)\\nsis\\makensis.exe"
|
||||
|
||||
stages:
|
||||
@@ -8,7 +8,7 @@ stages:
|
||||
- make_installer
|
||||
- upload
|
||||
|
||||
snapshot32:
|
||||
twblue32:
|
||||
tags:
|
||||
- shared-windows
|
||||
- windows
|
||||
@@ -17,11 +17,10 @@ snapshot32:
|
||||
- Set-Variable -Name "time" -Value (date -Format "%H:%m")
|
||||
- echo ${time}
|
||||
- echo "started by ${GITLAB_USER_NAME}"
|
||||
- choco install python --version 3.8.10 -y -ForceX86
|
||||
- choco install python --version 3.7.9 -y -ForceX86
|
||||
- '&$env:PYTHON -V'
|
||||
- '&$env:PYTHON -m pip install --upgrade pip'
|
||||
- '&$env:PYTHON -m pip install --upgrade -r requirements.txt'
|
||||
- '&$env:PYTHON -m pip uninstall enum34 -y'
|
||||
stage: build
|
||||
interruptible: true
|
||||
script:
|
||||
@@ -30,6 +29,7 @@ snapshot32:
|
||||
- '&$env:PYTHON documentation_importer.py'
|
||||
- cd ..\src
|
||||
- '&$env:PYTHON ..\doc\generator.py'
|
||||
- '&$env:PYTHON write_version_data.py'
|
||||
- '&$env:PYTHON setup.py build'
|
||||
- cd ..
|
||||
- mkdir artifacts
|
||||
@@ -37,7 +37,9 @@ snapshot32:
|
||||
- '&$env:PYTHON make_archive.py'
|
||||
- cd ..
|
||||
- mv src/dist artifacts/TWBlue
|
||||
- move src/twblue.zip artifacts/twblue_snapshot_x86.zip
|
||||
- move src/twblue.zip artifacts/twblue_x86.zip
|
||||
# Move the generated script nsis file to artifacts, so we won't need python when generating the installer.
|
||||
- move scripts/twblue.nsi artifacts/twblue.nsi
|
||||
only:
|
||||
- tags
|
||||
artifacts:
|
||||
@@ -45,7 +47,7 @@ snapshot32:
|
||||
- artifacts
|
||||
expire_in: 1 day
|
||||
|
||||
snapshot64:
|
||||
twblue64:
|
||||
tags:
|
||||
- shared-windows
|
||||
- windows
|
||||
@@ -54,7 +56,7 @@ snapshot64:
|
||||
- Set-Variable -Name "time" -Value (date -Format "%H:%m")
|
||||
- echo ${time}
|
||||
- echo "started by ${GITLAB_USER_NAME}"
|
||||
- choco install python --version 3.8.10 -y
|
||||
- choco install python --version 3.7.9 -y
|
||||
- '&$env:PYTHON -V'
|
||||
- '&$env:PYTHON -m pip install --upgrade pip'
|
||||
- '&$env:PYTHON -m pip install --upgrade -r requirements.txt'
|
||||
@@ -66,6 +68,7 @@ snapshot64:
|
||||
- '&$env:PYTHON documentation_importer.py'
|
||||
- cd ..\src
|
||||
- '&$env:PYTHON ..\doc\generator.py'
|
||||
- '&$env:PYTHON write_version_data.py'
|
||||
- '&$env:PYTHON setup.py build'
|
||||
- cd ..
|
||||
- mkdir artifacts
|
||||
@@ -73,7 +76,7 @@ snapshot64:
|
||||
- '&$env:PYTHON make_archive.py'
|
||||
- cd ..
|
||||
- mv src/dist artifacts/TWBlue64
|
||||
- move src/twblue.zip artifacts/twblue_snapshot_x64.zip
|
||||
- move src/twblue.zip artifacts/twblue_x64.zip
|
||||
only:
|
||||
- tags
|
||||
artifacts:
|
||||
@@ -95,9 +98,10 @@ generate_versions:
|
||||
script:
|
||||
- move artifacts/TWBlue scripts/
|
||||
- move artifacts/TWBlue64 scripts/
|
||||
- move artifacts/twblue.nsi scripts/installer.nsi
|
||||
- cd scripts
|
||||
- '&$env:NSIS twblue_snapshot.nsi'
|
||||
- move twblue_snapshot_setup.exe ../artifacts
|
||||
- '&$env:NSIS installer.nsi'
|
||||
- move twblue_setup.exe ../artifacts
|
||||
only:
|
||||
- tags
|
||||
artifacts:
|
||||
|
@@ -2,6 +2,17 @@
|
||||
|
||||
## changes in this version
|
||||
|
||||
* Added an user alias manager, located in the application menu in the menu bar. From this dialog, it is possible to review, add, edit or remove user aliases for the current account. ([#401](https://github.com/manuelcortez/TWBlue/issues/401))
|
||||
* TWBlue now closes the VLC player window automatically when a video reaches its end. ([#399](https://github.com/manuelcortez/TWBlue/issues/399))
|
||||
* After a lot of time, TWBlue now uses a new default Soundpack, called FreakyBlue. This soundpack will be set by default in all new sessions created in the application. Thanks to [Andre Louis](https://twitter.com/FreakyFwoof) for the pack. ([#247](https://github.com/manuelcortez/TWBlue/issues/247))
|
||||
* When reading a tweet, if the tweet contains more than 2 consecutive mentions, TWBlue will announce how many more users the tweet includes, as opposed to read every user in the conversation. You still can display the tweet to read all users.
|
||||
* In the tweet displayer, It is possible to copy a link to the current tweet or person by pressing a button called "copy link to clipboard".
|
||||
* Added a keymap capable to work under Windows 11. ([#391](https://github.com/manuelcortez/TWBlue/pull/391))
|
||||
* Added user aliases to TWBlue. This feature allows you to rename user's display names on Twitter, so the next time you'll read an user it will be announced as you configured. For adding an alias to an user, select the "add alias" option in the user menu, located in the menu bar. This feature works only if you have set display screen names unchecked. Users are displayed with their display name in people buffers only. This action is supported in all keymaps, although it is undefined by default. ([#389](https://github.com/manuelcortez/TWBlue/pull/389))
|
||||
* There are some changes to the autocomplete users feature:
|
||||
* Now users can search for twitter screen names or display names in the database.
|
||||
* It is possible to undefine keystrokes in the current keymap in TWBlue. This allows you, for example, to redefine keystrokes completely.
|
||||
* We have changed our Geocoding service to the Nominatim API from OpenStreetMap. Addresses present in tweets are going to be determined by this service, as the Google Maps API now requires an API key. ([#390](https://github.com/manuelcortez/TWBlue/issues/390))
|
||||
* Added a limited version of the Twitter's Streaming API: The Streaming API will work only for tweets, and will receive tweets only by people you follow. Protected users are not possible to be streamed. It is possible that during high tweet traffic, the Stream might get disconnected at times, but TWBlue should be capable of detecting this problem and reconnecting the stream again. ([#385](https://github.com/manuelcortez/TWBlue/pull/385))
|
||||
* Fixed an issue that made TWBlue to not show a dialog when attempting to show a profile for a suspended user. ([#387](https://github.com/manuelcortez/TWBlue/issues/387))
|
||||
* Added support for Twitter audio and videos: Tweets which contains audio or videos will be detected as audio items, and you can playback those with the regular command to play audios. ([#384,](https://github.com/manuelcortez/TWBlue/pull/384))
|
||||
|
@@ -5,19 +5,6 @@ return "key\0";
|
||||
char *get_api_secret(){
|
||||
return "secret_key\0";
|
||||
}
|
||||
char *get_dropbox_api_key(){
|
||||
return "key\0";
|
||||
}
|
||||
char *get_dropbox_api_secret(){
|
||||
return "secret_key\0";
|
||||
}
|
||||
char *get_twishort_api_key(){
|
||||
return "key\0";
|
||||
}
|
||||
char *get_bts_user(){
|
||||
return "user\0";
|
||||
}
|
||||
char *get_bts_password(){
|
||||
return "pass\0";
|
||||
}
|
||||
|
||||
|
@@ -3,10 +3,6 @@
|
||||
|
||||
char *get_api_key();
|
||||
char *get_api_secret();
|
||||
char *get_dropbox_api_key();
|
||||
char *get_dropbox_api_secret();
|
||||
char *get_twishort_api_key();
|
||||
char *get_bts_user();
|
||||
char *get_bts_password();
|
||||
|
||||
#endif
|
||||
|
@@ -9,7 +9,7 @@ oauthlib
|
||||
requests-oauthlib
|
||||
requests-toolbelt
|
||||
pypubsub
|
||||
pygeocoder
|
||||
geopy
|
||||
arrow
|
||||
python-dateutil
|
||||
futures
|
||||
@@ -25,6 +25,7 @@ urllib3
|
||||
youtube-dl
|
||||
python-vlc
|
||||
pypiwin32
|
||||
pywin32
|
||||
certifi
|
||||
backports.functools_lru_cache
|
||||
cx_freeze
|
||||
@@ -32,6 +33,21 @@ tweepy
|
||||
twitter-text-parser
|
||||
pyenchant
|
||||
sqlitedict
|
||||
cx-Logging
|
||||
h11
|
||||
h2
|
||||
hpack
|
||||
hstspreload
|
||||
httpcore
|
||||
httpx
|
||||
hyperframe
|
||||
rfc3986
|
||||
sniffio
|
||||
attrs
|
||||
importlib-metadata
|
||||
numpy
|
||||
pillow
|
||||
charset-normalizer
|
||||
git+https://github.com/accessibleapps/libloader
|
||||
git+https://github.com/accessibleapps/platform_utils
|
||||
git+https://github.com/accessibleapps/accessible_output2
|
||||
|
@@ -15,10 +15,10 @@ SetCompressor /solid lzma
|
||||
SetDatablockOptimize on
|
||||
VIAddVersionKey ProductName "TWBlue"
|
||||
VIAddVersionKey LegalCopyright "Copyright 2014-2021 Manuel Cortéz."
|
||||
VIAddVersionKey ProductVersion "0.95"
|
||||
VIAddVersionKey FileVersion "0.95"
|
||||
VIProductVersion "0.95.0.0"
|
||||
VIFileVersion "0.95.0.0"
|
||||
VIAddVersionKey ProductVersion "0.95.0"
|
||||
VIAddVersionKey FileVersion "0.95.0"
|
||||
VIProductVersion "0.95.0"
|
||||
VIFileVersion "0.95.0"
|
||||
!insertmacro MUI_PAGE_WELCOME
|
||||
!define MUI_LICENSEPAGE_RADIOBUTTONS
|
||||
!insertmacro MUI_PAGE_LICENSE "license.txt"
|
||||
@@ -32,7 +32,7 @@ var StartMenuFolder
|
||||
!insertmacro MUI_PAGE_FINISH
|
||||
!insertmacro MUI_UNPAGE_CONFIRM
|
||||
!insertmacro MUI_UNPAGE_INSTFILES
|
||||
!insertmacro MUI_LANGUAGE "English"
|
||||
!insertmacro MUI_LANGUAGE "English"
|
||||
!insertmacro MUI_LANGUAGE "French"
|
||||
!insertmacro MUI_LANGUAGE "Spanish"
|
||||
!insertmacro MUI_LANGUAGE "Italian"
|
||||
@@ -73,9 +73,9 @@ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "U
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall" "InstallLocation" $INSTDIR
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall" "Publisher" "Manuel Cortéz"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "DisplayVersion" "0.95"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "URLInfoAbout" "http://twblue.es"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "URLInfoAbout" "https://twblue.es"
|
||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "VersionMajor" 0
|
||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "VersionMinor" 95
|
||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "VersionMinor" 0
|
||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "NoModify" 1
|
||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "NoRepair" 1
|
||||
SectionEnd
|
||||
|
@@ -1,95 +0,0 @@
|
||||
!include "MUI2.nsh"
|
||||
!include "LogicLib.nsh"
|
||||
!include "x64.nsh"
|
||||
Unicode true
|
||||
CRCCheck on
|
||||
ManifestSupportedOS all
|
||||
XPStyle on
|
||||
Name "TWBlue"
|
||||
OutFile "TWBlue_snapshot_setup.exe"
|
||||
InstallDir "$PROGRAMFILES\twblue"
|
||||
InstallDirRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "InstallLocation"
|
||||
RequestExecutionLevel admin
|
||||
SetCompress auto
|
||||
SetCompressor /solid lzma
|
||||
SetDatablockOptimize on
|
||||
VIAddVersionKey ProductName "TWBlue Snapshot version"
|
||||
VIAddVersionKey LegalCopyright "Copyright 2014-2021 Manuel Cortéz."
|
||||
VIAddVersionKey ProductVersion "9"
|
||||
VIAddVersionKey FileVersion "9"
|
||||
VIProductVersion "9.0.0.0"
|
||||
VIFileVersion "9.0.0.0"
|
||||
!insertmacro MUI_PAGE_WELCOME
|
||||
!define MUI_LICENSEPAGE_RADIOBUTTONS
|
||||
!insertmacro MUI_PAGE_LICENSE "license.txt"
|
||||
!insertmacro MUI_PAGE_DIRECTORY
|
||||
var StartMenuFolder
|
||||
!insertmacro MUI_PAGE_STARTMENU startmenu $StartMenuFolder
|
||||
!insertmacro MUI_PAGE_INSTFILES
|
||||
!define MUI_FINISHPAGE_LINK "Visit TWBlue website"
|
||||
!define MUI_FINISHPAGE_LINK_LOCATION "https://twblue.es"
|
||||
!define MUI_FINISHPAGE_RUN "$INSTDIR\TWBlue.exe"
|
||||
!insertmacro MUI_PAGE_FINISH
|
||||
!insertmacro MUI_UNPAGE_CONFIRM
|
||||
!insertmacro MUI_UNPAGE_INSTFILES
|
||||
!insertmacro MUI_LANGUAGE "English"
|
||||
!insertmacro MUI_LANGUAGE "French"
|
||||
!insertmacro MUI_LANGUAGE "Spanish"
|
||||
!insertmacro MUI_LANGUAGE "Italian"
|
||||
!insertmacro MUI_LANGUAGE "Finnish"
|
||||
!insertmacro MUI_LANGUAGE "Russian"
|
||||
!insertmacro MUI_LANGUAGE "PortugueseBR"
|
||||
!insertmacro MUI_LANGUAGE "Polish"
|
||||
!insertmacro MUI_LANGUAGE "German"
|
||||
!insertmacro MUI_LANGUAGE "Hungarian"
|
||||
!insertmacro MUI_LANGUAGE "Turkish"
|
||||
!insertmacro MUI_LANGUAGE "Arabic"
|
||||
!insertmacro MUI_LANGUAGE "Galician"
|
||||
!insertmacro MUI_LANGUAGE "Catalan"
|
||||
!insertmacro MUI_LANGUAGE "Basque"
|
||||
!insertmacro MUI_LANGUAGE "Croatian"
|
||||
!insertmacro MUI_LANGUAGE "Japanese"
|
||||
!insertmacro MUI_LANGUAGE "SerbianLatin"
|
||||
!insertmacro MUI_LANGUAGE "Romanian"
|
||||
!insertmacro MUI_RESERVEFILE_LANGDLL
|
||||
Section
|
||||
SetShellVarContext All
|
||||
SetOutPath "$INSTDIR"
|
||||
${If} ${RunningX64}
|
||||
File /r TWBlue64\*
|
||||
${Else}
|
||||
File /r TWBlue\*
|
||||
${EndIf}
|
||||
CreateShortCut "$DESKTOP\TWBlue.lnk" "$INSTDIR\TWBlue.exe"
|
||||
!insertmacro MUI_STARTMENU_WRITE_BEGIN startmenu
|
||||
CreateDirectory "$SMPROGRAMS\$StartMenuFolder"
|
||||
CreateShortCut "$SMPROGRAMS\$StartMenuFolder\TWBlue.lnk" "$INSTDIR\TWBlue.exe"
|
||||
CreateShortCut "$SMPROGRAMS\$StartMenuFolder\TWBlue on the web.lnk" "http://twblue.es"
|
||||
CreateShortCut "$SMPROGRAMS\$StartMenuFolder\Uninstall.lnk" "$INSTDIR\Uninstall.exe"
|
||||
!insertmacro MUI_STARTMENU_WRITE_END
|
||||
WriteUninstaller "$INSTDIR\Uninstall.exe"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "DisplayName" "TWBlue"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "UninstallString" '"$INSTDIR\uninstall.exe"'
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall" "InstallLocation" $INSTDIR
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall" "Publisher" "Manuel Cortéz"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "DisplayVersion" "9"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "URLInfoAbout" "https://twblue.es"
|
||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "VersionMajor" 0
|
||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "VersionMinor" 0
|
||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "NoModify" 1
|
||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "NoRepair" 1
|
||||
SectionEnd
|
||||
Section "Uninstall"
|
||||
SetShellVarContext All
|
||||
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue"
|
||||
RMDir /r /REBOOTOK $INSTDIR
|
||||
Delete "$DESKTOP\TWBlue.lnk"
|
||||
!insertmacro MUI_STARTMENU_GETFOLDER startmenu $StartMenuFolder
|
||||
RMDir /r "$SMPROGRAMS\$StartMenuFolder"
|
||||
SectionEnd
|
||||
Function .onInit
|
||||
${If} ${RunningX64}
|
||||
StrCpy $instdir "$programfiles64\twblue"
|
||||
${EndIf}
|
||||
!insertmacro MUI_LANGDLL_DISPLAY
|
||||
FunctionEnd
|
@@ -21,7 +21,7 @@ volume = float(default=1.0)
|
||||
input_device = string(default="Default")
|
||||
output_device = string(default="Default")
|
||||
session_mute = boolean(default=False)
|
||||
current_soundpack = string(default="default")
|
||||
current_soundpack = string(default="FreakyBlue")
|
||||
indicate_audio = boolean(default=True)
|
||||
indicate_geo = boolean(default=True)
|
||||
indicate_img = boolean(default=True)
|
||||
@@ -49,3 +49,5 @@ braille_reporting = boolean(default=True)
|
||||
speech_reporting = boolean(default=True)
|
||||
|
||||
[filters]
|
||||
|
||||
[user-aliases]
|
@@ -3,15 +3,8 @@ import datetime
|
||||
|
||||
name = 'TWBlue'
|
||||
short_name='twblue'
|
||||
snapshot = True
|
||||
if snapshot == False:
|
||||
version = "0.95"
|
||||
update_url = 'https://twblue.es/updates/stable.php'
|
||||
mirror_update_url = 'https://raw.githubusercontent.com/manuelcortez/TWBlue/next-gen/updates/stable.json'
|
||||
else:
|
||||
version = "9"
|
||||
update_url = 'https://twblue.es/updates/snapshot.php'
|
||||
mirror_update_url = 'https://raw.githubusercontent.com/manuelcortez/TWBlue/next-gen/updates/snapshots.json'
|
||||
update_url = 'https://twblue.es/updates/updates.php'
|
||||
mirror_update_url = 'https://raw.githubusercontent.com/manuelcortez/TWBlue/next-gen/updates/updates.json'
|
||||
authors = ["Manuel Cortéz", "José Manuel Delicado"]
|
||||
authorEmail = "manuel@manuelcortez.net"
|
||||
copyright = "Copyright (C) 2013-2021, Manuel cortéz."
|
||||
@@ -20,3 +13,4 @@ translators = ["Manuel Cortéz (English)", "Mohammed Al Shara, Hatoun Felemban (
|
||||
url = u"https://twblue.es"
|
||||
report_bugs_url = "https://github.com/manuelcortez/twblue/issues"
|
||||
supported_languages = []
|
||||
version = "11"
|
||||
|
@@ -21,7 +21,7 @@ from audio_services import youtube_utils
|
||||
from controller.buffers.base import base
|
||||
from sessions.twitter import compose, utils, reduce
|
||||
from mysc.thread_utils import call_threaded
|
||||
from tweepy.error import TweepError
|
||||
from tweepy.errors import TweepyException
|
||||
from tweepy.cursor import Cursor
|
||||
from pubsub import pub
|
||||
from sessions.twitter.long_tweets import twishort, tweets
|
||||
@@ -140,7 +140,7 @@ class BaseBuffer(base.Buffer):
|
||||
try:
|
||||
tweet = self.session.twitter.get_status(id=tweet_id, include_ext_alt_text=True, tweet_mode="extended")
|
||||
tweet.full_text = utils.expand_urls(tweet.full_text, tweet.entities)
|
||||
except TweepError as e:
|
||||
except TweepyException as e:
|
||||
utils.twitter_error(e)
|
||||
return
|
||||
if message != None:
|
||||
@@ -151,7 +151,7 @@ class BaseBuffer(base.Buffer):
|
||||
try:
|
||||
tweet = self.session.twitter.get_status(id=l, include_ext_alt_text=True, tweet_mode="extended")
|
||||
tweet.full_text = utils.expand_urls(tweet.full_text, tweet.entities)
|
||||
except TweepError as e:
|
||||
except TweepyException as e:
|
||||
utils.twitter_error(e)
|
||||
return
|
||||
l = tweets.is_long(tweet)
|
||||
@@ -191,8 +191,8 @@ class BaseBuffer(base.Buffer):
|
||||
log.debug("Retrieved %d items from the cursored search on function %s." %(len(val), self.function))
|
||||
user_ids = [item.message_create["sender_id"] for item in val]
|
||||
self.session.save_users(user_ids)
|
||||
except TweepError as e:
|
||||
log.error("Error %s: %s" % (e.api_code, e.reason))
|
||||
except TweepyException as e:
|
||||
log.exception("Error %s" % (str(e)))
|
||||
return
|
||||
number_of_items = self.session.order_buffer(self.name, val)
|
||||
log.debug("Number of items retrieved: %d" % (number_of_items,))
|
||||
@@ -229,15 +229,15 @@ class BaseBuffer(base.Buffer):
|
||||
last_id = self.session.db[self.name][-1].id
|
||||
try:
|
||||
items = getattr(self.session.twitter, self.function)(max_id=last_id, count=self.session.settings["general"]["max_tweets_per_call"], *self.args, **self.kwargs)
|
||||
except TweepError as e:
|
||||
log.error("Error %s: %s" % (e.api_code, e.reason))
|
||||
except TweepyException as e:
|
||||
log.exception("Error %s" % (str(e)))
|
||||
return
|
||||
if items == None:
|
||||
return
|
||||
items_db = self.session.db[self.name]
|
||||
self.session.add_users_from_results(items)
|
||||
for i in items:
|
||||
if utils.is_allowed(i, self.session.settings, self.name) == True and utils.find_item(i.id, self.session.db[self.name]) == None:
|
||||
if utils.is_allowed(i, self.session.settings, self.name) == True and utils.find_item(i, self.session.db[self.name]) == None:
|
||||
i = reduce.reduce_tweet(i)
|
||||
i = self.session.check_quoted_status(i)
|
||||
i = self.session.check_long_tweet(i)
|
||||
@@ -611,13 +611,13 @@ class BaseBuffer(base.Buffer):
|
||||
items = self.session.db[self.name]
|
||||
try:
|
||||
if self.name == "direct_messages" or self.name == "sent_direct_messages":
|
||||
self.session.twitter.destroy_direct_message(id=self.get_right_tweet().id)
|
||||
self.session.twitter.delete_direct_message(id=self.get_right_tweet().id)
|
||||
items.pop(index)
|
||||
else:
|
||||
self.session.twitter.destroy_status(id=self.get_right_tweet().id)
|
||||
items.pop(index)
|
||||
self.buffer.list.remove_item(index)
|
||||
except TweepError:
|
||||
except TweepyException:
|
||||
self.session.sound.play("error.ogg")
|
||||
self.session.db[self.name] = items
|
||||
|
||||
@@ -644,8 +644,12 @@ class BaseBuffer(base.Buffer):
|
||||
original_tweet.text = utils.find_urls_in_text(original_tweet.text, original_tweet.entities)
|
||||
return compose.compose_quoted_tweet(quoted_tweet, original_tweet, self.session.db, self.session.settings["general"]["relative_times"])
|
||||
|
||||
def open_in_browser(self, *args, **kwargs):
|
||||
def get_item_url(self):
|
||||
tweet = self.get_tweet()
|
||||
output.speak(_(u"Opening item in web browser..."))
|
||||
url = "https://twitter.com/{screen_name}/status/{tweet_id}".format(screen_name=self.session.get_user(tweet.user).screen_name, tweet_id=tweet.id)
|
||||
return url
|
||||
|
||||
def open_in_browser(self, *args, **kwargs):
|
||||
url = self.get_item_url()
|
||||
output.speak(_(u"Opening item in web browser..."))
|
||||
webbrowser.open(url)
|
@@ -10,7 +10,7 @@ import logging
|
||||
from controller import messages
|
||||
from sessions.twitter import compose, utils
|
||||
from mysc.thread_utils import call_threaded
|
||||
from tweepy.error import TweepError
|
||||
from tweepy.errors import TweepyException
|
||||
from pubsub import pub
|
||||
from . import base
|
||||
|
||||
@@ -40,8 +40,8 @@ class DirectMessagesBuffer(base.BaseBuffer):
|
||||
results = [i for i in items]
|
||||
items = results
|
||||
log.debug("Retrieved %d items for cursored search in function %s" % (len(items), self.function))
|
||||
except TweepError as e:
|
||||
log.error("Error %s: %s" % (e.api_code, e.reason))
|
||||
except TweepyException as e:
|
||||
log.exception("Error %s" % (str(e)))
|
||||
return
|
||||
if items == None:
|
||||
return
|
||||
|
@@ -24,7 +24,7 @@ class ListBuffer(base.BaseBuffer):
|
||||
super(ListBuffer, self).start_stream(mandatory, play_sound, avoid_autoreading)
|
||||
|
||||
def get_user_ids(self):
|
||||
for i in Cursor(self.session.twitter.list_members, list_id=self.list_id, include_entities=False, skip_status=True, count=5000).items():
|
||||
for i in Cursor(self.session.twitter.get_list_members, list_id=self.list_id, include_entities=False, skip_status=True, count=5000).items():
|
||||
if i.id not in self.users:
|
||||
self.users.append(i.id)
|
||||
|
||||
|
@@ -14,7 +14,7 @@ import output
|
||||
import config
|
||||
import logging
|
||||
from mysc.thread_utils import call_threaded
|
||||
from tweepy.error import TweepError
|
||||
from tweepy.errors import TweepyException
|
||||
from pubsub import pub
|
||||
from sessions.twitter import compose
|
||||
from . import base
|
||||
@@ -125,8 +125,8 @@ class PeopleBuffer(base.BaseBuffer):
|
||||
val = results
|
||||
val.reverse()
|
||||
log.debug("Retrieved %d items from cursored search in function %s" % (len(val), self.function))
|
||||
except TweepError as e:
|
||||
log.error("Error %s: %s" % (e.api_code, e.reason))
|
||||
except TweepyException as e:
|
||||
log.exception("Error %s" % (str(e)))
|
||||
return
|
||||
number_of_items = self.session.order_people(self.name, val)
|
||||
log.debug("Number of items retrieved: %d" % (number_of_items,))
|
||||
@@ -155,8 +155,8 @@ class PeopleBuffer(base.BaseBuffer):
|
||||
results = [i for i in items]
|
||||
items = results
|
||||
log.debug("Retrieved %d items from cursored search in function %s" % (len(items), self.function))
|
||||
except TweepError as e:
|
||||
log.error("Error %s: %s" % (e.api_code, e.reason))
|
||||
except TweepyException as e:
|
||||
log.exception("Error %s" % (str(e)))
|
||||
return
|
||||
if items == None:
|
||||
return
|
||||
@@ -252,8 +252,7 @@ class PeopleBuffer(base.BaseBuffer):
|
||||
elif number_of_items > 1 and self.name in self.session.settings["other_buffers"]["autoread_buffers"] and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and self.session.settings["sound"]["session_mute"] == False:
|
||||
output.speak(_(u"{0} new followers.").format(number_of_items))
|
||||
|
||||
def open_in_browser(self, *args, **kwargs):
|
||||
def get_item_url(self, *args, **kwargs):
|
||||
tweet = self.get_tweet()
|
||||
output.speak(_(u"Opening item in web browser..."))
|
||||
url = "https://twitter.com/{screen_name}".format(screen_name=tweet.screen_name)
|
||||
webbrowser.open(url)
|
||||
return url
|
@@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import time
|
||||
import platform
|
||||
import locale
|
||||
if platform.system() == "Windows":
|
||||
from wxUI import commonMessageDialogs
|
||||
elif platform.system() == "Linux":
|
||||
@@ -8,6 +9,7 @@ elif platform.system() == "Linux":
|
||||
from gtkUI import commonMessageDialogs
|
||||
import widgetUtils
|
||||
import logging
|
||||
from tweepy.errors import TweepyException
|
||||
from . import base, people
|
||||
|
||||
log = logging.getLogger("controller.buffers.twitter.searchBuffer")
|
||||
@@ -64,35 +66,11 @@ class SearchPeopleBuffer(people.PeopleBuffer):
|
||||
class ConversationBuffer(SearchBuffer):
|
||||
|
||||
def start_stream(self, start=False, mandatory=False, play_sound=True, avoid_autoreading=False):
|
||||
# starts stream every 3 minutes.
|
||||
current_time = time.time()
|
||||
if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory == True:
|
||||
self.execution_time = current_time
|
||||
if start == True:
|
||||
self.statuses = []
|
||||
self.ids = []
|
||||
self.statuses.append(self.tweet)
|
||||
self.ids.append(self.tweet.id)
|
||||
tweet = self.tweet
|
||||
if not hasattr(tweet, "in_reply_to_status_id"):
|
||||
tweet.in_reply_to_status_id = None
|
||||
while tweet.in_reply_to_status_id != None:
|
||||
try:
|
||||
tweet = self.session.twitter.get_status(id=tweet.in_reply_to_status_id, tweet_mode="extended")
|
||||
except TweepError as err:
|
||||
break
|
||||
self.statuses.insert(0, tweet)
|
||||
self.ids.append(tweet.id)
|
||||
if tweet.in_reply_to_status_id == None:
|
||||
self.kwargs["since_id"] = tweet.id
|
||||
self.ids.append(tweet.id)
|
||||
val2 = self.session.search(self.name, tweet_mode="extended", *self.args, **self.kwargs)
|
||||
for i in val2:
|
||||
if i.in_reply_to_status_id in self.ids:
|
||||
self.statuses.append(i)
|
||||
self.ids.append(i.id)
|
||||
tweet = i
|
||||
number_of_items = self.session.order_buffer(self.name, self.statuses)
|
||||
results = self.get_replies(self.tweet)
|
||||
number_of_items = self.session.order_buffer(self.name, results)
|
||||
log.debug("Number of items retrieved: %d" % (number_of_items,))
|
||||
self.put_items_on_list(number_of_items)
|
||||
if number_of_items > 0 and self.sound != None and self.session.settings["sound"]["session_mute"] == False and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and play_sound == True:
|
||||
@@ -113,3 +91,33 @@ class ConversationBuffer(SearchBuffer):
|
||||
return True
|
||||
elif dlg == widgetUtils.NO:
|
||||
return False
|
||||
|
||||
def get_replies(self, tweet):
|
||||
""" Try to retrieve the whole conversation for the passed object by using a mix between calls to API V1.1 and V2 """
|
||||
results = []
|
||||
# If the tweet that starts the conversation is a reply to something else, let's try to get the parent tweet first.
|
||||
if hasattr(self, "in_reply_to_status_id") and self.tweet.in_reply_to_status_id != None:
|
||||
try:
|
||||
tweet2 = self.session.twitter_v2.get_tweet(id=self.tweet.in_reply_to_status_id, user_auth=True, tweet_fields=["conversation_id"])
|
||||
results.append(tweet2)
|
||||
except TweepyException as e:
|
||||
log.exception("There was an error attempting to retrieve a parent tweet for the conversation for {}".format(self.name))
|
||||
# Now, try to fetch the tweet initiating the conversation in V2 so we can get conversation_id
|
||||
try:
|
||||
tweet = self.session.twitter_v2.get_tweet(id=self.tweet.id, user_auth=True, tweet_fields=["conversation_id"])
|
||||
results.append(tweet.data)
|
||||
term = "conversation_id:{}".format(tweet.data.conversation_id)
|
||||
tweets = self.session.twitter_v2.search_recent_tweets(term, user_auth=True, max_results=98)
|
||||
if tweets.data != None:
|
||||
results.extend(tweets.data)
|
||||
except TweepyException as e:
|
||||
log.exception("There was an error when attempting to retrieve the whole conversation for buffer {}".format(self.buffer.name))
|
||||
new_results = []
|
||||
ids = [tweet.id for tweet in results]
|
||||
try:
|
||||
results = self.session.twitter.lookup_statuses(ids, include_ext_alt_text=True, tweet_mode="extended")
|
||||
results.sort(key=lambda x: x.id)
|
||||
except TweepyException as e:
|
||||
log.exception("There was an error attempting to retrieve tweets for Twitter API V1.1, in conversation buffer {}".format(self.name))
|
||||
return []
|
||||
return results
|
@@ -13,17 +13,17 @@ import widgetUtils
|
||||
import output
|
||||
import logging
|
||||
from mysc.thread_utils import call_threaded
|
||||
from tweepy.error import TweepError
|
||||
from tweepy.errors import TweepyException
|
||||
from pubsub import pub
|
||||
from controller.buffers import base
|
||||
|
||||
log = logging.getLogger("controller.buffers.twitter.trends")
|
||||
|
||||
class TrendsBuffer(base.Buffer):
|
||||
def __init__(self, parent, name, session, account, trendsFor, *args, **kwargs):
|
||||
super(TrendsBuffer, self).__init__(parent=parent, session=session)
|
||||
def __init__(self, parent, name, sessionObject, account, trendsFor, *args, **kwargs):
|
||||
super(TrendsBuffer, self).__init__(parent=parent, sessionObject=sessionObject)
|
||||
self.trendsFor = trendsFor
|
||||
self.session = session
|
||||
self.session = sessionObject
|
||||
self.account = account
|
||||
self.invisible = True
|
||||
self.buffer = buffers.trendsPanel(parent, name)
|
||||
@@ -44,9 +44,9 @@ class TrendsBuffer(base.Buffer):
|
||||
if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory == True:
|
||||
self.execution_time = current_time
|
||||
try:
|
||||
data = self.session.twitter.trends_place(id=self.trendsFor)
|
||||
except TweepError as err:
|
||||
log.error("Error %s: %s" % (err.api_code, err.reason))
|
||||
data = self.session.twitter.get_place_trends(id=self.trendsFor)
|
||||
except TweepyException as err:
|
||||
log.exception("Error %s" % (str(err)))
|
||||
if not hasattr(self, "name_"):
|
||||
self.name_ = data[0]["locations"][0]["name"]
|
||||
self.trends = data[0]["trends"]
|
||||
|
@@ -3,7 +3,7 @@ import widgetUtils
|
||||
import output
|
||||
import logging
|
||||
from wxUI.dialogs import lists
|
||||
from tweepy.error import TweepError
|
||||
from tweepy.errors import TweepyException
|
||||
from sessions.twitter import compose, utils
|
||||
from pubsub import pub
|
||||
|
||||
@@ -49,9 +49,9 @@ class listsController(object):
|
||||
new_list = self.session.twitter.create_list(name=name, description=description, mode=mode)
|
||||
self.session.db["lists"].append(new_list)
|
||||
self.dialog.lista.insert_item(False, *compose.compose_list(new_list))
|
||||
except TweepError as e:
|
||||
output.speak("error %s: %s" % (e.api_code, e.reason))
|
||||
log.exception("error %s: %s" % (e.api_code, e.reason))
|
||||
except TweepyException as e:
|
||||
output.speak("error %s" % (str(e)))
|
||||
log.exception("error %s" % (str(e)))
|
||||
dialog.destroy()
|
||||
|
||||
def edit_list(self, *args, **kwargs):
|
||||
@@ -70,8 +70,9 @@ class listsController(object):
|
||||
self.session.twitter.update_list(list_id=list.id, name=name, description=description, mode=mode)
|
||||
self.session.get_lists()
|
||||
self.dialog.populate_list(self.get_all_lists(), True)
|
||||
except TweepError as e:
|
||||
output.speak("error %s: %s" % (e.api_code, e.reason))
|
||||
except TweepyException as e:
|
||||
output.speak("error %s" % (str(e)))
|
||||
log.exception("error %s" % (str(e)))
|
||||
dialog.destroy()
|
||||
|
||||
def remove_list(self, *args, **kwargs):
|
||||
@@ -82,8 +83,9 @@ class listsController(object):
|
||||
self.session.twitter.destroy_list(list_id=list)
|
||||
self.session.db["lists"].pop(self.dialog.get_item())
|
||||
self.dialog.lista.remove_item(self.dialog.get_item())
|
||||
except TweepError as e:
|
||||
output.speak("error %s: %s" % (e.api_code, e.reason))
|
||||
except TweepyException as e:
|
||||
output.speak("error %s" % (str(e)))
|
||||
log.exception("error %s" % (str(e)))
|
||||
|
||||
def open_list_as_buffer(self, *args, **kwargs):
|
||||
if self.dialog.lista.get_count() == 0: return
|
||||
@@ -97,8 +99,9 @@ class listsController(object):
|
||||
list = self.session.twitter.subscribe_list(list_id=list_id)
|
||||
item = utils.find_item(list.id, self.session.db["lists"])
|
||||
self.session.db["lists"].append(list)
|
||||
except TweepError as e:
|
||||
output.speak("error %s: %s" % (e.api_code, e.reason))
|
||||
except TweepyException as e:
|
||||
output.speak("error %s" % (str(e)))
|
||||
log.exception("error %s" % (str(e)))
|
||||
|
||||
def unsubscribe(self, *args, **kwargs):
|
||||
if self.dialog.lista.get_count() == 0: return
|
||||
@@ -106,5 +109,6 @@ class listsController(object):
|
||||
try:
|
||||
list = self.session.twitter.unsubscribe_list(list_id=list_id)
|
||||
self.session.db["lists"].remove(list)
|
||||
except TweepError as e:
|
||||
output.speak("error %s: %s" % (e.api_code, e.reason))
|
||||
except TweepyException as e:
|
||||
output.speak("error %s" % (str(e)))
|
||||
log.exception("error %s" % (str(e)))
|
||||
|
@@ -2,6 +2,7 @@
|
||||
import platform
|
||||
system = platform.system()
|
||||
import application
|
||||
import wx
|
||||
import requests
|
||||
from audio_services import youtube_utils
|
||||
import arrow
|
||||
@@ -24,28 +25,28 @@ from sessions.twitter import utils, compose
|
||||
from sessionmanager import manager, sessionManager
|
||||
from controller import buffers
|
||||
from . import messages
|
||||
from . import userAliasController
|
||||
import sessions
|
||||
from sessions.twitter import session as session_
|
||||
from pubsub import pub
|
||||
import sound
|
||||
import output
|
||||
from tweepy.error import TweepError
|
||||
from tweepy.errors import TweepyException, Forbidden
|
||||
from mysc.thread_utils import call_threaded
|
||||
from mysc.repeating_timer import RepeatingTimer
|
||||
from mysc import restart
|
||||
import config
|
||||
import widgetUtils
|
||||
import pygeocoder
|
||||
from pygeolib import GeocoderError
|
||||
import logging
|
||||
import webbrowser
|
||||
from geopy.geocoders import Nominatim
|
||||
from mysc import localization
|
||||
import os
|
||||
import languageHandler
|
||||
|
||||
log = logging.getLogger("mainController")
|
||||
|
||||
geocoder = pygeocoder.Geocoder()
|
||||
geocoder = Nominatim(user_agent="TWBlue")
|
||||
|
||||
class Controller(object):
|
||||
|
||||
@@ -132,6 +133,7 @@ class Controller(object):
|
||||
pub.subscribe(self.manage_unfavourite, "unfavourite")
|
||||
pub.subscribe(self.manage_blocked_user, "blocked-user")
|
||||
pub.subscribe(self.manage_unblocked_user, "unblocked-user")
|
||||
pub.subscribe(self.create_buffer, "createBuffer")
|
||||
if system == "Windows":
|
||||
pub.subscribe(self.invisible_shorcuts_changed, "invisible-shorcuts-changed")
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.show_hide, menuitem=self.view.show_hide)
|
||||
@@ -185,9 +187,11 @@ class Controller(object):
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.report_error, self.view.reportError)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.view_documentation, self.view.doc)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.view_changelog, self.view.changelog)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.add_alias, self.view.addAlias)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.add_to_list, self.view.addToList)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.remove_from_list, self.view.removeFromList)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.update_buffer, self.view.update_buffer)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.manage_aliases, self.view.manageAliases)
|
||||
|
||||
def set_systray_icon(self):
|
||||
self.systrayIcon = sysTrayIcon.SysTrayIcon()
|
||||
@@ -292,6 +296,31 @@ class Controller(object):
|
||||
self.create_buffers(session, False)
|
||||
self.start_buffers(session)
|
||||
|
||||
def create_buffer(self, buffer_type="baseBuffer", session_type="twitter", buffer_title="", parent_tab=None, start=False, kwargs={}):
|
||||
log.debug("Creating buffer of type {0} with parent_tab of {2} arguments {1}".format(buffer_type, kwargs, parent_tab))
|
||||
if not hasattr(buffers, session_type):
|
||||
raise AttributeError("Session type %s does not exist yet." % (session_type))
|
||||
available_buffers = getattr(buffers, session_type)
|
||||
if not hasattr(available_buffers, buffer_type):
|
||||
raise AttributeError("Specified buffer type does not exist: %s" % (buffer_type,))
|
||||
buffer = getattr(available_buffers, buffer_type)(**kwargs)
|
||||
if start:
|
||||
if kwargs.get("function") == "user_timeline":
|
||||
try:
|
||||
buffer.start_stream(play_sound=False)
|
||||
except ValueError:
|
||||
commonMessageDialogs.unauthorized()
|
||||
return
|
||||
else:
|
||||
call_threaded(buffer.start_stream)
|
||||
self.buffers.append(buffer)
|
||||
if parent_tab == None:
|
||||
log.debug("Appending buffer {}...".format(buffer,))
|
||||
self.view.add_buffer(buffer.buffer, buffer_title)
|
||||
else:
|
||||
self.view.insert_buffer(buffer.buffer, buffer_title, parent_tab)
|
||||
log.debug("Inserting buffer {0} into control {1}".format(buffer, parent_tab))
|
||||
|
||||
def create_buffers(self, session, createAccounts=True):
|
||||
""" Generates buffer objects for an user account.
|
||||
session SessionObject: a sessionmanager.session.Session Object"""
|
||||
@@ -302,96 +331,54 @@ class Controller(object):
|
||||
account.setup_account()
|
||||
self.buffers.append(account)
|
||||
self.view.add_buffer(account.buffer , name=session.db["user_name"])
|
||||
root_position =self.view.search(session.db["user_name"], session.db["user_name"])
|
||||
for i in session.settings['general']['buffer_order']:
|
||||
if i == 'home':
|
||||
home = buffers.twitter.BaseBuffer(self.view.nb, "home_timeline", "home_timeline", session, session.db["user_name"], sound="tweet_received.ogg", tweet_mode="extended")
|
||||
self.buffers.append(home)
|
||||
self.view.insert_buffer(home.buffer, name=_(u"Home"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||
pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Home"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function="home_timeline", name="home_timeline", sessionObject=session, account=session.db["user_name"], sound="tweet_received.ogg", tweet_mode="extended"))
|
||||
elif i == 'mentions':
|
||||
mentions = buffers.twitter.BaseBuffer(self.view.nb, "mentions_timeline", "mentions", session, session.db["user_name"], sound="mention_received.ogg", tweet_mode="extended")
|
||||
self.buffers.append(mentions)
|
||||
self.view.insert_buffer(mentions.buffer, name=_(u"Mentions"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||
pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Mentions"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function="mentions_timeline", name="mentions", sessionObject=session, account=session.db["user_name"], sound="mention_received.ogg", tweet_mode="extended"))
|
||||
elif i == 'dm':
|
||||
dm = buffers.twitter.DirectMessagesBuffer(self.view.nb, "list_direct_messages", "direct_messages", session, session.db["user_name"], bufferType="dmPanel", compose_func="compose_direct_message", sound="dm_received.ogg")
|
||||
self.buffers.append(dm)
|
||||
self.view.insert_buffer(dm.buffer, name=_(u"Direct messages"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||
pub.sendMessage("createBuffer", buffer_type="DirectMessagesBuffer", session_type=session.type, buffer_title=_("Direct messages"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function="get_direct_messages", name="direct_messages", sessionObject=session, account=session.db["user_name"], bufferType="dmPanel", compose_func="compose_direct_message", sound="dm_received.ogg"))
|
||||
elif i == 'sent_dm':
|
||||
sent_dm = buffers.twitter.SentDirectMessagesBuffer(self.view.nb, "", "sent_direct_messages", session, session.db["user_name"], bufferType="dmPanel", compose_func="compose_direct_message")
|
||||
self.buffers.append(sent_dm)
|
||||
self.view.insert_buffer(sent_dm.buffer, name=_(u"Sent direct messages"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||
pub.sendMessage("createBuffer", buffer_type="SentDirectMessagesBuffer", session_type=session.type, buffer_title=_("Sent direct messages"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function=None, name="sent_direct_messages", sessionObject=session, account=session.db["user_name"], bufferType="dmPanel", compose_func="compose_direct_message"))
|
||||
elif i == 'sent_tweets':
|
||||
sent_tweets = buffers.twitter.BaseBuffer(self.view.nb, "user_timeline", "sent_tweets", session, session.db["user_name"], screen_name=session.db["user_name"], tweet_mode="extended")
|
||||
self.buffers.append(sent_tweets)
|
||||
self.view.insert_buffer(sent_tweets.buffer, name=_(u"Sent tweets"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||
pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Sent tweets"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function="user_timeline", name="sent_tweets", sessionObject=session, account=session.db["user_name"], screen_name=session.db["user_name"], tweet_mode="extended"))
|
||||
elif i == 'favorites':
|
||||
favourites = buffers.twitter.BaseBuffer(self.view.nb, "favorites", "favourites", session, session.db["user_name"], sound="favourite.ogg", tweet_mode="extended")
|
||||
self.buffers.append(favourites)
|
||||
self.view.insert_buffer(favourites.buffer, name=_(u"Likes"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||
pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Likes"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function="get_favorites", name="favourites", sessionObject=session, account=session.db["user_name"], sound="favourite.ogg", tweet_mode="extended"))
|
||||
elif i == 'followers':
|
||||
followers = buffers.twitter.PeopleBuffer(self.view.nb, "followers", "followers", session, session.db["user_name"], sound="update_followers.ogg", screen_name=session.db["user_name"])
|
||||
self.buffers.append(followers)
|
||||
self.view.insert_buffer(followers.buffer, name=_(u"Followers"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||
pub.sendMessage("createBuffer", buffer_type="PeopleBuffer", session_type=session.type, buffer_title=_("Followers"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function="get_followers", name="followers", sessionObject=session, account=session.db["user_name"], sound="update_followers.ogg", screen_name=session.db["user_name"]))
|
||||
elif i == 'friends':
|
||||
friends = buffers.twitter.PeopleBuffer(self.view.nb, "friends", "friends", session, session.db["user_name"], screen_name=session.db["user_name"])
|
||||
self.buffers.append(friends)
|
||||
self.view.insert_buffer(friends.buffer, name=_(u"Friends"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||
pub.sendMessage("createBuffer", buffer_type="PeopleBuffer", session_type=session.type, buffer_title=_("Following"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function="get_friends", name="friends", sessionObject=session, account=session.db["user_name"], screen_name=session.db["user_name"]))
|
||||
elif i == 'blocks':
|
||||
blocks = buffers.twitter.PeopleBuffer(self.view.nb, "blocks", "blocked", session, session.db["user_name"])
|
||||
self.buffers.append(blocks)
|
||||
self.view.insert_buffer(blocks.buffer, name=_(u"Blocked users"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||
pub.sendMessage("createBuffer", buffer_type="PeopleBuffer", session_type=session.type, buffer_title=_("Blocked users"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function="get_blocks", name="blocked", sessionObject=session, account=session.db["user_name"]))
|
||||
elif i == 'muted':
|
||||
muted = buffers.twitter.PeopleBuffer(self.view.nb, "mutes", "muted", session, session.db["user_name"])
|
||||
self.buffers.append(muted)
|
||||
self.view.insert_buffer(muted.buffer, name=_(u"Muted users"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||
timelines = buffers.base.EmptyBuffer(self.view.nb, "timelines", session.db["user_name"])
|
||||
self.buffers.append(timelines)
|
||||
self.view.insert_buffer(timelines.buffer , name=_(u"Timelines"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||
pub.sendMessage("createBuffer", buffer_type="PeopleBuffer", session_type=session.type, buffer_title=_("Muted users"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function="get_mutes", name="muted", sessionObject=session, account=session.db["user_name"]))
|
||||
pub.sendMessage("createBuffer", buffer_type="EmptyBuffer", session_type="base", buffer_title=_("Timelines"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, name="timelines", account=session.db["user_name"]))
|
||||
timelines_position =self.view.search("timelines", session.db["user_name"])
|
||||
for i in session.settings["other_buffers"]["timelines"]:
|
||||
tl = buffers.twitter.BaseBuffer(self.view.nb, "user_timeline", "%s-timeline" % (i,), session, session.db["user_name"], sound="tweet_timeline.ogg", bufferType=None, user_id=i, tweet_mode="extended")
|
||||
self.buffers.append(tl)
|
||||
self.view.insert_buffer(tl.buffer, name=_(u"Timeline for {}").format(i,), pos=self.view.search("timelines", session.db["user_name"]))
|
||||
favs_timelines = buffers.base.EmptyBuffer(self.view.nb, "favs_timelines", session.db["user_name"])
|
||||
self.buffers.append(favs_timelines)
|
||||
self.view.insert_buffer(favs_timelines.buffer , name=_(u"Likes timelines"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||
pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_(u"Timeline for {}").format(i,), parent_tab=timelines_position, start=False, kwargs=dict(parent=self.view.nb, function="user_timeline", name="%s-timeline" % (i,), sessionObject=session, account=session.db["user_name"], sound="tweet_timeline.ogg", bufferType=None, user_id=i, tweet_mode="extended"))
|
||||
pub.sendMessage("createBuffer", buffer_type="EmptyBuffer", session_type="base", buffer_title=_("Likes timelines"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, name="favs_timelines", account=session.db["user_name"]))
|
||||
favs_timelines_position =self.view.search("favs_timelines", session.db["user_name"])
|
||||
for i in session.settings["other_buffers"]["favourites_timelines"]:
|
||||
tl = buffers.twitter.BaseBuffer(self.view.nb, "favorites", "%s-favorite" % (i,), session, session.db["user_name"], bufferType=None, sound="favourites_timeline_updated.ogg", user_id=i, tweet_mode="extended")
|
||||
self.buffers.append(tl)
|
||||
self.view.insert_buffer(tl.buffer, name=_(u"Likes for {}").format(i,), pos=self.view.search("favs_timelines", session.db["user_name"]))
|
||||
followers_timelines = buffers.base.EmptyBuffer(self.view.nb, "followers_timelines", session.db["user_name"])
|
||||
self.buffers.append(followers_timelines)
|
||||
self.view.insert_buffer(followers_timelines.buffer , name=_(u"Followers' Timelines"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||
pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Likes for {}").format(i,), parent_tab=favs_timelines_position, start=False, kwargs=dict(parent=self.view.nb, function="get_favorites", name="%s-favorite" % (i,), sessionObject=session, account=session.db["user_name"], bufferType=None, sound="favourites_timeline_updated.ogg", user_id=i, tweet_mode="extended"))
|
||||
pub.sendMessage("createBuffer", buffer_type="EmptyBuffer", session_type="base", buffer_title=_("Followers timelines"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, name="followers_timelines", account=session.db["user_name"]))
|
||||
followers_timelines_position =self.view.search("followers_timelines", session.db["user_name"])
|
||||
for i in session.settings["other_buffers"]["followers_timelines"]:
|
||||
tl = buffers.twitter.PeopleBuffer(self.view.nb, "followers", "%s-followers" % (i,), session, session.db["user_name"], sound="new_event.ogg", user_id=i)
|
||||
self.buffers.append(tl)
|
||||
self.view.insert_buffer(tl.buffer, name=_(u"Followers for {}").format(i,), pos=self.view.search("followers_timelines", session.db["user_name"]))
|
||||
friends_timelines = buffers.base.EmptyBuffer(self.view.nb, "friends_timelines", session.db["user_name"])
|
||||
self.buffers.append(friends_timelines)
|
||||
self.view.insert_buffer(friends_timelines.buffer , name=_(u"Friends' Timelines"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||
pub.sendMessage("createBuffer", buffer_type="PeopleBuffer", session_type=session.type, buffer_title=_("Followers for {}").format(i,), parent_tab=followers_timelines_position, start=False, kwargs=dict(parent=self.view.nb, function="get_followers", name="%s-followers" % (i,), sessionObject=session, account=session.db["user_name"], sound="new_event.ogg", user_id=i))
|
||||
pub.sendMessage("createBuffer", buffer_type="EmptyBuffer", session_type="base", buffer_title=_("Following timelines"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, name="friends_timelines", account=session.db["user_name"]))
|
||||
friends_timelines_position =self.view.search("friends_timelines", session.db["user_name"])
|
||||
for i in session.settings["other_buffers"]["friends_timelines"]:
|
||||
tl = buffers.twitter.PeopleBuffer(self.view.nb, "friends", "%s-friends" % (i,), session, session.db["user_name"], sound="new_event.ogg", user_id=i)
|
||||
self.buffers.append(tl)
|
||||
self.view.insert_buffer(tl.buffer, name=_(u"Friends for {}").format(i,), pos=self.view.search("friends_timelines", session.db["user_name"]))
|
||||
lists = buffers.base.EmptyBuffer(self.view.nb, "lists", session.db["user_name"])
|
||||
self.buffers.append(lists)
|
||||
self.view.insert_buffer(lists.buffer , name=_(u"Lists"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||
pub.sendMessage("createBuffer", buffer_type="PeopleBuffer", session_type=session.type, buffer_title=_(u"Friends for {}").format(i,), parent_tab=friends_timelines_position, start=False, kwargs=dict(parent=self.view.nb, function="get_friends", name="%s-friends" % (i,), sessionObject=session, account=session.db["user_name"], sound="new_event.ogg", user_id=i))
|
||||
pub.sendMessage("createBuffer", buffer_type="EmptyBuffer", session_type="base", buffer_title=_("Lists"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, name="lists", account=session.db["user_name"]))
|
||||
lists_position =self.view.search("lists", session.db["user_name"])
|
||||
for i in session.settings["other_buffers"]["lists"]:
|
||||
tl = buffers.twitter.ListBuffer(self.view.nb, "list_timeline", "%s-list" % (i,), session, session.db["user_name"], bufferType=None, sound="list_tweet.ogg", list_id=utils.find_list(i, session.db["lists"]), tweet_mode="extended")
|
||||
session.lists.append(tl)
|
||||
self.buffers.append(tl)
|
||||
self.view.insert_buffer(tl.buffer, name=_(u"List for {}").format(i), pos=self.view.search("lists", session.db["user_name"]))
|
||||
searches = buffers.base.EmptyBuffer(self.view.nb, "searches", session.db["user_name"])
|
||||
self.buffers.append(searches)
|
||||
self.view.insert_buffer(searches.buffer , name=_(u"Searches"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||
pub.sendMessage("createBuffer", buffer_type="ListBuffer", session_type=session.type, buffer_title=_(u"List for {}").format(i), parent_tab=lists_position, start=False, kwargs=dict(parent=self.view.nb, function="list_timeline", name="%s-list" % (i,), sessionObject=session, account=session.db["user_name"], bufferType=None, sound="list_tweet.ogg", list_id=utils.find_list(i, session.db["lists"]), tweet_mode="extended"))
|
||||
pub.sendMessage("createBuffer", buffer_type="EmptyBuffer", session_type="base", buffer_title=_("Searches"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, name="searches", account=session.db["user_name"]))
|
||||
searches_position =self.view.search("searches", session.db["user_name"])
|
||||
for i in session.settings["other_buffers"]["tweet_searches"]:
|
||||
tl = buffers.twitter.SearchBuffer(self.view.nb, "search", "%s-searchterm" % (i,), session, session.db["user_name"], bufferType="searchPanel", sound="search_updated.ogg", q=i, tweet_mode="extended")
|
||||
self.buffers.append(tl)
|
||||
self.view.insert_buffer(tl.buffer, name=_(u"Search for {}").format(i), pos=self.view.search("searches", session.db["user_name"]))
|
||||
pub.sendMessage("createBuffer", buffer_type="SearchBuffer", session_type=session.type, buffer_title=_(u"Search for {}").format(i), parent_tab=searches_position, start=False, kwargs=dict(parent=self.view.nb, function="search_tweets", name="%s-searchterm" % (i,), sessionObject=session, account=session.db["user_name"], bufferType="searchPanel", sound="search_updated.ogg", q=i, tweet_mode="extended"))
|
||||
for i in session.settings["other_buffers"]["trending_topic_buffers"]:
|
||||
buffer = buffers.twitter.TrendsBuffer(self.view.nb, "%s_tt" % (i,), session, session.db["user_name"], i, sound="trends_updated.ogg")
|
||||
buffer.start_stream(play_sound=False)
|
||||
buffer.searchfunction = self.search
|
||||
self.buffers.append(buffer)
|
||||
self.view.insert_buffer(buffer.buffer, name=_(u"Trending topics for %s") % (buffer.name_), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||
pub.sendMessage("createBuffer", buffer_type="TrendsBuffer", session_type=session.type, buffer_title=_("Trending topics for %s") % (i), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, name="%s_tt" % (i,), sessionObject=session, account=session.db["user_name"], trendsFor=i, sound="trends_updated.ogg"))
|
||||
|
||||
def set_buffer_positions(self, session):
|
||||
"Sets positions for buffers if values exist in the database."
|
||||
@@ -430,21 +417,18 @@ class Controller(object):
|
||||
if dlg.get_response() == widgetUtils.OK and dlg.get("term") != "":
|
||||
term = dlg.get("term")
|
||||
buffer = self.get_best_buffer()
|
||||
searches_position =self.view.search("searches", buffer.session.db["user_name"])
|
||||
if dlg.get("tweets") == True:
|
||||
if term not in buffer.session.settings["other_buffers"]["tweet_searches"]:
|
||||
buffer.session.settings["other_buffers"]["tweet_searches"].append(term)
|
||||
buffer.session.settings.write()
|
||||
args = {"lang": dlg.get_language(), "result_type": dlg.get_result_type()}
|
||||
search = buffers.twitter.SearchBuffer(self.view.nb, "search", "%s-searchterm" % (term,), buffer.session, buffer.session.db["user_name"], bufferType="searchPanel", sound="search_updated.ogg", q=term, tweet_mode="extended", **args)
|
||||
pub.sendMessage("createBuffer", buffer_type="SearchBuffer", session_type=buffer.session.type, buffer_title=_("Search for {}").format(term), parent_tab=searches_position, start=True, kwargs=dict(parent=self.view.nb, function="search_tweets", name="%s-searchterm" % (term,), sessionObject=buffer.session, account=buffer.session.db["user_name"], bufferType="searchPanel", sound="search_updated.ogg", q=term, tweet_mode="extended", **args))
|
||||
else:
|
||||
log.error("A buffer for the %s search term is already created. You can't create a duplicate buffer." % (term,))
|
||||
return
|
||||
elif dlg.get("users") == True:
|
||||
search = buffers.twitter.SearchPeopleBuffer(self.view.nb, "search_users", "%s-searchUser" % (term,), buffer.session, buffer.session.db["user_name"], bufferType=None, sound="search_updated.ogg", q=term)
|
||||
search.start_stream(mandatory=True)
|
||||
pos=self.view.search("searches", buffer.session.db["user_name"])
|
||||
self.insert_buffer(search, pos)
|
||||
self.view.insert_buffer(search.buffer, name=_(u"Search for {}").format(term), pos=pos)
|
||||
pub.sendMessage("createBuffer", buffer_type="SearchPeopleBuffer", session_type=buffer.session.type, buffer_title=_("Search for {}").format(term), parent_tab=searches_position, start=True, kwargs=dict(parent=self.view.nb, function="search_users", name="%s-searchUser" % (term,), sessionObject=buffer.session, account=buffer.session.db["user_name"], bufferType=None, sound="search_updated.ogg", q=term))
|
||||
dlg.Destroy()
|
||||
|
||||
def find(self, *args, **kwargs):
|
||||
@@ -567,8 +551,9 @@ class Controller(object):
|
||||
if listBuffer != None: listBuffer.get_user_ids()
|
||||
buff.session.db["lists"].pop(older_list)
|
||||
buff.session.db["lists"].append(list)
|
||||
except TweepError as e:
|
||||
output.speak("error %s: %s" % (e.api_code, e.reason))
|
||||
except TweepyException as e:
|
||||
log.exception("error %s" % (str(e)))
|
||||
output.speak("error %s" % (str(e)))
|
||||
|
||||
def remove_from_list(self, *args, **kwargs):
|
||||
buff = self.get_best_buffer()
|
||||
@@ -595,8 +580,9 @@ class Controller(object):
|
||||
if listBuffer != None: listBuffer.get_user_ids()
|
||||
buff.session.db["lists"].pop(older_list)
|
||||
buff.session.db["lists"].append(list)
|
||||
except TweepError as e:
|
||||
output.speak("error %s: %s" % (e.api_code, e.reason))
|
||||
except TweepyException as e:
|
||||
output.speak("error %s" % (str(e)))
|
||||
log.exception("error %s" % (str(e)))
|
||||
|
||||
def list_manager(self, *args, **kwargs):
|
||||
s = self.get_best_buffer().session
|
||||
@@ -754,6 +740,31 @@ class Controller(object):
|
||||
users = utils.get_all_users(tweet, buff.session)
|
||||
u = userActionsController.userActionsController(buff, users, "report")
|
||||
|
||||
def add_alias(self, *args, **kwargs):
|
||||
buff = self.get_best_buffer()
|
||||
if not hasattr(buff, "get_right_tweet"): return
|
||||
tweet = buff.get_right_tweet()
|
||||
if buff.type == "people":
|
||||
users = [tweet.screen_name]
|
||||
elif buff.type == "dm":
|
||||
users = [buff.session.get_user(tweet.message_create["sender_id"]).screen_name]
|
||||
else:
|
||||
users = utils.get_all_users(tweet, buff.session)
|
||||
dlg = dialogs.userAliasDialogs.addAliasDialog(_("Add an user alias"), users)
|
||||
if dlg.get_response() == widgetUtils.OK:
|
||||
user, alias = dlg.get_user()
|
||||
if user == "" or alias == "":
|
||||
return
|
||||
user_id = buff.session.get_user_by_screen_name(user)
|
||||
buff.session.settings["user-aliases"][str(user_id)] = alias
|
||||
buff.session.settings.write()
|
||||
output.speak(_("Alias has been set correctly for {}.").format(user))
|
||||
pub.sendMessage("alias-added")
|
||||
|
||||
def manage_aliases(self, *args, **kwargs):
|
||||
buff = self.get_best_buffer()
|
||||
alias_controller = userAliasController.userAliasController(buff.session.settings)
|
||||
|
||||
def post_tweet(self, event=None):
|
||||
buffer = self.get_best_buffer()
|
||||
buffer.post_status()
|
||||
@@ -810,7 +821,7 @@ class Controller(object):
|
||||
return
|
||||
elif buffer.type == "baseBuffer" or buffer.type == "favourites_timeline" or buffer.type == "list" or buffer.type == "search":
|
||||
tweet, tweetsList = buffer.get_full_tweet()
|
||||
msg = messages.viewTweet(tweet, tweetsList, utc_offset=buffer.session.db["utc_offset"])
|
||||
msg = messages.viewTweet(tweet, tweetsList, utc_offset=buffer.session.db["utc_offset"], item_url=buffer.get_item_url())
|
||||
elif buffer.type == "dm":
|
||||
non_tweet = buffer.get_formatted_message()
|
||||
item = buffer.get_right_tweet()
|
||||
@@ -818,8 +829,11 @@ class Controller(object):
|
||||
date = original_date.shift(seconds=buffer.session.db["utc_offset"]).format(_(u"MMM D, YYYY. H:m"), locale=languageHandler.getLanguage())
|
||||
msg = messages.viewTweet(non_tweet, [], False, date=date)
|
||||
else:
|
||||
item_url = ""
|
||||
if hasattr(buffer, "get_item_url"):
|
||||
item_url = buffer.get_item_url()
|
||||
non_tweet = buffer.get_formatted_message()
|
||||
msg = messages.viewTweet(non_tweet, [], False)
|
||||
msg = messages.viewTweet(non_tweet, [], False, item_url=item_url)
|
||||
|
||||
def open_in_browser(self, *args, **kwargs):
|
||||
buffer = self.get_current_buffer()
|
||||
@@ -877,7 +891,7 @@ class Controller(object):
|
||||
if usr.id_str in buff.session.settings["other_buffers"]["favourites_timelines"]:
|
||||
commonMessageDialogs.timeline_exist()
|
||||
return
|
||||
tl = buffers.twitter.BaseBuffer(self.view.nb, "favorites", "%s-favorite" % (usr.id_str,), buff.session, buff.session.db["user_name"], bufferType=None, sound="favourites_timeline_updated.ogg", user_id=usr.id_str, tweet_mode="extended")
|
||||
tl = buffers.twitter.BaseBuffer(self.view.nb, "get_favorites", "%s-favorite" % (usr.id_str,), buff.session, buff.session.db["user_name"], bufferType=None, sound="favourites_timeline_updated.ogg", user_id=usr.id_str, tweet_mode="extended")
|
||||
try:
|
||||
tl.start_stream(play_sound=False)
|
||||
except ValueError:
|
||||
@@ -896,7 +910,7 @@ class Controller(object):
|
||||
if usr.id_str in buff.session.settings["other_buffers"]["followers_timelines"]:
|
||||
commonMessageDialogs.timeline_exist()
|
||||
return
|
||||
tl = buffers.twitter.PeopleBuffer(self.view.nb, "followers", "%s-followers" % (usr.id_str,), buff.session, buff.session.db["user_name"], sound="new_event.ogg", user_id=usr.id_str)
|
||||
tl = buffers.twitter.PeopleBuffer(self.view.nb, "get_followers", "%s-followers" % (usr.id_str,), buff.session, buff.session.db["user_name"], sound="new_event.ogg", user_id=usr.id_str)
|
||||
try:
|
||||
tl.start_stream(play_sound=False)
|
||||
except ValueError:
|
||||
@@ -915,7 +929,7 @@ class Controller(object):
|
||||
if usr.id_str in buff.session.settings["other_buffers"]["friends_timelines"]:
|
||||
commonMessageDialogs.timeline_exist()
|
||||
return
|
||||
tl = buffers.twitter.PeopleBuffer(self.view.nb, "friends", "%s-friends" % (usr.id_str,), buff.session, buff.session.db["user_name"], sound="new_event.ogg", user_id=usr.id_str)
|
||||
tl = buffers.twitter.PeopleBuffer(self.view.nb, "get_friends", "%s-friends" % (usr.id_str,), buff.session, buff.session.db["user_name"], sound="new_event.ogg", user_id=usr.id_str)
|
||||
try:
|
||||
tl.start_stream(play_sound=False)
|
||||
except ValueError:
|
||||
@@ -935,7 +949,7 @@ class Controller(object):
|
||||
buffer = self.get_current_buffer()
|
||||
id = buffer.get_right_tweet().id
|
||||
user = buffer.session.get_user(buffer.get_right_tweet().user).screen_name
|
||||
search = buffers.twitter.ConversationBuffer(self.view.nb, "search", "%s-searchterm" % (id,), buffer.session, buffer.session.db["user_name"], bufferType="searchPanel", sound="search_updated.ogg", since_id=id, q="@{0}".format(user,))
|
||||
search = buffers.twitter.ConversationBuffer(self.view.nb, "search_tweets", "%s-searchterm" % (id,), buffer.session, buffer.session.db["user_name"], bufferType="searchPanel", sound="search_updated.ogg", since_id=id, q="@{0}".format(user,))
|
||||
search.tweet = buffer.get_right_tweet()
|
||||
search.start_stream(start=True)
|
||||
pos=self.view.search("searches", buffer.session.db["user_name"])
|
||||
@@ -977,19 +991,17 @@ class Controller(object):
|
||||
if tweet.coordinates != None:
|
||||
x = tweet.coordinates["coordinates"][0]
|
||||
y = tweet.coordinates["coordinates"][1]
|
||||
address = geocoder.reverse_geocode(y, x, language = languageHandler.curLang)
|
||||
if event == None: output.speak(address[0].__str__())
|
||||
else: self.view.show_address(address[0].__str__())
|
||||
address = geocoder.reverse("{}, {}".format(y, x), language = languageHandler.curLang)
|
||||
if event == None: output.speak(address.address)
|
||||
else: self.view.show_address(address.address)
|
||||
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
|
||||
# except KeyError:
|
||||
# pass
|
||||
except AttributeError:
|
||||
pass
|
||||
output.speak(_("Unable to find address in OpenStreetMap."))
|
||||
|
||||
def view_reverse_geocode(self, event=None):
|
||||
try:
|
||||
@@ -1244,14 +1256,17 @@ class Controller(object):
|
||||
keymap = {}
|
||||
for i in config.keymap["keymap"]:
|
||||
if hasattr(self, i):
|
||||
keymap[config.keymap["keymap"][i]] = getattr(self, i)
|
||||
if config.keymap["keymap"][i] != "":
|
||||
keymap[config.keymap["keymap"][i]] = getattr(self, i)
|
||||
return keymap
|
||||
|
||||
def register_invisible_keyboard_shorcuts(self, keymap):
|
||||
if config.changed_keymap:
|
||||
commonMessageDialogs.changed_keymap()
|
||||
# Make sure we pass a keymap without undefined keystrokes.
|
||||
new_keymap = {key: keymap[key] for key in keymap.keys() if keymap[key] != ""}
|
||||
self.keyboard_handler = WXKeyboardHandler(self.view)
|
||||
self.keyboard_handler.register_keys(keymap)
|
||||
self.keyboard_handler.register_keys(new_keymap)
|
||||
|
||||
def unregister_invisible_keyboard_shorcuts(self, keymap):
|
||||
try:
|
||||
@@ -1336,11 +1351,10 @@ class Controller(object):
|
||||
i.start_stream()
|
||||
else:
|
||||
i.start_stream(play_sound=False)
|
||||
except TweepError as err:
|
||||
log.exception("Error %s starting buffer %s on account %s, with args %r and kwargs %r due to the following reason: %s" % (err.api_code, i.name, i.account, i.args, i.kwargs, err.reason))
|
||||
except TweepyException as err:
|
||||
log.exception("Error %s starting buffer %s on account %s, with args %r and kwargs %r." % (str(err), i.name, i.account, i.args, i.kwargs))
|
||||
# Determine if this error was caused by a block applied to the current user (IE permission errors).
|
||||
errors_allowed = [130]
|
||||
if (err.api_code != None and err.api_code not in errors_allowed) or (err.api_code == None and 'Not authorized' in err.reason): # A twitter error, so safely try to remove the buffer.
|
||||
if type(err) == Forbidden:
|
||||
buff = self.view.search(i.name, i.account)
|
||||
i.remove_buffer(force=True)
|
||||
commonMessageDialogs.blocked_timeline()
|
||||
@@ -1364,34 +1378,34 @@ class Controller(object):
|
||||
try:
|
||||
if sessions.sessions[i].is_logged == False: continue
|
||||
sessions.sessions[i].check_connection()
|
||||
except TweepError: # We shouldn't allow this function to die.
|
||||
except TweepyException: # We shouldn't allow this function to die.
|
||||
pass
|
||||
|
||||
def create_new_buffer(self, buffer, account, create):
|
||||
buff = self.search_buffer("home_timeline", account)
|
||||
if create == True:
|
||||
if buffer == "favourites":
|
||||
favourites = buffers.twitter.BaseBuffer(self.view.nb, "favorites", "favourites", buff.session, buff.session.db["user_name"], tweet_mode="extended")
|
||||
favourites = buffers.twitter.BaseBuffer(self.view.nb, "get_favorites", "favourites", buff.session, buff.session.db["user_name"], tweet_mode="extended")
|
||||
self.buffers.append(favourites)
|
||||
self.view.insert_buffer(favourites.buffer, name=_(u"Likes"), pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"]))
|
||||
favourites.start_stream(play_sound=False)
|
||||
if buffer == "followers":
|
||||
followers = buffers.twitter.PeopleBuffer(self.view.nb, "followers", "followers", buff.session, buff.session.db["user_name"], screen_name=buff.session.db["user_name"])
|
||||
followers = buffers.twitter.PeopleBuffer(self.view.nb, "get_followers", "followers", buff.session, buff.session.db["user_name"], screen_name=buff.session.db["user_name"])
|
||||
self.buffers.append(followers)
|
||||
self.view.insert_buffer(followers.buffer, name=_(u"Followers"), pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"]))
|
||||
followers.start_stream(play_sound=False)
|
||||
elif buffer == "friends":
|
||||
friends = buffers.twitter.PeopleBuffer(self.view.nb, "friends", "friends", buff.session, buff.session.db["user_name"], screen_name=buff.session.db["user_name"])
|
||||
friends = buffers.twitter.PeopleBuffer(self.view.nb, "get_friends", "friends", buff.session, buff.session.db["user_name"], screen_name=buff.session.db["user_name"])
|
||||
self.buffers.append(friends)
|
||||
self.view.insert_buffer(friends.buffer, name=_(u"Friends"), pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"]))
|
||||
friends.start_stream(play_sound=False)
|
||||
elif buffer == "blocked":
|
||||
blocks = buffers.twitter.PeopleBuffer(self.view.nb, "blocks", "blocked", buff.session, buff.session.db["user_name"])
|
||||
blocks = buffers.twitter.PeopleBuffer(self.view.nb, "get_blocks", "blocked", buff.session, buff.session.db["user_name"])
|
||||
self.buffers.append(blocks)
|
||||
self.view.insert_buffer(blocks.buffer, name=_(u"Blocked users"), pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"]))
|
||||
blocks.start_stream(play_sound=False)
|
||||
elif buffer == "muted":
|
||||
muted = buffers.twitter.PeopleBuffer(self.view.nb, "mutes", "muted", buff.session, buff.session.db["user_name"])
|
||||
muted = buffers.twitter.PeopleBuffer(self.view.nb, "get_mutes", "muted", buff.session, buff.session.db["user_name"])
|
||||
self.buffers.append(muted)
|
||||
self.view.insert_buffer(muted.buffer, name=_(u"Muted users"), pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"]))
|
||||
muted.start_stream(play_sound=False)
|
||||
@@ -1542,11 +1556,10 @@ class Controller(object):
|
||||
if i.session != None and i.session.is_logged == True:
|
||||
try:
|
||||
i.start_stream(mandatory=True)
|
||||
except TweepError as err:
|
||||
log.exception("Error %s starting buffer %s on account %s, with args %r and kwargs %r due to the following reason: %s" % (err.api_code, i.name, i.account, i.args, i.kwargs, err.reason))
|
||||
except TweepyException as err:
|
||||
log.exception("Error %s starting buffer %s on account %s, with args %r and kwargs %r." % (str(err), i.name, i.account, i.args, i.kwargs))
|
||||
# Determine if this error was caused by a block applied to the current user (IE permission errors).
|
||||
errors_allowed = [130]
|
||||
if (err.api_code != None and err.api_code not in errors_allowed) or (err.api_code == None and 'Not authorized' in err.reason): # A twitter error, so safely try to remove the buffer.
|
||||
if type(err) == Forbidden:
|
||||
buff = self.view.search(i.name, i.account)
|
||||
i.remove_buffer(force=True)
|
||||
commonMessageDialogs.blocked_timeline()
|
||||
@@ -1652,5 +1665,5 @@ class Controller(object):
|
||||
try:
|
||||
if sessions.sessions[i].is_logged == False: continue
|
||||
sessions.sessions[i].check_streams()
|
||||
except TweepError: # We shouldn't allow this function to die.
|
||||
except TweepyException: # We shouldn't allow this function to die.
|
||||
pass
|
||||
|
@@ -102,7 +102,7 @@ class basicTweet(object):
|
||||
else:
|
||||
self.message.disable_button("shortenButton")
|
||||
self.message.disable_button("unshortenButton")
|
||||
if self.message.get("long_tweet") == False:
|
||||
if self.message.get("long_tweet") == False and hasattr(self, "max"):
|
||||
text = self.message.get_text()
|
||||
results = parse_tweet(text)
|
||||
self.message.set_title(_(u"%s - %s of %d characters") % (self.title, results.weightedLength, self.max))
|
||||
@@ -205,7 +205,7 @@ class dm(basicTweet):
|
||||
c.show_menu("dm")
|
||||
|
||||
class viewTweet(basicTweet):
|
||||
def __init__(self, tweet, tweetList, is_tweet=True, utc_offset=0, date=""):
|
||||
def __init__(self, tweet, tweetList, is_tweet=True, utc_offset=0, date="", item_url=""):
|
||||
""" This represents a tweet displayer. However it could be used for showing something wich is not a tweet, like a direct message or an event.
|
||||
param tweet: A dictionary that represents a full tweet or a string for non-tweets.
|
||||
param tweetList: If is_tweet is set to True, this could be a list of quoted tweets.
|
||||
@@ -273,6 +273,10 @@ class viewTweet(basicTweet):
|
||||
text = tweet
|
||||
self.message = message.viewNonTweet(text, date)
|
||||
widgetUtils.connect_event(self.message.spellcheck, widgetUtils.BUTTON_PRESSED, self.spellcheck)
|
||||
if item_url != "":
|
||||
self.message.enable_button("share")
|
||||
widgetUtils.connect_event(self.message.share, widgetUtils.BUTTON_PRESSED, self.share)
|
||||
self.item_url = item_url
|
||||
widgetUtils.connect_event(self.message.translateButton, widgetUtils.BUTTON_PRESSED, self.translate)
|
||||
if self.contain_urls() == True:
|
||||
self.message.enable_button("unshortenButton")
|
||||
@@ -290,3 +294,8 @@ class viewTweet(basicTweet):
|
||||
if "https://twitter.com/" in i:
|
||||
text = text.replace(i, "\n")
|
||||
return text
|
||||
|
||||
def share(self, *args, **kwargs):
|
||||
if hasattr(self, "item_url"):
|
||||
output.copy(self.item_url)
|
||||
output.speak(_("Link copied to clipboard."))
|
@@ -8,7 +8,7 @@ class trendingTopicsController(object):
|
||||
self.countries = {}
|
||||
self.cities = {}
|
||||
self.dialog = trends.trendingTopicsDialog()
|
||||
self.information = session.twitter.trends_available()
|
||||
self.information = session.twitter.available_trends()
|
||||
self.split_information()
|
||||
widgetUtils.connect_event(self.dialog.country, widgetUtils.RADIOBUTTON, self.get_places)
|
||||
widgetUtils.connect_event(self.dialog.city, widgetUtils.RADIOBUTTON, self.get_places)
|
||||
|
@@ -6,7 +6,7 @@ import output
|
||||
from wxUI.dialogs import update_profile, show_user
|
||||
import logging
|
||||
log = logging.getLogger("controller.user")
|
||||
from tweepy.error import TweepError
|
||||
from tweepy.errors import TweepyException, Forbidden, NotFound
|
||||
from sessions.twitter import utils
|
||||
|
||||
class profileController(object):
|
||||
@@ -24,12 +24,12 @@ class profileController(object):
|
||||
else:
|
||||
try:
|
||||
self.get_data(screen_name=self.user)
|
||||
except TweepError as err:
|
||||
if err.api_code == 50:
|
||||
except TweepyException as err:
|
||||
if type(err) == NotFound:
|
||||
wx.MessageDialog(None, _(u"That user does not exist"), _(u"Error"), wx.ICON_ERROR).ShowModal()
|
||||
if err.api_code == 63:
|
||||
if type(err) == Forbidden:
|
||||
wx.MessageDialog(None, _(u"User has been suspended"), _(u"Error"), wx.ICON_ERROR).ShowModal()
|
||||
log.error("error %d: %s" % (err.api_code, err.reason))
|
||||
log.error("error %s" % (str(err)))
|
||||
return
|
||||
self.dialog = show_user.showUserProfile()
|
||||
string = self.get_user_info()
|
||||
@@ -44,7 +44,7 @@ class profileController(object):
|
||||
def get_data(self, screen_name):
|
||||
self.data = self.session.twitter.get_user(screen_name=screen_name)
|
||||
if screen_name != self.session.db["user_name"]:
|
||||
self.friendship_status = self.session.twitter.show_friendship(source_screen_name=self.session.db["user_name"], target_screen_name=screen_name)
|
||||
self.friendship_status = self.session.twitter.get_friendship(source_screen_name=self.session.db["user_name"], target_screen_name=screen_name)
|
||||
|
||||
def fill_profile_fields(self):
|
||||
self.dialog.set_name(self.data.name)
|
||||
@@ -83,12 +83,12 @@ class profileController(object):
|
||||
if self.file != None:
|
||||
try:
|
||||
self.session.twitter.update_profile_image(image=self.file)
|
||||
except TweepError as e:
|
||||
output.speak(u"Error %s. %s" % (e.api_code, e.reason))
|
||||
except TweepyException as e:
|
||||
output.speak(u"Error %s" % (str(e)))
|
||||
try:
|
||||
self.session.twitter.update_profile(name=name, description=description, location=location, url=url)
|
||||
except TweepError as e:
|
||||
output.speak(u"Error %s. %s" % (e.api_code, e.reason))
|
||||
except TweepyException as e:
|
||||
output.speak(u"Error %s." % (str(e)))
|
||||
|
||||
def get_user_info(self):
|
||||
string = u""
|
||||
|
@@ -3,7 +3,7 @@ import widgetUtils
|
||||
import output
|
||||
from wxUI.dialogs import userActions
|
||||
from pubsub import pub
|
||||
from tweepy.error import TweepError
|
||||
from tweepy.errors import TweepyException
|
||||
from extra import autocompletionUsers
|
||||
|
||||
class userActionsController(object):
|
||||
@@ -29,44 +29,44 @@ class userActionsController(object):
|
||||
def follow(self, user):
|
||||
try:
|
||||
self.session.twitter.create_friendship(screen_name=user )
|
||||
except TweepError as err:
|
||||
output.speak("Error %s: %s" % (err.api_code, err.reason), True)
|
||||
except TweepyException as err:
|
||||
output.speak("Error %s" % (str(err)), True)
|
||||
|
||||
def unfollow(self, user):
|
||||
try:
|
||||
id = self.session.twitter.destroy_friendship(screen_name=user )
|
||||
except TweepError as err:
|
||||
output.speak("Error %s: %s" % (err.api_code, err.reason), True)
|
||||
except TweepyException as err:
|
||||
output.speak("Error %s" % (str(err)), True)
|
||||
|
||||
def mute(self, user):
|
||||
try:
|
||||
id = self.session.twitter.create_mute(screen_name=user )
|
||||
except TweepError as err:
|
||||
output.speak("Error %s: %s" % (err.api_code, err.reason), True)
|
||||
except TweepyException as err:
|
||||
output.speak("Error %s" % (str(err)), True)
|
||||
|
||||
def unmute(self, user):
|
||||
try:
|
||||
id = self.session.twitter.destroy_mute(screen_name=user )
|
||||
except TweepError as err:
|
||||
output.speak("Error %s: %s" % (err.api_code, err.reason), True)
|
||||
except TweepyException as err:
|
||||
output.speak("Error %s" % (str(err)), True)
|
||||
|
||||
def report(self, user):
|
||||
try:
|
||||
id = self.session.twitter.report_spam(screen_name=user )
|
||||
except TweepError as err:
|
||||
output.speak("Error %s: %s" % (err.api_code, err.reason), True)
|
||||
except TweepyException as err:
|
||||
output.speak("Error %s" % (str(err)), True)
|
||||
|
||||
def block(self, user):
|
||||
try:
|
||||
id = self.session.twitter.create_block(screen_name=user )
|
||||
except TweepError as err:
|
||||
output.speak("Error %s: %s" % (err.api_code, err.reason), True)
|
||||
except TweepyException as err:
|
||||
output.speak("Error %s" % (str(err)), True)
|
||||
|
||||
def unblock(self, user):
|
||||
try:
|
||||
id = self.session.twitter.destroy_block(screen_name=user )
|
||||
except TweepError as err:
|
||||
output.speak("Error %s: %s" % (err.api_code, err.reason), True)
|
||||
except TweepyException as err:
|
||||
output.speak("Error %s" % (str(err)), True)
|
||||
|
||||
def ignore_client(self, user):
|
||||
tweet = self.buffer.get_right_tweet()
|
||||
|
53
src/controller/userAliasController.py
Normal file
53
src/controller/userAliasController.py
Normal file
@@ -0,0 +1,53 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import widgetUtils
|
||||
from pubsub import pub
|
||||
from wxUI.dialogs import userAliasDialogs
|
||||
from extra import autocompletionUsers
|
||||
|
||||
class userAliasController(object):
|
||||
def __init__(self, settings):
|
||||
super(userAliasController, self).__init__()
|
||||
self.settings = settings
|
||||
self.dialog = userAliasDialogs.userAliasEditorDialog()
|
||||
self.update_aliases_manager()
|
||||
widgetUtils.connect_event(self.dialog.add, widgetUtils.BUTTON_PRESSED, self.on_add)
|
||||
widgetUtils.connect_event(self.dialog.edit, widgetUtils.BUTTON_PRESSED, self.on_edit)
|
||||
widgetUtils.connect_event(self.dialog.remove, widgetUtils.BUTTON_PRESSED, self.on_remove)
|
||||
pub.subscribe(self.update_aliases_manager, "alias-added")
|
||||
self.dialog.ShowModal()
|
||||
|
||||
def update_aliases_manager(self):
|
||||
self.dialog.users.Clear()
|
||||
aliases = [self.settings["user-aliases"].get(k) for k in self.settings["user-aliases"].keys()]
|
||||
if len(aliases) > 0:
|
||||
self.dialog.users.InsertItems(aliases, 0)
|
||||
self.dialog.on_selection_changes()
|
||||
|
||||
def on_add(self, *args, **kwargs):
|
||||
pub.sendMessage("execute-action", action="add_alias")
|
||||
|
||||
def on_edit(self, *args, **kwargs):
|
||||
selection = self.dialog.get_selected_user()
|
||||
if selection != "":
|
||||
edited = self.dialog.edit_alias_dialog(_("Edit alias for {}").format(selection))
|
||||
if edited == None or edited == "":
|
||||
return
|
||||
for user_key in self.settings["user-aliases"].keys():
|
||||
if self.settings["user-aliases"][user_key] == selection:
|
||||
self.settings["user-aliases"][user_key] = edited
|
||||
self.settings.write()
|
||||
self.update_aliases_manager()
|
||||
break
|
||||
|
||||
def on_remove(self, *args, **kwargs):
|
||||
selection = self.dialog.get_selected_user()
|
||||
if selection == None or selection == "":
|
||||
return
|
||||
should_remove = self.dialog.remove_alias_dialog()
|
||||
if should_remove:
|
||||
for user_key in self.settings["user-aliases"].keys():
|
||||
if self.settings["user-aliases"][user_key] == selection:
|
||||
self.settings["user-aliases"].pop(user_key)
|
||||
self.settings.write()
|
||||
self.update_aliases_manager()
|
||||
break
|
@@ -1,5 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import widgetUtils
|
||||
from tweepy.errors import TweepyException
|
||||
from . import storage, wx_manage
|
||||
from wxUI import commonMessageDialogs
|
||||
|
||||
@@ -27,8 +28,9 @@ class autocompletionManage(object):
|
||||
if usr == False:
|
||||
return
|
||||
try:
|
||||
data = self.session.twitter.twitter.get_user(screen_name=usr)
|
||||
except:
|
||||
data = self.session.twitter.get_user(screen_name=usr)
|
||||
except TweepyException as e:
|
||||
log.exception("Exception raised when attempting to add an user to the autocomplete database manually.")
|
||||
self.dialog.show_invalid_user_error()
|
||||
return
|
||||
self.database.set_user(data.screen_name, data.name, 0)
|
||||
|
@@ -21,7 +21,7 @@ class storage(object):
|
||||
return self.cursor.fetchall()
|
||||
|
||||
def get_users(self, term):
|
||||
self.cursor.execute("""SELECT * FROM users WHERE user LIKE ?""", ('{}%'.format(term),))
|
||||
self.cursor.execute("""SELECT * FROM users WHERE UPPER(user) LIKE :term OR UPPER(name) LIKE :term""", {"term": "%{}%".format(term.upper())})
|
||||
return self.cursor.fetchall()
|
||||
|
||||
def set_user(self, screen_name, user_name, from_a_buffer):
|
||||
|
@@ -34,4 +34,5 @@ configuration = string(default="control+win+o")
|
||||
accountConfiguration = string(default="control+win+shift+o")
|
||||
update_buffer = string(default="control+win+shift+u")
|
||||
ocr_image = string(default="win+alt+o")
|
||||
open_in_browser = string(default="alt+control+win+return")
|
||||
open_in_browser = string(default="alt+control+win+return")
|
||||
add_alias=string(default="")
|
@@ -53,4 +53,5 @@ configuration = string(default="control+win+o")
|
||||
accountConfiguration = string(default="control+win+shift+o")
|
||||
update_buffer = string(default="control+win+shift+u")
|
||||
ocr_image = string(default="win+alt+o")
|
||||
open_in_browser = string(default="alt+control+win+return")
|
||||
open_in_browser = string(default="alt+control+win+return")
|
||||
add_alias=string(default="")
|
@@ -54,4 +54,5 @@ configuration = string(default="control+win+alt+o")
|
||||
accountConfiguration = string(default="control+win+shift+o")
|
||||
update_buffer = string(default="control+alt+shift+u")
|
||||
ocr_image = string(default="win+alt+o")
|
||||
open_in_browser = string(default="alt+control+win+return")
|
||||
open_in_browser = string(default="alt+control+win+return")
|
||||
add_alias=string(default="")
|
58
src/keymaps/Windows11.keymap
Normal file
58
src/keymaps/Windows11.keymap
Normal file
@@ -0,0 +1,58 @@
|
||||
[info]
|
||||
name = string(default="Windows 11")
|
||||
desc = string(default="A keymap with remapped modifiers for Windows 11 compatibility.")
|
||||
author = string(default="Bill Jesús <galorasd@gmail.com>")
|
||||
|
||||
[keymap]
|
||||
up = string(default="control+alt+win+up")
|
||||
down = string(default="control+alt+win+down")
|
||||
left = string(default="control+alt+win+left")
|
||||
right = string(default="control+alt+win+right")
|
||||
next_account = string(default="control+alt+win+shift+right")
|
||||
previous_account = string(default="control+alt+win+shift+left")
|
||||
open_conversation = string(default="control+alt+win+c")
|
||||
show_hide = string(default="control+win+w")
|
||||
post_tweet = string(default="alt+win+n")
|
||||
post_reply = string(default="control+win+r")
|
||||
post_retweet = string(default="alt+win+shift+r")
|
||||
send_dm = string(default="alt+win+shift+d")
|
||||
toggle_like = string(default="control+alt+win+f")
|
||||
follow = string(default="alt+win+shift+s")
|
||||
user_details = string(default="alt+win+shift+n")
|
||||
view_item = string(default="alt+win+v")
|
||||
exit = string(default="alt+win+f4")
|
||||
open_timeline = string(default="alt+win+i")
|
||||
remove_buffer = string(default="alt+win+shift+i")
|
||||
url = string(default="alt+win+return")
|
||||
audio = string(default="alt+shift+win+return")
|
||||
volume_up = string(default="control+alt+win+shift+up")
|
||||
go_home = string(default="control+alt+win+home")
|
||||
volume_down = string(default="control+alt+win+shift+down")
|
||||
go_end = string(default="control+alt+win+end")
|
||||
go_page_up = string(default="control+win+pageup")
|
||||
go_page_down = string(default="control+win+pagedown")
|
||||
update_profile = string(default="alt+win+p")
|
||||
delete = string(default="alt+win+delete")
|
||||
clear_buffer = string(default="alt+win+shift+delete")
|
||||
repeat_item = string(default="control+alt+win+space")
|
||||
copy_to_clipboard = string(default="alt+win+shift+c")
|
||||
add_to_list = string(default="alt+win+a")
|
||||
remove_from_list = string(default="alt+win+shift+a")
|
||||
toggle_buffer_mute = string(default="alt+win+shift+m")
|
||||
toggle_session_mute = string(default="control+alt+win+m")
|
||||
toggle_autoread = string(default="alt+win+e")
|
||||
search = string(default="alt+win+-")
|
||||
edit_keystrokes = string(default="alt+win+k")
|
||||
view_user_lists = string(default="alt+win+l")
|
||||
get_more_items = string(default="alt+win+pageup")
|
||||
reverse_geocode = string(default="control+win+g")
|
||||
view_reverse_geocode = string(default="alt+win+shift+g")
|
||||
get_trending_topics = string(default="control+win+t")
|
||||
check_for_updates = string(default="alt+win+u")
|
||||
list_manager = string(default="alt+win+shift+l")
|
||||
configuration = string(default="control+win+alt+o")
|
||||
accountConfiguration = string(default="control+win+shift+o")
|
||||
update_buffer = string(default="control+alt+shift+u")
|
||||
ocr_image = string(default="win+alt+o")
|
||||
open_in_browser = string(default="alt+control+win+return")
|
||||
add_alias=string(default="")
|
@@ -55,4 +55,5 @@ list_manager = string(default="control+win+shift+l")
|
||||
configuration = string(default="control+win+o")
|
||||
accountConfiguration = string(default="control+win+shift+o")
|
||||
update_buffer = string(default="control+win+shift+u")
|
||||
open_in_browser = string(default="alt+control+win+return")
|
||||
open_in_browser = string(default="alt+control+win+return")
|
||||
add_alias=string(default="")
|
@@ -56,4 +56,5 @@ configuration = string(default="control+win+o")
|
||||
accountConfiguration = string(default="control+win+shift+o")
|
||||
update_buffer = string(default="control+win+shift+u")
|
||||
ocr_image = string(default="win+alt+o")
|
||||
open_in_browser = string(default="alt+control+win+return")
|
||||
open_in_browser = string(default="alt+control+win+return")
|
||||
add_alias=string(default="")
|
@@ -1,5 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
actions = {
|
||||
"up": _(u"Go up in the current buffer"),
|
||||
"down": _(u"Go down in the current buffer"),
|
||||
@@ -57,4 +56,6 @@ actions = {
|
||||
"audio": _(u"Try to play an audio file"),
|
||||
"update_buffer": _(u"Updates the buffer and retrieves possible lost items there."),
|
||||
"ocr_image": _(u"Extracts the text from a picture and displays the result in a dialog."),
|
||||
"add_alias": _("Adds an alias to an user"),
|
||||
}
|
||||
|
@@ -1,7 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import
|
||||
from __future__ import unicode_literals
|
||||
from builtins import object
|
||||
import widgetUtils
|
||||
import config
|
||||
from . import wx_ui
|
||||
@@ -18,6 +15,7 @@ class KeystrokeEditor(object):
|
||||
self.hold_map = self.map.copy()
|
||||
self.dialog.put_keystrokes(constants.actions, self.map)
|
||||
widgetUtils.connect_event(self.dialog.edit, widgetUtils.BUTTON_PRESSED, self.edit_keystroke)
|
||||
widgetUtils.connect_event(self.dialog.undefine, widgetUtils.BUTTON_PRESSED, self.undefine_keystroke)
|
||||
widgetUtils.connect_event(self.dialog.execute, widgetUtils.BUTTON_PRESSED, self.execute_action)
|
||||
self.dialog.get_response()
|
||||
|
||||
@@ -33,6 +31,17 @@ class KeystrokeEditor(object):
|
||||
self.map[action] = new_keystroke
|
||||
self.dialog.put_keystrokes(constants.actions, self.map)
|
||||
|
||||
def undefine_keystroke(self, *args, **kwargs):
|
||||
action = self.dialog.actions[self.dialog.get_action()]
|
||||
keystroke = self.map.get(action)
|
||||
if keystroke == None:
|
||||
return
|
||||
answer = self.dialog.undefine_keystroke_confirmation()
|
||||
if answer == widgetUtils.YES:
|
||||
self.map[action] = ""
|
||||
self.changed = True
|
||||
self.dialog.put_keystrokes(constants.actions, self.map)
|
||||
|
||||
def set_keystroke(self, keystroke, dialog):
|
||||
for i in keystroke.split("+"):
|
||||
if hasattr(dialog, i):
|
||||
|
@@ -1,5 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
import wx
|
||||
from multiplatform_widgets import widgets
|
||||
from wxUI.dialogs import baseDialog
|
||||
@@ -18,6 +17,7 @@ class keystrokeEditorDialog(baseDialog.BaseWXDialog):
|
||||
firstSizer.Add(self.keys.list, 0, wx.ALL, 5)
|
||||
self.edit = wx.Button(panel, -1, _(u"Edit"))
|
||||
self.edit.SetDefault()
|
||||
self.undefine = wx.Button(panel, -1, _("Undefine keystroke"))
|
||||
self.execute = wx.Button(panel, -1, _(u"Execute action"))
|
||||
close = wx.Button(panel, wx.ID_CANCEL, _(u"Close"))
|
||||
secondSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
@@ -37,13 +37,18 @@ class keystrokeEditorDialog(baseDialog.BaseWXDialog):
|
||||
continue
|
||||
action = actions[i]
|
||||
self.actions.append(i)
|
||||
keystroke = keystrokes[i]
|
||||
keystroke = keystrokes.get(i)
|
||||
if keystroke == "":
|
||||
keystroke = _("Undefined")
|
||||
self.keys.insert_item(False, *[action, keystroke])
|
||||
self.keys.select_item(selection)
|
||||
|
||||
def get_action(self):
|
||||
return self.keys.get_selected()
|
||||
|
||||
def undefine_keystroke_confirmation(self):
|
||||
return wx.MessageDialog(self, _("Are you sure you want to undefine this keystroke?"), _("Undefine keystroke"), wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION).ShowModal()
|
||||
|
||||
class editKeystrokeDialog(baseDialog.BaseWXDialog):
|
||||
def __init__(self):
|
||||
super(editKeystrokeDialog, self).__init__(parent=None, id=-1, title=_(u"Editing keystroke"))
|
||||
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -6,7 +6,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: TW Blue 0.85\n"
|
||||
"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n"
|
||||
"PO-Revision-Date: 2020-10-23 14:30+0300\n"
|
||||
"PO-Revision-Date: 2021-07-05 16:03+0200\n"
|
||||
"Last-Translator: Artem Plaksin <admin@maniyax.ru>\n"
|
||||
"Language-Team: Alexander Jaszyn <a.jaszyn@ya.ru>\n"
|
||||
"Language: ru\n"
|
||||
@@ -14,7 +14,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
"X-Generator: Poedit 1.8.8\n"
|
||||
"X-Generator: Poedit 3.0\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
||||
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
@@ -208,14 +208,12 @@ msgstr ""
|
||||
"личных сообщений вместо этого."
|
||||
|
||||
#: ../src\controller\buffers\twitterBuffers.py:983
|
||||
#, fuzzy
|
||||
msgid "{0} new followers."
|
||||
msgstr "Новый читатель."
|
||||
msgstr "{0} новых читателей."
|
||||
|
||||
#: ../src\controller\buffers\twitterBuffers.py:1266
|
||||
#, fuzzy
|
||||
msgid "This action is not supported in the buffer, yet."
|
||||
msgstr "Это действие не поддерживается в данном буфере"
|
||||
msgstr "Это действие пока не поддерживается в буфере."
|
||||
|
||||
#: ../src\controller\mainController.py:273
|
||||
msgid "Ready"
|
||||
@@ -314,9 +312,8 @@ msgid "Select the user"
|
||||
msgstr "Выберите пользователя"
|
||||
|
||||
#: ../src\controller\mainController.py:809 ../src\controller\messages.py:236
|
||||
#, fuzzy
|
||||
msgid "MMM D, YYYY. H:m"
|
||||
msgstr "dddd, MMMM D, YYYY H:m:s"
|
||||
msgstr "MMM D, YYYY. H:m"
|
||||
|
||||
#: ../src\controller\mainController.py:934
|
||||
msgid "Conversation with {0}"
|
||||
@@ -1702,9 +1699,8 @@ msgid "Opens the global settings dialogue"
|
||||
msgstr "Открыть основные настройки"
|
||||
|
||||
#: ../src\keystrokeEditor\constants.py:54
|
||||
#, fuzzy
|
||||
msgid "Opens the list manager"
|
||||
msgstr "Менеджер Списков"
|
||||
msgstr "Открывает менеджер списков"
|
||||
|
||||
#: ../src\keystrokeEditor\constants.py:55
|
||||
msgid "Opens the account settings dialogue"
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -17,7 +17,7 @@ from sessions.twitter import session
|
||||
from . import manager
|
||||
import config_utils
|
||||
import config
|
||||
from tweepy.error import TweepError
|
||||
from tweepy.errors import TweepyException
|
||||
log = logging.getLogger("sessionmanager.sessionManager")
|
||||
|
||||
class sessionManagerController(object):
|
||||
@@ -83,7 +83,7 @@ class sessionManagerController(object):
|
||||
if i not in config.app["sessions"]["ignored_sessions"]:
|
||||
try:
|
||||
s.login()
|
||||
except TweepError:
|
||||
except TweepyException:
|
||||
self.show_auth_error(s.settings["twitter"]["user_name"])
|
||||
continue
|
||||
sessions.sessions[i] = s
|
||||
|
@@ -43,6 +43,10 @@ class baseSession(object):
|
||||
self.logged = False
|
||||
self.settings = None
|
||||
self.db={}
|
||||
# Config specification file.
|
||||
self.config_spec = "conf.defaults"
|
||||
# Session type.
|
||||
self.type = "base"
|
||||
|
||||
@property
|
||||
def is_logged(self):
|
||||
@@ -52,7 +56,7 @@ class baseSession(object):
|
||||
""" Get settings for a session."""
|
||||
file_ = "%s/session.conf" % (self.session_id,)
|
||||
log.debug("Creating config file %s" % (file_,))
|
||||
self.settings = config_utils.load_config(os.path.join(paths.config_path(), file_), os.path.join(paths.app_path(), "Conf.defaults"))
|
||||
self.settings = config_utils.load_config(os.path.join(paths.config_path(), file_), os.path.join(paths.app_path(), self.config_spec))
|
||||
self.init_sound()
|
||||
self.load_persistent_data()
|
||||
|
||||
|
@@ -45,9 +45,9 @@ def compose_tweet(tweet, db, relative_times, show_screen_names=False, session=No
|
||||
else:
|
||||
value = "text"
|
||||
if hasattr(tweet, "retweeted_status") and value != "message":
|
||||
text = StripChars(getattr(tweet.retweeted_status, value))
|
||||
text = utils.clean_mentions(StripChars(getattr(tweet.retweeted_status, value)))
|
||||
else:
|
||||
text = StripChars(getattr(tweet, value))
|
||||
text = utils.clean_mentions(StripChars(getattr(tweet, value)))
|
||||
if show_screen_names:
|
||||
user = session.get_user(tweet.user).screen_name
|
||||
else:
|
||||
@@ -111,7 +111,7 @@ def compose_quoted_tweet(quoted_tweet, original_tweet, show_screen_names=False,
|
||||
value = "full_text"
|
||||
else:
|
||||
value = "text"
|
||||
text = StripChars(getattr(quoted_tweet, value))
|
||||
text = utils.clean_mentions(StripChars(getattr(quoted_tweet, value)))
|
||||
if show_screen_names:
|
||||
quoting_user = session.get_user(quoted_tweet.user).screen_name
|
||||
else:
|
||||
@@ -124,9 +124,9 @@ def compose_quoted_tweet(quoted_tweet, original_tweet, show_screen_names=False,
|
||||
if hasattr(original_tweet, "message"):
|
||||
original_text = original_tweet.message
|
||||
elif hasattr(original_tweet, "full_text"):
|
||||
original_text = StripChars(original_tweet.full_text)
|
||||
original_text = utils.clean_mentions(StripChars(original_tweet.full_text))
|
||||
else:
|
||||
original_text = StripChars(original_tweet.text)
|
||||
original_text = utils.clean_mentions(StripChars(original_tweet.text))
|
||||
quoted_tweet.message = _(u"{0}. Quoted tweet from @{1}: {2}").format( text, original_user, original_text)
|
||||
quoted_tweet = tweets.clear_url(quoted_tweet)
|
||||
if hasattr(original_tweet, "entities") and original_tweet.entities.get("urls"):
|
||||
|
@@ -8,9 +8,10 @@ import wx
|
||||
import config
|
||||
import output
|
||||
import application
|
||||
import appkeys
|
||||
from pubsub import pub
|
||||
import tweepy
|
||||
from tweepy.error import TweepError
|
||||
from tweepy.errors import TweepyException, Forbidden, NotFound
|
||||
from tweepy.models import User as UserModel
|
||||
from mysc.thread_utils import call_threaded
|
||||
from keys import keyring
|
||||
@@ -51,7 +52,7 @@ class Session(base.baseSession):
|
||||
if i.id < last_id:
|
||||
log.error("Ignoring an older tweet... Last id: {0}, tweet id: {1}".format(last_id, i.id))
|
||||
continue
|
||||
if utils.find_item(i.id, self.db[name]) == None and utils.is_allowed(i, self.settings, name) == True:
|
||||
if utils.find_item(i, self.db[name]) == None and utils.is_allowed(i, self.settings, name) == True:
|
||||
if i == False: continue
|
||||
reduced_object = reduce.reduce_tweet(i)
|
||||
reduced_object = self.check_quoted_status(reduced_object)
|
||||
@@ -72,7 +73,7 @@ class Session(base.baseSession):
|
||||
self.db[name] = []
|
||||
objects = self.db[name]
|
||||
for i in data:
|
||||
if utils.find_item(i.id, self.db[name]) == None:
|
||||
if utils.find_item(i, self.db[name]) == None:
|
||||
if self.settings["general"]["reverse_timelines"] == False: objects.append(i)
|
||||
else: objects.insert(0, i)
|
||||
num = num+1
|
||||
@@ -94,12 +95,12 @@ class Session(base.baseSession):
|
||||
for i in data:
|
||||
# Twitter returns sender_id as str, which must be converted to int in order to match to our user_id object.
|
||||
if int(i.message_create["sender_id"]) == self.db["user_id"]:
|
||||
if "sent_direct_messages" in self.db and utils.find_item(i.id, self.db["sent_direct_messages"]) == None:
|
||||
if "sent_direct_messages" in self.db and utils.find_item(i, self.db["sent_direct_messages"]) == None:
|
||||
if self.settings["general"]["reverse_timelines"] == False: sent_objects.append(i)
|
||||
else: sent_objects.insert(0, i)
|
||||
sent = sent+1
|
||||
else:
|
||||
if utils.find_item(i.id, self.db["direct_messages"]) == None:
|
||||
if utils.find_item(i, self.db["direct_messages"]) == None:
|
||||
if self.settings["general"]["reverse_timelines"] == False: objects.append(i)
|
||||
else: objects.insert(0, i)
|
||||
incoming = incoming+1
|
||||
@@ -124,6 +125,7 @@ class Session(base.baseSession):
|
||||
# This will be especially useful because if the user reactivates their account later, TWblue will try to retrieve such user again at startup.
|
||||
# If we wouldn't implement this approach, TWBlue would save permanently the "deleted user" object.
|
||||
self.deleted_users = {}
|
||||
self.type = "twitter"
|
||||
pub.subscribe(self.handle_new_status, "newStatus")
|
||||
pub.subscribe(self.handle_connected, "streamConnected")
|
||||
|
||||
@@ -134,9 +136,10 @@ class Session(base.baseSession):
|
||||
if self.settings["twitter"]["user_key"] != None and self.settings["twitter"]["user_secret"] != None:
|
||||
try:
|
||||
log.debug("Logging in to twitter...")
|
||||
self.auth = tweepy.OAuthHandler(keyring.get("api_key"), keyring.get("api_secret"))
|
||||
self.auth = tweepy.OAuthHandler(appkeys.twitter_api_key, appkeys.twitter_api_secret)
|
||||
self.auth.set_access_token(self.settings["twitter"]["user_key"], self.settings["twitter"]["user_secret"])
|
||||
self.twitter = tweepy.API(self.auth)
|
||||
self.twitter_v2 = tweepy.Client(consumer_key=appkeys.twitter_api_key, consumer_secret=appkeys.twitter_api_secret, access_token=self.settings["twitter"]["user_key"], access_token_secret=self.settings["twitter"]["user_secret"])
|
||||
if verify_credentials == True:
|
||||
self.credentials = self.twitter.verify_credentials()
|
||||
self.logged = True
|
||||
@@ -155,7 +158,7 @@ class Session(base.baseSession):
|
||||
if self.logged == True:
|
||||
raise Exceptions.AlreadyAuthorisedError("The authorisation process is not needed at this time.")
|
||||
else:
|
||||
self.auth = tweepy.OAuthHandler(keyring.get("api_key"), keyring.get("api_secret"))
|
||||
self.auth = tweepy.OAuthHandler(appkeys.twitter_api_key, appkeys.twitter_api_secret)
|
||||
redirect_url = self.auth.get_authorization_url()
|
||||
webbrowser.open_new_tab(redirect_url)
|
||||
self.authorisation_dialog = authorisationDialog()
|
||||
@@ -198,14 +201,14 @@ class Session(base.baseSession):
|
||||
try:
|
||||
val = getattr(self.twitter, call_name)(*args, **kwargs)
|
||||
finished = True
|
||||
except TweepError as e:
|
||||
output.speak(e.reason)
|
||||
except TweepyException as e:
|
||||
output.speak(str(e))
|
||||
val = None
|
||||
if e.error_code != 403 and e.error_code != 404:
|
||||
if type(e) != NotFound and type(e) != Forvidden:
|
||||
tries = tries+1
|
||||
time.sleep(5)
|
||||
elif report_failure and hasattr(e, 'reason'):
|
||||
output.speak(_("%s failed. Reason: %s") % (action, e.reason))
|
||||
elif report_failure:
|
||||
output.speak(_("%s failed. Reason: %s") % (action, str(e)))
|
||||
finished = True
|
||||
# except:
|
||||
# tries = tries + 1
|
||||
@@ -217,7 +220,7 @@ class Session(base.baseSession):
|
||||
|
||||
def search(self, name, *args, **kwargs):
|
||||
""" Search in twitter, passing args and kwargs as arguments to the Twython function."""
|
||||
tl = self.twitter.search(*args, **kwargs)
|
||||
tl = self.twitter.search_tweets(*args, **kwargs)
|
||||
tl.reverse()
|
||||
return tl
|
||||
|
||||
@@ -270,12 +273,12 @@ class Session(base.baseSession):
|
||||
# @_require_login
|
||||
def get_lists(self):
|
||||
""" Gets the lists that the user is subscribed to and stores them in the database. Returns None."""
|
||||
self.db["lists"] = self.twitter.lists_all(reverse=True)
|
||||
self.db["lists"] = self.twitter.get_lists(reverse=True)
|
||||
|
||||
# @_require_login
|
||||
def get_muted_users(self):
|
||||
""" Gets muted users (oh really?)."""
|
||||
self.db["muted_users"] = self.twitter.mutes_ids()
|
||||
self.db["muted_users"] = self.twitter.get_muted_ids()
|
||||
|
||||
# @_require_login
|
||||
def get_stream(self, name, function, *args, **kwargs):
|
||||
@@ -416,12 +419,12 @@ class Session(base.baseSession):
|
||||
log.debug("Requesting user id {} as it is not present in the users database.".format(id))
|
||||
try:
|
||||
user = self.twitter.get_user(id=id)
|
||||
except TweepError as err:
|
||||
except TweepyException as err:
|
||||
user = UserModel(None)
|
||||
user.screen_name = "deleted_user"
|
||||
user.id = id
|
||||
user.name = _("Deleted account")
|
||||
if hasattr(err, "api_code") and err.api_code == 50:
|
||||
if type(err) == NotFound:
|
||||
self.deleted_users[id] = user
|
||||
return user
|
||||
else:
|
||||
@@ -430,9 +433,25 @@ class Session(base.baseSession):
|
||||
users = self.db["users"]
|
||||
users[user.id_str] = user
|
||||
self.db["users"] = users
|
||||
user.name = self.get_user_alias(user)
|
||||
return user
|
||||
else:
|
||||
return self.db["users"][str(id)]
|
||||
user = self.db["users"][str(id)]
|
||||
user.name = self.get_user_alias(user)
|
||||
return user
|
||||
|
||||
def get_user_alias(self, user):
|
||||
""" Retrieves an alias for the passed user model, if exists.
|
||||
@ user Tweepy.models.user: An user object.
|
||||
"""
|
||||
aliases = self.settings.get("user-aliases")
|
||||
if aliases == None:
|
||||
log.error("Aliases are not defined for this config spec.")
|
||||
return user.name
|
||||
user_alias = aliases.get(user.id_str)
|
||||
if user_alias != None:
|
||||
return user_alias
|
||||
return user.name
|
||||
|
||||
def get_user_by_screen_name(self, screen_name):
|
||||
""" Returns an user identifier associated with a screen_name.
|
||||
@@ -466,14 +485,14 @@ class Session(base.baseSession):
|
||||
return
|
||||
log.debug("TWBlue will get %d new users from Twitter." % (len(users_to_retrieve)))
|
||||
try:
|
||||
users = self.twitter.lookup_users(user_ids=users_to_retrieve, tweet_mode="extended")
|
||||
users = self.twitter.lookup_users(user_id=users_to_retrieve, tweet_mode="extended")
|
||||
users_db = self.db["users"]
|
||||
for user in users:
|
||||
users_db[user.id_str] = user
|
||||
log.debug("Added %d new users" % (len(users)))
|
||||
self.db["users"] = users_db
|
||||
except TweepError as err:
|
||||
if hasattr(err, "api_code") and err.api_code == 17: # Users not found.
|
||||
except TweepyException as err:
|
||||
if type(err) == NotFound: # User not found.
|
||||
log.error("The specified users {} were not found in twitter.".format(user_ids))
|
||||
# Creates a deleted user object for every user_id not found here.
|
||||
# This will make TWBlue to not waste Twitter API calls when attempting to retrieve those users again.
|
||||
@@ -506,9 +525,8 @@ class Session(base.baseSession):
|
||||
def start_streaming(self):
|
||||
if config.app["app-settings"]["no_streaming"]:
|
||||
return
|
||||
self.stream_listener = streaming.StreamListener(twitter_api=self.twitter, user=self.db["user_name"], user_id=self.db["user_id"], muted_users=self.db["muted_users"])
|
||||
self.stream = streaming.Stream(auth = self.auth, listener=self.stream_listener, chunk_size=1025)
|
||||
self.stream_thread = call_threaded(self.stream.filter, follow=self.stream_listener.users, stall_warnings=True)
|
||||
self.stream = streaming.Stream(twitter_api=self.twitter, user=self.db["user_name"], user_id=self.db["user_id"], muted_users=self.db["muted_users"], consumer_key=appkeys.twitter_api_key, consumer_secret=appkeys.twitter_api_secret, access_token=self.settings["twitter"]["user_key"], access_token_secret=self.settings["twitter"]["user_secret"], chunk_size=1025)
|
||||
self.stream_thread = call_threaded(self.stream.filter, follow=self.stream.users, stall_warnings=True)
|
||||
|
||||
def stop_streaming(self):
|
||||
if config.app["app-settings"]["no_streaming"]:
|
||||
@@ -537,7 +555,7 @@ class Session(base.baseSession):
|
||||
status._json = {**status._json, **status._json["extended_tweet"]}
|
||||
# Sends status to database, where it will be reduced and changed according to our needs.
|
||||
buffers_to_send = []
|
||||
if status.user.id_str in self.stream_listener.users:
|
||||
if status.user.id_str in self.stream.users:
|
||||
buffers_to_send.append("home_timeline")
|
||||
if status.user.id == self.db["user_id"]:
|
||||
buffers_to_send.append("sent_tweets")
|
||||
|
@@ -12,17 +12,17 @@ from pubsub import pub
|
||||
|
||||
log = logging.getLogger("sessions.twitter.streaming")
|
||||
|
||||
class StreamListener(tweepy.StreamListener):
|
||||
class Stream(tweepy.Stream):
|
||||
|
||||
def __init__(self, twitter_api, user, user_id, muted_users=[], *args, **kwargs):
|
||||
super(StreamListener, self).__init__(*args, **kwargs)
|
||||
super(Stream, self).__init__(*args, **kwargs)
|
||||
log.debug("Starting streaming listener for account {}".format(user))
|
||||
self.started = False
|
||||
self.users = []
|
||||
self.api = twitter_api
|
||||
self.user = user
|
||||
self.user_id = user_id
|
||||
friends = self.api.friends_ids()
|
||||
friends = self.api.get_friend_ids()
|
||||
log.debug("Retrieved {} friends to add to the streaming listener.".format(len(friends)))
|
||||
self.users.append(str(self.user_id))
|
||||
log.debug("Got {} muted users.".format(len(muted_users)))
|
||||
@@ -45,78 +45,3 @@ class StreamListener(tweepy.StreamListener):
|
||||
return
|
||||
if status.user.id_str in self.users:
|
||||
pub.sendMessage("newStatus", status=status, user=self.user)
|
||||
|
||||
|
||||
|
||||
class Stream(tweepy.Stream):
|
||||
|
||||
def _run(self):
|
||||
# Authenticate
|
||||
url = "https://%s%s" % (self.host, self.url)
|
||||
|
||||
# Connect and process the stream
|
||||
error_counter = 0
|
||||
resp = None
|
||||
exc_info = None
|
||||
while self.running:
|
||||
if self.retry_count is not None:
|
||||
if error_counter > self.retry_count:
|
||||
# quit if error count greater than retry count
|
||||
break
|
||||
try:
|
||||
auth = self.auth.apply_auth()
|
||||
resp = self.session.request('POST',
|
||||
url,
|
||||
data=self.body,
|
||||
timeout=self.timeout,
|
||||
stream=True,
|
||||
auth=auth,
|
||||
verify=self.verify,
|
||||
proxies = self.proxies)
|
||||
if resp.status_code != 200:
|
||||
if self.listener.on_error(resp.status_code) is False:
|
||||
break
|
||||
error_counter += 1
|
||||
if resp.status_code == 420:
|
||||
self.retry_time = max(self.retry_420_start,
|
||||
self.retry_time)
|
||||
time.sleep(self.retry_time)
|
||||
self.retry_time = min(self.retry_time * 2,
|
||||
self.retry_time_cap)
|
||||
else:
|
||||
error_counter = 0
|
||||
self.retry_time = self.retry_time_start
|
||||
self.snooze_time = self.snooze_time_step
|
||||
self.listener.on_connect()
|
||||
self._read_loop(resp)
|
||||
except (requests.ConnectionError, requests.Timeout, ssl.SSLError, urllib3.exceptions.ReadTimeoutError, urllib3.exceptions.ProtocolError) as exc:
|
||||
# This is still necessary, as a SSLError can actually be
|
||||
# thrown when using Requests
|
||||
# If it's not time out treat it like any other exception
|
||||
if isinstance(exc, ssl.SSLError):
|
||||
if not (exc.args and 'timed out' in str(exc.args[0])):
|
||||
exc_info = sys.exc_info()
|
||||
break
|
||||
if self.listener.on_timeout() is False:
|
||||
break
|
||||
if self.running is False:
|
||||
break
|
||||
time.sleep(self.snooze_time)
|
||||
self.snooze_time = min(self.snooze_time + self.snooze_time_step,
|
||||
self.snooze_time_cap)
|
||||
except Exception as exc:
|
||||
exc_info = sys.exc_info()
|
||||
# any other exception is fatal, so kill loop
|
||||
break
|
||||
|
||||
# cleanup
|
||||
self.running = False
|
||||
if resp:
|
||||
resp.close()
|
||||
|
||||
self.new_session()
|
||||
|
||||
if exc_info:
|
||||
# call a handler first so that the exception can be logged.
|
||||
self.listener.on_exception(exc_info[1])
|
||||
six.reraise(*exc_info)
|
||||
|
@@ -6,7 +6,7 @@ import logging
|
||||
import requests
|
||||
import time
|
||||
import sound
|
||||
from tweepy.error import TweepError
|
||||
from tweepy.errors import TweepyException, NotFound, Forbidden
|
||||
log = logging.getLogger("twitter.utils")
|
||||
""" Some utilities for the twitter interface."""
|
||||
|
||||
@@ -60,9 +60,13 @@ def find_urls (tweet, twitter_media=False):
|
||||
urls.append(i)
|
||||
return urls
|
||||
|
||||
def find_item(id, listItem):
|
||||
for i in range(0, len(listItem)):
|
||||
if listItem[i].id == id: return i
|
||||
def find_item(item, listItems):
|
||||
for i in range(0, len(listItems)):
|
||||
if listItems[i].id == item.id:
|
||||
return i
|
||||
# Check also retweets.
|
||||
if hasattr(item, "retweeted_status") and item.retweeted_status.id == listItems[i].id:
|
||||
return i
|
||||
return None
|
||||
|
||||
def find_list(name, lists):
|
||||
@@ -155,8 +159,8 @@ def if_user_exists(twitter, user):
|
||||
try:
|
||||
data = twitter.get_user(screen_name=user)
|
||||
return data
|
||||
except TweepError as err:
|
||||
if err.api_code == 50:
|
||||
except TweepyException as err:
|
||||
if type(err) == NotFound:
|
||||
return None
|
||||
else:
|
||||
return user
|
||||
@@ -223,12 +227,12 @@ def filter_tweet(tweet, tweet_data, settings, buffer_name):
|
||||
return True
|
||||
|
||||
def twitter_error(error):
|
||||
if error.api_code == 179:
|
||||
if type(error) == Forbidden:
|
||||
msg = _(u"Sorry, you are not authorised to see this status.")
|
||||
elif error.api_code == 144:
|
||||
elif type(error) == NotFound:
|
||||
msg = _(u"No status found with that ID")
|
||||
else:
|
||||
msg = _(u"Error code {0}").format(error.api_code,)
|
||||
msg = _(u"Error {0}").format(str(error),)
|
||||
output.speak(msg)
|
||||
|
||||
def expand_urls(text, entities):
|
||||
@@ -240,3 +244,20 @@ def expand_urls(text, entities):
|
||||
if url["url"] in text:
|
||||
text = text.replace(url["url"], url["expanded_url"])
|
||||
return text
|
||||
|
||||
def clean_mentions(text):
|
||||
new_text = text
|
||||
mentionned_people = [u for u in re.finditer("(?<=^|(?<=[^a-zA-Z0-9-\.]))@([A-Za-z0-9_]+)", text)]
|
||||
if len(mentionned_people) <= 2:
|
||||
return text
|
||||
end = -2
|
||||
total_users = 0
|
||||
for user in mentionned_people:
|
||||
if abs(user.start()-end) < 3:
|
||||
new_text = new_text.replace(user.group(0), "", 1)
|
||||
total_users = total_users+1
|
||||
end = user.end()
|
||||
if total_users-2 < 1:
|
||||
return text
|
||||
new_text = _("{user_1}, {user_2} and {all_users} more: {text}").format(user_1=mentionned_people[0].group(0), user_2=mentionned_people[1].group(0), all_users=total_users-2, text=new_text)
|
||||
return new_text
|
@@ -3,7 +3,7 @@ import sys
|
||||
import application
|
||||
import platform
|
||||
import os
|
||||
from cx_Freeze import setup, Executable
|
||||
from cx_Freeze import setup, Executable, winmsvcr
|
||||
from requests import certs
|
||||
|
||||
def get_architecture_files():
|
||||
@@ -40,16 +40,19 @@ build_exe_options = dict(
|
||||
build_exe="dist",
|
||||
optimize=1,
|
||||
includes=["enchant.tokenize.en"], # This is not handled automatically by cx_freeze.
|
||||
include_msvcr=True,
|
||||
include_msvcr=False,
|
||||
replace_paths = [("*", "")],
|
||||
include_files=["icon.ico", "conf.defaults", "app-configuration.defaults", "keymaps", "locales", "sounds", "documentation", ("keys/lib", "keys/lib"), find_sound_lib_datafiles(), find_accessible_output2_datafiles()]+get_architecture_files(),
|
||||
packages=["wxUI"],
|
||||
bin_path_excludes=["C:\\Program Files", "C:\Program Files (x86)"],
|
||||
)
|
||||
|
||||
executables = [
|
||||
Executable('main.py', base=base, targetName="twblue")
|
||||
Executable('main.py', base=base, target_name="twblue")
|
||||
]
|
||||
|
||||
winmsvcr.FILES = ()
|
||||
winmsvcr.FILES_TO_DUPLICATE = ()
|
||||
setup(name=application.name,
|
||||
version=application.version,
|
||||
description=application.description,
|
||||
|
@@ -114,6 +114,8 @@ class URLStream(object):
|
||||
# LibVLC controls.
|
||||
self.instance = vlc.Instance()
|
||||
self.player = self.instance.media_player_new()
|
||||
self.event_manager = self.player.event_manager()
|
||||
self.event_manager.event_attach(vlc.EventType.MediaPlayerEndReached, self.end_callback)
|
||||
|
||||
def prepare(self, url):
|
||||
""" Takes an URL and prepares it to be streamed. This function will try to unshorten the passed URL and, if needed, to transform it into a valid URL."""
|
||||
@@ -158,3 +160,9 @@ class URLStream(object):
|
||||
def stop_audio(self):
|
||||
output.speak(_(u"Stopped."), True)
|
||||
self.player.stop()
|
||||
|
||||
def end_callback(self, event, *args, **kwargs):
|
||||
call_threaded(self.player.stop)
|
||||
|
||||
def __del__(self):
|
||||
self.event_manager.event_detach(vlc.EventType.MediaPlayerEndReached)
|
@@ -1,4 +1,3 @@
|
||||
from __future__ import unicode_literals
|
||||
from logging import getLogger
|
||||
logger = getLogger('update')
|
||||
|
||||
@@ -24,8 +23,8 @@ def perform_update(endpoint, current_version, app_name='', password=None, update
|
||||
if not available_update:
|
||||
logger.debug("No update available")
|
||||
return False
|
||||
available_version = float(available_update['current_version'])
|
||||
if not float(available_version) > float(current_version) or platform.system()+platform.architecture()[0][:2] not in available_update['downloads']:
|
||||
available_version = available_update['current_version']
|
||||
if available_version == current_version or platform.system()+platform.architecture()[0][:2] not in available_update['downloads']:
|
||||
logger.debug("No update for this architecture")
|
||||
return False
|
||||
available_description = available_update.get('description', None)
|
||||
@@ -42,10 +41,10 @@ def perform_update(endpoint, current_version, app_name='', password=None, update
|
||||
downloaded = download_update(update_url, download_path, requests_session=requests_session, progress_callback=progress_callback)
|
||||
extracted = extract_update(downloaded, update_path, password=password)
|
||||
bootstrap_path = move_bootstrap(extracted)
|
||||
execute_bootstrap(bootstrap_path, extracted)
|
||||
logger.info("Update prepared for installation.")
|
||||
if callable(update_complete_callback):
|
||||
update_complete_callback()
|
||||
execute_bootstrap(bootstrap_path, extracted)
|
||||
logger.info("Update prepared for installation.")
|
||||
|
||||
def create_requests_session(app_name=None, version=None):
|
||||
user_agent = ''
|
||||
|
@@ -1,6 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import
|
||||
from __future__ import unicode_literals
|
||||
import application
|
||||
from . import update
|
||||
import platform
|
||||
|
38
src/write_version_data.py
Normal file
38
src/write_version_data.py
Normal file
@@ -0,0 +1,38 @@
|
||||
#! /usr/bin/env python# -*- coding: iso-8859-1 -*-
|
||||
""" Write version info (taken from the last commit) to application.py. This method has been implemented this way for running updates.
|
||||
This file is not intended to be called by the user. It will be used only by the Gitlab CI runner."""
|
||||
import os
|
||||
import requests
|
||||
from codecs import open
|
||||
|
||||
print("Writing version data for update...")
|
||||
commit_info = requests.get("https://gitlab.com/api/v4/projects/23482196/repository/commits/next-gen")
|
||||
commit_info = commit_info.json()
|
||||
commit = commit_info["short_id"]
|
||||
print("Got new version info: {commit}".format(commit=commit,))
|
||||
file = open("application.py", "r", encoding="utf-8")
|
||||
lines = file.readlines()
|
||||
lines[-1] = 'version = "{}"'.format(commit_info["created_at"][:10].replace("-", "."))
|
||||
file.close()
|
||||
file2 = open("application.py", "w", encoding="utf-8")
|
||||
file2.writelines(lines)
|
||||
file2.close()
|
||||
print("Wrote application.py with the new version info.")
|
||||
|
||||
print("Updating next version on installer setup...")
|
||||
file = open("..\\scripts\\twblue.nsi", "r", encoding="utf-8")
|
||||
contents = file.read()
|
||||
contents = contents.replace("0.95", commit_info["created_at"][:10].replace("-", "."))
|
||||
file.close()
|
||||
file2 = open("..\\scripts\\twblue.nsi", "w", encoding="utf-8")
|
||||
file2.write(contents)
|
||||
file2.close()
|
||||
print("done")
|
||||
print("Writing keys to module...")
|
||||
file3 = open("appkeys.py", "w")
|
||||
keys = """twitter_api_key = "{}"
|
||||
twitter_api_secret = "{}"
|
||||
""".format(os.environ.get("TWITTER_API_KEY"), os.environ.get("TWITTER_API_SECRET"))
|
||||
file3.write(keys)
|
||||
file3.close()
|
||||
print("Wrote set of keys for consumer of {}".format(os.environ.get("TWITTER_API_KEY")))
|
@@ -1,3 +1,3 @@
|
||||
from __future__ import absolute_import
|
||||
from __future__ import unicode_literals
|
||||
from . import baseDialog, trends, configuration, lists, message, search, find, show_user, update_profile, urlList, userSelection, utils, filterDialogs
|
||||
from . import baseDialog, trends, configuration, lists, message, search, find, show_user, update_profile, urlList, userSelection, utils, filterDialogs, userAliasDialogs
|
||||
|
@@ -1,6 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
from builtins import str
|
||||
import wx
|
||||
import widgetUtils
|
||||
|
||||
@@ -356,6 +354,8 @@ class viewTweet(widgetUtils.BaseDialog):
|
||||
infoBox.Add(sourceBox, 0, wx.ALL, 5)
|
||||
mainBox.Add(infoBox, 0, wx.ALL, 5)
|
||||
mainBox.Add(dateBox, 0, wx.ALL, 5)
|
||||
self.share = wx.Button(panel, wx.ID_ANY, _("Copy link to clipboard"))
|
||||
self.share.Enable(False)
|
||||
self.spellcheck = wx.Button(panel, -1, _("Check &spelling..."), size=wx.DefaultSize)
|
||||
self.unshortenButton = wx.Button(panel, -1, _(u"&Expand URL"), size=wx.DefaultSize)
|
||||
self.unshortenButton.Disable()
|
||||
@@ -363,6 +363,7 @@ class viewTweet(widgetUtils.BaseDialog):
|
||||
cancelButton = wx.Button(panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize)
|
||||
cancelButton.SetDefault()
|
||||
buttonsBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
buttonsBox.Add(self.share, 0, wx.ALL, 5)
|
||||
buttonsBox.Add(self.spellcheck, 0, wx.ALL, 5)
|
||||
buttonsBox.Add(self.unshortenButton, 0, wx.ALL, 5)
|
||||
buttonsBox.Add(self.translateButton, 0, wx.ALL, 5)
|
||||
@@ -429,6 +430,8 @@ class viewNonTweet(widgetUtils.BaseDialog):
|
||||
dateBox.Add(dateLabel, 0, wx.ALL, 5)
|
||||
dateBox.Add(date, 0, wx.ALL, 5)
|
||||
mainBox.Add(dateBox, 0, wx.ALL, 5)
|
||||
self.share = wx.Button(panel, wx.ID_ANY, _("Copy link to clipboard"))
|
||||
self.share.Enable(False)
|
||||
self.spellcheck = wx.Button(panel, -1, _("Check &spelling..."), size=wx.DefaultSize)
|
||||
self.unshortenButton = wx.Button(panel, -1, _(u"&Expand URL"), size=wx.DefaultSize)
|
||||
self.unshortenButton.Disable()
|
||||
@@ -436,6 +439,7 @@ class viewNonTweet(widgetUtils.BaseDialog):
|
||||
cancelButton = wx.Button(panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize)
|
||||
cancelButton.SetDefault()
|
||||
buttonsBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
buttonsBox.Add(self.share, 0, wx.ALL, 5)
|
||||
buttonsBox.Add(self.spellcheck, 0, wx.ALL, 5)
|
||||
buttonsBox.Add(self.unshortenButton, 0, wx.ALL, 5)
|
||||
buttonsBox.Add(self.translateButton, 0, wx.ALL, 5)
|
||||
@@ -463,5 +467,5 @@ class viewNonTweet(widgetUtils.BaseDialog):
|
||||
self.text.SetFocus()
|
||||
|
||||
def enable_button(self, buttonName):
|
||||
if getattr(self, buttonName):
|
||||
if hasattr(self, buttonName):
|
||||
return getattr(self, buttonName).Enable()
|
||||
|
95
src/wxUI/dialogs/userAliasDialogs.py
Normal file
95
src/wxUI/dialogs/userAliasDialogs.py
Normal file
@@ -0,0 +1,95 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import wx
|
||||
import gettext
|
||||
from . import baseDialog
|
||||
|
||||
class addAliasDialog(baseDialog.BaseWXDialog):
|
||||
def __init__(self, title, users):
|
||||
super(addAliasDialog, self).__init__(parent=None, id=wx.ID_ANY, title=title)
|
||||
panel = wx.Panel(self)
|
||||
userSizer = wx.BoxSizer()
|
||||
self.cb = wx.ComboBox(panel, -1, choices=users, value=users[0], size=wx.DefaultSize)
|
||||
self.cb.SetFocus()
|
||||
self.autocompletion = wx.Button(panel, -1, _(u"&Autocomplete users"))
|
||||
userSizer.Add(wx.StaticText(panel, -1, _(u"User")), 0, wx.ALL, 5)
|
||||
userSizer.Add(self.cb, 0, wx.ALL, 5)
|
||||
userSizer.Add(self.autocompletion, 0, wx.ALL, 5)
|
||||
aliasSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
aliasLabel = wx.StaticText(panel, wx.ID_ANY, _("Alias"))
|
||||
self.alias = wx.TextCtrl(panel, wx.ID_ANY)
|
||||
aliasSizer.Add(aliasLabel, 0, wx.ALL, 5)
|
||||
aliasSizer.Add(self.alias, 0, wx.ALL, 5)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
ok = wx.Button(panel, wx.ID_OK, _(u"OK"))
|
||||
ok.SetDefault()
|
||||
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"Close"))
|
||||
btnsizer = wx.BoxSizer()
|
||||
btnsizer.Add(ok, 0, wx.ALL, 5)
|
||||
btnsizer.Add(cancel, 0, wx.ALL, 5)
|
||||
sizer.Add(userSizer, 0, wx.ALL, 5)
|
||||
sizer.Add(aliasSizer, 0, wx.ALL, 5)
|
||||
sizer.Add(btnsizer, 0, wx.ALL, 5)
|
||||
panel.SetSizer(sizer)
|
||||
self.SetClientSize(sizer.CalcMin())
|
||||
|
||||
def get_user(self):
|
||||
return (self.cb.GetValue(), self.alias.GetValue())
|
||||
|
||||
class userAliasEditorDialog(wx.Dialog):
|
||||
def __init__(self, *args, **kwds):
|
||||
super(userAliasEditorDialog, self).__init__(parent=None)
|
||||
self.SetTitle(_("Edit user aliases"))
|
||||
main_sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
userListSizer = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, _("Users")), wx.VERTICAL)
|
||||
main_sizer.Add(userListSizer, 1, wx.EXPAND, 0)
|
||||
self.users = wx.ListBox(self, wx.ID_ANY, choices=[])
|
||||
self.users.Bind(wx.EVT_LISTBOX, self.on_selection_changes)
|
||||
userListSizer.Add(self.users, 0, 0, 0)
|
||||
actionsSizer = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, _("Actions")), wx.HORIZONTAL)
|
||||
main_sizer.Add(actionsSizer, 1, wx.EXPAND, 0)
|
||||
self.add = wx.Button(self, wx.ID_ANY, _("Add alias"))
|
||||
self.add.SetToolTip(_("Adds a new user alias"))
|
||||
actionsSizer.Add(self.add, 0, 0, 0)
|
||||
self.edit = wx.Button(self, wx.ID_ANY, _("Edit"))
|
||||
self.edit.SetToolTip(_("Edit the currently focused user Alias."))
|
||||
self.edit.Enable(False)
|
||||
actionsSizer.Add(self.edit, 0, 0, 0)
|
||||
self.remove = wx.Button(self, wx.ID_ANY, _("Remove"))
|
||||
self.remove.SetToolTip(_("Remove the currently focused user alias."))
|
||||
self.remove.Enable(False)
|
||||
actionsSizer.Add(self.remove, 0, 0, 0)
|
||||
btnSizer = wx.StdDialogButtonSizer()
|
||||
main_sizer.Add(btnSizer, 0, wx.ALIGN_RIGHT | wx.ALL, 4)
|
||||
self.button_CLOSE = wx.Button(self, wx.ID_CLOSE, "")
|
||||
btnSizer.AddButton(self.button_CLOSE)
|
||||
btnSizer.Realize()
|
||||
self.SetSizer(main_sizer)
|
||||
main_sizer.Fit(self)
|
||||
self.SetEscapeId(self.button_CLOSE.GetId())
|
||||
self.Layout()
|
||||
|
||||
def on_selection_changes(self, *args, **kwargs):
|
||||
selection = self.users.GetSelection()
|
||||
if selection == -1:
|
||||
self.enable_action_buttons(False)
|
||||
else:
|
||||
self.enable_action_buttons(True)
|
||||
|
||||
def get_selected_user(self):
|
||||
return self.users.GetStringSelection()
|
||||
|
||||
def remove_alias_dialog(self, *args, **kwargs):
|
||||
dlg = wx.MessageDialog(self, _("Are you sure you want to delete this user alias?"), _("Remove user alias"), wx.YES_NO)
|
||||
if dlg.ShowModal() == wx.ID_YES:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def enable_action_buttons(self, enabled=True):
|
||||
self.edit.Enable(enabled)
|
||||
self.remove.Enable(enabled)
|
||||
|
||||
def edit_alias_dialog(self, title):
|
||||
dlg = wx.TextEntryDialog(self, title, _("User alias"))
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
return dlg.GetValue()
|
@@ -46,5 +46,4 @@ class selectUserDialog(baseDialog.BaseWXDialog):
|
||||
self.SetClientSize(sizer.CalcMin())
|
||||
|
||||
def get_user(self):
|
||||
return self.cb.GetValue()
|
||||
|
||||
return self.cb.GetValue()
|
@@ -20,6 +20,7 @@ class mainFrame(wx.Frame):
|
||||
self.show_hide = app.Append(wx.ID_ANY, _(u"&Hide window"))
|
||||
self.menuitem_search = app.Append(wx.ID_ANY, _(u"&Search"))
|
||||
self.lists = app.Append(wx.ID_ANY, _(u"&Lists manager"))
|
||||
self.manageAliases = app.Append(wx.ID_ANY, _("Manage user aliases"))
|
||||
self.keystroke_editor = app.Append(wx.ID_ANY, _(u"&Edit keystrokes"))
|
||||
self.account_settings = app.Append(wx.ID_ANY, _(u"Account se&ttings"))
|
||||
self.prefs = app.Append(wx.ID_PREFERENCES, _(u"&Global settings"))
|
||||
@@ -43,6 +44,7 @@ class mainFrame(wx.Frame):
|
||||
self.follow = user.Append(wx.ID_ANY, _(u"&Actions..."))
|
||||
self.timeline = user.Append(wx.ID_ANY, _(u"&View timeline..."))
|
||||
self.dm = user.Append(wx.ID_ANY, _(u"Direct me&ssage"))
|
||||
self.addAlias = user.Append(wx.ID_ANY, _("Add a&lias"))
|
||||
self.addToList = user.Append(wx.ID_ANY, _(u"&Add to list"))
|
||||
self.removeFromList = user.Append(wx.ID_ANY, _(u"R&emove from list"))
|
||||
self.viewLists = user.Append(wx.ID_ANY, _(u"&View lists"))
|
||||
|
@@ -1,6 +0,0 @@
|
||||
{"current_version": "0.95",
|
||||
"description": "The first version for the new generation of TWBlue.",
|
||||
"date": "day_name_abr month day_numb, 2016",
|
||||
"downloads":
|
||||
{"Windows32": "http://twblue.es/pubs/twblue_ngen_0.80_x86.zip",
|
||||
"Windows64": "http://twblue.es/pubs/twblue_ngen_0.80_x64.zip"}}
|
@@ -1,4 +1,4 @@
|
||||
{"current_version": "8",
|
||||
{"current_version": "11",
|
||||
"description": "Snapshot version.",
|
||||
"date": "unknown",
|
||||
"downloads":
|
Submodule windows-dependencies updated: 3244b9e3fb...27a7c41983
Reference in New Issue
Block a user