diff -r 000000000000 -r 7c0001cacf8e src/pyams_content/component/links/container.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/component/links/container.py Thu Oct 08 13:37:29 2015 +0200 @@ -0,0 +1,123 @@ +# +# Copyright (c) 2008-2015 Thierry Florac +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# + +__docformat__ = 'restructuredtext' + + +# import standard library + +# import interfaces +from pyams_content.component.links.interfaces import ILinkContainer, ILinkContainerTarget, LINK_CONTAINER_KEY, \ + ILinkLinksContainer, LINK_LINKS_CONTAINER_KEY, ILinkLinksContainerTarget +from pyams_i18n.interfaces import II18n +from zope.annotation.interfaces import IAnnotations +from zope.location.interfaces import ISublocations +from zope.schema.interfaces import IVocabularyFactory +from zope.traversing.interfaces import ITraversable + +# import packages +from persistent import Persistent +from persistent.list import PersistentList +from pyams_utils.adapter import adapter_config, ContextAdapter +from pyams_utils.traversing import get_parent +from pyramid.threadlocal import get_current_registry +from zope.container.contained import Contained +from zope.container.folder import Folder +from zope.interface import implementer, provider +from zope.lifecycleevent import ObjectCreatedEvent +from zope.location import locate +from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm, getVocabularyRegistry + + +@implementer(ILinkContainer) +class LinkContainer(Folder): + """Links container""" + + last_id = 1 + + def __setitem__(self, key, value): + key = str(self.last_id) + super(LinkContainer, self).__setitem__(key, value) + self.last_id += 1 + + +@adapter_config(context=ILinkContainerTarget, provides=ILinkContainer) +def link_container_factory(target): + """Links container factory""" + annotations = IAnnotations(target) + container = annotations.get(LINK_CONTAINER_KEY) + if container is None: + container = annotations[LINK_CONTAINER_KEY] = LinkContainer() + get_current_registry().notify(ObjectCreatedEvent(container)) + locate(container, target, '++links++') + return container + + +@adapter_config(name='links', context=ILinkContainerTarget, provides=ITraversable) +class LinkContainerNamespace(ContextAdapter): + """++links++ namespace adapter""" + + def traverse(self, name, furtherpath=None): + return ILinkContainer(self.context) + + +@adapter_config(name='links', context=ILinkContainerTarget, provides=ISublocations) +class LinkContainerSublocations(ContextAdapter): + """Links container sublocations""" + + def sublocations(self): + return ILinkContainer(self.context).values() + + +@provider(IVocabularyFactory) +class LinkContainerLinksVocabulary(SimpleVocabulary): + """Links container links vocabulary""" + + def __init__(self, context): + target = get_parent(context, ILinkContainerTarget) + terms = [SimpleTerm(link.__name__, title=II18n(link).query_attribute('title')) + for link in ILinkContainer(target).values()] + super(LinkContainerLinksVocabulary, self).__init__(terms) + +getVocabularyRegistry().register('PyAMS content links', LinkContainerLinksVocabulary) + + +# +# Link links container +# + +@implementer(ILinkLinksContainer) +class LinkLinksContainer(Persistent, Contained): + """Links links container""" + + def __init__(self): + self.links = PersistentList() + + +@adapter_config(context=ILinkLinksContainerTarget, provides=ILinkLinksContainer) +def link_links_container_factory(target): + """Links links container factory""" + annotations = IAnnotations(target) + container = annotations.get(LINK_LINKS_CONTAINER_KEY) + if container is None: + container = annotations[LINK_LINKS_CONTAINER_KEY] = LinkLinksContainer() + get_current_registry().notify(ObjectCreatedEvent(container)) + locate(container, target, '++links-links++') + return container + + +@adapter_config(name='links-links', context=ILinkLinksContainerTarget, provides=ITraversable) +class LinkLinksContainerNamespace(ContextAdapter): + """++links-links++ namespace adapter""" + + def traverse(self, name, furtherpath=None): + return ILinkLinksContainer(self.context)