diff --git a/weboob/tools/backend.py b/weboob/tools/backend.py index 425e066f..7e52ca71 100644 --- a/weboob/tools/backend.py +++ b/weboob/tools/backend.py @@ -101,6 +101,9 @@ class BackendStorage(object): """ Load storage. + It is made automatically when your backend is created, and use the + ``STORAGE`` class attribute as default. + :param default: this is the default tree if storage is empty :type default: :class:`dict` """ diff --git a/weboob/tools/browser/browser.py b/weboob/tools/browser/browser.py index f9cf2f0a..6fd84b07 100644 --- a/weboob/tools/browser/browser.py +++ b/weboob/tools/browser/browser.py @@ -306,9 +306,18 @@ class StandardBrowser(mechanize.Browser): self.logger.info(msg) def get_document(self, result): + """ + Get a parsed document from a stream. + + :param result: HTML page stream + :type result: stream + """ return self.parser.parse(result, self.ENCODING) def location(self, *args, **kwargs): + """ + Go on an URL and get the related document. + """ return self.get_document(self.openurl(*args, **kwargs)) @staticmethod @@ -454,21 +463,6 @@ class BaseBrowser(StandardBrowser): except BrowserUnavailable: pass - def pageaccess(func): - """ - Decorator to use around a method which access to a page. - """ - def inner(self, *args, **kwargs): - if not self.page or self.password and not self.page.is_logged(): - self.home() - - return func(self, *args, **kwargs) - return inner - - @pageaccess - def keepalive(self): - self.home() - def submit(self, *args, **kwargs): """ Submit the selected form. @@ -483,9 +477,19 @@ class BaseBrowser(StandardBrowser): raise BrowserUnavailable(e) def is_on_page(self, pageCls): + """ + Check the current page. + + :param pageCls: class of the page to check + :type pageCls: :class:`BasePage` + :rtype: bool + """ return isinstance(self.page, pageCls) def absurl(self, rel): + """ + Get an absolute URL from a relative one. + """ if rel is None: return None if not rel.startswith('/'): @@ -493,6 +497,9 @@ class BaseBrowser(StandardBrowser): return '%s://%s%s' % (self.PROTOCOL, self.DOMAIN, rel) def follow_link(self, *args, **kwargs): + """ + Follow a link on the page. + """ try: self._change_location(mechanize.Browser.follow_link(self, *args, **kwargs)) except (mechanize.response_seek_wrapper, urllib2.HTTPError, urllib2.URLError, BadStatusLine), e: diff --git a/weboob/tools/storage.py b/weboob/tools/storage.py index bc1e3918..eeef1106 100644 --- a/weboob/tools/storage.py +++ b/weboob/tools/storage.py @@ -25,18 +25,33 @@ from .config.yamlconfig import YamlConfig class IStorage(object): def load(self, what, name, default={}): + """ + Load data from storage. + """ raise NotImplementedError() def save(self, what, name): + """ + Write changes in storage on the disk. + """ raise NotImplementedError() def set(self, what, name, *args): + """ + Set data in a path. + """ raise NotImplementedError() def delete(self, what, name, *args): + """ + Delete a value or a path. + """ raise NotImplementedError() def get(self, what, name, *args, **kwargs): + """ + Get a value or a path. + """ raise NotImplementedError() diff --git a/weboob/tools/value.py b/weboob/tools/value.py index 9b7a7b4a..11bf200e 100644 --- a/weboob/tools/value.py +++ b/weboob/tools/value.py @@ -22,16 +22,39 @@ import re from .ordereddict import OrderedDict -__all__ = ['ValuesDict', 'Value', 'ValueInt', 'ValueBool', 'ValueFloat'] +__all__ = ['ValuesDict', 'Value', 'ValueBackendPassword', 'ValueInt', 'ValueFloat', 'ValueBool'] class ValuesDict(OrderedDict): + """ + Ordered dictionarry which can take values in constructor. + + >>> ValuesDict(Value('a', label='Test'), + ValueInt('b', label='Test2')) + """ def __init__(self, *values): OrderedDict.__init__(self) for v in values: self[v.id] = v class Value(object): + """ + Value. + + :param label: human readable description of a value + :type label: str + :param required: if ``True``, the backend can't loaded if the key isn't found in its configuration + :type required: bool + :param default: an optional default value, used when the key is not in config. If there is no default value and the key + is not found in configuration, the **required** parameter is implicitly set + :param masked: if ``True``, the value is masked. It is useful for applications to know if this key is a password + :type masked: bool + :param regexp: if specified, on load the specified value is checked against this regexp, and an error is raised if it doesn't match + :type regexp: str + :param choices: if this parameter is set, the value must be in the list + :type choices: (list,dict) + """ + def __init__(self, *args, **kwargs): if len(args) > 0: self.id = args[0] @@ -49,6 +72,11 @@ class Value(object): self._value = kwargs.get('value', None) def check_valid(self, v): + """ + Check if the given value is valid. + + :raises: ValueError + """ if v == '' and self.default != '': raise ValueError('Value can\'t be empty') if self.regexp is not None and not re.match(self.regexp, unicode(v)): @@ -58,16 +86,34 @@ class Value(object): v, ', '.join(unicode(s) for s in self.choices.iterkeys()))) def load(self, domain, v, callbacks): + """ + Load value. + + :param domain: what is the domain of this value + :type domain: str + :param v: value to load + :param callbacks: list of weboob callbacks + :type callbacks: dict + """ return self.set(v) def set(self, v): + """ + Set a value. + """ self.check_valid(v) self._value = v def dump(self): + """ + Dump value to be stored. + """ return self.get() def get(self): + """ + Get the value. + """ return self._value class ValueBackendPassword(Value):