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
100 lines
3.2 KiB
Python
100 lines
3.2 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
# Copyright(C) 2010-2012 Nicolas Duhamel, Laurent Bachelier
|
|
#
|
|
# This file is part of weboob.
|
|
#
|
|
# weboob is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU Affero General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# weboob is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU Affero General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
from .base import IBaseCap
|
|
|
|
__all__ = ['ICapCollection', 'Collection', 'CollectionNotFound']
|
|
|
|
|
|
class CollectionNotFound(Exception):
|
|
def __init__(self, split_path=None):
|
|
if split_path is not None:
|
|
msg = 'Collection not found: %s' % '/'.join(split_path)
|
|
else:
|
|
msg = 'Collection not found'
|
|
Exception.__init__(self, msg)
|
|
|
|
|
|
class Children(object):
|
|
"""
|
|
Dynamic property of a Collection.
|
|
Returns a list, either by calling a function or because
|
|
it already has the list.
|
|
"""
|
|
def __get__(self, obj, type=None):
|
|
if obj._children is None:
|
|
if callable(obj._fct):
|
|
obj._children = obj._fct(obj.id)
|
|
return obj._children or []
|
|
|
|
|
|
class Collection(object):
|
|
"""
|
|
Collection of objects.
|
|
Should provide a way to be filled, either by providing the children
|
|
right away, or a function. The function will be called once with the id
|
|
as an argument if there were no children provided, but only on demand.
|
|
It can be found in a list of objects, it indicantes a "folder"
|
|
you can hop into.
|
|
id and title should be unicode.
|
|
"""
|
|
children = Children()
|
|
backend = None
|
|
|
|
def __init__(self, _id=None, title=None, children=None, fct=None):
|
|
self.id = _id
|
|
self.title = title
|
|
# It does not make sense to have both at init
|
|
assert not (fct is not None and children is not None)
|
|
self._children = children
|
|
self._fct = fct
|
|
|
|
def __iter__(self):
|
|
return iter(self.children)
|
|
|
|
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
|
|
else:
|
|
return u'Unknown collection'
|
|
|
|
|
|
class ICapCollection(IBaseCap):
|
|
def _flatten_resources(self, resources, clean_only=False):
|
|
"""
|
|
Expand all collections in a list
|
|
If clean_only is True, do not expand collections, only remove them.
|
|
"""
|
|
lst = list()
|
|
for resource in resources:
|
|
if isinstance(resource, (list, Collection)):
|
|
if not clean_only:
|
|
lst.extend(self._flatten_resources(resource))
|
|
else:
|
|
lst.append(resource)
|
|
return lst
|
|
|
|
def iter_resources(self, objs, split_path):
|
|
"""
|
|
split_path is a list, either empty (root path) or with one or many
|
|
components.
|
|
"""
|
|
raise NotImplementedError()
|