From b9ce127bc1036b0759690c355f6d856b186041fc Mon Sep 17 00:00:00 2001 From: Bill Dengler Date: Fri, 16 Jun 2017 21:25:01 +0000 Subject: [PATCH] Initial (automated) port to Python3. --- src/application.py | 35 +- src/audio_services/services.py | 98 +- src/config_utils.py | 156 +-- src/controller/attach.py | 77 +- src/controller/buffersController.py | 7 +- src/controller/filters.py | 13 +- src/controller/listsController.py | 213 ++--- src/controller/mainController.py | 9 +- src/controller/messages.py | 9 +- src/controller/settings.py | 638 ++++++------- src/controller/trendingTopics.py | 89 +- src/controller/user.py | 251 ++--- src/controller/userActionsController.py | 1 + src/extra/AudioUploader/audioUploader.py | 4 +- src/extra/AudioUploader/transfer.py | 11 +- src/extra/AudioUploader/utils.py | 85 +- src/extra/SoundsTutorial/soundsTutorial.py | 1 + src/extra/SpellChecker/spellchecker.py | 2 + src/extra/autocompletionUsers/completion.py | 1 + src/extra/autocompletionUsers/manage.py | 1 + src/extra/autocompletionUsers/settings.py | 1 + src/extra/autocompletionUsers/storage.py | 103 +- src/extra/ocr/OCRSpace.py | 87 +- src/extra/translator/translator.py | 217 ++--- src/fixes/fix_urllib3_warnings.py | 50 +- src/issueReporter/issueReporter.py | 1 + src/keyboard_handler/linux.py | 7 +- src/keyboard_handler/main.py | 1 + src/keyboard_handler/osx.py | 1 + src/keyboard_handler/windows.py | 1 + src/keyboard_handler/wx_handler.py | 3 +- src/keys/__init__.py | 82 +- src/keystrokeEditor/keystrokeEditor.py | 1 + src/languageHandler.py | 424 +++++---- src/libloader/libloader.py | 113 +-- src/logger.py | 2 +- src/long_tweets/twishort.py | 5 +- src/multiplatform_widgets/widgets.py | 179 ++-- src/mysc/thread_utils.py | 74 +- src/notifier/linux.py | 49 +- src/notifier/windows.py | 13 +- src/paths.py | 171 ++-- src/platform_utils/autostart/windows.py | 21 +- src/platform_utils/blackhole.py | 33 +- src/platform_utils/paths.py | 229 ++--- .../shell_integration/windows.py | 22 +- src/pocket_utils/authorisationHandler.py | 30 +- src/sessionmanager/manager.py | 1 + src/sessionmanager/session.py | 17 +- src/sessionmanager/sessionManager.py | 2 + src/sessionmanager/session_exceptions.py | 13 +- src/sound.py | 354 +++---- src/twitter/authorisationHandler.py | 44 +- src/twitter/buffers/stream.py | 1 + src/twitter/compose.py | 13 +- src/twitter/twitter.py | 7 +- src/twitter/utils.py | 2 + src/update/utils.py | 85 +- src/update/wxUpdater.py | 5 +- src/url_shortener/shorteners/clckru.py | 6 +- src/url_shortener/shorteners/hkcim.py | 6 +- src/url_shortener/shorteners/isgd.py | 6 +- src/url_shortener/shorteners/onjme.py | 6 +- src/url_shortener/shorteners/tinyarrows.py | 6 +- src/url_shortener/shorteners/tinyurl.py | 6 +- src/url_shortener/shorteners/url_shortener.py | 7 +- src/url_shortener/shorteners/xedcc.py | 6 +- src/widgetUtils/gtkUtils.py | 288 +++--- src/wxUI/dialogs/configuration.py | 3 +- src/wxUI/dialogs/message.py | 893 +++++++++--------- src/wxUI/view.py | 397 ++++---- 71 files changed, 2958 insertions(+), 2837 deletions(-) diff --git a/src/application.py b/src/application.py index a6e31043..a4a183e8 100644 --- a/src/application.py +++ b/src/application.py @@ -1,18 +1,19 @@ -# -*- coding: utf-8 -*- -name = 'TWBlue' -snapshot = False -if snapshot == False: - version = "0.90" - update_url = 'http://twblue.es/updates/twblue_ngen.json' - mirror_update_url = 'https://raw.githubusercontent.com/manuelcortez/TWBlue/next-gen/updates/stable.json' -else: - version = "10.99" - update_url = 'http://twblue.es/updates/snapshots_ngen.json' - mirror_update_url = 'https://raw.githubusercontent.com/manuelcortez/TWBlue/next-gen/updates/snapshots.json' -authors = [u"Manuel Cortéz", u"José Manuel Delicado"] -authorEmail = "manuel@manuelcortez.net" -copyright = u"Copyright (C) 2013-2017, Manuel cortéz." -description = unicode(name+" is an app designed to use Twitter simply and efficiently while using minimal system resources. This app provides access to most Twitter features.") -translators = [u"Manuel Cortéz (English)", u"Mohammed Al Shara, Hatoun Felemban (Arabic)", u"Francisco Torres (Catalan)", u"Manuel cortéz (Spanish)", u"Sukil Etxenike Arizaleta (Basque)", u"Jani Kinnunen (finnish)", u"Rémy Ruiz (French)", u"Juan Buño (Galician)", u"Steffen Schultz (German)", u"Zvonimir Stanečić (Croatian)", u"Robert Osztolykan (Hungarian)", u"Christian Leo Mameli (Italian)", u"Riku (Japanese)", u"Paweł Masarczyk (Polish)", u"Odenilton Júnior Santos (Portuguese)", u"Florian Ionașcu, Nicușor Untilă (Romanian)", u"Natalia Hedlund, Valeria Kuznetsova (Russian)", u"Aleksandar Đurić (Serbian)", u"Burak Yüksek (Turkish)"] -url = u"http://twblue.es" +# -*- coding: utf-8 -*- +from builtins import str +name = 'TWBlue' +snapshot = False +if snapshot == False: + version = "0.90" + update_url = 'http://twblue.es/updates/twblue_ngen.json' + mirror_update_url = 'https://raw.githubusercontent.com/manuelcortez/TWBlue/next-gen/updates/stable.json' +else: + version = "10.99" + update_url = 'http://twblue.es/updates/snapshots_ngen.json' + mirror_update_url = 'https://raw.githubusercontent.com/manuelcortez/TWBlue/next-gen/updates/snapshots.json' +authors = [u"Manuel Cortéz", u"José Manuel Delicado"] +authorEmail = "manuel@manuelcortez.net" +copyright = u"Copyright (C) 2013-2017, Manuel cortéz." +description = str(name+" is an app designed to use Twitter simply and efficiently while using minimal system resources. This app provides access to most Twitter features.") +translators = [u"Manuel Cortéz (English)", u"Mohammed Al Shara, Hatoun Felemban (Arabic)", u"Francisco Torres (Catalan)", u"Manuel cortéz (Spanish)", u"Sukil Etxenike Arizaleta (Basque)", u"Jani Kinnunen (finnish)", u"Rémy Ruiz (French)", u"Juan Buño (Galician)", u"Steffen Schultz (German)", u"Zvonimir Stanečić (Croatian)", u"Robert Osztolykan (Hungarian)", u"Christian Leo Mameli (Italian)", u"Riku (Japanese)", u"Paweł Masarczyk (Polish)", u"Odenilton Júnior Santos (Portuguese)", u"Florian Ionașcu, Nicușor Untilă (Romanian)", u"Natalia Hedlund, Valeria Kuznetsova (Russian)", u"Aleksandar Đurić (Serbian)", u"Burak Yüksek (Turkish)"] +url = u"http://twblue.es" report_bugs_url = "http://twblue.es/bugs/api/soap/mantisconnect.php?wsdl" \ No newline at end of file diff --git a/src/audio_services/services.py b/src/audio_services/services.py index 1db7c9b7..5ebf0b5f 100644 --- a/src/audio_services/services.py +++ b/src/audio_services/services.py @@ -1,48 +1,50 @@ -from audio_services import matches_url -import json -import re -import urllib - -@matches_url('https://audioboom.com') -def convert_audioboom(url): - if "audioboom.com" not in url.lower(): - raise TypeError('%r is not a valid URL' % url) - audio_id = url.split('.com/')[-1] - return 'https://audioboom.com/%s.mp3' % audio_id - -@matches_url ('https://soundcloud.com/') -def convert_soundcloud (url): - client_id = "df8113ca95c157b6c9731f54b105b473" - permalink = urllib.urlopen ('http://api.soundcloud.com/resolve.json?client_id=%s&url=%s' %(client_id, url)) - if permalink.getcode () == 404: - permalink.close () - raise TypeError('%r is not a valid URL' % url) - else: - resolved_url = permalink.geturl () - permalink.close () - track_url = urllib.urlopen (resolved_url) - track_data = json.loads (track_url.read ()) - track_url.close () - if track_data ['streamable']: - return track_data ['stream_url'] + "?client_id=%s" %client_id - else: - raise TypeError('%r is not streamable' % url) - -@matches_url('http://twup.me') -def convert_twup(url): - result = re.match("^http://twup.me/(?P[A-Za-z0-9]+/?)$", url, re.I) - if not result or result.group("audio_id") is None: - raise TypeError('%r is not a valid URL' % url) - audio_id = result.group("audio_id") - return 'http://twup.me/%s' % audio_id - -#@matches_url('http://sndup.net') -#def convert_sndup(url): -# result = re.match("^http://sndup.net/(?P[a-z0-9]+/?)(|d|l|a)/?$", url, re.I) -# if not result or result.group("audio_id") is None: -# raise TypeError('%r is not a valid URL' % url) -# audio_id = result.group("audio_id") -# return 'http://sndup.net/%s/a' % audio_id - -def convert_generic_audio(url): - return url +from future import standard_library +standard_library.install_aliases() +from audio_services import matches_url +import json +import re +import urllib.request, urllib.parse, urllib.error + +@matches_url('https://audioboom.com') +def convert_audioboom(url): + if "audioboom.com" not in url.lower(): + raise TypeError('%r is not a valid URL' % url) + audio_id = url.split('.com/')[-1] + return 'https://audioboom.com/%s.mp3' % audio_id + +@matches_url ('https://soundcloud.com/') +def convert_soundcloud (url): + client_id = "df8113ca95c157b6c9731f54b105b473" + permalink = urllib.request.urlopen ('http://api.soundcloud.com/resolve.json?client_id=%s&url=%s' %(client_id, url)) + if permalink.getcode () == 404: + permalink.close () + raise TypeError('%r is not a valid URL' % url) + else: + resolved_url = permalink.geturl () + permalink.close () + track_url = urllib.request.urlopen (resolved_url) + track_data = json.loads (track_url.read ()) + track_url.close () + if track_data ['streamable']: + return track_data ['stream_url'] + "?client_id=%s" %client_id + else: + raise TypeError('%r is not streamable' % url) + +@matches_url('http://twup.me') +def convert_twup(url): + result = re.match("^http://twup.me/(?P[A-Za-z0-9]+/?)$", url, re.I) + if not result or result.group("audio_id") is None: + raise TypeError('%r is not a valid URL' % url) + audio_id = result.group("audio_id") + return 'http://twup.me/%s' % audio_id + +#@matches_url('http://sndup.net') +#def convert_sndup(url): +# result = re.match("^http://sndup.net/(?P[a-z0-9]+/?)(|d|l|a)/?$", url, re.I) +# if not result or result.group("audio_id") is None: +# raise TypeError('%r is not a valid URL' % url) +# audio_id = result.group("audio_id") +# return 'http://sndup.net/%s/a' % audio_id + +def convert_generic_audio(url): + return url diff --git a/src/config_utils.py b/src/config_utils.py index e6d926c5..aee936d7 100644 --- a/src/config_utils.py +++ b/src/config_utils.py @@ -1,79 +1,79 @@ -# -*- coding: utf-8 -*- -from configobj import ConfigObj, ParseError -from validate import Validator, ValidateError -import os -import string -from logging import getLogger -log = getLogger("config_utils") - -class ConfigLoadError(Exception): pass - -def load_config(config_path, configspec_path=None, copy=True, *args, **kwargs): - if os.path.exists(config_path): - clean_config(config_path) - spec = ConfigObj(configspec_path, encoding='UTF8', list_values=False, _inspec=True) - try: - config = ConfigObj(infile=config_path, configspec=spec, create_empty=True, encoding='UTF8', *args, **kwargs) - except ParseError: - raise ConfigLoadError("Unable to load %r" % config_path) - validator = Validator() - validated = config.validate(validator, preserve_errors=False, copy=copy) - if validated == True: - config.write() - return config - else: - log.exception("Error in config file: {0}".format(validated,)) - -def is_blank(arg): - "Check if a line is blank." - for c in arg: - if c not in string.whitespace: - return False - return True - -def get_keys(path): - "Gets the keys of a configobj config file." - res=[] - fin=open(path) - for line in fin: - if not is_blank(line): - res.append(line[0:line.find('=')].strip()) - fin.close() - return res - -def hist(keys): - "Generates a histogram of an iterable." - res={} - for k in keys: - res[k]=res.setdefault(k,0)+1 - return res - -def find_problems(hist): - "Takes a histogram and returns a list of items occurring more than once." - res=[] - for k,v in hist.items(): - if v>1: - res.append(k) - return res - -def clean_config(path): - "Cleans a config file. If duplicate values are found, delete all of them and just use the default." - orig=[] - cleaned=[] - fin=open(path) - for line in fin: - orig.append(line) - fin.close() - for p in find_problems(hist(get_keys(path))): - for o in orig: - o.strip() - if p not in o: - cleaned.append(o) - if len(cleaned) != 0: - cam=open(path,'w') - for c in cleaned: - cam.write(c) - cam.close() - return True - else: +# -*- coding: utf-8 -*- +from configobj import ConfigObj, ParseError +from validate import Validator, ValidateError +import os +import string +from logging import getLogger +log = getLogger("config_utils") + +class ConfigLoadError(Exception): pass + +def load_config(config_path, configspec_path=None, copy=True, *args, **kwargs): + if os.path.exists(config_path): + clean_config(config_path) + spec = ConfigObj(configspec_path, encoding='UTF8', list_values=False, _inspec=True) + try: + config = ConfigObj(infile=config_path, configspec=spec, create_empty=True, encoding='UTF8', *args, **kwargs) + except ParseError: + raise ConfigLoadError("Unable to load %r" % config_path) + validator = Validator() + validated = config.validate(validator, preserve_errors=False, copy=copy) + if validated == True: + config.write() + return config + else: + log.exception("Error in config file: {0}".format(validated,)) + +def is_blank(arg): + "Check if a line is blank." + for c in arg: + if c not in string.whitespace: + return False + return True + +def get_keys(path): + "Gets the keys of a configobj config file." + res=[] + fin=open(path) + for line in fin: + if not is_blank(line): + res.append(line[0:line.find('=')].strip()) + fin.close() + return res + +def hist(keys): + "Generates a histogram of an iterable." + res={} + for k in keys: + res[k]=res.setdefault(k,0)+1 + return res + +def find_problems(hist): + "Takes a histogram and returns a list of items occurring more than once." + res=[] + for k,v in list(hist.items()): + if v>1: + res.append(k) + return res + +def clean_config(path): + "Cleans a config file. If duplicate values are found, delete all of them and just use the default." + orig=[] + cleaned=[] + fin=open(path) + for line in fin: + orig.append(line) + fin.close() + for p in find_problems(hist(get_keys(path))): + for o in orig: + o.strip() + if p not in o: + cleaned.append(o) + if len(cleaned) != 0: + cam=open(path,'w') + for c in cleaned: + cam.write(c) + cam.close() + return True + else: return False \ No newline at end of file diff --git a/src/controller/attach.py b/src/controller/attach.py index c2af23bb..784fee62 100644 --- a/src/controller/attach.py +++ b/src/controller/attach.py @@ -1,38 +1,39 @@ -# -*- coding: utf-8 -*- -import os -import widgetUtils -import logging -from wxUI.dialogs import attach as gui -log = logging.getLogger("controller.attach") - -class attach(object): - def __init__(self): - self.attachments = list() - self.dialog = gui.attachDialog() - widgetUtils.connect_event(self.dialog.photo, widgetUtils.BUTTON_PRESSED, self.upload_image) - widgetUtils.connect_event(self.dialog.remove, widgetUtils.BUTTON_PRESSED, self.remove_attachment) - self.dialog.get_response() - log.debug("Attachments controller started.") - - def upload_image(self, *args, **kwargs): - image, description = self.dialog.get_image() - if image != None: - imageInfo = {"type": "photo", "file": image, "description": description} - log.debug("Image data to upload: %r" % (imageInfo,)) - self.attachments.append(imageInfo) - info = [_(u"Photo"), description] - self.dialog.attachments.insert_item(False, *info) - self.dialog.remove.Enable(True) - - def remove_attachment(self, *args, **kwargs): - current_item = self.dialog.attachments.get_selected() - log.debug("Removing item %d" % (current_item,)) - if current_item == -1: current_item = 0 - self.attachments.pop(current_item) - self.dialog.attachments.remove_item(current_item) - self.check_remove_status() - log.debug("Removed") - - def check_remove_status(self): - if len(self.attachments) == 0 and self.dialog.attachments.get_count() == 0: - self.dialog.remove.Enable(False) +# -*- coding: utf-8 -*- +from builtins import object +import os +import widgetUtils +import logging +from wxUI.dialogs import attach as gui +log = logging.getLogger("controller.attach") + +class attach(object): + def __init__(self): + self.attachments = list() + self.dialog = gui.attachDialog() + widgetUtils.connect_event(self.dialog.photo, widgetUtils.BUTTON_PRESSED, self.upload_image) + widgetUtils.connect_event(self.dialog.remove, widgetUtils.BUTTON_PRESSED, self.remove_attachment) + self.dialog.get_response() + log.debug("Attachments controller started.") + + def upload_image(self, *args, **kwargs): + image, description = self.dialog.get_image() + if image != None: + imageInfo = {"type": "photo", "file": image, "description": description} + log.debug("Image data to upload: %r" % (imageInfo,)) + self.attachments.append(imageInfo) + info = [_(u"Photo"), description] + self.dialog.attachments.insert_item(False, *info) + self.dialog.remove.Enable(True) + + def remove_attachment(self, *args, **kwargs): + current_item = self.dialog.attachments.get_selected() + log.debug("Removing item %d" % (current_item,)) + if current_item == -1: current_item = 0 + self.attachments.pop(current_item) + self.dialog.attachments.remove_item(current_item) + self.check_remove_status() + log.debug("Removed") + + def check_remove_status(self): + if len(self.attachments) == 0 and self.dialog.attachments.get_count() == 0: + self.dialog.remove.Enable(False) diff --git a/src/controller/buffersController.py b/src/controller/buffersController.py index 0b951e32..89e79bac 100644 --- a/src/controller/buffersController.py +++ b/src/controller/buffersController.py @@ -1,5 +1,8 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import +from builtins import str +from builtins import range +from builtins import object import time import platform if platform.system() == "Windows": @@ -389,7 +392,7 @@ class baseBufferController(bufferController): def remove_tweet(self, id): if type(self.session.db[self.name]) == dict: return - for i in xrange(0, len(self.session.db[self.name])): + for i in range(0, len(self.session.db[self.name])): if self.session.db[self.name][i]["id"] == id: self.session.db[self.name].pop(i) self.remove_item(i) @@ -606,7 +609,7 @@ class baseBufferController(bufferController): # fix this: original_date = arrow.get(self.session.db[self.name][self.buffer.list.get_selected()]["created_at"], "ddd MMM D H:m:s Z YYYY", locale="en") ts = original_date.humanize(locale=languageHandler.getLanguage()) - self.buffer.list.list.SetItem(self.buffer.list.get_selected(), 2, unicode(ts)) + self.buffer.list.list.SetItem(self.buffer.list.get_selected(), 2, str(ts)) if self.session.settings['sound']['indicate_audio'] and utils.is_audio(tweet): self.session.sound.play("audio.ogg") if self.session.settings['sound']['indicate_geo'] and utils.is_geocoded(tweet): diff --git a/src/controller/filters.py b/src/controller/filters.py index 28777e49..11515f50 100644 --- a/src/controller/filters.py +++ b/src/controller/filters.py @@ -1,7 +1,8 @@ -# -*- coding: utf-8 -*- -from wxUI.dialogs import filters - -class filterController(object): - def __init__(self): - self.dialog = filters.filterDialog() +# -*- coding: utf-8 -*- +from builtins import object +from wxUI.dialogs import filters + +class filterController(object): + def __init__(self): + self.dialog = filters.filterDialog() self.dialog.get_response() \ No newline at end of file diff --git a/src/controller/listsController.py b/src/controller/listsController.py index 84b19b08..a10f730b 100644 --- a/src/controller/listsController.py +++ b/src/controller/listsController.py @@ -1,106 +1,107 @@ -# -*- coding: utf-8 -*- -import widgetUtils -import output -from wxUI.dialogs import lists -from twython import TwythonError -from twitter import compose, utils -from pubsub import pub - -class listsController(object): - def __init__(self, session, user=None): - super(listsController, self).__init__() - self.session = session - if user == None: - self.dialog = lists.listViewer() - self.dialog.populate_list(self.get_all_lists()) - widgetUtils.connect_event(self.dialog.createBtn, widgetUtils.BUTTON_PRESSED, self.create_list) - widgetUtils.connect_event(self.dialog.editBtn, widgetUtils.BUTTON_PRESSED, self.edit_list) - widgetUtils.connect_event(self.dialog.deleteBtn, widgetUtils.BUTTON_PRESSED, self.remove_list) - widgetUtils.connect_event(self.dialog.view, widgetUtils.BUTTON_PRESSED, self.open_list_as_buffer) - widgetUtils.connect_event(self.dialog.deleteBtn, widgetUtils.BUTTON_PRESSED, self.remove_list) - else: - self.dialog = lists.userListViewer(user) - self.dialog.populate_list(self.get_user_lists(user)) - widgetUtils.connect_event(self.dialog.createBtn, widgetUtils.BUTTON_PRESSED, self.subscribe) - widgetUtils.connect_event(self.dialog.deleteBtn, widgetUtils.BUTTON_PRESSED, self.unsubscribe) - self.dialog.get_response() - - def get_all_lists(self): - return [compose.compose_list(item) for item in self.session.db["lists"]] - - def get_user_lists(self, user): - self.lists = self.session.twitter.twitter.show_lists(reverse=True, screen_name=user) - return [compose.compose_list(item) for item in self.lists] - - def create_list(self, *args, **kwargs): - dialog = lists.createListDialog() - if dialog.get_response() == widgetUtils.OK: - name = dialog.get("name") - description = dialog.get("description") - p = dialog.get("public") - if p == True: - mode = "public" - else: - mode = "private" - try: - new_list = self.session.twitter.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 TwythonError as e: - output.speak("error %s: %s" % (e.status_code, e.msg)) - dialog.destroy() - - def edit_list(self, *args, **kwargs): - if self.dialog.lista.get_count() == 0: return - list = self.session.db["lists"][self.dialog.get_item()] - dialog = lists.editListDialog(list) - if dialog.get_response() == widgetUtils.OK: - name = dialog.get("name") - description = dialog.get("description") - p = dialog.get("public") - if p == True: - mode = "public" - else: - mode = "private" - try: - self.session.twitter.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 TwythonError as e: - output.speak("error %s: %s" % (e.error_code, e.msg)) - dialog.destroy() - - def remove_list(self, *args, **kwargs): - if self.dialog.lista.get_count() == 0: return - list = self.session.db["lists"][self.dialog.get_item()]["id"] - if lists.remove_list() == widgetUtils.YES: - try: - self.session.twitter.twitter.delete_list(list_id=list) - self.session.db["lists"].pop(self.dialog.get_item()) - self.dialog.lista.remove_item(self.dialog.get_item()) - except TwythonError as e: - output.speak("error %s: %s" % (e.error_code, e.msg)) - - def open_list_as_buffer(self, *args, **kwargs): - if self.dialog.lista.get_count() == 0: return - list = self.session.db["lists"][self.dialog.get_item()] - pub.sendMessage("create-new-buffer", buffer="list", account=self.session.db["user_name"], create=list["name"]) - - def subscribe(self, *args, **kwargs): - if self.dialog.lista.get_count() == 0: return - list_id = self.lists[self.dialog.get_item()]["id"] - try: - list = self.session.twitter.twitter.subscribe_to_list(list_id=list_id) - item = utils.find_item(list["id"], self.session.db["lists"]) - self.session.db["lists"].append(list) - except TwythonError as e: - output.speak("error %s: %s" % (e.status_code, e.msg)) - - def unsubscribe(self, *args, **kwargs): - if self.dialog.lista.get_count() == 0: return - list_id = self.lists[self.dialog.get_item()]["id"] - try: - list = self.session.twitter.twitter.unsubscribe_from_list(list_id=list_id) - self.session.db["lists"].remove(list) - except TwythonError as e: - output.speak("error %s: %s" % (e.status_code, e.msg)) +# -*- coding: utf-8 -*- +from builtins import object +import widgetUtils +import output +from wxUI.dialogs import lists +from twython import TwythonError +from twitter import compose, utils +from pubsub import pub + +class listsController(object): + def __init__(self, session, user=None): + super(listsController, self).__init__() + self.session = session + if user == None: + self.dialog = lists.listViewer() + self.dialog.populate_list(self.get_all_lists()) + widgetUtils.connect_event(self.dialog.createBtn, widgetUtils.BUTTON_PRESSED, self.create_list) + widgetUtils.connect_event(self.dialog.editBtn, widgetUtils.BUTTON_PRESSED, self.edit_list) + widgetUtils.connect_event(self.dialog.deleteBtn, widgetUtils.BUTTON_PRESSED, self.remove_list) + widgetUtils.connect_event(self.dialog.view, widgetUtils.BUTTON_PRESSED, self.open_list_as_buffer) + widgetUtils.connect_event(self.dialog.deleteBtn, widgetUtils.BUTTON_PRESSED, self.remove_list) + else: + self.dialog = lists.userListViewer(user) + self.dialog.populate_list(self.get_user_lists(user)) + widgetUtils.connect_event(self.dialog.createBtn, widgetUtils.BUTTON_PRESSED, self.subscribe) + widgetUtils.connect_event(self.dialog.deleteBtn, widgetUtils.BUTTON_PRESSED, self.unsubscribe) + self.dialog.get_response() + + def get_all_lists(self): + return [compose.compose_list(item) for item in self.session.db["lists"]] + + def get_user_lists(self, user): + self.lists = self.session.twitter.twitter.show_lists(reverse=True, screen_name=user) + return [compose.compose_list(item) for item in self.lists] + + def create_list(self, *args, **kwargs): + dialog = lists.createListDialog() + if dialog.get_response() == widgetUtils.OK: + name = dialog.get("name") + description = dialog.get("description") + p = dialog.get("public") + if p == True: + mode = "public" + else: + mode = "private" + try: + new_list = self.session.twitter.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 TwythonError as e: + output.speak("error %s: %s" % (e.status_code, e.msg)) + dialog.destroy() + + def edit_list(self, *args, **kwargs): + if self.dialog.lista.get_count() == 0: return + list = self.session.db["lists"][self.dialog.get_item()] + dialog = lists.editListDialog(list) + if dialog.get_response() == widgetUtils.OK: + name = dialog.get("name") + description = dialog.get("description") + p = dialog.get("public") + if p == True: + mode = "public" + else: + mode = "private" + try: + self.session.twitter.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 TwythonError as e: + output.speak("error %s: %s" % (e.error_code, e.msg)) + dialog.destroy() + + def remove_list(self, *args, **kwargs): + if self.dialog.lista.get_count() == 0: return + list = self.session.db["lists"][self.dialog.get_item()]["id"] + if lists.remove_list() == widgetUtils.YES: + try: + self.session.twitter.twitter.delete_list(list_id=list) + self.session.db["lists"].pop(self.dialog.get_item()) + self.dialog.lista.remove_item(self.dialog.get_item()) + except TwythonError as e: + output.speak("error %s: %s" % (e.error_code, e.msg)) + + def open_list_as_buffer(self, *args, **kwargs): + if self.dialog.lista.get_count() == 0: return + list = self.session.db["lists"][self.dialog.get_item()] + pub.sendMessage("create-new-buffer", buffer="list", account=self.session.db["user_name"], create=list["name"]) + + def subscribe(self, *args, **kwargs): + if self.dialog.lista.get_count() == 0: return + list_id = self.lists[self.dialog.get_item()]["id"] + try: + list = self.session.twitter.twitter.subscribe_to_list(list_id=list_id) + item = utils.find_item(list["id"], self.session.db["lists"]) + self.session.db["lists"].append(list) + except TwythonError as e: + output.speak("error %s: %s" % (e.status_code, e.msg)) + + def unsubscribe(self, *args, **kwargs): + if self.dialog.lista.get_count() == 0: return + list_id = self.lists[self.dialog.get_item()]["id"] + try: + list = self.session.twitter.twitter.unsubscribe_from_list(list_id=list_id) + self.session.db["lists"].remove(list) + except TwythonError as e: + output.speak("error %s: %s" % (e.status_code, e.msg)) diff --git a/src/controller/mainController.py b/src/controller/mainController.py index 80b04015..6837fc39 100644 --- a/src/controller/mainController.py +++ b/src/controller/mainController.py @@ -1,5 +1,8 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import +from builtins import str +from builtins import range +from builtins import object import platform system = platform.system() import application @@ -264,7 +267,7 @@ class Controller(object): self.start_buffers(session_.sessions[i]) self.set_buffer_positions(session_.sessions[i]) if config.app["app-settings"]["play_ready_sound"] == True: - session_.sessions[session_.sessions.keys()[0]].sound.play("ready.ogg") + session_.sessions[list(session_.sessions.keys())[0]].sound.play("ready.ogg") if config.app["app-settings"]["speak_ready_msg"] == True: output.speak(_(u"Ready")) self.started = True @@ -478,7 +481,7 @@ class Controller(object): output.speak(_(u"Empty buffer."), True) return start = page.buffer.list.get_selected() - for i in xrange(start,count): + for i in range(start,count): page.buffer.list.select_item(i) if string.lower() in page.get_message().lower(): return output.speak(page.get_message(), True) @@ -1595,7 +1598,7 @@ class Controller(object): output.speak(_(u"This tweet doesn't contain images")) return if len(tweet["entities"]["media"]) > 1: - image_list = [_(u"Picture {0}").format(i,) for i in xrange(0, len(tweet["entities"]["media"]))] + image_list = [_(u"Picture {0}").format(i,) for i in range(0, len(tweet["entities"]["media"]))] dialog = dialogs.urlList.urlList(title=_(u"Select the picture")) if dialog.get_response() == widgetUtils.OK: img = tweet["entities"]["media"][dialog.get_item()] diff --git a/src/controller/messages.py b/src/controller/messages.py index 48c464b5..02740c9e 100644 --- a/src/controller/messages.py +++ b/src/controller/messages.py @@ -1,5 +1,8 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import +from builtins import str +from builtins import range +from builtins import object import re import platform from . import attach @@ -172,14 +175,14 @@ class reply(tweet): def get_ids(self): excluded_ids = "" - for i in xrange(0, len(self.message.checkboxes)): + for i in range(0, len(self.message.checkboxes)): if self.message.checkboxes[i].GetValue() == False: excluded_ids = excluded_ids + "{0},".format(self.ids[i],) return excluded_ids def get_people(self): people = "" - for i in xrange(0, len(self.message.checkboxes)): + for i in range(0, len(self.message.checkboxes)): if self.message.checkboxes[i].GetValue() == True: people = people + "{0} ".format(self.message.checkboxes[i].GetLabel(),) return people @@ -203,7 +206,7 @@ class viewTweet(basicTweet): if is_tweet == True: image_description = [] text = "" - for i in xrange(0, len(tweetList)): + for i in range(0, len(tweetList)): # tweets with message keys are longer tweets, the message value is the full messaje taken from twishort. if "message" in tweetList[i] and tweetList[i]["is_quote_status"] == False: value = "message" diff --git a/src/controller/settings.py b/src/controller/settings.py index f98c5353..71af759a 100644 --- a/src/controller/settings.py +++ b/src/controller/settings.py @@ -1,317 +1,321 @@ -# -*- coding: utf-8 -*- -import os -import webbrowser -import sound_lib -import paths -import widgetUtils -import config -import languageHandler -import output -import application -from wxUI.dialogs import configuration -from wxUI import commonMessageDialogs -from extra.autocompletionUsers import settings -from extra.ocr import OCRSpace -from pubsub import pub -import logging -import config_utils -log = logging.getLogger("Settings") -import keys -from collections import OrderedDict -from platform_utils.autostart import windows as autostart_windows - -class globalSettingsController(object): - def __init__(self): - super(globalSettingsController, self).__init__() - self.dialog = configuration.configurationDialog() - self.create_config() - self.needs_restart = False - self.is_started = True - - def make_kmmap(self): - res={} - for i in os.listdir(paths.app_path('keymaps')): - if ".keymap" not in i: - continue - try: - res[i[:-7]] =i - except: - log.exception("Exception while loading keymap " + i) - return res - - def create_config(self): - self.kmmap=self.make_kmmap() - self.langs = languageHandler.getAvailableLanguages() - langs = [] - [langs.append(i[1]) for i in self.langs] - self.codes = [] - [self.codes.append(i[0]) for i in self.langs] - id = self.codes.index(config.app["app-settings"]["language"]) - self.kmfriendlies=[] - self.kmnames=[] - for k,v in self.kmmap.items(): - self.kmfriendlies.append(k) - self.kmnames.append(v) - self.kmid=self.kmnames.index(config.app['app-settings']['load_keymap']) - self.dialog.create_general(langs,self.kmfriendlies) - self.dialog.general.language.SetSelection(id) - self.dialog.general.km.SetSelection(self.kmid) - if paths.mode == "installed": - self.dialog.set_value("general", "autostart", config.app["app-settings"]["autostart"]) - else: - self.dialog.general.autostart.Enable(False) - self.dialog.set_value("general", "ask_at_exit", config.app["app-settings"]["ask_at_exit"]) - self.dialog.set_value("general", "play_ready_sound", config.app["app-settings"]["play_ready_sound"]) - self.dialog.set_value("general", "speak_ready_msg", config.app["app-settings"]["speak_ready_msg"]) - self.dialog.set_value("general", "handle_longtweets", config.app["app-settings"]["handle_longtweets"]) - self.dialog.set_value("general", "use_invisible_shorcuts", config.app["app-settings"]["use_invisible_keyboard_shorcuts"]) - self.dialog.set_value("general", "disable_sapi5", config.app["app-settings"]["voice_enabled"]) - self.dialog.set_value("general", "hide_gui", config.app["app-settings"]["hide_gui"]) - self.dialog.set_value("general", "check_for_updates", config.app["app-settings"]["check_for_updates"]) - proxyTypes=config.proxyTypes - self.dialog.create_proxy([_(u"Direct connection")]+proxyTypes) - if config.app["proxy"]["type"] not in proxyTypes: - self.dialog.proxy.type.SetSelection(0) - else: - self.dialog.proxy.type.SetSelection(proxyTypes.index(config.app["proxy"]["type"])+1) - self.dialog.set_value("proxy", "server", config.app["proxy"]["server"]) - self.dialog.set_value("proxy", "port", config.app["proxy"]["port"]) - self.dialog.set_value("proxy", "user", config.app["proxy"]["user"]) - self.dialog.set_value("proxy", "password", config.app["proxy"]["password"]) - - self.dialog.realize() - self.response = self.dialog.get_response() - - def save_configuration(self): - if self.codes[self.dialog.general.language.GetSelection()] != config.app["app-settings"]["language"]: - config.app["app-settings"]["language"] = self.codes[self.dialog.general.language.GetSelection()] - languageHandler.setLanguage(config.app["app-settings"]["language"]) - self.needs_restart = True - if self.kmnames[self.dialog.general.km.GetSelection()] != config.app["app-settings"]["load_keymap"]: - config.app["app-settings"]["load_keymap"] =self.kmnames[self.dialog.general.km.GetSelection()] - kmFile = open(paths.config_path("keymap.keymap"), "w") - kmFile.close() - self.needs_restart = True - - if config.app["app-settings"]["autostart"] != self.dialog.get_value("general", "autostart") and paths.mode == "installed": - config.app["app-settings"]["autostart"] = self.dialog.get_value("general", "autostart") - autostart_windows.setAutoStart(application.name, enable=self.dialog.get_value("general", "autostart")) - if config.app["app-settings"]["use_invisible_keyboard_shorcuts"] != self.dialog.get_value("general", "use_invisible_shorcuts"): - config.app["app-settings"]["use_invisible_keyboard_shorcuts"] = self.dialog.get_value("general", "use_invisible_shorcuts") - pub.sendMessage("invisible-shorcuts-changed", registered=self.dialog.get_value("general", "use_invisible_shorcuts")) - config.app["app-settings"]["voice_enabled"] = self.dialog.get_value("general", "disable_sapi5") - config.app["app-settings"]["hide_gui"] = self.dialog.get_value("general", "hide_gui") - config.app["app-settings"]["ask_at_exit"] = self.dialog.get_value("general", "ask_at_exit") - config.app["app-settings"]["handle_longtweets"] = self.dialog.get_value("general", "handle_longtweets") - config.app["app-settings"]["play_ready_sound"] = self.dialog.get_value("general", "play_ready_sound") - config.app["app-settings"]["speak_ready_msg"] = self.dialog.get_value("general", "speak_ready_msg") - config.app["app-settings"]["check_for_updates"] = self.dialog.get_value("general", "check_for_updates") - if config.app["proxy"]["type"]!=self.dialog.get_value("proxy", "type") or config.app["proxy"]["server"] != self.dialog.get_value("proxy", "server") or config.app["proxy"]["port"] != self.dialog.get_value("proxy", "port") or config.app["proxy"]["user"] != self.dialog.get_value("proxy", "user") or config.app["proxy"]["password"] != self.dialog.get_value("proxy", "password"): - if self.is_started == True: - self.needs_restart = True - config.app["proxy"]["type"]=self.dialog.get_value("proxy", "type") - config.app["proxy"]["server"] = self.dialog.get_value("proxy", "server") - config.app["proxy"]["port"] = self.dialog.get_value("proxy", "port") - config.app["proxy"]["user"] = self.dialog.get_value("proxy", "user") - config.app["proxy"]["password"] = self.dialog.get_value("proxy", "password") - config.app.write() - -class accountSettingsController(globalSettingsController): - def __init__(self, buffer, window): - self.user = buffer.session.db["user_name"] - self.buffer = buffer - self.window = window - self.config = buffer.session.settings - super(accountSettingsController, self).__init__() - - def create_config(self): - self.dialog.create_general_account() - widgetUtils.connect_event(self.dialog.general.au, widgetUtils.BUTTON_PRESSED, self.manage_autocomplete) - self.dialog.set_value("general", "relative_time", self.config["general"]["relative_times"]) - self.dialog.set_value("general", "show_screen_names", self.config["general"]["show_screen_names"]) - self.dialog.set_value("general", "apiCalls", self.config["general"]["max_api_calls"]) - self.dialog.set_value("general", "itemsPerApiCall", self.config["general"]["max_tweets_per_call"]) - self.dialog.set_value("general", "reverse_timelines", self.config["general"]["reverse_timelines"]) - rt = self.config["general"]["retweet_mode"] - if rt == "ask": - self.dialog.set_value("general", "retweet_mode", _(u"Ask")) - elif rt == "direct": - self.dialog.set_value("general", "retweet_mode", _(u"Retweet without comments")) - else: - self.dialog.set_value("general", "retweet_mode", _(u"Retweet with comments")) - self.dialog.set_value("general", "persist_size", str(self.config["general"]["persist_size"])) - self.dialog.create_other_buffers() - buffer_values = self.get_buffers_list() - self.dialog.buffers.insert_buffers(buffer_values) - self.dialog.buffers.connect_hook_func(self.toggle_buffer_active) - widgetUtils.connect_event(self.dialog.buffers.toggle_state, widgetUtils.BUTTON_PRESSED, self.toggle_state) - widgetUtils.connect_event(self.dialog.buffers.up, widgetUtils.BUTTON_PRESSED, self.dialog.buffers.move_up) - widgetUtils.connect_event(self.dialog.buffers.down, widgetUtils.BUTTON_PRESSED, self.dialog.buffers.move_down) - - - self.dialog.create_ignored_clients(self.config["twitter"]["ignored_clients"]) - widgetUtils.connect_event(self.dialog.ignored_clients.add, widgetUtils.BUTTON_PRESSED, self.add_ignored_client) - widgetUtils.connect_event(self.dialog.ignored_clients.remove, widgetUtils.BUTTON_PRESSED, self.remove_ignored_client) - self.input_devices = sound_lib.input.Input.get_device_names() - self.output_devices = sound_lib.output.Output.get_device_names() - self.soundpacks = [] - [self.soundpacks.append(i) for i in os.listdir(paths.sound_path()) if os.path.isdir(paths.sound_path(i)) == True ] - self.dialog.create_sound(self.input_devices, self.output_devices, self.soundpacks) - self.dialog.set_value("sound", "volumeCtrl", self.config["sound"]["volume"]*100) - self.dialog.set_value("sound", "input", self.config["sound"]["input_device"]) - self.dialog.set_value("sound", "output", self.config["sound"]["output_device"]) - self.dialog.set_value("sound", "session_mute", self.config["sound"]["session_mute"]) - self.dialog.set_value("sound", "soundpack", self.config["sound"]["current_soundpack"]) - self.dialog.set_value("sound", "indicate_audio", self.config["sound"]["indicate_audio"]) - self.dialog.set_value("sound", "indicate_geo", self.config["sound"]["indicate_geo"]) - self.dialog.set_value("sound", "indicate_img", self.config["sound"]["indicate_img"]) - self.dialog.create_extras(OCRSpace.translatable_langs) - self.dialog.set_value("extras", "sndup_apiKey", self.config["sound"]["sndup_api_key"]) - language_index = OCRSpace.OcrLangs.index(self.config["mysc"]["ocr_language"]) - self.dialog.extras.ocr_lang.SetSelection(language_index) - self.dialog.realize() - self.dialog.set_title(_(u"Account settings for %s") % (self.user,)) - self.response = self.dialog.get_response() - - def save_configuration(self): - if self.config["general"]["relative_times"] != self.dialog.get_value("general", "relative_time"): - self.needs_restart = True - self.config["general"]["relative_times"] = self.dialog.get_value("general", "relative_time") - self.config["general"]["show_screen_names"] = self.dialog.get_value("general", "show_screen_names") - self.config["general"]["max_api_calls"] = self.dialog.get_value("general", "apiCalls") - self.config["general"]["max_tweets_per_call"] = self.dialog.get_value("general", "itemsPerApiCall") - if self.config["general"]["persist_size"] != self.dialog.get_value("general", "persist_size"): - if self.dialog.get_value("general", "persist_size") == '': - self.config["general"]["persist_size"] =-1 - else: - try: - self.config["general"]["persist_size"] = int(self.dialog.get_value("general", "persist_size")) - except ValueError: - output.speak("Invalid cache size, setting to default.",True) - self.config["general"]["persist_size"] =1764 - - if self.config["general"]["reverse_timelines"] != self.dialog.get_value("general", "reverse_timelines"): - self.needs_restart = True - self.config["general"]["reverse_timelines"] = self.dialog.get_value("general", "reverse_timelines") - rt = self.dialog.get_value("general", "retweet_mode") - if rt == _(u"Ask"): - self.config["general"]["retweet_mode"] = "ask" - elif rt == _(u"Retweet without comments"): - self.config["general"]["retweet_mode"] = "direct" - else: - self.config["general"]["retweet_mode"] = "comment" - buffers_list = self.dialog.buffers.get_list() - if set(self.config["general"]["buffer_order"]) != set(buffers_list) or buffers_list != self.config["general"]["buffer_order"]: - self.needs_restart = True - self.config["general"]["buffer_order"] = buffers_list - self.config["mysc"]["ocr_language"] = OCRSpace.OcrLangs[self.dialog.extras.ocr_lang.GetSelection()] -# if self.config["other_buffers"]["show_followers"] != self.dialog.get_value("buffers", "followers"): -# self.config["other_buffers"]["show_followers"] = self.dialog.get_value("buffers", "followers") -# pub.sendMessage("create-new-buffer", buffer="followers", account=self.user, create=self.config["other_buffers"]["show_followers"]) -# if self.config["other_buffers"]["show_friends"] != self.dialog.get_value("buffers", "friends"): -# self.config["other_buffers"]["show_friends"] = self.dialog.get_value("buffers", "friends") -# pub.sendMessage("create-new-buffer", buffer="friends", account=self.user, create=self.config["other_buffers"]["show_friends"]) -# if self.config["other_buffers"]["show_favourites"] != self.dialog.get_value("buffers", "favs"): -# self.config["other_buffers"]["show_favourites"] = self.dialog.get_value("buffers", "favs") -# pub.sendMessage("create-new-buffer", buffer="favourites", account=self.user, create=self.config["other_buffers"]["show_favourites"]) -# if self.config["other_buffers"]["show_blocks"] != self.dialog.get_value("buffers", "blocks"): -# self.config["other_buffers"]["show_blocks"] = self.dialog.get_value("buffers", "blocks") -# pub.sendMessage("create-new-buffer", buffer="blocked", account=self.user, create=self.config["other_buffers"]["show_blocks"]) -# if self.config["other_buffers"]["show_muted_users"] != self.dialog.get_value("buffers", "mutes"): -# self.config["other_buffers"]["show_muted_users"] = self.dialog.get_value("buffers", "mutes") -# pub.sendMessage("create-new-buffer", buffer="muted", account=self.user, create=self.config["other_buffers"]["show_muted_users"]) -# if self.config["other_buffers"]["show_events"] != self.dialog.get_value("buffers", "events"): -# self.config["other_buffers"]["show_events"] = self.dialog.get_value("buffers", "events") -# pub.sendMessage("create-new-buffer", buffer="events", account=self.user, create=self.config["other_buffers"]["show_events"]) - if self.config["sound"]["input_device"] != self.dialog.sound.get("input"): - self.config["sound"]["input_device"] = self.dialog.sound.get("input") - try: - self.buffer.session.sound.input.set_device(self.buffer.session.sound.input.find_device_by_name(self.config["sound"]["input_device"])) - except: - self.config["sound"]["input_device"] = "default" - if self.config["sound"]["output_device"] != self.dialog.sound.get("output"): - self.config["sound"]["output_device"] = self.dialog.sound.get("output") - try: - self.buffer.session.sound.output.set_device(self.buffer.session.sound.output.find_device_by_name(self.config["sound"]["output_device"])) - except: - self.config["sound"]["output_device"] = "default" - self.config["sound"]["volume"] = self.dialog.get_value("sound", "volumeCtrl")/100.0 - self.config["sound"]["session_mute"] = self.dialog.get_value("sound", "session_mute") - self.config["sound"]["current_soundpack"] = self.dialog.sound.get("soundpack") - self.config["sound"]["indicate_audio"] = self.dialog.get_value("sound", "indicate_audio") - self.config["sound"]["indicate_geo"] = self.dialog.get_value("sound", "indicate_geo") - self.config["sound"]["indicate_img"] = self.dialog.get_value("sound", "indicate_img") - self.config["sound"]["sndup_api_key"] = self.dialog.get_value("extras", "sndup_apiKey") - self.buffer.session.sound.config = self.config["sound"] - self.buffer.session.sound.check_soundpack() - self.config.write() - - def toggle_state(self,*args,**kwargs): - return self.dialog.buffers.change_selected_item() - - def manage_autocomplete(self, *args, **kwargs): - configuration = settings.autocompletionSettings(self.buffer.session.settings, self.buffer, self.window) - - def add_ignored_client(self, *args, **kwargs): - client = commonMessageDialogs.get_ignored_client() - if client == None: return - if client not in self.config["twitter"]["ignored_clients"]: - self.config["twitter"]["ignored_clients"].append(client) - self.dialog.ignored_clients.append(client) - - def remove_ignored_client(self, *args, **kwargs): - if self.dialog.ignored_clients.get_clients() == 0: return - id = self.dialog.ignored_clients.get_client_id() - self.config["twitter"]["ignored_clients"].pop(id) - self.dialog.ignored_clients.remove_(id) - - def get_buffers_list(self): - all_buffers=OrderedDict() - all_buffers['home']=_(u"Home") - all_buffers['mentions']=_(u"Mentions") - all_buffers['dm']=_(u"Direct Messages") - all_buffers['sent_dm']=_(u"Sent direct messages") - all_buffers['sent_tweets']=_(u"Sent tweets") - all_buffers['favorites']=_(u"Likes") - all_buffers['followers']=_(u"Followers") - all_buffers['friends']=_(u"Friends") - all_buffers['blocks']=_(u"Blocked users") - all_buffers['muted']=_(u"Muted users") - all_buffers['events']=_(u"Events") - list_buffers = [] - hidden_buffers=[] - for i in all_buffers.keys(): - if i in self.config["general"]["buffer_order"]: - list_buffers.append((i, all_buffers[i], True)) - else: - hidden_buffers.append((i, all_buffers[i], False)) - list_buffers.extend(hidden_buffers) - return list_buffers - - def toggle_buffer_active(self, ev): - change = self.dialog.buffers.get_event(ev) - if change == True: - self.dialog.buffers.change_selected_item() - -# def manage_pocket(self, *args, **kwargs): -# if self.dialog.services.get_pocket_status() == _(u"Connect your Pocket account"): -# self.connect_pocket() -# else: -# self.disconnect_pocket() - -# def connect_pocket(self): -# dlg = self.dialog.services.show_pocket_dialog() -# if dlg == widgetUtils.YES: -# request_token = pocket.Pocket.get_request_token(consumer_key=keys.keyring.get("pocket_consumer_key"), redirect_uri="http://127.0.0.1:8080") -# auth_url = pocket.Pocket.get_auth_url(code=request_token, redirect_uri="http://127.0.0.1:8080") -# webbrowser.open_new_tab(auth_url) -# httpd = BaseHTTPServer.HTTPServer(('127.0.0.1', 8080), authorisationHandler.handler) -# while authorisationHandler.logged == False: -# httpd.handle_request() -# user_credentials = pocket.Pocket.get_credentials(consumer_key=keys.keyring.get("pocket_consumer_key"), code=request_token) -# self.dialog.services.set_pocket(True) -# self.config["services"]["pocket_access_token"] = user_credentials["access_token"] - - def disconnect_dropbox(self): - self.config["services"]["pocket_access_token"] = "" - self.dialog.services.set_pocket(False) +# -*- coding: utf-8 -*- +from __future__ import division +from builtins import str +from past.utils import old_div +from builtins import object +import os +import webbrowser +import sound_lib +import paths +import widgetUtils +import config +import languageHandler +import output +import application +from wxUI.dialogs import configuration +from wxUI import commonMessageDialogs +from extra.autocompletionUsers import settings +from extra.ocr import OCRSpace +from pubsub import pub +import logging +import config_utils +log = logging.getLogger("Settings") +import keys +from collections import OrderedDict +from platform_utils.autostart import windows as autostart_windows + +class globalSettingsController(object): + def __init__(self): + super(globalSettingsController, self).__init__() + self.dialog = configuration.configurationDialog() + self.create_config() + self.needs_restart = False + self.is_started = True + + def make_kmmap(self): + res={} + for i in os.listdir(paths.app_path('keymaps')): + if ".keymap" not in i: + continue + try: + res[i[:-7]] =i + except: + log.exception("Exception while loading keymap " + i) + return res + + def create_config(self): + self.kmmap=self.make_kmmap() + self.langs = languageHandler.getAvailableLanguages() + langs = [] + [langs.append(i[1]) for i in self.langs] + self.codes = [] + [self.codes.append(i[0]) for i in self.langs] + id = self.codes.index(config.app["app-settings"]["language"]) + self.kmfriendlies=[] + self.kmnames=[] + for k,v in list(self.kmmap.items()): + self.kmfriendlies.append(k) + self.kmnames.append(v) + self.kmid=self.kmnames.index(config.app['app-settings']['load_keymap']) + self.dialog.create_general(langs,self.kmfriendlies) + self.dialog.general.language.SetSelection(id) + self.dialog.general.km.SetSelection(self.kmid) + if paths.mode == "installed": + self.dialog.set_value("general", "autostart", config.app["app-settings"]["autostart"]) + else: + self.dialog.general.autostart.Enable(False) + self.dialog.set_value("general", "ask_at_exit", config.app["app-settings"]["ask_at_exit"]) + self.dialog.set_value("general", "play_ready_sound", config.app["app-settings"]["play_ready_sound"]) + self.dialog.set_value("general", "speak_ready_msg", config.app["app-settings"]["speak_ready_msg"]) + self.dialog.set_value("general", "handle_longtweets", config.app["app-settings"]["handle_longtweets"]) + self.dialog.set_value("general", "use_invisible_shorcuts", config.app["app-settings"]["use_invisible_keyboard_shorcuts"]) + self.dialog.set_value("general", "disable_sapi5", config.app["app-settings"]["voice_enabled"]) + self.dialog.set_value("general", "hide_gui", config.app["app-settings"]["hide_gui"]) + self.dialog.set_value("general", "check_for_updates", config.app["app-settings"]["check_for_updates"]) + proxyTypes=config.proxyTypes + self.dialog.create_proxy([_(u"Direct connection")]+proxyTypes) + if config.app["proxy"]["type"] not in proxyTypes: + self.dialog.proxy.type.SetSelection(0) + else: + self.dialog.proxy.type.SetSelection(proxyTypes.index(config.app["proxy"]["type"])+1) + self.dialog.set_value("proxy", "server", config.app["proxy"]["server"]) + self.dialog.set_value("proxy", "port", config.app["proxy"]["port"]) + self.dialog.set_value("proxy", "user", config.app["proxy"]["user"]) + self.dialog.set_value("proxy", "password", config.app["proxy"]["password"]) + + self.dialog.realize() + self.response = self.dialog.get_response() + + def save_configuration(self): + if self.codes[self.dialog.general.language.GetSelection()] != config.app["app-settings"]["language"]: + config.app["app-settings"]["language"] = self.codes[self.dialog.general.language.GetSelection()] + languageHandler.setLanguage(config.app["app-settings"]["language"]) + self.needs_restart = True + if self.kmnames[self.dialog.general.km.GetSelection()] != config.app["app-settings"]["load_keymap"]: + config.app["app-settings"]["load_keymap"] =self.kmnames[self.dialog.general.km.GetSelection()] + kmFile = open(paths.config_path("keymap.keymap"), "w") + kmFile.close() + self.needs_restart = True + + if config.app["app-settings"]["autostart"] != self.dialog.get_value("general", "autostart") and paths.mode == "installed": + config.app["app-settings"]["autostart"] = self.dialog.get_value("general", "autostart") + autostart_windows.setAutoStart(application.name, enable=self.dialog.get_value("general", "autostart")) + if config.app["app-settings"]["use_invisible_keyboard_shorcuts"] != self.dialog.get_value("general", "use_invisible_shorcuts"): + config.app["app-settings"]["use_invisible_keyboard_shorcuts"] = self.dialog.get_value("general", "use_invisible_shorcuts") + pub.sendMessage("invisible-shorcuts-changed", registered=self.dialog.get_value("general", "use_invisible_shorcuts")) + config.app["app-settings"]["voice_enabled"] = self.dialog.get_value("general", "disable_sapi5") + config.app["app-settings"]["hide_gui"] = self.dialog.get_value("general", "hide_gui") + config.app["app-settings"]["ask_at_exit"] = self.dialog.get_value("general", "ask_at_exit") + config.app["app-settings"]["handle_longtweets"] = self.dialog.get_value("general", "handle_longtweets") + config.app["app-settings"]["play_ready_sound"] = self.dialog.get_value("general", "play_ready_sound") + config.app["app-settings"]["speak_ready_msg"] = self.dialog.get_value("general", "speak_ready_msg") + config.app["app-settings"]["check_for_updates"] = self.dialog.get_value("general", "check_for_updates") + if config.app["proxy"]["type"]!=self.dialog.get_value("proxy", "type") or config.app["proxy"]["server"] != self.dialog.get_value("proxy", "server") or config.app["proxy"]["port"] != self.dialog.get_value("proxy", "port") or config.app["proxy"]["user"] != self.dialog.get_value("proxy", "user") or config.app["proxy"]["password"] != self.dialog.get_value("proxy", "password"): + if self.is_started == True: + self.needs_restart = True + config.app["proxy"]["type"]=self.dialog.get_value("proxy", "type") + config.app["proxy"]["server"] = self.dialog.get_value("proxy", "server") + config.app["proxy"]["port"] = self.dialog.get_value("proxy", "port") + config.app["proxy"]["user"] = self.dialog.get_value("proxy", "user") + config.app["proxy"]["password"] = self.dialog.get_value("proxy", "password") + config.app.write() + +class accountSettingsController(globalSettingsController): + def __init__(self, buffer, window): + self.user = buffer.session.db["user_name"] + self.buffer = buffer + self.window = window + self.config = buffer.session.settings + super(accountSettingsController, self).__init__() + + def create_config(self): + self.dialog.create_general_account() + widgetUtils.connect_event(self.dialog.general.au, widgetUtils.BUTTON_PRESSED, self.manage_autocomplete) + self.dialog.set_value("general", "relative_time", self.config["general"]["relative_times"]) + self.dialog.set_value("general", "show_screen_names", self.config["general"]["show_screen_names"]) + self.dialog.set_value("general", "apiCalls", self.config["general"]["max_api_calls"]) + self.dialog.set_value("general", "itemsPerApiCall", self.config["general"]["max_tweets_per_call"]) + self.dialog.set_value("general", "reverse_timelines", self.config["general"]["reverse_timelines"]) + rt = self.config["general"]["retweet_mode"] + if rt == "ask": + self.dialog.set_value("general", "retweet_mode", _(u"Ask")) + elif rt == "direct": + self.dialog.set_value("general", "retweet_mode", _(u"Retweet without comments")) + else: + self.dialog.set_value("general", "retweet_mode", _(u"Retweet with comments")) + self.dialog.set_value("general", "persist_size", str(self.config["general"]["persist_size"])) + self.dialog.create_other_buffers() + buffer_values = self.get_buffers_list() + self.dialog.buffers.insert_buffers(buffer_values) + self.dialog.buffers.connect_hook_func(self.toggle_buffer_active) + widgetUtils.connect_event(self.dialog.buffers.toggle_state, widgetUtils.BUTTON_PRESSED, self.toggle_state) + widgetUtils.connect_event(self.dialog.buffers.up, widgetUtils.BUTTON_PRESSED, self.dialog.buffers.move_up) + widgetUtils.connect_event(self.dialog.buffers.down, widgetUtils.BUTTON_PRESSED, self.dialog.buffers.move_down) + + + self.dialog.create_ignored_clients(self.config["twitter"]["ignored_clients"]) + widgetUtils.connect_event(self.dialog.ignored_clients.add, widgetUtils.BUTTON_PRESSED, self.add_ignored_client) + widgetUtils.connect_event(self.dialog.ignored_clients.remove, widgetUtils.BUTTON_PRESSED, self.remove_ignored_client) + self.input_devices = sound_lib.input.Input.get_device_names() + self.output_devices = sound_lib.output.Output.get_device_names() + self.soundpacks = [] + [self.soundpacks.append(i) for i in os.listdir(paths.sound_path()) if os.path.isdir(paths.sound_path(i)) == True ] + self.dialog.create_sound(self.input_devices, self.output_devices, self.soundpacks) + self.dialog.set_value("sound", "volumeCtrl", self.config["sound"]["volume"]*100) + self.dialog.set_value("sound", "input", self.config["sound"]["input_device"]) + self.dialog.set_value("sound", "output", self.config["sound"]["output_device"]) + self.dialog.set_value("sound", "session_mute", self.config["sound"]["session_mute"]) + self.dialog.set_value("sound", "soundpack", self.config["sound"]["current_soundpack"]) + self.dialog.set_value("sound", "indicate_audio", self.config["sound"]["indicate_audio"]) + self.dialog.set_value("sound", "indicate_geo", self.config["sound"]["indicate_geo"]) + self.dialog.set_value("sound", "indicate_img", self.config["sound"]["indicate_img"]) + self.dialog.create_extras(OCRSpace.translatable_langs) + self.dialog.set_value("extras", "sndup_apiKey", self.config["sound"]["sndup_api_key"]) + language_index = OCRSpace.OcrLangs.index(self.config["mysc"]["ocr_language"]) + self.dialog.extras.ocr_lang.SetSelection(language_index) + self.dialog.realize() + self.dialog.set_title(_(u"Account settings for %s") % (self.user,)) + self.response = self.dialog.get_response() + + def save_configuration(self): + if self.config["general"]["relative_times"] != self.dialog.get_value("general", "relative_time"): + self.needs_restart = True + self.config["general"]["relative_times"] = self.dialog.get_value("general", "relative_time") + self.config["general"]["show_screen_names"] = self.dialog.get_value("general", "show_screen_names") + self.config["general"]["max_api_calls"] = self.dialog.get_value("general", "apiCalls") + self.config["general"]["max_tweets_per_call"] = self.dialog.get_value("general", "itemsPerApiCall") + if self.config["general"]["persist_size"] != self.dialog.get_value("general", "persist_size"): + if self.dialog.get_value("general", "persist_size") == '': + self.config["general"]["persist_size"] =-1 + else: + try: + self.config["general"]["persist_size"] = int(self.dialog.get_value("general", "persist_size")) + except ValueError: + output.speak("Invalid cache size, setting to default.",True) + self.config["general"]["persist_size"] =1764 + + if self.config["general"]["reverse_timelines"] != self.dialog.get_value("general", "reverse_timelines"): + self.needs_restart = True + self.config["general"]["reverse_timelines"] = self.dialog.get_value("general", "reverse_timelines") + rt = self.dialog.get_value("general", "retweet_mode") + if rt == _(u"Ask"): + self.config["general"]["retweet_mode"] = "ask" + elif rt == _(u"Retweet without comments"): + self.config["general"]["retweet_mode"] = "direct" + else: + self.config["general"]["retweet_mode"] = "comment" + buffers_list = self.dialog.buffers.get_list() + if set(self.config["general"]["buffer_order"]) != set(buffers_list) or buffers_list != self.config["general"]["buffer_order"]: + self.needs_restart = True + self.config["general"]["buffer_order"] = buffers_list + self.config["mysc"]["ocr_language"] = OCRSpace.OcrLangs[self.dialog.extras.ocr_lang.GetSelection()] +# if self.config["other_buffers"]["show_followers"] != self.dialog.get_value("buffers", "followers"): +# self.config["other_buffers"]["show_followers"] = self.dialog.get_value("buffers", "followers") +# pub.sendMessage("create-new-buffer", buffer="followers", account=self.user, create=self.config["other_buffers"]["show_followers"]) +# if self.config["other_buffers"]["show_friends"] != self.dialog.get_value("buffers", "friends"): +# self.config["other_buffers"]["show_friends"] = self.dialog.get_value("buffers", "friends") +# pub.sendMessage("create-new-buffer", buffer="friends", account=self.user, create=self.config["other_buffers"]["show_friends"]) +# if self.config["other_buffers"]["show_favourites"] != self.dialog.get_value("buffers", "favs"): +# self.config["other_buffers"]["show_favourites"] = self.dialog.get_value("buffers", "favs") +# pub.sendMessage("create-new-buffer", buffer="favourites", account=self.user, create=self.config["other_buffers"]["show_favourites"]) +# if self.config["other_buffers"]["show_blocks"] != self.dialog.get_value("buffers", "blocks"): +# self.config["other_buffers"]["show_blocks"] = self.dialog.get_value("buffers", "blocks") +# pub.sendMessage("create-new-buffer", buffer="blocked", account=self.user, create=self.config["other_buffers"]["show_blocks"]) +# if self.config["other_buffers"]["show_muted_users"] != self.dialog.get_value("buffers", "mutes"): +# self.config["other_buffers"]["show_muted_users"] = self.dialog.get_value("buffers", "mutes") +# pub.sendMessage("create-new-buffer", buffer="muted", account=self.user, create=self.config["other_buffers"]["show_muted_users"]) +# if self.config["other_buffers"]["show_events"] != self.dialog.get_value("buffers", "events"): +# self.config["other_buffers"]["show_events"] = self.dialog.get_value("buffers", "events") +# pub.sendMessage("create-new-buffer", buffer="events", account=self.user, create=self.config["other_buffers"]["show_events"]) + if self.config["sound"]["input_device"] != self.dialog.sound.get("input"): + self.config["sound"]["input_device"] = self.dialog.sound.get("input") + try: + self.buffer.session.sound.input.set_device(self.buffer.session.sound.input.find_device_by_name(self.config["sound"]["input_device"])) + except: + self.config["sound"]["input_device"] = "default" + if self.config["sound"]["output_device"] != self.dialog.sound.get("output"): + self.config["sound"]["output_device"] = self.dialog.sound.get("output") + try: + self.buffer.session.sound.output.set_device(self.buffer.session.sound.output.find_device_by_name(self.config["sound"]["output_device"])) + except: + self.config["sound"]["output_device"] = "default" + self.config["sound"]["volume"] = old_div(self.dialog.get_value("sound", "volumeCtrl"),100.0) + self.config["sound"]["session_mute"] = self.dialog.get_value("sound", "session_mute") + self.config["sound"]["current_soundpack"] = self.dialog.sound.get("soundpack") + self.config["sound"]["indicate_audio"] = self.dialog.get_value("sound", "indicate_audio") + self.config["sound"]["indicate_geo"] = self.dialog.get_value("sound", "indicate_geo") + self.config["sound"]["indicate_img"] = self.dialog.get_value("sound", "indicate_img") + self.config["sound"]["sndup_api_key"] = self.dialog.get_value("extras", "sndup_apiKey") + self.buffer.session.sound.config = self.config["sound"] + self.buffer.session.sound.check_soundpack() + self.config.write() + + def toggle_state(self,*args,**kwargs): + return self.dialog.buffers.change_selected_item() + + def manage_autocomplete(self, *args, **kwargs): + configuration = settings.autocompletionSettings(self.buffer.session.settings, self.buffer, self.window) + + def add_ignored_client(self, *args, **kwargs): + client = commonMessageDialogs.get_ignored_client() + if client == None: return + if client not in self.config["twitter"]["ignored_clients"]: + self.config["twitter"]["ignored_clients"].append(client) + self.dialog.ignored_clients.append(client) + + def remove_ignored_client(self, *args, **kwargs): + if self.dialog.ignored_clients.get_clients() == 0: return + id = self.dialog.ignored_clients.get_client_id() + self.config["twitter"]["ignored_clients"].pop(id) + self.dialog.ignored_clients.remove_(id) + + def get_buffers_list(self): + all_buffers=OrderedDict() + all_buffers['home']=_(u"Home") + all_buffers['mentions']=_(u"Mentions") + all_buffers['dm']=_(u"Direct Messages") + all_buffers['sent_dm']=_(u"Sent direct messages") + all_buffers['sent_tweets']=_(u"Sent tweets") + all_buffers['favorites']=_(u"Likes") + all_buffers['followers']=_(u"Followers") + all_buffers['friends']=_(u"Friends") + all_buffers['blocks']=_(u"Blocked users") + all_buffers['muted']=_(u"Muted users") + all_buffers['events']=_(u"Events") + list_buffers = [] + hidden_buffers=[] + for i in list(all_buffers.keys()): + if i in self.config["general"]["buffer_order"]: + list_buffers.append((i, all_buffers[i], True)) + else: + hidden_buffers.append((i, all_buffers[i], False)) + list_buffers.extend(hidden_buffers) + return list_buffers + + def toggle_buffer_active(self, ev): + change = self.dialog.buffers.get_event(ev) + if change == True: + self.dialog.buffers.change_selected_item() + +# def manage_pocket(self, *args, **kwargs): +# if self.dialog.services.get_pocket_status() == _(u"Connect your Pocket account"): +# self.connect_pocket() +# else: +# self.disconnect_pocket() + +# def connect_pocket(self): +# dlg = self.dialog.services.show_pocket_dialog() +# if dlg == widgetUtils.YES: +# request_token = pocket.Pocket.get_request_token(consumer_key=keys.keyring.get("pocket_consumer_key"), redirect_uri="http://127.0.0.1:8080") +# auth_url = pocket.Pocket.get_auth_url(code=request_token, redirect_uri="http://127.0.0.1:8080") +# webbrowser.open_new_tab(auth_url) +# httpd = BaseHTTPServer.HTTPServer(('127.0.0.1', 8080), authorisationHandler.handler) +# while authorisationHandler.logged == False: +# httpd.handle_request() +# user_credentials = pocket.Pocket.get_credentials(consumer_key=keys.keyring.get("pocket_consumer_key"), code=request_token) +# self.dialog.services.set_pocket(True) +# self.config["services"]["pocket_access_token"] = user_credentials["access_token"] + + def disconnect_dropbox(self): + self.config["services"]["pocket_access_token"] = "" + self.dialog.services.set_pocket(False) diff --git a/src/controller/trendingTopics.py b/src/controller/trendingTopics.py index 102aa227..f2e5c3d2 100644 --- a/src/controller/trendingTopics.py +++ b/src/controller/trendingTopics.py @@ -1,45 +1,46 @@ -# -*- coding: utf-8 -*- -from wxUI.dialogs import trends -import widgetUtils - -class trendingTopicsController(object): - def __init__(self, session): - super(trendingTopicsController, self).__init__() - self.countries = {} - self.cities = {} - self.dialog = trends.trendingTopicsDialog() - self.information = session.twitter.twitter.get_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) - self.get_places() - - def split_information(self): - for i in self.information: - if i["placeType"]["name"] == "Country": - self.countries[i["name"]] = i["woeid"] - else: - self.cities[i["name"]] = i["woeid"] - - def get_places(self, event=None): - values = [] - if self.dialog.get_active() == "country": - for i in self.information: - if i["placeType"]["name"] == "Country": - values.append(i["name"]) - elif self.dialog.get_active() == "city": - for i in self.information: - if i["placeType"]["name"] != "Country": - values.append(i["name"]) - self.dialog.set(values) - - def get_woeid(self): - selected = self.dialog.get_item() - if self.dialog.get_active() == "country": - woeid = self.countries[selected] - else: - woeid = self.cities[selected] - return woeid - - def get_string(self): +# -*- coding: utf-8 -*- +from builtins import object +from wxUI.dialogs import trends +import widgetUtils + +class trendingTopicsController(object): + def __init__(self, session): + super(trendingTopicsController, self).__init__() + self.countries = {} + self.cities = {} + self.dialog = trends.trendingTopicsDialog() + self.information = session.twitter.twitter.get_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) + self.get_places() + + def split_information(self): + for i in self.information: + if i["placeType"]["name"] == "Country": + self.countries[i["name"]] = i["woeid"] + else: + self.cities[i["name"]] = i["woeid"] + + def get_places(self, event=None): + values = [] + if self.dialog.get_active() == "country": + for i in self.information: + if i["placeType"]["name"] == "Country": + values.append(i["name"]) + elif self.dialog.get_active() == "city": + for i in self.information: + if i["placeType"]["name"] != "Country": + values.append(i["name"]) + self.dialog.set(values) + + def get_woeid(self): + selected = self.dialog.get_item() + if self.dialog.get_active() == "country": + woeid = self.countries[selected] + else: + woeid = self.cities[selected] + return woeid + + def get_string(self): return self.dialog.get_item() \ No newline at end of file diff --git a/src/controller/user.py b/src/controller/user.py index ffa80eec..bde78ffb 100644 --- a/src/controller/user.py +++ b/src/controller/user.py @@ -1,126 +1,127 @@ -# -*- coding: utf-8 -*- -import wx -import webbrowser -import widgetUtils -import output -from wxUI.dialogs import update_profile, show_user -import logging -log = logging.getLogger("controller.user") -from twython import TwythonError - -class profileController(object): - def __init__(self, session, user=None): - super(profileController, self).__init__() - self.file = None - self.session = session - self.user = user - if user == None: - self.get_data(screen_name=self.session.db["user_name"]) - self.dialog = update_profile.updateProfileDialog() - self.fill_profile_fields() - self.uploaded = False - widgetUtils.connect_event(self.dialog.upload_image, widgetUtils.BUTTON_PRESSED, self.upload_image) - else: - try: - self.get_data(screen_name=self.user) - except TwythonError as err: - if err.error_code == 404: - wx.MessageDialog(None, _(u"That user does not exist"), _(u"Error"), wx.ICON_ERROR).ShowModal() - if err.error_code == 403: - wx.MessageDialog(None, _(u"User has been suspended"), _(u"Error"), wx.ICON_ERROR).ShowModal() - log.error("error %d: %s" % (err.error_code, err.msg)) - return - self.dialog = show_user.showUserProfile() - string = self.get_user_info() - self.dialog.set("text", string) - self.dialog.set_title(_(u"Information for %s") % (self.data["screen_name"])) - if self.data["url"] != None: - self.dialog.enable_url() - widgetUtils.connect_event(self.dialog.url, widgetUtils.BUTTON_PRESSED, self.visit_url) - if self.dialog.get_response() == widgetUtils.OK and self.user == None: - self.do_update() - - def get_data(self, screen_name): - self.data = self.session.twitter.twitter.show_user(screen_name=screen_name) - if screen_name != self.session.db["user_name"]: - self.friendship_status = self.session.twitter.twitter.show_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"]) - if self.data["url"] != None: - self.dialog.set_url(self.data["url"]) - if len(self.data["location"]) > 0: - self.dialog.set_location(self.data["location"]) - if len(self.data["description"]) > 0: - self.dialog.set_description(self.data["description"]) - - def get_image(self): - file = self.dialog.upload_picture() - if file != None: - self.file = open(file, "rb") - self.uploaded = True - self.dialog.change_upload_button(self.uploaded) - - def discard_image(self): - self.file = None - output.speak(_(u"Discarded")) - self.uploaded = False - self.dialog.change_upload_button(self.uploaded) - - def upload_image(self, *args, **kwargs): - if self.uploaded == False: - self.get_image() - elif self.uploaded == True: - self.discard_image() - - def do_update(self): - if self.user != None: return - name = self.dialog.get("name") - description = self.dialog.get("description") - location = self.dialog.get("location") - url = self.dialog.get("url") - if self.file != None: - try: - self.session.twitter.twitter.update_profile_image(image=self.file) - except TwythonError as e: - output.speak(u"Error %s. %s" % (e.error_code, e.msg)) - try: - self.session.twitter.twitter.update_profile(name=name, description=description, location=location, url=url) - except TwythonError as e: - output.speak(u"Error %s. %s" % (e.error_code, e.msg)) - - def get_user_info(self): - - string = u"" - string = string + _(u"Username: @%s\n") % (self.data["screen_name"]) - string = string + _(u"Name: %s\n") % (self.data["name"]) - if self.data["location"] != "": - string = string + _(u"Location: %s\n") % (self.data["location"]) - if self.data["url"] != None: - string = string+ _(u"URL: %s\n") % (self.data["url"]) - if self.data["description"] != "": - string = string+ _(u"Bio: %s\n") % (self.data["description"]) - if self.data["protected"] == True: protected = _(u"Yes") - else: protected = _(u"No") - string = string+ _(u"Protected: %s\n") % (protected) - if hasattr(self, "friendship_status"): - relation = False - friendship = "Relationship: " - if self.friendship_status["relationship"]["target"]["followed_by"]: - friendship += _(u"You follow {0}. ").format(self.data["name"],) - relation = True - if self.friendship_status["relationship"]["target"]["following"]: - friendship += _(u"{0} is following you.").format(self.data["name"],) - relation = True - if relation == True: - string = string+friendship+"\n" - string = string+_(u"Followers: %s\n Friends: %s\n") % (self.data["followers_count"], self.data["friends_count"]) - if self.data["verified"] == True: verified = _(u"Yes") - else: verified = _(u"No") - string = string+ _(u"Verified: %s\n") % (verified) - string = string+ _(u"Tweets: %s\n") % (self.data["statuses_count"]) - string = string+ _(u"Likes: %s") % (self.data["favourites_count"]) - return string - - def visit_url(self, *args, **kwargs): +# -*- coding: utf-8 -*- +from builtins import object +import wx +import webbrowser +import widgetUtils +import output +from wxUI.dialogs import update_profile, show_user +import logging +log = logging.getLogger("controller.user") +from twython import TwythonError + +class profileController(object): + def __init__(self, session, user=None): + super(profileController, self).__init__() + self.file = None + self.session = session + self.user = user + if user == None: + self.get_data(screen_name=self.session.db["user_name"]) + self.dialog = update_profile.updateProfileDialog() + self.fill_profile_fields() + self.uploaded = False + widgetUtils.connect_event(self.dialog.upload_image, widgetUtils.BUTTON_PRESSED, self.upload_image) + else: + try: + self.get_data(screen_name=self.user) + except TwythonError as err: + if err.error_code == 404: + wx.MessageDialog(None, _(u"That user does not exist"), _(u"Error"), wx.ICON_ERROR).ShowModal() + if err.error_code == 403: + wx.MessageDialog(None, _(u"User has been suspended"), _(u"Error"), wx.ICON_ERROR).ShowModal() + log.error("error %d: %s" % (err.error_code, err.msg)) + return + self.dialog = show_user.showUserProfile() + string = self.get_user_info() + self.dialog.set("text", string) + self.dialog.set_title(_(u"Information for %s") % (self.data["screen_name"])) + if self.data["url"] != None: + self.dialog.enable_url() + widgetUtils.connect_event(self.dialog.url, widgetUtils.BUTTON_PRESSED, self.visit_url) + if self.dialog.get_response() == widgetUtils.OK and self.user == None: + self.do_update() + + def get_data(self, screen_name): + self.data = self.session.twitter.twitter.show_user(screen_name=screen_name) + if screen_name != self.session.db["user_name"]: + self.friendship_status = self.session.twitter.twitter.show_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"]) + if self.data["url"] != None: + self.dialog.set_url(self.data["url"]) + if len(self.data["location"]) > 0: + self.dialog.set_location(self.data["location"]) + if len(self.data["description"]) > 0: + self.dialog.set_description(self.data["description"]) + + def get_image(self): + file = self.dialog.upload_picture() + if file != None: + self.file = open(file, "rb") + self.uploaded = True + self.dialog.change_upload_button(self.uploaded) + + def discard_image(self): + self.file = None + output.speak(_(u"Discarded")) + self.uploaded = False + self.dialog.change_upload_button(self.uploaded) + + def upload_image(self, *args, **kwargs): + if self.uploaded == False: + self.get_image() + elif self.uploaded == True: + self.discard_image() + + def do_update(self): + if self.user != None: return + name = self.dialog.get("name") + description = self.dialog.get("description") + location = self.dialog.get("location") + url = self.dialog.get("url") + if self.file != None: + try: + self.session.twitter.twitter.update_profile_image(image=self.file) + except TwythonError as e: + output.speak(u"Error %s. %s" % (e.error_code, e.msg)) + try: + self.session.twitter.twitter.update_profile(name=name, description=description, location=location, url=url) + except TwythonError as e: + output.speak(u"Error %s. %s" % (e.error_code, e.msg)) + + def get_user_info(self): + + string = u"" + string = string + _(u"Username: @%s\n") % (self.data["screen_name"]) + string = string + _(u"Name: %s\n") % (self.data["name"]) + if self.data["location"] != "": + string = string + _(u"Location: %s\n") % (self.data["location"]) + if self.data["url"] != None: + string = string+ _(u"URL: %s\n") % (self.data["url"]) + if self.data["description"] != "": + string = string+ _(u"Bio: %s\n") % (self.data["description"]) + if self.data["protected"] == True: protected = _(u"Yes") + else: protected = _(u"No") + string = string+ _(u"Protected: %s\n") % (protected) + if hasattr(self, "friendship_status"): + relation = False + friendship = "Relationship: " + if self.friendship_status["relationship"]["target"]["followed_by"]: + friendship += _(u"You follow {0}. ").format(self.data["name"],) + relation = True + if self.friendship_status["relationship"]["target"]["following"]: + friendship += _(u"{0} is following you.").format(self.data["name"],) + relation = True + if relation == True: + string = string+friendship+"\n" + string = string+_(u"Followers: %s\n Friends: %s\n") % (self.data["followers_count"], self.data["friends_count"]) + if self.data["verified"] == True: verified = _(u"Yes") + else: verified = _(u"No") + string = string+ _(u"Verified: %s\n") % (verified) + string = string+ _(u"Tweets: %s\n") % (self.data["statuses_count"]) + string = string+ _(u"Likes: %s") % (self.data["favourites_count"]) + return string + + def visit_url(self, *args, **kwargs): webbrowser.open_new_tab(self.data["url"]) \ No newline at end of file diff --git a/src/controller/userActionsController.py b/src/controller/userActionsController.py index a4041839..29641efc 100644 --- a/src/controller/userActionsController.py +++ b/src/controller/userActionsController.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +from builtins import object import re import widgetUtils import output diff --git a/src/extra/AudioUploader/audioUploader.py b/src/extra/AudioUploader/audioUploader.py index ea1aff8b..e2716e23 100644 --- a/src/extra/AudioUploader/audioUploader.py +++ b/src/extra/AudioUploader/audioUploader.py @@ -17,6 +17,8 @@ # ############################################################ from __future__ import absolute_import +from builtins import str +from builtins import object import widgetUtils from . import wx_ui from . import wx_transfer_dialogs @@ -132,7 +134,7 @@ class audioUploader(object): def _play(self): output.speak(_(u"Playing...")) # try: - self.playing = sound_lib.stream.FileStream(file=unicode(self.file), flags=sound_lib.stream.BASS_UNICODE) + self.playing = sound_lib.stream.FileStream(file=str(self.file), flags=sound_lib.stream.BASS_UNICODE) self.playing.play() self.dialog.set("play", _(u"&Stop")) try: diff --git a/src/extra/AudioUploader/transfer.py b/src/extra/AudioUploader/transfer.py index 25d492e9..12da3f23 100644 --- a/src/extra/AudioUploader/transfer.py +++ b/src/extra/AudioUploader/transfer.py @@ -1,5 +1,8 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import +from __future__ import division +from builtins import object +from past.utils import old_div import sys import threading import time @@ -21,7 +24,7 @@ class Upload(object): self.background_thread = None self.transfer_rate = 0 self.local_filename=os.path.basename(self.filename) - if isinstance(self.local_filename, unicode): + if isinstance(self.local_filename, str): self.local_filename=self.local_filename.encode(sys.getfilesystemencoding()) self.fin=open(self.filename, 'rb') self.m = MultipartEncoder(fields={field:(self.local_filename, self.fin, "application/octet-stream")}) @@ -44,11 +47,11 @@ class Upload(object): progress["percent"] = 0 self.transfer_rate = 0 else: - progress["percent"] = int((float(progress["current"]) / progress["total"]) * 100) - self.transfer_rate = progress["current"] / self.elapsed_time() + progress["percent"] = int((old_div(float(progress["current"]), progress["total"])) * 100) + self.transfer_rate = old_div(progress["current"], self.elapsed_time()) progress["speed"] = '%s/s' % convert_bytes(self.transfer_rate) if self.transfer_rate: - progress["eta"] = (progress["total"] - progress["current"]) / self.transfer_rate + progress["eta"] = old_div((progress["total"] - progress["current"]), self.transfer_rate) else: progress["eta"] = 0 pub.sendMessage("uploading", data=progress) diff --git a/src/extra/AudioUploader/utils.py b/src/extra/AudioUploader/utils.py index 9a20ab26..42ee7f4a 100644 --- a/src/extra/AudioUploader/utils.py +++ b/src/extra/AudioUploader/utils.py @@ -1,42 +1,45 @@ -# -*- coding: utf-8 -*- - -def convert_bytes(n): - K, M, G, T, P = 1 << 10, 1 << 20, 1 << 30, 1 << 40, 1 << 50 - if n >= P: - return '%.2fPb' % (float(n) / T) - elif n >= T: - return '%.2fTb' % (float(n) / T) - elif n >= G: - return '%.2fGb' % (float(n) / G) - elif n >= M: - return '%.2fMb' % (float(n) / M) - elif n >= K: - return '%.2fKb' % (float(n) / K) - else: - return '%d' % n - -def seconds_to_string(seconds, precision=0): - day = seconds // 86400 - hour = seconds // 3600 - min = (seconds // 60) % 60 - sec = seconds - (hour * 3600) - (min * 60) - sec_spec = "." + str(precision) + "f" - sec_string = sec.__format__(sec_spec) - string = "" - if day == 1: - string += _(u"%d day, ") % day - elif day >= 2: - string += _(u"%d days, ") % day - if (hour == 1): - string += _(u"%d hour, ") % hour - elif (hour >= 2): - string += _("%d hours, ") % hour - if (min == 1): - string += _(u"%d minute, ") % min - elif (min >= 2): - string += _(u"%d minutes, ") % min - if sec >= 0 and sec <= 2: - string += _(u"%s second") % sec_string - else: - string += _(u"%s seconds") % sec_string +# -*- coding: utf-8 -*- + +from __future__ import division +from builtins import str +from past.utils import old_div +def convert_bytes(n): + K, M, G, T, P = 1 << 10, 1 << 20, 1 << 30, 1 << 40, 1 << 50 + if n >= P: + return '%.2fPb' % (old_div(float(n), T)) + elif n >= T: + return '%.2fTb' % (old_div(float(n), T)) + elif n >= G: + return '%.2fGb' % (old_div(float(n), G)) + elif n >= M: + return '%.2fMb' % (old_div(float(n), M)) + elif n >= K: + return '%.2fKb' % (old_div(float(n), K)) + else: + return '%d' % n + +def seconds_to_string(seconds, precision=0): + day = seconds // 86400 + hour = seconds // 3600 + min = (seconds // 60) % 60 + sec = seconds - (hour * 3600) - (min * 60) + sec_spec = "." + str(precision) + "f" + sec_string = sec.__format__(sec_spec) + string = "" + if day == 1: + string += _(u"%d day, ") % day + elif day >= 2: + string += _(u"%d days, ") % day + if (hour == 1): + string += _(u"%d hour, ") % hour + elif (hour >= 2): + string += _("%d hours, ") % hour + if (min == 1): + string += _(u"%d minute, ") % min + elif (min >= 2): + string += _(u"%d minutes, ") % min + if sec >= 0 and sec <= 2: + string += _(u"%s second") % sec_string + else: + string += _(u"%s seconds") % sec_string return string \ No newline at end of file diff --git a/src/extra/SoundsTutorial/soundsTutorial.py b/src/extra/SoundsTutorial/soundsTutorial.py index 863bebdc..a01ca803 100644 --- a/src/extra/SoundsTutorial/soundsTutorial.py +++ b/src/extra/SoundsTutorial/soundsTutorial.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import +from builtins import object import platform import widgetUtils import os diff --git a/src/extra/SpellChecker/spellchecker.py b/src/extra/SpellChecker/spellchecker.py index ec689a29..67a9b90a 100644 --- a/src/extra/SpellChecker/spellchecker.py +++ b/src/extra/SpellChecker/spellchecker.py @@ -1,5 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import +from builtins import next +from builtins import object import logging log = logging.getLogger("extra.SpellChecker.spellChecker") from . import wx_ui diff --git a/src/extra/autocompletionUsers/completion.py b/src/extra/autocompletionUsers/completion.py index 96aa74f3..341d70ba 100644 --- a/src/extra/autocompletionUsers/completion.py +++ b/src/extra/autocompletionUsers/completion.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import +from builtins import object import output from . import storage from . import wx_menu diff --git a/src/extra/autocompletionUsers/manage.py b/src/extra/autocompletionUsers/manage.py index 858291cf..3ecbbbe8 100644 --- a/src/extra/autocompletionUsers/manage.py +++ b/src/extra/autocompletionUsers/manage.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import # -*- coding: utf-8 -*- +from builtins import object from . import storage import widgetUtils from . import wx_manage diff --git a/src/extra/autocompletionUsers/settings.py b/src/extra/autocompletionUsers/settings.py index 9a72d4c5..6783ccfe 100644 --- a/src/extra/autocompletionUsers/settings.py +++ b/src/extra/autocompletionUsers/settings.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import # -*- coding: utf-8 -*- +from builtins import object from . import storage import widgetUtils from . import wx_settings diff --git a/src/extra/autocompletionUsers/storage.py b/src/extra/autocompletionUsers/storage.py index ed9896b2..f7d86c58 100644 --- a/src/extra/autocompletionUsers/storage.py +++ b/src/extra/autocompletionUsers/storage.py @@ -1,52 +1,53 @@ -# -*- coding: utf-8 -*- -import sqlite3, paths - -class storage(object): - def __init__(self, session_id): - self.connection = sqlite3.connect(paths.config_path("%s/autocompletionUsers.dat" % (session_id))) - self.cursor = self.connection.cursor() - if self.table_exist("users") == False: - self.create_table() - - def table_exist(self, table): - ask = self.cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='%s'" % (table)) - answer = ask.fetchone() - if answer == None: - return False - else: - return True - - def get_all_users(self): - self.cursor.execute("""select * from users""") - return self.cursor.fetchall() - - def get_users(self, term): - self.cursor.execute("""SELECT * FROM users WHERE user LIKE ?""", ('{}%'.format(term),)) - return self.cursor.fetchall() - - def set_user(self, screen_name, user_name, from_a_buffer): - self.cursor.execute("""insert or ignore into users values(?, ?, ?)""", (screen_name, user_name, from_a_buffer)) - self.connection.commit() - - def remove_user(self, user): - self.cursor.execute("""DELETE FROM users WHERE user = ?""", (user,)) - self.connection.commit() - return self.cursor.fetchone() - - def remove_by_buffer(self, bufferType): - """ Removes all users saved on a buffer. BufferType is 0 for no buffer, 1 for friends and 2 for followers""" - self.cursor.execute("""DELETE FROM users WHERE from_a_buffer = ?""", (bufferType,)) - self.connection.commit() - return self.cursor.fetchone() - - def create_table(self): - self.cursor.execute(""" - create table users( -user TEXT UNIQUE, -name TEXT, -from_a_buffer INTEGER -)""") - - def __del__(self): - self.cursor.close() +# -*- coding: utf-8 -*- +from builtins import object +import sqlite3, paths + +class storage(object): + def __init__(self, session_id): + self.connection = sqlite3.connect(paths.config_path("%s/autocompletionUsers.dat" % (session_id))) + self.cursor = self.connection.cursor() + if self.table_exist("users") == False: + self.create_table() + + def table_exist(self, table): + ask = self.cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='%s'" % (table)) + answer = ask.fetchone() + if answer == None: + return False + else: + return True + + def get_all_users(self): + self.cursor.execute("""select * from users""") + return self.cursor.fetchall() + + def get_users(self, term): + self.cursor.execute("""SELECT * FROM users WHERE user LIKE ?""", ('{}%'.format(term),)) + return self.cursor.fetchall() + + def set_user(self, screen_name, user_name, from_a_buffer): + self.cursor.execute("""insert or ignore into users values(?, ?, ?)""", (screen_name, user_name, from_a_buffer)) + self.connection.commit() + + def remove_user(self, user): + self.cursor.execute("""DELETE FROM users WHERE user = ?""", (user,)) + self.connection.commit() + return self.cursor.fetchone() + + def remove_by_buffer(self, bufferType): + """ Removes all users saved on a buffer. BufferType is 0 for no buffer, 1 for friends and 2 for followers""" + self.cursor.execute("""DELETE FROM users WHERE from_a_buffer = ?""", (bufferType,)) + self.connection.commit() + return self.cursor.fetchone() + + def create_table(self): + self.cursor.execute(""" + create table users( +user TEXT UNIQUE, +name TEXT, +from_a_buffer INTEGER +)""") + + def __del__(self): + self.cursor.close() self.connection.close() \ No newline at end of file diff --git a/src/extra/ocr/OCRSpace.py b/src/extra/ocr/OCRSpace.py index 0b4f4821..a88a92f7 100644 --- a/src/extra/ocr/OCRSpace.py +++ b/src/extra/ocr/OCRSpace.py @@ -1,43 +1,44 @@ -# -*- coding: utf-8 -*- -""" original module taken and modified from https://github.com/ctoth/cloudOCR""" -import requests - -translatable_langs = [_(u"Detect automatically"), _(u"Danish"), _(u"Dutch"), _(u"English"), _(u"Finnish"), _(u"French"), _(u"German"), _(u"Hungarian"), _(u"Korean"), _(u"Italian"), _(u"Japanese"), _(u"Polish"), _(u"Portuguese"), _(u"Russian"), _(u"Spanish"), _(u"Turkish")] -short_langs = ["", "da", "du", "en", "fi", "fr", "de", "hu", "ko", "it", "ja", "pl", "pt", "ru", "es", "tr"] -OcrLangs = ["", "dan", "dut", "eng", "fin", "fre", "ger", "hun", "kor", "ita", "jpn", "pol", "por", "rus", "spa", "tur"] - -class APIError(Exception): - pass - -class OCRSpaceAPI(object): - - def __init__(self, key="4e72ae996f88957", url='https://api.ocr.space/parse/image'): - self.key = key - self.url = url - - def OCR_URL(self, url, overlay=False, lang=None): - payload = { - 'url': url, - 'isOverlayRequired': overlay, - 'apikey': self.key, - } - if lang != None: - payload.update(language=lang) - r = requests.post(self.url, data=payload) - result = r.json()['ParsedResults'][0] - if result['ErrorMessage']: - raise APIError(result['ErrorMessage']) - return result - - def OCR_file(self, fileobj, overlay=False): - payload = { - 'isOverlayRequired': overlay, - 'apikey': self.key, - 'lang': 'es', - } - r = requests.post(self.url, data=payload, files={'file': fileobj}) - results = r.json()['ParsedResults'] - if results[0]['ErrorMessage']: - raise APIError(results[0]['ErrorMessage']) - return results - +# -*- coding: utf-8 -*- +""" original module taken and modified from https://github.com/ctoth/cloudOCR""" +from builtins import object +import requests + +translatable_langs = [_(u"Detect automatically"), _(u"Danish"), _(u"Dutch"), _(u"English"), _(u"Finnish"), _(u"French"), _(u"German"), _(u"Hungarian"), _(u"Korean"), _(u"Italian"), _(u"Japanese"), _(u"Polish"), _(u"Portuguese"), _(u"Russian"), _(u"Spanish"), _(u"Turkish")] +short_langs = ["", "da", "du", "en", "fi", "fr", "de", "hu", "ko", "it", "ja", "pl", "pt", "ru", "es", "tr"] +OcrLangs = ["", "dan", "dut", "eng", "fin", "fre", "ger", "hun", "kor", "ita", "jpn", "pol", "por", "rus", "spa", "tur"] + +class APIError(Exception): + pass + +class OCRSpaceAPI(object): + + def __init__(self, key="4e72ae996f88957", url='https://api.ocr.space/parse/image'): + self.key = key + self.url = url + + def OCR_URL(self, url, overlay=False, lang=None): + payload = { + 'url': url, + 'isOverlayRequired': overlay, + 'apikey': self.key, + } + if lang != None: + payload.update(language=lang) + r = requests.post(self.url, data=payload) + result = r.json()['ParsedResults'][0] + if result['ErrorMessage']: + raise APIError(result['ErrorMessage']) + return result + + def OCR_file(self, fileobj, overlay=False): + payload = { + 'isOverlayRequired': overlay, + 'apikey': self.key, + 'lang': 'es', + } + r = requests.post(self.url, data=payload, files={'file': fileobj}) + results = r.json()['ParsedResults'] + if results[0]['ErrorMessage']: + raise APIError(results[0]['ErrorMessage']) + return results + diff --git a/src/extra/translator/translator.py b/src/extra/translator/translator.py index 9caa697d..01dd51ef 100644 --- a/src/extra/translator/translator.py +++ b/src/extra/translator/translator.py @@ -1,108 +1,109 @@ -# -*- coding: utf-8 -*- -from yandex_translate import YandexTranslate - -def translate(text="", source="auto", target="en"): - t = YandexTranslate("trnsl.1.1.20161012T134532Z.d01b9c75fc39aa74.7d1be75a5166a80583eeb020e10f584168da6bf7") - return t.translate(text, target)["text"][0] - - -languages = { - "af": _(u"Afrikaans"), - "sq": _(u"Albanian"), - "am": _(u"Amharic"), - "ar": _(u"Arabic"), - "hy": _(u"Armenian"), - "az": _(u"Azerbaijani"), - "eu": _(u"Basque"), - "be": _(u"Belarusian"), - "bn": _(u"Bengali"), - "bh": _(u"Bihari"), - "bg": _(u"Bulgarian"), - "my": _(u"Burmese"), - "ca": _(u"Catalan"), - "chr": _(u"Cherokee"), - "zh": _(u"Chinese"), - "zh-CN": _(u"Chinese_simplified"), - "zh-TW": _(u"Chinese_traditional"), - "hr": _(u"Croatian"), - "cs": _(u"Czech"), - "da": _(u"Danish"), - "dv": _(u"Dhivehi"), - "nl": _(u"Dutch"), - "en": _(u"English"), - "eo": _(u"Esperanto"), - "et": _(u"Estonian"), - "tl": _(u"Filipino"), - "fi": _(u"Finnish"), - "fr": _(u"French"), - "gl": _(u"Galician"), - "ka": _(u"Georgian"), - "de": _(u"German"), - "el": _(u"Greek"), - "gn": _(u"Guarani"), - "gu": _(u"Gujarati"), - "iw": _(u"Hebrew"), - "hi": _(u"Hindi"), - "hu": _(u"Hungarian"), - "is": _(u"Icelandic"), - "id": _(u"Indonesian"), - "iu": _(u"Inuktitut"), - "ga": _(u"Irish"), - "it": _(u"Italian"), - "ja": _(u"Japanese"), - "kn": _(u"Kannada"), - "kk": _(u"Kazakh"), - "km": _(u"Khmer"), - "ko": _(u"Korean"), - "ku": _(u"Kurdish"), - "ky": _(u"Kyrgyz"), - "lo": _(u"Laothian"), - "lv": _(u"Latvian"), - "lt": _(u"Lithuanian"), - "mk": _(u"Macedonian"), - "ms": _(u"Malay"), - "ml": _(u"Malayalam"), - "mt": _(u"Maltese"), - "mr": _(u"Marathi"), - "mn": _(u"Mongolian"), - "ne": _(u"Nepali"), - "no": _(u"Norwegian"), - "or": _(u"Oriya"), - "ps": _(u"Pashto"), - "fa": _(u"Persian"), - "pl": _(u"Polish"), - "pt-PT": _(u"Portuguese"), - "pa": _(u"Punjabi"), - "ro": _(u"Romanian"), - "ru": _(u"Russian"), - "sa": _(u"Sanskrit"), - "sr": _(u"Serbian"), - "sd": _(u"Sindhi"), - "si": _(u"Sinhalese"), - "sk": _(u"Slovak"), - "sl": _(u"Slovenian"), - "es": _(u"Spanish"), - "sw": _(u"Swahili"), - "sv": _(u"Swedish"), - "tg": _(u"Tajik"), - "ta": _(u"Tamil"), - "tl": _(u"Tagalog"), - "te": _(u"Telugu"), - "th": _(u"Thai"), - "bo": _(u"Tibetan"), - "tr": _(u"Turkish"), - "uk": _(u"Ukrainian"), - "ur": _(u"Urdu"), - "uz": _(u"Uzbek"), - "ug": _(u"Uighur"), - "vi": _(u"Vietnamese"), - "cy": _(u"Welsh"), - "yi": _(u"Yiddish") -} - -def available_languages(): - l = languages.keys() - d = languages.values() - l.insert(0, '') - d.insert(0, _(u"autodetect")) - return sorted(zip(l, d)) +# -*- coding: utf-8 -*- +from builtins import zip +from yandex_translate import YandexTranslate + +def translate(text="", source="auto", target="en"): + t = YandexTranslate("trnsl.1.1.20161012T134532Z.d01b9c75fc39aa74.7d1be75a5166a80583eeb020e10f584168da6bf7") + return t.translate(text, target)["text"][0] + + +languages = { + "af": _(u"Afrikaans"), + "sq": _(u"Albanian"), + "am": _(u"Amharic"), + "ar": _(u"Arabic"), + "hy": _(u"Armenian"), + "az": _(u"Azerbaijani"), + "eu": _(u"Basque"), + "be": _(u"Belarusian"), + "bn": _(u"Bengali"), + "bh": _(u"Bihari"), + "bg": _(u"Bulgarian"), + "my": _(u"Burmese"), + "ca": _(u"Catalan"), + "chr": _(u"Cherokee"), + "zh": _(u"Chinese"), + "zh-CN": _(u"Chinese_simplified"), + "zh-TW": _(u"Chinese_traditional"), + "hr": _(u"Croatian"), + "cs": _(u"Czech"), + "da": _(u"Danish"), + "dv": _(u"Dhivehi"), + "nl": _(u"Dutch"), + "en": _(u"English"), + "eo": _(u"Esperanto"), + "et": _(u"Estonian"), + "tl": _(u"Filipino"), + "fi": _(u"Finnish"), + "fr": _(u"French"), + "gl": _(u"Galician"), + "ka": _(u"Georgian"), + "de": _(u"German"), + "el": _(u"Greek"), + "gn": _(u"Guarani"), + "gu": _(u"Gujarati"), + "iw": _(u"Hebrew"), + "hi": _(u"Hindi"), + "hu": _(u"Hungarian"), + "is": _(u"Icelandic"), + "id": _(u"Indonesian"), + "iu": _(u"Inuktitut"), + "ga": _(u"Irish"), + "it": _(u"Italian"), + "ja": _(u"Japanese"), + "kn": _(u"Kannada"), + "kk": _(u"Kazakh"), + "km": _(u"Khmer"), + "ko": _(u"Korean"), + "ku": _(u"Kurdish"), + "ky": _(u"Kyrgyz"), + "lo": _(u"Laothian"), + "lv": _(u"Latvian"), + "lt": _(u"Lithuanian"), + "mk": _(u"Macedonian"), + "ms": _(u"Malay"), + "ml": _(u"Malayalam"), + "mt": _(u"Maltese"), + "mr": _(u"Marathi"), + "mn": _(u"Mongolian"), + "ne": _(u"Nepali"), + "no": _(u"Norwegian"), + "or": _(u"Oriya"), + "ps": _(u"Pashto"), + "fa": _(u"Persian"), + "pl": _(u"Polish"), + "pt-PT": _(u"Portuguese"), + "pa": _(u"Punjabi"), + "ro": _(u"Romanian"), + "ru": _(u"Russian"), + "sa": _(u"Sanskrit"), + "sr": _(u"Serbian"), + "sd": _(u"Sindhi"), + "si": _(u"Sinhalese"), + "sk": _(u"Slovak"), + "sl": _(u"Slovenian"), + "es": _(u"Spanish"), + "sw": _(u"Swahili"), + "sv": _(u"Swedish"), + "tg": _(u"Tajik"), + "ta": _(u"Tamil"), + "tl": _(u"Tagalog"), + "te": _(u"Telugu"), + "th": _(u"Thai"), + "bo": _(u"Tibetan"), + "tr": _(u"Turkish"), + "uk": _(u"Ukrainian"), + "ur": _(u"Urdu"), + "uz": _(u"Uzbek"), + "ug": _(u"Uighur"), + "vi": _(u"Vietnamese"), + "cy": _(u"Welsh"), + "yi": _(u"Yiddish") +} + +def available_languages(): + l = list(languages.keys()) + d = list(languages.values()) + l.insert(0, '') + d.insert(0, _(u"autodetect")) + return sorted(zip(l, d)) diff --git a/src/fixes/fix_urllib3_warnings.py b/src/fixes/fix_urllib3_warnings.py index 21a7c577..2870fce5 100644 --- a/src/fixes/fix_urllib3_warnings.py +++ b/src/fixes/fix_urllib3_warnings.py @@ -1,24 +1,26 @@ -# -*- coding: utf-8 -*- -from requests.packages import urllib3 -from requests.packages.urllib3 import fields -import six -import urllib - -def fix(): - urllib3.disable_warnings() - fields.format_header_param=patched_format_header_param - -def patched_format_header_param(name, value): - if not any(ch in value for ch in '"\\\r\n'): - result = '%s="%s"' % (name, value) - try: - result.encode('ascii') - except (UnicodeEncodeError, UnicodeDecodeError): - pass - else: - return result - if not six.PY3 and isinstance(value, six.text_type): # Python 2: - value = value.encode('utf-8') - value=urllib.quote(value, safe='') - value = '%s=%s' % (name, value) - return value +# -*- coding: utf-8 -*- +from future import standard_library +standard_library.install_aliases() +from requests.packages import urllib3 +from requests.packages.urllib3 import fields +import six +import urllib.request, urllib.parse, urllib.error + +def fix(): + urllib3.disable_warnings() + fields.format_header_param=patched_format_header_param + +def patched_format_header_param(name, value): + if not any(ch in value for ch in '"\\\r\n'): + result = '%s="%s"' % (name, value) + try: + result.encode('ascii') + except (UnicodeEncodeError, UnicodeDecodeError): + pass + else: + return result + if not six.PY3 and isinstance(value, six.text_type): # Python 2: + value = value.encode('utf-8') + value=urllib.parse.quote(value, safe='') + value = '%s=%s' % (name, value) + return value diff --git a/src/issueReporter/issueReporter.py b/src/issueReporter/issueReporter.py index 937d9b3b..68698597 100644 --- a/src/issueReporter/issueReporter.py +++ b/src/issueReporter/issueReporter.py @@ -17,6 +17,7 @@ # ############################################################ from __future__ import absolute_import +from builtins import object import keys import wx from . import wx_ui diff --git a/src/keyboard_handler/linux.py b/src/keyboard_handler/linux.py index 25b39114..af249502 100644 --- a/src/keyboard_handler/linux.py +++ b/src/keyboard_handler/linux.py @@ -1,7 +1,10 @@ from __future__ import absolute_import +from future import standard_library +standard_library.install_aliases() +from builtins import chr from .main import KeyboardHandler import threading -import thread +import _thread import pyatspi def parse(s): """parse a string like control+f into (modifier, key). @@ -37,7 +40,7 @@ def handler(e): if (not e.is_text) and e.id >= 97 <= 126: k = chr(e.id) if (m,k) not in keys: return False - thread.start_new(keys[(m,k)], ()) + _thread.start_new(keys[(m,k)], ()) return True #don't pass it on class LinuxKeyboardHandler(KeyboardHandler): def __init__(self, *args, **kwargs): diff --git a/src/keyboard_handler/main.py b/src/keyboard_handler/main.py index a69cbef6..40024009 100644 --- a/src/keyboard_handler/main.py +++ b/src/keyboard_handler/main.py @@ -1,3 +1,4 @@ +from builtins import object import platform import time diff --git a/src/keyboard_handler/osx.py b/src/keyboard_handler/osx.py index f13de3ec..52f13038 100644 --- a/src/keyboard_handler/osx.py +++ b/src/keyboard_handler/osx.py @@ -1,4 +1,5 @@ from __future__ import absolute_import +from builtins import str from AppKit import * from PyObjCTools import AppHelper from Carbon.CarbonEvt import RegisterEventHotKey, GetApplicationEventTarget diff --git a/src/keyboard_handler/windows.py b/src/keyboard_handler/windows.py index 07144c21..c12b6e9f 100644 --- a/src/keyboard_handler/windows.py +++ b/src/keyboard_handler/windows.py @@ -1,4 +1,5 @@ from __future__ import absolute_import +from builtins import str import win32api import win32con diff --git a/src/keyboard_handler/wx_handler.py b/src/keyboard_handler/wx_handler.py index 8328abb5..00e50f27 100644 --- a/src/keyboard_handler/wx_handler.py +++ b/src/keyboard_handler/wx_handler.py @@ -1,5 +1,6 @@ from __future__ import print_function from __future__ import absolute_import +from builtins import chr import functools import wx import platform @@ -84,7 +85,7 @@ class WXKeyboardHandler(keyboard_handler): def process_key (self, evt, id): evt.Skip() - key_ids = self.key_ids.keys() + key_ids = list(self.key_ids.keys()) for i in key_ids: if self.key_ids.get(i) == id: self.handle_key(i) diff --git a/src/keys/__init__.py b/src/keys/__init__.py index 69818a83..588499d0 100644 --- a/src/keys/__init__.py +++ b/src/keys/__init__.py @@ -1,41 +1,41 @@ -# -*- coding: utf-8 -*- -import application -import platform -import exceptions -from ctypes import c_char_p -from libloader import load_library -import paths -#if application.snapshot == True: -# if platform.architecture()[0][:2] == "32": -# lib = load_library("snapshot_api_keys32", x86_path=paths.app_path("keys/lib")) -# else: -# lib = load_library("snapshot_api_keys64", x64_path=paths.app_path("keys/lib")) -#else: -if platform.architecture()[0][:2] == "32": - lib = load_library("stable_api_keys32", x86_path=paths.app_path("keys/lib")) -else: - lib = load_library("stable_api_keys64", x64_path=paths.app_path("keys/lib")) - -# import linuxKeys -# lib = linuxKeys - -keyring = None - -def setup(): - global keyring - if keyring == None: - keyring = Keyring() - -class Keyring(object): - def __init__(self): - super(Keyring, self).__init__() - - def _call_method(self, function): - result = getattr(lib, function) - result = c_char_p(result.__call__()) - return result.value - - def get(self, func): - if hasattr(application,func+"_override"): - return getattr(application,func+'_override') - return getattr(self, "_call_method")("get_"+func) +# -*- coding: utf-8 -*- +from builtins import object +import application +import platform +from ctypes import c_char_p +from libloader import load_library +import paths +#if application.snapshot == True: +# if platform.architecture()[0][:2] == "32": +# lib = load_library("snapshot_api_keys32", x86_path=paths.app_path("keys/lib")) +# else: +# lib = load_library("snapshot_api_keys64", x64_path=paths.app_path("keys/lib")) +#else: +if platform.architecture()[0][:2] == "32": + lib = load_library("stable_api_keys32", x86_path=paths.app_path("keys/lib")) +else: + lib = load_library("stable_api_keys64", x64_path=paths.app_path("keys/lib")) + +# import linuxKeys +# lib = linuxKeys + +keyring = None + +def setup(): + global keyring + if keyring == None: + keyring = Keyring() + +class Keyring(object): + def __init__(self): + super(Keyring, self).__init__() + + def _call_method(self, function): + result = getattr(lib, function) + result = c_char_p(result.__call__()) + return result.value + + def get(self, func): + if hasattr(application,func+"_override"): + return getattr(application,func+'_override') + return getattr(self, "_call_method")("get_"+func) diff --git a/src/keystrokeEditor/keystrokeEditor.py b/src/keystrokeEditor/keystrokeEditor.py index 55651bfc..97bda2fe 100644 --- a/src/keystrokeEditor/keystrokeEditor.py +++ b/src/keystrokeEditor/keystrokeEditor.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import +from builtins import object import widgetUtils import config from . import wx_ui diff --git a/src/languageHandler.py b/src/languageHandler.py index 7dcbc830..0c0d60f2 100644 --- a/src/languageHandler.py +++ b/src/languageHandler.py @@ -1,210 +1,214 @@ -import __builtin__ -import os -import sys -import ctypes -import locale -import gettext -import paths -import platform - -# A fix for the mac locales -#if platform.system() == 'Darwin': - -#a few Windows locale constants -LOCALE_SLANGUAGE=0x2 -LOCALE_SLANGDISPLAYNAME=0x6f - -curLang="en" - -def localeNameToWindowsLCID(localeName): - """Retreave the Windows locale identifier (LCID) for the given locale name - @param localeName: a string of 2letterLanguage_2letterCountry or or just 2letterLanguage - @type localeName: string - @returns: a Windows LCID - @rtype: integer - """ - #Windows Vista is able to convert locale names to LCIDs - func_LocaleNameToLCID=getattr(ctypes.windll.kernel32,'LocaleNameToLCID',None) - if func_LocaleNameToLCID is not None: - localeName=localeName.replace('_','-') - LCID=func_LocaleNameToLCID(unicode(localeName),0) - else: #Windows doesn't have this functionality, manually search Python's windows_locale dictionary for the LCID - localeName=locale.normalize(localeName) - if '.' in localeName: - localeName=localeName.split('.')[0] - LCList=[x[0] for x in locale.windows_locale.iteritems() if x[1]==localeName] - if len(LCList)>0: - LCID=LCList[0] - else: - LCID=0 - return LCID - -def getLanguageDescription(language): - """Finds out the description (localized full name) of a given local name""" - desc=None - if platform.system() == "Windows": - LCID=localeNameToWindowsLCID(language) - if LCID!=0: - buf=ctypes.create_unicode_buffer(1024) - if '_' not in language: - res=ctypes.windll.kernel32.GetLocaleInfoW(LCID,LOCALE_SLANGDISPLAYNAME,buf,1024) - else: - res=0 - if res==0: - res=ctypes.windll.kernel32.GetLocaleInfoW(LCID,LOCALE_SLANGUAGE,buf,1024) - desc=buf.value - elif platform.system() == "Linux" or not desc: - desc={ - "am":pgettext("languageName","Amharic"), - "an":pgettext("languageName","Aragonese"), - "es":pgettext("languageName","Spanish"), - "pt":pgettext("languageName","Portuguese"), - "ru":pgettext("languageName","Russian"), - "it":pgettext("languageName","italian"), - "tr":pgettext("languageName","Turkey"), - "gl":pgettext("languageName","Galician"), - "ca":pgettext("languageName","Catala"), - "eu":pgettext("languageName","Vasque"), - "pl":pgettext("languageName","polish"), - "ar":pgettext("languageName","Arabic"), - "ne":pgettext("languageName","Nepali"), - "sr":pgettext("languageName","Serbian (Latin)"), - "ja":pgettext("languageName","Japanese"), - "ro":pgettext("languageName","Romanian"), - }.get(language,None) - return desc - -def getAvailableLanguages(): - """generates a list of locale names, plus their full localized language and country names. - @rtype: list of tuples - """ - #Make a list of all the locales found in NVDA's locale dir - l=[x for x in os.listdir(paths.locale_path()) if not x.startswith('.')] - l=[x for x in l if os.path.isfile(paths.locale_path('%s/LC_MESSAGES/twblue.mo' % x))] - #Make sure that en (english) is in the list as it may not have any locale files, but is default - if 'en' not in l: - l.append('en') - l.sort() - #For each locale, ask Windows for its human readable display name - d=[] - for i in l: - desc=getLanguageDescription(i) - label="%s, %s"%(desc,i) if desc else i - d.append(label) - #include a 'user default, windows' language, which just represents the default language for this user account - l.append("system") - # Translators: the label for the Windows default NVDA interface language. - d.append(_("User default")) - #return a zipped up version of both the lists (a list with tuples of locale,label) - return zip(l,d) - -def makePgettext(translations): - """Obtaina pgettext function for use with a gettext translations instance. - pgettext is used to support message contexts, - but Python 2.7's gettext module doesn't support this, - so NVDA must provide its own implementation. - """ - if isinstance(translations, gettext.GNUTranslations): - def pgettext(context, message): - message = unicode(message) - try: - # Look up the message with its context. - return translations._catalog[u"%s\x04%s" % (context, message)] - except KeyError: - return message - else: - def pgettext(context, message): - return unicode(message) - return pgettext - -def setLanguage(lang): - system = platform.system() - global curLang - try: - if lang=="system": - if system == "Windows": - windowsLCID=ctypes.windll.kernel32.GetUserDefaultUILanguage() - localeName=locale.windows_locale[windowsLCID] - elif system == "Darwin": - import Foundation - localeName = Foundation.NSLocale.currentLocale().identifier() - elif system == "Linux": - localeName = locale.getdefaultlocale()[0] - trans=gettext.translation('twblue', localedir=paths.locale_path(), languages=[localeName]) - curLang=localeName -# else: -# localeName=locale.getdefaultlocale()[0] -# trans=gettext.translation('twblue', localedir=paths.locale_path(), languages=[localeName]) -# curLang=localeName - - else: - trans=gettext.translation("twblue", localedir=paths.locale_path(), languages=[lang]) - curLang=lang - localeChanged=False - #Try setting Python's locale to lang -# try: - if system == "Windows": - locale.setlocale(locale.LC_ALL, langToWindowsLocale(lang)) - localeChanged=True - else: - locale.setlocale(locale.LC_ALL, lang) - localeChanged=True -# except: -# pass - if not localeChanged and '_' in lang: - #Python couldn'tsupport the language_country locale, just try language. - try: - locale.setlocale(locale.LC_ALL, lang.split('_')[0]) - except: - pass - #Set the windows locale for this thread (NVDA core) to this locale. - if system == "Windows": - LCID=localeNameToWindowsLCID(lang) - ctypes.windll.kernel32.SetThreadLocale(LCID) - except IOError: - trans=gettext.translation("twblue",fallback=True) - curLang="en" - trans.install(unicode=True) - # Install our pgettext function. -# __builtin__.__dict__["pgettext"] = makePgettext(trans) - -def getLanguage(): - return curLang - -def normalizeLanguage(lang): - """ - Normalizes a language-dialect string in to a standard form we can deal with. - Converts any dash to underline, and makes sure that language is lowercase and dialect is upercase. - """ - lang=lang.replace('-','_') - ld=lang.split('_') - ld[0]=ld[0].lower() - #Filter out meta languages such as x-western - if ld[0]=='x': - return None - if len(ld)>=2: - ld[1]=ld[1].upper() - return "_".join(ld) - -def langToWindowsLocale(lang): - languages = {"en": "eng", - "ar": "ara", - "ca": "cat", -"de": "deu", - "es": "esp", - "fi": "fin", - "fr": "fre_FRA", - "gl": "glc", - "eu": "euq", - "hu": "hun", - "hr": "hrv", - "it": "ita", - "ja": "jpn", - "pl": "plk", - "pt": "ptb", - "ro": "rom", - "ru": "rus", - "tr": "trk", - "sr": "eng", - } - return languages[lang] +from future import standard_library +standard_library.install_aliases() +from builtins import zip +from builtins import str +import builtins +import os +import sys +import ctypes +import locale +import gettext +import paths +import platform + +# A fix for the mac locales +#if platform.system() == 'Darwin': + +#a few Windows locale constants +LOCALE_SLANGUAGE=0x2 +LOCALE_SLANGDISPLAYNAME=0x6f + +curLang="en" + +def localeNameToWindowsLCID(localeName): + """Retreave the Windows locale identifier (LCID) for the given locale name + @param localeName: a string of 2letterLanguage_2letterCountry or or just 2letterLanguage + @type localeName: string + @returns: a Windows LCID + @rtype: integer + """ + #Windows Vista is able to convert locale names to LCIDs + func_LocaleNameToLCID=getattr(ctypes.windll.kernel32,'LocaleNameToLCID',None) + if func_LocaleNameToLCID is not None: + localeName=localeName.replace('_','-') + LCID=func_LocaleNameToLCID(str(localeName),0) + else: #Windows doesn't have this functionality, manually search Python's windows_locale dictionary for the LCID + localeName=locale.normalize(localeName) + if '.' in localeName: + localeName=localeName.split('.')[0] + LCList=[x[0] for x in locale.windows_locale.items() if x[1]==localeName] + if len(LCList)>0: + LCID=LCList[0] + else: + LCID=0 + return LCID + +def getLanguageDescription(language): + """Finds out the description (localized full name) of a given local name""" + desc=None + if platform.system() == "Windows": + LCID=localeNameToWindowsLCID(language) + if LCID!=0: + buf=ctypes.create_unicode_buffer(1024) + if '_' not in language: + res=ctypes.windll.kernel32.GetLocaleInfoW(LCID,LOCALE_SLANGDISPLAYNAME,buf,1024) + else: + res=0 + if res==0: + res=ctypes.windll.kernel32.GetLocaleInfoW(LCID,LOCALE_SLANGUAGE,buf,1024) + desc=buf.value + elif platform.system() == "Linux" or not desc: + desc={ + "am":pgettext("languageName","Amharic"), + "an":pgettext("languageName","Aragonese"), + "es":pgettext("languageName","Spanish"), + "pt":pgettext("languageName","Portuguese"), + "ru":pgettext("languageName","Russian"), + "it":pgettext("languageName","italian"), + "tr":pgettext("languageName","Turkey"), + "gl":pgettext("languageName","Galician"), + "ca":pgettext("languageName","Catala"), + "eu":pgettext("languageName","Vasque"), + "pl":pgettext("languageName","polish"), + "ar":pgettext("languageName","Arabic"), + "ne":pgettext("languageName","Nepali"), + "sr":pgettext("languageName","Serbian (Latin)"), + "ja":pgettext("languageName","Japanese"), + "ro":pgettext("languageName","Romanian"), + }.get(language,None) + return desc + +def getAvailableLanguages(): + """generates a list of locale names, plus their full localized language and country names. + @rtype: list of tuples + """ + #Make a list of all the locales found in NVDA's locale dir + l=[x for x in os.listdir(paths.locale_path()) if not x.startswith('.')] + l=[x for x in l if os.path.isfile(paths.locale_path('%s/LC_MESSAGES/twblue.mo' % x))] + #Make sure that en (english) is in the list as it may not have any locale files, but is default + if 'en' not in l: + l.append('en') + l.sort() + #For each locale, ask Windows for its human readable display name + d=[] + for i in l: + desc=getLanguageDescription(i) + label="%s, %s"%(desc,i) if desc else i + d.append(label) + #include a 'user default, windows' language, which just represents the default language for this user account + l.append("system") + # Translators: the label for the Windows default NVDA interface language. + d.append(_("User default")) + #return a zipped up version of both the lists (a list with tuples of locale,label) + return list(zip(l,d)) + +def makePgettext(translations): + """Obtaina pgettext function for use with a gettext translations instance. + pgettext is used to support message contexts, + but Python 2.7's gettext module doesn't support this, + so NVDA must provide its own implementation. + """ + if isinstance(translations, gettext.GNUTranslations): + def pgettext(context, message): + message = str(message) + try: + # Look up the message with its context. + return translations._catalog[u"%s\x04%s" % (context, message)] + except KeyError: + return message + else: + def pgettext(context, message): + return str(message) + return pgettext + +def setLanguage(lang): + system = platform.system() + global curLang + try: + if lang=="system": + if system == "Windows": + windowsLCID=ctypes.windll.kernel32.GetUserDefaultUILanguage() + localeName=locale.windows_locale[windowsLCID] + elif system == "Darwin": + import Foundation + localeName = Foundation.NSLocale.currentLocale().identifier() + elif system == "Linux": + localeName = locale.getdefaultlocale()[0] + trans=gettext.translation('twblue', localedir=paths.locale_path(), languages=[localeName]) + curLang=localeName +# else: +# localeName=locale.getdefaultlocale()[0] +# trans=gettext.translation('twblue', localedir=paths.locale_path(), languages=[localeName]) +# curLang=localeName + + else: + trans=gettext.translation("twblue", localedir=paths.locale_path(), languages=[lang]) + curLang=lang + localeChanged=False + #Try setting Python's locale to lang +# try: + if system == "Windows": + locale.setlocale(locale.LC_ALL, langToWindowsLocale(lang)) + localeChanged=True + else: + locale.setlocale(locale.LC_ALL, lang) + localeChanged=True +# except: +# pass + if not localeChanged and '_' in lang: + #Python couldn'tsupport the language_country locale, just try language. + try: + locale.setlocale(locale.LC_ALL, lang.split('_')[0]) + except: + pass + #Set the windows locale for this thread (NVDA core) to this locale. + if system == "Windows": + LCID=localeNameToWindowsLCID(lang) + ctypes.windll.kernel32.SetThreadLocale(LCID) + except IOError: + trans=gettext.translation("twblue",fallback=True) + curLang="en" + trans.install() + # Install our pgettext function. +# __builtin__.__dict__["pgettext"] = makePgettext(trans) + +def getLanguage(): + return curLang + +def normalizeLanguage(lang): + """ + Normalizes a language-dialect string in to a standard form we can deal with. + Converts any dash to underline, and makes sure that language is lowercase and dialect is upercase. + """ + lang=lang.replace('-','_') + ld=lang.split('_') + ld[0]=ld[0].lower() + #Filter out meta languages such as x-western + if ld[0]=='x': + return None + if len(ld)>=2: + ld[1]=ld[1].upper() + return "_".join(ld) + +def langToWindowsLocale(lang): + languages = {"en": "eng", + "ar": "ara", + "ca": "cat", +"de": "deu", + "es": "esp", + "fi": "fin", + "fr": "fre_FRA", + "gl": "glc", + "eu": "euq", + "hu": "hun", + "hr": "hrv", + "it": "ita", + "ja": "jpn", + "pl": "plk", + "pt": "ptb", + "ro": "rom", + "ru": "rus", + "tr": "trk", + "sr": "eng", + } + return languages[lang] diff --git a/src/libloader/libloader.py b/src/libloader/libloader.py index 174da584..4f3b2d62 100644 --- a/src/libloader/libloader.py +++ b/src/libloader/libloader.py @@ -1,56 +1,57 @@ -import ctypes -import collections -import platform -import os - -TYPES = { - 'Linux': { - 'loader': ctypes.CDLL, - 'functype': ctypes.CFUNCTYPE, - 'prefix': 'lib', - 'extension': '.so' - }, - 'Darwin': { - 'loader': ctypes.CDLL, - 'functype': ctypes.CFUNCTYPE, - 'prefix': 'lib', - 'extension': '.dylib' - }, -} -if platform.system() == 'Windows': - TYPES['Windows'] = { - 'loader': ctypes.WinDLL, - 'functype': ctypes.WINFUNCTYPE, - 'prefix': "", - 'extension': '.dll' - } - -class LibraryLoadError(OSError): pass - -def load_library(library, x86_path='.', x64_path='.', *args, **kwargs): - lib = find_library_path(library, x86_path=x86_path, x64_path=x64_path) - loaded = _do_load(str(lib), *args, **kwargs) - if loaded is not None: - return loaded - raise LibraryLoadError('unable to load %r. Provided library path: %r' % (library, lib)) - -def _do_load(file, *args, **kwargs): - loader = TYPES[platform.system()]['loader'] - return loader(file, *args, **kwargs) - -def find_library_path(libname, x86_path='.', x64_path='.'): - libname = '%s%s' % (TYPES[platform.system()]['prefix'], libname) - if platform.architecture()[0] == '64bit': - path = os.path.join(x64_path, libname) - else: - path = os.path.join(x86_path, libname) - ext = get_library_extension() - path = '%s%s' % (path, ext) - return os.path.abspath(path) - - -def get_functype(): - return TYPES[platform.system()]['functype'] - -def get_library_extension(): - return TYPES[platform.system()]['extension'] +from builtins import str +import ctypes +import collections +import platform +import os + +TYPES = { + 'Linux': { + 'loader': ctypes.CDLL, + 'functype': ctypes.CFUNCTYPE, + 'prefix': 'lib', + 'extension': '.so' + }, + 'Darwin': { + 'loader': ctypes.CDLL, + 'functype': ctypes.CFUNCTYPE, + 'prefix': 'lib', + 'extension': '.dylib' + }, +} +if platform.system() == 'Windows': + TYPES['Windows'] = { + 'loader': ctypes.WinDLL, + 'functype': ctypes.WINFUNCTYPE, + 'prefix': "", + 'extension': '.dll' + } + +class LibraryLoadError(OSError): pass + +def load_library(library, x86_path='.', x64_path='.', *args, **kwargs): + lib = find_library_path(library, x86_path=x86_path, x64_path=x64_path) + loaded = _do_load(str(lib), *args, **kwargs) + if loaded is not None: + return loaded + raise LibraryLoadError('unable to load %r. Provided library path: %r' % (library, lib)) + +def _do_load(file, *args, **kwargs): + loader = TYPES[platform.system()]['loader'] + return loader(file, *args, **kwargs) + +def find_library_path(libname, x86_path='.', x64_path='.'): + libname = '%s%s' % (TYPES[platform.system()]['prefix'], libname) + if platform.architecture()[0] == '64bit': + path = os.path.join(x64_path, libname) + else: + path = os.path.join(x86_path, libname) + ext = get_library_extension() + path = '%s%s' % (path, ext) + return os.path.abspath(path) + + +def get_functype(): + return TYPES[platform.system()]['functype'] + +def get_library_extension(): + return TYPES[platform.system()]['extension'] diff --git a/src/logger.py b/src/logger.py index 4820a28e..d3548600 100644 --- a/src/logger.py +++ b/src/logger.py @@ -9,7 +9,7 @@ ERROR_LOG_FILE = "error.log" MESSAGE_FORMAT = "%(asctime)s %(name)s %(levelname)s: %(message)s" DATE_FORMAT = u"%d/%m/%Y %H:%M:%S" -formatter = logging.Formatter(MESSAGE_FORMAT.decode("utf-8"), datefmt=DATE_FORMAT) +formatter = logging.Formatter(MESSAGE_FORMAT, datefmt=DATE_FORMAT) requests_log = logging.getLogger("requests") requests_log.setLevel(logging.WARNING) diff --git a/src/long_tweets/twishort.py b/src/long_tweets/twishort.py index 57a55ac0..91a4037e 100644 --- a/src/long_tweets/twishort.py +++ b/src/long_tweets/twishort.py @@ -17,6 +17,7 @@ # ############################################################ from __future__ import print_function +from builtins import range import requests import keys import logging @@ -42,7 +43,7 @@ def is_long(tweet): # see https://github.com/manuelcortez/TWBlue/issues/103 except TypeError: pass - if long == False and "retweeted_status" in tweet: + if int == False and "retweeted_status" in tweet: for url in range(0, len(tweet["retweeted_status"]["entities"]["urls"])): try: if tweet["retweeted_status"]["entities"]["urls"][url] != None and "twishort.com" in tweet["retweeted_status"]["entities"]["urls"][url]["expanded_url"]: @@ -51,7 +52,7 @@ def is_long(tweet): pass except TypeError: pass - return long + return int def get_full_text(uri): try: diff --git a/src/multiplatform_widgets/widgets.py b/src/multiplatform_widgets/widgets.py index 2e7d67a2..81174747 100644 --- a/src/multiplatform_widgets/widgets.py +++ b/src/multiplatform_widgets/widgets.py @@ -1,89 +1,92 @@ -# -*- coding: utf-8 -*- -import wx -import platform -import logging -log = logging.getLogger("multiplatform_widgets.widgets") - -class list(object): - def __init__(self, parent, *columns, **listArguments): - self.system = platform.system() - self.columns = columns - self.listArguments = listArguments - log.debug("Creating list: Columns: %s, arguments: %s" % (self.columns, self.listArguments)) - self.create_list(parent) -# self.set_size() - - def set_windows_size(self, column, characters_max): -# it = wx.ListItem() -# dc = wx.WindowDC(self.list) -# dc.SetFont(it.GetFont()) -# (x, y) = dc.GetTextExtent("r"*characters_max) - self.list.SetColumnWidth(column, characters_max*2) - - def set_size(self): - self.list.SetSize((self.list.GetBestSize()[0], 728)) -# self.list.SetSize((1439, 1000)) - - def create_list(self, parent): - if self.system == "Windows": - self.list = wx.ListCtrl(parent, -1, **self.listArguments) - for i in xrange(0, len(self.columns)): - self.list.InsertColumn(i, u"%s" % (self.columns[i])) - else: - self.list = wx.ListBox(parent, -1, choices=[]) - - def insert_item(self, reversed, *item): - """ Inserts an item on the list, depending on the OS.""" - if self.system == "Windows": - if reversed == False: items = self.list.GetItemCount() - else: items = 0 - self.list.InsertItem(items, unicode(item[0])) - for i in xrange(1, len(self.columns)): - self.list.SetItem(items, i, unicode(item[i])) - else: - self.list.Append(" ".join(item)) - - def remove_item(self, pos): - """ Deletes an item from the list.""" - if self.system == "Windows": - if pos > 0: self.list.Focus(pos-1) - self.list.DeleteItem(pos) - else: - if pos > 0: self.list.SetSelection(pos-1) - self.list.Delete(pos) - - def clear(self): - if self.system == "Windows": - self.list.DeleteAllItems() - else: - self.list.Clear() - - def get_selected(self): - if self.system == "Windows": - return self.list.GetFocusedItem() - else: - return self.list.GetSelection() - - def select_item(self, pos): - if self.system == "Windows": - self.list.Focus(pos) - else: - self.list.SetSelection(pos) - - def get_count(self): - if self.system == "Windows": - selected = self.list.GetItemCount() - else: - selected = self.list.GetCount() - if selected == -1: - return 0 - else: - return selected - - def get_text_column(self, indexId, column): - item = self.list.GetItem(indexId, column) - return item.GetText() - - def set_text_column(self, indexId, column, text): - item = self.list.SetItem(indexId, column, unicode(text)) +# -*- coding: utf-8 -*- +from builtins import str +from builtins import range +from builtins import object +import wx +import platform +import logging +log = logging.getLogger("multiplatform_widgets.widgets") + +class list(object): + def __init__(self, parent, *columns, **listArguments): + self.system = platform.system() + self.columns = columns + self.listArguments = listArguments + log.debug("Creating list: Columns: %s, arguments: %s" % (self.columns, self.listArguments)) + self.create_list(parent) +# self.set_size() + + def set_windows_size(self, column, characters_max): +# it = wx.ListItem() +# dc = wx.WindowDC(self.list) +# dc.SetFont(it.GetFont()) +# (x, y) = dc.GetTextExtent("r"*characters_max) + self.list.SetColumnWidth(column, characters_max*2) + + def set_size(self): + self.list.SetSize((self.list.GetBestSize()[0], 728)) +# self.list.SetSize((1439, 1000)) + + def create_list(self, parent): + if self.system == "Windows": + self.list = wx.ListCtrl(parent, -1, **self.listArguments) + for i in range(0, len(self.columns)): + self.list.InsertColumn(i, u"%s" % (self.columns[i])) + else: + self.list = wx.ListBox(parent, -1, choices=[]) + + def insert_item(self, reversed, *item): + """ Inserts an item on the list, depending on the OS.""" + if self.system == "Windows": + if reversed == False: items = self.list.GetItemCount() + else: items = 0 + self.list.InsertItem(items, str(item[0])) + for i in range(1, len(self.columns)): + self.list.SetItem(items, i, str(item[i])) + else: + self.list.Append(" ".join(item)) + + def remove_item(self, pos): + """ Deletes an item from the list.""" + if self.system == "Windows": + if pos > 0: self.list.Focus(pos-1) + self.list.DeleteItem(pos) + else: + if pos > 0: self.list.SetSelection(pos-1) + self.list.Delete(pos) + + def clear(self): + if self.system == "Windows": + self.list.DeleteAllItems() + else: + self.list.Clear() + + def get_selected(self): + if self.system == "Windows": + return self.list.GetFocusedItem() + else: + return self.list.GetSelection() + + def select_item(self, pos): + if self.system == "Windows": + self.list.Focus(pos) + else: + self.list.SetSelection(pos) + + def get_count(self): + if self.system == "Windows": + selected = self.list.GetItemCount() + else: + selected = self.list.GetCount() + if selected == -1: + return 0 + else: + return selected + + def get_text_column(self, indexId, column): + item = self.list.GetItem(indexId, column) + return item.GetText() + + def set_text_column(self, indexId, column, text): + item = self.list.SetItem(indexId, column, str(text)) return item \ No newline at end of file diff --git a/src/mysc/thread_utils.py b/src/mysc/thread_utils.py index 92902a53..491c2696 100644 --- a/src/mysc/thread_utils.py +++ b/src/mysc/thread_utils.py @@ -1,37 +1,39 @@ -# -*- coding: utf-8 -*- -import logging -log = logging.getLogger("mysc.thread_utils") -import threading -import wx -from pubsub import pub -from twython import TwythonRateLimitError -import time - -def call_threaded(func, *args, **kwargs): - #Call the given function in a daemonized thread and return the thread. - def new_func(*a, **k): - try: - func(*a, **k) - except TwythonRateLimitError: - pass - except: - log.exception("Thread %d with function %r, args of %r, and kwargs of %r failed to run." % (threading.current_thread().ident, func, a, k)) -# pass - thread = threading.Thread(target=new_func, args=args, kwargs=kwargs) - thread.daemon = True - thread.start() - return thread - -def stream_threaded(func, *args, **kwargs): - def new_func(*a, **k): - try: - func(**k) - except Exception as msg: - log.error("Error in stream with args: %r" % (a,)) - log.error(msg.message) - pub.sendMessage("stream-error", session=a[0]) - - thread = threading.Thread(target=new_func, args=args, kwargs=kwargs) - thread.daemon = True - thread.start() +# -*- coding: utf-8 -*- +from future import standard_library +standard_library.install_aliases() +import logging +log = logging.getLogger("mysc.thread_utils") +import threading +import wx +from pubsub import pub +from twython import TwythonRateLimitError +import time + +def call_threaded(func, *args, **kwargs): + #Call the given function in a daemonized thread and return the thread. + def new_func(*a, **k): + try: + func(*a, **k) + except TwythonRateLimitError: + pass + except: + log.exception("Thread %d with function %r, args of %r, and kwargs of %r failed to run." % (threading.current_thread().ident, func, a, k)) +# pass + thread = threading.Thread(target=new_func, args=args, kwargs=kwargs) + thread.daemon = True + thread.start() + return thread + +def stream_threaded(func, *args, **kwargs): + def new_func(*a, **k): + try: + func(**k) + except Exception as msg: + log.error("Error in stream with args: %r" % (a,)) + log.error(msg.message) + pub.sendMessage("stream-error", session=a[0]) + + thread = threading.Thread(target=new_func, args=args, kwargs=kwargs) + thread.daemon = True + thread.start() return thread \ No newline at end of file diff --git a/src/notifier/linux.py b/src/notifier/linux.py index 42da5f21..643a95f3 100644 --- a/src/notifier/linux.py +++ b/src/notifier/linux.py @@ -1,25 +1,26 @@ -# -*- coding: utf-8 -*- -import dbus -import application - -class notifications(object): - """Supports notifications on Linux. - """ - - def __init__(self): - super(notifications, self).__init__() - self.item = "org.freedesktop.Notifications" - self.path = "/org/freedesktop/Notifications" - self.interface = "org.freedesktop.Notifications" - self.app_name = application.name - self.id_num_to_replace = 0 - self.icon = "/usr/share/icons/Tango/32x32/status/sunny.png" - - def notify(self, title="", text=""): - actions_list = '' - hint = '' - time = 5000 # Use seconds x 1000 - bus = dbus.SessionBus() - notif = bus.get_object(self.item, self.path) - notify = dbus.Interface(notif, self.interface) +# -*- coding: utf-8 -*- +from builtins import object +import dbus +import application + +class notifications(object): + """Supports notifications on Linux. + """ + + def __init__(self): + super(notifications, self).__init__() + self.item = "org.freedesktop.Notifications" + self.path = "/org/freedesktop/Notifications" + self.interface = "org.freedesktop.Notifications" + self.app_name = application.name + self.id_num_to_replace = 0 + self.icon = "/usr/share/icons/Tango/32x32/status/sunny.png" + + def notify(self, title="", text=""): + actions_list = '' + hint = '' + time = 5000 # Use seconds x 1000 + bus = dbus.SessionBus() + notif = bus.get_object(self.item, self.path) + notify = dbus.Interface(notif, self.interface) notify.Notify(self.app_name, self.id_num_to_replace, self.icon, title, text, actions_list, hint, time) \ No newline at end of file diff --git a/src/notifier/windows.py b/src/notifier/windows.py index 5e1dd320..f5c86d00 100644 --- a/src/notifier/windows.py +++ b/src/notifier/windows.py @@ -1,7 +1,8 @@ -# -*- coding: utf-8 -*- -import wx - -class notification(object): - - def notify(self, title, text): +# -*- coding: utf-8 -*- +from builtins import object +import wx + +class notification(object): + + def notify(self, title, text): wx.NotificationMessage(title, text).Show() \ No newline at end of file diff --git a/src/paths.py b/src/paths.py index 84f3ef13..6ecd4669 100644 --- a/src/paths.py +++ b/src/paths.py @@ -1,85 +1,86 @@ -# -*- coding: utf-8 -*- -import platform -import os -import sys -import logging -from platform_utils import paths as paths_ - -from functools import wraps - -mode = "portable" -directory = None - -log = logging.getLogger("paths") - -def merge_paths(func): - @wraps(func) - def merge_paths_wrapper(*a): - return unicode(os.path.join(func(), *a)) - return merge_paths_wrapper - -@merge_paths -def app_path(): - return paths_.app_path() - -@merge_paths -def config_path(): - global mode, directory - if mode == "portable": - if directory != None: path = os.path.join(directory, "config") - elif directory == None: path = app_path(u"config") - elif mode == "installed": - path = data_path(u"config") - if not os.path.exists(path): - log.debug("%s path does not exist, creating..." % (path,)) - os.mkdir(path) - return path - -@merge_paths -def logs_path(): - global mode, directory - if mode == "portable": - if directory != None: path = os.path.join(directory, "logs") - elif directory == None: path = app_path(u"logs") - elif mode == "installed": - path = data_path(u"logs") - if not os.path.exists(path): - log.debug("%s path does not exist, creating..." % (path,)) - os.mkdir(path) - return path - -@merge_paths -def data_path(app_name='TW blue'): -# if platform.system() == "Windows": -# import shlobj -# data_path = os.path.join(shlobj.SHGetFolderPath(0, shlobj.CSIDL_APPDATA), app_name) -# else: - if platform.system() == "Windows": - import winpaths - data_path = os.path.join(winpaths.get_appdata(), app_name) - else: - data_path = os.path.join(os.environ['HOME'], ".%s" % app_name) - if not os.path.exists(data_path): - os.mkdir(data_path) - return data_path - -@merge_paths -def locale_path(): - return app_path(u"locales") - -@merge_paths -def sound_path(): - return app_path(u"sounds") - -@merge_paths -def com_path(): - global mode, directory - if mode == "portable": - if directory != None: path = os.path.join(directory, "com_cache") - elif directory == None: path = app_path(u"com_cache") - elif mode == "installed": - path = data_path(u"com_cache") - if not os.path.exists(path): - log.debug("%s path does not exist, creating..." % (path,)) - os.mkdir(path) - return path +# -*- coding: utf-8 -*- +from builtins import str +import platform +import os +import sys +import logging +from platform_utils import paths as paths_ + +from functools import wraps + +mode = "portable" +directory = None + +log = logging.getLogger("paths") + +def merge_paths(func): + @wraps(func) + def merge_paths_wrapper(*a): + return str(os.path.join(func(), *a)) + return merge_paths_wrapper + +@merge_paths +def app_path(): + return paths_.app_path() + +@merge_paths +def config_path(): + global mode, directory + if mode == "portable": + if directory != None: path = os.path.join(directory, "config") + elif directory == None: path = app_path(u"config") + elif mode == "installed": + path = data_path(u"config") + if not os.path.exists(path): + log.debug("%s path does not exist, creating..." % (path,)) + os.mkdir(path) + return path + +@merge_paths +def logs_path(): + global mode, directory + if mode == "portable": + if directory != None: path = os.path.join(directory, "logs") + elif directory == None: path = app_path(u"logs") + elif mode == "installed": + path = data_path(u"logs") + if not os.path.exists(path): + log.debug("%s path does not exist, creating..." % (path,)) + os.mkdir(path) + return path + +@merge_paths +def data_path(app_name='TW blue'): +# if platform.system() == "Windows": +# import shlobj +# data_path = os.path.join(shlobj.SHGetFolderPath(0, shlobj.CSIDL_APPDATA), app_name) +# else: + if platform.system() == "Windows": + import winpaths + data_path = os.path.join(winpaths.get_appdata(), app_name) + else: + data_path = os.path.join(os.environ['HOME'], ".%s" % app_name) + if not os.path.exists(data_path): + os.mkdir(data_path) + return data_path + +@merge_paths +def locale_path(): + return app_path(u"locales") + +@merge_paths +def sound_path(): + return app_path(u"sounds") + +@merge_paths +def com_path(): + global mode, directory + if mode == "portable": + if directory != None: path = os.path.join(directory, "com_cache") + elif directory == None: path = app_path(u"com_cache") + elif mode == "installed": + path = data_path(u"com_cache") + if not os.path.exists(path): + log.debug("%s path does not exist, creating..." % (path,)) + os.mkdir(path) + return path diff --git a/src/platform_utils/autostart/windows.py b/src/platform_utils/autostart/windows.py index f4ada511..019eff3f 100644 --- a/src/platform_utils/autostart/windows.py +++ b/src/platform_utils/autostart/windows.py @@ -1,20 +1,21 @@ from __future__ import print_function -import _winreg +from builtins import str +import winreg import os import sys from platform_utils import paths -RUN_REGKEY = ur"SOFTWARE\Microsoft\Windows\CurrentVersion\Run" +RUN_REGKEY = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run" def is_installed(app_subkey): """Checks if the currently running copy is installed or portable variant. Requires the name of the application subkey found under the uninstall section in Windows registry.""" try: - key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s" % app_subkey) - inst_dir = _winreg.QueryValueEx(key,"InstallLocation")[0] + key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s" % app_subkey) + inst_dir = winreg.QueryValueEx(key,"InstallLocation")[0] except WindowsError: return False - _winreg.CloseKey(key) + winreg.CloseKey(key) try: return os.stat(inst_dir) == os.stat(paths.app_path()) except WindowsError: @@ -24,8 +25,8 @@ def getAutoStart(app_name): """Queries if the automatic startup should be set for the application or not, depending on it's current state.""" try: - key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, RUN_REGKEY) - val = _winreg.QueryValueEx(key, unicode(app_name))[0] + key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, RUN_REGKEY) + val = winreg.QueryValueEx(key, str(app_name))[0] return os.stat(val) == os.stat(sys.argv[0]) except (WindowsError, OSError): return False @@ -35,8 +36,8 @@ def setAutoStart(app_name, enable=True): print(paths.get_executable()) if getAutoStart(app_name) == enable: return - key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, RUN_REGKEY, 0, _winreg.KEY_WRITE) + key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, RUN_REGKEY, 0, winreg.KEY_WRITE) if enable: - _winreg.SetValueEx(key, unicode(app_name), None, _winreg.REG_SZ, paths.get_executable()) + winreg.SetValueEx(key, str(app_name), None, winreg.REG_SZ, paths.get_executable()) else: - _winreg.DeleteValue(key, unicode(app_name)) + winreg.DeleteValue(key, str(app_name)) diff --git a/src/platform_utils/blackhole.py b/src/platform_utils/blackhole.py index 7a089b40..70e07446 100644 --- a/src/platform_utils/blackhole.py +++ b/src/platform_utils/blackhole.py @@ -1,16 +1,17 @@ -# Replacement for py2exe distributed module -# Avoids the use of the standard py2exe console. -# Just import this file and it should go away - -import sys -if hasattr(sys,"frozen"): # true only if we are running as a py2exe app - class Blackhole(object): - def write(self,text): - pass - def flush(self): - pass - sys.stdout = Blackhole() - sys.stderr = Blackhole() - del Blackhole - del sys - +# Replacement for py2exe distributed module +# Avoids the use of the standard py2exe console. +# Just import this file and it should go away + +from builtins import object +import sys +if hasattr(sys,"frozen"): # true only if we are running as a py2exe app + class Blackhole(object): + def write(self,text): + pass + def flush(self): + pass + sys.stdout = Blackhole() + sys.stderr = Blackhole() + del Blackhole + del sys + diff --git a/src/platform_utils/paths.py b/src/platform_utils/paths.py index 912e28af..a132a188 100644 --- a/src/platform_utils/paths.py +++ b/src/platform_utils/paths.py @@ -1,114 +1,115 @@ -import inspect -import platform -import os -import subprocess -import sys -import string -import unicodedata - - -def app_data_path(app_name=None): - """Cross-platform method for determining where to put application data.""" - """Requires the name of the application""" - plat = platform.system() - if plat == 'Windows': - import winpaths - path = winpaths.get_appdata() - elif plat == 'Darwin': - path = os.path.join(os.path.expanduser('~'), 'Library', 'Application Support') - elif plat == 'Linux': - path = os.path.expanduser('~') - app_name = '.%s' % app_name.replace(' ', '_') - return os.path.join(path, app_name) - -def prepare_app_data_path(app_name): - """Creates the application's data directory, given its name.""" - dir = app_data_path(app_name) - return ensure_path(dir) - -def embedded_data_path(): - if platform.system() == 'Darwin' and is_frozen(): - return os.path.abspath(os.path.join(executable_directory(), '..', 'Resources')) - return app_path() - -def is_frozen(): - """Return a bool indicating if application is compressed""" - import imp - return hasattr(sys, 'frozen') or imp.is_frozen("__main__") - -def get_executable(): - """Returns the full executable path/name if frozen, or the full path/name of the main module if not.""" - if is_frozen(): - if platform.system() != 'Darwin': - return sys.executable -#On darwin, sys.executable points to python. We want the full path to the exe we ran. - exedir = os.path.abspath(os.path.dirname(sys.executable)) - items = os.listdir(exedir) - items.remove('python') - return os.path.join(exedir, items[0]) - #Not frozen - try: - import __main__ - return os.path.abspath(__main__.__file__) - except AttributeError: - return sys.argv[0] - -def get_module(level=2): - """Hacky method for deriving the caller of this function's module.""" - return inspect.getmodule(inspect.stack()[level][0]).__file__ - -def executable_directory(): - """Always determine the directory of the executable, even when run with py2exe or otherwise frozen""" - executable = get_executable() - path = os.path.abspath(os.path.dirname(executable)) - return path - -def app_path(): - """Return the root of the application's directory""" - path = executable_directory() - if is_frozen() and platform.system() == 'Darwin': - path = os.path.abspath(os.path.join(path, '..', '..')) - return path - -def module_path(level=2): - return os.path.abspath(os.path.dirname(get_module(level))) - -def documents_path(): - """On windows, returns the path to My Documents. On OSX, returns the user's Documents folder. For anything else, returns the user's home directory.""" - plat = platform.system() - if plat == 'Windows': - import winpaths - path = winpaths.get_my_documents() - elif plat == 'Darwin': - path = os.path.join(os.path.expanduser('~'), 'Documents') - else: - path = os.path.expanduser('~') - return path - -def safe_filename(filename): - """Given a filename, returns a safe version with no characters that would not work on different platforms.""" - SAFE_FILE_CHARS = "'-_.()[]{}!@#$%^&+=`~ " - filename = unicode(filename) - new_filename = ''.join(c for c in filename if c in SAFE_FILE_CHARS or c.isalnum()) - #Windows doesn't like directory names ending in space, macs consider filenames beginning with a dot as hidden, and windows removes dots at the ends of filenames. - return new_filename.strip(' .') - -def ensure_path(path): - if not os.path.exists(path): - os.makedirs(path) - return path - -def start_file(path): - if platform.system() == 'Windows': - os.startfile(path) - else: - subprocess.Popen(['open', path]) - -def get_applications_path(): - """Return the directory where applications are commonly installed on the system.""" - plat = platform.system() - if plat == 'Windows': - import winpaths - return winpaths.get_program_files() - elif plat == 'Darwin': - return '/Applications' +from builtins import str +import inspect +import platform +import os +import subprocess +import sys +import string +import unicodedata + + +def app_data_path(app_name=None): + """Cross-platform method for determining where to put application data.""" + """Requires the name of the application""" + plat = platform.system() + if plat == 'Windows': + import winpaths + path = winpaths.get_appdata() + elif plat == 'Darwin': + path = os.path.join(os.path.expanduser('~'), 'Library', 'Application Support') + elif plat == 'Linux': + path = os.path.expanduser('~') + app_name = '.%s' % app_name.replace(' ', '_') + return os.path.join(path, app_name) + +def prepare_app_data_path(app_name): + """Creates the application's data directory, given its name.""" + dir = app_data_path(app_name) + return ensure_path(dir) + +def embedded_data_path(): + if platform.system() == 'Darwin' and is_frozen(): + return os.path.abspath(os.path.join(executable_directory(), '..', 'Resources')) + return app_path() + +def is_frozen(): + """Return a bool indicating if application is compressed""" + import imp + return hasattr(sys, 'frozen') or imp.is_frozen("__main__") + +def get_executable(): + """Returns the full executable path/name if frozen, or the full path/name of the main module if not.""" + if is_frozen(): + if platform.system() != 'Darwin': + return sys.executable +#On darwin, sys.executable points to python. We want the full path to the exe we ran. + exedir = os.path.abspath(os.path.dirname(sys.executable)) + items = os.listdir(exedir) + items.remove('python') + return os.path.join(exedir, items[0]) + #Not frozen + try: + import __main__ + return os.path.abspath(__main__.__file__) + except AttributeError: + return sys.argv[0] + +def get_module(level=2): + """Hacky method for deriving the caller of this function's module.""" + return inspect.getmodule(inspect.stack()[level][0]).__file__ + +def executable_directory(): + """Always determine the directory of the executable, even when run with py2exe or otherwise frozen""" + executable = get_executable() + path = os.path.abspath(os.path.dirname(executable)) + return path + +def app_path(): + """Return the root of the application's directory""" + path = executable_directory() + if is_frozen() and platform.system() == 'Darwin': + path = os.path.abspath(os.path.join(path, '..', '..')) + return path + +def module_path(level=2): + return os.path.abspath(os.path.dirname(get_module(level))) + +def documents_path(): + """On windows, returns the path to My Documents. On OSX, returns the user's Documents folder. For anything else, returns the user's home directory.""" + plat = platform.system() + if plat == 'Windows': + import winpaths + path = winpaths.get_my_documents() + elif plat == 'Darwin': + path = os.path.join(os.path.expanduser('~'), 'Documents') + else: + path = os.path.expanduser('~') + return path + +def safe_filename(filename): + """Given a filename, returns a safe version with no characters that would not work on different platforms.""" + SAFE_FILE_CHARS = "'-_.()[]{}!@#$%^&+=`~ " + filename = str(filename) + new_filename = ''.join(c for c in filename if c in SAFE_FILE_CHARS or c.isalnum()) + #Windows doesn't like directory names ending in space, macs consider filenames beginning with a dot as hidden, and windows removes dots at the ends of filenames. + return new_filename.strip(' .') + +def ensure_path(path): + if not os.path.exists(path): + os.makedirs(path) + return path + +def start_file(path): + if platform.system() == 'Windows': + os.startfile(path) + else: + subprocess.Popen(['open', path]) + +def get_applications_path(): + """Return the directory where applications are commonly installed on the system.""" + plat = platform.system() + if plat == 'Windows': + import winpaths + return winpaths.get_program_files() + elif plat == 'Darwin': + return '/Applications' diff --git a/src/platform_utils/shell_integration/windows.py b/src/platform_utils/shell_integration/windows.py index b25a1250..fc124f63 100644 --- a/src/platform_utils/shell_integration/windows.py +++ b/src/platform_utils/shell_integration/windows.py @@ -1,10 +1,12 @@ -import _winreg - -SHELL_REGKEY = ur"Directory\shell" - -def context_menu_integrate(item_key_name, item_display_text, item_command): - app_menu_key = _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, SHELL_REGKEY, 0, _winreg.KEY_WRITE) - menu_item_key = _winreg.CreateKey(app_menu_key, item_key_name) - _winreg.SetValueEx(menu_item_key, None, None, _winreg.REG_SZ, item_display_text) - item_command_key = _winreg.CreateKey(menu_item_key, 'command') - _winreg.SetValueEx(item_command_key, None, None, _winreg.REG_SZ, item_command) +from future import standard_library +standard_library.install_aliases() +import winreg + +SHELL_REGKEY = ur"Directory\shell" + +def context_menu_integrate(item_key_name, item_display_text, item_command): + app_menu_key = winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, SHELL_REGKEY, 0, winreg.KEY_WRITE) + menu_item_key = winreg.CreateKey(app_menu_key, item_key_name) + winreg.SetValueEx(menu_item_key, None, None, winreg.REG_SZ, item_display_text) + item_command_key = winreg.CreateKey(menu_item_key, 'command') + winreg.SetValueEx(item_command_key, None, None, winreg.REG_SZ, item_command) diff --git a/src/pocket_utils/authorisationHandler.py b/src/pocket_utils/authorisationHandler.py index 1dd25984..bd5ff908 100644 --- a/src/pocket_utils/authorisationHandler.py +++ b/src/pocket_utils/authorisationHandler.py @@ -1,15 +1,17 @@ -# -*- coding: utf-8 -*- -import BaseHTTPServer, application - -logged = False - -class handler(BaseHTTPServer.BaseHTTPRequestHandler): - - def do_GET(self): - global logged - self.send_response(200) - self.send_header("Content-type", "text/html") - self.end_headers() - logged = True - self.wfile.write("You have successfully logged into Pocket with" + application.name + ". " +# -*- coding: utf-8 -*- +from future import standard_library +standard_library.install_aliases() +import http.server, application + +logged = False + +class handler(http.server.BaseHTTPRequestHandler): + + def do_GET(self): + global logged + self.send_response(200) + self.send_header("Content-type", "text/html") + self.end_headers() + logged = True + self.wfile.write("You have successfully logged into Pocket with" + application.name + ". " "You can close this window now.") \ No newline at end of file diff --git a/src/sessionmanager/manager.py b/src/sessionmanager/manager.py index 58d54d06..0a626914 100644 --- a/src/sessionmanager/manager.py +++ b/src/sessionmanager/manager.py @@ -1,6 +1,7 @@ # -*- coding: cp1252 -*- #from config_utils import Configuration, ConfigurationResetException from __future__ import absolute_import +from builtins import object import config import paths import os diff --git a/src/sessionmanager/session.py b/src/sessionmanager/session.py index 5b376800..b69f9f89 100644 --- a/src/sessionmanager/session.py +++ b/src/sessionmanager/session.py @@ -1,7 +1,12 @@ # -*- coding: utf-8 -*- """ The main session object. Here are the twitter functions to interact with the "model" of TWBlue.""" from __future__ import absolute_import -import urllib2 +from future import standard_library +standard_library.install_aliases() +from builtins import str +from builtins import range +from builtins import object +import urllib.request, urllib.error, urllib.parse import config import twitter from keys import keyring @@ -408,8 +413,8 @@ class Session(object): if not os.path.exists(shelfname): output.speak("Generating database, this might take a while.",True) shelf=shelve.open(paths.config_path(shelfname),'c') - for key,value in self.db.items(): - if type(key) != str and type(key) != unicode: + for key,value in list(self.db.items()): + if type(key) != str and type(key) != str: output.speak("Uh oh, while shelving the database, a key of type " + str(type(key)) + " has been found. It will be converted to type str, but this will cause all sorts of problems on deshelve. Please bring this to the attention of the " + application.name + " developers immediately. More information about the error will be written to the error log.",True) log.error("Uh oh, " + str(key) + " is of type " + str(type(key)) + "!") # Convert unicode objects to UTF-8 strings before shelve these objects. @@ -432,7 +437,7 @@ class Session(object): return try: shelf=shelve.open(paths.config_path(shelfname),'c') - for key,value in shelf.items(): + for key,value in list(shelf.items()): self.db[key]=value shelf.close() except: @@ -471,8 +476,8 @@ class Session(object): def check_long_tweet(self, tweet): long = twishort.is_long(tweet) - if long != False and config.app["app-settings"]["handle_longtweets"]: - tweet["message"] = twishort.get_full_text(long) + if int != False and config.app["app-settings"]["handle_longtweets"]: + tweet["message"] = twishort.get_full_text(int) if tweet["message"] == False: return False tweet["twishort"] = True for i in tweet["entities"]["user_mentions"]: diff --git a/src/sessionmanager/sessionManager.py b/src/sessionmanager/sessionManager.py index f2830fbc..e9537673 100644 --- a/src/sessionmanager/sessionManager.py +++ b/src/sessionmanager/sessionManager.py @@ -1,5 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import +from builtins import str +from builtins import object import shutil import widgetUtils import platform diff --git a/src/sessionmanager/session_exceptions.py b/src/sessionmanager/session_exceptions.py index fd7cfc79..84545e81 100644 --- a/src/sessionmanager/session_exceptions.py +++ b/src/sessionmanager/session_exceptions.py @@ -1,9 +1,8 @@ # -*- coding: cp1252 -*- -import exceptions -class InvalidSessionError(exceptions.Exception): pass -class NonExistentSessionError(exceptions.Exception): pass -class NotLoggedSessionError(exceptions.BaseException): pass -class NotConfiguredSessionError(exceptions.BaseException): pass -class RequireCredentialsSessionError(exceptions.BaseException): pass -class AlreadyAuthorisedError(exceptions.BaseException): pass \ No newline at end of file +class InvalidSessionError(Exception): pass +class NonExistentSessionError(Exception): pass +class NotLoggedSessionError(BaseException): pass +class NotConfiguredSessionError(BaseException): pass +class RequireCredentialsSessionError(BaseException): pass +class AlreadyAuthorisedError(BaseException): pass \ No newline at end of file diff --git a/src/sound.py b/src/sound.py index f6f771b5..2c6e661c 100644 --- a/src/sound.py +++ b/src/sound.py @@ -1,176 +1,178 @@ -# -*- coding: utf-8 -*- -import sys -import url_shortener -import audio_services -import os -import logging as original_logger -log = original_logger.getLogger("sound") -import paths -from sound_lib.output import Output -from sound_lib.input import Input -from sound_lib.recording import WaveRecording -from sound_lib.stream import FileStream -from sound_lib.stream import URLStream as SoundlibURLStream -import subprocess -import platform -import output -system = platform.system() -from mysc.repeating_timer import RepeatingTimer -from mysc.thread_utils import call_threaded -import application -import tempfile -import glob -URLPlayer = None - -def setup(): - global URLPlayer - if not URLPlayer: - log.debug("creating stream URL player...") - URLPlayer = URLStream() - -def recode_audio(filename, quality=4.5): - global system - if system == "Windows": subprocess.call(r'"%s" -q %r "%s"' % (paths.app_path('oggenc2.exe'), quality, filename)) - -def recording(filename): -# try: - val = WaveRecording(filename=filename) -# except sound_lib.main.BassError: -# sound_lib.input.Input() -# val = sound_lib.recording.WaveRecording(filename=filename) - return val - -class soundSystem(object): - - def check_soundpack(self): - """ Checks if the folder where live the current soundpack exists.""" - self.soundpack_OK = False - if os.path.exists(paths.sound_path(self.config["current_soundpack"])): - self.path = paths.sound_path(self.config["current_soundpack"]) - self.soundpack_OK = True - elif os.path.exists(paths.sound_path("default")): - log.error("The soundpack does not exist, using default...") - self.path = paths.sound_path("default") - self.soundpack_OK = True - else: - log.error("The current soundpack could not be found and the default soundpack has been deleted, " + application.name + " will not play sounds.") - self.soundpack_OK = False - - def __init__(self, soundConfig): - """ Sound Player.""" - self.config = soundConfig - # Set the output and input default devices. - try: - self.output = Output() - self.input = Input() - except IOError: - pass - # Try to use the selected device from the configuration. It can fail if the machine does not has a mic. - try: - log.debug("Setting input and output devices...") - self.output.set_device(self.output.find_device_by_name(self.config["output_device"])) - self.input.set_device(self.input.find_device_by_name(self.config["input_device"])) - except: - log.exception("Error in input or output devices, using defaults...") - self.config["output_device"] = "Default" - self.config["input_device"] = "Default" - - self.files = [] - self.cleaner = RepeatingTimer(60, self.clear_list) - self.cleaner.start() - self.check_soundpack() - - def clear_list(self): - if len(self.files) == 0: return - try: - for i in range(0, len(self.files)): - if self.files[i].is_playing == False: - self.files[i].free() - self.files.pop(i) - except IndexError: - pass - - def play(self, sound, argument=False): - if self.soundpack_OK == False: return - if self.config["session_mute"] == True: return - sound_object = FileStream(file="%s/%s" % (self.path, sound)) - sound_object.volume = float(self.config["volume"]) - self.files.append(sound_object) - sound_object.play() - -class URLStream(object): - def __init__(self,url=None): - self.url = url - self.prepared = False - log.debug("URL Player initialized") - - def prepare(self, url): - log.debug("Preparing URL: %s" % (url,)) - self.prepared = False - self.url = url_shortener.unshorten(url) - log.debug("Expanded URL: %s" % (self.url,)) - if self.url != None: - transformer = audio_services.find_url_transformer(self.url) - self.url = transformer(self.url) - log.debug("Transformed URL: %s. Prepared" % (self.url,)) - self.prepared = True - else: - self.url = url - log.debug("Transformed URL: %s. Prepared" % (self.url,)) - self.prepared = True - - - def seek(self,step): - pos=self.stream.get_position() - pos=self.stream.bytes_to_seconds(pos) - pos+=step - pos=self.stream.seconds_to_bytes(pos) - if pos<0: - pos=0 - self.stream.set_position(pos) - - def playpause(self): - if self.stream.is_playing==True: - self.stream.pause() - else: - self.stream.play() - - def play(self, url=None, volume=1.0, stream=None,announce=True): - if announce: - output.speak(_(u"Playing...")) - log.debug("Attempting to play an URL...") - if url != None: - self.prepare(url) - elif stream != None: - self.stream=stream - if self.prepared == True: - self.stream = SoundlibURLStream(url=self.url) - if hasattr(self,'stream'): - self.stream.volume = float(volume) - self.stream.play() - log.debug("played") -# call_threaded(self.delete_when_done) - - def stop_audio(self,delete=False): - if hasattr(self, "stream"): - output.speak(_(u"Stopped."), True) - try: - self.stream.stop() - log.debug("Stopped audio stream.") - except: - log.exception("Exception while stopping stream.") - if delete: - del self.stream - log.debug("Deleted audio stream.") - return True - else: - return False - - @staticmethod - def delete_old_tempfiles(): - for f in glob(os.path.join(tempfile.gettempdir(), 'tmp*.wav')): - try: - os.remove(f) - except: - pass - +# -*- coding: utf-8 -*- +from builtins import range +from builtins import object +import sys +import url_shortener +import audio_services +import os +import logging as original_logger +log = original_logger.getLogger("sound") +import paths +from sound_lib.output import Output +from sound_lib.input import Input +from sound_lib.recording import WaveRecording +from sound_lib.stream import FileStream +from sound_lib.stream import URLStream as SoundlibURLStream +import subprocess +import platform +import output +system = platform.system() +from mysc.repeating_timer import RepeatingTimer +from mysc.thread_utils import call_threaded +import application +import tempfile +import glob +URLPlayer = None + +def setup(): + global URLPlayer + if not URLPlayer: + log.debug("creating stream URL player...") + URLPlayer = URLStream() + +def recode_audio(filename, quality=4.5): + global system + if system == "Windows": subprocess.call(r'"%s" -q %r "%s"' % (paths.app_path('oggenc2.exe'), quality, filename)) + +def recording(filename): +# try: + val = WaveRecording(filename=filename) +# except sound_lib.main.BassError: +# sound_lib.input.Input() +# val = sound_lib.recording.WaveRecording(filename=filename) + return val + +class soundSystem(object): + + def check_soundpack(self): + """ Checks if the folder where live the current soundpack exists.""" + self.soundpack_OK = False + if os.path.exists(paths.sound_path(self.config["current_soundpack"])): + self.path = paths.sound_path(self.config["current_soundpack"]) + self.soundpack_OK = True + elif os.path.exists(paths.sound_path("default")): + log.error("The soundpack does not exist, using default...") + self.path = paths.sound_path("default") + self.soundpack_OK = True + else: + log.error("The current soundpack could not be found and the default soundpack has been deleted, " + application.name + " will not play sounds.") + self.soundpack_OK = False + + def __init__(self, soundConfig): + """ Sound Player.""" + self.config = soundConfig + # Set the output and input default devices. + try: + self.output = Output() + self.input = Input() + except IOError: + pass + # Try to use the selected device from the configuration. It can fail if the machine does not has a mic. + try: + log.debug("Setting input and output devices...") + self.output.set_device(self.output.find_device_by_name(self.config["output_device"])) + self.input.set_device(self.input.find_device_by_name(self.config["input_device"])) + except: + log.exception("Error in input or output devices, using defaults...") + self.config["output_device"] = "Default" + self.config["input_device"] = "Default" + + self.files = [] + self.cleaner = RepeatingTimer(60, self.clear_list) + self.cleaner.start() + self.check_soundpack() + + def clear_list(self): + if len(self.files) == 0: return + try: + for i in range(0, len(self.files)): + if self.files[i].is_playing == False: + self.files[i].free() + self.files.pop(i) + except IndexError: + pass + + def play(self, sound, argument=False): + if self.soundpack_OK == False: return + if self.config["session_mute"] == True: return + sound_object = FileStream(file="%s/%s" % (self.path, sound)) + sound_object.volume = float(self.config["volume"]) + self.files.append(sound_object) + sound_object.play() + +class URLStream(object): + def __init__(self,url=None): + self.url = url + self.prepared = False + log.debug("URL Player initialized") + + def prepare(self, url): + log.debug("Preparing URL: %s" % (url,)) + self.prepared = False + self.url = url_shortener.unshorten(url) + log.debug("Expanded URL: %s" % (self.url,)) + if self.url != None: + transformer = audio_services.find_url_transformer(self.url) + self.url = transformer(self.url) + log.debug("Transformed URL: %s. Prepared" % (self.url,)) + self.prepared = True + else: + self.url = url + log.debug("Transformed URL: %s. Prepared" % (self.url,)) + self.prepared = True + + + def seek(self,step): + pos=self.stream.get_position() + pos=self.stream.bytes_to_seconds(pos) + pos+=step + pos=self.stream.seconds_to_bytes(pos) + if pos<0: + pos=0 + self.stream.set_position(pos) + + def playpause(self): + if self.stream.is_playing==True: + self.stream.pause() + else: + self.stream.play() + + def play(self, url=None, volume=1.0, stream=None,announce=True): + if announce: + output.speak(_(u"Playing...")) + log.debug("Attempting to play an URL...") + if url != None: + self.prepare(url) + elif stream != None: + self.stream=stream + if self.prepared == True: + self.stream = SoundlibURLStream(url=self.url) + if hasattr(self,'stream'): + self.stream.volume = float(volume) + self.stream.play() + log.debug("played") +# call_threaded(self.delete_when_done) + + def stop_audio(self,delete=False): + if hasattr(self, "stream"): + output.speak(_(u"Stopped."), True) + try: + self.stream.stop() + log.debug("Stopped audio stream.") + except: + log.exception("Exception while stopping stream.") + if delete: + del self.stream + log.debug("Deleted audio stream.") + return True + else: + return False + + @staticmethod + def delete_old_tempfiles(): + for f in glob(os.path.join(tempfile.gettempdir(), 'tmp*.wav')): + try: + os.remove(f) + except: + pass + diff --git a/src/twitter/authorisationHandler.py b/src/twitter/authorisationHandler.py index e7cc668a..389e1176 100644 --- a/src/twitter/authorisationHandler.py +++ b/src/twitter/authorisationHandler.py @@ -1,21 +1,23 @@ -# -*- coding: utf-8 -*- -import BaseHTTPServer -import application -from urlparse import urlparse, parse_qs - -logged = False -verifier = None - -class handler(BaseHTTPServer.BaseHTTPRequestHandler): - - def do_GET(self): - global logged - self.send_response(200) - self.send_header("Content-type", "text/html") - self.end_headers() - logged = True - params = parse_qs(urlparse(self.path).query) - global verifier - verifier = params.get('oauth_verifier', [None])[0] - self.wfile.write(u"You have successfully logged into Twitter with {0}. You can close this window now.".format(application.name)) - self.finish() +# -*- coding: utf-8 -*- +from future import standard_library +standard_library.install_aliases() +import http.server +import application +from urllib.parse import urlparse, parse_qs + +logged = False +verifier = None + +class handler(http.server.BaseHTTPRequestHandler): + + def do_GET(self): + global logged + self.send_response(200) + self.send_header("Content-type", "text/html") + self.end_headers() + logged = True + params = parse_qs(urlparse(self.path).query) + global verifier + verifier = params.get('oauth_verifier', [None])[0] + self.wfile.write(u"You have successfully logged into Twitter with {0}. You can close this window now.".format(application.name)) + self.finish() diff --git a/src/twitter/buffers/stream.py b/src/twitter/buffers/stream.py index e7b37ba1..86798ae1 100644 --- a/src/twitter/buffers/stream.py +++ b/src/twitter/buffers/stream.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +from builtins import str import config from requests.auth import HTTPProxyAuth from twitter import utils diff --git a/src/twitter/compose.py b/src/twitter/compose.py index 91da76ab..b8d4b3f0 100644 --- a/src/twitter/compose.py +++ b/src/twitter/compose.py @@ -1,10 +1,15 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import +from future import standard_library +standard_library.install_aliases() +from builtins import str +from builtins import chr +from builtins import range import platform system = platform.system() from . import utils import re -import htmlentitydefs +import html.entities import time import output import languageHandler @@ -22,10 +27,10 @@ def StripChars(s): If we match &blah; and it's not found, &blah; will be returned. if we match #\d+, unichr(digits) will be returned. Else, a unicode string will be returned.""" - if match.group(1).startswith('#'): return unichr(int(match.group(1)[1:])) - replacement = htmlentitydefs.entitydefs.get(match.group(1), "&%s;" % match.group(1)) + if match.group(1).startswith('#'): return chr(int(match.group(1)[1:])) + replacement = html.entities.entitydefs.get(match.group(1), "&%s;" % match.group(1)) return replacement.decode('iso-8859-1') - return unicode(entity_re.sub(matchFunc, s)) + return str(entity_re.sub(matchFunc, s)) chars = "abcdefghijklmnopqrstuvwxyz" diff --git a/src/twitter/twitter.py b/src/twitter/twitter.py index 94c7d053..ab0740bd 100644 --- a/src/twitter/twitter.py +++ b/src/twitter/twitter.py @@ -1,8 +1,11 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import +from future import standard_library +standard_library.install_aliases() +from builtins import object import config import random -import BaseHTTPServer +import http.server import webbrowser from twython import Twython, TwythonError from keys import keyring @@ -21,7 +24,7 @@ class twitter(object): def authorise(self, settings): authorisationHandler.logged = False port = random.randint(30000, 65535) - httpd = BaseHTTPServer.HTTPServer(('127.0.0.1', port), authorisationHandler.handler) + httpd = http.server.HTTPServer(('127.0.0.1', port), authorisationHandler.handler) twitter = Twython(keyring.get("api_key"), keyring.get("api_secret"), auth_endpoint='authorize') auth = twitter.get_authentication_tokens("http://127.0.0.1:{0}".format(port,)) webbrowser.open_new_tab(auth['auth_url']) diff --git a/src/twitter/utils.py b/src/twitter/utils.py index 9299e96e..0d24332f 100644 --- a/src/twitter/utils.py +++ b/src/twitter/utils.py @@ -1,5 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import print_function +from builtins import str +from builtins import range import url_shortener, re import output from twython import TwythonError diff --git a/src/update/utils.py b/src/update/utils.py index 9a20ab26..42ee7f4a 100644 --- a/src/update/utils.py +++ b/src/update/utils.py @@ -1,42 +1,45 @@ -# -*- coding: utf-8 -*- - -def convert_bytes(n): - K, M, G, T, P = 1 << 10, 1 << 20, 1 << 30, 1 << 40, 1 << 50 - if n >= P: - return '%.2fPb' % (float(n) / T) - elif n >= T: - return '%.2fTb' % (float(n) / T) - elif n >= G: - return '%.2fGb' % (float(n) / G) - elif n >= M: - return '%.2fMb' % (float(n) / M) - elif n >= K: - return '%.2fKb' % (float(n) / K) - else: - return '%d' % n - -def seconds_to_string(seconds, precision=0): - day = seconds // 86400 - hour = seconds // 3600 - min = (seconds // 60) % 60 - sec = seconds - (hour * 3600) - (min * 60) - sec_spec = "." + str(precision) + "f" - sec_string = sec.__format__(sec_spec) - string = "" - if day == 1: - string += _(u"%d day, ") % day - elif day >= 2: - string += _(u"%d days, ") % day - if (hour == 1): - string += _(u"%d hour, ") % hour - elif (hour >= 2): - string += _("%d hours, ") % hour - if (min == 1): - string += _(u"%d minute, ") % min - elif (min >= 2): - string += _(u"%d minutes, ") % min - if sec >= 0 and sec <= 2: - string += _(u"%s second") % sec_string - else: - string += _(u"%s seconds") % sec_string +# -*- coding: utf-8 -*- + +from __future__ import division +from builtins import str +from past.utils import old_div +def convert_bytes(n): + K, M, G, T, P = 1 << 10, 1 << 20, 1 << 30, 1 << 40, 1 << 50 + if n >= P: + return '%.2fPb' % (old_div(float(n), T)) + elif n >= T: + return '%.2fTb' % (old_div(float(n), T)) + elif n >= G: + return '%.2fGb' % (old_div(float(n), G)) + elif n >= M: + return '%.2fMb' % (old_div(float(n), M)) + elif n >= K: + return '%.2fKb' % (old_div(float(n), K)) + else: + return '%d' % n + +def seconds_to_string(seconds, precision=0): + day = seconds // 86400 + hour = seconds // 3600 + min = (seconds // 60) % 60 + sec = seconds - (hour * 3600) - (min * 60) + sec_spec = "." + str(precision) + "f" + sec_string = sec.__format__(sec_spec) + string = "" + if day == 1: + string += _(u"%d day, ") % day + elif day >= 2: + string += _(u"%d days, ") % day + if (hour == 1): + string += _(u"%d hour, ") % hour + elif (hour >= 2): + string += _("%d hours, ") % hour + if (min == 1): + string += _(u"%d minute, ") % min + elif (min >= 2): + string += _(u"%d minutes, ") % min + if sec >= 0 and sec <= 2: + string += _(u"%s second") % sec_string + else: + string += _(u"%s seconds") % sec_string return string \ No newline at end of file diff --git a/src/update/wxUpdater.py b/src/update/wxUpdater.py index c9e05c58..3cd20d87 100644 --- a/src/update/wxUpdater.py +++ b/src/update/wxUpdater.py @@ -1,5 +1,8 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import +from __future__ import division +from builtins import str +from past.utils import old_div import wx import application from . import utils @@ -25,7 +28,7 @@ def progress_callback(total_downloaded, total_size): if total_downloaded == total_size: progress_dialog.Destroy() else: - progress_dialog.Update((total_downloaded*100)/total_size, _(u"Updating... %s of %s") % (str(utils.convert_bytes(total_downloaded)), str(utils.convert_bytes(total_size)))) + progress_dialog.Update(old_div((total_downloaded*100),total_size), _(u"Updating... %s of %s") % (str(utils.convert_bytes(total_downloaded)), str(utils.convert_bytes(total_size)))) def update_finished(): ms = wx.MessageDialog(None, _(u"The update has been downloaded and installed successfully. Press OK to continue."), _(u"Done!")).ShowModal() \ No newline at end of file diff --git a/src/url_shortener/shorteners/clckru.py b/src/url_shortener/shorteners/clckru.py index efc18023..131f934b 100644 --- a/src/url_shortener/shorteners/clckru.py +++ b/src/url_shortener/shorteners/clckru.py @@ -1,5 +1,7 @@ from __future__ import absolute_import -import urllib +from future import standard_library +standard_library.install_aliases() +import urllib.request, urllib.parse, urllib.error from .url_shortener import URLShortener @@ -11,7 +13,7 @@ class ClckruShortener (URLShortener): def _shorten (self, url): answer = url - api = urllib.urlopen ("http://clck.ru/--?url=" + urllib.quote(url)) + api = urllib.request.urlopen ("http://clck.ru/--?url=" + urllib.parse.quote(url)) if api.getcode() == 200: answer = api.read() api.close() diff --git a/src/url_shortener/shorteners/hkcim.py b/src/url_shortener/shorteners/hkcim.py index 2b45dc18..2f984cf4 100644 --- a/src/url_shortener/shorteners/hkcim.py +++ b/src/url_shortener/shorteners/hkcim.py @@ -1,5 +1,7 @@ from __future__ import absolute_import -import urllib +from future import standard_library +standard_library.install_aliases() +import urllib.request, urllib.parse, urllib.error from .url_shortener import URLShortener @@ -10,7 +12,7 @@ class HKCShortener (URLShortener): def _shorten (self, url): answer = url - api = urllib.urlopen ("http://hkc.im/yourls-api.php?action=shorturl&format=simple&url=" + urllib.quote(url)) + api = urllib.request.urlopen ("http://hkc.im/yourls-api.php?action=shorturl&format=simple&url=" + urllib.parse.quote(url)) if api.getcode() == 200: answer = api.read() api.close() diff --git a/src/url_shortener/shorteners/isgd.py b/src/url_shortener/shorteners/isgd.py index a624cf85..8ac65902 100644 --- a/src/url_shortener/shorteners/isgd.py +++ b/src/url_shortener/shorteners/isgd.py @@ -1,5 +1,7 @@ from __future__ import absolute_import -import urllib +from future import standard_library +standard_library.install_aliases() +import urllib.request, urllib.parse, urllib.error from .url_shortener import URLShortener @@ -11,7 +13,7 @@ class IsgdShortener (URLShortener): def _shorten (self, url): answer = url - api = urllib.urlopen ("http://is.gd/api.php?longurl=" + urllib.quote(url)) + api = urllib.request.urlopen ("http://is.gd/api.php?longurl=" + urllib.parse.quote(url)) if api.getcode() == 200: answer = api.read() api.close() diff --git a/src/url_shortener/shorteners/onjme.py b/src/url_shortener/shorteners/onjme.py index ecb2bc91..d9f1e8fa 100644 --- a/src/url_shortener/shorteners/onjme.py +++ b/src/url_shortener/shorteners/onjme.py @@ -1,5 +1,7 @@ from __future__ import absolute_import -import urllib +from future import standard_library +standard_library.install_aliases() +import urllib.request, urllib.parse, urllib.error from .url_shortener import URLShortener @@ -10,7 +12,7 @@ class OnjmeShortener (URLShortener): def _shorten (self, url): answer = url - api = urllib.urlopen ("http://onj.me/yourls-api.php?action=shorturl&format=simple&url=" + urllib.quote(url)) + api = urllib.request.urlopen ("http://onj.me/yourls-api.php?action=shorturl&format=simple&url=" + urllib.parse.quote(url)) if api.getcode() == 200: answer = api.read() api.close() diff --git a/src/url_shortener/shorteners/tinyarrows.py b/src/url_shortener/shorteners/tinyarrows.py index 7a6d020f..57645204 100644 --- a/src/url_shortener/shorteners/tinyarrows.py +++ b/src/url_shortener/shorteners/tinyarrows.py @@ -1,5 +1,7 @@ from __future__ import absolute_import -import urllib +from future import standard_library +standard_library.install_aliases() +import urllib.request, urllib.parse, urllib.error from .url_shortener import URLShortener @@ -10,7 +12,7 @@ class TinyArrowsShortener (URLShortener): def _shorten (self, url): answer = url - answer = urllib.urlopen("http://tinyarro.ws/api-create.php?utfpure=1&url=%s" % urllib.quote(url)).read() + answer = urllib.request.urlopen("http://tinyarro.ws/api-create.php?utfpure=1&url=%s" % urllib.parse.quote(url)).read() return answer.decode('UTF-8') def created_url(self, url): diff --git a/src/url_shortener/shorteners/tinyurl.py b/src/url_shortener/shorteners/tinyurl.py index d8057498..08e2637e 100644 --- a/src/url_shortener/shorteners/tinyurl.py +++ b/src/url_shortener/shorteners/tinyurl.py @@ -1,6 +1,8 @@ from __future__ import absolute_import +from future import standard_library +standard_library.install_aliases() from .url_shortener import URLShortener -import urllib +import urllib.request, urllib.parse, urllib.error class TinyurlShortener (URLShortener): def __init__(self, *args, **kwargs): self.name = "TinyURL.com" @@ -9,7 +11,7 @@ class TinyurlShortener (URLShortener): def _shorten (self, url): answer = url - api = urllib.urlopen ("http://tinyurl.com/api-create.php?url=" + urllib.quote(url)) + api = urllib.request.urlopen ("http://tinyurl.com/api-create.php?url=" + urllib.parse.quote(url)) if api.getcode() == 200: answer = api.read() api.close() diff --git a/src/url_shortener/shorteners/url_shortener.py b/src/url_shortener/shorteners/url_shortener.py index 2bab88ab..1e42e359 100644 --- a/src/url_shortener/shorteners/url_shortener.py +++ b/src/url_shortener/shorteners/url_shortener.py @@ -1,5 +1,8 @@ -from httplib import HTTPConnection -from urlparse import urlparse +from future import standard_library +standard_library.install_aliases() +from builtins import object +from http.client import HTTPConnection +from urllib.parse import urlparse class URLShortener (object): diff --git a/src/url_shortener/shorteners/xedcc.py b/src/url_shortener/shorteners/xedcc.py index c12e55be..a02e2ef8 100644 --- a/src/url_shortener/shorteners/xedcc.py +++ b/src/url_shortener/shorteners/xedcc.py @@ -1,5 +1,7 @@ from __future__ import absolute_import -import urllib +from future import standard_library +standard_library.install_aliases() +import urllib.request, urllib.parse, urllib.error from .url_shortener import URLShortener @@ -10,7 +12,7 @@ class XedccShortener (URLShortener): def _shorten (self, url): answer = url - api = urllib.urlopen ("http://xed.cc/yourls-api.php?action=shorturl&format=simple&url=" + urllib.quote(url)) + api = urllib.request.urlopen ("http://xed.cc/yourls-api.php?action=shorturl&format=simple&url=" + urllib.parse.quote(url)) if api.getcode() == 200: answer = api.read() api.close() diff --git a/src/widgetUtils/gtkUtils.py b/src/widgetUtils/gtkUtils.py index 8b19f238..03211f11 100644 --- a/src/widgetUtils/gtkUtils.py +++ b/src/widgetUtils/gtkUtils.py @@ -1,143 +1,145 @@ -from gi.repository import Gtk, Gdk -from gi.repository import GObject - -toolkit = "gtk" -# Code responses for GTK +3 dialogs. -# this is when an user presses OK on a dialogue. -OK = Gtk.ResponseType.OK -# This is when an user presses cancel on a dialogue. -CANCEL = Gtk.ResponseType.CANCEL -# This is when an user closes the dialogue or an id to create the close button. -CLOSE = Gtk.ResponseType.CLOSE -# The response for a "yes" Button pressed on a dialogue. -YES = Gtk.ResponseType.YES -# This is when the user presses No on a default dialogue. -NO = Gtk.ResponseType.NO - -#events -# This is raised when the application must be closed. -CLOSE_EVENT = "delete-event" -# This is activated when a button is pressed. -BUTTON_PRESSED = "clicked" -# This is activated when an user enter text on an edit box. -ENTERED_TEXT = "changed" -MENU = "activate" - -#KEYPRESS = wx.EVT_CHAR_HOOK -#NOTEBOOK_PAGE_CHANGED = wx.EVT_NOTEBOOK_PAGE_CHANGED -CHECKBOX = "toggled" - -def exit_application(): - """ Closes the current window cleanly. """ - Gtk.main_quit() - -def connect_event(parent, event, func, menuitem=None, *args, **kwargs): - """ Connects an event to a function. - parent Gtk.widget: The widget that will listen for the event. - event widgetUtils.event: The event that will be listened for the parent. The event should be one of the widgetUtils events. - function func: The function that will be connected to the event.""" - if menuitem == None: - return getattr(parent, "connect")(event, func, *args, **kwargs) - else: - return getattr(menuitem, "connect")(event, func, *args, **kwargs) - -class list(object): - def __init__(self, *columns, **listArguments): - self.columns = columns - self.list_arguments = listArguments - self.create_list() - - def create_list(self): - columns = [] - [columns.append(str) for i in self.columns] - self.store = Gtk.ListStore(*columns) - self.list = Gtk.TreeView(model=self.store) - renderer = Gtk.CellRendererText() - for i in range(0, len(self.columns)): - column = Gtk.TreeViewColumn(self.columns[i], renderer, text=i) -# column.set_sort_column_id(i) - self.list.append_column(column) - - def insert_item(self, reversed=False, *item): - if reversed == False: - self.store.append(row=item) - else: - self.store.insert(position=0, row=item) - - def get_selected(self): - tree_selection = self.list.get_selection() - (model, pathlist) = tree_selection.get_selected_rows() - return int(pathlist[0].to_string() ) - - def select_item(self, item): - tree_selection = self.list.get_selection() - tree_selection.select_path(item) - - def remove_item(self, item): - self.store.remove(self.store.get_iter(item)) - - def get_count(self): - return len(self.store) - -class baseDialog(Gtk.Dialog): - def __init__(self, *args, **kwargs): - super(baseDialog, self).__init__(*args, **kwargs) - self.box = self.get_content_area() - - def get_response(self): - answer = self.run() - return answer - -class buffer(GObject.GObject): - name = GObject.property(type=str) - - def __init__(self, obj): - super(buffer, self).__init__() - self.buffer = obj - -class notebook(object): - - def __init__(self): - self.store = Gtk.TreeStore(buffer.__gtype__) - self.view = Gtk.TreeView() - self.view.set_model(self.store) - - column = Gtk.TreeViewColumn("Buffer") - cell = Gtk.CellRendererText() - column.pack_start(cell, True) - column.set_cell_data_func(cell, self.get_buffer) - self.view.append_column(column) - - def get_current_page(self): - tree_selection = self.view.get_selection() - (model, pathlist) = tree_selection.get_selected_rows() - iter = pathlist[0] - return self.store[iter][0].buffer - - def get_buffer(self, column, cell, model, iter, data): - cell.set_property('text', self.store.get_value(iter, 0).name) - - def match_func(self, row, name_, account): - name = name_ - account = account - iter = self.store.get_iter(row.path) - if self.store[iter][0].buffer.name == name and self.store[iter][0].buffer.account == account: - return (row.path, iter) - else: - return (None, None) - - def search(self, rows, name_, account): - if not rows: return None - for row in rows: - (path, iter) = self.match_func(row, name_, account) - if iter != None: - return (path, iter) - (result_path, result_iter) = self.search(row.iterchildren(), name_, account) - if result_path: return (result_path, result_iter) - return (None, None) - -class mainLoopObject(object): - - def run(self): - GObject.type_register(buffer) - Gtk.main() +from builtins import range +from builtins import object +from gi.repository import Gtk, Gdk +from gi.repository import GObject + +toolkit = "gtk" +# Code responses for GTK +3 dialogs. +# this is when an user presses OK on a dialogue. +OK = Gtk.ResponseType.OK +# This is when an user presses cancel on a dialogue. +CANCEL = Gtk.ResponseType.CANCEL +# This is when an user closes the dialogue or an id to create the close button. +CLOSE = Gtk.ResponseType.CLOSE +# The response for a "yes" Button pressed on a dialogue. +YES = Gtk.ResponseType.YES +# This is when the user presses No on a default dialogue. +NO = Gtk.ResponseType.NO + +#events +# This is raised when the application must be closed. +CLOSE_EVENT = "delete-event" +# This is activated when a button is pressed. +BUTTON_PRESSED = "clicked" +# This is activated when an user enter text on an edit box. +ENTERED_TEXT = "changed" +MENU = "activate" + +#KEYPRESS = wx.EVT_CHAR_HOOK +#NOTEBOOK_PAGE_CHANGED = wx.EVT_NOTEBOOK_PAGE_CHANGED +CHECKBOX = "toggled" + +def exit_application(): + """ Closes the current window cleanly. """ + Gtk.main_quit() + +def connect_event(parent, event, func, menuitem=None, *args, **kwargs): + """ Connects an event to a function. + parent Gtk.widget: The widget that will listen for the event. + event widgetUtils.event: The event that will be listened for the parent. The event should be one of the widgetUtils events. + function func: The function that will be connected to the event.""" + if menuitem == None: + return getattr(parent, "connect")(event, func, *args, **kwargs) + else: + return getattr(menuitem, "connect")(event, func, *args, **kwargs) + +class list(object): + def __init__(self, *columns, **listArguments): + self.columns = columns + self.list_arguments = listArguments + self.create_list() + + def create_list(self): + columns = [] + [columns.append(str) for i in self.columns] + self.store = Gtk.ListStore(*columns) + self.list = Gtk.TreeView(model=self.store) + renderer = Gtk.CellRendererText() + for i in range(0, len(self.columns)): + column = Gtk.TreeViewColumn(self.columns[i], renderer, text=i) +# column.set_sort_column_id(i) + self.list.append_column(column) + + def insert_item(self, reversed=False, *item): + if reversed == False: + self.store.append(row=item) + else: + self.store.insert(position=0, row=item) + + def get_selected(self): + tree_selection = self.list.get_selection() + (model, pathlist) = tree_selection.get_selected_rows() + return int(pathlist[0].to_string() ) + + def select_item(self, item): + tree_selection = self.list.get_selection() + tree_selection.select_path(item) + + def remove_item(self, item): + self.store.remove(self.store.get_iter(item)) + + def get_count(self): + return len(self.store) + +class baseDialog(Gtk.Dialog): + def __init__(self, *args, **kwargs): + super(baseDialog, self).__init__(*args, **kwargs) + self.box = self.get_content_area() + + def get_response(self): + answer = self.run() + return answer + +class buffer(GObject.GObject): + name = GObject.property(type=str) + + def __init__(self, obj): + super(buffer, self).__init__() + self.buffer = obj + +class notebook(object): + + def __init__(self): + self.store = Gtk.TreeStore(buffer.__gtype__) + self.view = Gtk.TreeView() + self.view.set_model(self.store) + + column = Gtk.TreeViewColumn("Buffer") + cell = Gtk.CellRendererText() + column.pack_start(cell, True) + column.set_cell_data_func(cell, self.get_buffer) + self.view.append_column(column) + + def get_current_page(self): + tree_selection = self.view.get_selection() + (model, pathlist) = tree_selection.get_selected_rows() + iter = pathlist[0] + return self.store[iter][0].buffer + + def get_buffer(self, column, cell, model, iter, data): + cell.set_property('text', self.store.get_value(iter, 0).name) + + def match_func(self, row, name_, account): + name = name_ + account = account + iter = self.store.get_iter(row.path) + if self.store[iter][0].buffer.name == name and self.store[iter][0].buffer.account == account: + return (row.path, iter) + else: + return (None, None) + + def search(self, rows, name_, account): + if not rows: return None + for row in rows: + (path, iter) = self.match_func(row, name_, account) + if iter != None: + return (path, iter) + (result_path, result_iter) = self.search(row.iterchildren(), name_, account) + if result_path: return (result_path, result_iter) + return (None, None) + +class mainLoopObject(object): + + def run(self): + GObject.type_register(buffer) + Gtk.main() diff --git a/src/wxUI/dialogs/configuration.py b/src/wxUI/dialogs/configuration.py index 94158d96..9e661449 100644 --- a/src/wxUI/dialogs/configuration.py +++ b/src/wxUI/dialogs/configuration.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import # -*- coding: utf-8 -*- +from builtins import range from . import baseDialog import wx import logging as original_logger @@ -214,7 +215,7 @@ class other_buffers(wx.Panel): output.speak(self.buffers.get_text_column(current, 2),True) def get_list(self): buffers_list = [] - for i in xrange(0, self.buffers.get_count()): + for i in range(0, self.buffers.get_count()): if self.buffers.get_text_column(i, 2) == _(u"Show"): buffers_list.append(self.buffers.get_text_column(i, 0)) return buffers_list diff --git a/src/wxUI/dialogs/message.py b/src/wxUI/dialogs/message.py index aad7e3b2..c5ef7aeb 100644 --- a/src/wxUI/dialogs/message.py +++ b/src/wxUI/dialogs/message.py @@ -1,446 +1,447 @@ -# -*- coding: utf-8 -*- -import wx -import widgetUtils - -class textLimited(widgetUtils.BaseDialog): - def __init__(self, *args, **kwargs): - super(textLimited, self).__init__(parent=None, *args, **kwargs) - - def createTextArea(self, message="", text=""): - if not hasattr(self, "panel"): - self.panel = wx.Panel(self) - self.label = wx.StaticText(self.panel, -1, message) - self.SetTitle(str(len(text))) - self.text = wx.TextCtrl(self.panel, -1, text, size=(439, -1),style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER) -# font = self.text.GetFont() -# dc = wx.WindowDC(self.text) -# dc.SetFont(font) -# x, y = dc.GetTextExtent("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") -# self.text.SetSize((x, y)) - self.Bind(wx.EVT_CHAR_HOOK, self.handle_keys, self.text) - self.text.SetFocus() - self.textBox = wx.BoxSizer(wx.HORIZONTAL) - self.textBox.Add(self.label, 0, wx.ALL, 5) - self.textBox.Add(self.text, 0, wx.ALL, 5) - - def text_focus(self): - self.text.SetFocus() - - def get_text(self): - return self.text.GetValue() - - def set_text(self, text): - return self.text.ChangeValue(text) - - def set_title(self, new_title): - return self.SetTitle(new_title) - - def enable_button(self, buttonName): - if hasattr(self, buttonName): - return getattr(self, buttonName).Enable() - - def disable_button(self, buttonName): - if hasattr(self, buttonName): - return getattr(self, buttonName).Disable() - - def onSelect(self, ev): - self.text.SelectAll() - - def handle_keys(self, event): - shift=event.ShiftDown() - if event.GetKeyCode() == wx.WXK_RETURN and shift==False and hasattr(self,'okButton'): - wx.PostEvent(self.okButton.GetEventHandler(), wx.PyCommandEvent(wx.EVT_BUTTON.typeId,wx.ID_OK)) - else: - event.Skip() - - def set_cursor_at_end(self): - self.text.SetInsertionPoint(len(self.text.GetValue())) - - def set_cursor_at_position(self, position): - self.text.SetInsertionPoint(position) - - def get_position(self): - return self.text.GetInsertionPoint() - - def popup_menu(self, menu): - self.PopupMenu(menu, self.text.GetPosition()) - -class tweet(textLimited): - def createControls(self, title, message, text): - self.mainBox = wx.BoxSizer(wx.VERTICAL) - self.createTextArea(message, text) - self.mainBox.Add(self.textBox, 0, wx.ALL, 5) - self.long_tweet = wx.CheckBox(self.panel, -1, _(u"&Long tweet")) - self.long_tweet.SetValue(True) - self.upload_image = wx.Button(self.panel, -1, _(u"&Upload image..."), size=wx.DefaultSize) - self.spellcheck = wx.Button(self.panel, -1, _("Check &spelling..."), size=wx.DefaultSize) - self.attach = wx.Button(self.panel, -1, _(u"&Attach audio..."), size=wx.DefaultSize) - self.shortenButton = wx.Button(self.panel, -1, _(u"Sh&orten URL"), size=wx.DefaultSize) - self.unshortenButton = wx.Button(self.panel, -1, _(u"&Expand URL"), size=wx.DefaultSize) - self.shortenButton.Disable() - self.unshortenButton.Disable() - self.translateButton = wx.Button(self.panel, -1, _(u"&Translate..."), size=wx.DefaultSize) - self.autocompletionButton = wx.Button(self.panel, -1, _(u"Auto&complete users")) - self.okButton = wx.Button(self.panel, wx.ID_OK, _(u"Sen&d"), size=wx.DefaultSize) - self.okButton.SetDefault() - cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize) - self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL) - self.buttonsBox1.Add(self.upload_image, 0, wx.ALL, 10) - self.buttonsBox1.Add(self.spellcheck, 0, wx.ALL, 10) - self.buttonsBox1.Add(self.attach, 0, wx.ALL, 10) - self.mainBox.Add(self.buttonsBox1, 0, wx.ALL, 10) - self.buttonsBox2 = wx.BoxSizer(wx.HORIZONTAL) - self.buttonsBox2.Add(self.shortenButton, 0, wx.ALL, 10) - self.buttonsBox2.Add(self.unshortenButton, 0, wx.ALL, 10) - self.buttonsBox2.Add(self.translateButton, 0, wx.ALL, 10) - self.mainBox.Add(self.buttonsBox2, 0, wx.ALL, 10) - self.ok_cancelSizer = wx.BoxSizer(wx.HORIZONTAL) - self.ok_cancelSizer.Add(self.autocompletionButton, 0, wx.ALL, 10) - self.ok_cancelSizer.Add(self.okButton, 0, wx.ALL, 10) - self.ok_cancelSizer.Add(cancelButton, 0, wx.ALL, 10) - self.mainBox.Add(self.ok_cancelSizer) - selectId = wx.NewId() - self.Bind(wx.EVT_MENU, self.onSelect, id=selectId) - self.accel_tbl = wx.AcceleratorTable([ -(wx.ACCEL_CTRL, ord('A'), selectId), -]) - self.SetAcceleratorTable(self.accel_tbl) - self.panel.SetSizer(self.mainBox) - - def __init__(self, title, message, text, *args, **kwargs): - super(tweet, self).__init__() - self.shift=False - self.createControls(message, title, text) - self.SetClientSize(self.mainBox.CalcMin()) - - def get_image(self): - openFileDialog = wx.FileDialog(self, _(u"Select the picture to be uploaded"), "", "", _("Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) - if openFileDialog.ShowModal() == wx.ID_CANCEL: - return None - return open(openFileDialog.GetPath(), "rb") - - -class retweet(tweet): - def createControls(self, title, message, text): - self.mainBox = wx.BoxSizer(wx.VERTICAL) - self.createTextArea(message, "") - label = wx.StaticText(self.panel, -1, _(u"Retweet")) - self.text2 = wx.TextCtrl(self.panel, -1, text, size=(439, -1), style=wx.TE_MULTILINE|wx.TE_READONLY) - self.retweetBox = wx.BoxSizer(wx.HORIZONTAL) - self.retweetBox.Add(label, 0, wx.ALL, 5) - self.retweetBox.Add(self.text2, 0, wx.ALL, 5) - self.mainBox.Add(self.textBox, 0, wx.ALL, 5) - self.mainBox.Add(self.retweetBox, 0, wx.ALL, 5) - self.upload_image = wx.Button(self.panel, -1, _(u"&Upload image..."), size=wx.DefaultSize) - self.spellcheck = wx.Button(self.panel, -1, _("Check &spelling..."), size=wx.DefaultSize) - self.attach = wx.Button(self.panel, -1, _(u"&Attach audio..."), size=wx.DefaultSize) - self.shortenButton = wx.Button(self.panel, -1, _(u"Sh&orten URL"), size=wx.DefaultSize) - self.unshortenButton = wx.Button(self.panel, -1, _(u"&Expand URL"), size=wx.DefaultSize) - self.shortenButton.Disable() - self.unshortenButton.Disable() - self.translateButton = wx.Button(self.panel, -1, _(u"&Translate..."), size=wx.DefaultSize) - self.autocompletionButton = wx.Button(self.panel, -1, _(u"Auto&complete users")) - self.okButton = wx.Button(self.panel, wx.ID_OK, _(u"Sen&d"), size=wx.DefaultSize) - self.okButton.SetDefault() - cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize) - self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL) - self.buttonsBox1.Add(self.upload_image, 0, wx.ALL, 10) - self.buttonsBox1.Add(self.spellcheck, 0, wx.ALL, 10) - self.buttonsBox1.Add(self.attach, 0, wx.ALL, 10) - self.mainBox.Add(self.buttonsBox1, 0, wx.ALL, 10) - self.buttonsBox2 = wx.BoxSizer(wx.HORIZONTAL) - self.buttonsBox2.Add(self.shortenButton, 0, wx.ALL, 10) - self.buttonsBox2.Add(self.unshortenButton, 0, wx.ALL, 10) - self.buttonsBox2.Add(self.translateButton, 0, wx.ALL, 10) - self.mainBox.Add(self.buttonsBox2, 0, wx.ALL, 10) - self.ok_cancelSizer = wx.BoxSizer(wx.HORIZONTAL) - self.ok_cancelSizer.Add(self.autocompletionButton, 0, wx.ALL, 10) - self.ok_cancelSizer.Add(self.okButton, 0, wx.ALL, 10) - self.ok_cancelSizer.Add(cancelButton, 0, wx.ALL, 10) - self.mainBox.Add(self.ok_cancelSizer) - selectId = wx.NewId() - self.Bind(wx.EVT_MENU, self.onSelect, id=selectId) - self.accel_tbl = wx.AcceleratorTable([ -(wx.ACCEL_CTRL, ord('A'), selectId), -]) - self.SetAcceleratorTable(self.accel_tbl) - self.panel.SetSizer(self.mainBox) - - def __init__(self, title, message, text, *args, **kwargs): - super(tweet, self).__init__() - self.createControls(message, title, text) -# self.onTimer(wx.EVT_CHAR_HOOK) - self.SetClientSize(self.mainBox.CalcMin()) - - def get_image(self): - openFileDialog = wx.FileDialog(self, _(u"Select the picture to be uploaded"), "", "", _("Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) - if openFileDialog.ShowModal() == wx.ID_CANCEL: - return None - return open(openFileDialog.GetPath(), "rb") - -class dm(textLimited): - def createControls(self, title, message, users): - self.panel = wx.Panel(self) - self.mainBox = wx.BoxSizer(wx.VERTICAL) - label = wx.StaticText(self.panel, -1, _(u"&Recipient")) - self.cb = wx.ComboBox(self.panel, -1, choices=users, value=users[0], size=wx.DefaultSize) - self.autocompletionButton = wx.Button(self.panel, -1, _(u"Auto&complete users")) - self.createTextArea(message, text="") - userBox = wx.BoxSizer(wx.HORIZONTAL) - userBox.Add(label, 0, wx.ALL, 5) - userBox.Add(self.cb, 0, wx.ALL, 5) - userBox.Add(self.autocompletionButton, 0, wx.ALL, 5) - self.mainBox.Add(userBox, 0, wx.ALL, 5) - self.mainBox.Add(self.textBox, 0, wx.ALL, 5) - self.spellcheck = wx.Button(self.panel, -1, _("Check &spelling..."), size=wx.DefaultSize) - self.attach = wx.Button(self.panel, -1, _(u"&Attach audio..."), size=wx.DefaultSize) - self.shortenButton = wx.Button(self.panel, -1, _(u"Sh&orten URL"), size=wx.DefaultSize) - self.unshortenButton = wx.Button(self.panel, -1, _(u"&Expand URL"), size=wx.DefaultSize) - self.shortenButton.Disable() - self.unshortenButton.Disable() - self.translateButton = wx.Button(self.panel, -1, _(u"&Translate..."), size=wx.DefaultSize) - self.okButton = wx.Button(self.panel, wx.ID_OK, _(u"Sen&d"), size=wx.DefaultSize) - self.okButton.SetDefault() - cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize) - self.buttonsBox = wx.BoxSizer(wx.HORIZONTAL) - self.buttonsBox.Add(self.spellcheck, 0, wx.ALL, 5) - self.buttonsBox.Add(self.attach, 0, wx.ALL, 5) - self.mainBox.Add(self.buttonsBox, 0, wx.ALL, 5) - self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL) - self.buttonsBox1.Add(self.shortenButton, 0, wx.ALL, 5) - self.buttonsBox1.Add(self.unshortenButton, 0, wx.ALL, 5) - self.buttonsBox1.Add(self.translateButton, 0, wx.ALL, 5) - self.mainBox.Add(self.buttonsBox1, 0, wx.ALL, 5) - self.buttonsBox3 = wx.BoxSizer(wx.HORIZONTAL) - self.buttonsBox3.Add(self.okButton, 0, wx.ALL, 5) - self.buttonsBox3.Add(cancelButton, 0, wx.ALL, 5) - self.mainBox.Add(self.buttonsBox3, 0, wx.ALL, 5) - self.panel.SetSizer(self.mainBox) - self.SetClientSize(self.mainBox.CalcMin()) - - def __init__(self, title, message, users, *args, **kwargs): - super(dm, self).__init__() - self.createControls(message, title, users) -# self.onTimer(wx.EVT_CHAR_HOOK) -# self.SetClientSize(self.mainBox.CalcMin()) - - def get_user(self): - return self.cb.GetValue() - - def set_user(self, user): - return self.cb.SetValue(user) - -class reply(textLimited): - - def get_image(self): - openFileDialog = wx.FileDialog(self, _(u"Select the picture to be uploaded"), "", "", _("Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) - if openFileDialog.ShowModal() == wx.ID_CANCEL: - return None - return open(openFileDialog.GetPath(), "rb") - - def createControls(self, title, message, text): - self.mainBox = wx.BoxSizer(wx.VERTICAL) - self.createTextArea(message, text) - self.mainBox.Add(self.textBox, 0, wx.ALL, 5) - self.usersbox = wx.BoxSizer(wx.VERTICAL) - self.mentionAll = wx.CheckBox(self.panel, -1, _(u"&Mention to all"), size=wx.DefaultSize) - self.mentionAll.Disable() - self.usersbox.Add(self.mentionAll, 0, wx.ALL, 5) - self.checkboxes = [] - for i in self.users: - user_checkbox = wx.CheckBox(self.panel, -1, "@"+i, size=wx.DefaultSize) - self.checkboxes.append(user_checkbox) - self.usersbox.Add(self.checkboxes[-1], 0, wx.ALL, 5) - self.mainBox.Add(self.usersbox, 0, wx.ALL, 10) - self.long_tweet = wx.CheckBox(self.panel, -1, _(u"&Long tweet")) - self.long_tweet.SetValue(True) - self.upload_image = wx.Button(self.panel, -1, _(u"&Upload image..."), size=wx.DefaultSize) - self.spellcheck = wx.Button(self.panel, -1, _("Check &spelling..."), size=wx.DefaultSize) - self.attach = wx.Button(self.panel, -1, _(u"&Attach audio..."), size=wx.DefaultSize) - self.shortenButton = wx.Button(self.panel, -1, _(u"Sh&orten URL"), size=wx.DefaultSize) - self.unshortenButton = wx.Button(self.panel, -1, _(u"&Expand URL"), size=wx.DefaultSize) - self.shortenButton.Disable() - self.unshortenButton.Disable() - self.translateButton = wx.Button(self.panel, -1, _(u"&Translate..."), size=wx.DefaultSize) - self.autocompletionButton = wx.Button(self.panel, -1, _(u"Auto&complete users")) - self.okButton = wx.Button(self.panel, wx.ID_OK, _(u"Sen&d"), size=wx.DefaultSize) - self.okButton.SetDefault() - cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize) - self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL) - self.buttonsBox1.Add(self.upload_image, 0, wx.ALL, 10) - self.buttonsBox1.Add(self.spellcheck, 0, wx.ALL, 10) - self.buttonsBox1.Add(self.attach, 0, wx.ALL, 10) - self.mainBox.Add(self.buttonsBox1, 0, wx.ALL, 10) - self.buttonsBox2 = wx.BoxSizer(wx.HORIZONTAL) - self.buttonsBox2.Add(self.shortenButton, 0, wx.ALL, 10) - self.buttonsBox2.Add(self.unshortenButton, 0, wx.ALL, 10) - self.buttonsBox2.Add(self.translateButton, 0, wx.ALL, 10) - self.mainBox.Add(self.buttonsBox2, 0, wx.ALL, 10) - self.ok_cancelSizer = wx.BoxSizer(wx.HORIZONTAL) - self.ok_cancelSizer.Add(self.autocompletionButton, 0, wx.ALL, 10) - self.ok_cancelSizer.Add(self.okButton, 0, wx.ALL, 10) - self.ok_cancelSizer.Add(cancelButton, 0, wx.ALL, 10) - self.mainBox.Add(self.ok_cancelSizer, 0, wx.ALL, 10) - selectId = wx.NewId() - self.Bind(wx.EVT_MENU, self.onSelect, id=selectId) - self.accel_tbl = wx.AcceleratorTable([ -(wx.ACCEL_CTRL, ord('A'), selectId), -]) - self.SetAcceleratorTable(self.accel_tbl) - self.panel.SetSizer(self.mainBox) - - def __init__(self, title, message, text, users=[], *args, **kwargs): - self.users = users - super(reply, self).__init__() - self.shift=False - self.createControls(message, title, text) - self.SetClientSize(self.mainBox.CalcMin()) - -class viewTweet(widgetUtils.BaseDialog): - def set_title(self, lenght): - self.SetTitle(_(u"Tweet - %i characters ") % (lenght,)) - - def __init__(self, text, rt_count, favs_count,source, *args, **kwargs): - super(viewTweet, self).__init__(None, size=(850,850)) - panel = wx.Panel(self) - label = wx.StaticText(panel, -1, _(u"Tweet")) - self.text = wx.TextCtrl(panel, -1, text, style=wx.TE_READONLY|wx.TE_MULTILINE, size=(250, 180)) - dc = wx.WindowDC(self.text) - dc.SetFont(self.text.GetFont()) - (x, y) = dc.GetMultiLineTextExtent("0"*140) - self.text.SetSize((x, y)) - self.text.SetFocus() - textBox = wx.BoxSizer(wx.HORIZONTAL) - textBox.Add(label, 0, wx.ALL, 5) - textBox.Add(self.text, 1, wx.EXPAND, 5) - mainBox = wx.BoxSizer(wx.VERTICAL) - mainBox.Add(textBox, 0, wx.ALL, 5) - label2 = wx.StaticText(panel, -1, _(u"Image description")) - self.image_description = wx.TextCtrl(panel, -1, style=wx.TE_READONLY|wx.TE_MULTILINE, size=(250, 180)) - dc = wx.WindowDC(self.image_description) - dc.SetFont(self.image_description.GetFont()) - (x, y) = dc.GetMultiLineTextExtent("0"*450) - self.image_description.SetSize((x, y)) - self.image_description.Enable(False) - iBox = wx.BoxSizer(wx.HORIZONTAL) - iBox.Add(label2, 0, wx.ALL, 5) - iBox.Add(self.image_description, 1, wx.EXPAND, 5) - mainBox.Add(iBox, 0, wx.ALL, 5) - rtCountLabel = wx.StaticText(panel, -1, _(u"Retweets: ")) - rtCount = wx.TextCtrl(panel, -1, rt_count, size=wx.DefaultSize, style=wx.TE_READONLY|wx.TE_MULTILINE) - rtBox = wx.BoxSizer(wx.HORIZONTAL) - rtBox.Add(rtCountLabel, 0, wx.ALL, 5) - rtBox.Add(rtCount, 0, wx.ALL, 5) - favsCountLabel = wx.StaticText(panel, -1, _(u"Likes: ")) - favsCount = wx.TextCtrl(panel, -1, favs_count, size=wx.DefaultSize, style=wx.TE_READONLY|wx.TE_MULTILINE) - favsBox = wx.BoxSizer(wx.HORIZONTAL) - favsBox.Add(favsCountLabel, 0, wx.ALL, 5) - favsBox.Add(favsCount, 0, wx.ALL, 5) - sourceLabel = wx.StaticText(panel, -1, _(u"Source: ")) - sourceTweet = wx.TextCtrl(panel, -1, source, size=wx.DefaultSize, style=wx.TE_READONLY|wx.TE_MULTILINE) - sourceBox = wx.BoxSizer(wx.HORIZONTAL) - sourceBox.Add(sourceLabel, 0, wx.ALL, 5) - sourceBox.Add(sourceTweet, 0, wx.ALL, 5) - infoBox = wx.BoxSizer(wx.HORIZONTAL) - infoBox.Add(rtBox, 0, wx.ALL, 5) - infoBox.Add(favsBox, 0, wx.ALL, 5) - infoBox.Add(sourceBox, 0, wx.ALL, 5) - mainBox.Add(infoBox, 0, wx.ALL, 5) - 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() - self.translateButton = wx.Button(panel, -1, _(u"&Translate..."), size=wx.DefaultSize) - cancelButton = wx.Button(panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize) - cancelButton.SetDefault() - buttonsBox = wx.BoxSizer(wx.HORIZONTAL) - buttonsBox.Add(self.spellcheck, 0, wx.ALL, 5) - buttonsBox.Add(self.unshortenButton, 0, wx.ALL, 5) - buttonsBox.Add(self.translateButton, 0, wx.ALL, 5) - buttonsBox.Add(cancelButton, 0, wx.ALL, 5) - mainBox.Add(buttonsBox, 0, wx.ALL, 5) - selectId = wx.NewId() - self.Bind(wx.EVT_MENU, self.onSelect, id=selectId) - self.accel_tbl = wx.AcceleratorTable([ -(wx.ACCEL_CTRL, ord('A'), selectId), -]) - self.SetAcceleratorTable(self.accel_tbl) - panel.SetSizer(mainBox) - self.SetClientSize(mainBox.CalcMin()) - - def set_text(self, text): - self.text.ChangeValue(text) - - def get_text(self): - return self.text.GetValue() - - def set_image_description(self, desc): - self.image_description.Enable(True) - if len(self.image_description.GetValue()) == 0: - self.image_description.SetValue(desc) - else: - self.image_description.SetValue(self.image_description.GetValue()+"\n"+desc) - - def text_focus(self): - self.text.SetFocus() - - def onSelect(self, ev): - self.text.SelectAll() - - def enable_button(self, buttonName): - if hasattr(self, buttonName): - return getattr(self, buttonName).Enable() - -class viewNonTweet(widgetUtils.BaseDialog): - - def __init__(self, text, *args, **kwargs): - super(viewNonTweet, self).__init__(None, size=(850,850)) - self.SetTitle(_(u"View")) - panel = wx.Panel(self) - label = wx.StaticText(panel, -1, _(u"Item")) - self.text = wx.TextCtrl(parent=panel, id=-1, value=text, style=wx.TE_READONLY|wx.TE_MULTILINE, size=(250, 180)) - dc = wx.WindowDC(self.text) - dc.SetFont(self.text.GetFont()) - (x, y) = dc.GetMultiLineTextExtent("0"*140) - self.text.SetSize((x, y)) - self.text.SetFocus() - textBox = wx.BoxSizer(wx.HORIZONTAL) - textBox.Add(label, 0, wx.ALL, 5) - textBox.Add(self.text, 1, wx.EXPAND, 5) - mainBox = wx.BoxSizer(wx.VERTICAL) - mainBox.Add(textBox, 0, wx.ALL, 5) - 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() - self.translateButton = wx.Button(panel, -1, _(u"&Translate..."), size=wx.DefaultSize) - cancelButton = wx.Button(panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize) - cancelButton.SetDefault() - buttonsBox = wx.BoxSizer(wx.HORIZONTAL) - buttonsBox.Add(self.spellcheck, 0, wx.ALL, 5) - buttonsBox.Add(self.unshortenButton, 0, wx.ALL, 5) - buttonsBox.Add(self.translateButton, 0, wx.ALL, 5) - buttonsBox.Add(cancelButton, 0, wx.ALL, 5) - mainBox.Add(buttonsBox, 0, wx.ALL, 5) - selectId = wx.NewId() - self.Bind(wx.EVT_MENU, self.onSelect, id=selectId) - self.accel_tbl = wx.AcceleratorTable([ -(wx.ACCEL_CTRL, ord('A'), selectId), -]) - self.SetAcceleratorTable(self.accel_tbl) - panel.SetSizer(mainBox) - self.SetClientSize(mainBox.CalcMin()) - - def onSelect(self, ev): - self.text.SelectAll() - - def set_text(self, text): - self.text.ChangeValue(text) - - def get_text(self): - return self.text.GetValue() - - def text_focus(self): - self.text.SetFocus() - - def enable_button(self, buttonName): - if getattr(self, buttonName): - return getattr(self, buttonName).Enable() +# -*- coding: utf-8 -*- +from builtins import str +import wx +import widgetUtils + +class textLimited(widgetUtils.BaseDialog): + def __init__(self, *args, **kwargs): + super(textLimited, self).__init__(parent=None, *args, **kwargs) + + def createTextArea(self, message="", text=""): + if not hasattr(self, "panel"): + self.panel = wx.Panel(self) + self.label = wx.StaticText(self.panel, -1, message) + self.SetTitle(str(len(text))) + self.text = wx.TextCtrl(self.panel, -1, text, size=(439, -1),style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER) +# font = self.text.GetFont() +# dc = wx.WindowDC(self.text) +# dc.SetFont(font) +# x, y = dc.GetTextExtent("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") +# self.text.SetSize((x, y)) + self.Bind(wx.EVT_CHAR_HOOK, self.handle_keys, self.text) + self.text.SetFocus() + self.textBox = wx.BoxSizer(wx.HORIZONTAL) + self.textBox.Add(self.label, 0, wx.ALL, 5) + self.textBox.Add(self.text, 0, wx.ALL, 5) + + def text_focus(self): + self.text.SetFocus() + + def get_text(self): + return self.text.GetValue() + + def set_text(self, text): + return self.text.ChangeValue(text) + + def set_title(self, new_title): + return self.SetTitle(new_title) + + def enable_button(self, buttonName): + if hasattr(self, buttonName): + return getattr(self, buttonName).Enable() + + def disable_button(self, buttonName): + if hasattr(self, buttonName): + return getattr(self, buttonName).Disable() + + def onSelect(self, ev): + self.text.SelectAll() + + def handle_keys(self, event): + shift=event.ShiftDown() + if event.GetKeyCode() == wx.WXK_RETURN and shift==False and hasattr(self,'okButton'): + wx.PostEvent(self.okButton.GetEventHandler(), wx.PyCommandEvent(wx.EVT_BUTTON.typeId,wx.ID_OK)) + else: + event.Skip() + + def set_cursor_at_end(self): + self.text.SetInsertionPoint(len(self.text.GetValue())) + + def set_cursor_at_position(self, position): + self.text.SetInsertionPoint(position) + + def get_position(self): + return self.text.GetInsertionPoint() + + def popup_menu(self, menu): + self.PopupMenu(menu, self.text.GetPosition()) + +class tweet(textLimited): + def createControls(self, title, message, text): + self.mainBox = wx.BoxSizer(wx.VERTICAL) + self.createTextArea(message, text) + self.mainBox.Add(self.textBox, 0, wx.ALL, 5) + self.long_tweet = wx.CheckBox(self.panel, -1, _(u"&Long tweet")) + self.long_tweet.SetValue(True) + self.upload_image = wx.Button(self.panel, -1, _(u"&Upload image..."), size=wx.DefaultSize) + self.spellcheck = wx.Button(self.panel, -1, _("Check &spelling..."), size=wx.DefaultSize) + self.attach = wx.Button(self.panel, -1, _(u"&Attach audio..."), size=wx.DefaultSize) + self.shortenButton = wx.Button(self.panel, -1, _(u"Sh&orten URL"), size=wx.DefaultSize) + self.unshortenButton = wx.Button(self.panel, -1, _(u"&Expand URL"), size=wx.DefaultSize) + self.shortenButton.Disable() + self.unshortenButton.Disable() + self.translateButton = wx.Button(self.panel, -1, _(u"&Translate..."), size=wx.DefaultSize) + self.autocompletionButton = wx.Button(self.panel, -1, _(u"Auto&complete users")) + self.okButton = wx.Button(self.panel, wx.ID_OK, _(u"Sen&d"), size=wx.DefaultSize) + self.okButton.SetDefault() + cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize) + self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL) + self.buttonsBox1.Add(self.upload_image, 0, wx.ALL, 10) + self.buttonsBox1.Add(self.spellcheck, 0, wx.ALL, 10) + self.buttonsBox1.Add(self.attach, 0, wx.ALL, 10) + self.mainBox.Add(self.buttonsBox1, 0, wx.ALL, 10) + self.buttonsBox2 = wx.BoxSizer(wx.HORIZONTAL) + self.buttonsBox2.Add(self.shortenButton, 0, wx.ALL, 10) + self.buttonsBox2.Add(self.unshortenButton, 0, wx.ALL, 10) + self.buttonsBox2.Add(self.translateButton, 0, wx.ALL, 10) + self.mainBox.Add(self.buttonsBox2, 0, wx.ALL, 10) + self.ok_cancelSizer = wx.BoxSizer(wx.HORIZONTAL) + self.ok_cancelSizer.Add(self.autocompletionButton, 0, wx.ALL, 10) + self.ok_cancelSizer.Add(self.okButton, 0, wx.ALL, 10) + self.ok_cancelSizer.Add(cancelButton, 0, wx.ALL, 10) + self.mainBox.Add(self.ok_cancelSizer) + selectId = wx.NewId() + self.Bind(wx.EVT_MENU, self.onSelect, id=selectId) + self.accel_tbl = wx.AcceleratorTable([ +(wx.ACCEL_CTRL, ord('A'), selectId), +]) + self.SetAcceleratorTable(self.accel_tbl) + self.panel.SetSizer(self.mainBox) + + def __init__(self, title, message, text, *args, **kwargs): + super(tweet, self).__init__() + self.shift=False + self.createControls(message, title, text) + self.SetClientSize(self.mainBox.CalcMin()) + + def get_image(self): + openFileDialog = wx.FileDialog(self, _(u"Select the picture to be uploaded"), "", "", _("Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) + if openFileDialog.ShowModal() == wx.ID_CANCEL: + return None + return open(openFileDialog.GetPath(), "rb") + + +class retweet(tweet): + def createControls(self, title, message, text): + self.mainBox = wx.BoxSizer(wx.VERTICAL) + self.createTextArea(message, "") + label = wx.StaticText(self.panel, -1, _(u"Retweet")) + self.text2 = wx.TextCtrl(self.panel, -1, text, size=(439, -1), style=wx.TE_MULTILINE|wx.TE_READONLY) + self.retweetBox = wx.BoxSizer(wx.HORIZONTAL) + self.retweetBox.Add(label, 0, wx.ALL, 5) + self.retweetBox.Add(self.text2, 0, wx.ALL, 5) + self.mainBox.Add(self.textBox, 0, wx.ALL, 5) + self.mainBox.Add(self.retweetBox, 0, wx.ALL, 5) + self.upload_image = wx.Button(self.panel, -1, _(u"&Upload image..."), size=wx.DefaultSize) + self.spellcheck = wx.Button(self.panel, -1, _("Check &spelling..."), size=wx.DefaultSize) + self.attach = wx.Button(self.panel, -1, _(u"&Attach audio..."), size=wx.DefaultSize) + self.shortenButton = wx.Button(self.panel, -1, _(u"Sh&orten URL"), size=wx.DefaultSize) + self.unshortenButton = wx.Button(self.panel, -1, _(u"&Expand URL"), size=wx.DefaultSize) + self.shortenButton.Disable() + self.unshortenButton.Disable() + self.translateButton = wx.Button(self.panel, -1, _(u"&Translate..."), size=wx.DefaultSize) + self.autocompletionButton = wx.Button(self.panel, -1, _(u"Auto&complete users")) + self.okButton = wx.Button(self.panel, wx.ID_OK, _(u"Sen&d"), size=wx.DefaultSize) + self.okButton.SetDefault() + cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize) + self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL) + self.buttonsBox1.Add(self.upload_image, 0, wx.ALL, 10) + self.buttonsBox1.Add(self.spellcheck, 0, wx.ALL, 10) + self.buttonsBox1.Add(self.attach, 0, wx.ALL, 10) + self.mainBox.Add(self.buttonsBox1, 0, wx.ALL, 10) + self.buttonsBox2 = wx.BoxSizer(wx.HORIZONTAL) + self.buttonsBox2.Add(self.shortenButton, 0, wx.ALL, 10) + self.buttonsBox2.Add(self.unshortenButton, 0, wx.ALL, 10) + self.buttonsBox2.Add(self.translateButton, 0, wx.ALL, 10) + self.mainBox.Add(self.buttonsBox2, 0, wx.ALL, 10) + self.ok_cancelSizer = wx.BoxSizer(wx.HORIZONTAL) + self.ok_cancelSizer.Add(self.autocompletionButton, 0, wx.ALL, 10) + self.ok_cancelSizer.Add(self.okButton, 0, wx.ALL, 10) + self.ok_cancelSizer.Add(cancelButton, 0, wx.ALL, 10) + self.mainBox.Add(self.ok_cancelSizer) + selectId = wx.NewId() + self.Bind(wx.EVT_MENU, self.onSelect, id=selectId) + self.accel_tbl = wx.AcceleratorTable([ +(wx.ACCEL_CTRL, ord('A'), selectId), +]) + self.SetAcceleratorTable(self.accel_tbl) + self.panel.SetSizer(self.mainBox) + + def __init__(self, title, message, text, *args, **kwargs): + super(tweet, self).__init__() + self.createControls(message, title, text) +# self.onTimer(wx.EVT_CHAR_HOOK) + self.SetClientSize(self.mainBox.CalcMin()) + + def get_image(self): + openFileDialog = wx.FileDialog(self, _(u"Select the picture to be uploaded"), "", "", _("Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) + if openFileDialog.ShowModal() == wx.ID_CANCEL: + return None + return open(openFileDialog.GetPath(), "rb") + +class dm(textLimited): + def createControls(self, title, message, users): + self.panel = wx.Panel(self) + self.mainBox = wx.BoxSizer(wx.VERTICAL) + label = wx.StaticText(self.panel, -1, _(u"&Recipient")) + self.cb = wx.ComboBox(self.panel, -1, choices=users, value=users[0], size=wx.DefaultSize) + self.autocompletionButton = wx.Button(self.panel, -1, _(u"Auto&complete users")) + self.createTextArea(message, text="") + userBox = wx.BoxSizer(wx.HORIZONTAL) + userBox.Add(label, 0, wx.ALL, 5) + userBox.Add(self.cb, 0, wx.ALL, 5) + userBox.Add(self.autocompletionButton, 0, wx.ALL, 5) + self.mainBox.Add(userBox, 0, wx.ALL, 5) + self.mainBox.Add(self.textBox, 0, wx.ALL, 5) + self.spellcheck = wx.Button(self.panel, -1, _("Check &spelling..."), size=wx.DefaultSize) + self.attach = wx.Button(self.panel, -1, _(u"&Attach audio..."), size=wx.DefaultSize) + self.shortenButton = wx.Button(self.panel, -1, _(u"Sh&orten URL"), size=wx.DefaultSize) + self.unshortenButton = wx.Button(self.panel, -1, _(u"&Expand URL"), size=wx.DefaultSize) + self.shortenButton.Disable() + self.unshortenButton.Disable() + self.translateButton = wx.Button(self.panel, -1, _(u"&Translate..."), size=wx.DefaultSize) + self.okButton = wx.Button(self.panel, wx.ID_OK, _(u"Sen&d"), size=wx.DefaultSize) + self.okButton.SetDefault() + cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize) + self.buttonsBox = wx.BoxSizer(wx.HORIZONTAL) + self.buttonsBox.Add(self.spellcheck, 0, wx.ALL, 5) + self.buttonsBox.Add(self.attach, 0, wx.ALL, 5) + self.mainBox.Add(self.buttonsBox, 0, wx.ALL, 5) + self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL) + self.buttonsBox1.Add(self.shortenButton, 0, wx.ALL, 5) + self.buttonsBox1.Add(self.unshortenButton, 0, wx.ALL, 5) + self.buttonsBox1.Add(self.translateButton, 0, wx.ALL, 5) + self.mainBox.Add(self.buttonsBox1, 0, wx.ALL, 5) + self.buttonsBox3 = wx.BoxSizer(wx.HORIZONTAL) + self.buttonsBox3.Add(self.okButton, 0, wx.ALL, 5) + self.buttonsBox3.Add(cancelButton, 0, wx.ALL, 5) + self.mainBox.Add(self.buttonsBox3, 0, wx.ALL, 5) + self.panel.SetSizer(self.mainBox) + self.SetClientSize(self.mainBox.CalcMin()) + + def __init__(self, title, message, users, *args, **kwargs): + super(dm, self).__init__() + self.createControls(message, title, users) +# self.onTimer(wx.EVT_CHAR_HOOK) +# self.SetClientSize(self.mainBox.CalcMin()) + + def get_user(self): + return self.cb.GetValue() + + def set_user(self, user): + return self.cb.SetValue(user) + +class reply(textLimited): + + def get_image(self): + openFileDialog = wx.FileDialog(self, _(u"Select the picture to be uploaded"), "", "", _("Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) + if openFileDialog.ShowModal() == wx.ID_CANCEL: + return None + return open(openFileDialog.GetPath(), "rb") + + def createControls(self, title, message, text): + self.mainBox = wx.BoxSizer(wx.VERTICAL) + self.createTextArea(message, text) + self.mainBox.Add(self.textBox, 0, wx.ALL, 5) + self.usersbox = wx.BoxSizer(wx.VERTICAL) + self.mentionAll = wx.CheckBox(self.panel, -1, _(u"&Mention to all"), size=wx.DefaultSize) + self.mentionAll.Disable() + self.usersbox.Add(self.mentionAll, 0, wx.ALL, 5) + self.checkboxes = [] + for i in self.users: + user_checkbox = wx.CheckBox(self.panel, -1, "@"+i, size=wx.DefaultSize) + self.checkboxes.append(user_checkbox) + self.usersbox.Add(self.checkboxes[-1], 0, wx.ALL, 5) + self.mainBox.Add(self.usersbox, 0, wx.ALL, 10) + self.long_tweet = wx.CheckBox(self.panel, -1, _(u"&Long tweet")) + self.long_tweet.SetValue(True) + self.upload_image = wx.Button(self.panel, -1, _(u"&Upload image..."), size=wx.DefaultSize) + self.spellcheck = wx.Button(self.panel, -1, _("Check &spelling..."), size=wx.DefaultSize) + self.attach = wx.Button(self.panel, -1, _(u"&Attach audio..."), size=wx.DefaultSize) + self.shortenButton = wx.Button(self.panel, -1, _(u"Sh&orten URL"), size=wx.DefaultSize) + self.unshortenButton = wx.Button(self.panel, -1, _(u"&Expand URL"), size=wx.DefaultSize) + self.shortenButton.Disable() + self.unshortenButton.Disable() + self.translateButton = wx.Button(self.panel, -1, _(u"&Translate..."), size=wx.DefaultSize) + self.autocompletionButton = wx.Button(self.panel, -1, _(u"Auto&complete users")) + self.okButton = wx.Button(self.panel, wx.ID_OK, _(u"Sen&d"), size=wx.DefaultSize) + self.okButton.SetDefault() + cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize) + self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL) + self.buttonsBox1.Add(self.upload_image, 0, wx.ALL, 10) + self.buttonsBox1.Add(self.spellcheck, 0, wx.ALL, 10) + self.buttonsBox1.Add(self.attach, 0, wx.ALL, 10) + self.mainBox.Add(self.buttonsBox1, 0, wx.ALL, 10) + self.buttonsBox2 = wx.BoxSizer(wx.HORIZONTAL) + self.buttonsBox2.Add(self.shortenButton, 0, wx.ALL, 10) + self.buttonsBox2.Add(self.unshortenButton, 0, wx.ALL, 10) + self.buttonsBox2.Add(self.translateButton, 0, wx.ALL, 10) + self.mainBox.Add(self.buttonsBox2, 0, wx.ALL, 10) + self.ok_cancelSizer = wx.BoxSizer(wx.HORIZONTAL) + self.ok_cancelSizer.Add(self.autocompletionButton, 0, wx.ALL, 10) + self.ok_cancelSizer.Add(self.okButton, 0, wx.ALL, 10) + self.ok_cancelSizer.Add(cancelButton, 0, wx.ALL, 10) + self.mainBox.Add(self.ok_cancelSizer, 0, wx.ALL, 10) + selectId = wx.NewId() + self.Bind(wx.EVT_MENU, self.onSelect, id=selectId) + self.accel_tbl = wx.AcceleratorTable([ +(wx.ACCEL_CTRL, ord('A'), selectId), +]) + self.SetAcceleratorTable(self.accel_tbl) + self.panel.SetSizer(self.mainBox) + + def __init__(self, title, message, text, users=[], *args, **kwargs): + self.users = users + super(reply, self).__init__() + self.shift=False + self.createControls(message, title, text) + self.SetClientSize(self.mainBox.CalcMin()) + +class viewTweet(widgetUtils.BaseDialog): + def set_title(self, lenght): + self.SetTitle(_(u"Tweet - %i characters ") % (lenght,)) + + def __init__(self, text, rt_count, favs_count,source, *args, **kwargs): + super(viewTweet, self).__init__(None, size=(850,850)) + panel = wx.Panel(self) + label = wx.StaticText(panel, -1, _(u"Tweet")) + self.text = wx.TextCtrl(panel, -1, text, style=wx.TE_READONLY|wx.TE_MULTILINE, size=(250, 180)) + dc = wx.WindowDC(self.text) + dc.SetFont(self.text.GetFont()) + (x, y) = dc.GetMultiLineTextExtent("0"*140) + self.text.SetSize((x, y)) + self.text.SetFocus() + textBox = wx.BoxSizer(wx.HORIZONTAL) + textBox.Add(label, 0, wx.ALL, 5) + textBox.Add(self.text, 1, wx.EXPAND, 5) + mainBox = wx.BoxSizer(wx.VERTICAL) + mainBox.Add(textBox, 0, wx.ALL, 5) + label2 = wx.StaticText(panel, -1, _(u"Image description")) + self.image_description = wx.TextCtrl(panel, -1, style=wx.TE_READONLY|wx.TE_MULTILINE, size=(250, 180)) + dc = wx.WindowDC(self.image_description) + dc.SetFont(self.image_description.GetFont()) + (x, y) = dc.GetMultiLineTextExtent("0"*450) + self.image_description.SetSize((x, y)) + self.image_description.Enable(False) + iBox = wx.BoxSizer(wx.HORIZONTAL) + iBox.Add(label2, 0, wx.ALL, 5) + iBox.Add(self.image_description, 1, wx.EXPAND, 5) + mainBox.Add(iBox, 0, wx.ALL, 5) + rtCountLabel = wx.StaticText(panel, -1, _(u"Retweets: ")) + rtCount = wx.TextCtrl(panel, -1, rt_count, size=wx.DefaultSize, style=wx.TE_READONLY|wx.TE_MULTILINE) + rtBox = wx.BoxSizer(wx.HORIZONTAL) + rtBox.Add(rtCountLabel, 0, wx.ALL, 5) + rtBox.Add(rtCount, 0, wx.ALL, 5) + favsCountLabel = wx.StaticText(panel, -1, _(u"Likes: ")) + favsCount = wx.TextCtrl(panel, -1, favs_count, size=wx.DefaultSize, style=wx.TE_READONLY|wx.TE_MULTILINE) + favsBox = wx.BoxSizer(wx.HORIZONTAL) + favsBox.Add(favsCountLabel, 0, wx.ALL, 5) + favsBox.Add(favsCount, 0, wx.ALL, 5) + sourceLabel = wx.StaticText(panel, -1, _(u"Source: ")) + sourceTweet = wx.TextCtrl(panel, -1, source, size=wx.DefaultSize, style=wx.TE_READONLY|wx.TE_MULTILINE) + sourceBox = wx.BoxSizer(wx.HORIZONTAL) + sourceBox.Add(sourceLabel, 0, wx.ALL, 5) + sourceBox.Add(sourceTweet, 0, wx.ALL, 5) + infoBox = wx.BoxSizer(wx.HORIZONTAL) + infoBox.Add(rtBox, 0, wx.ALL, 5) + infoBox.Add(favsBox, 0, wx.ALL, 5) + infoBox.Add(sourceBox, 0, wx.ALL, 5) + mainBox.Add(infoBox, 0, wx.ALL, 5) + 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() + self.translateButton = wx.Button(panel, -1, _(u"&Translate..."), size=wx.DefaultSize) + cancelButton = wx.Button(panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize) + cancelButton.SetDefault() + buttonsBox = wx.BoxSizer(wx.HORIZONTAL) + buttonsBox.Add(self.spellcheck, 0, wx.ALL, 5) + buttonsBox.Add(self.unshortenButton, 0, wx.ALL, 5) + buttonsBox.Add(self.translateButton, 0, wx.ALL, 5) + buttonsBox.Add(cancelButton, 0, wx.ALL, 5) + mainBox.Add(buttonsBox, 0, wx.ALL, 5) + selectId = wx.NewId() + self.Bind(wx.EVT_MENU, self.onSelect, id=selectId) + self.accel_tbl = wx.AcceleratorTable([ +(wx.ACCEL_CTRL, ord('A'), selectId), +]) + self.SetAcceleratorTable(self.accel_tbl) + panel.SetSizer(mainBox) + self.SetClientSize(mainBox.CalcMin()) + + def set_text(self, text): + self.text.ChangeValue(text) + + def get_text(self): + return self.text.GetValue() + + def set_image_description(self, desc): + self.image_description.Enable(True) + if len(self.image_description.GetValue()) == 0: + self.image_description.SetValue(desc) + else: + self.image_description.SetValue(self.image_description.GetValue()+"\n"+desc) + + def text_focus(self): + self.text.SetFocus() + + def onSelect(self, ev): + self.text.SelectAll() + + def enable_button(self, buttonName): + if hasattr(self, buttonName): + return getattr(self, buttonName).Enable() + +class viewNonTweet(widgetUtils.BaseDialog): + + def __init__(self, text, *args, **kwargs): + super(viewNonTweet, self).__init__(None, size=(850,850)) + self.SetTitle(_(u"View")) + panel = wx.Panel(self) + label = wx.StaticText(panel, -1, _(u"Item")) + self.text = wx.TextCtrl(parent=panel, id=-1, value=text, style=wx.TE_READONLY|wx.TE_MULTILINE, size=(250, 180)) + dc = wx.WindowDC(self.text) + dc.SetFont(self.text.GetFont()) + (x, y) = dc.GetMultiLineTextExtent("0"*140) + self.text.SetSize((x, y)) + self.text.SetFocus() + textBox = wx.BoxSizer(wx.HORIZONTAL) + textBox.Add(label, 0, wx.ALL, 5) + textBox.Add(self.text, 1, wx.EXPAND, 5) + mainBox = wx.BoxSizer(wx.VERTICAL) + mainBox.Add(textBox, 0, wx.ALL, 5) + 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() + self.translateButton = wx.Button(panel, -1, _(u"&Translate..."), size=wx.DefaultSize) + cancelButton = wx.Button(panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize) + cancelButton.SetDefault() + buttonsBox = wx.BoxSizer(wx.HORIZONTAL) + buttonsBox.Add(self.spellcheck, 0, wx.ALL, 5) + buttonsBox.Add(self.unshortenButton, 0, wx.ALL, 5) + buttonsBox.Add(self.translateButton, 0, wx.ALL, 5) + buttonsBox.Add(cancelButton, 0, wx.ALL, 5) + mainBox.Add(buttonsBox, 0, wx.ALL, 5) + selectId = wx.NewId() + self.Bind(wx.EVT_MENU, self.onSelect, id=selectId) + self.accel_tbl = wx.AcceleratorTable([ +(wx.ACCEL_CTRL, ord('A'), selectId), +]) + self.SetAcceleratorTable(self.accel_tbl) + panel.SetSizer(mainBox) + self.SetClientSize(mainBox.CalcMin()) + + def onSelect(self, ev): + self.text.SelectAll() + + def set_text(self, text): + self.text.ChangeValue(text) + + def get_text(self): + return self.text.GetValue() + + def text_focus(self): + self.text.SetFocus() + + def enable_button(self, buttonName): + if getattr(self, buttonName): + return getattr(self, buttonName).Enable() diff --git a/src/wxUI/view.py b/src/wxUI/view.py index b0c564bd..9bc11630 100644 --- a/src/wxUI/view.py +++ b/src/wxUI/view.py @@ -1,198 +1,199 @@ -# -*- coding: utf-8 -*- -import wx -import application - -class mainFrame(wx.Frame): - """ Main class of the Frame. This is the Main Window.""" - - ### MENU - def makeMenus(self): - """ Creates, bind and returns the menu bar for the application. Also in this function, the accel table is created.""" - menuBar = wx.MenuBar() - - # Application menu - app = wx.Menu() - self.manage_accounts = app.Append(wx.NewId(), _(u"&Manage accounts")) - self.updateProfile = app.Append(wx.NewId(), _(u"&Update profile")) - self.show_hide = app.Append(wx.NewId(), _(u"&Hide window")) - self.menuitem_search = app.Append(wx.NewId(), _(u"&Search")) - self.lists = app.Append(wx.NewId(), _(u"&Lists manager")) - self.keystroke_editor = app.Append(wx.NewId(), _(u"&Edit keystrokes")) - self.account_settings = app.Append(wx.NewId(), _(u"Account se&ttings")) - self.prefs = app.Append(wx.ID_PREFERENCES, _(u"&Global settings")) - self.close = app.Append(wx.ID_EXIT, _(u"E&xit")) - - # Tweet menu - tweet = wx.Menu() - self.compose = tweet.Append(wx.NewId(), _(u"&Tweet")) - self.reply = tweet.Append(wx.NewId(), _(u"Re&ply")) - self.retweet = tweet.Append(wx.NewId(), _(u"&Retweet")) - self.fav = tweet.Append(wx.NewId(), _(u"&Like")) - self.unfav = tweet.Append(wx.NewId(), _(u"&Unlike")) - self.view = tweet.Append(wx.NewId(), _(u"&Show tweet")) - self.view_coordinates = tweet.Append(wx.NewId(), _(u"View &address")) - self.view_conversation = tweet.Append(wx.NewId(), _(u"View conversa&tion")) - self.ocr = tweet.Append(wx.NewId(), _(u"Read text in picture")) - self.delete = tweet.Append(wx.NewId(), _(u"&Delete")) - - # User menu - user = wx.Menu() - self.follow = user.Append(wx.NewId(), _(u"&Actions...")) - self.timeline = user.Append(wx.NewId(), _(u"&View timeline...")) - self.dm = user.Append(wx.NewId(), _(u"Direct me&ssage")) - self.addToList = user.Append(wx.NewId(), _(u"&Add to list")) - self.removeFromList = user.Append(wx.NewId(), _(u"R&emove from list")) - self.viewLists = user.Append(wx.NewId(), _(u"&View lists")) - self.details = user.Append(wx.NewId(), _(u"Show user &profile")) - self.favs = user.Append(wx.NewId(), _(u"V&iew likes")) - - # buffer menu - buffer = wx.Menu() - self.update_buffer = buffer.Append(wx.NewId(), _(u"&Update buffer")) - self.trends = buffer.Append(wx.NewId(), _(u"New &trending topics buffer...")) - self.find = buffer.Append(wx.NewId(), _(u"Find a string in the currently focused buffer...")) - self.load_previous_items = buffer.Append(wx.NewId(), _(u"&Load previous items")) - buffer.AppendSeparator() - self.mute_buffer = buffer.AppendCheckItem(wx.NewId(), _(u"&Mute")) - self.autoread = buffer.AppendCheckItem(wx.NewId(), _(u"&Autoread")) - self.clear = buffer.Append(wx.NewId(), _(u"&Clear buffer")) - self.deleteTl = buffer.Append(wx.NewId(), _(u"&Destroy")) - - # audio menu - audio = wx.Menu() - self.seekLeft = audio.Append(wx.NewId(), _(u"&Seek back 5 seconds")) - self.seekRight = audio.Append(wx.NewId(), _(u"&Seek forward 5 seconds")) - - # Help Menu - help = wx.Menu() - self.doc = help.Append(-1, _(u"&Documentation")) - self.sounds_tutorial = help.Append(wx.NewId(), _(u"Sounds &tutorial")) - self.changelog = help.Append(wx.NewId(), _(u"&What's new in this version?")) - self.check_for_updates = help.Append(wx.NewId(), _(u"&Check for updates")) - self.reportError = help.Append(wx.NewId(), _(u"&Report an error")) - self.visit_website = help.Append(-1, _(u"{0}'s &website").format(application.name,)) - self.about = help.Append(-1, _(u"About &{0}").format(application.name,)) - - # Add all to the menu Bar - menuBar.Append(app, _(u"&Application")) - menuBar.Append(tweet, _(u"&Tweet")) - menuBar.Append(user, _(u"&User")) - menuBar.Append(buffer, _(u"&Buffer")) - menuBar.Append(audio, _(u"&Audio")) - menuBar.Append(help, _(u"&Help")) - - self.accel_tbl = wx.AcceleratorTable([ -(wx.ACCEL_CTRL, ord('N'), self.compose.GetId()), -(wx.ACCEL_CTRL, ord('R'), self.reply.GetId()), -(wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('R'), self.retweet.GetId()), -(wx.ACCEL_CTRL, ord('F'), self.fav.GetId()), -(wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('F'), self.unfav.GetId()), -(wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('V'), self.view.GetId()), -(wx.ACCEL_CTRL, ord('D'), self.dm.GetId()), - -(wx.ACCEL_CTRL, ord('Q'), self.close.GetId()), -(wx.ACCEL_CTRL, ord('S'), self.follow.GetId()), -(wx.ACCEL_CTRL, ord('I'), self.timeline.GetId()), -(wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('I'), self.deleteTl.GetId()), -(wx.ACCEL_CTRL, ord('M'), self.show_hide.GetId()), -(wx.ACCEL_CTRL, wx.WXK_LEFT, self.seekLeft.GetId()), -(wx.ACCEL_CTRL, ord('P'), self.updateProfile.GetId()), -(wx.ACCEL_CTRL, wx.WXK_RIGHT, self.seekRight.GetId()), -(wx.ACCEL_CTRL, ord(' '), self.seekLeft.GetId()), - ]) - - self.SetAcceleratorTable(self.accel_tbl) - return menuBar - - ### MAIN - def __init__(self): - """ Main function of this class.""" - super(mainFrame, self).__init__(None, -1, application.name, size=(1600, 1600)) - self.panel = wx.Panel(self) - self.sizer = wx.BoxSizer(wx.VERTICAL) - self.SetTitle(application.name) - self.SetMenuBar(self.makeMenus()) - self.nb = wx.Treebook(self.panel, wx.NewId()) - self.buffers = {} - - def get_buffer_count(self): - return self.nb.GetPageCount() - - def add_buffer(self, buffer, name): - self.nb.AddPage(buffer, name) - self.buffers[name] = buffer.GetId() - - def insert_buffer(self, buffer, name, pos): - self.nb.InsertSubPage(pos, buffer, name) - self.buffers[name] = buffer.GetId() - - def prepare(self): - self.sizer.Add(self.nb, 0, wx.ALL, 5) - self.panel.SetSizer(self.sizer) -# self.Maximize() - self.sizer.Layout() - self.SetClientSize(self.sizer.CalcMin()) -# print self.GetSize() - - def get_buffers(self): - return [self.nb.GetPage(i) for i in range(0, self.nb.GetPageCount())] - - def search(self, name_, account): - for i in range(0, self.nb.GetPageCount()): - if self.nb.GetPage(i).name == name_ and self.nb.GetPage(i).account == account: return i - - def get_current_buffer(self): - return self.nb.GetCurrentPage() - - def get_current_buffer_pos(self): - return self.nb.GetSelection() - - def get_buffer(self, pos): - return self.GetPage(pos) - - def change_buffer(self, position): - self.nb.ChangeSelection(position) - - def get_buffer_text(self): - return self.nb.GetPageText(self.nb.GetSelection()) - - def get_buffer_by_id(self, id): - return self.nb.FindWindowById(id) - def advance_selection(self, forward): - self.nb.AdvanceSelection(forward) - - def show(self): - self.Show() - - def show_address(self, address): - wx.MessageDialog(self, address, _(u"Address"), wx.OK).ShowModal() - - def delete_buffer(self, pos): - self.nb.DeletePage(pos) - - def about_dialog(self): - info = wx.AboutDialogInfo() - info.SetName(application.name) - info.SetVersion(application.version) - info.SetDescription(application.description) - info.SetCopyright(application.copyright) - info.SetTranslators(application.translators) -# info.SetLicence(application.licence) - for i in application.authors: - info.AddDeveloper(i) - wx.AboutBox(info) - def set_focus(self): - self.SetFocus() - - def check_menuitem(self, menuitem, check=True): - if hasattr(self, menuitem): - getattr(self, menuitem).Check(check) - - def set_page_title(self, page, title): - return self.nb.SetPageText(page, title) - - def get_page_title(self, page): - return self.nb.GetPageText(page) - -def no_update_available(): - wx.MessageDialog(None, _(u"Your {0} version is up to date").format(application.name,), _(u"Update"), style=wx.OK).ShowModal() +# -*- coding: utf-8 -*- +from builtins import range +import wx +import application + +class mainFrame(wx.Frame): + """ Main class of the Frame. This is the Main Window.""" + + ### MENU + def makeMenus(self): + """ Creates, bind and returns the menu bar for the application. Also in this function, the accel table is created.""" + menuBar = wx.MenuBar() + + # Application menu + app = wx.Menu() + self.manage_accounts = app.Append(wx.NewId(), _(u"&Manage accounts")) + self.updateProfile = app.Append(wx.NewId(), _(u"&Update profile")) + self.show_hide = app.Append(wx.NewId(), _(u"&Hide window")) + self.menuitem_search = app.Append(wx.NewId(), _(u"&Search")) + self.lists = app.Append(wx.NewId(), _(u"&Lists manager")) + self.keystroke_editor = app.Append(wx.NewId(), _(u"&Edit keystrokes")) + self.account_settings = app.Append(wx.NewId(), _(u"Account se&ttings")) + self.prefs = app.Append(wx.ID_PREFERENCES, _(u"&Global settings")) + self.close = app.Append(wx.ID_EXIT, _(u"E&xit")) + + # Tweet menu + tweet = wx.Menu() + self.compose = tweet.Append(wx.NewId(), _(u"&Tweet")) + self.reply = tweet.Append(wx.NewId(), _(u"Re&ply")) + self.retweet = tweet.Append(wx.NewId(), _(u"&Retweet")) + self.fav = tweet.Append(wx.NewId(), _(u"&Like")) + self.unfav = tweet.Append(wx.NewId(), _(u"&Unlike")) + self.view = tweet.Append(wx.NewId(), _(u"&Show tweet")) + self.view_coordinates = tweet.Append(wx.NewId(), _(u"View &address")) + self.view_conversation = tweet.Append(wx.NewId(), _(u"View conversa&tion")) + self.ocr = tweet.Append(wx.NewId(), _(u"Read text in picture")) + self.delete = tweet.Append(wx.NewId(), _(u"&Delete")) + + # User menu + user = wx.Menu() + self.follow = user.Append(wx.NewId(), _(u"&Actions...")) + self.timeline = user.Append(wx.NewId(), _(u"&View timeline...")) + self.dm = user.Append(wx.NewId(), _(u"Direct me&ssage")) + self.addToList = user.Append(wx.NewId(), _(u"&Add to list")) + self.removeFromList = user.Append(wx.NewId(), _(u"R&emove from list")) + self.viewLists = user.Append(wx.NewId(), _(u"&View lists")) + self.details = user.Append(wx.NewId(), _(u"Show user &profile")) + self.favs = user.Append(wx.NewId(), _(u"V&iew likes")) + + # buffer menu + buffer = wx.Menu() + self.update_buffer = buffer.Append(wx.NewId(), _(u"&Update buffer")) + self.trends = buffer.Append(wx.NewId(), _(u"New &trending topics buffer...")) + self.find = buffer.Append(wx.NewId(), _(u"Find a string in the currently focused buffer...")) + self.load_previous_items = buffer.Append(wx.NewId(), _(u"&Load previous items")) + buffer.AppendSeparator() + self.mute_buffer = buffer.AppendCheckItem(wx.NewId(), _(u"&Mute")) + self.autoread = buffer.AppendCheckItem(wx.NewId(), _(u"&Autoread")) + self.clear = buffer.Append(wx.NewId(), _(u"&Clear buffer")) + self.deleteTl = buffer.Append(wx.NewId(), _(u"&Destroy")) + + # audio menu + audio = wx.Menu() + self.seekLeft = audio.Append(wx.NewId(), _(u"&Seek back 5 seconds")) + self.seekRight = audio.Append(wx.NewId(), _(u"&Seek forward 5 seconds")) + + # Help Menu + help = wx.Menu() + self.doc = help.Append(-1, _(u"&Documentation")) + self.sounds_tutorial = help.Append(wx.NewId(), _(u"Sounds &tutorial")) + self.changelog = help.Append(wx.NewId(), _(u"&What's new in this version?")) + self.check_for_updates = help.Append(wx.NewId(), _(u"&Check for updates")) + self.reportError = help.Append(wx.NewId(), _(u"&Report an error")) + self.visit_website = help.Append(-1, _(u"{0}'s &website").format(application.name,)) + self.about = help.Append(-1, _(u"About &{0}").format(application.name,)) + + # Add all to the menu Bar + menuBar.Append(app, _(u"&Application")) + menuBar.Append(tweet, _(u"&Tweet")) + menuBar.Append(user, _(u"&User")) + menuBar.Append(buffer, _(u"&Buffer")) + menuBar.Append(audio, _(u"&Audio")) + menuBar.Append(help, _(u"&Help")) + + self.accel_tbl = wx.AcceleratorTable([ +(wx.ACCEL_CTRL, ord('N'), self.compose.GetId()), +(wx.ACCEL_CTRL, ord('R'), self.reply.GetId()), +(wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('R'), self.retweet.GetId()), +(wx.ACCEL_CTRL, ord('F'), self.fav.GetId()), +(wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('F'), self.unfav.GetId()), +(wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('V'), self.view.GetId()), +(wx.ACCEL_CTRL, ord('D'), self.dm.GetId()), + +(wx.ACCEL_CTRL, ord('Q'), self.close.GetId()), +(wx.ACCEL_CTRL, ord('S'), self.follow.GetId()), +(wx.ACCEL_CTRL, ord('I'), self.timeline.GetId()), +(wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('I'), self.deleteTl.GetId()), +(wx.ACCEL_CTRL, ord('M'), self.show_hide.GetId()), +(wx.ACCEL_CTRL, wx.WXK_LEFT, self.seekLeft.GetId()), +(wx.ACCEL_CTRL, ord('P'), self.updateProfile.GetId()), +(wx.ACCEL_CTRL, wx.WXK_RIGHT, self.seekRight.GetId()), +(wx.ACCEL_CTRL, ord(' '), self.seekLeft.GetId()), + ]) + + self.SetAcceleratorTable(self.accel_tbl) + return menuBar + + ### MAIN + def __init__(self): + """ Main function of this class.""" + super(mainFrame, self).__init__(None, -1, application.name, size=(1600, 1600)) + self.panel = wx.Panel(self) + self.sizer = wx.BoxSizer(wx.VERTICAL) + self.SetTitle(application.name) + self.SetMenuBar(self.makeMenus()) + self.nb = wx.Treebook(self.panel, wx.NewId()) + self.buffers = {} + + def get_buffer_count(self): + return self.nb.GetPageCount() + + def add_buffer(self, buffer, name): + self.nb.AddPage(buffer, name) + self.buffers[name] = buffer.GetId() + + def insert_buffer(self, buffer, name, pos): + self.nb.InsertSubPage(pos, buffer, name) + self.buffers[name] = buffer.GetId() + + def prepare(self): + self.sizer.Add(self.nb, 0, wx.ALL, 5) + self.panel.SetSizer(self.sizer) +# self.Maximize() + self.sizer.Layout() + self.SetClientSize(self.sizer.CalcMin()) +# print self.GetSize() + + def get_buffers(self): + return [self.nb.GetPage(i) for i in range(0, self.nb.GetPageCount())] + + def search(self, name_, account): + for i in range(0, self.nb.GetPageCount()): + if self.nb.GetPage(i).name == name_ and self.nb.GetPage(i).account == account: return i + + def get_current_buffer(self): + return self.nb.GetCurrentPage() + + def get_current_buffer_pos(self): + return self.nb.GetSelection() + + def get_buffer(self, pos): + return self.GetPage(pos) + + def change_buffer(self, position): + self.nb.ChangeSelection(position) + + def get_buffer_text(self): + return self.nb.GetPageText(self.nb.GetSelection()) + + def get_buffer_by_id(self, id): + return self.nb.FindWindowById(id) + def advance_selection(self, forward): + self.nb.AdvanceSelection(forward) + + def show(self): + self.Show() + + def show_address(self, address): + wx.MessageDialog(self, address, _(u"Address"), wx.OK).ShowModal() + + def delete_buffer(self, pos): + self.nb.DeletePage(pos) + + def about_dialog(self): + info = wx.AboutDialogInfo() + info.SetName(application.name) + info.SetVersion(application.version) + info.SetDescription(application.description) + info.SetCopyright(application.copyright) + info.SetTranslators(application.translators) +# info.SetLicence(application.licence) + for i in application.authors: + info.AddDeveloper(i) + wx.AboutBox(info) + def set_focus(self): + self.SetFocus() + + def check_menuitem(self, menuitem, check=True): + if hasattr(self, menuitem): + getattr(self, menuitem).Check(check) + + def set_page_title(self, page, title): + return self.nb.SetPageText(page, title) + + def get_page_title(self, page): + return self.nb.GetPageText(page) + +def no_update_available(): + wx.MessageDialog(None, _(u"Your {0} version is up to date").format(application.name,), _(u"Update"), style=wx.OK).ShowModal()