diff -r 000000000000 -r 7c0001cacf8e src/pyams_content/component/gallery/zmi/gallery.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/component/gallery/zmi/gallery.py Thu Oct 08 13:37:29 2015 +0200 @@ -0,0 +1,241 @@ +# +# 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 json + +# import interfaces +from pyams_content.component.gallery.interfaces import IGallery, IGalleryFileInfo, IGalleryFile +from pyams_content.component.gallery.zmi.interfaces import IGalleryImageAddFields +from pyams_content.interfaces import MANAGE_CONTENT_PERMISSION +from pyams_file.interfaces.archive import IArchiveExtractor +from pyams_form.interfaces.form import IWidgetsPrefixViewletsManager +from pyams_i18n.interfaces import II18n +from pyams_skin.interfaces.viewlet import IWidgetTitleViewletManager, IContextActions +from pyams_skin.layer import IPyAMSLayer +from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION +from z3c.form.interfaces import NOT_CHANGED + +# import packages +from pyams_content.shared.common.zmi import WfSharedContentPermissionMixin +from pyams_file.file import get_magic_content_type, FileFactory +from pyams_file.zmi.file import FilePropertiesAction +from pyams_form.form import AJAXAddForm, AJAXEditForm +from pyams_pagelet.pagelet import pagelet_config +from pyams_skin.viewlet.toolbar import ToolbarAction, ToolbarMenuDivider, JsToolbarMenuItem +from pyams_template.template import template_config +from pyams_utils.registry import query_utility +from pyams_utils.url import absolute_url +from pyams_viewlet.viewlet import viewlet_config, Viewlet +from pyams_zmi.form import AdminDialogEditForm, AdminDialogAddForm, AdminDialogDisplayForm +from pyramid.renderers import render_to_response +from pyramid.view import view_config +from z3c.form import field +from zope.interface import alsoProvides, Interface +from zope.lifecycleevent import ObjectCreatedEvent + +from pyams_content import _ + + +@pagelet_config(name='contents.html', context=IGallery, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION) +class GalleryContentForm(AdminDialogDisplayForm): + """Gallery contents form""" + + legend = _("Update gallery contents") + dialog_class = 'modal-max' + + fields = field.Fields(Interface) + show_widget_title = True + + +@viewlet_config(name='add-image.menu', context=IGallery, view=GalleryContentForm, manager=IWidgetTitleViewletManager) +class GalleryImageAddMenu(WfSharedContentPermissionMixin, ToolbarAction): + """Gallery image add menu""" + + label = _("Add image(s)") + + url = 'add-image.html' + modal_target = True + stop_propagation = True + + +@pagelet_config(name='add-image.html', context=IGallery, layer=IPyAMSLayer, permission=MANAGE_CONTENT_PERMISSION) +class GalleryImageAddForm(AdminDialogAddForm): + """Gallery image add form""" + + legend = _("Add image(s)") + icon_css_class = 'fa -fa-fw fa-picture-o' + + fields = field.Fields(IGalleryImageAddFields) + ajax_handler = 'add-image.json' + + def updateWidgets(self, prefix=None): + super(GalleryImageAddForm, self).updateWidgets(prefix) + self.widgets['author_comments'].label_css_class = 'textarea' + + def create(self, data): + medias = [] + images = data['images_data'] + if images and (images is not NOT_CHANGED): + if isinstance(images, (list, tuple)): + images = images[1] + if hasattr(images, 'seek'): + images.seek(0) + registry = self.request.registry + content_type = get_magic_content_type(images) + if hasattr(images, 'seek'): + images.seek(0) + extractor = query_utility(IArchiveExtractor, name=content_type.decode()) + if extractor is not None: + extractor.initialize(images) + for content, filename in extractor.get_contents(): + media = FileFactory(content) + registry.notify(ObjectCreatedEvent(media)) + medias.append(media) + else: + media = FileFactory(images) + registry.notify(ObjectCreatedEvent(media)) + medias.append(media) + for media in medias: + alsoProvides(media, IGalleryFile) + IGalleryFileInfo(media).author = data.get('author') + IGalleryFileInfo(media).author_comments = data.get('author_comments') + self.context['none'] = media + return None + + +@view_config(name='add-image.json', context=IGallery, request_type=IPyAMSLayer, + permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True) +class GalleryImageAJAXAddForm(AJAXAddForm, GalleryImageAddForm): + """Gallery image add form, JSON renderer""" + + def get_ajax_output(self, changes): + return {'status': 'reload', + 'location': absolute_url(self.context, self.request, 'get-gallery-images.html'), + 'target': '#gallery-images'} + + +@viewlet_config(name='gallery-images', context=IGallery, view=GalleryContentForm, manager=IWidgetsPrefixViewletsManager) +@template_config(template='templates/gallery-images.pt', layer=IPyAMSLayer) +class GalleryImagesViewlet(Viewlet): + """Gallery images viewlet""" + + def get_info(self, image): + return IGalleryFileInfo(image) + + def get_title(self, image): + return II18n(IGalleryFileInfo(image)).query_attribute('title', request=self.request) + + +@view_config(name='get-gallery-images.html', context=IGallery, request_type=IPyAMSLayer, + permission=VIEW_SYSTEM_PERMISSION) +class GalleryImagesView(WfSharedContentPermissionMixin): + """Gallery images view""" + + def __init__(self, context, request): + self.context = context + self.request = request + + def __call__(self): + return render_to_response('templates/gallery-images.pt', {'view': self}, request=self.request) + + def get_info(self, image): + return IGalleryFileInfo(image) + + def get_title(self, image): + return II18n(IGalleryFileInfo(image)).query_attribute('title', request=self.request) + + +@view_config(name='set-images-order.json', context=IGallery, request_type=IPyAMSLayer, + permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True) +def set_images_order(request): + """Set gallery images order""" + images_names = json.loads(request.params.get('images')) + request.context.updateOrder(images_names) + return {'status': 'success'} + + +@viewlet_config(name='file.properties.action', context=IGalleryFile, layer=IPyAMSLayer, view=Interface, + manager=IContextActions, permission=VIEW_SYSTEM_PERMISSION, weight=1) +class GalleryFilePropertiesAction(FilePropertiesAction): + """Media properties action""" + + url = 'gallery-file-properties.html' + + +@pagelet_config(name='gallery-file-properties.html', context=IGalleryFile, layer=IPyAMSLayer, + permission=VIEW_SYSTEM_PERMISSION) +class GalleryFilePropertiesEditForm(AdminDialogEditForm): + """Gallery file properties edit form""" + + legend = _("Update image properties") + icon_css_class = 'fa fa-fw fa-edit' + + fields = field.Fields(IGalleryFileInfo) + ajax_handler = 'gallery-file-properties.json' + + def getContent(self): + return IGalleryFileInfo(self.context) + + @property + def title(self): + return II18n(self.getContent()).query_attribute('title', request=self.request) + + def updateWidgets(self, prefix=None): + super(GalleryFilePropertiesEditForm, self).updateWidgets(prefix) + self.widgets['description'].label_css_class = 'textarea' + self.widgets['author_comments'].label_css_class = 'textarea' + self.widgets['sound_description'].label_css_class = 'textarea' + + +@view_config(name='gallery-file-properties.json', context=IGalleryFile, request_type=IPyAMSLayer, + permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True) +class GalleryFileInfoPropertiesAJAXEditForm(AJAXEditForm, GalleryFilePropertiesEditForm): + """Gallery file properties edit form, JSON renderer""" + + +@viewlet_config(name='gallery-file-remover.divider', context=IGalleryFile, layer=IPyAMSLayer, view=Interface, + manager=IContextActions, weight=89) +class GalleryFileRemoverDivider(WfSharedContentPermissionMixin, ToolbarMenuDivider): + """Gallery file remover divider""" + + +@viewlet_config(name='gallery-file-remover.action', context=IGalleryFile, layer=IPyAMSLayer, view=Interface, + manager=IContextActions, weight=90) +class GalleryFileRemoverAction(WfSharedContentPermissionMixin, JsToolbarMenuItem): + """Gallery file remover action""" + + label = _("Remove image...") + label_css_class = 'fa fa-fw fa-trash' + + url = 'PyAMS_content.galleries.removeFile' + + +@view_config(name='delete-element.json', context=IGallery, request_type=IPyAMSLayer, + permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True) +def delete_gallery_element(request): + """Delete gallery element""" + translate = request.localizer.translate + name = request.params.get('object_name') + if not name: + return {'status': 'message', + 'messagebox': {'status': 'error', + 'content': translate(_("No provided object_name argument!"))}} + if name not in request.context: + return {'status': 'message', + 'messagebox': {'status': 'error', + 'content': translate(_("Given image name doesn't exist!"))}} + del request.context[name] + return {'status': 'success'}