diff --git a/weboob/capabilities/base.py b/weboob/capabilities/base.py index 15c678ce..c638170f 100644 --- a/weboob/capabilities/base.py +++ b/weboob/capabilities/base.py @@ -19,7 +19,12 @@ from weboob.tools.misc import iter_fields -__all__ = ['IBaseCap', 'NotAvailable', 'NotLoaded', 'CapBaseObject'] +__all__ = ['FieldNotFound', 'IBaseCap', 'NotAvailable', 'NotLoaded', 'CapBaseObject'] + + +class FieldNotFound(Exception): + def __init__(self, obj, field): + Exception.__init__(self, u'Field "%s" not found for object %s' % (field, obj)) class NotAvailableMeta(type): @@ -55,6 +60,7 @@ class NotLoaded(object): class IBaseCap(object): pass + class CapBaseObject(object): FIELDS = None diff --git a/weboob/tools/application/base.py b/weboob/tools/application/base.py index 88dea237..26642177 100644 --- a/weboob/tools/application/base.py +++ b/weboob/tools/application/base.py @@ -25,7 +25,6 @@ from weboob.capabilities.base import NotAvailable, NotLoaded from weboob.core.ouiboube import Weboob from weboob.tools.config.iconfig import ConfigError from weboob.tools.backend import ObjectNotAvailable -from weboob.tools.misc import iter_fields __all__ = ['BackendNotFound', 'BaseApplication', 'ConfigError'] @@ -212,12 +211,7 @@ class BaseApplication(object): def _complete_obj(self, backend, fields, obj): if fields: - if fields == 'direct': - fields = None - elif fields == 'full': - fields = [k for k, v in iter_fields(obj)] try: - print fields backend.fillobj(obj, fields) except ObjectNotAvailable, e: logging.warning(u'Could not retrieve required fields (%s): %s' % (','.join(fields), e)) @@ -292,6 +286,7 @@ class BaseApplication(object): level = logging.WARNING log_format = '%(asctime)s:%(levelname)s:%(pathname)s:%(lineno)d:%(funcName)s %(message)s' logging.basicConfig(stream=sys.stdout, level=level, format=log_format) + logging.root.level = level app._handle_options() app.handle_application_options() diff --git a/weboob/tools/application/formatters/iformatter.py b/weboob/tools/application/formatters/iformatter.py index d55f6aaa..c617fe57 100644 --- a/weboob/tools/application/formatters/iformatter.py +++ b/weboob/tools/application/formatters/iformatter.py @@ -16,16 +16,11 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -from weboob.capabilities.base import CapBaseObject +from weboob.capabilities.base import CapBaseObject, FieldNotFound from weboob.tools.ordereddict import OrderedDict -__all__ = ['FieldNotFound', 'IFormatter'] - - -class FieldNotFound(Exception): - def __init__(self, field): - Exception.__init__(self, u'Field not found: "%s"' % field) +__all__ = ['IFormatter'] class IFormatter(object): @@ -97,7 +92,7 @@ class IFormatter(object): try: value = d[key] except KeyError: - raise FieldNotFound(key) + raise FieldNotFound(obj, key) if key == 'id' and obj.backend is not None: value = self.build_id(value, obj.backend) diff --git a/weboob/tools/application/repl.py b/weboob/tools/application/repl.py index d3ec8832..4991610d 100644 --- a/weboob/tools/application/repl.py +++ b/weboob/tools/application/repl.py @@ -31,12 +31,13 @@ import re import subprocess import sys +from weboob.capabilities.base import FieldNotFound from weboob.core import CallErrors from weboob.core.backendscfg import BackendsConfig +from weboob.tools.misc import iter_fields from .base import BackendNotFound, BaseApplication from .formatters.load import formatters, load_formatter -from .formatters.iformatter import FieldNotFound from .results import ResultsCondition, ResultsConditionException @@ -155,7 +156,19 @@ class ReplApplication(cmd.Cmd, BaseApplication): """ if kwargs.pop('backends', None) is None: kwargs['backends'] = self.enabled_backends - return self.weboob.do(self._complete, self.options.count, self.selected_fields, function, *args, **kwargs) + fields = self.selected_fields + if fields == ['direct']: + fields = None + elif fields == ['full']: + fields = [k for k, v in iter_fields(obj)] + try: + for values in self.weboob.do(self._complete, self.options.count, fields, function, *args, **kwargs): + yield values + except CallErrors, e: + if len(e.errors) == 1 and isinstance(e.errors[0][1], FieldNotFound): + logging.error(e.errors[0][1]) + else: + raise # options related methods @@ -175,7 +188,7 @@ class ReplApplication(cmd.Cmd, BaseApplication): if self.options.select: self.selected_fields = self.options.select.split(',') else: - self.selected_fields = 'direct' + self.selected_fields = ['direct'] if self.options.condition: self.condition = ResultsCondition(self.options.condition) @@ -380,7 +393,10 @@ class ReplApplication(cmd.Cmd, BaseApplication): """ select [FIELD_NAME]... | "direct" | "full" """ - print self.selected_fields + if line: + self.selected_fields = line.split() + else: + print ' '.join(self.selected_fields) # user interaction related methods @@ -445,8 +461,11 @@ class ReplApplication(cmd.Cmd, BaseApplication): self.formatter.set_header(string) def format(self, result): + fields = self.selected_fields + if fields == ['direct'] or fields == ['full']: + fields = None try: - self.formatter.format(obj=result, selected_fields=self.selected_fields, condition=self.condition) + self.formatter.format(obj=result, selected_fields=fields, condition=self.condition) except FieldNotFound, e: logging.error(e) except ResultsConditionException, e: diff --git a/weboob/tools/backend.py b/weboob/tools/backend.py index 6a89ad92..56e880fa 100644 --- a/weboob/tools/backend.py +++ b/weboob/tools/backend.py @@ -21,7 +21,7 @@ import os from threading import RLock from logging import debug -from weboob.capabilities.base import IBaseCap, NotLoaded, CapBaseObject +from weboob.capabilities.base import CapBaseObject, FieldNotFound, IBaseCap, NotLoaded from weboob.tools.misc import iter_fields @@ -211,7 +211,10 @@ class BaseBackend(object): return True return False - def fillobj(self, obj, fields): + def fillobj(self, obj, fields=None): + """ + @param fields which fields to fill; if None, only "direct" fields are filled (list) + """ def not_loaded(v): return (v is NotLoaded or isinstance(v, CapBaseObject) and not v.__iscomplete__()) @@ -219,14 +222,15 @@ class BaseBackend(object): fields = (fields,) missing_fields = [] - if fields is None or '*' in fields: + if fields is None: if isinstance(obj, CapBaseObject): - fields = obj.iter_fields() + fields = [item[0] for item in obj.iter_fields()] else: - fields = iter_fields(obj) + fields = [item[0] for item in iter_fields(obj)] for field in fields: - assert hasattr(obj, field), u'%r does not have field %s' % (obj, field) + if not hasattr(obj, field): + raise FieldNotFound(obj, field) value = getattr(obj, field) missing = False