diff --git a/modules/canalplus/browser.py b/modules/canalplus/browser.py index 8dae0251..43a315cc 100644 --- a/modules/canalplus/browser.py +++ b/modules/canalplus/browser.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -# Copyright(C) 2010-2011 Nicolas Duhamel +# Copyright(C) 2010-2012 Nicolas Duhamel, Laurent Bachelier # # This file is part of weboob. # @@ -90,18 +90,14 @@ class CanalplusBrowser(BaseBrowser): yield channel elif len(split_path) == 2: subchannels = self.iter_resources(split_path[0:1]) - channel = None - for subchannel in subchannels: - # allow matching by title for backward compatibility (for now) - if split_path[0] == subchannel.split_path[0] and \ - split_path[1] in (subchannel.split_path[1], subchannel.title): - channel = subchannel - if channel: - self.location("http://service.canal-plus.com/video/rest/getMEAs/cplus/%s" % channel.id) + try: + channel = [subchannel for subchannel in subchannels + if split_path == subchannel.split_path][0] + self.location("http://service.canal-plus.com/video/rest/getMEAs/cplus/%s" % channel._link_id) assert self.is_on_page(VideoPage) for video in self.page.iter_channel(): yield video - else: + except IndexError: raise CollectionNotFound(split_path) else: diff --git a/modules/canalplus/pages/initpage.py b/modules/canalplus/pages/initpage.py index a5709f60..c4f4daee 100644 --- a/modules/canalplus/pages/initpage.py +++ b/modules/canalplus/pages/initpage.py @@ -34,11 +34,12 @@ class InitPage(BasePage): for elem in self.document[2].getchildren(): for e in elem.getchildren(): if e.tag == "NOM": - name = e.text.strip() + name = unicode(e.text.strip()) channels.append(Collection([name])) elif e.tag == "SELECTIONS": for select in e: - sub = Collection([name, select[0].text], - title=select[1].text.strip()) + subname = unicode(select[1].text.strip()) + sub = Collection([name, subname]) + sub._link_id = select[0].text channels.append(sub) return channels diff --git a/modules/redmine/backend.py b/modules/redmine/backend.py index 7b3d6714..d8cd1b0e 100644 --- a/modules/redmine/backend.py +++ b/modules/redmine/backend.py @@ -107,6 +107,15 @@ class RedmineBackend(BaseBackend, ICapContent, ICapBugTracker, ICapCollection): raise CollectionNotFound(split_path) + def _is_collection_valid(self, objs, split_path): + if len(split_path) == 0: + return True + if Issue in objs and len(split_path) == 1: + for project in self.browser.iter_projects(): + if split_path[0] in (project['id'], project['name']): + return True + return self.get_project(split_path[0]) is not None + return False ############# CapBugTracker ################################################### def _build_project(self, project_dict): diff --git a/weboob/capabilities/collection.py b/weboob/capabilities/collection.py index 6bfb8e44..e85820d0 100644 --- a/weboob/capabilities/collection.py +++ b/weboob/capabilities/collection.py @@ -38,7 +38,7 @@ class Collection(CapBaseObject): It is a dumb object, it must not contain callbacks to a backend. """ - def __init__(self, split_path, backend=None, title=None): + def __init__(self, split_path, title=None, backend=None): self.split_path = split_path self.title = title _id = split_path[-1] if len(split_path) else None @@ -74,3 +74,30 @@ class ICapCollection(IBaseCap): components. """ raise NotImplementedError() + + def get_collection(self, objs, split_path): + """ + Get a collection for a given split path. + 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) + if self._is_collection_valid(objs, collection.split_path): + return collection + + def _is_collection_valid(self, objs, split_path): + """ + Tests if a collection is valid. + For compatibility reasons, and to provide a default way, it checks if + the collection has at least one object in it. However, it is not very + efficient or exact, and you are encouraged to override this method. + """ + # Root + if len(split_path) == 0: + return True + try: + i = self.iter_resources(objs, split_path) + i.next() + return True + except (StopIteration, CollectionNotFound): + return False diff --git a/weboob/tools/application/repl.py b/weboob/tools/application/repl.py index e636fca6..7b7a70e1 100644 --- a/weboob/tools/application/repl.py +++ b/weboob/tools/application/repl.py @@ -894,16 +894,16 @@ class ReplApplication(Cmd, ConsoleApplication): else: self.working_path.cd1(line) - objects, collections = self._fetch_objects(objs=self.COLLECTION_OBJECTS) - if len(objects) + len(collections) == 0: + collections = [res for backend, res in self.do('get_collection', + objs=self.COLLECTION_OBJECTS, split_path=self.working_path.get(), + caps=ICapCollection) if res is not None] + if len(collections): + self._change_prompt() + else: print >>sys.stderr, u"Path: %s not found" % unicode(self.working_path) self.working_path.restore() return 1 - self._change_prompt() - self.objects = objects - self.collections = collections - def _fetch_objects(self, objs): objects = [] collections = [] @@ -927,7 +927,9 @@ class ReplApplication(Cmd, ConsoleApplication): return (objects, collections) def complete_cd(self, text, line, begidx, endidx): - directories = set(['..']) + directories = set() + if len(self.working_path.get()): + directories.add('..') mline = line.partition(' ')[2] offs = len(mline) - len(text) @@ -935,9 +937,7 @@ class ReplApplication(Cmd, ConsoleApplication): self.objects, self.collections = self._fetch_objects(objs=self.COLLECTION_OBJECTS) for collection in self.collections: - directories.add(collection.id) - if collection.title: - directories.add(collection.title) + directories.add(collection.id.encode(sys.stdout.encoding or locale.getpreferredencoding())) return [s[offs:] for s in directories if s.startswith(mline)]