From cb1372b99f465a6af17d86cf1822551e32e69a87 Mon Sep 17 00:00:00 2001 From: Romain Bignon Date: Sat, 21 May 2011 10:26:57 +0200 Subject: [PATCH] new class BackendConfig to manage backend configs --- weboob/backends/arte/backend.py | 12 ++-- weboob/backends/aum/backend.py | 32 ++++----- weboob/backends/bnporc/backend.py | 30 ++++---- weboob/backends/bouygues/backend.py | 10 +-- weboob/backends/bp/backend.py | 12 ++-- weboob/backends/canalplus/backend.py | 8 +-- weboob/backends/cragr/backend.py | 14 ++-- weboob/backends/creditmutuel/backend.py | 10 +-- weboob/backends/dlfp/backend.py | 24 +++---- weboob/backends/ehentai/backend.py | 18 ++--- weboob/backends/fourchan/backend.py | 8 +-- weboob/backends/gazelle/backend.py | 16 ++--- weboob/backends/lcl/backend.py | 14 ++-- weboob/backends/mediawiki/backend.py | 21 ++++-- weboob/backends/newsfeed/backend.py | 10 +-- weboob/backends/orange/backend.py | 16 ++--- weboob/backends/pastebin/backend.py | 23 ++++--- weboob/backends/piratebay/backend.py | 4 -- weboob/backends/redmine/backend.py | 14 ++-- weboob/backends/sfr/backend.py | 10 +-- weboob/backends/societegenerale/backend.py | 12 ++-- weboob/core/backendscfg.py | 8 +++ weboob/tools/backend.py | 79 +++++++++++++++++----- 23 files changed, 234 insertions(+), 171 deletions(-) diff --git a/weboob/backends/arte/backend.py b/weboob/backends/arte/backend.py index ff1df0d64c..3f852ea20d 100644 --- a/weboob/backends/arte/backend.py +++ b/weboob/backends/arte/backend.py @@ -21,8 +21,8 @@ from __future__ import with_statement from weboob.capabilities.video import ICapVideo -from weboob.tools.backend import BaseBackend -from weboob.tools.value import ValuesDict, Value +from weboob.tools.backend import BaseBackend, BackendConfig +from weboob.tools.value import Value from .browser import ArteBrowser from .video import ArteVideo @@ -38,13 +38,13 @@ class ArteBackend(BaseBackend, ICapVideo): VERSION = '0.9' DESCRIPTION = 'Arte french TV' LICENSE = 'AGPLv3+' - CONFIG = ValuesDict(Value('lang', label='Lang of videos', - choices={'fr': 'French', 'de': 'Deutsch', 'en': 'English'}, default='fr'), - Value('quality', label='Quality of videos', choices=['hd', 'sd'], default='hd')) + CONFIG = BackendConfig(Value('lang', label='Lang of videos', + choices={'fr': 'French', 'de': 'Deutsch', 'en': 'English'}, default='fr'), + Value('quality', label='Quality of videos', choices=['hd', 'sd'], default='hd')) BROWSER = ArteBrowser def create_default_browser(self): - return self.create_browser(lang=self.config['lang'], quality=self.config['quality']) + return self.create_browser(lang=self.config['lang'].get(), quality=self.config['quality'].get()) def get_video(self, _id): with self.browser: diff --git a/weboob/backends/aum/backend.py b/weboob/backends/aum/backend.py index 50b1b3b76c..6c726f22d5 100644 --- a/weboob/backends/aum/backend.py +++ b/weboob/backends/aum/backend.py @@ -30,9 +30,9 @@ from weboob.capabilities.dating import ICapDating, OptimizationNotFound from weboob.capabilities.contact import ICapContact, Contact, ContactPhoto, ProfileNode, Query, QueryError from weboob.capabilities.account import ICapAccount, StatusField -from weboob.tools.backend import BaseBackend +from weboob.tools.backend import BaseBackend, BackendConfig from weboob.tools.browser import BrowserUnavailable -from weboob.tools.value import Value, ValuesDict, ValueBool +from weboob.tools.value import Value, ValuesDict, ValueBool, ValueBackendPassword from weboob.tools.log import getLogger from .captcha import CaptchaError @@ -55,10 +55,10 @@ class AuMBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapDating, ICapCh VERSION = '0.9' LICENSE = 'AGPLv3+' DESCRIPTION = u"“Adopte un mec” french dating website" - CONFIG = ValuesDict(Value('username', label='Username'), - Value('password', label='Password', masked=True), - ValueBool('antispam', label='Enable anti-spam', default=False), - ValueBool('baskets', label='Get baskets with new messages', default=True)) + CONFIG = BackendConfig(Value('username', label='Username'), + ValueBackendPassword('password', label='Password'), + ValueBool('antispam', label='Enable anti-spam', default=False), + ValueBool('baskets', label='Get baskets with new messages', default=True)) STORAGE = {'profiles_walker': {'viewed': []}, 'priority_connection': {'config': {}, 'fakes': {}}, 'queries_queue': {'queue': []}, @@ -70,13 +70,13 @@ class AuMBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapDating, ICapCh def __init__(self, *args, **kwargs): BaseBackend.__init__(self, *args, **kwargs) - if self.config['antispam']: + if self.config['antispam'].get(): self.antispam = AntiSpam() else: self.antispam = None def create_default_browser(self): - return self.create_browser(self.config['username'], self.config['password']) + return self.create_browser(self.config['username'].get(), self.config['password'].get()) def report_spam(self, id, suppr_id=None): if suppr_id: @@ -215,7 +215,7 @@ def iter_unread_messages(self, thread=None): if m.flags & m.IS_UNREAD: yield m - if not self.config['baskets']: + if not self.config['baskets'].get(): return # Send mail when someone added me in her basket. @@ -437,18 +437,18 @@ def register_account(klass, account): @param account an Account object which describe the account to create """ browser = None - bday, bmonth, byear = account.properties['birthday'].value.split('/', 2) + bday, bmonth, byear = account.properties['birthday'].get().split('/', 2) while not browser: try: - browser = klass.BROWSER(account.properties['username'].value) - browser.register(password= account.properties['password'].value, - sex= (0 if account.properties['sex'].value == 'm' else 1), + browser = klass.BROWSER(account.properties['username'].get()) + browser.register(password= account.properties['password'].get(), + sex= (0 if account.properties['sex'].get() == 'm' else 1), birthday_d= int(bday), birthday_m= int(bmonth), birthday_y= int(byear), - zipcode= account.properties['zipcode'].value, - country= account.properties['country'].value, - godfather= account.properties['godfather'].value) + zipcode= account.properties['zipcode'].get(), + country= account.properties['country'].get(), + godfather= account.properties['godfather'].get()) except CaptchaError: getLogger('aum').info('Unable to resolve captcha. Retrying...') browser = None diff --git a/weboob/backends/bnporc/backend.py b/weboob/backends/bnporc/backend.py index 3589d01b1e..6da89e06e6 100644 --- a/weboob/backends/bnporc/backend.py +++ b/weboob/backends/bnporc/backend.py @@ -22,8 +22,8 @@ from __future__ import with_statement from weboob.capabilities.bank import ICapBank, AccountNotFound, Account, Recipient -from weboob.tools.backend import BaseBackend -from weboob.tools.value import ValuesDict, Value +from weboob.tools.backend import BaseBackend, BackendConfig +from weboob.tools.value import Value, ValueBackendPassword from .browser import BNPorc @@ -38,29 +38,27 @@ class BNPorcBackend(BaseBackend, ICapBank): VERSION = '0.9' LICENSE = 'AGPLv3+' DESCRIPTION = 'BNP Paribas french bank\' website' - CONFIG = ValuesDict(Value('login', label='Account ID'), - Value('password', label='Password', masked=True), - Value('rotating_password', - label='Password to set when the allowed uses are exhausted (6 digits)', - default='', masked=True, - regexp='^(\d{6}|)$')) + CONFIG = BackendConfig(Value('login', label='Account ID'), + ValueBackendPassword('password', label='Password', regexp='^(\d{6}|)$'), + ValueBackendPassword('rotating_password', + label='Password to set when the allowed uses are exhausted (6 digits)', + regexp='^(\d{6}|)$')) BROWSER = BNPorc def create_default_browser(self): - if self.config['rotating_password'].isdigit() and len(self.config['rotating_password']) == 6: - rotating_password = self.config['rotating_password'] + if self.config['rotating_password'].get().isdigit() and len(self.config['rotating_password'].get()) == 6: + rotating_password = self.config['rotating_password'].get() else: rotating_password = None - return self.create_browser(self.config['login'], - self.config['password'], + return self.create_browser(self.config['login'].get(), + self.config['password'].get(), password_changed_cb=self._password_changed_cb, rotating_password=rotating_password) def _password_changed_cb(self, old, new): - new_settings = {'password': new, - 'rotating_password': old, - } - self.weboob.backends_config.edit_backend(self.name, self.NAME, new_settings) + self.config['password'].set(new) + self.config['rotating_password'].set(old) + self.config.save() def iter_accounts(self): for account in self.browser.get_accounts_list(): diff --git a/weboob/backends/bouygues/backend.py b/weboob/backends/bouygues/backend.py index 1d6aade346..07e8ce3eba 100644 --- a/weboob/backends/bouygues/backend.py +++ b/weboob/backends/bouygues/backend.py @@ -21,8 +21,8 @@ from __future__ import with_statement from weboob.capabilities.messages import CantSendMessage, ICapMessages, ICapMessagesPost -from weboob.tools.backend import BaseBackend -from weboob.tools.value import ValuesDict, Value +from weboob.tools.backend import BaseBackend, BackendConfig +from weboob.tools.value import ValueBackendPassword, Value from .browser import BouyguesBrowser @@ -37,13 +37,13 @@ class BouyguesBackend(BaseBackend, ICapMessages, ICapMessagesPost): VERSION = '0.9' DESCRIPTION = 'Bouygues french mobile phone provider' LICENSE = 'AGPLv3+' - CONFIG = ValuesDict(Value('login', label='Login'), - Value('password', label='Password', masked=True)) + CONFIG = BackendConfig(Value('login', label='Login'), + ValueBackendPassword('password', label='Password')) BROWSER = BouyguesBrowser ACCOUNT_REGISTER_PROPERTIES = None def create_default_browser(self): - return self.create_browser(self.config['login'], self.config['password']) + return self.create_browser(self.config['login'].get(), self.config['password'].get()) def post_message(self, message): if not message.content.strip(): diff --git a/weboob/backends/bp/backend.py b/weboob/backends/bp/backend.py index daa2269bb0..e9dce7470a 100644 --- a/weboob/backends/bp/backend.py +++ b/weboob/backends/bp/backend.py @@ -19,8 +19,8 @@ from weboob.capabilities.bank import ICapBank, AccountNotFound -from weboob.tools.backend import BaseBackend -from weboob.tools.value import ValuesDict, Value +from weboob.tools.backend import BaseBackend, BackendConfig +from weboob.tools.value import ValueBackendPassword, Value from .browser import BPBrowser @@ -35,12 +35,12 @@ class BPBackend(BaseBackend, ICapBank): VERSION = '0.9' LICENSE = 'AGPLv3+' DESCRIPTION = u'La banque postale, French bank' - CONFIG = ValuesDict(Value('login', label='Account ID'), - Value('password', label='Password', masked=True)) + CONFIG = BackendConfig(Value('login', label='Account ID'), + ValueBackendPassword('password', label='Password')) BROWSER = BPBrowser def create_default_browser(self): - return self.create_browser(self.config['login'], self.config['password']) + return self.create_browser(self.config['login'].get(), self.config['password'].get()) def iter_accounts(self): for account in self.browser.get_accounts_list(): @@ -56,7 +56,7 @@ def get_account(self, _id): def iter_history(self, account): for history in self.browser.get_history(account): yield history - + def transfer(self, id_from, id_to, amount, reason=None): from_account = self.get_account(id_from) to_account = self.get_account(id_to) diff --git a/weboob/backends/canalplus/backend.py b/weboob/backends/canalplus/backend.py index c92c8ec58c..a3896aefa7 100644 --- a/weboob/backends/canalplus/backend.py +++ b/weboob/backends/canalplus/backend.py @@ -21,8 +21,8 @@ from __future__ import with_statement from weboob.capabilities.video import ICapVideo -from weboob.tools.backend import BaseBackend -from weboob.tools.value import ValuesDict, Value +from weboob.tools.backend import BaseBackend, BackendConfig +from weboob.tools.value import Value from .browser import CanalplusBrowser from .pages import CanalplusVideo @@ -40,11 +40,11 @@ class CanalplusBackend(BaseBackend, ICapVideo, ICapCollection): VERSION = '0.9' DESCRIPTION = 'Canal plus french TV' LICENSE = 'GPLv3' - CONFIG = ValuesDict(Value('quality', label='Quality of videos', choices=['hd', 'sd'], default='hd')) + CONFIG = BackendConfig(Value('quality', label='Quality of videos', choices=['hd', 'sd'], default='hd')) BROWSER = CanalplusBrowser def create_default_browser(self): - return self.create_browser(quality=self.config['quality']) + return self.create_browser(quality=self.config['quality'].get()) def iter_search_results(self, pattern=None, sortby=ICapVideo.SEARCH_RELEVANCE, nsfw=False, max_results=None): with self.browser: diff --git a/weboob/backends/cragr/backend.py b/weboob/backends/cragr/backend.py index 5c429aad46..86919a0fac 100644 --- a/weboob/backends/cragr/backend.py +++ b/weboob/backends/cragr/backend.py @@ -19,9 +19,9 @@ from weboob.capabilities.bank import ICapBank, AccountNotFound -from weboob.tools.backend import BaseBackend +from weboob.tools.backend import BaseBackend, BackendConfig from weboob.tools.ordereddict import OrderedDict -from weboob.tools.value import ValuesDict, Value +from weboob.tools.value import ValueBackendPassword, Value from .browser import Cragr @@ -72,13 +72,15 @@ class CragrBackend(BaseBackend, ICapBank): 'm.ca-toulouse31.fr': u'Toulouse 31', # m.ca-toulousain.fr redirects here 'm.ca-tourainepoitou.fr': u'Tourraine Poitou', }.iteritems())]) - CONFIG = ValuesDict(Value('website', label='Website to use', choices=website_choices), - Value('login', label='Account ID'), - Value('password', label='Password', masked=True)) + CONFIG = BackendConfig(Value('website', label='Website to use', choices=website_choices), + Value('login', label='Account ID'), + ValueBackendPassword('password', label='Password')) BROWSER = Cragr def create_default_browser(self): - return self.create_browser(self.config['website'], self.config['login'], self.config['password']) + return self.create_browser(self.config['website'].get(), + self.config['login'].get(), + self.config['password'].get()) def iter_accounts(self): for account in self.browser.get_accounts_list(): diff --git a/weboob/backends/creditmutuel/backend.py b/weboob/backends/creditmutuel/backend.py index c58fb43f2f..676a0c639e 100644 --- a/weboob/backends/creditmutuel/backend.py +++ b/weboob/backends/creditmutuel/backend.py @@ -19,8 +19,8 @@ from weboob.capabilities.bank import ICapBank, AccountNotFound -from weboob.tools.backend import BaseBackend -from weboob.tools.value import ValuesDict, Value +from weboob.tools.backend import BaseBackend, BackendConfig +from weboob.tools.value import ValueBackendPassword, Value from .browser import CreditMutuelBrowser @@ -35,12 +35,12 @@ class CreditMutuelBackend(BaseBackend, ICapBank): VERSION = '0.9' DESCRIPTION = u'Crédit Mutuel french bank' LICENSE = 'AGPLv3+' - CONFIG = ValuesDict(Value('login', label='Account ID', regexp='^\d{1,13}\w$'), - Value('password', label='Password of account', masked=True)) + CONFIG = BackendConfig(Value('login', label='Account ID', regexp='^\d{1,13}\w$'), + ValueBackendPassword('password', label='Password of account')) BROWSER = CreditMutuelBrowser def create_default_browser(self): - return self.create_browser( self.config['login'], self.config['password']) + return self.create_browser(self.config['login'].get(), self.config['password'].get()) def iter_accounts(self): for account in self.browser.get_accounts_list(): diff --git a/weboob/backends/dlfp/backend.py b/weboob/backends/dlfp/backend.py index bf015b6e2c..8c96e43b06 100644 --- a/weboob/backends/dlfp/backend.py +++ b/weboob/backends/dlfp/backend.py @@ -20,9 +20,9 @@ from __future__ import with_statement -from weboob.tools.backend import BaseBackend +from weboob.tools.backend import BaseBackend, BackendConfig from weboob.tools.newsfeed import Newsfeed -from weboob.tools.value import Value, ValueBool, ValuesDict +from weboob.tools.value import Value, ValueBool, ValueBackendPassword from weboob.tools.misc import limit from weboob.capabilities.messages import ICapMessages, ICapMessagesPost, Message, Thread, CantSendMessage from weboob.capabilities.content import ICapContent, Content @@ -41,14 +41,14 @@ class DLFPBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapContent): VERSION = '0.9' LICENSE = 'AGPLv3+' DESCRIPTION = "Da Linux French Page" - CONFIG = ValuesDict(Value('username', label='Username', regexp='.+'), - Value('password', label='Password', regexp='.+', masked=True), - ValueBool('get_news', label='Get newspapers', default=True), - ValueBool('get_diaries', label='Get diaries', default=False), - ValueBool('get_polls', label='Get polls', default=False), - ValueBool('get_board', label='Get board', default=False), - ValueBool('get_wiki', label='Get wiki', default=False), - ValueBool('get_tracker', label='Get tracker', default=False)) + CONFIG = BackendConfig(Value('username', label='Username', regexp='.+'), + ValueBackendPassword('password', label='Password'), + ValueBool('get_news', label='Get newspapers', default=True), + ValueBool('get_diaries', label='Get diaries', default=False), + ValueBool('get_polls', label='Get polls', default=False), + ValueBool('get_board', label='Get board', default=False), + ValueBool('get_wiki', label='Get wiki', default=False), + ValueBool('get_tracker', label='Get tracker', default=False)) STORAGE = {'seen': {}} BROWSER = DLFP @@ -61,7 +61,7 @@ class DLFPBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapContent): } def create_default_browser(self): - return self.create_browser(self.config['username'], self.config['password']) + return self.create_browser(self.config['username'].get(), self.config['password'].get()) def deinit(self): # don't need to logout if the browser hasn't been used. @@ -76,7 +76,7 @@ def deinit(self): def iter_threads(self): whats = set() for param, url in self.FEEDS.iteritems(): - if self.config[param]: + if self.config[param].get(): whats.add(url) for what in whats: diff --git a/weboob/backends/ehentai/backend.py b/weboob/backends/ehentai/backend.py index 65f36b3cea..a1a1270a88 100644 --- a/weboob/backends/ehentai/backend.py +++ b/weboob/backends/ehentai/backend.py @@ -21,9 +21,9 @@ import re from weboob.capabilities.gallery import ICapGallery -from weboob.tools.backend import BaseBackend +from weboob.tools.backend import BaseBackend, BackendConfig from weboob.tools.misc import ratelimit -from weboob.tools.value import Value, ValuesDict +from weboob.tools.value import Value, ValueBackendPassword from .browser import EHentaiBrowser from .gallery import EHentaiGallery, EHentaiImage @@ -40,16 +40,18 @@ class EHentaiBackend(BaseBackend, ICapGallery): DESCRIPTION = 'E-hentai galleries' LICENSE = 'AGPLv3+' BROWSER = EHentaiBrowser - CONFIG = ValuesDict( + CONFIG = BackendConfig( Value('domain', label='Domain', default='g.e-hentai.org'), Value('username', label='Username', default=''), - Value('password', label='Password', default='', masked=True)) + ValueBackendPassword('password', label='Password')) def create_default_browser(self): - return self.create_browser( - self.config['domain'], - self.config['username'], - self.config['password']) + username = self.config['username'].get() + if username: + password = self.config['password'].get() + else: + password = None + return self.create_browser(self.config['domain'].get(), username, password) def iter_search_results(self, pattern=None, sortby=None, max_results=None): with self.browser: diff --git a/weboob/backends/fourchan/backend.py b/weboob/backends/fourchan/backend.py index f29bc31525..6040fc263b 100644 --- a/weboob/backends/fourchan/backend.py +++ b/weboob/backends/fourchan/backend.py @@ -21,8 +21,8 @@ from __future__ import with_statement from weboob.capabilities.messages import ICapMessages, Message, Thread -from weboob.tools.backend import BaseBackend -from weboob.tools.value import Value, ValuesDict +from weboob.tools.backend import BaseBackend, BackendConfig +from weboob.tools.value import Value from .browser import FourChan @@ -37,7 +37,7 @@ class FourChanBackend(BaseBackend, ICapMessages): VERSION = '0.9' LICENSE = 'AGPLv3+' DESCRIPTION = '4chan website' - CONFIG = ValuesDict(Value('boards', label='Boards to fetch')) + CONFIG = BackendConfig(Value('boards', label='Boards to fetch')) STORAGE = {'boards': {}} BROWSER = FourChan @@ -100,7 +100,7 @@ def get_thread(self, id): return thread def iter_threads(self): - for board in self.config['boards'].split(' '): + for board in self.config['boards'].get().split(' '): with self.browser: threads = self.browser.get_threads(board) for thread in threads: diff --git a/weboob/backends/gazelle/backend.py b/weboob/backends/gazelle/backend.py index 5cf2723611..5fecf25ab9 100644 --- a/weboob/backends/gazelle/backend.py +++ b/weboob/backends/gazelle/backend.py @@ -18,8 +18,8 @@ # along with weboob. If not, see . from weboob.capabilities.torrent import ICapTorrent -from weboob.tools.backend import BaseBackend -from weboob.tools.value import ValuesDict, Value +from weboob.tools.backend import BaseBackend, BackendConfig +from weboob.tools.value import ValueBackendPassword, Value from .browser import GazelleBrowser @@ -34,15 +34,15 @@ class GazelleBackend(BaseBackend, ICapTorrent): VERSION = '0.9' DESCRIPTION = 'gazelle bittorrent tracker' LICENSE = 'AGPLv3+' - CONFIG = ValuesDict(Value('domain', label='Domain (example "ssl.what.cd")'), - Value('protocol', label='Protocol to use', choices=('http', 'https')), - Value('username', label='Username'), - Value('password', label='Password', masked=True)) + CONFIG = BackendConfig(Value('domain', label='Domain (example "ssl.what.cd")'), + Value('protocol', label='Protocol to use', choices=('http', 'https')), + Value('username', label='Username'), + ValueBackendPassword('password', label='Password')) BROWSER = GazelleBrowser def create_default_browser(self): - return self.create_browser(self.config['protocol'], self.config['domain'], - self.config['username'], self.config['password']) + return self.create_browser(self.config['protocol'].get(), self.config['domain'].get(), + self.config['username'].get(), self.config['password'].get()) def get_torrent(self, id): return self.browser.get_torrent(id) diff --git a/weboob/backends/lcl/backend.py b/weboob/backends/lcl/backend.py index 938da9b916..2fd8c74454 100644 --- a/weboob/backends/lcl/backend.py +++ b/weboob/backends/lcl/backend.py @@ -21,8 +21,8 @@ from __future__ import with_statement from weboob.capabilities.bank import ICapBank, AccountNotFound -from weboob.tools.backend import BaseBackend -from weboob.tools.value import ValuesDict, Value +from weboob.tools.backend import BaseBackend, BackendConfig +from weboob.tools.value import ValueBackendPassword, Value from .browser import LCLBrowser @@ -37,13 +37,15 @@ class LCLBackend(BaseBackend, ICapBank): VERSION = '0.9' DESCRIPTION = 'Le Credit Lyonnais crappy french bank' LICENSE = 'AGPLv3+' - CONFIG = ValuesDict(Value('login', label='Account ID', regexp='^\d{1,6}\w$'), - Value('password', label='Password of account', masked=True), - Value('agency', label='Agency code', regexp='^\d{3,4}$')) + CONFIG = BackendConfig(Value('login', label='Account ID', regexp='^\d{1,6}\w$'), + ValueBackendPassword('password', label='Password of account'), + Value('agency', label='Agency code', regexp='^\d{3,4}$')) BROWSER = LCLBrowser def create_default_browser(self): - return self.create_browser(self.config['agency'], self.config['login'], self.config['password']) + return self.create_browser(self.config['agency'].get(), + self.config['login'].get(), + self.config['password'].get()) def iter_accounts(self): for account in self.browser.get_accounts_list(): diff --git a/weboob/backends/mediawiki/backend.py b/weboob/backends/mediawiki/backend.py index 093f81b407..28814fb1cd 100644 --- a/weboob/backends/mediawiki/backend.py +++ b/weboob/backends/mediawiki/backend.py @@ -19,9 +19,9 @@ from __future__ import with_statement -from weboob.tools.backend import BaseBackend +from weboob.tools.backend import BaseBackend, BackendConfig from weboob.capabilities.content import ICapContent, Content -from weboob.tools.value import ValuesDict, Value +from weboob.tools.value import ValueBackendPassword, Value from .browser import MediawikiBrowser @@ -36,14 +36,21 @@ class MediawikiBackend(BaseBackend, ICapContent): VERSION = '0.9' LICENSE = 'AGPLv3+' DESCRIPTION = 'Mediawiki wiki software application' - CONFIG = ValuesDict(Value('url', label='URL of the Mediawiki website', default='http://en.wikipedia.org/'), - Value('apiurl', label='URL of the Mediawiki website\'s API', default='http://en.wikipedia.org/w/api.php'), - Value('username', label='Login', default=''), - Value('password', label='Password', default='', masked=True)) + CONFIG = BackendConfig(Value('url', label='URL of the Mediawiki website', default='http://en.wikipedia.org/'), + Value('apiurl', label='URL of the Mediawiki website\'s API', default='http://en.wikipedia.org/w/api.php'), + Value('username', label='Login', default=''), + ValueBackendPassword('password', label='Password', default='')) BROWSER = MediawikiBrowser def create_default_browser(self): - return self.create_browser(self.config['url'], self.config['apiurl'], self.config['username'], self.config['password']) + username = self.config['username'].get() + if len(username) > 0: + password = self.config['password'].get() + else: + password = None + return self.create_browser(self.config['url'].get(), + self.config['apiurl'].get(), + username, password) def get_content(self, _id): _id = _id.replace(' ', '_').encode('utf-8') diff --git a/weboob/backends/newsfeed/backend.py b/weboob/backends/newsfeed/backend.py index 741b4e6661..e7dce61e3d 100644 --- a/weboob/backends/newsfeed/backend.py +++ b/weboob/backends/newsfeed/backend.py @@ -18,10 +18,10 @@ # along with weboob. If not, see . -from weboob.tools.backend import BaseBackend +from weboob.tools.backend import BaseBackend, BackendConfig from weboob.capabilities.messages import ICapMessages, Message, Thread from weboob.tools.newsfeed import Newsfeed -from weboob.tools.value import Value, ValuesDict +from weboob.tools.value import Value __all__ = ['NewsfeedBackend'] @@ -34,12 +34,12 @@ class NewsfeedBackend(BaseBackend, ICapMessages): VERSION = '0.9' DESCRIPTION = "Loads RSS and Atom feeds from any website" LICENSE = "AGPLv3+" - CONFIG = ValuesDict(Value('url', label="Atom/RSS feed's url")) + CONFIG = BackendConfig(Value('url', label="Atom/RSS feed's url")) STORAGE = {'seen': []} def iter_threads(self): - for article in Newsfeed(self.config["url"]).iter_entries(): + for article in Newsfeed(self.config['url'].get()).iter_entries(): yield self.get_thread(article.id, article) def get_thread(self, id, entry=None): @@ -50,7 +50,7 @@ def get_thread(self, id, entry=None): thread = Thread(id) if entry is None: - entry = Newsfeed(self.config["url"]).get_entry(id) + entry = Newsfeed(self.config['url'].get()).get_entry(id) if entry is None: return None diff --git a/weboob/backends/orange/backend.py b/weboob/backends/orange/backend.py index 2753b1f3fb..3609dde4a8 100644 --- a/weboob/backends/orange/backend.py +++ b/weboob/backends/orange/backend.py @@ -22,8 +22,8 @@ from weboob.capabilities.messages import CantSendMessage, ICapMessages, ICapMessagesPost from weboob.capabilities.account import ICapAccount, StatusField -from weboob.tools.backend import BaseBackend -from weboob.tools.value import ValuesDict, Value +from weboob.tools.backend import BaseBackend, BackendConfig +from weboob.tools.value import ValueBackendPassword, Value from .browser import OrangeBrowser @@ -38,15 +38,15 @@ class OrangeBackend(BaseBackend, ICapAccount, ICapMessages, ICapMessagesPost): VERSION = '0.9' DESCRIPTION = 'Orange french mobile phone provider' LICENSE = 'AGPLv3+' - CONFIG = ValuesDict(Value('login', label='Login'), - Value('password', label='Password', masked=True), - Value('phonenumber', Label='Phone number') - ) + CONFIG = BackendConfig(Value('login', label='Login'), + ValueBackendPassword('password', label='Password'), + Value('phonenumber', Label='Phone number') + ) BROWSER = OrangeBrowser ACCOUNT_REGISTER_PROPERTIES = None def create_default_browser(self): - return self.create_browser(self.config['login'], self.config['password']) + return self.create_browser(self.config['login'].get(), self.config['password'].get()) def get_account_status(self): with self.browser: @@ -57,4 +57,4 @@ def post_message(self, message): if not message.content.strip(): raise CantSendMessage(u'Message content is empty.') with self.browser: - self.browser.post_message(message, self.config['phonenumber']) + self.browser.post_message(message, self.config['phonenumber'].get()) diff --git a/weboob/backends/pastebin/backend.py b/weboob/backends/pastebin/backend.py index bfb61e72fd..5036bba5eb 100644 --- a/weboob/backends/pastebin/backend.py +++ b/weboob/backends/pastebin/backend.py @@ -21,9 +21,9 @@ from __future__ import with_statement from weboob.tools.capabilities.paste import BasePasteBackend -from weboob.tools.backend import BaseBackend +from weboob.tools.backend import BaseBackend, BackendConfig from weboob.capabilities.base import NotLoaded -from weboob.tools.value import Value, ValuesDict +from weboob.tools.value import Value, ValueBackendPassword from .browser import PastebinBrowser from .paste import PastebinPaste @@ -40,10 +40,10 @@ class PastebinBackend(BaseBackend, BasePasteBackend): DESCRIPTION = 'Pastebin paste tool' LICENSE = 'AGPLv3+' BROWSER = PastebinBrowser - CONFIG = ValuesDict( + CONFIG = BackendConfig( Value('username', label='Optional username', default=''), - Value('password', label='Optional password', default='', masked=True), - Value('api_key', label='Optional API key', default='', masked=True), + ValueBackendPassword('password', label='Optional password', default=''), + ValueBackendPassword('api_key', label='Optional API key', default='', noprompt=True), ) EXPIRATIONS = { @@ -55,10 +55,13 @@ class PastebinBackend(BaseBackend, BasePasteBackend): } def create_default_browser(self): - return self.create_browser(self.config['api_key'] if self.config['api_key'] else None, - self.config['username'] if self.config['username'] else None, - self.config['password'] if self.config['password'] else None, - get_home=False) + username = self.config['username'].get() + if username: + password = self.config['password'].get() + else: + password = None + return self.create_browser(self.config['api_key'].get() if self.config['api_key'].get() else None, + username, password, get_home=False) def new_paste(self, *args, **kwargs): return PastebinPaste(*args, **kwargs) @@ -94,7 +97,7 @@ def post_paste(self, paste, max_age=None, use_api=True): else: expiration = None with self.browser: - if use_api and self.config.get('api_key'): + if use_api and self.config.get('api_key').get(): self.browser.api_post_paste(paste, expiration=self.EXPIRATIONS.get(expiration)) else: self.browser.post_paste(paste, expiration=self.EXPIRATIONS.get(expiration)) diff --git a/weboob/backends/piratebay/backend.py b/weboob/backends/piratebay/backend.py index e1c2de4aea..92d4e4e510 100644 --- a/weboob/backends/piratebay/backend.py +++ b/weboob/backends/piratebay/backend.py @@ -33,10 +33,6 @@ class PiratebayBackend(BaseBackend, ICapTorrent): VERSION = '0.9' DESCRIPTION = 'the pirate bay bittorrent tracker' LICENSE = 'AGPLv3+' - #CONFIG = ValuesDict(Value('domain', label='Domain (example "ssl.what.cd")'), - # Value('protocol', label='Protocol to use', choices=('http', 'https')), - # Value('username', label='Username'), - # Value('password', label='Password', masked=True)) BROWSER = PiratebayBrowser def create_default_browser(self): diff --git a/weboob/backends/redmine/backend.py b/weboob/backends/redmine/backend.py index 1dc3afd14b..b7fb24b873 100644 --- a/weboob/backends/redmine/backend.py +++ b/weboob/backends/redmine/backend.py @@ -21,8 +21,8 @@ from __future__ import with_statement from weboob.capabilities.content import ICapContent, Content -from weboob.tools.backend import BaseBackend -from weboob.tools.value import ValuesDict, Value +from weboob.tools.backend import BaseBackend, BackendConfig +from weboob.tools.value import ValueBackendPassword, Value from .browser import RedmineBrowser @@ -37,13 +37,15 @@ class RedmineBackend(BaseBackend, ICapContent): VERSION = '0.9' DESCRIPTION = 'The Redmine project management web application' LICENSE = 'AGPLv3+' - CONFIG = ValuesDict(Value('url', label='URL of the Redmine website'), - Value('username', label='Login'), - Value('password', label='Password', masked=True)) + CONFIG = BackendConfig(Value('url', label='URL of the Redmine website'), + Value('username', label='Login'), + ValueBackendPassword('password', label='Password')) BROWSER = RedmineBrowser def create_default_browser(self): - return self.create_browser(self.config['url'], self.config['username'], self.config['password']) + return self.create_browser(self.config['url'].get(), + self.config['username'].get(), + self.config['password'].get()) def id2path(self, id): return id.split('/', 2) diff --git a/weboob/backends/sfr/backend.py b/weboob/backends/sfr/backend.py index d7ba2daa1e..de7c44445e 100644 --- a/weboob/backends/sfr/backend.py +++ b/weboob/backends/sfr/backend.py @@ -22,8 +22,8 @@ from weboob.capabilities.messages import CantSendMessage, ICapMessages, ICapMessagesPost from weboob.capabilities.account import ICapAccount, StatusField -from weboob.tools.backend import BaseBackend -from weboob.tools.value import ValuesDict, Value +from weboob.tools.backend import BaseBackend, BackendConfig +from weboob.tools.value import Value, ValueBackendPassword from .browser import SfrBrowser @@ -38,13 +38,13 @@ class SfrBackend(BaseBackend, ICapAccount, ICapMessages, ICapMessagesPost): VERSION = '0.9' DESCRIPTION = 'SFR french mobile phone provider' LICENSE = 'AGPLv3+' - CONFIG = ValuesDict(Value('login', label='Login'), - Value('password', label='Password', masked=True)) + CONFIG = BackendConfig(Value('login', label='Login'), + ValueBackendPassword('password', label='Password')) BROWSER = SfrBrowser ACCOUNT_REGISTER_PROPERTIES = None def create_default_browser(self): - return self.create_browser(self.config['login'], self.config['password']) + return self.create_browser(self.config['login'].get(), self.config['password'].get()) # ICapMessagesPost methods diff --git a/weboob/backends/societegenerale/backend.py b/weboob/backends/societegenerale/backend.py index ffc21e7c0f..953670f307 100644 --- a/weboob/backends/societegenerale/backend.py +++ b/weboob/backends/societegenerale/backend.py @@ -22,8 +22,8 @@ from __future__ import with_statement from weboob.capabilities.bank import ICapBank, AccountNotFound -from weboob.tools.backend import BaseBackend -from weboob.tools.value import ValuesDict, Value +from weboob.tools.backend import BaseBackend, BackendConfig +from weboob.tools.value import ValueBackendPassword, Value from .browser import SocieteGenerale @@ -38,13 +38,13 @@ class SocieteGeneraleBackend(BaseBackend, ICapBank): VERSION = '0.9' LICENSE = 'AGPLv3+' DESCRIPTION = u'Société Générale french bank\' website' - CONFIG = ValuesDict(Value('login', label='Account ID'), - Value('password', label='Password', masked=True)) + CONFIG = BackendConfig(Value('login', label='Account ID'), + ValueBackendPassword('password', label='Password')) BROWSER = SocieteGenerale def create_default_browser(self): - return self.create_browser(self.config['login'], - self.config['password']) + return self.create_browser(self.config['login'].get(), + self.config['password'].get()) def iter_accounts(self): for account in self.browser.get_accounts_list(): diff --git a/weboob/core/backendscfg.py b/weboob/core/backendscfg.py index 5293e3466a..34fa4200f6 100644 --- a/weboob/core/backendscfg.py +++ b/weboob/core/backendscfg.py @@ -73,6 +73,14 @@ def iter_backends(self): continue yield instance_name, backend_name, params + def backend_exists(self, name): + """ + Return True if the backend exists in config. + """ + config = RawConfigParser() + config.read(self.confpath) + return name in config.sections() + def add_backend(self, instance_name, backend_name, params, edit=False): if not instance_name: raise ValueError(u'Please give a name to the configured backend.') diff --git a/weboob/tools/backend.py b/weboob/tools/backend.py index 1331844a95..3ebea530ef 100644 --- a/weboob/tools/backend.py +++ b/weboob/tools/backend.py @@ -20,10 +20,12 @@ import os from threading import RLock +from copy import copy from weboob.capabilities.base import CapBaseObject, FieldNotFound, IBaseCap, NotLoaded from weboob.tools.misc import iter_fields from weboob.tools.log import getLogger +from weboob.tools.value import ValuesDict __all__ = ['BaseBackend', 'ObjectNotAvailable'] @@ -60,6 +62,61 @@ def save(self): if self.storage: return self.storage.save('backends', self.name) +class BackendConfig(ValuesDict): + modname = None + instname = None + weboob = None + + def load(self, weboob, modname, instname, config, nofail=False): + """ + Load configuration from dict to create an instance. + + @param weboob [Weboob] weboob object + @param modname [str] name of module + @param instname [str] name of instance of this backend + @param params [dict] parameters to load + @param nofail [bool] if true, this call can't fail. + @return [BackendConfig] + """ + cfg = BackendConfig() + cfg.modname = modname + cfg.instname = instname + cfg.weboob = weboob + for name, field in self.iteritems(): + value = config.get(name, None) + + if value is None: + if not nofail and field.required: + raise BaseBackend.ConfigError('Backend(%s): Configuration error: Missing parameter "%s" (%s)' + % (cfg.instname, name, field.description)) + value = field.default + + field = copy(field) + try: + field.load(cfg.instname, value, cfg.weboob.callbacks) + except ValueError, v: + if not nofail: + raise BaseBackend.ConfigError('Backend(%s): Configuration error for field "%s": %s' % (cfg.instname, name, v)) + + cfg[name] = field + return cfg + + def dump(self): + settings = {} + for name, value in self.iteritems(): + settings[name] = value.dump() + return settings + + def save(self, edit=True, params=None): + assert self.modname is not None + assert self.instname is not None + assert self.weboob is not None + + dump = self.dump() + if params is not None: + dump.update(params) + + self.weboob.backends_config.add_backend(self.instname, self.modname, dump, edit) class BaseBackend(object): # Backend name. @@ -76,7 +133,7 @@ class BaseBackend(object): LICENSE = '' # Configuration required for this backend. # Values must be weboob.tools.value.Value objects. - CONFIG = {} + CONFIG = BackendConfig() # Storage STORAGE = {} # Browser class @@ -99,7 +156,7 @@ def __exit__(self, t, v, tb): def __repr__(self): return u"" % self.name - def __init__(self, weboob, name, config, storage, logger=None): + def __init__(self, weboob, name, config=None, storage=None, logger=None): self.logger = getLogger(name, parent=logger) self.weboob = weboob self.name = name @@ -108,23 +165,9 @@ def __init__(self, weboob, name, config, storage, logger=None): # Private fields (which start with '_') self._private_config = dict((key, value) for key, value in config.iteritems() if key.startswith('_')) - # Configuration of backend - self.config = {} - for name, field in self.CONFIG.iteritems(): - value = config.get(name, None) - - if value is None: - if field.required: - raise BaseBackend.ConfigError('Backend(%s): Configuration error: Missing parameter "%s" (%s)' % (self.name, name, field.description)) - value = field.default - - try: - field.set_value(value) - except ValueError, v: - raise BaseBackend.ConfigError('Backend(%s): Configuration error for field "%s": %s' % (self.name, name, v)) + # Load configuration of backend. + self.config = self.CONFIG.load(weboob, self.NAME, self.name, config) - # field.value is a property which converts string to right type (bool/int/float) - self.config[name] = field.value self.storage = BackendStorage(self.name, storage) self.storage.load(self.STORAGE) -- GitLab