src/pyams_content/component/gallery/zmi/file.py
changeset 363 86d1a240d4dc
parent 316 b50158f7050d
child 365 e956535074d3
equal deleted inserted replaced
362:8fc21a7ef206 363:86d1a240d4dc
     7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
     7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
     8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
     9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
    10 # FOR A PARTICULAR PURPOSE.
    10 # FOR A PARTICULAR PURPOSE.
    11 #
    11 #
    12 from pyams_content.shared.common import IWfSharedContent
       
    13 from pyams_form.interfaces.form import IFormContextPermissionChecker
       
    14 
    12 
    15 __docformat__ = 'restructuredtext'
    13 __docformat__ = 'restructuredtext'
    16 
    14 
    17 
    15 
    18 # import standard library
    16 # import standard library
    19 
    17 
    20 # import interfaces
    18 # import interfaces
    21 from pyams_content.component.gallery.interfaces import IGallery, IGalleryFile
    19 from pyams_content.component.gallery.interfaces import IGallery, IGalleryFile
    22 from pyams_content.component.gallery.zmi.interfaces import IGalleryImageAddFields, IGalleryImagesView
    20 from pyams_content.component.gallery.zmi.interfaces import IGalleryMediasAddFields, IGalleryContentsView
    23 from pyams_content.interfaces import MANAGE_CONTENT_PERMISSION
    21 from pyams_content.interfaces import MANAGE_CONTENT_PERMISSION
    24 from pyams_file.interfaces.archive import IArchiveExtractor
    22 from pyams_file.interfaces.archive import IArchiveExtractor
       
    23 from pyams_form.interfaces.form import IFormContextPermissionChecker
    25 from pyams_i18n.interfaces import II18n
    24 from pyams_i18n.interfaces import II18n
    26 from pyams_skin.interfaces.viewlet import IWidgetTitleViewletManager, IContextActions
    25 from pyams_skin.interfaces.viewlet import IWidgetTitleViewletManager, IContextActions
    27 from pyams_skin.layer import IPyAMSLayer
    26 from pyams_skin.layer import IPyAMSLayer
    28 from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION, FORBIDDEN_PERMISSION
    27 from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION, FORBIDDEN_PERMISSION
    29 from z3c.form.interfaces import NOT_CHANGED
    28 from z3c.form.interfaces import NOT_CHANGED
    30 from zope.schema.interfaces import WrongType
    29 from zope.schema.interfaces import WrongType
    31 
    30 
    32 # import packages
    31 # import packages
    33 from pyams_content.component.gallery.file import GalleryFile
    32 from pyams_content.component.gallery.file import GalleryFile
       
    33 from pyams_content.shared.common import IWfSharedContent
    34 from pyams_content.shared.common.zmi import WfSharedContentPermissionMixin
    34 from pyams_content.shared.common.zmi import WfSharedContentPermissionMixin
    35 from pyams_file.file import get_magic_content_type
    35 from pyams_file.file import get_magic_content_type
    36 from pyams_file.zmi.file import FilePropertiesAction
    36 from pyams_file.zmi.file import FilePropertiesAction
    37 from pyams_form.form import AJAXAddForm, AJAXEditForm
    37 from pyams_form.form import AJAXAddForm, AJAXEditForm
    38 from pyams_form.group import NamedWidgetsGroup
    38 from pyams_form.group import NamedWidgetsGroup
    48 from zope.lifecycleevent import ObjectCreatedEvent
    48 from zope.lifecycleevent import ObjectCreatedEvent
    49 
    49 
    50 from pyams_content import _
    50 from pyams_content import _
    51 
    51 
    52 
    52 
    53 @viewlet_config(name='add-image.menu', context=IGallery, view=IGalleryImagesView, manager=IWidgetTitleViewletManager)
    53 @viewlet_config(name='add-media.menu', context=IGallery, view=IGalleryContentsView, manager=IWidgetTitleViewletManager)
    54 class GalleryImageAddMenu(WfSharedContentPermissionMixin, ToolbarAction):
    54 class GalleryMediaAddMenu(WfSharedContentPermissionMixin, ToolbarAction):
    55     """Gallery image add menu"""
    55     """Gallery media add menu"""
    56 
    56 
    57     label = _("Add image(s)")
    57     label = _("Add media(s)")
    58 
    58 
    59     url = 'add-image.html'
    59     url = 'add-media.html'
    60     modal_target = True
    60     modal_target = True
    61     stop_propagation = True
    61     stop_propagation = True
    62 
    62 
    63 
    63 
    64 @pagelet_config(name='add-image.html', context=IGallery, layer=IPyAMSLayer, permission=MANAGE_CONTENT_PERMISSION)
    64 @pagelet_config(name='add-media.html', context=IGallery, layer=IPyAMSLayer, permission=MANAGE_CONTENT_PERMISSION)
    65 class GalleryImageAddForm(AdminDialogAddForm):
    65 class GalleryMediaAddForm(AdminDialogAddForm):
    66     """Gallery image add form"""
    66     """Gallery media add form"""
    67 
    67 
    68     legend = _("Add image(s)")
    68     legend = _("Add media(s)")
    69     icon_css_class = 'fa -fa-fw fa-picture-o'
    69     icon_css_class = 'fa -fa-fw fa-picture-o'
    70 
    70 
    71     fields = field.Fields(IGalleryImageAddFields)
    71     fields = field.Fields(IGalleryMediasAddFields)
    72     ajax_handler = 'add-image.json'
    72     ajax_handler = 'add-media.json'
    73 
    73 
    74     def updateWidgets(self, prefix=None):
    74     def updateWidgets(self, prefix=None):
    75         super(GalleryImageAddForm, self).updateWidgets(prefix)
    75         super(GalleryMediaAddForm, self).updateWidgets(prefix)
    76         if 'author_comments' in self.widgets:
    76         if 'author_comments' in self.widgets:
    77             self.widgets['author_comments'].widget_css_class = 'textarea'
    77             self.widgets['author_comments'].widget_css_class = 'textarea'
    78 
    78 
    79     def create(self, data):
    79     def create(self, data):
    80         medias = []
    80         medias = []
    81         images = data['images_data']
    81         medias_data = data['medias_data']
    82         if images and (images is not NOT_CHANGED):
    82         if medias_data and (medias_data is not NOT_CHANGED):
    83             filename = None
    83             filename = None
    84             if isinstance(images, (list, tuple)):
    84             if isinstance(medias_data, (list, tuple)):
    85                 filename, images = images
    85                 filename, medias_data = medias_data
    86             if hasattr(images, 'seek'):
    86             if hasattr(medias_data, 'seek'):
    87                 images.seek(0)
    87                 medias_data.seek(0)
    88             registry = self.request.registry
    88             registry = self.request.registry
    89             content_type = get_magic_content_type(images)
    89             content_type = get_magic_content_type(medias_data)
    90             if isinstance(content_type, bytes):
    90             if isinstance(content_type, bytes):
    91                 content_type = content_type.decode()
    91                 content_type = content_type.decode()
    92             if hasattr(images, 'seek'):
    92             if hasattr(medias_data, 'seek'):
    93                 images.seek(0)
    93                 medias_data.seek(0)
    94             extractor = query_utility(IArchiveExtractor, name=content_type)
    94             extractor = query_utility(IArchiveExtractor, name=content_type)
    95             if extractor is not None:
    95             if extractor is not None:
    96                 extractor.initialize(images)
    96                 extractor.initialize(medias_data)
    97                 for content, filename in extractor.get_contents():
    97                 for content, filename in extractor.get_contents():
    98                     try:
    98                     try:
    99                         media = GalleryFile()
    99                         media = GalleryFile()
   100                         media.data = filename, content
   100                         media.data = filename, content
   101                     except WrongType:
   101                     except WrongType:
   104                         registry.notify(ObjectCreatedEvent(media))
   104                         registry.notify(ObjectCreatedEvent(media))
   105                         medias.append(media)
   105                         medias.append(media)
   106             else:
   106             else:
   107                 try:
   107                 try:
   108                     media = GalleryFile()
   108                     media = GalleryFile()
   109                     media.data = filename, images if filename else images
   109                     media.data = filename, medias_data if filename else medias_data
   110                 except WrongType:
   110                 except WrongType:
   111                     pass
   111                     pass
   112                 else:
   112                 else:
   113                     registry.notify(ObjectCreatedEvent(media))
   113                     registry.notify(ObjectCreatedEvent(media))
   114                     medias.append(media)
   114                     medias.append(media)
   117                 media.author_comments = data.get('author_comments')
   117                 media.author_comments = data.get('author_comments')
   118                 self.context.append(media)
   118                 self.context.append(media)
   119         return None
   119         return None
   120 
   120 
   121 
   121 
   122 @view_config(name='add-image.json', context=IGallery, request_type=IPyAMSLayer,
   122 @view_config(name='add-media.json', context=IGallery, request_type=IPyAMSLayer,
   123              permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
   123              permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
   124 class GalleryImageAJAXAddForm(AJAXAddForm, GalleryImageAddForm):
   124 class GalleryMediaAJAXAddForm(AJAXAddForm, GalleryMediaAddForm):
   125     """Gallery image add form, JSON renderer"""
   125     """Gallery media add form, JSON renderer"""
   126 
   126 
   127     def get_ajax_output(self, changes):
   127     def get_ajax_output(self, changes):
   128         return {'status': 'reload',
   128         return {'status': 'reload',
   129                 'location': absolute_url(self.context, self.request, 'get-gallery-images.html'),
   129                 'location': absolute_url(self.context, self.request, 'get-gallery-medias.html'),
   130                 'target': '#gallery_images_{0}'.format(self.context.__name__)}
   130                 'target': '#gallery_medias_{0}'.format(self.context.__name__)}
   131 
   131 
   132 
   132 
   133 @viewlet_config(name='file.showhide.action', context=IGalleryFile, layer=IPyAMSLayer, view=IGalleryImagesView,
   133 @viewlet_config(name='file.showhide.action', context=IGalleryFile, layer=IPyAMSLayer, view=IGalleryContentsView,
   134                 manager=IContextActions, permission=VIEW_SYSTEM_PERMISSION, weight=1)
   134                 manager=IContextActions, permission=VIEW_SYSTEM_PERMISSION, weight=1)
   135 class GalleryFileShowHideAction(WfSharedContentPermissionMixin, JsToolbarActionItem):
   135 class GalleryFileShowHideAction(WfSharedContentPermissionMixin, JsToolbarActionItem):
   136     """Gallery file show/hide action"""
   136     """Gallery file show/hide action"""
   137 
   137 
   138     edit_permission = FORBIDDEN_PERMISSION
   138     edit_permission = FORBIDDEN_PERMISSION
   144             self.edit_permission = IFormContextPermissionChecker(content).edit_permission
   144             self.edit_permission = IFormContextPermissionChecker(content).edit_permission
   145 
   145 
   146     @property
   146     @property
   147     def label(self):
   147     def label(self):
   148         if self.request.has_permission(self.edit_permission, context=self.context):
   148         if self.request.has_permission(self.edit_permission, context=self.context):
   149             return _("Show/hide image")
   149             return _("Show/hide media")
   150         else:
   150         else:
   151             return ''
   151             return ''
   152 
   152 
   153     @property
   153     @property
   154     def label_css_class(self):
   154     def label_css_class(self):
   157         else:
   157         else:
   158             return 'fa fa-fw fa-eye-slash text-danger'
   158             return 'fa fa-fw fa-eye-slash text-danger'
   159 
   159 
   160     hint_gravity = 'nw'
   160     hint_gravity = 'nw'
   161 
   161 
   162     url = 'PyAMS_content.galleries.switchImageVisibility'
   162     url = 'PyAMS_content.galleries.switchMediaVisibility'
   163 
   163 
   164     def get_url(self):
   164     def get_url(self):
   165         if self.request.has_permission(self.edit_permission, context=self.context):
   165         if self.request.has_permission(self.edit_permission, context=self.context):
   166             return self.url
   166             return self.url
   167 
   167 
   168 
   168 
   169 @viewlet_config(name='file.properties.action', context=IGalleryFile, layer=IPyAMSLayer, view=IGalleryImagesView,
   169 @viewlet_config(name='file.properties.action', context=IGalleryFile, layer=IPyAMSLayer, view=IGalleryContentsView,
   170                 manager=IContextActions, permission=VIEW_SYSTEM_PERMISSION, weight=5)
   170                 manager=IContextActions, permission=VIEW_SYSTEM_PERMISSION, weight=5)
   171 class GalleryFilePropertiesAction(FilePropertiesAction):
   171 class GalleryFilePropertiesAction(FilePropertiesAction):
   172     """Media properties action"""
   172     """Media properties action"""
   173 
   173 
   174     url = 'gallery-file-properties.html'
   174     url = 'gallery-file-properties.html'
   177 @pagelet_config(name='gallery-file-properties.html', context=IGalleryFile, layer=IPyAMSLayer,
   177 @pagelet_config(name='gallery-file-properties.html', context=IGalleryFile, layer=IPyAMSLayer,
   178                 permission=VIEW_SYSTEM_PERMISSION)
   178                 permission=VIEW_SYSTEM_PERMISSION)
   179 class GalleryFilePropertiesEditForm(AdminDialogEditForm):
   179 class GalleryFilePropertiesEditForm(AdminDialogEditForm):
   180     """Gallery file properties edit form"""
   180     """Gallery file properties edit form"""
   181 
   181 
   182     legend = _("Update image properties")
   182     legend = _("Update media properties")
   183     icon_css_class = 'fa fa-fw fa-picture-o'
   183     icon_css_class = 'fa fa-fw fa-picture-o'
   184     dialog_class = 'modal-large'
   184     dialog_class = 'modal-large'
   185 
   185 
   186     fields = field.Fields(IGalleryFile).omit('__parent__', '__name__', 'visible')
   186     fields = field.Fields(IGalleryFile).omit('__parent__', '__name__', 'visible')
   187     ajax_handler = 'gallery-file-properties.json'
   187     ajax_handler = 'gallery-file-properties.json'
   221             gallery = get_parent(self.context, IGallery)
   221             gallery = get_parent(self.context, IGallery)
   222             if gallery is not None:
   222             if gallery is not None:
   223                 output.setdefault('events', []).append({
   223                 output.setdefault('events', []).append({
   224                     'event': 'myams.refresh',
   224                     'event': 'myams.refresh',
   225                     'options': {
   225                     'options': {
   226                         'handler': 'PyAMS_content.galleries.updateImageTitle',
   226                         'handler': 'PyAMS_content.galleries.updateMediaTitle',
   227                         'image_id': 'image_{0}_{1}'.format(gallery.__name__, self.context.__name__),
   227                         'media_id': 'media_{0}_{1}'.format(gallery.__name__, self.context.__name__),
   228                         'title': II18n(self.context).query_attribute('title', request=self.request)
   228                         'title': II18n(self.context).query_attribute('title', request=self.request)
   229                     }
   229                     }
   230                 })
   230                 })
   231         return output
   231         return output
   232 
   232 
   233 
   233 
   234 @viewlet_config(name='gallery-file-remover.action', context=IGalleryFile, layer=IPyAMSLayer, view=IGalleryImagesView,
   234 @viewlet_config(name='gallery-file-remover.action', context=IGalleryFile, layer=IPyAMSLayer, view=IGalleryContentsView,
   235                 manager=IContextActions, weight=90)
   235                 manager=IContextActions, weight=90)
   236 class GalleryFileRemoverAction(WfSharedContentPermissionMixin, JsToolbarActionItem):
   236 class GalleryFileRemoverAction(WfSharedContentPermissionMixin, JsToolbarActionItem):
   237     """Gallery file remover action"""
   237     """Gallery file remover action"""
   238 
   238 
   239     label = _("Remove image...")
   239     label = _("Remove media...")
   240     label_css_class = 'fa fa-fw fa-trash'
   240     label_css_class = 'fa fa-fw fa-trash'
   241     hint_gravity = 'nw'
   241     hint_gravity = 'nw'
   242 
   242 
   243     url = 'PyAMS_content.galleries.removeFile'
   243     url = 'PyAMS_content.galleries.removeMedia'
   244 
   244 
   245 
   245 
   246 @view_config(name='delete-element.json', context=IGallery, request_type=IPyAMSLayer,
   246 @view_config(name='delete-element.json', context=IGallery, request_type=IPyAMSLayer,
   247              permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
   247              permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
   248 def delete_gallery_element(request):
   248 def delete_gallery_element(request):
   254                 'messagebox': {'status': 'error',
   254                 'messagebox': {'status': 'error',
   255                                'content': translate(_("No provided object_name argument!"))}}
   255                                'content': translate(_("No provided object_name argument!"))}}
   256     if name not in request.context:
   256     if name not in request.context:
   257         return {'status': 'message',
   257         return {'status': 'message',
   258                 'messagebox': {'status': 'error',
   258                 'messagebox': {'status': 'error',
   259                                'content': translate(_("Given image name doesn't exist!"))}}
   259                                'content': translate(_("Given media name doesn't exist!"))}}
   260     del request.context[name]
   260     del request.context[name]
   261     return {'status': 'success'}
   261     return {'status': 'success'}