Skip to content
weboobcfg.py 10.8 KiB
Newer Older
# -*- coding: utf-8 -*-

# Copyright(C) 2010-2012 Romain Bignon, Christophe Benz
Romain Bignon's avatar
Romain Bignon committed
# This file is part of weboob.
Romain Bignon's avatar
Romain Bignon committed
# weboob is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
Romain Bignon's avatar
Romain Bignon committed
# 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
Romain Bignon's avatar
Romain Bignon committed
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public License
Romain Bignon's avatar
Romain Bignon committed
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from __future__ import print_function
Christophe Benz's avatar
Christophe Benz committed

import os
from collections import OrderedDict
from weboob.capabilities.account import CapAccount
from weboob.exceptions import ModuleLoadError
from weboob.tools.application.repl import ReplApplication
from weboob.tools.application.console import ConsoleProgress
from weboob.tools.application.formatters.iformatter import IFormatter

__all__ = ['WeboobCfg']


class ModuleInfoFormatter(IFormatter):
    def format_dict(self, minfo):
        result = '.------------------------------------------------------------------------------.\n'
        result += '| Module %-69s |\n' % minfo['name']
        result += "+-----------------.------------------------------------------------------------'\n"
        result += '| Version         | %s\n' % minfo['version']
        result += '| Maintainer      | %s\n' % minfo['maintainer']
        result += '| License         | %s\n' % minfo['license']
        result += '| Description     | %s\n' % minfo['description']
        result += '| Capabilities    | %s\n' % ', '.join(minfo['capabilities'])
        result += '| Installed       | %s\n' % minfo['installed']
        result += '| Location        | %s\n' % minfo['location']
        if 'config' in minfo:
            first = True
            for key, field in minfo['config'].items():
                label = field['label']
                if field['default'] is not None:
                    label += ' (default: %s)' % field['default']

                    result += '| Configuration   | %s: %s\n' % (key, label)
                    result += '|                 | %s: %s\n' % (key, label)
        result += "'-----------------'\n"
        return result


class WeboobCfg(ReplApplication):
    APPNAME = 'weboob-config'
Romain Bignon's avatar
Romain Bignon committed
    VERSION = '1.5'
Florent's avatar
Florent committed
    COPYRIGHT = 'Copyright(C) 2010-YEAR Christophe Benz, Romain Bignon'
    DESCRIPTION = "Weboob-Config is a console application to add/edit/remove backends, " \
                  "and to register new website accounts."
    SHORT_DESCRIPTION = "manage backends or register new accounts"
    EXTRA_FORMATTERS = {'info_formatter': ModuleInfoFormatter}
    COMMANDS_FORMATTERS = {'modules':     'table',
                           'list':        'table',
    def load_default_backends(self):
        pass

    def do_add(self, line):
        """
        add MODULE_NAME [BACKEND_NAME] [PARAMETERS ...]
        Create a backend from a module. By default, if BACKEND_NAME is omitted,
        that's the module name which is used.

        You can specify parameters from command line in form "key=value".
            print('You must specify a module name. Hint: use the "modules" command.', file=self.stderr)
        module_name, options = self.parse_command_args(line, 2, 1)
        if options:
            options = options.split(' ')
        else:
            options = ()

        backend_name = None
        params = {}
        # set backend params from command-line arguments
        for option in options:
            try:
                key, value = option.split('=', 1)
            except ValueError:
                if backend_name is None:
                    backend_name = option
                else:
                    print('Parameters have to be formatted "key=value"', file=self.stderr)
                    return 2
            else:
                params[key] = value
        self.add_backend(module_name, backend_name or module_name, params)
    def do_register(self, line):
        """
        Register a new account on a module.
        """
        self.register_backend(line)

    def do_confirm(self, backend_name):
        """
        confirm BACKEND

        For a backend which support CapAccount, parse a confirmation mail
        after using the 'register' command to automatically confirm the
        subscribe.

Christophe Benz's avatar
Christophe Benz committed
        It takes mail from stdin. Use it with postfix for example.
        """
        # Do not use the ReplApplication.load_backends() method because we
        # don't want to prompt user to create backend.
        self.weboob.load_backends(names=[backend_name])
        try:
            backend = self.weboob.get_backend(backend_name)
        except KeyError:
            print('Error: backend "%s" not found.' % backend_name, file=self.stderr)
        if not backend.has_caps(CapAccount):
            print('Error: backend "%s" does not support accounts management' % backend_name, file=self.stderr)
        if not backend.confirm_account(mail):
            print('Error: Unable to confirm account creation', file=self.stderr)
    def do_list(self, line):
        for backend_name, module_name, params in sorted(self.weboob.backends_config.iter_backends()):
                module = self.weboob.modules_loader.get_or_load_module(module_name)
            except ModuleLoadError as e:
                self.logger.warning('Unable to load module %r: %s' % (module_name, e))
            if caps and not module.has_caps(*caps):
            row = OrderedDict([('Name', backend_name),
                               ('Module', module_name),
Christophe Benz's avatar
Christophe Benz committed
                               ('Configuration', ', '.join(
                                   '%s=%s' % (key, ('*****' if key in module.config and module.config[key].masked
                                                    else value))
                                   for key, value in params.items())),
    def do_enable(self, backend_name):
        """
        enable NAME

        Enable a backend.
        """
        try:
            self.weboob.backends_config.edit_backend(backend_name, {'_enabled': '1'})
        except KeyError:
            print('Backend instance "%s" does not exist' % backend_name, file=self.stderr)
            return 1

    def do_disable(self, backend_name):
        """
        disable NAME

        Disable a backend.
        """
        try:
            self.weboob.backends_config.edit_backend(backend_name, {'_enabled': '0'})
        except KeyError:
            print('Backend instance "%s" does not exist' % backend_name, file=self.stderr)
            return 1

    def do_remove(self, backend_name):
        if not self.weboob.backends_config.remove_backend(backend_name):
            print('Backend instance "%s" does not exist' % backend_name, file=self.stderr)
    def do_edit(self, line):
Romain Bignon's avatar
Romain Bignon committed
        except KeyError:
            print('Error: backend "%s" not found' % line, file=self.stderr)
Christophe Benz's avatar
Christophe Benz committed

    def do_modules(self, line):
        Show available modules.
        caps = line.split()
        for name, info in sorted(self.weboob.repositories.get_all_modules_info(caps).items()):
Christophe Benz's avatar
Christophe Benz committed
            row = OrderedDict([('Name', name),
                               ('Capabilities', info.capabilities),
                               ('Description', info.description),
                               ('Installed', info.is_installed()),
Christophe Benz's avatar
Christophe Benz committed
                               ])
            self.format(row)

    def do_info(self, line):
        Display information about a module.
            print('You must specify a module name. Hint: use the "modules" command.', file=self.stderr)
        minfo = self.weboob.repositories.get_module_info(line)
        if not minfo:
            print('Module "%s" does not exist.' % line, file=self.stderr)
            module = self.weboob.modules_loader.get_or_load_module(line)
        except ModuleLoadError:
Christophe Benz's avatar
Christophe Benz committed

        self.start_format()
        self.format(self.create_minfo_dict(minfo, module))


    def create_minfo_dict(self, minfo, module):
        module_info = {}
        module_info['name'] = minfo.name
        module_info['version'] = minfo.version
        module_info['maintainer'] = minfo.maintainer
        module_info['license'] = minfo.license
        module_info['description'] = minfo.description
        module_info['capabilities'] = minfo.capabilities
        module_info['installed'] = '%s%s' % (('yes' if module else 'no'), ' (new version available)' if self.weboob.repositories.versions.get(minfo.name) > minfo.version else '')
        module_info['location'] = '%s' % (minfo.url or os.path.join(minfo.path, minfo.name))
            for key, field in module.config.items():
                module_info['config'][key] = {'label': field.label,
                                              'default': field.default,
                                              'description': field.description,
                                              'regexp': field.regexp,
                                              'choices': field.choices,
                                              'masked': field.masked,
                                              'required': field.required}
Christophe Benz's avatar
Christophe Benz committed

    def do_update(self, line):
        """
        update

        Update weboob.
        """
        self.weboob.update(ConsoleProgress(self))
        if self.weboob.repositories.errors:
            print('Errors building modules: %s' % ', '.join(self.weboob.repositories.errors.keys()), file=self.stderr)
            if not self.options.debug:
                print('Use --debug to get more information.', file=self.stderr)
            return 1