diff --git a/weboob/backends/arte/backend.py b/weboob/backends/arte/backend.py
index ff1df0d64ca2aad20a91bad5b3a84ef827a1c8e0..3f852ea20de24ecee041e7ec1d75026093baf0be 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 50b1b3b76c9a1185e07806e2cfadcdc703601f26..6c726f22d5fc10d488a4f827a3d24e6f06de193d 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 3589d01b1e34d4e0d319e6e0268f81199b281c6d..6da89e06e621e93f44f7621ceed39f4f89318f8f 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 1d6aade346020cebbdffb7155a646e4a725fd0f4..07e8ce3eba6f878168a7f59444333e7094c4987c 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 daa2269bb01a03cd65a278c6f7e0de3966777b5c..e9dce7470a0e801f715832bde886cb47e5822e3b 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 c92c8ec58c30b07377d34d543557aea2e03694f8..a3896aefa7509e93e8de2021a50b909727c79c87 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 5c429aad46813b3ac7966955521289f7ea5af220..86919a0fac2e9e2caf625dd8110a9f504c9c0dca 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 c58fb43f2fcac7941eb4996f7c98b0a32272d17c..676a0c639ef952842f7950dfb75a910f482e3515 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 bf015b6e2ccbbaeb8451a91d528bc4abe893bbb1..8c96e43b069014ba1a44542783f4fd3960058187 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 65f36b3cea1b17b0e96f3586549d3a545100dfd1..a1a1270a88d51f9046232c39f644c7be1e82251b 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 f29bc315252b1152434f299a7f6967f687482eaf..6040fc263bd3211a890eb5dcfb8b8245311d4483 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 5cf272361109f80205497e25a5ebf11ba432ebff..5fecf25ab953cf9fdc1822620696f7e4bb3c6e64 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 938da9b916ad1f5c9561dc851db7da1784cb41a3..2fd8c744541cfba017eaa98958e42d7e078fc812 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 093f81b407d969f942dad075a1c56347995da8b8..28814fb1cd563309b72e79411e91b8768b07a9b4 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 741b4e6661a253fceefa3cdbb6404f37102d5a77..e7dce61e3d7b55ac1b4d455db666bed6ad8132a1 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 2753b1f3fbc039e3adf2e114ebf97c525027b7bc..3609dde4a8c42024da826f2d3b4c9967e54c3725 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 bfb61e72fd83c1aa0d892956e145c0a0da6376bf..5036bba5ebf712a285295eca9a7a6f29e59b1d8b 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 e1c2de4aea86d20cb08bdd11501275cbce90998c..92d4e4e51033bc52e6e5ff7d6457612bf7f78d46 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 1dc3afd14ba4fa4e704fe6488e910e3b68d7d118..b7fb24b8739779b063502a6577f2e1de308faa81 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 d7ba2daa1e6af1d3006c01287d3d978079d523dd..de7c44445e8c5ffbaa57c9f008d27ad7b1987646 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 ffc21e7c0fd516ca4ac8b7d1eefd1ffa6e0de307..953670f3070ca65c3cec34b994014b262c876e0c 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 5293e3466a0e32e6b9e558240c513134726c1cc1..34fa4200f6d004884397687da30fc287d8b048a6 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 1331844a95bc7fe927d5cb370e50fa661be615a9..3ebea530ef81e9e61d05c40c22913924437fb932 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)