Add object type filtering to iter_resources

This commit is contained in:
Laurent Bachelier 2012-02-05 13:30:02 +01:00
commit bfb3689456
16 changed files with 92 additions and 61 deletions

View file

@ -22,7 +22,7 @@ from __future__ import with_statement
import re import re
from weboob.capabilities.video import ICapVideo from weboob.capabilities.video import ICapVideo, BaseVideo
from weboob.tools.backend import BaseBackend, BackendConfig from weboob.tools.backend import BaseBackend, BackendConfig
from weboob.tools.value import Value from weboob.tools.value import Value
@ -71,6 +71,7 @@ class CanalplusBackend(BaseBackend, ICapVideo, ICapCollection):
OBJECTS = {CanalplusVideo: fill_video} OBJECTS = {CanalplusVideo: fill_video}
def iter_resources(self, split_path): def iter_resources(self, objs, split_path):
with self.browser: if BaseVideo in objs:
return self.browser.iter_resources(split_path) with self.browser:
return self.browser.iter_resources(split_path)

View file

@ -19,6 +19,7 @@
from weboob.tools.test import BackendTest from weboob.tools.test import BackendTest
from weboob.capabilities.video import BaseVideo
class CanalPlusTest(BackendTest): class CanalPlusTest(BackendTest):
BACKEND = 'canalplus' BACKEND = 'canalplus'
@ -29,3 +30,10 @@ class CanalPlusTest(BackendTest):
v = l[0] v = l[0]
self.backend.fillobj(v, ('url',)) self.backend.fillobj(v, ('url',))
self.assertTrue(v.url and v.url.startswith('rtmp://'), 'URL for video "%s" not found: %s' % (v.id, v.url)) self.assertTrue(v.url and v.url.startswith('rtmp://'), 'URL for video "%s" not found: %s' % (v.id, v.url))
def test_ls(self):
l = list(self.backend.iter_resources((BaseVideo, ), []))
self.assertTrue(len(l) > 0)
l = list(self.backend.iter_resources((BaseVideo, ), ['SPORT']))
self.assertTrue(len(l) > 0)

View file

@ -62,15 +62,16 @@ class NovaBackend(BaseBackend, ICapRadio, ICapCollection):
_RADIOS = {'nova': (u'Radio Nova', u'Radio nova', u'http://broadcast.infomaniak.net:80/radionova-high.mp3'), _RADIOS = {'nova': (u'Radio Nova', u'Radio nova', u'http://broadcast.infomaniak.net:80/radionova-high.mp3'),
} }
def iter_resources(self, split_path): def iter_resources(self, objs, split_path):
if len(split_path) > 0: if Radio in objs:
raise CollectionNotFound(split_path) if len(split_path) > 0:
raise CollectionNotFound(split_path)
for id in self._RADIOS.iterkeys(): for id in self._RADIOS.iterkeys():
yield self.get_radio(id) yield self.get_radio(id)
def iter_radios_search(self, pattern): def iter_radios_search(self, pattern):
for radio in self.iter_resources([]): for radio in self.iter_resources((Radio, ), []):
if pattern.lower() in radio.title.lower() or pattern.lower() in radio.description.lower(): if pattern.lower() in radio.title.lower() or pattern.lower() in radio.description.lower():
yield radio yield radio

View file

@ -19,10 +19,11 @@
from weboob.tools.test import BackendTest from weboob.tools.test import BackendTest
from weboob.capabilities.radio import Radio
class NovaTest(BackendTest): class NovaTest(BackendTest):
BACKEND = 'nova' BACKEND = 'nova'
def test_nova(self): def test_nova(self):
l = list(self.backend.iter_resources([])) l = list(self.backend.iter_resources((Radio, ), []))
self.assertTrue(len(l) > 0) self.assertTrue(len(l) > 0)

View file

@ -46,15 +46,16 @@ class OuiFMBackend(BaseBackend, ICapRadio, ICapCollection):
def create_default_browser(self): def create_default_browser(self):
return self.create_browser(parser='json') return self.create_browser(parser='json')
def iter_resources(self, split_path): def iter_resources(self, objs, split_path):
if len(split_path) > 0: if Radio in objs:
raise CollectionNotFound(split_path) if len(split_path) > 0:
raise CollectionNotFound(split_path)
for id in self._RADIOS.iterkeys(): for id in self._RADIOS.iterkeys():
yield self.get_radio(id) yield self.get_radio(id)
def iter_radios_search(self, pattern): def iter_radios_search(self, pattern):
for radio in self.iter_resources([]): for radio in self.iter_resources((Radio, ), []):
if pattern.lower() in radio.title.lower() or pattern.lower() in radio.description.lower(): if pattern.lower() in radio.title.lower() or pattern.lower() in radio.description.lower():
yield radio yield radio

View file

@ -19,10 +19,12 @@
from weboob.tools.test import BackendTest from weboob.tools.test import BackendTest
from weboob.capabilities.radio import Radio
class OuiFMTest(BackendTest): class OuiFMTest(BackendTest):
BACKEND = 'ouifm' BACKEND = 'ouifm'
def test_ouifm(self): def test_ouifm(self):
l = list(self.backend.iter_resources([])) l = list(self.backend.iter_resources((Radio, ), []))
self.assertTrue(len(l) > 0) self.assertTrue(len(l) > 0)

View file

@ -102,22 +102,23 @@ class RadioFranceBackend(BaseBackend, ICapRadio, ICapCollection, ICapVideo):
_RSS_RADIOS = ('francemusique', ) _RSS_RADIOS = ('francemusique', )
_ANTENNA_RADIOS = ('fip', ) _ANTENNA_RADIOS = ('fip', )
def iter_resources(self, split_path): def iter_resources(self, objs, split_path):
if len(split_path) == 1 and split_path[0] == 'francebleu': if Radio in objs:
for _id in sorted(self._RADIOS.iterkeys()): if len(split_path) == 1 and split_path[0] == 'francebleu':
if _id.startswith('fb'): for _id in sorted(self._RADIOS.iterkeys()):
yield self.get_radio(_id) if _id.startswith('fb'):
elif len(split_path) == 0: yield self.get_radio(_id)
for _id in sorted(self._RADIOS.iterkeys()): elif len(split_path) == 0:
if not _id.startswith('fb'): for _id in sorted(self._RADIOS.iterkeys()):
yield self.get_radio(_id) if not _id.startswith('fb'):
yield Collection('francebleu', 'France Bleu', yield self.get_radio(_id)
children=self.iter_resources(['francebleu'])) yield Collection('francebleu', 'France Bleu',
else: children=self.iter_resources(objs, ['francebleu']))
raise CollectionNotFound(split_path) else:
raise CollectionNotFound(split_path)
def iter_radios_search(self, pattern): def iter_radios_search(self, pattern):
for radio in self._flatten_resources(self.iter_resources([])): for radio in self._flatten_resources(self.iter_resources((Radio, ), [])):
if pattern.lower() in radio.title.lower() or pattern.lower() in radio.description.lower(): if pattern.lower() in radio.title.lower() or pattern.lower() in radio.description.lower():
yield radio yield radio

View file

@ -19,14 +19,20 @@
from weboob.tools.test import BackendTest from weboob.tools.test import BackendTest
from weboob.capabilities.video import BaseVideo
from weboob.capabilities.radio import Radio
class RadioFranceTest(BackendTest): class RadioFranceTest(BackendTest):
BACKEND = 'radiofrance' BACKEND = 'radiofrance'
def test_get_radios(self): def test_get_radios(self):
l = list(self.backend.iter_resources([])) l = list(self.backend.iter_resources(objs=[Radio], split_path=[]))
self.assertTrue(len(l) > 0) self.assertTrue(0 < len(l) < 30)
l = list(self.backend.iter_resources(objs=[Radio], split_path=['francebleu']))
self.assertTrue(len(l) > 30)
l = list(self.backend.iter_resources(objs=[BaseVideo], split_path=[]))
self.assertEquals(len(l), 0)
def test_get_video(self): def test_get_video(self):
# this should be available up to 24/10/2014 15h00 # this should be available up to 24/10/2014 15h00

View file

@ -94,17 +94,18 @@ class RedmineBackend(BaseBackend, ICapContent, ICapBugTracker, ICapCollection):
return self.browser.get_wiki_preview(project, page, content.content) return self.browser.get_wiki_preview(project, page, content.content)
############# CapCollection ################################################### ############# CapCollection ###################################################
def iter_resources(self, split_path): def iter_resources(self, objs, split_path):
if len(split_path) == 0: if Project in objs or Issue in objs:
return [Collection(project.id, project.name, fct=self.iter_issues) if len(split_path) == 0:
for project in self.iter_projects()] return [Collection(project.id, project.name, fct=self.iter_issues)
for project in self.iter_projects()]
if len(split_path) == 1: if len(split_path) == 1:
query = Query() query = Query()
query.project = unicode(split_path[0]) query.project = unicode(split_path[0])
return self.iter_issues(query) return self.iter_issues(query)
raise CollectionNotFound(split_path) raise CollectionNotFound(split_path)
############# CapBugTracker ################################################### ############# CapBugTracker ###################################################

View file

@ -20,7 +20,7 @@
import sys import sys
from weboob.capabilities.bank import ICapBank from weboob.capabilities.bank import ICapBank, Account, Operation
from weboob.tools.application.repl import ReplApplication from weboob.tools.application.repl import ReplApplication
from weboob.tools.application.formatters.iformatter import IFormatter from weboob.tools.application.formatters.iformatter import IFormatter
@ -142,6 +142,7 @@ class Boobank(ReplApplication):
'list': 'account_list', 'list': 'account_list',
'transfer': 'transfer', 'transfer': 'transfer',
} }
COLLECTION_OBJECTS = (Account, Operation, )
def _complete_account(self, exclude=None): def _complete_account(self, exclude=None):
if exclude: if exclude:

View file

@ -21,7 +21,7 @@
from datetime import timedelta from datetime import timedelta
import sys import sys
from weboob.capabilities.bugtracker import ICapBugTracker, Query, Update from weboob.capabilities.bugtracker import ICapBugTracker, Query, Update, Project, Issue
from weboob.tools.application.repl import ReplApplication from weboob.tools.application.repl import ReplApplication
from weboob.tools.application.formatters.iformatter import IFormatter from weboob.tools.application.formatters.iformatter import IFormatter
from weboob.tools.misc import html2text from weboob.tools.misc import html2text
@ -93,6 +93,7 @@ class BoobTracker(ReplApplication):
'search': 'issues_list', 'search': 'issues_list',
'ls': 'issues_list', 'ls': 'issues_list',
} }
COLLECTION_OBJECTS = (Project, Issue, )
def add_application_options(self, group): def add_application_options(self, group):
group.add_option('--author') group.add_option('--author')

View file

@ -20,7 +20,7 @@
import sys import sys
from weboob.capabilities.radio import ICapRadio from weboob.capabilities.radio import ICapRadio, Radio
from weboob.capabilities.base import NotLoaded from weboob.capabilities.base import NotLoaded
from weboob.tools.application.repl import ReplApplication from weboob.tools.application.repl import ReplApplication
from weboob.tools.application.media_player import InvalidMediaPlayer, MediaPlayer, MediaPlayerNotFound from weboob.tools.application.media_player import InvalidMediaPlayer, MediaPlayer, MediaPlayerNotFound
@ -66,6 +66,7 @@ class Radioob(ReplApplication):
COMMANDS_FORMATTERS = {'ls': 'radio_list', COMMANDS_FORMATTERS = {'ls': 'radio_list',
'search': 'radio_list', 'search': 'radio_list',
} }
COLLECTION_OBJECTS = (Radio, )
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
ReplApplication.__init__(self, *args, **kwargs) ReplApplication.__init__(self, *args, **kwargs)

View file

@ -23,7 +23,7 @@ import subprocess
import sys import sys
import os import os
from weboob.capabilities.video import ICapVideo from weboob.capabilities.video import ICapVideo, BaseVideo
from weboob.capabilities.base import NotLoaded from weboob.capabilities.base import NotLoaded
from weboob.tools.application.repl import ReplApplication from weboob.tools.application.repl import ReplApplication
from weboob.tools.application.media_player import InvalidMediaPlayer, MediaPlayer, MediaPlayerNotFound from weboob.tools.application.media_player import InvalidMediaPlayer, MediaPlayer, MediaPlayerNotFound
@ -66,6 +66,7 @@ class Videoob(ReplApplication):
EXTRA_FORMATTERS = {'video_list': VideoListFormatter} EXTRA_FORMATTERS = {'video_list': VideoListFormatter}
COMMANDS_FORMATTERS = {'search': 'video_list', COMMANDS_FORMATTERS = {'search': 'video_list',
'ls': 'video_list'} 'ls': 'video_list'}
COLLECTION_OBJECTS = (BaseVideo, )
nsfw = True nsfw = True

View file

@ -74,11 +74,12 @@ class Transfer(CapBaseObject):
self.add_field('recipient', (int, long, basestring)) self.add_field('recipient', (int, long, basestring))
class ICapBank(ICapCollection): class ICapBank(ICapCollection):
def iter_resources(self, split_path): def iter_resources(self, objs, split_path):
if len(split_path) > 0: if Account in objs:
raise CollectionNotFound(split_path) if len(split_path) > 0:
raise CollectionNotFound(split_path)
return self.iter_accounts() return self.iter_accounts()
def iter_accounts(self): def iter_accounts(self):
raise NotImplementedError() raise NotImplementedError()

View file

@ -91,7 +91,7 @@ class ICapCollection(IBaseCap):
lst.append(resource) lst.append(resource)
return lst return lst
def iter_resources(self, split_path): def iter_resources(self, objs, split_path):
""" """
split_path is a list, either empty (root path) or with one or many split_path is a list, either empty (root path) or with one or many
components. components.

View file

@ -80,6 +80,9 @@ class ReplApplication(Cmd, ConsoleApplication):
DEFAULT_FORMATTER = 'multiline' DEFAULT_FORMATTER = 'multiline'
COMMANDS_FORMATTERS = {} COMMANDS_FORMATTERS = {}
# Objects to allow in do_ls / do_cd
COLLECTION_OBJECTS = tuple()
weboob_commands = set(['backends', 'condition', 'count', 'formatter', 'inspect', 'logging', 'select', 'quit', 'ls', 'cd']) weboob_commands = set(['backends', 'condition', 'count', 'formatter', 'inspect', 'logging', 'select', 'quit', 'ls', 'cd'])
hidden_commands = set(['EOF']) hidden_commands = set(['EOF'])
@ -849,7 +852,7 @@ class ReplApplication(Cmd, ConsoleApplication):
List objects in current path. List objects in current path.
""" """
self.objects = self._fetch_objects() self.objects = 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):
@ -879,21 +882,22 @@ class ReplApplication(Cmd, ConsoleApplication):
else: else:
self.working_path.extend(line) self.working_path.extend(line)
objects = self._fetch_objects() objects = self._fetch_objects(objs=self.COLLECTION_OBJECTS)
if len(objects) == 0: if len(objects) == 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.objects = objects
self._change_prompt() self._change_prompt()
def _fetch_objects(self): def _fetch_objects(self, objs):
objects = [] objects = []
path = self.working_path.get() split_path = self.working_path.get()
try: try:
for backend, res in self.do('iter_resources', path, caps=ICapCollection): for backend, res in self.do('iter_resources',
objs=objs, split_path=split_path,
caps=ICapCollection):
objects.append(res) objects.append(res)
except CallErrors, errors: except CallErrors, errors:
for backend, error, backtrace in errors.errors: for backend, error, backtrace in errors.errors:
@ -910,7 +914,7 @@ class ReplApplication(Cmd, ConsoleApplication):
offs = len(mline) - len(text) offs = len(mline) - len(text)
if len(self.objects) == 0: if len(self.objects) == 0:
self.objects = self._fetch_objects() self.objects = self._fetch_objects(objs=self.COLLECTION_OBJECTS)
for obj in self.objects: for obj in self.objects:
if isinstance(obj, Collection): if isinstance(obj, Collection):