first step in python3 support
This commit is contained in:
parent
7c1e08eb96
commit
6fcac89dd5
25 changed files with 302 additions and 208 deletions
|
|
@ -18,9 +18,14 @@
|
||||||
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
# 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 datetime import datetime, timedelta
|
||||||
|
|
||||||
|
from weboob.tools.compat import basestring
|
||||||
from weboob.tools.browser2 import LoginBrowser, URL, Wget, need_login
|
from weboob.tools.browser2 import LoginBrowser, URL, Wget, need_login
|
||||||
from weboob.tools.exceptions import BrowserIncorrectPassword
|
from weboob.tools.exceptions import BrowserIncorrectPassword
|
||||||
from weboob.capabilities.bank import Transfer, TransferError
|
from weboob.capabilities.bank import Transfer, TransferError
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,11 @@
|
||||||
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
# 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
|
from decimal import Decimal
|
||||||
import re
|
import re
|
||||||
from dateutil.relativedelta import relativedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
import datetime, uuid
|
import datetime, uuid
|
||||||
from dateutil.relativedelta import relativedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
|
|
@ -321,15 +322,15 @@ class Boobank(ReplApplication):
|
||||||
|
|
||||||
account = self.get_object(id, 'get_account', [])
|
account = self.get_object(id, 'get_account', [])
|
||||||
if not 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
|
return 2
|
||||||
|
|
||||||
if end_date is not None:
|
if end_date is not None:
|
||||||
try:
|
try:
|
||||||
end_date = parse_date(end_date)
|
end_date = parse_date(end_date)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
print >>sys.stderr, '"%s" is an incorrect date format (for example "%s")' % \
|
print('"%s" is an incorrect date format (for example "%s")' % \
|
||||||
(end_date, (datetime.date.today() - relativedelta(months=1)).strftime('%Y-%m-%d'))
|
(end_date, (datetime.date.today() - relativedelta(months=1)).strftime('%Y-%m-%d')), file=sys.stderr)
|
||||||
return 3
|
return 3
|
||||||
old_count = self.options.count
|
old_count = self.options.count
|
||||||
self.options.count = None
|
self.options.count = None
|
||||||
|
|
@ -399,7 +400,7 @@ class Boobank(ReplApplication):
|
||||||
|
|
||||||
account = self.get_object(id_from, 'get_account', [])
|
account = self.get_object(id_from, 'get_account', [])
|
||||||
if not 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
|
return 1
|
||||||
|
|
||||||
if not id_to:
|
if not id_to:
|
||||||
|
|
@ -415,13 +416,13 @@ class Boobank(ReplApplication):
|
||||||
id_to, backend_name_to = self.parse_id(id_to)
|
id_to, backend_name_to = self.parse_id(id_to)
|
||||||
|
|
||||||
if account.backend != backend_name_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
|
return 4
|
||||||
|
|
||||||
try:
|
try:
|
||||||
amount = Decimal(amount)
|
amount = Decimal(amount)
|
||||||
except (TypeError, ValueError, InvalidOperation):
|
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
|
return 2
|
||||||
|
|
||||||
if self.interactive:
|
if self.interactive:
|
||||||
|
|
@ -434,10 +435,10 @@ class Boobank(ReplApplication):
|
||||||
to = recipient.label
|
to = recipient.label
|
||||||
break
|
break
|
||||||
|
|
||||||
print 'Amount: %s%s' % (amount, account.currency_text)
|
print('Amount: %s%s' % (amount, account.currency_text))
|
||||||
print 'From: %s' % account.label
|
print('From: %s' % account.label)
|
||||||
print 'To: %s' % to
|
print('To: %s' % to)
|
||||||
print 'Reason: %s' % (reason or '')
|
print('Reason: %s' % (reason or ''))
|
||||||
if not self.ask('Are you sure to do this transfer?', default=True):
|
if not self.ask('Are you sure to do this transfer?', default=True):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -453,7 +454,7 @@ class Boobank(ReplApplication):
|
||||||
"""
|
"""
|
||||||
account = self.get_object(id, 'get_account', [])
|
account = self.get_object(id, 'get_account', [])
|
||||||
if not 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
|
return 2
|
||||||
|
|
||||||
self.start_format()
|
self.start_format()
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@ from datetime import date, datetime
|
||||||
from binascii import crc32
|
from binascii import crc32
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
from weboob.tools.compat import basestring, long
|
||||||
|
|
||||||
from .base import CapBaseObject, Field, StringField, DateField, DecimalField, IntField, UserError, Currency
|
from .base import CapBaseObject, Field, StringField, DateField, DecimalField, IntField, UserError, Currency
|
||||||
from .collection import ICapCollection
|
from .collection import ICapCollection
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import re
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from copy import deepcopy, copy
|
from copy import deepcopy, copy
|
||||||
|
|
||||||
|
from weboob.tools.compat import unicode, long
|
||||||
from weboob.tools.misc import to_unicode
|
from weboob.tools.misc import to_unicode
|
||||||
from weboob.tools.date import new_date, new_datetime
|
from weboob.tools.date import new_date, new_datetime
|
||||||
from weboob.tools.ordereddict import OrderedDict
|
from weboob.tools.ordereddict import OrderedDict
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,10 @@
|
||||||
import stat
|
import stat
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from ConfigParser import RawConfigParser, DuplicateSectionError
|
try:
|
||||||
|
from ConfigParser import RawConfigParser, DuplicateSectionError
|
||||||
|
except ImportError:
|
||||||
|
from configparser import RawConfigParser, DuplicateSectionError
|
||||||
from logging import warning
|
from logging import warning
|
||||||
|
|
||||||
__all__ = ['BackendsConfig', 'BackendAlreadyExists']
|
__all__ = ['BackendsConfig', 'BackendAlreadyExists']
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,10 @@
|
||||||
|
|
||||||
from copy import copy
|
from copy import copy
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
import Queue
|
try:
|
||||||
|
import Queue
|
||||||
|
except ImportError:
|
||||||
|
import queue as Queue
|
||||||
|
|
||||||
from weboob.capabilities.base import CapBaseObject
|
from weboob.capabilities.base import CapBaseObject
|
||||||
from weboob.tools.misc import get_backtrace
|
from weboob.tools.misc import get_backtrace
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
import imp
|
import imp
|
||||||
import tarfile
|
import tarfile
|
||||||
import posixpath
|
import posixpath
|
||||||
|
|
@ -32,29 +32,24 @@ from tempfile import NamedTemporaryFile
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from contextlib import closing
|
from contextlib import closing
|
||||||
from compileall import compile_dir
|
from compileall import compile_dir
|
||||||
from StringIO import StringIO
|
from io import BytesIO
|
||||||
|
|
||||||
from .modules import Module
|
from .modules import Module
|
||||||
from weboob.tools.log import getLogger
|
from weboob.tools.log import getLogger
|
||||||
from weboob.tools.misc import to_unicode
|
from weboob.tools.misc import to_unicode
|
||||||
from weboob.tools.browser import StandardBrowser, BrowserUnavailable
|
from weboob.tools.browser2.browser import BaseBrowser, Weboob as WeboobProfile
|
||||||
from ConfigParser import RawConfigParser, DEFAULTSECT
|
try:
|
||||||
|
from configparser import RawConfigParser, DEFAULTSECT
|
||||||
|
except ImportError:
|
||||||
|
from ConfigParser import RawConfigParser, DEFAULTSECT
|
||||||
|
|
||||||
|
BrowserUnavailable = object()
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['IProgress', 'ModuleInstallError', 'ModuleInfo', 'RepositoryUnavailable',
|
__all__ = ['IProgress', 'ModuleInstallError', 'ModuleInfo', 'RepositoryUnavailable',
|
||||||
'Repository', 'Versions', 'Repositories', 'InvalidSignature', 'Keyring']
|
'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):
|
class ModuleInfo(object):
|
||||||
"""
|
"""
|
||||||
Information about a module available on a repository.
|
Information about a module available on a repository.
|
||||||
|
|
@ -125,7 +120,8 @@ class Repository(object):
|
||||||
KEYDIR = '.keys'
|
KEYDIR = '.keys'
|
||||||
KEYRING = 'trusted.gpg'
|
KEYRING = 'trusted.gpg'
|
||||||
|
|
||||||
def __init__(self, url):
|
def __init__(self, browser, url):
|
||||||
|
self.browser = browser
|
||||||
self.url = url
|
self.url = url
|
||||||
self.name = u''
|
self.name = u''
|
||||||
self.update = 0
|
self.update = 0
|
||||||
|
|
@ -179,9 +175,8 @@ class Repository(object):
|
||||||
fp = open(filename, 'r')
|
fp = open(filename, 'r')
|
||||||
else:
|
else:
|
||||||
# This is a remote repository, download file
|
# This is a remote repository, download file
|
||||||
browser = WeboobBrowser()
|
|
||||||
try:
|
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:
|
except BrowserUnavailable as e:
|
||||||
raise RepositoryUnavailable(unicode(e))
|
raise RepositoryUnavailable(unicode(e))
|
||||||
|
|
||||||
|
|
@ -208,20 +203,19 @@ class Repository(object):
|
||||||
|
|
||||||
if not keyring.exists() or self.key_update > keyring.version:
|
if not keyring.exists() or self.key_update > keyring.version:
|
||||||
# This is a remote repository, download file
|
# This is a remote repository, download file
|
||||||
browser = WeboobBrowser()
|
|
||||||
try:
|
try:
|
||||||
keyring_data = browser.readurl(posixpath.join(self.url, self.KEYRING))
|
keyring_data = self.browser.open(posixpath.join(self.url, self.KEYRING)).content
|
||||||
sig_data = browser.readurl(posixpath.join(self.url, self.KEYRING + '.sig'))
|
sig_data = self.browser.open(posixpath.join(self.url, self.KEYRING + '.sig')).content
|
||||||
except BrowserUnavailable as e:
|
except BrowserUnavailable as e:
|
||||||
raise RepositoryUnavailable(unicode(e))
|
raise RepositoryUnavailable(unicode(e))
|
||||||
if keyring.exists():
|
if keyring.exists():
|
||||||
if not keyring.is_valid(keyring_data, sig_data):
|
if not keyring.is_valid(keyring_data, sig_data):
|
||||||
raise InvalidSignature('the keyring itself')
|
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:
|
else:
|
||||||
print 'First time saving the keyring, blindly accepted.'
|
print('First time saving the keyring, blindly accepted.')
|
||||||
keyring.save(keyring_data, self.key_update)
|
keyring.save(keyring_data, self.key_update)
|
||||||
print keyring
|
print(keyring)
|
||||||
|
|
||||||
def parse_index(self, fp):
|
def parse_index(self, fp):
|
||||||
"""
|
"""
|
||||||
|
|
@ -275,7 +269,7 @@ class Repository(object):
|
||||||
:param filename: file to save index
|
:param filename: file to save index
|
||||||
:type filename: str
|
:type filename: str
|
||||||
"""
|
"""
|
||||||
print 'Rebuild index'
|
print('Rebuild index')
|
||||||
self.modules.clear()
|
self.modules.clear()
|
||||||
|
|
||||||
if os.path.isdir(os.path.join(path, self.KEYDIR)):
|
if os.path.isdir(os.path.join(path, self.KEYDIR)):
|
||||||
|
|
@ -298,7 +292,7 @@ class Repository(object):
|
||||||
if fp:
|
if fp:
|
||||||
fp.close()
|
fp.close()
|
||||||
except Exception as e:
|
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:
|
else:
|
||||||
m = ModuleInfo(module.name)
|
m = ModuleInfo(module.name)
|
||||||
m.version = self.get_tree_mtime(module_path)
|
m.version = self.get_tree_mtime(module_path)
|
||||||
|
|
@ -388,10 +382,10 @@ class Versions(object):
|
||||||
|
|
||||||
class IProgress(object):
|
class IProgress(object):
|
||||||
def progress(self, percent, message):
|
def progress(self, percent, message):
|
||||||
print '=== [%3.0f%%] %s' % (percent*100, message)
|
print('=== [%3.0f%%] %s' % (percent*100, message))
|
||||||
|
|
||||||
def error(self, message):
|
def error(self, message):
|
||||||
print >>sys.stderr, 'ERROR: %s' % message
|
print('ERROR: %s' % message, file=sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
class ModuleInstallError(Exception):
|
class ModuleInstallError(Exception):
|
||||||
|
|
@ -425,7 +419,11 @@ class Repositories(object):
|
||||||
def __init__(self, workdir, datadir, version):
|
def __init__(self, workdir, datadir, version):
|
||||||
self.logger = getLogger('repositories')
|
self.logger = getLogger('repositories')
|
||||||
self.version = version
|
self.version = version
|
||||||
WeboobBrowser.set_version(version)
|
|
||||||
|
class WeboobBrowser(BaseBrowser):
|
||||||
|
PROFILE = WeboobProfile(version)
|
||||||
|
|
||||||
|
self.browser = WeboobBrowser()
|
||||||
|
|
||||||
self.workdir = workdir
|
self.workdir = workdir
|
||||||
self.datadir = datadir
|
self.datadir = datadir
|
||||||
|
|
@ -503,10 +501,10 @@ class Repositories(object):
|
||||||
for name in sorted(os.listdir(self.repos_dir)):
|
for name in sorted(os.listdir(self.repos_dir)):
|
||||||
path = os.path.join(self.repos_dir, name)
|
path = os.path.join(self.repos_dir, name)
|
||||||
try:
|
try:
|
||||||
repository = Repository(path)
|
repository = Repository(self.browser, path)
|
||||||
self.repositories.append(repository)
|
self.repositories.append(repository)
|
||||||
except RepositoryUnavailable as e:
|
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):
|
def get_module_icon_path(self, module):
|
||||||
return os.path.join(self.icons_dir, '%s.png' % module.name)
|
return os.path.join(self.icons_dir, '%s.png' % module.name)
|
||||||
|
|
@ -530,14 +528,13 @@ class Repositories(object):
|
||||||
else:
|
else:
|
||||||
icon_url = module.url.replace('.tar.gz', '.png')
|
icon_url = module.url.replace('.tar.gz', '.png')
|
||||||
|
|
||||||
browser = WeboobBrowser()
|
|
||||||
try:
|
try:
|
||||||
icon = browser.openurl(icon_url)
|
icon = self.browser.open(icon_url)
|
||||||
except BrowserUnavailable:
|
except BrowserUnavailable:
|
||||||
pass # no icon, no problem
|
pass # no icon, no problem
|
||||||
else:
|
else:
|
||||||
with open(dest_path, 'wb') as fp:
|
with open(dest_path, 'wb') as fp:
|
||||||
fp.write(icon.read())
|
fp.write(icon.content)
|
||||||
|
|
||||||
def _parse_source_list(self):
|
def _parse_source_list(self):
|
||||||
l = []
|
l = []
|
||||||
|
|
@ -564,7 +561,7 @@ class Repositories(object):
|
||||||
gpgv = Keyring.find_gpgv()
|
gpgv = Keyring.find_gpgv()
|
||||||
for line in self._parse_source_list():
|
for line in self._parse_source_list():
|
||||||
progress.progress(0.0, 'Getting %s' % line)
|
progress.progress(0.0, 'Getting %s' % line)
|
||||||
repository = Repository(line)
|
repository = Repository(self.browser, line)
|
||||||
filename = self.url2filename(repository.url)
|
filename = self.url2filename(repository.url)
|
||||||
prio_filename = '%02d-%s' % (len(self.repositories), filename)
|
prio_filename = '%02d-%s' % (len(self.repositories), filename)
|
||||||
repo_path = os.path.join(self.repos_dir, prio_filename)
|
repo_path = os.path.join(self.repos_dir, prio_filename)
|
||||||
|
|
@ -587,7 +584,7 @@ class Repositories(object):
|
||||||
"""
|
"""
|
||||||
l = []
|
l = []
|
||||||
for line in self._parse_source_list():
|
for line in self._parse_source_list():
|
||||||
repository = Repository(line)
|
repository = Repository(self.browser, line)
|
||||||
filename = self.url2filename(repository.url)
|
filename = self.url2filename(repository.url)
|
||||||
prio_filename = '%02d-%s' % (len(l), filename)
|
prio_filename = '%02d-%s' % (len(l), filename)
|
||||||
repo_path = os.path.join(self.repos_dir, prio_filename)
|
repo_path = os.path.join(self.repos_dir, prio_filename)
|
||||||
|
|
@ -657,17 +654,16 @@ class Repositories(object):
|
||||||
else:
|
else:
|
||||||
raise ModuleInstallError('The latest version of %s is already installed' % module.name)
|
raise ModuleInstallError('The latest version of %s is already installed' % module.name)
|
||||||
|
|
||||||
browser = WeboobBrowser()
|
|
||||||
progress.progress(0.2, 'Downloading module...')
|
progress.progress(0.2, 'Downloading module...')
|
||||||
try:
|
try:
|
||||||
tardata = browser.readurl(module.url)
|
tardata = self.browser.open(module.url).content
|
||||||
except BrowserUnavailable as e:
|
except BrowserUnavailable as e:
|
||||||
raise ModuleInstallError('Unable to fetch module: %s' % e)
|
raise ModuleInstallError('Unable to fetch module: %s' % e)
|
||||||
|
|
||||||
# Check signature
|
# Check signature
|
||||||
if module.signed and Keyring.find_gpgv():
|
if module.signed and Keyring.find_gpgv():
|
||||||
progress.progress(0.5, 'Checking module authenticity...')
|
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_path = os.path.join(self.keyrings_dir, self.url2filename(module.repo_url))
|
||||||
keyring = Keyring(keyring_path)
|
keyring = Keyring(keyring_path)
|
||||||
if not keyring.exists():
|
if not keyring.exists():
|
||||||
|
|
@ -679,7 +675,7 @@ class Repositories(object):
|
||||||
if os.path.isdir(module_dir):
|
if os.path.isdir(module_dir):
|
||||||
shutil.rmtree(module_dir)
|
shutil.rmtree(module_dir)
|
||||||
progress.progress(0.7, 'Setting up module...')
|
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)
|
tar.extractall(self.modules_dir)
|
||||||
if not os.path.isdir(module_dir):
|
if not os.path.isdir(module_dir):
|
||||||
raise ModuleInstallError('The archive for %s looks invalid.' % module.name)
|
raise ModuleInstallError('The archive for %s looks invalid.' % module.name)
|
||||||
|
|
@ -776,7 +772,7 @@ class Keyring(object):
|
||||||
stderr=subprocess.PIPE)
|
stderr=subprocess.PIPE)
|
||||||
out, err = proc.communicate(data)
|
out, err = proc.communicate(data)
|
||||||
if proc.returncode or 'GOODSIG' not in out or 'VALIDSIG' not in out:
|
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 False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,14 @@
|
||||||
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
# 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.log import getLogger
|
||||||
from weboob.tools.misc import get_backtrace
|
from weboob.tools.misc import get_backtrace
|
||||||
|
|
||||||
|
|
@ -45,14 +50,14 @@ class IScheduler(object):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
class RepeatedTimer(_Timer):
|
class RepeatedTimer(Timer):
|
||||||
def run(self):
|
def run(self):
|
||||||
while not self.finished.isSet():
|
while not self.finished.isSet():
|
||||||
try:
|
try:
|
||||||
self.function(*self.args, **self.kwargs)
|
self.function(*self.args, **self.kwargs)
|
||||||
except Exception:
|
except Exception:
|
||||||
# do not stop timer because of an exception
|
# do not stop timer because of an exception
|
||||||
print get_backtrace()
|
print(get_backtrace())
|
||||||
self.finished.wait(self.interval)
|
self.finished.wait(self.interval)
|
||||||
self.finished.set()
|
self.finished.set()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@
|
||||||
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import optparse
|
import optparse
|
||||||
from optparse import OptionGroup, OptionParser
|
from optparse import OptionGroup, OptionParser
|
||||||
|
|
@ -27,7 +29,6 @@ import tempfile
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from weboob.capabilities.base import ConversionWarning, CapBaseObject
|
from weboob.capabilities.base import ConversionWarning, CapBaseObject
|
||||||
from weboob.tools.browser.browser import FormFieldConversionWarning
|
|
||||||
from weboob.core import Weboob, CallErrors
|
from weboob.core import Weboob, CallErrors
|
||||||
from weboob.core.backendscfg import BackendsConfig
|
from weboob.core.backendscfg import BackendsConfig
|
||||||
from weboob.tools.config.iconfig import ConfigError
|
from weboob.tools.config.iconfig import ConfigError
|
||||||
|
|
@ -295,9 +296,9 @@ class BaseApplication(object):
|
||||||
if isinstance(error, MoreResultsAvailable):
|
if isinstance(error, MoreResultsAvailable):
|
||||||
return False
|
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:
|
if logging.root.level == logging.DEBUG:
|
||||||
print >>sys.stderr, backtrace
|
print(backtrace, file=sys.stderr)
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
@ -322,7 +323,7 @@ class BaseApplication(object):
|
||||||
ask_debug_mode = True
|
ask_debug_mode = True
|
||||||
|
|
||||||
if ask_debug_mode:
|
if ask_debug_mode:
|
||||||
print >>sys.stderr, debugmsg
|
print(debugmsg, file=sys.stderr)
|
||||||
|
|
||||||
def parse_args(self, args):
|
def parse_args(self, args):
|
||||||
self.options, args = self._parser.parse_args(args)
|
self.options, args = self._parser.parse_args(args)
|
||||||
|
|
@ -333,7 +334,7 @@ class BaseApplication(object):
|
||||||
if not option.help is optparse.SUPPRESS_HELP:
|
if not option.help is optparse.SUPPRESS_HELP:
|
||||||
items.update(str(option).split('/'))
|
items.update(str(option).split('/'))
|
||||||
items.update(self._get_completions())
|
items.update(self._get_completions())
|
||||||
print ' '.join(items)
|
print(' '.join(items))
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
if self.options.debug or self.options.save_responses:
|
if self.options.debug or self.options.save_responses:
|
||||||
|
|
@ -350,13 +351,18 @@ class BaseApplication(object):
|
||||||
# this only matters to developers
|
# this only matters to developers
|
||||||
if not self.options.debug and not self.options.save_responses:
|
if not self.options.debug and not self.options.save_responses:
|
||||||
warnings.simplefilter('ignore', category=ConversionWarning)
|
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 = []
|
handlers = []
|
||||||
|
|
||||||
if self.options.save_responses:
|
if self.options.save_responses:
|
||||||
responses_dirname = tempfile.mkdtemp(prefix='weboob_session_')
|
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['save_responses'] = True
|
||||||
log_settings['responses_dirname'] = responses_dirname
|
log_settings['responses_dirname'] = responses_dirname
|
||||||
handlers.append(self.create_logging_file_handler(os.path.join(responses_dirname, 'debug.log')))
|
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()])
|
cls.setup_logging(logging.INFO, [cls.create_default_logger()])
|
||||||
|
|
||||||
if args is None:
|
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:
|
try:
|
||||||
app = cls()
|
app = cls()
|
||||||
except BackendsConfig.WrongPermissions as e:
|
except BackendsConfig.WrongPermissions as e:
|
||||||
print >>sys.stderr, e
|
print(e, file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
@ -437,12 +443,12 @@ class BaseApplication(object):
|
||||||
args = app.parse_args(args)
|
args = app.parse_args(args)
|
||||||
sys.exit(app.main(args))
|
sys.exit(app.main(args))
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print >>sys.stderr, 'Program killed by SIGINT'
|
print('Program killed by SIGINT', file=sys.stderr)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
except EOFError:
|
except EOFError:
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
except ConfigError as e:
|
except ConfigError as e:
|
||||||
print >>sys.stderr, 'Configuration error: %s' % e
|
print('Configuration error: %s' % e, file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
except CallErrors as e:
|
except CallErrors as e:
|
||||||
try:
|
try:
|
||||||
|
|
@ -451,7 +457,7 @@ class BaseApplication(object):
|
||||||
pass
|
pass
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
except ResultsConditionError as e:
|
except ResultsConditionError as e:
|
||||||
print >>sys.stderr, '%s' % e
|
print('%s' % e, file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
finally:
|
finally:
|
||||||
app.deinit()
|
app.deinit()
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
from copy import copy
|
from copy import copy
|
||||||
import getpass
|
import getpass
|
||||||
|
|
@ -110,7 +111,7 @@ class ConsoleApplication(BaseApplication):
|
||||||
ret = super(ConsoleApplication, self).load_backends(*args, **kwargs)
|
ret = super(ConsoleApplication, self).load_backends(*args, **kwargs)
|
||||||
|
|
||||||
for err in errors:
|
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):
|
if self.ask('Do you want to reconfigure this backend?', default=True):
|
||||||
self.edit_backend(err.backend_name)
|
self.edit_backend(err.backend_name)
|
||||||
self.load_backends(names=[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):
|
def check_loaded_backends(self, default_config=None):
|
||||||
while len(self.enabled_backends) == 0:
|
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):
|
if not os.isatty(sys.stdout.fileno()) or not self.ask('Do you want to configure backends?', default=True):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
@ -136,7 +137,7 @@ class ConsoleApplication(BaseApplication):
|
||||||
r = ''
|
r = ''
|
||||||
while r != 'q':
|
while r != 'q':
|
||||||
modules = []
|
modules = []
|
||||||
print '\nAvailable modules:'
|
print('\nAvailable modules:')
|
||||||
for name, info in sorted(self.weboob.repositories.get_all_modules_info().iteritems()):
|
for name, info in sorted(self.weboob.repositories.get_all_modules_info().iteritems()):
|
||||||
if not self.is_module_loadable(info):
|
if not self.is_module_loadable(info):
|
||||||
continue
|
continue
|
||||||
|
|
@ -150,16 +151,16 @@ class ConsoleApplication(BaseApplication):
|
||||||
loaded = 2
|
loaded = 2
|
||||||
else:
|
else:
|
||||||
loaded += 1
|
loaded += 1
|
||||||
print '%s%d)%s [%s] %s%-15s%s %s' % (self.BOLD, len(modules), self.NC, loaded,
|
print('%s%d)%s [%s] %s%-15s%s %s' % (self.BOLD, len(modules), self.NC, loaded,
|
||||||
self.BOLD, name, self.NC, info.description)
|
self.BOLD, name, self.NC, info.description))
|
||||||
print '%sa) --all--%s install all backends' % (self.BOLD, self.NC)
|
print('%sa) --all--%s install all backends' % (self.BOLD, self.NC))
|
||||||
print '%sq)%s --stop--\n' % (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)$')
|
r = self.ask('Select a backend to create (q to stop)', regexp='^(\d+|q|a)$')
|
||||||
|
|
||||||
if str(r).isdigit():
|
if str(r).isdigit():
|
||||||
i = int(r) - 1
|
i = int(r) - 1
|
||||||
if i < 0 or i >= len(modules):
|
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
|
continue
|
||||||
name = modules[i]
|
name = modules[i]
|
||||||
try:
|
try:
|
||||||
|
|
@ -167,7 +168,7 @@ class ConsoleApplication(BaseApplication):
|
||||||
if inst:
|
if inst:
|
||||||
self.load_backends(names=[inst])
|
self.load_backends(names=[inst])
|
||||||
except (KeyboardInterrupt, EOFError):
|
except (KeyboardInterrupt, EOFError):
|
||||||
print '\nAborted.'
|
print('\nAborted.')
|
||||||
elif r == 'a':
|
elif r == 'a':
|
||||||
try:
|
try:
|
||||||
for name in modules:
|
for name in modules:
|
||||||
|
|
@ -177,11 +178,11 @@ class ConsoleApplication(BaseApplication):
|
||||||
if inst:
|
if inst:
|
||||||
self.load_backends(names=[inst])
|
self.load_backends(names=[inst])
|
||||||
except (KeyboardInterrupt, EOFError):
|
except (KeyboardInterrupt, EOFError):
|
||||||
print '\nAborted.'
|
print('\nAborted.')
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|
||||||
print 'Right right!'
|
print('Right right!')
|
||||||
|
|
||||||
def _handle_options(self):
|
def _handle_options(self):
|
||||||
self.load_default_backends()
|
self.load_default_backends()
|
||||||
|
|
@ -202,7 +203,7 @@ class ConsoleApplication(BaseApplication):
|
||||||
try:
|
try:
|
||||||
super(ConsoleApplication, klass).run(args)
|
super(ConsoleApplication, klass).run(args)
|
||||||
except BackendNotFound as e:
|
except BackendNotFound as e:
|
||||||
print 'Error: Backend "%s" not found.' % e
|
print('Error: Backend "%s" not found.' % e)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
def do(self, function, *args, **kwargs):
|
def do(self, function, *args, **kwargs):
|
||||||
|
|
@ -234,11 +235,11 @@ class ConsoleApplication(BaseApplication):
|
||||||
backend = None
|
backend = None
|
||||||
|
|
||||||
if not backend:
|
if not backend:
|
||||||
print >>sys.stderr, 'Backend "%s" does not exist.' % name
|
print('Backend "%s" does not exist.' % name, file=sys.stderr)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
if not backend.has_caps(ICapAccount) or backend.klass.ACCOUNT_REGISTER_PROPERTIES is None:
|
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
|
return 1
|
||||||
|
|
||||||
account = Account()
|
account = Account()
|
||||||
|
|
@ -252,17 +253,17 @@ class ConsoleApplication(BaseApplication):
|
||||||
for key, prop in backend.klass.ACCOUNT_REGISTER_PROPERTIES.iteritems():
|
for key, prop in backend.klass.ACCOUNT_REGISTER_PROPERTIES.iteritems():
|
||||||
if not asked_config:
|
if not asked_config:
|
||||||
asked_config = True
|
asked_config = True
|
||||||
print 'Configuration of new account %s' % website
|
print('Configuration of new account %s' % website)
|
||||||
print '-----------------------------%s' % ('-' * len(website))
|
print('-----------------------------%s' % ('-' * len(website)))
|
||||||
p = copy(prop)
|
p = copy(prop)
|
||||||
p.set(self.ask(prop, default=account.properties[key].get() if (key in account.properties) else prop.default))
|
p.set(self.ask(prop, default=account.properties[key].get() if (key in account.properties) else prop.default))
|
||||||
account.properties[key] = p
|
account.properties[key] = p
|
||||||
if asked_config:
|
if asked_config:
|
||||||
print '-----------------------------%s' % ('-' * len(website))
|
print('-----------------------------%s' % ('-' * len(website)))
|
||||||
try:
|
try:
|
||||||
backend.klass.register_account(account)
|
backend.klass.register_account(account)
|
||||||
except AccountRegisterError as e:
|
except AccountRegisterError as e:
|
||||||
print u'%s' % e
|
print(u'%s' % e)
|
||||||
if self.ask('Do you want to try again?', default=True):
|
if self.ask('Do you want to try again?', default=True):
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
|
|
@ -283,10 +284,10 @@ class ConsoleApplication(BaseApplication):
|
||||||
try:
|
try:
|
||||||
self.weboob.repositories.install(name)
|
self.weboob.repositories.install(name)
|
||||||
except ModuleInstallError as e:
|
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
|
return False
|
||||||
|
|
||||||
print ''
|
print('')
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def edit_backend(self, name, params=None):
|
def edit_backend(self, name, params=None):
|
||||||
|
|
@ -304,7 +305,7 @@ class ConsoleApplication(BaseApplication):
|
||||||
if minfo is None:
|
if minfo is None:
|
||||||
raise ModuleLoadError(name, 'Module does not exist')
|
raise ModuleLoadError(name, 'Module does not exist')
|
||||||
if not minfo.is_installed():
|
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)
|
self.install_module(minfo)
|
||||||
module = self.weboob.modules_loader.get_or_load_module(name)
|
module = self.weboob.modules_loader.get_or_load_module(name)
|
||||||
config = module.config
|
config = module.config
|
||||||
|
|
@ -315,7 +316,7 @@ class ConsoleApplication(BaseApplication):
|
||||||
params = items
|
params = items
|
||||||
config = module.config.load(self.weboob, bname, name, params, nofail=True)
|
config = module.config.load(self.weboob, bname, name, params, nofail=True)
|
||||||
except ModuleLoadError as e:
|
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
|
return 1
|
||||||
|
|
||||||
# ask for params non-specified on command-line arguments
|
# ask for params non-specified on command-line arguments
|
||||||
|
|
@ -323,18 +324,18 @@ class ConsoleApplication(BaseApplication):
|
||||||
for key, value in config.iteritems():
|
for key, value in config.iteritems():
|
||||||
if not asked_config:
|
if not asked_config:
|
||||||
asked_config = True
|
asked_config = True
|
||||||
print ''
|
print('')
|
||||||
print 'Configuration of backend %s' % module.name
|
print('Configuration of backend %s' % module.name)
|
||||||
print '-------------------------%s' % ('-' * len(module.name))
|
print('-------------------------%s' % ('-' * len(module.name)))
|
||||||
if key not in params or edit:
|
if key not in params or edit:
|
||||||
params[key] = self.ask(value, default=params[key] if (key in params) else value.default)
|
params[key] = self.ask(value, default=params[key] if (key in params) else value.default)
|
||||||
else:
|
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:
|
if asked_config:
|
||||||
print '-------------------------%s' % ('-' * len(module.name))
|
print('-------------------------%s' % ('-' * len(module.name)))
|
||||||
|
|
||||||
while not edit and self.weboob.backends_config.backend_exists(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):
|
if not self.ask('Add new backend for module "%s"?' % module.name, default=False):
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
@ -347,10 +348,10 @@ class ConsoleApplication(BaseApplication):
|
||||||
continue
|
continue
|
||||||
config[key].set(value)
|
config[key].set(value)
|
||||||
config.save(edit=edit)
|
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
|
return name
|
||||||
except BackendAlreadyExists:
|
except BackendAlreadyExists:
|
||||||
print >>sys.stderr, 'Backend "%s" already exists.' % name
|
print('Backend "%s" already exists.' % name, file=sys.stderr)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
def ask(self, question, default=None, masked=None, regexp=None, choices=None, tiny=None):
|
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)
|
question = u'[%s] %s' % (v.id, question)
|
||||||
|
|
||||||
if isinstance(v, ValueBackendPassword):
|
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
|
question = v.label
|
||||||
choices = OrderedDict()
|
choices = OrderedDict()
|
||||||
choices['c'] = 'Run an external tool during backend load'
|
choices['c'] = 'Run an external tool during backend load'
|
||||||
|
|
@ -414,9 +415,9 @@ class ConsoleApplication(BaseApplication):
|
||||||
if r == 'p':
|
if r == 'p':
|
||||||
return ''
|
return ''
|
||||||
if r == 'c':
|
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):
|
if v.is_command(v.default):
|
||||||
print ': %s' % v.default[1:-1]
|
print(': %s' % v.default[1:-1])
|
||||||
else:
|
else:
|
||||||
d = None
|
d = None
|
||||||
while True:
|
while True:
|
||||||
|
|
@ -424,7 +425,7 @@ class ConsoleApplication(BaseApplication):
|
||||||
try:
|
try:
|
||||||
subprocess.check_output(cmd, shell=True)
|
subprocess.check_output(cmd, shell=True)
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
print '%s' % e
|
print('%s' % e)
|
||||||
else:
|
else:
|
||||||
return '`%s`' % cmd
|
return '`%s`' % cmd
|
||||||
|
|
||||||
|
|
@ -443,10 +444,10 @@ class ConsoleApplication(BaseApplication):
|
||||||
question = u'%s (%s)' % (question, '/'.join((s.upper() if s == v.default else s)
|
question = u'%s (%s)' % (question, '/'.join((s.upper() if s == v.default else s)
|
||||||
for s in (v.choices.iterkeys())))
|
for s in (v.choices.iterkeys())))
|
||||||
for key, value in v.choices.iteritems():
|
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:
|
else:
|
||||||
for n, (key, value) in enumerate(v.choices.iteritems()):
|
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
|
aliases[str(n + 1)] = key
|
||||||
question = u'%s (choose in list)' % question
|
question = u'%s (choose in list)' % question
|
||||||
if v.masked:
|
if v.masked:
|
||||||
|
|
@ -483,7 +484,7 @@ class ConsoleApplication(BaseApplication):
|
||||||
try:
|
try:
|
||||||
v.set(line)
|
v.set(line)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
print >>sys.stderr, u'Error: %s' % e
|
print(u'Error: %s' % e, file=sys.stderr)
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
@ -509,8 +510,8 @@ class ConsoleApplication(BaseApplication):
|
||||||
text = f.read()
|
text = f.read()
|
||||||
else:
|
else:
|
||||||
if sys.stdin.isatty():
|
if sys.stdin.isatty():
|
||||||
print 'Reading content from stdin... Type ctrl-D ' \
|
print('Reading content from stdin... Type ctrl-D ' \
|
||||||
'from an empty line to stop.'
|
'from an empty line to stop.')
|
||||||
text = sys.stdin.read()
|
text = sys.stdin.read()
|
||||||
return text.decode(sys.stdin.encoding or locale.getpreferredencoding())
|
return text.decode(sys.stdin.encoding or locale.getpreferredencoding())
|
||||||
|
|
||||||
|
|
@ -524,7 +525,7 @@ class ConsoleApplication(BaseApplication):
|
||||||
msg = unicode(error)
|
msg = unicode(error)
|
||||||
if not msg:
|
if not msg:
|
||||||
msg = 'invalid login/password.'
|
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):
|
if self.ask('Do you want to reconfigure this backend?', default=True):
|
||||||
self.unload_backends(names=[backend.name])
|
self.unload_backends(names=[backend.name])
|
||||||
self.edit_backend(backend.name)
|
self.edit_backend(backend.name)
|
||||||
|
|
@ -533,21 +534,21 @@ class ConsoleApplication(BaseApplication):
|
||||||
msg = unicode(error)
|
msg = unicode(error)
|
||||||
if not msg:
|
if not msg:
|
||||||
msg = 'website is unavailable.'
|
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):
|
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):
|
elif isinstance(error, NotImplementedError):
|
||||||
print >>sys.stderr, u'Error(%s): this feature is not supported yet by this backend.' % backend.name
|
print(u'Error(%s): this feature is not supported yet by this backend.' % backend.name, file=sys.stderr)
|
||||||
print >>sys.stderr, u' %s To help the maintainer of this backend implement this feature,' % (' ' * len(backend.name))
|
print(u' %s To help the maintainer of this backend implement this feature,' % (' ' * len(backend.name)), file=sys.stderr)
|
||||||
print >>sys.stderr, u' %s please contact: %s <%s@issues.weboob.org>' % (' ' * len(backend.name), backend.MAINTAINER, backend.NAME)
|
print(u' %s please contact: %s <%s@issues.weboob.org>' % (' ' * len(backend.name), backend.MAINTAINER, backend.NAME), file=sys.stderr)
|
||||||
elif isinstance(error, UserError):
|
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):
|
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):
|
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:
|
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)
|
minfo = self.weboob.repositories.get_module_info(backend.NAME)
|
||||||
if minfo and not minfo.is_local():
|
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 \
|
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.ask('A new version of %s is available. Do you want to install it?' % minfo.name, default=True) and \
|
||||||
self.install_module(minfo):
|
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
|
return
|
||||||
|
|
||||||
if logging.root.level == logging.DEBUG:
|
if logging.root.level == logging.DEBUG:
|
||||||
print >>sys.stderr, backtrace
|
print(backtrace, file=sys.stderr)
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
@ -581,6 +582,6 @@ class ConsoleApplication(BaseApplication):
|
||||||
ask_debug_mode = True
|
ask_debug_mode = True
|
||||||
|
|
||||||
if ask_debug_mode:
|
if ask_debug_mode:
|
||||||
print >>sys.stderr, debugmsg
|
print(debugmsg, file=sys.stderr)
|
||||||
elif len(more_results) > 0:
|
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)
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@
|
||||||
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
@ -118,7 +120,7 @@ class IFormatter(object):
|
||||||
|
|
||||||
if isinstance(line, unicode):
|
if isinstance(line, unicode):
|
||||||
line = line.encode('utf-8')
|
line = line.encode('utf-8')
|
||||||
print line
|
print(line)
|
||||||
self.print_lines += 1
|
self.print_lines += 1
|
||||||
|
|
||||||
def start_format(self, **kwargs):
|
def start_format(self, **kwargs):
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@
|
||||||
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
# 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.capabilities.base import NotAvailable, NotLoaded
|
||||||
from weboob.tools.json import json
|
from weboob.tools.json import json
|
||||||
|
|
||||||
|
|
@ -52,7 +54,7 @@ class JsonFormatter(IFormatter):
|
||||||
self.queue = []
|
self.queue = []
|
||||||
|
|
||||||
def flush(self):
|
def flush(self):
|
||||||
print json.dumps(self.queue, cls=Encoder)
|
print(json.dumps(self.queue, cls=Encoder))
|
||||||
|
|
||||||
def format_dict(self, item):
|
def format_dict(self, item):
|
||||||
self.queue.append(item)
|
self.queue.append(item)
|
||||||
|
|
@ -64,4 +66,4 @@ class JsonLineFormatter(IFormatter):
|
||||||
The advantage is that it can be streamed.
|
The advantage is that it can be streamed.
|
||||||
"""
|
"""
|
||||||
def format_dict(self, item):
|
def format_dict(self, item):
|
||||||
print json.dumps(item, cls=Encoder)
|
print(json.dumps(item, cls=Encoder))
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@
|
||||||
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
from prettytable import PrettyTable
|
from prettytable import PrettyTable
|
||||||
|
|
||||||
from weboob.capabilities.base import empty
|
from weboob.capabilities.base import empty
|
||||||
|
|
@ -40,7 +42,7 @@ class TableFormatter(IFormatter):
|
||||||
def flush(self):
|
def flush(self):
|
||||||
s = self.get_formatted_table()
|
s = self.get_formatted_table()
|
||||||
if s is not None:
|
if s is not None:
|
||||||
print s.encode('utf-8')
|
print(s.encode('utf-8'))
|
||||||
|
|
||||||
def get_formatted_table(self):
|
def get_formatted_table(self):
|
||||||
if len(self.queue) == 0:
|
if len(self.queue) == 0:
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@
|
||||||
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from subprocess import PIPE, Popen
|
from subprocess import PIPE, Popen
|
||||||
import cookielib
|
import cookielib
|
||||||
|
|
@ -102,7 +104,7 @@ class MediaPlayer(object):
|
||||||
player_name = args[0]
|
player_name = args[0]
|
||||||
args.append(media.url)
|
args.append(media.url)
|
||||||
|
|
||||||
print 'Invoking "%s".' % (' '.join(args))
|
print('Invoking "%s".' % (' '.join(args)))
|
||||||
os.spawnlp(os.P_WAIT, player_name, *args)
|
os.spawnlp(os.P_WAIT, player_name, *args)
|
||||||
|
|
||||||
def _play_proxy(self, media, player_name, args):
|
def _play_proxy(self, media, player_name, args):
|
||||||
|
|
@ -120,9 +122,9 @@ class MediaPlayer(object):
|
||||||
|
|
||||||
assert args is not None
|
assert args is not None
|
||||||
|
|
||||||
print ':: Play_proxy streaming from %s' % media.url
|
print(':: Play_proxy streaming from %s' % media.url)
|
||||||
print ':: to %s %s' % (player_name, args)
|
print(':: to %s %s' % (player_name, args))
|
||||||
print player_name + ' ' + args
|
print(player_name + ' ' + args)
|
||||||
proc = Popen(player_name + ' ' + args, stdin=PIPE, shell=True)
|
proc = Popen(player_name + ' ' + args, stdin=PIPE, shell=True)
|
||||||
|
|
||||||
# Handle cookies (and redirection 302...)
|
# Handle cookies (and redirection 302...)
|
||||||
|
|
@ -142,7 +144,7 @@ class MediaPlayer(object):
|
||||||
try:
|
try:
|
||||||
proc.stdin.write(_buffer)
|
proc.stdin.write(_buffer)
|
||||||
except:
|
except:
|
||||||
print "play_proxy broken pipe. Can't write anymore."
|
print("play_proxy broken pipe. Can't write anymore.")
|
||||||
break
|
break
|
||||||
|
|
||||||
def _play_rtmp(self, media, player_name, args):
|
def _play_rtmp(self, media, player_name, args):
|
||||||
|
|
@ -181,9 +183,9 @@ class MediaPlayer(object):
|
||||||
player_name = player_name.split(' ')
|
player_name = player_name.split(' ')
|
||||||
args = args.split(' ')
|
args = args.split(' ')
|
||||||
|
|
||||||
print ':: Streaming from %s' % media_url
|
print(':: Streaming from %s' % media_url)
|
||||||
print ':: to %s %s' % (player_name, args)
|
print(':: to %s %s' % (player_name, args))
|
||||||
print ':: %s' % rtmp
|
print(':: %s' % rtmp)
|
||||||
p1 = Popen(rtmp.split(), stdout=PIPE)
|
p1 = Popen(rtmp.split(), stdout=PIPE)
|
||||||
Popen(player_name + args, stdin=p1.stdout, stderr=PIPE)
|
Popen(player_name + args, stdin=p1.stdout, stderr=PIPE)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
|
|
@ -237,8 +239,8 @@ class QtDo(QObject):
|
||||||
msg += u'<br />%s' % to_unicode(line)
|
msg += u'<br />%s' % to_unicode(line)
|
||||||
if ul_opened:
|
if ul_opened:
|
||||||
msg += u'</li></ul>'
|
msg += u'</li></ul>'
|
||||||
print >>sys.stderr, error
|
print(error, file=sys.stderr)
|
||||||
print >>sys.stderr, backtrace
|
print(backtrace, file=sys.stderr)
|
||||||
QMessageBox.critical(None, unicode(self.tr('Error with backend %s')) % backend.name,
|
QMessageBox.critical(None, unicode(self.tr('Error with backend %s')) % backend.name,
|
||||||
msg, QMessageBox.Ok)
|
msg, QMessageBox.Ok)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
import atexit
|
import atexit
|
||||||
from cmd import Cmd
|
from cmd import Cmd
|
||||||
|
|
@ -198,20 +199,20 @@ class ReplApplication(Cmd, ConsoleApplication):
|
||||||
except BackendNotGiven as e:
|
except BackendNotGiven as e:
|
||||||
backend_name = None
|
backend_name = None
|
||||||
while not backend_name:
|
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):
|
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,
|
print('%s%d)%s %s%-15s%s %s' % (self.BOLD, index + 1, self.NC, self.BOLD, name, self.NC,
|
||||||
backend.DESCRIPTION)
|
backend.DESCRIPTION))
|
||||||
i = self.ask('Select a backend to proceed with "%s"' % id)
|
i = self.ask('Select a backend to proceed with "%s"' % id)
|
||||||
if not i.isdigit():
|
if not i.isdigit():
|
||||||
if not i in dict(e.backends):
|
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
|
continue
|
||||||
backend_name = i
|
backend_name = i
|
||||||
else:
|
else:
|
||||||
i = int(i)
|
i = int(i)
|
||||||
if i < 0 or i > len(e.backends):
|
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
|
continue
|
||||||
backend_name = e.backends[i-1][0]
|
backend_name = e.backends[i-1][0]
|
||||||
|
|
||||||
|
|
@ -405,12 +406,12 @@ class ReplApplication(Cmd, ConsoleApplication):
|
||||||
except CallErrors as e:
|
except CallErrors as e:
|
||||||
self.bcall_errors_handler(e)
|
self.bcall_errors_handler(e)
|
||||||
except BackendNotGiven as e:
|
except BackendNotGiven as e:
|
||||||
print >>sys.stderr, 'Error: %s' % str(e)
|
print('Error: %s' % str(e), file=sys.stderr)
|
||||||
except NotEnoughArguments as e:
|
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):
|
except (KeyboardInterrupt, EOFError):
|
||||||
# ^C during a command process doesn't exit application.
|
# ^C during a command process doesn't exit application.
|
||||||
print '\nAborted.'
|
print('\nAborted.')
|
||||||
finally:
|
finally:
|
||||||
self.flush()
|
self.flush()
|
||||||
|
|
||||||
|
|
@ -422,12 +423,12 @@ class ReplApplication(Cmd, ConsoleApplication):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def default(self, line):
|
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)
|
cmd, arg, ignore = Cmd.parseline(self, line)
|
||||||
if cmd is not None:
|
if cmd is not None:
|
||||||
names = set(name[3:] for name in self.get_names() if name.startswith('do_' + cmd))
|
names = set(name[3:] for name in self.get_names() if name.startswith('do_' + cmd))
|
||||||
if len(names) > 0:
|
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
|
return 2
|
||||||
|
|
||||||
def completenames(self, text, *ignored):
|
def completenames(self, text, *ignored):
|
||||||
|
|
@ -561,7 +562,7 @@ class ReplApplication(Cmd, ConsoleApplication):
|
||||||
Quit the command line interpreter when ^D is pressed.
|
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 empty line for the next shell prompt to appear on the first column of the terminal
|
||||||
print
|
print()
|
||||||
return self.do_quit(arg)
|
return self.do_quit(arg)
|
||||||
|
|
||||||
def do_help(self, arg=None):
|
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)
|
lines[0] = '%s%s%s' % (self.BOLD, lines[0], self.NC)
|
||||||
self.stdout.write('%s\n' % '\n'.join(lines))
|
self.stdout.write('%s\n' % '\n'.join(lines))
|
||||||
else:
|
else:
|
||||||
print >>sys.stderr, 'Unknown command: "%s"' % arg
|
print('Unknown command: "%s"' % arg, file=sys.stderr)
|
||||||
else:
|
else:
|
||||||
cmds = self._parser.formatter.format_commands(self._parser.commands)
|
cmds = self._parser.formatter.format_commands(self._parser.commands)
|
||||||
self.stdout.write('%s\n' % cmds)
|
self.stdout.write('%s\n' % cmds)
|
||||||
|
|
@ -644,20 +645,20 @@ class ReplApplication(Cmd, ConsoleApplication):
|
||||||
if action in ('add', 'register'):
|
if action in ('add', 'register'):
|
||||||
minfo = self.weboob.repositories.get_module_info(backend_name)
|
minfo = self.weboob.repositories.get_module_info(backend_name)
|
||||||
if minfo is None:
|
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
|
return 1
|
||||||
else:
|
else:
|
||||||
if not minfo.has_caps(self.CAPS):
|
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
|
return 1
|
||||||
else:
|
else:
|
||||||
if backend_name not in [backend.name for backend in self.weboob.iter_backends()]:
|
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
|
return 1
|
||||||
|
|
||||||
if action in ('enable', 'disable', 'only', 'add', 'register', 'edit', 'remove'):
|
if action in ('enable', 'disable', 'only', 'add', 'register', 'edit', 'remove'):
|
||||||
if not given_backend_names:
|
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
|
return 2
|
||||||
|
|
||||||
given_backends = set(backend for backend in self.weboob.iter_backends() if backend.name in given_backend_names)
|
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:
|
try:
|
||||||
self.enabled_backends.remove(backend)
|
self.enabled_backends.remove(backend)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
print >>sys.stderr, '%s is not enabled' % backend.name
|
print('%s is not enabled' % backend.name, file=sys.stderr)
|
||||||
elif action == 'only':
|
elif action == 'only':
|
||||||
self.enabled_backends = set()
|
self.enabled_backends = set()
|
||||||
for backend in given_backends:
|
for backend in given_backends:
|
||||||
|
|
@ -678,9 +679,9 @@ class ReplApplication(Cmd, ConsoleApplication):
|
||||||
elif action == 'list':
|
elif action == 'list':
|
||||||
enabled_backends_names = set(backend.name for backend in self.enabled_backends)
|
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
|
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:
|
if len(disabled_backends_names) > 0:
|
||||||
print 'Disabled: %s' % ', '.join(disabled_backends_names)
|
print('Disabled: %s' % ', '.join(disabled_backends_names))
|
||||||
elif action == 'add':
|
elif action == 'add':
|
||||||
for name in given_backend_names:
|
for name in given_backend_names:
|
||||||
instname = self.add_backend(name)
|
instname = self.add_backend(name)
|
||||||
|
|
@ -705,7 +706,7 @@ class ReplApplication(Cmd, ConsoleApplication):
|
||||||
self.unload_backends(backend.name)
|
self.unload_backends(backend.name)
|
||||||
elif action == 'list-modules':
|
elif action == 'list-modules':
|
||||||
modules = []
|
modules = []
|
||||||
print 'Modules list:'
|
print('Modules list:')
|
||||||
for name, info in sorted(self.weboob.repositories.get_all_modules_info().iteritems()):
|
for name, info in sorted(self.weboob.repositories.get_all_modules_info().iteritems()):
|
||||||
if not self.is_module_loadable(info):
|
if not self.is_module_loadable(info):
|
||||||
continue
|
continue
|
||||||
|
|
@ -719,14 +720,14 @@ class ReplApplication(Cmd, ConsoleApplication):
|
||||||
loaded = 2
|
loaded = 2
|
||||||
else:
|
else:
|
||||||
loaded += 1
|
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:
|
else:
|
||||||
print >>sys.stderr, 'Unknown action: "%s"' % action
|
print('Unknown action: "%s"' % action, file=sys.stderr)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
if len(self.enabled_backends) == 0:
|
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):
|
def complete_logging(self, text, line, begidx, endidx):
|
||||||
levels = ('debug', 'info', 'warning', 'error', 'quiet', 'default')
|
levels = ('debug', 'info', 'warning', 'error', 'quiet', 'default')
|
||||||
|
|
@ -760,15 +761,15 @@ class ReplApplication(Cmd, ConsoleApplication):
|
||||||
if logging.root.level == level:
|
if logging.root.level == level:
|
||||||
current = label
|
current = label
|
||||||
break
|
break
|
||||||
print 'Current level: %s' % current
|
print('Current level: %s' % current)
|
||||||
return
|
return
|
||||||
|
|
||||||
levels = dict(levels)
|
levels = dict(levels)
|
||||||
try:
|
try:
|
||||||
level = levels[args[0]]
|
level = levels[args[0]]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
print >>sys.stderr, 'Level "%s" does not exist.' % args[0]
|
print('Level "%s" does not exist.' % args[0], file=sys.stderr)
|
||||||
print >>sys.stderr, 'Availables: %s' % ' '.join(levels.iterkeys())
|
print('Availables: %s' % ' '.join(levels.iterkeys()), file=sys.stderr)
|
||||||
return 2
|
return 2
|
||||||
else:
|
else:
|
||||||
logging.root.setLevel(level)
|
logging.root.setLevel(level)
|
||||||
|
|
@ -792,13 +793,13 @@ class ReplApplication(Cmd, ConsoleApplication):
|
||||||
try:
|
try:
|
||||||
self.condition = ResultsCondition(line)
|
self.condition = ResultsCondition(line)
|
||||||
except ResultsConditionError as e:
|
except ResultsConditionError as e:
|
||||||
print >>sys.stderr, '%s' % e
|
print('%s' % e, file=sys.stderr)
|
||||||
return 2
|
return 2
|
||||||
else:
|
else:
|
||||||
if self.condition is None:
|
if self.condition is None:
|
||||||
print 'No condition is set.'
|
print('No condition is set.')
|
||||||
else:
|
else:
|
||||||
print str(self.condition)
|
print(str(self.condition))
|
||||||
|
|
||||||
def do_count(self, line):
|
def do_count(self, line):
|
||||||
"""
|
"""
|
||||||
|
|
@ -819,7 +820,7 @@ class ReplApplication(Cmd, ConsoleApplication):
|
||||||
try:
|
try:
|
||||||
count = int(line)
|
count = int(line)
|
||||||
except ValueError:
|
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
|
return 2
|
||||||
else:
|
else:
|
||||||
if count > 0:
|
if count > 0:
|
||||||
|
|
@ -830,9 +831,9 @@ class ReplApplication(Cmd, ConsoleApplication):
|
||||||
self._is_default_count = False
|
self._is_default_count = False
|
||||||
else:
|
else:
|
||||||
if self.options.count is None:
|
if self.options.count is None:
|
||||||
print 'Counting disabled.'
|
print('Counting disabled.')
|
||||||
else:
|
else:
|
||||||
print self.options.count
|
print(self.options.count)
|
||||||
|
|
||||||
def complete_formatter(self, text, line, *ignored):
|
def complete_formatter(self, text, line, *ignored):
|
||||||
formatters = self.formatters_loader.get_available_formatters()
|
formatters = self.formatters_loader.get_available_formatters()
|
||||||
|
|
@ -871,17 +872,17 @@ class ReplApplication(Cmd, ConsoleApplication):
|
||||||
args = line.strip().split()
|
args = line.strip().split()
|
||||||
if args:
|
if args:
|
||||||
if args[0] == 'list':
|
if args[0] == 'list':
|
||||||
print ', '.join(self.formatters_loader.get_available_formatters())
|
print(', '.join(self.formatters_loader.get_available_formatters()))
|
||||||
elif args[0] == 'option':
|
elif args[0] == 'option':
|
||||||
if len(args) > 1:
|
if len(args) > 1:
|
||||||
if len(args) == 2:
|
if len(args) == 2:
|
||||||
if args[1] == 'header':
|
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':
|
elif args[1] == 'keys':
|
||||||
print 'off' if self.options.no_keys else 'on'
|
print('off' if self.options.no_keys else 'on')
|
||||||
else:
|
else:
|
||||||
if args[2] not in ('on', 'off'):
|
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
|
return 2
|
||||||
else:
|
else:
|
||||||
if args[1] == 'header':
|
if args[1] == 'header':
|
||||||
|
|
@ -889,7 +890,7 @@ class ReplApplication(Cmd, ConsoleApplication):
|
||||||
elif args[1] == 'keys':
|
elif args[1] == 'keys':
|
||||||
self.options.no_keys = True if args[2] == 'off' else False
|
self.options.no_keys = True if args[2] == 'off' else False
|
||||||
else:
|
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
|
return 2
|
||||||
else:
|
else:
|
||||||
if args[0] in self.formatters_loader.get_available_formatters():
|
if args[0] in self.formatters_loader.get_available_formatters():
|
||||||
|
|
@ -899,13 +900,13 @@ class ReplApplication(Cmd, ConsoleApplication):
|
||||||
self.commands_formatters = {}
|
self.commands_formatters = {}
|
||||||
self.DEFAULT_FORMATTER = self.set_formatter(args[0])
|
self.DEFAULT_FORMATTER = self.set_formatter(args[0])
|
||||||
else:
|
else:
|
||||||
print >>sys.stderr, 'Formatter "%s" is not available.\n' \
|
print('Formatter "%s" is not available.\n' \
|
||||||
'Available formatters: %s.' % (args[0], ', '.join(self.formatters_loader.get_available_formatters()))
|
'Available formatters: %s.' % (args[0], ', '.join(self.formatters_loader.get_available_formatters())), file=sys.stderr)
|
||||||
return 1
|
return 1
|
||||||
else:
|
else:
|
||||||
print 'Default formatter: %s' % self.DEFAULT_FORMATTER
|
print('Default formatter: %s' % self.DEFAULT_FORMATTER)
|
||||||
for key, klass in self.commands_formatters.iteritems():
|
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):
|
def do_select(self, line):
|
||||||
"""
|
"""
|
||||||
|
|
@ -922,7 +923,7 @@ class ReplApplication(Cmd, ConsoleApplication):
|
||||||
split = line.split()
|
split = line.split()
|
||||||
self.selected_fields = split
|
self.selected_fields = split
|
||||||
else:
|
else:
|
||||||
print ' '.join(self.selected_fields)
|
print(' '.join(self.selected_fields))
|
||||||
|
|
||||||
def complete_inspect(self, text, line, begidx, endidx):
|
def complete_inspect(self, text, line, begidx, endidx):
|
||||||
return sorted(set(backend.name for backend in self.enabled_backends))
|
return sorted(set(backend.name for backend in self.enabled_backends))
|
||||||
|
|
@ -940,18 +941,18 @@ class ReplApplication(Cmd, ConsoleApplication):
|
||||||
else:
|
else:
|
||||||
backend_name = line.strip()
|
backend_name = line.strip()
|
||||||
if not backend_name:
|
if not backend_name:
|
||||||
print >>sys.stderr, 'Please specify a backend name.'
|
print('Please specify a backend name.', file=sys.stderr)
|
||||||
return 2
|
return 2
|
||||||
backends = set(backend for backend in self.enabled_backends if backend.name == backend_name)
|
backends = set(backend for backend in self.enabled_backends if backend.name == backend_name)
|
||||||
if not backends:
|
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
|
return 1
|
||||||
backend = backends.pop()
|
backend = backends.pop()
|
||||||
if not backend.browser:
|
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
|
return 1
|
||||||
if not backend.browser.page:
|
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
|
return 1
|
||||||
browser = backend.browser
|
browser = backend.browser
|
||||||
data = browser.parser.tostring(browser.page.document)
|
data = browser.parser.tostring(browser.page.document)
|
||||||
|
|
@ -959,7 +960,7 @@ class ReplApplication(Cmd, ConsoleApplication):
|
||||||
from webkit_mechanize_browser.browser import Browser
|
from webkit_mechanize_browser.browser import Browser
|
||||||
from weboob.tools.inspect import Page
|
from weboob.tools.inspect import Page
|
||||||
except ImportError:
|
except ImportError:
|
||||||
print data
|
print(data)
|
||||||
else:
|
else:
|
||||||
page = Page(core=browser, data=data, uri=browser._response.geturl())
|
page = Page(core=browser, data=data, uri=browser._response.geturl())
|
||||||
browser = Browser(view=page.view)
|
browser = Browser(view=page.view)
|
||||||
|
|
@ -1064,11 +1065,11 @@ class ReplApplication(Cmd, ConsoleApplication):
|
||||||
def _format_collection(self, collection, only):
|
def _format_collection(self, collection, only):
|
||||||
if only is False or collection.basename in only:
|
if only is False or collection.basename in only:
|
||||||
if collection.basename and collection.title:
|
if collection.basename and collection.title:
|
||||||
print u'%s~ (%s) %s (%s)%s' % \
|
print(u'%s~ (%s) %s (%s)%s' % \
|
||||||
(self.BOLD, collection.basename, collection.title, collection.backend, self.NC)
|
(self.BOLD, collection.basename, collection.title, collection.backend, self.NC))
|
||||||
else:
|
else:
|
||||||
print u'%s~ (%s) (%s)%s' % \
|
print(u'%s~ (%s) (%s)%s' % \
|
||||||
(self.BOLD, collection.basename, collection.backend, self.NC)
|
(self.BOLD, collection.basename, collection.backend, self.NC))
|
||||||
|
|
||||||
|
|
||||||
def _format_obj(self, obj, only):
|
def _format_obj(self, obj, only):
|
||||||
|
|
@ -1106,7 +1107,7 @@ class ReplApplication(Cmd, ConsoleApplication):
|
||||||
if len(collections) == 1:
|
if len(collections) == 1:
|
||||||
self.working_path.split_path = collections[0].split_path
|
self.working_path.split_path = collections[0].split_path
|
||||||
else:
|
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()
|
self.working_path.restore()
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
@ -1199,10 +1200,10 @@ class ReplApplication(Cmd, ConsoleApplication):
|
||||||
try:
|
try:
|
||||||
self.formatter = self.formatters_loader.build_formatter(name)
|
self.formatter = self.formatters_loader.build_formatter(name)
|
||||||
except FormatterLoadError as e:
|
except FormatterLoadError as e:
|
||||||
print >>sys.stderr, '%s' % e
|
print('%s' % e, file=sys.stderr)
|
||||||
if self.DEFAULT_FORMATTER == name:
|
if self.DEFAULT_FORMATTER == name:
|
||||||
self.DEFAULT_FORMATTER = ReplApplication.DEFAULT_FORMATTER
|
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)
|
self.formatter = self.formatters_loader.build_formatter(self.DEFAULT_FORMATTER)
|
||||||
name = self.DEFAULT_FORMATTER
|
name = self.DEFAULT_FORMATTER
|
||||||
if self.options.no_header:
|
if self.options.no_header:
|
||||||
|
|
@ -1235,9 +1236,9 @@ class ReplApplication(Cmd, ConsoleApplication):
|
||||||
try:
|
try:
|
||||||
self.formatter.format(obj=result, selected_fields=fields, alias=alias)
|
self.formatter.format(obj=result, selected_fields=fields, alias=alias)
|
||||||
except FieldNotFound as e:
|
except FieldNotFound as e:
|
||||||
print >>sys.stderr, e
|
print(e, file=sys.stderr)
|
||||||
except MandatoryFieldsNotFound as e:
|
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):
|
def flush(self):
|
||||||
self.formatter.flush()
|
self.formatter.flush()
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,12 @@
|
||||||
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
# 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 copy import copy
|
||||||
from httplib import BadStatusLine
|
from httplib import BadStatusLine
|
||||||
|
|
@ -28,7 +34,6 @@ except ImportError:
|
||||||
raise ImportError('Please install python-mechanize')
|
raise ImportError('Please install python-mechanize')
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
|
||||||
import re
|
import re
|
||||||
import tempfile
|
import tempfile
|
||||||
from threading import RLock
|
from threading import RLock
|
||||||
|
|
@ -288,7 +293,7 @@ class StandardBrowser(mechanize.Browser):
|
||||||
"""
|
"""
|
||||||
if self.responses_dirname is None:
|
if self.responses_dirname is None:
|
||||||
self.responses_dirname = tempfile.mkdtemp(prefix='weboob_session_')
|
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):
|
elif not os.path.isdir(self.responses_dirname):
|
||||||
os.makedirs(self.responses_dirname)
|
os.makedirs(self.responses_dirname)
|
||||||
# get the content-type, remove optionnal charset part
|
# get the content-type, remove optionnal charset part
|
||||||
|
|
@ -391,7 +396,7 @@ class StandardBrowser(mechanize.Browser):
|
||||||
value = [self.str(is_list.index(args[label]))]
|
value = [self.str(is_list.index(args[label]))]
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
if args[label]:
|
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
|
return
|
||||||
else:
|
else:
|
||||||
value = [self.str(args[label])]
|
value = [self.str(args[label])]
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@
|
||||||
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import sqlite3 as sqlite
|
import sqlite3 as sqlite
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
|
|
@ -40,7 +42,7 @@ class FirefoxCookieJar(CookieJar):
|
||||||
try:
|
try:
|
||||||
db = sqlite.connect(database=self.sqlite_file, timeout=10.0)
|
db = sqlite.connect(database=self.sqlite_file, timeout=10.0)
|
||||||
except sqlite.OperationalError as err:
|
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 None
|
||||||
|
|
||||||
return db
|
return db
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,13 @@
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
# 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
|
import re
|
||||||
from urlparse import urlparse, urljoin
|
try:
|
||||||
|
from urllib.parse import urlparse, urljoin
|
||||||
|
except ImportError:
|
||||||
|
from urlparse import urlparse, urljoin
|
||||||
import mimetypes
|
import mimetypes
|
||||||
import os
|
import os
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
@ -157,7 +160,7 @@ class BaseBrowser(object):
|
||||||
def _save(self, response, warning=False, **kwargs):
|
def _save(self, response, warning=False, **kwargs):
|
||||||
if self.responses_dirname is None:
|
if self.responses_dirname is None:
|
||||||
self.responses_dirname = tempfile.mkdtemp(prefix='weboob_session_')
|
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):
|
elif not os.path.isdir(self.responses_dirname):
|
||||||
os.makedirs(self.responses_dirname)
|
os.makedirs(self.responses_dirname)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,10 @@
|
||||||
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import requests.cookies
|
import requests.cookies
|
||||||
import cookielib
|
try:
|
||||||
|
import cookielib
|
||||||
|
except ImportError:
|
||||||
|
import http.cookiejar as cookielib
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['WeboobCookieJar']
|
__all__ = ['WeboobCookieJar']
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import re
|
||||||
import lxml.html as html
|
import lxml.html as html
|
||||||
|
|
||||||
from weboob.tools.misc import html2text
|
from weboob.tools.misc import html2text
|
||||||
|
from weboob.tools.compat import basestring
|
||||||
from weboob.capabilities.base import empty
|
from weboob.capabilities.base import empty
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -258,7 +259,7 @@ class CleanDecimal(CleanText):
|
||||||
if self.replace_dots:
|
if self.replace_dots:
|
||||||
text = text.replace('.','').replace(',','.')
|
text = text.replace('.','').replace(',','.')
|
||||||
try:
|
try:
|
||||||
return Decimal(re.sub(ur'[^\d\-\.]', '', text))
|
return Decimal(re.sub(r'[^\d\-\.]', '', text))
|
||||||
except InvalidOperation as e:
|
except InvalidOperation as e:
|
||||||
return self.default_or_raise(e)
|
return self.default_or_raise(e)
|
||||||
|
|
||||||
|
|
@ -388,7 +389,7 @@ class DateGuesser(Filter):
|
||||||
|
|
||||||
class Time(Filter):
|
class Time(Filter):
|
||||||
klass = datetime.time
|
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'}
|
kwargs = {'hour': 'hh', 'minute': 'mm', 'second': 'ss'}
|
||||||
|
|
||||||
def __init__(self, selector, default=_NO_DEFAULT):
|
def __init__(self, selector, default=_NO_DEFAULT):
|
||||||
|
|
@ -407,7 +408,7 @@ class Time(Filter):
|
||||||
|
|
||||||
class Duration(Time):
|
class Duration(Time):
|
||||||
klass = datetime.timedelta
|
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'}
|
kwargs = {'hours': 'hh', 'minutes': 'mm', 'seconds': 'ss'}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,18 +19,22 @@
|
||||||
|
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
from urllib import unquote
|
try:
|
||||||
|
from urllib.parse import unquote
|
||||||
|
except ImportError:
|
||||||
|
from urllib import unquote
|
||||||
import requests
|
import requests
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from cStringIO import StringIO
|
from io import BytesIO
|
||||||
import lxml.html as html
|
import lxml.html as html
|
||||||
import lxml.etree as etree
|
import lxml.etree as etree
|
||||||
|
|
||||||
from weboob.tools.json import json
|
from weboob.tools.json import json
|
||||||
from weboob.tools.ordereddict import OrderedDict
|
from weboob.tools.ordereddict import OrderedDict
|
||||||
from weboob.tools.regex_helper import normalize
|
from weboob.tools.regex_helper import normalize
|
||||||
|
from weboob.tools.compat import basestring
|
||||||
|
|
||||||
from weboob.tools.log import getLogger
|
from weboob.tools.log import getLogger
|
||||||
|
|
||||||
|
|
@ -527,7 +531,7 @@ class XMLPage(BasePage):
|
||||||
def __init__(self, browser, response, *args, **kwargs):
|
def __init__(self, browser, response, *args, **kwargs):
|
||||||
super(XMLPage, self).__init__(browser, response, *args, **kwargs)
|
super(XMLPage, self).__init__(browser, response, *args, **kwargs)
|
||||||
parser = etree.XMLParser(encoding=self.ENCODING or response.encoding)
|
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):
|
class RawPage(BasePage):
|
||||||
|
|
@ -551,7 +555,7 @@ class HTMLPage(BasePage):
|
||||||
def __init__(self, browser, response, *args, **kwargs):
|
def __init__(self, browser, response, *args, **kwargs):
|
||||||
super(HTMLPage, self).__init__(browser, response, *args, **kwargs)
|
super(HTMLPage, self).__init__(browser, response, *args, **kwargs)
|
||||||
parser = html.HTMLParser(encoding=self.ENCODING or response.encoding)
|
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):
|
def get_form(self, xpath='//form', name=None, nr=None):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
37
weboob/tools/compat.py
Normal file
37
weboob/tools/compat.py
Normal 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
|
||||||
|
|
@ -27,6 +27,7 @@ import traceback
|
||||||
import types
|
import types
|
||||||
# keep compatibility
|
# keep compatibility
|
||||||
from .date import local2utc, utc2local
|
from .date import local2utc, utc2local
|
||||||
|
from .compat import unicode
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['get_backtrace', 'get_bytes_size', 'html2text', 'iter_fields',
|
__all__ = ['get_backtrace', 'get_bytes_size', 'html2text', 'iter_fields',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue