first step in python3 support

This commit is contained in:
Romain Bignon 2014-05-17 13:37:47 +02:00
commit 6fcac89dd5
25 changed files with 302 additions and 208 deletions

View file

@ -18,9 +18,14 @@
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from urlparse import urlsplit, parse_qsl, urlparse
try:
from urlparse import urlsplit, parse_qsl, urlparse
except ImportError:
from urllib.parse import urlsplit, parse_qsl, urlparse
from datetime import datetime, timedelta
from weboob.tools.compat import basestring
from weboob.tools.browser2 import LoginBrowser, URL, Wget, need_login
from weboob.tools.exceptions import BrowserIncorrectPassword
from weboob.capabilities.bank import Transfer, TransferError

View file

@ -18,7 +18,11 @@
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from urlparse import urlparse, parse_qs
try:
from urlparse import urlparse, parse_qs
except ImportError:
from urllib.parse import urlparse, parse_qs
from decimal import Decimal
import re
from dateutil.relativedelta import relativedelta

View file

@ -17,6 +17,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from __future__ import print_function
import datetime, uuid
from dateutil.relativedelta import relativedelta
@ -321,15 +322,15 @@ class Boobank(ReplApplication):
account = self.get_object(id, 'get_account', [])
if not account:
print >>sys.stderr, 'Error: account "%s" not found (Hint: try the command "list")' % id
print('Error: account "%s" not found (Hint: try the command "list")' % id, file=sys.stderr)
return 2
if end_date is not None:
try:
end_date = parse_date(end_date)
except ValueError:
print >>sys.stderr, '"%s" is an incorrect date format (for example "%s")' % \
(end_date, (datetime.date.today() - relativedelta(months=1)).strftime('%Y-%m-%d'))
print('"%s" is an incorrect date format (for example "%s")' % \
(end_date, (datetime.date.today() - relativedelta(months=1)).strftime('%Y-%m-%d')), file=sys.stderr)
return 3
old_count = self.options.count
self.options.count = None
@ -399,7 +400,7 @@ class Boobank(ReplApplication):
account = self.get_object(id_from, 'get_account', [])
if not account:
print >>sys.stderr, 'Error: account %s not found' % id_from
print('Error: account %s not found' % id_from, file=sys.stderr)
return 1
if not id_to:
@ -415,13 +416,13 @@ class Boobank(ReplApplication):
id_to, backend_name_to = self.parse_id(id_to)
if account.backend != backend_name_to:
print >>sys.stderr, "Transfer between different backends is not implemented"
print("Transfer between different backends is not implemented", file=sys.stderr)
return 4
try:
amount = Decimal(amount)
except (TypeError, ValueError, InvalidOperation):
print >>sys.stderr, 'Error: please give a decimal amount to transfer'
print('Error: please give a decimal amount to transfer', file=sys.stderr)
return 2
if self.interactive:
@ -434,10 +435,10 @@ class Boobank(ReplApplication):
to = recipient.label
break
print 'Amount: %s%s' % (amount, account.currency_text)
print 'From: %s' % account.label
print 'To: %s' % to
print 'Reason: %s' % (reason or '')
print('Amount: %s%s' % (amount, account.currency_text))
print('From: %s' % account.label)
print('To: %s' % to)
print('Reason: %s' % (reason or ''))
if not self.ask('Are you sure to do this transfer?', default=True):
return
@ -453,7 +454,7 @@ class Boobank(ReplApplication):
"""
account = self.get_object(id, 'get_account', [])
if not account:
print >>sys.stderr, 'Error: account "%s" not found (Hint: try the command "list")' % id
print('Error: account "%s" not found (Hint: try the command "list")' % id, file=sys.stderr)
return 2
self.start_format()

View file

@ -22,6 +22,8 @@ from datetime import date, datetime
from binascii import crc32
import re
from weboob.tools.compat import basestring, long
from .base import CapBaseObject, Field, StringField, DateField, DecimalField, IntField, UserError, Currency
from .collection import ICapCollection

View file

@ -24,6 +24,7 @@ import re
from decimal import Decimal
from copy import deepcopy, copy
from weboob.tools.compat import unicode, long
from weboob.tools.misc import to_unicode
from weboob.tools.date import new_date, new_datetime
from weboob.tools.ordereddict import OrderedDict

View file

@ -23,7 +23,10 @@
import stat
import os
import sys
from ConfigParser import RawConfigParser, DuplicateSectionError
try:
from ConfigParser import RawConfigParser, DuplicateSectionError
except ImportError:
from configparser import RawConfigParser, DuplicateSectionError
from logging import warning
__all__ = ['BackendsConfig', 'BackendAlreadyExists']

View file

@ -20,7 +20,10 @@
from copy import copy
from threading import Thread
import Queue
try:
import Queue
except ImportError:
import queue as Queue
from weboob.capabilities.base import CapBaseObject
from weboob.tools.misc import get_backtrace

View file

@ -18,7 +18,7 @@
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from __future__ import print_function
import imp
import tarfile
import posixpath
@ -32,29 +32,24 @@ from tempfile import NamedTemporaryFile
from datetime import datetime
from contextlib import closing
from compileall import compile_dir
from StringIO import StringIO
from io import BytesIO
from .modules import Module
from weboob.tools.log import getLogger
from weboob.tools.misc import to_unicode
from weboob.tools.browser import StandardBrowser, BrowserUnavailable
from ConfigParser import RawConfigParser, DEFAULTSECT
from weboob.tools.browser2.browser import BaseBrowser, Weboob as WeboobProfile
try:
from configparser import RawConfigParser, DEFAULTSECT
except ImportError:
from ConfigParser import RawConfigParser, DEFAULTSECT
BrowserUnavailable = object()
__all__ = ['IProgress', 'ModuleInstallError', 'ModuleInfo', 'RepositoryUnavailable',
'Repository', 'Versions', 'Repositories', 'InvalidSignature', 'Keyring']
class WeboobBrowser(StandardBrowser):
"""
Browser with a specific useragent.
"""
@classmethod
def set_version(klass, version):
klass.USER_AGENT = 'weboob/%s' % version
class ModuleInfo(object):
"""
Information about a module available on a repository.
@ -125,7 +120,8 @@ class Repository(object):
KEYDIR = '.keys'
KEYRING = 'trusted.gpg'
def __init__(self, url):
def __init__(self, browser, url):
self.browser = browser
self.url = url
self.name = u''
self.update = 0
@ -179,9 +175,8 @@ class Repository(object):
fp = open(filename, 'r')
else:
# This is a remote repository, download file
browser = WeboobBrowser()
try:
fp = browser.openurl(posixpath.join(self.url, self.INDEX))
fp = BytesIO(self.browser.open(posixpath.join(self.url, self.INDEX)).content)
except BrowserUnavailable as e:
raise RepositoryUnavailable(unicode(e))
@ -208,20 +203,19 @@ class Repository(object):
if not keyring.exists() or self.key_update > keyring.version:
# This is a remote repository, download file
browser = WeboobBrowser()
try:
keyring_data = browser.readurl(posixpath.join(self.url, self.KEYRING))
sig_data = browser.readurl(posixpath.join(self.url, self.KEYRING + '.sig'))
keyring_data = self.browser.open(posixpath.join(self.url, self.KEYRING)).content
sig_data = self.browser.open(posixpath.join(self.url, self.KEYRING + '.sig')).content
except BrowserUnavailable as e:
raise RepositoryUnavailable(unicode(e))
if keyring.exists():
if not keyring.is_valid(keyring_data, sig_data):
raise InvalidSignature('the keyring itself')
print 'The keyring was updated (and validated by the previous one).'
print('The keyring was updated (and validated by the previous one).')
else:
print 'First time saving the keyring, blindly accepted.'
print('First time saving the keyring, blindly accepted.')
keyring.save(keyring_data, self.key_update)
print keyring
print(keyring)
def parse_index(self, fp):
"""
@ -275,7 +269,7 @@ class Repository(object):
:param filename: file to save index
:type filename: str
"""
print 'Rebuild index'
print('Rebuild index')
self.modules.clear()
if os.path.isdir(os.path.join(path, self.KEYDIR)):
@ -298,7 +292,7 @@ class Repository(object):
if fp:
fp.close()
except Exception as e:
print >>sys.stderr, 'Unable to build module %s: [%s] %s' % (name, type(e).__name__, e)
print('Unable to build module %s: [%s] %s' % (name, type(e).__name__, e), file=sys.stderr)
else:
m = ModuleInfo(module.name)
m.version = self.get_tree_mtime(module_path)
@ -388,10 +382,10 @@ class Versions(object):
class IProgress(object):
def progress(self, percent, message):
print '=== [%3.0f%%] %s' % (percent*100, message)
print('=== [%3.0f%%] %s' % (percent*100, message))
def error(self, message):
print >>sys.stderr, 'ERROR: %s' % message
print('ERROR: %s' % message, file=sys.stderr)
class ModuleInstallError(Exception):
@ -425,7 +419,11 @@ class Repositories(object):
def __init__(self, workdir, datadir, version):
self.logger = getLogger('repositories')
self.version = version
WeboobBrowser.set_version(version)
class WeboobBrowser(BaseBrowser):
PROFILE = WeboobProfile(version)
self.browser = WeboobBrowser()
self.workdir = workdir
self.datadir = datadir
@ -503,10 +501,10 @@ class Repositories(object):
for name in sorted(os.listdir(self.repos_dir)):
path = os.path.join(self.repos_dir, name)
try:
repository = Repository(path)
repository = Repository(self.browser, path)
self.repositories.append(repository)
except RepositoryUnavailable as e:
print >>sys.stderr, 'Unable to load repository %s (%s), try to update repositories.' % (name, e)
print('Unable to load repository %s (%s), try to update repositories.' % (name, e), file=sys.stderr)
def get_module_icon_path(self, module):
return os.path.join(self.icons_dir, '%s.png' % module.name)
@ -530,14 +528,13 @@ class Repositories(object):
else:
icon_url = module.url.replace('.tar.gz', '.png')
browser = WeboobBrowser()
try:
icon = browser.openurl(icon_url)
icon = self.browser.open(icon_url)
except BrowserUnavailable:
pass # no icon, no problem
else:
with open(dest_path, 'wb') as fp:
fp.write(icon.read())
fp.write(icon.content)
def _parse_source_list(self):
l = []
@ -564,7 +561,7 @@ class Repositories(object):
gpgv = Keyring.find_gpgv()
for line in self._parse_source_list():
progress.progress(0.0, 'Getting %s' % line)
repository = Repository(line)
repository = Repository(self.browser, line)
filename = self.url2filename(repository.url)
prio_filename = '%02d-%s' % (len(self.repositories), filename)
repo_path = os.path.join(self.repos_dir, prio_filename)
@ -587,7 +584,7 @@ class Repositories(object):
"""
l = []
for line in self._parse_source_list():
repository = Repository(line)
repository = Repository(self.browser, line)
filename = self.url2filename(repository.url)
prio_filename = '%02d-%s' % (len(l), filename)
repo_path = os.path.join(self.repos_dir, prio_filename)
@ -657,17 +654,16 @@ class Repositories(object):
else:
raise ModuleInstallError('The latest version of %s is already installed' % module.name)
browser = WeboobBrowser()
progress.progress(0.2, 'Downloading module...')
try:
tardata = browser.readurl(module.url)
tardata = self.browser.open(module.url).content
except BrowserUnavailable as e:
raise ModuleInstallError('Unable to fetch module: %s' % e)
# Check signature
if module.signed and Keyring.find_gpgv():
progress.progress(0.5, 'Checking module authenticity...')
sig_data = browser.readurl(posixpath.join(module.url + '.sig'))
sig_data = self.browser.open(posixpath.join(module.url + '.sig')).content
keyring_path = os.path.join(self.keyrings_dir, self.url2filename(module.repo_url))
keyring = Keyring(keyring_path)
if not keyring.exists():
@ -679,7 +675,7 @@ class Repositories(object):
if os.path.isdir(module_dir):
shutil.rmtree(module_dir)
progress.progress(0.7, 'Setting up module...')
with closing(tarfile.open('', 'r:gz', StringIO(tardata))) as tar:
with closing(tarfile.open('', 'r:gz', BytesIO(tardata))) as tar:
tar.extractall(self.modules_dir)
if not os.path.isdir(module_dir):
raise ModuleInstallError('The archive for %s looks invalid.' % module.name)
@ -776,7 +772,7 @@ class Keyring(object):
stderr=subprocess.PIPE)
out, err = proc.communicate(data)
if proc.returncode or 'GOODSIG' not in out or 'VALIDSIG' not in out:
print >>sys.stderr, out, err
print(out, err, file=sys.stderr)
return False
return True

View file

@ -18,9 +18,14 @@
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from __future__ import print_function
from threading import Event, RLock
try:
from threading import _Timer as Timer
except ImportError:
from threading import Timer
from threading import Timer, Event, RLock, _Timer
from weboob.tools.log import getLogger
from weboob.tools.misc import get_backtrace
@ -45,14 +50,14 @@ class IScheduler(object):
raise NotImplementedError()
class RepeatedTimer(_Timer):
class RepeatedTimer(Timer):
def run(self):
while not self.finished.isSet():
try:
self.function(*self.args, **self.kwargs)
except Exception:
# do not stop timer because of an exception
print get_backtrace()
print(get_backtrace())
self.finished.wait(self.interval)
self.finished.set()

View file

@ -18,6 +18,8 @@
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from __future__ import print_function
import logging
import optparse
from optparse import OptionGroup, OptionParser
@ -27,7 +29,6 @@ import tempfile
import warnings
from weboob.capabilities.base import ConversionWarning, CapBaseObject
from weboob.tools.browser.browser import FormFieldConversionWarning
from weboob.core import Weboob, CallErrors
from weboob.core.backendscfg import BackendsConfig
from weboob.tools.config.iconfig import ConfigError
@ -295,9 +296,9 @@ class BaseApplication(object):
if isinstance(error, MoreResultsAvailable):
return False
print >>sys.stderr, u'Error(%s): %s' % (backend.name, error)
print(u'Error(%s): %s' % (backend.name, error), file=sys.stderr)
if logging.root.level == logging.DEBUG:
print >>sys.stderr, backtrace
print(backtrace, file=sys.stderr)
else:
return True
@ -322,7 +323,7 @@ class BaseApplication(object):
ask_debug_mode = True
if ask_debug_mode:
print >>sys.stderr, debugmsg
print(debugmsg, file=sys.stderr)
def parse_args(self, args):
self.options, args = self._parser.parse_args(args)
@ -333,7 +334,7 @@ class BaseApplication(object):
if not option.help is optparse.SUPPRESS_HELP:
items.update(str(option).split('/'))
items.update(self._get_completions())
print ' '.join(items)
print(' '.join(items))
sys.exit(0)
if self.options.debug or self.options.save_responses:
@ -350,13 +351,18 @@ class BaseApplication(object):
# this only matters to developers
if not self.options.debug and not self.options.save_responses:
warnings.simplefilter('ignore', category=ConversionWarning)
warnings.simplefilter('ignore', category=FormFieldConversionWarning)
try:
from weboob.tools.browser.browser import FormFieldConversionWarning
except ImportError:
pass
else:
warnings.simplefilter('ignore', category=FormFieldConversionWarning)
handlers = []
if self.options.save_responses:
responses_dirname = tempfile.mkdtemp(prefix='weboob_session_')
print >>sys.stderr, 'Debug data will be saved in this directory: %s' % responses_dirname
print('Debug data will be saved in this directory: %s' % responses_dirname, file=sys.stderr)
log_settings['save_responses'] = True
log_settings['responses_dirname'] = responses_dirname
handlers.append(self.create_logging_file_handler(os.path.join(responses_dirname, 'debug.log')))
@ -424,12 +430,12 @@ class BaseApplication(object):
cls.setup_logging(logging.INFO, [cls.create_default_logger()])
if args is None:
args = [(sys.stdin.encoding and arg.decode(sys.stdin.encoding) or to_unicode(arg)) for arg in sys.argv]
args = [(sys.stdin.encoding and isinstance(arg, bytes) and arg.decode(sys.stdin.encoding) or to_unicode(arg)) for arg in sys.argv]
try:
app = cls()
except BackendsConfig.WrongPermissions as e:
print >>sys.stderr, e
print(e, file=sys.stderr)
sys.exit(1)
try:
@ -437,12 +443,12 @@ class BaseApplication(object):
args = app.parse_args(args)
sys.exit(app.main(args))
except KeyboardInterrupt:
print >>sys.stderr, 'Program killed by SIGINT'
print('Program killed by SIGINT', file=sys.stderr)
sys.exit(0)
except EOFError:
sys.exit(0)
except ConfigError as e:
print >>sys.stderr, 'Configuration error: %s' % e
print('Configuration error: %s' % e, file=sys.stderr)
sys.exit(1)
except CallErrors as e:
try:
@ -451,7 +457,7 @@ class BaseApplication(object):
pass
sys.exit(1)
except ResultsConditionError as e:
print >>sys.stderr, '%s' % e
print('%s' % e, file=sys.stderr)
sys.exit(1)
finally:
app.deinit()

View file

@ -18,6 +18,7 @@
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from __future__ import print_function
from copy import copy
import getpass
@ -110,7 +111,7 @@ class ConsoleApplication(BaseApplication):
ret = super(ConsoleApplication, self).load_backends(*args, **kwargs)
for err in errors:
print >>sys.stderr, 'Error(%s): %s' % (err.backend_name, err)
print('Error(%s): %s' % (err.backend_name, err), file=sys.stderr)
if self.ask('Do you want to reconfigure this backend?', default=True):
self.edit_backend(err.backend_name)
self.load_backends(names=[err.backend_name])
@ -124,7 +125,7 @@ class ConsoleApplication(BaseApplication):
def check_loaded_backends(self, default_config=None):
while len(self.enabled_backends) == 0:
print 'Warning: there is currently no configured backend for %s' % self.APPNAME
print('Warning: there is currently no configured backend for %s' % self.APPNAME)
if not os.isatty(sys.stdout.fileno()) or not self.ask('Do you want to configure backends?', default=True):
return False
@ -136,7 +137,7 @@ class ConsoleApplication(BaseApplication):
r = ''
while r != 'q':
modules = []
print '\nAvailable modules:'
print('\nAvailable modules:')
for name, info in sorted(self.weboob.repositories.get_all_modules_info().iteritems()):
if not self.is_module_loadable(info):
continue
@ -150,16 +151,16 @@ class ConsoleApplication(BaseApplication):
loaded = 2
else:
loaded += 1
print '%s%d)%s [%s] %s%-15s%s %s' % (self.BOLD, len(modules), self.NC, loaded,
self.BOLD, name, self.NC, info.description)
print '%sa) --all--%s install all backends' % (self.BOLD, self.NC)
print '%sq)%s --stop--\n' % (self.BOLD, self.NC)
print('%s%d)%s [%s] %s%-15s%s %s' % (self.BOLD, len(modules), self.NC, loaded,
self.BOLD, name, self.NC, info.description))
print('%sa) --all--%s install all backends' % (self.BOLD, self.NC))
print('%sq)%s --stop--\n' % (self.BOLD, self.NC))
r = self.ask('Select a backend to create (q to stop)', regexp='^(\d+|q|a)$')
if str(r).isdigit():
i = int(r) - 1
if i < 0 or i >= len(modules):
print >>sys.stderr, 'Error: %s is not a valid choice' % r
print('Error: %s is not a valid choice' % r, file=sys.stderr)
continue
name = modules[i]
try:
@ -167,7 +168,7 @@ class ConsoleApplication(BaseApplication):
if inst:
self.load_backends(names=[inst])
except (KeyboardInterrupt, EOFError):
print '\nAborted.'
print('\nAborted.')
elif r == 'a':
try:
for name in modules:
@ -177,11 +178,11 @@ class ConsoleApplication(BaseApplication):
if inst:
self.load_backends(names=[inst])
except (KeyboardInterrupt, EOFError):
print '\nAborted.'
print('\nAborted.')
else:
break
print 'Right right!'
print('Right right!')
def _handle_options(self):
self.load_default_backends()
@ -202,7 +203,7 @@ class ConsoleApplication(BaseApplication):
try:
super(ConsoleApplication, klass).run(args)
except BackendNotFound as e:
print 'Error: Backend "%s" not found.' % e
print('Error: Backend "%s" not found.' % e)
sys.exit(1)
def do(self, function, *args, **kwargs):
@ -234,11 +235,11 @@ class ConsoleApplication(BaseApplication):
backend = None
if not backend:
print >>sys.stderr, 'Backend "%s" does not exist.' % name
print('Backend "%s" does not exist.' % name, file=sys.stderr)
return 1
if not backend.has_caps(ICapAccount) or backend.klass.ACCOUNT_REGISTER_PROPERTIES is None:
print >>sys.stderr, 'You can\'t register a new account with %s' % name
print('You can\'t register a new account with %s' % name, file=sys.stderr)
return 1
account = Account()
@ -252,17 +253,17 @@ class ConsoleApplication(BaseApplication):
for key, prop in backend.klass.ACCOUNT_REGISTER_PROPERTIES.iteritems():
if not asked_config:
asked_config = True
print 'Configuration of new account %s' % website
print '-----------------------------%s' % ('-' * len(website))
print('Configuration of new account %s' % website)
print('-----------------------------%s' % ('-' * len(website)))
p = copy(prop)
p.set(self.ask(prop, default=account.properties[key].get() if (key in account.properties) else prop.default))
account.properties[key] = p
if asked_config:
print '-----------------------------%s' % ('-' * len(website))
print('-----------------------------%s' % ('-' * len(website)))
try:
backend.klass.register_account(account)
except AccountRegisterError as e:
print u'%s' % e
print(u'%s' % e)
if self.ask('Do you want to try again?', default=True):
continue
else:
@ -283,10 +284,10 @@ class ConsoleApplication(BaseApplication):
try:
self.weboob.repositories.install(name)
except ModuleInstallError as e:
print >>sys.stderr, 'Unable to install module "%s": %s' % (name, e)
print('Unable to install module "%s": %s' % (name, e), file=sys.stderr)
return False
print ''
print('')
return True
def edit_backend(self, name, params=None):
@ -304,7 +305,7 @@ class ConsoleApplication(BaseApplication):
if minfo is None:
raise ModuleLoadError(name, 'Module does not exist')
if not minfo.is_installed():
print 'Module "%s" is available but not installed.' % minfo.name
print('Module "%s" is available but not installed.' % minfo.name)
self.install_module(minfo)
module = self.weboob.modules_loader.get_or_load_module(name)
config = module.config
@ -315,7 +316,7 @@ class ConsoleApplication(BaseApplication):
params = items
config = module.config.load(self.weboob, bname, name, params, nofail=True)
except ModuleLoadError as e:
print >>sys.stderr, 'Unable to load module "%s": %s' % (name, e)
print('Unable to load module "%s": %s' % (name, e), file=sys.stderr)
return 1
# ask for params non-specified on command-line arguments
@ -323,18 +324,18 @@ class ConsoleApplication(BaseApplication):
for key, value in config.iteritems():
if not asked_config:
asked_config = True
print ''
print 'Configuration of backend %s' % module.name
print '-------------------------%s' % ('-' * len(module.name))
print('')
print('Configuration of backend %s' % module.name)
print('-------------------------%s' % ('-' * len(module.name)))
if key not in params or edit:
params[key] = self.ask(value, default=params[key] if (key in params) else value.default)
else:
print u' [%s] %s: %s' % (key, value.description, '(masked)' if value.masked else params[key])
print(u' [%s] %s: %s' % (key, value.description, '(masked)' if value.masked else params[key]))
if asked_config:
print '-------------------------%s' % ('-' * len(module.name))
print('-------------------------%s' % ('-' * len(module.name)))
while not edit and self.weboob.backends_config.backend_exists(name):
print >>sys.stderr, 'Backend instance "%s" already exists in "%s"' % (name, self.weboob.backends_config.confpath)
print('Backend instance "%s" already exists in "%s"' % (name, self.weboob.backends_config.confpath), file=sys.stderr)
if not self.ask('Add new backend for module "%s"?' % module.name, default=False):
return 1
@ -347,10 +348,10 @@ class ConsoleApplication(BaseApplication):
continue
config[key].set(value)
config.save(edit=edit)
print 'Backend "%s" successfully %s.' % (name, 'edited' if edit else 'added')
print('Backend "%s" successfully %s.' % (name, 'edited' if edit else 'added'))
return name
except BackendAlreadyExists:
print >>sys.stderr, 'Backend "%s" already exists.' % name
print('Backend "%s" already exists.' % name, file=sys.stderr)
return 1
def ask(self, question, default=None, masked=None, regexp=None, choices=None, tiny=None):
@ -395,7 +396,7 @@ class ConsoleApplication(BaseApplication):
question = u'[%s] %s' % (v.id, question)
if isinstance(v, ValueBackendPassword):
print question.encode(sys.stdout.encoding or locale.getpreferredencoding()) + ':'
print(question.encode(sys.stdout.encoding or locale.getpreferredencoding()) + ':')
question = v.label
choices = OrderedDict()
choices['c'] = 'Run an external tool during backend load'
@ -414,9 +415,9 @@ class ConsoleApplication(BaseApplication):
if r == 'p':
return ''
if r == 'c':
print 'Enter the shell command that will print the required value on the standard output'
print('Enter the shell command that will print the required value on the standard output')
if v.is_command(v.default):
print ': %s' % v.default[1:-1]
print(': %s' % v.default[1:-1])
else:
d = None
while True:
@ -424,7 +425,7 @@ class ConsoleApplication(BaseApplication):
try:
subprocess.check_output(cmd, shell=True)
except subprocess.CalledProcessError as e:
print '%s' % e
print('%s' % e)
else:
return '`%s`' % cmd
@ -443,10 +444,10 @@ class ConsoleApplication(BaseApplication):
question = u'%s (%s)' % (question, '/'.join((s.upper() if s == v.default else s)
for s in (v.choices.iterkeys())))
for key, value in v.choices.iteritems():
print ' %s%s%s: %s' % (self.BOLD, key, self.NC, value)
print(' %s%s%s: %s' % (self.BOLD, key, self.NC, value))
else:
for n, (key, value) in enumerate(v.choices.iteritems()):
print ' %s%2d)%s %s' % (self.BOLD, n + 1, self.NC, value)
print(' %s%2d)%s %s' % (self.BOLD, n + 1, self.NC, value))
aliases[str(n + 1)] = key
question = u'%s (choose in list)' % question
if v.masked:
@ -483,7 +484,7 @@ class ConsoleApplication(BaseApplication):
try:
v.set(line)
except ValueError as e:
print >>sys.stderr, u'Error: %s' % e
print(u'Error: %s' % e, file=sys.stderr)
else:
break
@ -509,8 +510,8 @@ class ConsoleApplication(BaseApplication):
text = f.read()
else:
if sys.stdin.isatty():
print 'Reading content from stdin... Type ctrl-D ' \
'from an empty line to stop.'
print('Reading content from stdin... Type ctrl-D ' \
'from an empty line to stop.')
text = sys.stdin.read()
return text.decode(sys.stdin.encoding or locale.getpreferredencoding())
@ -524,7 +525,7 @@ class ConsoleApplication(BaseApplication):
msg = unicode(error)
if not msg:
msg = 'invalid login/password.'
print >>sys.stderr, 'Error(%s): %s' % (backend.name, msg)
print('Error(%s): %s' % (backend.name, msg), file=sys.stderr)
if self.ask('Do you want to reconfigure this backend?', default=True):
self.unload_backends(names=[backend.name])
self.edit_backend(backend.name)
@ -533,21 +534,21 @@ class ConsoleApplication(BaseApplication):
msg = unicode(error)
if not msg:
msg = 'website is unavailable.'
print >>sys.stderr, u'Error(%s): %s' % (backend.name, msg)
print(u'Error(%s): %s' % (backend.name, msg), file=sys.stderr)
elif isinstance(error, BrowserForbidden):
print >>sys.stderr, u'Error(%s): %s' % (backend.name, msg or 'Forbidden')
print(u'Error(%s): %s' % (backend.name, msg or 'Forbidden'), file=sys.stderr)
elif isinstance(error, NotImplementedError):
print >>sys.stderr, u'Error(%s): this feature is not supported yet by this backend.' % backend.name
print >>sys.stderr, u' %s To help the maintainer of this backend implement this feature,' % (' ' * len(backend.name))
print >>sys.stderr, u' %s please contact: %s <%s@issues.weboob.org>' % (' ' * len(backend.name), backend.MAINTAINER, backend.NAME)
print(u'Error(%s): this feature is not supported yet by this backend.' % backend.name, file=sys.stderr)
print(u' %s To help the maintainer of this backend implement this feature,' % (' ' * len(backend.name)), file=sys.stderr)
print(u' %s please contact: %s <%s@issues.weboob.org>' % (' ' * len(backend.name), backend.MAINTAINER, backend.NAME), file=sys.stderr)
elif isinstance(error, UserError):
print >>sys.stderr, u'Error(%s): %s' % (backend.name, to_unicode(error))
print(u'Error(%s): %s' % (backend.name, to_unicode(error)), file=sys.stderr)
elif isinstance(error, MoreResultsAvailable):
print >>sys.stderr, u'Hint: There are more results for backend %s' % (backend.name)
print(u'Hint: There are more results for backend %s' % (backend.name), file=sys.stderr)
elif isinstance(error, SSLError):
print >>sys.stderr, u'FATAL(%s): ' % backend.name + self.BOLD + '/!\ SERVER CERTIFICATE IS INVALID /!\\' + self.NC
print(u'FATAL(%s): ' % backend.name + self.BOLD + '/!\ SERVER CERTIFICATE IS INVALID /!\\' + self.NC, file=sys.stderr)
else:
print >>sys.stderr, u'Bug(%s): %s' % (backend.name, to_unicode(error))
print(u'Bug(%s): %s' % (backend.name, to_unicode(error)), file=sys.stderr)
minfo = self.weboob.repositories.get_module_info(backend.NAME)
if minfo and not minfo.is_local():
@ -558,11 +559,11 @@ class ConsoleApplication(BaseApplication):
if minfo and minfo.version > self.weboob.repositories.versions.get(minfo.name) and \
self.ask('A new version of %s is available. Do you want to install it?' % minfo.name, default=True) and \
self.install_module(minfo):
print 'New version of module %s has been installed. Retry to call the command.' % minfo.name
print('New version of module %s has been installed. Retry to call the command.' % minfo.name)
return
if logging.root.level == logging.DEBUG:
print >>sys.stderr, backtrace
print(backtrace, file=sys.stderr)
else:
return True
@ -581,6 +582,6 @@ class ConsoleApplication(BaseApplication):
ask_debug_mode = True
if ask_debug_mode:
print >>sys.stderr, debugmsg
print(debugmsg, file=sys.stderr)
elif len(more_results) > 0:
print >>sys.stderr, 'Hint: There are more results available for %s (use option -n or count command)' % (', '.join(more_results))
print('Hint: There are more results available for %s (use option -n or count command)' % (', '.join(more_results)), file=sys.stderr)

View file

@ -18,6 +18,8 @@
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from __future__ import print_function
import os
import sys
import subprocess
@ -118,7 +120,7 @@ class IFormatter(object):
if isinstance(line, unicode):
line = line.encode('utf-8')
print line
print(line)
self.print_lines += 1
def start_format(self, **kwargs):

View file

@ -18,6 +18,8 @@
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from __future__ import print_function
from weboob.capabilities.base import NotAvailable, NotLoaded
from weboob.tools.json import json
@ -52,7 +54,7 @@ class JsonFormatter(IFormatter):
self.queue = []
def flush(self):
print json.dumps(self.queue, cls=Encoder)
print(json.dumps(self.queue, cls=Encoder))
def format_dict(self, item):
self.queue.append(item)
@ -64,4 +66,4 @@ class JsonLineFormatter(IFormatter):
The advantage is that it can be streamed.
"""
def format_dict(self, item):
print json.dumps(item, cls=Encoder)
print(json.dumps(item, cls=Encoder))

View file

@ -18,6 +18,8 @@
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from __future__ import print_function
from prettytable import PrettyTable
from weboob.capabilities.base import empty
@ -40,7 +42,7 @@ class TableFormatter(IFormatter):
def flush(self):
s = self.get_formatted_table()
if s is not None:
print s.encode('utf-8')
print(s.encode('utf-8'))
def get_formatted_table(self):
if len(self.queue) == 0:

View file

@ -18,6 +18,8 @@
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from __future__ import print_function
import os
from subprocess import PIPE, Popen
import cookielib
@ -102,7 +104,7 @@ class MediaPlayer(object):
player_name = args[0]
args.append(media.url)
print 'Invoking "%s".' % (' '.join(args))
print('Invoking "%s".' % (' '.join(args)))
os.spawnlp(os.P_WAIT, player_name, *args)
def _play_proxy(self, media, player_name, args):
@ -120,9 +122,9 @@ class MediaPlayer(object):
assert args is not None
print ':: Play_proxy streaming from %s' % media.url
print ':: to %s %s' % (player_name, args)
print player_name + ' ' + args
print(':: Play_proxy streaming from %s' % media.url)
print(':: to %s %s' % (player_name, args))
print(player_name + ' ' + args)
proc = Popen(player_name + ' ' + args, stdin=PIPE, shell=True)
# Handle cookies (and redirection 302...)
@ -142,7 +144,7 @@ class MediaPlayer(object):
try:
proc.stdin.write(_buffer)
except:
print "play_proxy broken pipe. Can't write anymore."
print("play_proxy broken pipe. Can't write anymore.")
break
def _play_rtmp(self, media, player_name, args):
@ -181,9 +183,9 @@ class MediaPlayer(object):
player_name = player_name.split(' ')
args = args.split(' ')
print ':: Streaming from %s' % media_url
print ':: to %s %s' % (player_name, args)
print ':: %s' % rtmp
print(':: Streaming from %s' % media_url)
print(':: to %s %s' % (player_name, args))
print(':: %s' % rtmp)
p1 = Popen(rtmp.split(), stdout=PIPE)
Popen(player_name + args, stdin=p1.stdout, stderr=PIPE)

View file

@ -17,6 +17,8 @@
# You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from __future__ import print_function
import sys
import logging
import re
@ -237,8 +239,8 @@ class QtDo(QObject):
msg += u'<br />%s' % to_unicode(line)
if ul_opened:
msg += u'</li></ul>'
print >>sys.stderr, error
print >>sys.stderr, backtrace
print(error, file=sys.stderr)
print(backtrace, file=sys.stderr)
QMessageBox.critical(None, unicode(self.tr('Error with backend %s')) % backend.name,
msg, QMessageBox.Ok)

View file

@ -17,6 +17,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from __future__ import print_function
import atexit
from cmd import Cmd
@ -198,20 +199,20 @@ class ReplApplication(Cmd, ConsoleApplication):
except BackendNotGiven as e:
backend_name = None
while not backend_name:
print 'This command works with an unique backend. Availables:'
print('This command works with an unique backend. Availables:')
for index, (name, backend) in enumerate(e.backends):
print '%s%d)%s %s%-15s%s %s' % (self.BOLD, index + 1, self.NC, self.BOLD, name, self.NC,
backend.DESCRIPTION)
print('%s%d)%s %s%-15s%s %s' % (self.BOLD, index + 1, self.NC, self.BOLD, name, self.NC,
backend.DESCRIPTION))
i = self.ask('Select a backend to proceed with "%s"' % id)
if not i.isdigit():
if not i in dict(e.backends):
print >>sys.stderr, 'Error: %s is not a valid backend' % i
print('Error: %s is not a valid backend' % i, file=sys.stderr)
continue
backend_name = i
else:
i = int(i)
if i < 0 or i > len(e.backends):
print >>sys.stderr, 'Error: %s is not a valid choice' % i
print('Error: %s is not a valid choice' % i, file=sys.stderr)
continue
backend_name = e.backends[i-1][0]
@ -405,12 +406,12 @@ class ReplApplication(Cmd, ConsoleApplication):
except CallErrors as e:
self.bcall_errors_handler(e)
except BackendNotGiven as e:
print >>sys.stderr, 'Error: %s' % str(e)
print('Error: %s' % str(e), file=sys.stderr)
except NotEnoughArguments as e:
print >>sys.stderr, 'Error: not enough arguments. %s' % str(e)
print('Error: not enough arguments. %s' % str(e), file=sys.stderr)
except (KeyboardInterrupt, EOFError):
# ^C during a command process doesn't exit application.
print '\nAborted.'
print('\nAborted.')
finally:
self.flush()
@ -422,12 +423,12 @@ class ReplApplication(Cmd, ConsoleApplication):
pass
def default(self, line):
print >>sys.stderr, 'Unknown command: "%s"' % line
print('Unknown command: "%s"' % line, file=sys.stderr)
cmd, arg, ignore = Cmd.parseline(self, line)
if cmd is not None:
names = set(name[3:] for name in self.get_names() if name.startswith('do_' + cmd))
if len(names) > 0:
print >>sys.stderr, 'Do you mean: %s?' % ', '.join(names)
print('Do you mean: %s?' % ', '.join(names), file=sys.stderr)
return 2
def completenames(self, text, *ignored):
@ -561,7 +562,7 @@ class ReplApplication(Cmd, ConsoleApplication):
Quit the command line interpreter when ^D is pressed.
"""
# print empty line for the next shell prompt to appear on the first column of the terminal
print
print()
return self.do_quit(arg)
def do_help(self, arg=None):
@ -581,7 +582,7 @@ class ReplApplication(Cmd, ConsoleApplication):
lines[0] = '%s%s%s' % (self.BOLD, lines[0], self.NC)
self.stdout.write('%s\n' % '\n'.join(lines))
else:
print >>sys.stderr, 'Unknown command: "%s"' % arg
print('Unknown command: "%s"' % arg, file=sys.stderr)
else:
cmds = self._parser.formatter.format_commands(self._parser.commands)
self.stdout.write('%s\n' % cmds)
@ -644,20 +645,20 @@ class ReplApplication(Cmd, ConsoleApplication):
if action in ('add', 'register'):
minfo = self.weboob.repositories.get_module_info(backend_name)
if minfo is None:
print >>sys.stderr, 'Module "%s" does not exist.' % backend_name
print('Module "%s" does not exist.' % backend_name, file=sys.stderr)
return 1
else:
if not minfo.has_caps(self.CAPS):
print >>sys.stderr, 'Module "%s" is not supported by this application => skipping.' % backend_name
print('Module "%s" is not supported by this application => skipping.' % backend_name, file=sys.stderr)
return 1
else:
if backend_name not in [backend.name for backend in self.weboob.iter_backends()]:
print >>sys.stderr, 'Backend "%s" does not exist => skipping.' % backend_name
print('Backend "%s" does not exist => skipping.' % backend_name, file=sys.stderr)
return 1
if action in ('enable', 'disable', 'only', 'add', 'register', 'edit', 'remove'):
if not given_backend_names:
print >>sys.stderr, 'Please give at least a backend name.'
print('Please give at least a backend name.', file=sys.stderr)
return 2
given_backends = set(backend for backend in self.weboob.iter_backends() if backend.name in given_backend_names)
@ -670,7 +671,7 @@ class ReplApplication(Cmd, ConsoleApplication):
try:
self.enabled_backends.remove(backend)
except KeyError:
print >>sys.stderr, '%s is not enabled' % backend.name
print('%s is not enabled' % backend.name, file=sys.stderr)
elif action == 'only':
self.enabled_backends = set()
for backend in given_backends:
@ -678,9 +679,9 @@ class ReplApplication(Cmd, ConsoleApplication):
elif action == 'list':
enabled_backends_names = set(backend.name for backend in self.enabled_backends)
disabled_backends_names = set(backend.name for backend in self.weboob.iter_backends()) - enabled_backends_names
print 'Enabled: %s' % ', '.join(enabled_backends_names)
print('Enabled: %s' % ', '.join(enabled_backends_names))
if len(disabled_backends_names) > 0:
print 'Disabled: %s' % ', '.join(disabled_backends_names)
print('Disabled: %s' % ', '.join(disabled_backends_names))
elif action == 'add':
for name in given_backend_names:
instname = self.add_backend(name)
@ -705,7 +706,7 @@ class ReplApplication(Cmd, ConsoleApplication):
self.unload_backends(backend.name)
elif action == 'list-modules':
modules = []
print 'Modules list:'
print('Modules list:')
for name, info in sorted(self.weboob.repositories.get_all_modules_info().iteritems()):
if not self.is_module_loadable(info):
continue
@ -719,14 +720,14 @@ class ReplApplication(Cmd, ConsoleApplication):
loaded = 2
else:
loaded += 1
print '[%s] %s%-15s%s %s' % (loaded, self.BOLD, name, self.NC, info.description)
print('[%s] %s%-15s%s %s' % (loaded, self.BOLD, name, self.NC, info.description))
else:
print >>sys.stderr, 'Unknown action: "%s"' % action
print('Unknown action: "%s"' % action, file=sys.stderr)
return 1
if len(self.enabled_backends) == 0:
print >>sys.stderr, 'Warning: no more backends are loaded. %s is probably unusable.' % self.APPNAME.capitalize()
print('Warning: no more backends are loaded. %s is probably unusable.' % self.APPNAME.capitalize(), file=sys.stderr)
def complete_logging(self, text, line, begidx, endidx):
levels = ('debug', 'info', 'warning', 'error', 'quiet', 'default')
@ -760,15 +761,15 @@ class ReplApplication(Cmd, ConsoleApplication):
if logging.root.level == level:
current = label
break
print 'Current level: %s' % current
print('Current level: %s' % current)
return
levels = dict(levels)
try:
level = levels[args[0]]
except KeyError:
print >>sys.stderr, 'Level "%s" does not exist.' % args[0]
print >>sys.stderr, 'Availables: %s' % ' '.join(levels.iterkeys())
print('Level "%s" does not exist.' % args[0], file=sys.stderr)
print('Availables: %s' % ' '.join(levels.iterkeys()), file=sys.stderr)
return 2
else:
logging.root.setLevel(level)
@ -792,13 +793,13 @@ class ReplApplication(Cmd, ConsoleApplication):
try:
self.condition = ResultsCondition(line)
except ResultsConditionError as e:
print >>sys.stderr, '%s' % e
print('%s' % e, file=sys.stderr)
return 2
else:
if self.condition is None:
print 'No condition is set.'
print('No condition is set.')
else:
print str(self.condition)
print(str(self.condition))
def do_count(self, line):
"""
@ -819,7 +820,7 @@ class ReplApplication(Cmd, ConsoleApplication):
try:
count = int(line)
except ValueError:
print >>sys.stderr, 'Could not interpret "%s" as a number.' % line
print('Could not interpret "%s" as a number.' % line, file=sys.stderr)
return 2
else:
if count > 0:
@ -830,9 +831,9 @@ class ReplApplication(Cmd, ConsoleApplication):
self._is_default_count = False
else:
if self.options.count is None:
print 'Counting disabled.'
print('Counting disabled.')
else:
print self.options.count
print(self.options.count)
def complete_formatter(self, text, line, *ignored):
formatters = self.formatters_loader.get_available_formatters()
@ -871,17 +872,17 @@ class ReplApplication(Cmd, ConsoleApplication):
args = line.strip().split()
if args:
if args[0] == 'list':
print ', '.join(self.formatters_loader.get_available_formatters())
print(', '.join(self.formatters_loader.get_available_formatters()))
elif args[0] == 'option':
if len(args) > 1:
if len(args) == 2:
if args[1] == 'header':
print 'off' if self.options.no_header else 'on'
print('off' if self.options.no_header else 'on')
elif args[1] == 'keys':
print 'off' if self.options.no_keys else 'on'
print('off' if self.options.no_keys else 'on')
else:
if args[2] not in ('on', 'off'):
print >>sys.stderr, 'Invalid value "%s". Please use "on" or "off" values.' % args[2]
print('Invalid value "%s". Please use "on" or "off" values.' % args[2], file=sys.stderr)
return 2
else:
if args[1] == 'header':
@ -889,7 +890,7 @@ class ReplApplication(Cmd, ConsoleApplication):
elif args[1] == 'keys':
self.options.no_keys = True if args[2] == 'off' else False
else:
print >>sys.stderr, 'Don\'t know which option to set. Available options: header, keys.'
print('Don\'t know which option to set. Available options: header, keys.', file=sys.stderr)
return 2
else:
if args[0] in self.formatters_loader.get_available_formatters():
@ -899,13 +900,13 @@ class ReplApplication(Cmd, ConsoleApplication):
self.commands_formatters = {}
self.DEFAULT_FORMATTER = self.set_formatter(args[0])
else:
print >>sys.stderr, 'Formatter "%s" is not available.\n' \
'Available formatters: %s.' % (args[0], ', '.join(self.formatters_loader.get_available_formatters()))
print('Formatter "%s" is not available.\n' \
'Available formatters: %s.' % (args[0], ', '.join(self.formatters_loader.get_available_formatters())), file=sys.stderr)
return 1
else:
print 'Default formatter: %s' % self.DEFAULT_FORMATTER
print('Default formatter: %s' % self.DEFAULT_FORMATTER)
for key, klass in self.commands_formatters.iteritems():
print 'Command "%s": %s' % (key, klass)
print('Command "%s": %s' % (key, klass))
def do_select(self, line):
"""
@ -922,7 +923,7 @@ class ReplApplication(Cmd, ConsoleApplication):
split = line.split()
self.selected_fields = split
else:
print ' '.join(self.selected_fields)
print(' '.join(self.selected_fields))
def complete_inspect(self, text, line, begidx, endidx):
return sorted(set(backend.name for backend in self.enabled_backends))
@ -940,18 +941,18 @@ class ReplApplication(Cmd, ConsoleApplication):
else:
backend_name = line.strip()
if not backend_name:
print >>sys.stderr, 'Please specify a backend name.'
print('Please specify a backend name.', file=sys.stderr)
return 2
backends = set(backend for backend in self.enabled_backends if backend.name == backend_name)
if not backends:
print >>sys.stderr, 'No backend found for "%s"' % backend_name
print('No backend found for "%s"' % backend_name, file=sys.stderr)
return 1
backend = backends.pop()
if not backend.browser:
print >>sys.stderr, 'No browser created for backend "%s".' % backend.name
print('No browser created for backend "%s".' % backend.name, file=sys.stderr)
return 1
if not backend.browser.page:
print >>sys.stderr, 'The browser of %s is not on any page.' % backend.name
print('The browser of %s is not on any page.' % backend.name, file=sys.stderr)
return 1
browser = backend.browser
data = browser.parser.tostring(browser.page.document)
@ -959,7 +960,7 @@ class ReplApplication(Cmd, ConsoleApplication):
from webkit_mechanize_browser.browser import Browser
from weboob.tools.inspect import Page
except ImportError:
print data
print(data)
else:
page = Page(core=browser, data=data, uri=browser._response.geturl())
browser = Browser(view=page.view)
@ -1064,11 +1065,11 @@ class ReplApplication(Cmd, ConsoleApplication):
def _format_collection(self, collection, only):
if only is False or collection.basename in only:
if collection.basename and collection.title:
print u'%s~ (%s) %s (%s)%s' % \
(self.BOLD, collection.basename, collection.title, collection.backend, self.NC)
print(u'%s~ (%s) %s (%s)%s' % \
(self.BOLD, collection.basename, collection.title, collection.backend, self.NC))
else:
print u'%s~ (%s) (%s)%s' % \
(self.BOLD, collection.basename, collection.backend, self.NC)
print(u'%s~ (%s) (%s)%s' % \
(self.BOLD, collection.basename, collection.backend, self.NC))
def _format_obj(self, obj, only):
@ -1106,7 +1107,7 @@ class ReplApplication(Cmd, ConsoleApplication):
if len(collections) == 1:
self.working_path.split_path = collections[0].split_path
else:
print >>sys.stderr, u"Path: %s not found" % unicode(self.working_path)
print(u"Path: %s not found" % unicode(self.working_path), file=sys.stderr)
self.working_path.restore()
return 1
@ -1199,10 +1200,10 @@ class ReplApplication(Cmd, ConsoleApplication):
try:
self.formatter = self.formatters_loader.build_formatter(name)
except FormatterLoadError as e:
print >>sys.stderr, '%s' % e
print('%s' % e, file=sys.stderr)
if self.DEFAULT_FORMATTER == name:
self.DEFAULT_FORMATTER = ReplApplication.DEFAULT_FORMATTER
print >>sys.stderr, 'Falling back to "%s".' % (self.DEFAULT_FORMATTER)
print('Falling back to "%s".' % (self.DEFAULT_FORMATTER), file=sys.stderr)
self.formatter = self.formatters_loader.build_formatter(self.DEFAULT_FORMATTER)
name = self.DEFAULT_FORMATTER
if self.options.no_header:
@ -1235,9 +1236,9 @@ class ReplApplication(Cmd, ConsoleApplication):
try:
self.formatter.format(obj=result, selected_fields=fields, alias=alias)
except FieldNotFound as e:
print >>sys.stderr, e
print(e, file=sys.stderr)
except MandatoryFieldsNotFound as e:
print >>sys.stderr, '%s Hint: select missing fields or use another formatter (ex: multiline).' % e
print('%s Hint: select missing fields or use another formatter (ex: multiline).' % e, file=sys.stderr)
def flush(self):
self.formatter.flush()

View file

@ -18,6 +18,12 @@
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from __future__ import print_function
import sys
if sys.version_info >= (3,0):
raise ImportError("This module isn't compatible with python3")
from copy import copy
from httplib import BadStatusLine
@ -28,7 +34,6 @@ except ImportError:
raise ImportError('Please install python-mechanize')
import os
import sys
import re
import tempfile
from threading import RLock
@ -288,7 +293,7 @@ class StandardBrowser(mechanize.Browser):
"""
if self.responses_dirname is None:
self.responses_dirname = tempfile.mkdtemp(prefix='weboob_session_')
print >>sys.stderr, 'Debug data will be saved in this directory: %s' % self.responses_dirname
print('Debug data will be saved in this directory: %s' % self.responses_dirname, file=sys.stderr)
elif not os.path.isdir(self.responses_dirname):
os.makedirs(self.responses_dirname)
# get the content-type, remove optionnal charset part
@ -391,7 +396,7 @@ class StandardBrowser(mechanize.Browser):
value = [self.str(is_list.index(args[label]))]
except ValueError as e:
if args[label]:
print >>sys.stderr, '[%s] %s: %s' % (label, args[label], e)
print('[%s] %s: %s' % (label, args[label], e), file=sys.stderr)
return
else:
value = [self.str(args[label])]

View file

@ -18,6 +18,8 @@
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from __future__ import print_function
try:
import sqlite3 as sqlite
except ImportError as e:
@ -40,7 +42,7 @@ class FirefoxCookieJar(CookieJar):
try:
db = sqlite.connect(database=self.sqlite_file, timeout=10.0)
except sqlite.OperationalError as err:
print 'Unable to open %s database: %s' % (self.sqlite_file, err)
print('Unable to open %s database: %s' % (self.sqlite_file, err))
return None
return db

View file

@ -17,10 +17,13 @@
# You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from __future__ import absolute_import
from __future__ import absolute_import, print_function
import re
from urlparse import urlparse, urljoin
try:
from urllib.parse import urlparse, urljoin
except ImportError:
from urlparse import urlparse, urljoin
import mimetypes
import os
import tempfile
@ -157,7 +160,7 @@ class BaseBrowser(object):
def _save(self, response, warning=False, **kwargs):
if self.responses_dirname is None:
self.responses_dirname = tempfile.mkdtemp(prefix='weboob_session_')
print >>sys.stderr, 'Debug data will be saved in this directory: %s' % self.responses_dirname
print('Debug data will be saved in this directory: %s' % self.responses_dirname, file=sys.stderr)
elif not os.path.isdir(self.responses_dirname):
os.makedirs(self.responses_dirname)

View file

@ -17,7 +17,10 @@
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
import requests.cookies
import cookielib
try:
import cookielib
except ImportError:
import http.cookiejar as cookielib
__all__ = ['WeboobCookieJar']

View file

@ -26,6 +26,7 @@ import re
import lxml.html as html
from weboob.tools.misc import html2text
from weboob.tools.compat import basestring
from weboob.capabilities.base import empty
@ -258,7 +259,7 @@ class CleanDecimal(CleanText):
if self.replace_dots:
text = text.replace('.','').replace(',','.')
try:
return Decimal(re.sub(ur'[^\d\-\.]', '', text))
return Decimal(re.sub(r'[^\d\-\.]', '', text))
except InvalidOperation as e:
return self.default_or_raise(e)
@ -388,7 +389,7 @@ class DateGuesser(Filter):
class Time(Filter):
klass = datetime.time
regexp = re.compile(ur'(?P<hh>\d+):?(?P<mm>\d+)(:(?P<ss>\d+))?')
regexp = re.compile(r'(?P<hh>\d+):?(?P<mm>\d+)(:(?P<ss>\d+))?')
kwargs = {'hour': 'hh', 'minute': 'mm', 'second': 'ss'}
def __init__(self, selector, default=_NO_DEFAULT):
@ -407,7 +408,7 @@ class Time(Filter):
class Duration(Time):
klass = datetime.timedelta
regexp = re.compile(ur'((?P<hh>\d+)[:;])?(?P<mm>\d+)[;:](?P<ss>\d+)')
regexp = re.compile(r'((?P<hh>\d+)[:;])?(?P<mm>\d+)[;:](?P<ss>\d+)')
kwargs = {'hours': 'hh', 'minutes': 'mm', 'seconds': 'ss'}

View file

@ -19,18 +19,22 @@
from __future__ import absolute_import
from urllib import unquote
try:
from urllib.parse import unquote
except ImportError:
from urllib import unquote
import requests
import re
import sys
from copy import deepcopy
from cStringIO import StringIO
from io import BytesIO
import lxml.html as html
import lxml.etree as etree
from weboob.tools.json import json
from weboob.tools.ordereddict import OrderedDict
from weboob.tools.regex_helper import normalize
from weboob.tools.compat import basestring
from weboob.tools.log import getLogger
@ -527,7 +531,7 @@ class XMLPage(BasePage):
def __init__(self, browser, response, *args, **kwargs):
super(XMLPage, self).__init__(browser, response, *args, **kwargs)
parser = etree.XMLParser(encoding=self.ENCODING or response.encoding)
self.doc = etree.parse(StringIO(response.content), parser)
self.doc = etree.parse(BytesIO(response.content), parser)
class RawPage(BasePage):
@ -551,7 +555,7 @@ class HTMLPage(BasePage):
def __init__(self, browser, response, *args, **kwargs):
super(HTMLPage, self).__init__(browser, response, *args, **kwargs)
parser = html.HTMLParser(encoding=self.ENCODING or response.encoding)
self.doc = html.parse(StringIO(response.content), parser)
self.doc = html.parse(BytesIO(response.content), parser)
def get_form(self, xpath='//form', name=None, nr=None):
"""

37
weboob/tools/compat.py Normal file
View file

@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
# Copyright(C) 2014 Romain Bignon
#
# This file is part of weboob.
#
# weboob is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# weboob is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
__all__ = ['unicode', 'long', 'basestring']
try:
unicode = unicode
except NameError:
unicode = str
try:
long = long
except NameError:
long = int
try:
basestring = basestring
except NameError:
basestring = str

View file

@ -27,6 +27,7 @@ import traceback
import types
# keep compatibility
from .date import local2utc, utc2local
from .compat import unicode
__all__ = ['get_backtrace', 'get_bytes_size', 'html2text', 'iter_fields',