src/pyams_content/component/extfile/zmi/container.py
changeset 0 7c0001cacf8e
child 7 cbc55162b64e
equal deleted inserted replaced
-1:000000000000 0:7c0001cacf8e
       
     1 #
       
     2 # Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
       
     3 # All Rights Reserved.
       
     4 #
       
     5 # This software is subject to the provisions of the Zope Public License,
       
     6 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
       
     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
       
     9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
       
    10 # FOR A PARTICULAR PURPOSE.
       
    11 #
       
    12 
       
    13 __docformat__ = 'restructuredtext'
       
    14 
       
    15 
       
    16 # import standard library
       
    17 
       
    18 # import interfaces
       
    19 from pyams_content.component.extfile.interfaces import IExtFileContainerTarget, IExtFileContainer, \
       
    20     IExtFileLinksContainerTarget, IExtFileLinksContainer
       
    21 from pyams_content.interfaces import MANAGE_CONTENT_PERMISSION
       
    22 from pyams_file.interfaces import IFileInfo, IFile, IImage
       
    23 from pyams_i18n.interfaces import II18n
       
    24 from pyams_skin.interfaces import IInnerPage, IPageHeader
       
    25 from pyams_skin.layer import IPyAMSLayer
       
    26 from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION
       
    27 from pyams_utils.interfaces.data import IObjectData
       
    28 from pyams_zmi.interfaces.menu import IPropertiesMenu
       
    29 from pyams_zmi.layer import IAdminLayer
       
    30 from z3c.table.interfaces import IValues, IColumn
       
    31 
       
    32 # import packages
       
    33 from pyams_content.component.extfile.zmi.widget import ExtFileLinkSelectFieldWidget
       
    34 from pyams_content.shared.common.zmi import WfModifiedContentColumnMixin
       
    35 from pyams_form.form import AJAXEditForm
       
    36 from pyams_form.security import ProtectedFormObjectMixin
       
    37 from pyams_pagelet.pagelet import pagelet_config
       
    38 from pyams_skin.page import DefaultPageHeaderAdapter
       
    39 from pyams_skin.table import BaseTable, I18nColumn, TrashColumn
       
    40 from pyams_skin.viewlet.menu import MenuItem, MenuDivider
       
    41 from pyams_template.template import template_config
       
    42 from pyams_utils.adapter import adapter_config, ContextRequestViewAdapter
       
    43 from pyams_utils.size import get_human_size
       
    44 from pyams_utils.traversing import get_parent
       
    45 from pyams_utils.url import absolute_url
       
    46 from pyams_viewlet.viewlet import viewlet_config
       
    47 from pyams_zmi.form import AdminDialogEditForm
       
    48 from pyams_zmi.view import AdminView
       
    49 from pyramid.decorator import reify
       
    50 from pyramid.view import view_config
       
    51 from z3c.form import field
       
    52 from z3c.table.column import GetAttrColumn
       
    53 from zope.interface import implementer, alsoProvides, Interface
       
    54 
       
    55 from pyams_content import _
       
    56 
       
    57 
       
    58 @viewlet_config(name='external-files.menu', context=IExtFileContainerTarget, layer=IAdminLayer,
       
    59                 manager=IPropertiesMenu, permission=VIEW_SYSTEM_PERMISSION, weight=200)
       
    60 class ExtFileContainerMenu(MenuItem):
       
    61     """External files container menu"""
       
    62 
       
    63     label = _("External files...")
       
    64     icon_class = 'fa-file-text-o'
       
    65     url = '#external-files.html'
       
    66 
       
    67 
       
    68 #
       
    69 # External files container views
       
    70 #
       
    71 
       
    72 @view_config(name='get-files-list.json', context=Interface, request_type=IPyAMSLayer,
       
    73              renderer='json', xhr=True)
       
    74 def get_files_list(request):
       
    75     """Get container files in JSON format for TinyMCE editor"""
       
    76     target = get_parent(request.context, IExtFileContainerTarget)
       
    77     if target is None:
       
    78         return []
       
    79     container = IExtFileContainer(target)
       
    80     return sorted([{'title': II18n(file).query_attribute('title', request=request),
       
    81                     'value': absolute_url(II18n(file).query_attribute('data', request=request), request)}
       
    82                    for file in container.values()],
       
    83                   key=lambda x: x['title'])
       
    84 
       
    85 
       
    86 @view_config(name='get-images-list.json', context=Interface, request_type=IPyAMSLayer,
       
    87              renderer='json', xhr=True)
       
    88 def get_images_list(request):
       
    89     """Get container images in JSON format for TinyMCE editor"""
       
    90     target = get_parent(request.context, IExtFileContainerTarget)
       
    91     if target is None:
       
    92         return []
       
    93     container = IExtFileContainer(target)
       
    94     return sorted([{'title': II18n(img).query_attribute('title', request=request),
       
    95                     'value': absolute_url(II18n(img).query_attribute('data', request=request), request)}
       
    96                    for img in container.images],
       
    97                   key=lambda x: x['title'])
       
    98 
       
    99 
       
   100 @pagelet_config(name='external-files.html', context=IExtFileContainerTarget, layer=IPyAMSLayer,
       
   101                 permission=VIEW_SYSTEM_PERMISSION)
       
   102 @template_config(template='templates/container.pt', layer=IPyAMSLayer)
       
   103 @implementer(IInnerPage)
       
   104 class ExtFileContainerView(AdminView):
       
   105     """External files container view"""
       
   106 
       
   107     title = _("External files list")
       
   108 
       
   109     def __init__(self, context, request):
       
   110         super(ExtFileContainerView, self).__init__(context, request)
       
   111         self.files_table = ExtFileContainerTable(context, request, self, _("External files"), 'files')
       
   112         self.images_table = ExtFileContainerTable(context, request, self, _("Images"), 'images')
       
   113         self.videos_table = ExtFileContainerTable(context, request, self, _("Videos"), 'videos')
       
   114         self.audios_table = ExtFileContainerTable(context, request, self, _("Sounds"), 'audios')
       
   115 
       
   116     def update(self):
       
   117         super(ExtFileContainerView, self).update()
       
   118         self.files_table.update()
       
   119         self.images_table.update()
       
   120         self.videos_table.update()
       
   121         self.audios_table.update()
       
   122 
       
   123 
       
   124 class ExtFileContainerTable(BaseTable):
       
   125     """External files container table"""
       
   126 
       
   127     hide_toolbar = True
       
   128     cssClasses = {'table': 'table table-bordered table-striped table-hover table-tight'}
       
   129 
       
   130     def __init__(self, context, request, view, title, property):
       
   131         super(ExtFileContainerTable, self).__init__(context, request)
       
   132         self.view = view
       
   133         self.title = title
       
   134         self.files_property = property
       
   135         self.object_data = {'ams-widget-toggle-button': 'false'}
       
   136         alsoProvides(self, IObjectData)
       
   137 
       
   138     @property
       
   139     def data_attributes(self):
       
   140         attributes = super(ExtFileContainerTable, self).data_attributes
       
   141         attributes['table'] = {'data-ams-location': absolute_url(IExtFileContainer(self.context), self.request),
       
   142                                'data-ams-datatable-sort': 'false',
       
   143                                'data-ams-datatable-pagination': 'false'}
       
   144         return attributes
       
   145 
       
   146     @reify
       
   147     def values(self):
       
   148         return list(super(ExtFileContainerTable, self).values)
       
   149 
       
   150     def render(self):
       
   151         if not self.values:
       
   152             if self.files_property == 'files':
       
   153                 for table in (self.view.images_table, self.view.videos_table, self.view.audios_table):
       
   154                     if table.values:
       
   155                         return ''
       
   156                 translate = self.request.localizer.translate
       
   157                 return translate(_("No currently stored external file."))
       
   158             else:
       
   159                 return ''
       
   160         return super(ExtFileContainerTable, self).render()
       
   161 
       
   162 
       
   163 @adapter_config(name='name', context=(IExtFileContainerTarget, IPyAMSLayer, ExtFileContainerTable), provides=IColumn)
       
   164 class ExtFileContainerNameColumn(I18nColumn, WfModifiedContentColumnMixin, GetAttrColumn):
       
   165     """External files container name column"""
       
   166 
       
   167     _header = _("Title")
       
   168 
       
   169     weight = 10
       
   170 
       
   171     def getValue(self, obj):
       
   172         return II18n(obj).query_attribute('title', request=self.request)
       
   173 
       
   174 
       
   175 @adapter_config(name='filename', context=(IExtFileContainerTarget, IPyAMSLayer, ExtFileContainerTable), provides=IColumn)
       
   176 class ExtFileContainerFilenameColumn(I18nColumn, GetAttrColumn):
       
   177     """External file container filename column"""
       
   178 
       
   179     _header = _("Filename")
       
   180 
       
   181     weight = 15
       
   182 
       
   183     def getValue(self, obj):
       
   184         data = II18n(obj).query_attribute('data', request=self.request)
       
   185         if data is not None:
       
   186             return IFileInfo(data).filename
       
   187         else:
       
   188             return '--'
       
   189 
       
   190 
       
   191 @adapter_config(name='filesize', context=(IExtFileContainerTarget, IPyAMSLayer, ExtFileContainerTable), provides=IColumn)
       
   192 class ExtFileContainerFileSizeColumn(I18nColumn, GetAttrColumn):
       
   193     """External file container file size column"""
       
   194 
       
   195     _header = _("Size")
       
   196 
       
   197     weight = 20
       
   198 
       
   199     def getValue(self, obj):
       
   200         data = II18n(obj).query_attribute('data', request=self.request)
       
   201         if data is not None:
       
   202             result = get_human_size(IFile(data).get_size())
       
   203             if IImage.providedBy(data):
       
   204                 result = '{0} ({1[0]}x{1[1]})'.format(result, IImage(data).get_image_size())
       
   205             return result
       
   206         else:
       
   207             return 'N/A'
       
   208 
       
   209 
       
   210 @adapter_config(name='trash', context=(IExtFileContainerTarget, IPyAMSLayer, ExtFileContainerTable), provides=IColumn)
       
   211 class ExtFileContainerTrashColumn(ProtectedFormObjectMixin, TrashColumn):
       
   212     """External files container trash column"""
       
   213 
       
   214 
       
   215 @adapter_config(context=(IExtFileContainerTarget, IPyAMSLayer, ExtFileContainerTable), provides=IValues)
       
   216 class ExtFileContainerValues(ContextRequestViewAdapter):
       
   217     """External files container values"""
       
   218 
       
   219     @property
       
   220     def values(self):
       
   221         return getattr(IExtFileContainer(self.context), self.view.files_property)
       
   222 
       
   223 
       
   224 @adapter_config(context=(IExtFileContainerTarget, IPyAMSLayer, ExtFileContainerView), provides=IPageHeader)
       
   225 class ExtFileHeaderAdapter(DefaultPageHeaderAdapter):
       
   226     """External files container header adapter"""
       
   227 
       
   228     back_url = '#properties.html'
       
   229     icon_class = 'fa fa-fw fa-file-text-o'
       
   230 
       
   231 
       
   232 #
       
   233 # External files links edit form
       
   234 #
       
   235 
       
   236 @pagelet_config(name='extfile-links.html', context=IExtFileLinksContainerTarget, layer=IPyAMSLayer,
       
   237                 permission=VIEW_SYSTEM_PERMISSION)
       
   238 class ExtFileLinksContainerLinksEditForm(AdminDialogEditForm):
       
   239     """External file links container edit form"""
       
   240 
       
   241     legend = _("Edit external files links")
       
   242 
       
   243     fields = field.Fields(IExtFileLinksContainer)
       
   244     fields['files'].widgetFactory = ExtFileLinkSelectFieldWidget
       
   245 
       
   246     ajax_handler = 'extfile-links.json'
       
   247     edit_permission = MANAGE_CONTENT_PERMISSION
       
   248 
       
   249 
       
   250 @view_config(name='extfile-links.json', context=IExtFileLinksContainerTarget, request_type=IPyAMSLayer,
       
   251              permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
       
   252 class ExtFileLinksContainerAJAXEditForm(AJAXEditForm, ExtFileLinksContainerLinksEditForm):
       
   253     """External file links container edit form, JSON renderer"""