Make CapCollection a bit more useable

Collections are not stored in replapplication.objects anymore, but in
replapplication.collections. This fixes the IDs issue. There was no gain
from storing them in objects.

Completion right after cd should be faster (and should always have been
like that, it was pretty much a bug).

The display of do_ls() should be much clearer. Collections are always at
the end, have ids/title/backend like objects (but using a formatter
would be better than my current hack).

There are still many issues with the current implementation.
refs #774
closes #785
This commit is contained in:
Laurent Bachelier 2012-02-12 15:49:08 +01:00
commit 9c5326c0e4
3 changed files with 42 additions and 24 deletions

View file

@ -55,6 +55,7 @@ class Collection(object):
id and title should be unicode. id and title should be unicode.
""" """
children = Children() children = Children()
backend = None
def __init__(self, _id=None, title=None, children=None, fct=None): def __init__(self, _id=None, title=None, children=None, fct=None):
self.id = _id self.id = _id

View file

@ -24,6 +24,7 @@ from copy import copy
from threading import Thread, Event, RLock, Timer from threading import Thread, Event, RLock, Timer
from weboob.capabilities.base import CapBaseObject from weboob.capabilities.base import CapBaseObject
from weboob.capabilities.collection import Collection
from weboob.tools.misc import get_backtrace from weboob.tools.misc import get_backtrace
from weboob.tools.log import getLogger from weboob.tools.log import getLogger
@ -92,6 +93,7 @@ class BackendsCall(object):
if isinstance(result, CapBaseObject): if isinstance(result, CapBaseObject):
if self.condition and not self.condition.is_valid(result): if self.condition and not self.condition.is_valid(result):
return return
if isinstance(result, (CapBaseObject, Collection)):
result.backend = backend.name result.backend = backend.name
self.responses.append((backend, result)) self.responses.append((backend, result))
self.response_event.set() self.response_event.set()

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright(C) 2010-2012 Christophe Benz, Romain Bignon # Copyright(C) 2010-2012 Christophe Benz, Romain Bignon, Laurent Bachelier
# #
# This file is part of weboob. # This file is part of weboob.
# #
@ -136,6 +136,7 @@ class ReplApplication(Cmd, ConsoleApplication):
self._interactive = False self._interactive = False
self.objects = [] self.objects = []
self.collections = []
self.working_path = Path() self.working_path = Path()
@property @property
@ -149,6 +150,7 @@ class ReplApplication(Cmd, ConsoleApplication):
else: else:
self.prompt = '%s> ' % (self.APPNAME) self.prompt = '%s> ' % (self.APPNAME)
self.objects = [] self.objects = []
self.collections = []
def change_path(self, path): def change_path(self, path):
self.working_path.fromstring(path) self.working_path.fromstring(path)
@ -164,7 +166,7 @@ class ReplApplication(Cmd, ConsoleApplication):
if self.interactive: if self.interactive:
try: try:
obj = self.objects[int(id) - 1] obj = self.objects[int(id) - 1]
except (IndexError,ValueError): except (IndexError, ValueError):
pass pass
else: else:
if isinstance(obj, CapBaseObject): if isinstance(obj, CapBaseObject):
@ -197,7 +199,7 @@ class ReplApplication(Cmd, ConsoleApplication):
if self.interactive: if self.interactive:
try: try:
obj = self.objects[int(_id) - 1] obj = self.objects[int(_id) - 1]
except (IndexError,ValueError): except (IndexError, ValueError):
pass pass
else: else:
if isinstance(obj, CapBaseObject): if isinstance(obj, CapBaseObject):
@ -213,10 +215,12 @@ class ReplApplication(Cmd, ConsoleApplication):
def unload_backends(self, *args, **kwargs): def unload_backends(self, *args, **kwargs):
self.objects = [] self.objects = []
self.collections = []
return ConsoleApplication.unload_backends(self, *args, **kwargs) return ConsoleApplication.unload_backends(self, *args, **kwargs)
def load_backends(self, *args, **kwargs): def load_backends(self, *args, **kwargs):
self.objects = [] self.objects = []
self.collections = []
return ConsoleApplication.load_backends(self, *args, **kwargs) return ConsoleApplication.load_backends(self, *args, **kwargs)
def main(self, argv): def main(self, argv):
@ -245,6 +249,7 @@ class ReplApplication(Cmd, ConsoleApplication):
readline.read_history_file(history_filepath) readline.read_history_file(history_filepath)
except IOError: except IOError:
pass pass
def savehist(): def savehist():
readline.write_history_file(history_filepath) readline.write_history_file(history_filepath)
atexit.register(savehist) atexit.register(savehist)
@ -852,21 +857,26 @@ class ReplApplication(Cmd, ConsoleApplication):
List objects in current path. List objects in current path.
""" """
self.objects = self._fetch_objects(objs=self.COLLECTION_OBJECTS) self.objects, self.collections = self._fetch_objects(objs=self.COLLECTION_OBJECTS)
for obj in self.objects: for obj in self.objects:
if isinstance(obj, CapBaseObject): if isinstance(obj, CapBaseObject):
self.format(obj) self.format(obj)
elif isinstance(obj, Collection):
if obj.id and obj.title:
print u'Collection: %s%s%s (%s)' % \
(self.BOLD, obj.id, self.NC, obj.title)
elif obj.id:
print u'Collection: %s%s%s' % (self.BOLD, obj.id, self.NC)
else:
print obj
else: else:
print obj.title print obj
if self.collections:
print
print 'Collections:'
for collection in self.collections:
if collection.id and collection.title:
print u'%s* (%s) %s (%s)%s' % \
(self.BOLD, collection.id, collection.title, collection.backend, self.NC)
elif collection.id:
print u'%s* (%s) (%s)%s' % \
(self.BOLD, collection.id, collection.backend, self.NC)
else:
print collection
self.flush() self.flush()
@ -882,23 +892,29 @@ class ReplApplication(Cmd, ConsoleApplication):
else: else:
self.working_path.extend(line) self.working_path.extend(line)
objects = self._fetch_objects(objs=self.COLLECTION_OBJECTS) objects, collections = self._fetch_objects(objs=self.COLLECTION_OBJECTS)
if len(objects) == 0: if len(objects) + len(collections) == 0:
print >>sys.stderr, "Path: %s not found" % self.working_path.tostring() print >>sys.stderr, "Path: %s not found" % self.working_path.tostring()
self.working_path.restore() self.working_path.restore()
return 1 return 1
self._change_prompt() self._change_prompt()
self.objects = objects
self.collections = collections
def _fetch_objects(self, objs): def _fetch_objects(self, objs):
objects = [] objects = []
collections = []
split_path = self.working_path.get() split_path = self.working_path.get()
try: try:
for backend, res in self.do('iter_resources', for backend, res in self.do('iter_resources',
objs=objs, split_path=split_path, objs=objs, split_path=split_path,
caps=ICapCollection): caps=ICapCollection):
objects.append(res) if isinstance(res, Collection):
collections.append(res)
else:
objects.append(res)
except CallErrors, errors: except CallErrors, errors:
for backend, error, backtrace in errors.errors: for backend, error, backtrace in errors.errors:
if isinstance(error, CollectionNotFound): if isinstance(error, CollectionNotFound):
@ -906,21 +922,20 @@ class ReplApplication(Cmd, ConsoleApplication):
else: else:
self.bcall_error_handler(backend, error, backtrace) self.bcall_error_handler(backend, error, backtrace)
return objects return (objects, collections)
def complete_cd(self, text, line, begidx, endidx): def complete_cd(self, text, line, begidx, endidx):
directories = set(['..']) directories = set(['..'])
mline = line.partition(' ')[2] mline = line.partition(' ')[2]
offs = len(mline) - len(text) offs = len(mline) - len(text)
if len(self.objects) == 0: if len(self.collections) == 0:
self.objects = self._fetch_objects(objs=self.COLLECTION_OBJECTS) self.objects, self.collections = self._fetch_objects(objs=self.COLLECTION_OBJECTS)
for obj in self.objects: for collection in self.collections:
if isinstance(obj, Collection): directories.add(collection.id)
directories.add(obj.id) if collection.title:
if obj.title: directories.add(collection.title)
directories.add(obj.title)
return [s[offs:] for s in directories if s.startswith(mline)] return [s[offs:] for s in directories if s.startswith(mline)]