diff --git a/modules/canalplus/browser.py b/modules/canalplus/browser.py index 48f5c12d..b77c2e67 100644 --- a/modules/canalplus/browser.py +++ b/modules/canalplus/browser.py @@ -82,11 +82,11 @@ class CanalplusBrowser(BaseBrowser): if len(split_path) == 0: for channel in channels: - if channel.level == 1: + if channel.path_level == 1: yield channel elif len(split_path) == 1: for channel in channels: - if channel.level == 2 and split_path == channel.parent: + if channel.path_level == 2 and split_path == channel.parent_path: yield channel elif len(split_path) == 2: subchannels = self.iter_resources(split_path[0:1]) diff --git a/modules/redmine/backend.py b/modules/redmine/backend.py index ce9a84dc..aec26b95 100644 --- a/modules/redmine/backend.py +++ b/modules/redmine/backend.py @@ -106,9 +106,9 @@ class RedmineBackend(BaseBackend, ICapContent, ICapBugTracker, ICapCollection): return self.iter_issues(query) def validate_collection(self, objs, collection): - if collection.level == 0: + if collection.path_level == 0: return - if Issue in objs and collection.level == 1: + if Issue in objs and collection.path_level == 1: for project in self.iter_projects(): if collection.basename == project.id: return Collection([project.id], project.name) diff --git a/weboob/capabilities/collection.py b/weboob/capabilities/collection.py index 6ef8c112..51cfe5e0 100644 --- a/weboob/capabilities/collection.py +++ b/weboob/capabilities/collection.py @@ -19,7 +19,7 @@ from .base import IBaseCap, CapBaseObject -__all__ = ['ICapCollection', 'Collection', 'CollectionNotFound'] +__all__ = ['ICapCollection', 'BaseCollection', 'Collection', 'CollectionNotFound'] class CollectionNotFound(Exception): @@ -31,39 +31,49 @@ class CollectionNotFound(Exception): Exception.__init__(self, msg) -class Collection(CapBaseObject): +class BaseCollection(CapBaseObject): + """ + Inherit from this if you want to create an object that is *also* a Collection. + However, this probably will not work properly for now. + """ + def __init__(self, split_path): + self.split_path = split_path + + @property + def basename(self): + return self.split_path[-1] if self.path_level else None + + @property + def parent_path(self): + return self.split_path[0:-1] if self.path_level else None + + @property + def path_level(self): + return len(self.split_path) + + +class Collection(BaseCollection): """ A Collection is a "fake" object returned in results, which shows you can get more results if you go into its path. It is a dumb object, it must not contain callbacks to a backend. + + Do not inherit from this class if you want to make a regular CapBaseObject + a Collection, use BaseCollection instead. """ - def __init__(self, split_path, title=None, backend=None): - self.split_path = split_path + def __init__(self, split_path, title=None): self.title = title - _id = self.basename - CapBaseObject.__init__(self, _id, backend) + BaseCollection.__init__(self, split_path) def __unicode__(self): - if self.title and self.id: - return u'%s (%s)' % (self.id, self.title) - elif self.id: - return u'%s' % self.id + if self.title and self.basename: + return u'%s (%s)' % (self.basename, self.title) + elif self.basename: + return u'%s' % self.basename else: return u'Unknown collection' - @property - def basename(self): - return self.split_path[-1] if self.level else None - - @property - def parent(self): - return self.split_path[0:-1] if self.level else None - - @property - def level(self): - return len(self.split_path) - class ICapCollection(IBaseCap): def iter_resources_flat(self, objs, split_path, clean_only=False): @@ -93,7 +103,7 @@ class ICapCollection(IBaseCap): If the path is invalid (i.e. can't be handled by this module), it should return None. """ - collection = Collection(split_path, None, self.name) + collection = Collection(split_path, None) return self.validate_collection(objs, collection) or collection def validate_collection(self, objs, collection): @@ -105,7 +115,7 @@ class ICapCollection(IBaseCap): You can replace the collection object entirely by returning a new one. """ # Root - if collection.level == 0: + if collection.path_level == 0: return try: i = self.iter_resources(objs, collection.split_path) @@ -121,20 +131,20 @@ class ICapCollection(IBaseCap): def test(): c = Collection([]) assert c.basename is None - assert c.parent is None - assert c.level == 0 + assert c.parent_path is None + assert c.path_level == 0 c = Collection([u'lol']) assert c.basename == u'lol' - assert c.parent == [] - assert c.level == 1 + assert c.parent_path == [] + assert c.path_level == 1 c = Collection([u'lol', u'cat']) assert c.basename == u'cat' - assert c.parent == [u'lol'] - assert c.level == 2 + assert c.parent_path == [u'lol'] + assert c.path_level == 2 c = Collection([u'w', u'e', u'e', u'b', u'o', u'o', u'b']) assert c.basename == u'b' - assert c.parent == [u'w', u'e', u'e', u'b', u'o', u'o'] - assert c.level == 7 + assert c.parent_path == [u'w', u'e', u'e', u'b', u'o', u'o'] + assert c.path_level == 7 diff --git a/weboob/tools/application/repl.py b/weboob/tools/application/repl.py index d89185d8..1f6a8bab 100644 --- a/weboob/tools/application/repl.py +++ b/weboob/tools/application/repl.py @@ -32,7 +32,7 @@ from weboob.tools.application.formatters.iformatter import MandatoryFieldsNotFou from weboob.tools.misc import to_unicode from weboob.tools.path import WorkingPath from weboob.tools.ordereddict import OrderedDict -from weboob.capabilities.collection import Collection, ICapCollection, CollectionNotFound +from weboob.capabilities.collection import Collection, BaseCollection, ICapCollection, CollectionNotFound from .console import BackendNotGiven, ConsoleApplication from .formatters.load import FormattersLoader, FormatterLoadError @@ -864,19 +864,13 @@ class ReplApplication(Cmd, ConsoleApplication): print obj if self.collections: - print - print 'Collections:' for collection in self.collections: if collection.basename and collection.title: - print u'%s* (%s) %s (%s)%s' % \ + print u'%s~ (%s) %s (%s)%s' % \ (self.BOLD, collection.basename, collection.title, collection.backend, self.NC) - elif collection.basename: - print u'%s* (%s) (%s)%s' % \ - (self.BOLD, collection.basename, collection.backend, self.NC) else: - print collection - - self.flush() + print u'%s~ (%s) (%s)%s' % \ + (self.BOLD, collection.basename, collection.backend, self.NC) def do_cd(self, line): """ @@ -938,6 +932,13 @@ class ReplApplication(Cmd, ConsoleApplication): return (objects, collections) + def all_collections(self): + """ + Get all objects that are collections: regular objects and fake dumb objects. + """ + obj_collections = [obj for obj in self.objects if isinstance(obj, BaseCollection)] + return obj_collections + self.collections + def complete_cd(self, text, line, begidx, endidx): directories = set() if len(self.working_path.get()): @@ -945,7 +946,8 @@ class ReplApplication(Cmd, ConsoleApplication): mline = line.partition(' ')[2] offs = len(mline) - len(text) - if len(self.collections) == 0: + # refresh only if needed + if len(self.objects) == 0 and len(self.collections) == 0: try: self.objects, self.collections = self._fetch_objects(objs=self.COLLECTION_OBJECTS) except CallErrors, errors: @@ -955,7 +957,8 @@ class ReplApplication(Cmd, ConsoleApplication): else: self.bcall_error_handler(backend, error, backtrace) - for collection in self.collections: + collections = self.all_collections() + for collection in collections: directories.add(collection.basename.encode(sys.stdout.encoding or locale.getpreferredencoding())) return [s[offs:] for s in directories if s.startswith(mline)]