diff -r 000000000000 -r 7c0001cacf8e src/pyams_content/component/gallery/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/component/gallery/__init__.py Thu Oct 08 13:37:29 2015 +0200 @@ -0,0 +1,183 @@ +# +# 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.gallery.interfaces import IGalleryFileInfo, GALLERY_FILE_INFO_KEY, IGallery, IGalleryFile +from pyams_content.shared.common.interfaces import IWfSharedContent +from pyams_file.interfaces import IMediaFile +from pyams_form.interfaces.form import IFormContextPermissionChecker +from pyams_i18n.interfaces import II18n +from zope.annotation.interfaces import IAnnotations +from zope.lifecycleevent.interfaces import IObjectAddedEvent, IObjectModifiedEvent, IObjectRemovedEvent +from zope.traversing.interfaces import ITraversable + +# import packages +from persistent import Persistent +from pyams_file.property import FileProperty +from pyams_utils.adapter import adapter_config, ContextAdapter +from pyams_utils.container import BTreeOrderedContainer +from pyams_utils.traversing import get_parent +from pyramid.events import subscriber +from pyramid.threadlocal import get_current_registry +from zope.lifecycleevent import ObjectCreatedEvent, ObjectModifiedEvent +from zope.container.contained import Contained +from zope.interface import implementer +from zope.location import locate +from zope.schema.fieldproperty import FieldProperty + + +# +# Gallery file +# + +@implementer(IGalleryFileInfo) +class GalleryFileInfo(Persistent, Contained): + """Gallery file info""" + + title = FieldProperty(IGalleryFileInfo['title']) + description = FieldProperty(IGalleryFileInfo['description']) + author = FieldProperty(IGalleryFileInfo['author']) + author_comments = FieldProperty(IGalleryFileInfo['author_comments']) + sound = FileProperty(IGalleryFileInfo['sound']) + sound_title = FieldProperty(IGalleryFileInfo['sound_title']) + sound_description = FieldProperty(IGalleryFileInfo['sound_description']) + pif_number = FieldProperty(IGalleryFileInfo['pif_number']) + visible = FieldProperty(IGalleryFileInfo['visible']) + + def get_title(self, request=None): + return II18n(self).query_attribute('title', request=request) + + +@adapter_config(context=IGalleryFile, provides=IGalleryFileInfo) +def media_gallery_info_factory(file): + """Gallery file gallery info factory""" + annotations = IAnnotations(file) + info = annotations.get(GALLERY_FILE_INFO_KEY) + if info is None: + info = annotations[GALLERY_FILE_INFO_KEY] = GalleryFileInfo() + get_current_registry().notify(ObjectCreatedEvent(info)) + locate(info, file, '++gallery-info++') + return info + + +@adapter_config(name='gallery-info', context=IGalleryFile, provides=ITraversable) +class MediaGalleryInfoTraverser(ContextAdapter): + """Gallery file gallery info adapter""" + + def traverse(self, name, furtherpath=None): + return IGalleryFileInfo(self.context) + + +@adapter_config(context=IGalleryFile, provides=IFormContextPermissionChecker) +class GalleryFilePermissionChecker(ContextAdapter): + """Gallery file permission checker""" + + @property + def edit_permission(self): + content = get_parent(self.context, IWfSharedContent) + return IFormContextPermissionChecker(content).edit_permission + + +@adapter_config(context=IGalleryFileInfo, provides=IFormContextPermissionChecker) +class GalleryFileInfoPermissionChecker(ContextAdapter): + """Gallery file info permission checker""" + + @property + def edit_permission(self): + content = get_parent(self.context, IWfSharedContent) + return IFormContextPermissionChecker(content).edit_permission + + +@subscriber(IObjectAddedEvent, context_selector=IMediaFile) +def handle_added_media(event): + """Handle added media file""" + content = get_parent(event.object, IWfSharedContent) + if content is not None: + get_current_registry().notify(ObjectModifiedEvent(content)) + + +@subscriber(IObjectModifiedEvent, context_selector=IMediaFile) +def handle_modified_media(event): + """Handle modified media file""" + content = get_parent(event.object, IWfSharedContent) + if content is not None: + get_current_registry().notify(ObjectModifiedEvent(content)) + + +@subscriber(IObjectRemovedEvent, context_selector=IMediaFile) +def handle_removed_media(event): + """Handle removed media file""" + content = get_parent(event.object, IWfSharedContent) + if content is not None: + get_current_registry().notify(ObjectModifiedEvent(content)) + + +# +# Gallery +# + +@implementer(IGallery) +class Gallery(BTreeOrderedContainer): + """Gallery persistent class""" + + title = FieldProperty(IGallery['title']) + description = FieldProperty(IGallery['description']) + visible = FieldProperty(IGallery['visible']) + + last_id = 1 + + def __setitem__(self, key, value): + key = str(self.last_id) + super(Gallery, self).__setitem__(key, value) + self.last_id += 1 + + def get_visible_images(self): + return [image for image in self.values() if image.visible] + + +@adapter_config(context=IGallery, provides=IFormContextPermissionChecker) +class GalleryPermissionChecker(ContextAdapter): + """Gallery permission checker""" + + @property + def edit_permission(self): + content = get_parent(self.context, IWfSharedContent) + return IFormContextPermissionChecker(content).edit_permission + + +@subscriber(IObjectAddedEvent, context_selector=IGallery) +def handle_added_gallery(event): + """Handle added gallery""" + content = get_parent(event.object, IWfSharedContent) + if content is not None: + get_current_registry().notify(ObjectModifiedEvent(content)) + + +@subscriber(IObjectModifiedEvent, context_selector=IGallery) +def handle_modified_gallery(event): + """Handle modified gallery""" + content = get_parent(event.object, IWfSharedContent) + if content is not None: + get_current_registry().notify(ObjectModifiedEvent(content)) + + +@subscriber(IObjectRemovedEvent, context_selector=IGallery) +def handle_removed_gallery(event): + """Handle removed gallery""" + content = get_parent(event.object, IWfSharedContent) + if content is not None: + get_current_registry().notify(ObjectModifiedEvent(content))