src/pyams_content/component/extfile/__init__.py
changeset 140 67bad9f880ee
parent 60 da1454d7d358
child 201 46819098e77a
--- a/src/pyams_content/component/extfile/__init__.py	Mon Sep 11 14:53:15 2017 +0200
+++ b/src/pyams_content/component/extfile/__init__.py	Mon Sep 11 14:54:30 2017 +0200
@@ -16,21 +16,27 @@
 # import standard library
 
 # import interfaces
-from pyams_content.component.extfile.interfaces import IBaseExtFile, IExtFile, IExtImage, IExtVideo, IExtAudio
+from pyams_content.component.association.interfaces import IAssociationInfo
+from pyams_content.component.extfile.interfaces import IBaseExtFile, IExtFile, IExtImage, IExtVideo, IExtAudio, \
+    IExtMedia
 from pyams_content.shared.common.interfaces import IWfSharedContent
+from pyams_file.interfaces import IFileInfo, IResponsiveImage, DELETED_FILE
 from pyams_form.interfaces.form import IFormContextPermissionChecker
+from pyams_i18n.interfaces import II18n, INegotiator
 from zope.lifecycleevent.interfaces import IObjectAddedEvent, IObjectModifiedEvent, IObjectRemovedEvent
 
 # import packages
-from persistent import Persistent
+from pyams_content.component.association import AssociationItem
 from pyams_i18n.property import I18nFileProperty
 from pyams_utils.adapter import adapter_config, ContextAdapter
+from pyams_utils.registry import query_utility
+from pyams_utils.request import check_request
+from pyams_utils.size import get_human_size
 from pyams_utils.traversing import get_parent
 from pyams_utils.vocabulary import vocabulary_config
 from pyramid.events import subscriber
 from pyramid.threadlocal import get_current_registry
-from zope.container.contained import Contained
-from zope.interface import implementer
+from zope.interface import implementer, alsoProvides
 from zope.lifecycleevent import ObjectModifiedEvent
 from zope.schema.fieldproperty import FieldProperty
 from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm
@@ -58,12 +64,39 @@
 
 
 @implementer(IBaseExtFile)
-class BaseExtFile(Persistent, Contained):
+class BaseExtFile(AssociationItem):
     """External file persistent class"""
 
     title = FieldProperty(IExtFile['title'])
     description = FieldProperty(IExtFile['description'])
     author = FieldProperty(IExtFile['author'])
+    language = FieldProperty(IExtFile['language'])
+    filename = FieldProperty(IExtFile['filename'])
+
+
+@adapter_config(context=IBaseExtFile, provides=IAssociationInfo)
+class BaseExtFileAssociationInfoAdapter(ContextAdapter):
+    """Base external file association info adapter"""
+
+    @property
+    def pictogram(self):
+        return self.context.icon_class
+
+    @property
+    def user_title(self):
+        return II18n(self.context).query_attribute('title') or self.context.filename
+
+    @property
+    def inner_title(self):
+        return self.context.filename or '--'
+
+    @property
+    def human_size(self):
+        data = II18n(self.context).query_attribute('data')
+        if data and data.data:
+            return get_human_size(data.get_size())
+        else:
+            return '--'
 
 
 @adapter_config(context=IBaseExtFile, provides=IFormContextPermissionChecker)
@@ -76,10 +109,34 @@
         return IFormContextPermissionChecker(content).edit_permission
 
 
+def update_properties(extfile):
+    """Update missing file properties"""
+    request = check_request()
+    i18n = query_utility(INegotiator)
+    if i18n is not None:
+        lang = i18n.server_language
+        data = II18n(extfile).get_attribute('data', lang, request)
+        if data:
+            info = IFileInfo(data)
+            info.title = II18n(extfile).get_attribute('title', lang, request)
+            info.description = II18n(extfile).get_attribute('description', lang, request)
+            if not extfile.filename:
+                extfile.filename = info.filename
+            else:
+                info.filename = extfile.filename
+        for lang, data in (extfile.data or {}).items():
+            if data is not None:
+                IFileInfo(data).language = lang
+
+
 @subscriber(IObjectAddedEvent, context_selector=IBaseExtFile)
 def handle_added_extfile(event):
     """Handle added external file"""
-    content = get_parent(event.object, IWfSharedContent)
+    # update inner file properties
+    extfile = event.object
+    update_properties(extfile)
+    # notify content modification
+    content = get_parent(extfile, IWfSharedContent)
     if content is not None:
         get_current_registry().notify(ObjectModifiedEvent(content))
 
@@ -87,7 +144,11 @@
 @subscriber(IObjectModifiedEvent, context_selector=IBaseExtFile)
 def handle_modified_extfile(event):
     """Handle modified external file"""
-    content = get_parent(event.object, IWfSharedContent)
+    # update inner file properties
+    extfile = event.object
+    update_properties(extfile)
+    # notify content modification
+    content = get_parent(extfile, IWfSharedContent)
     if content is not None:
         get_current_registry().notify(ObjectModifiedEvent(content))
 
@@ -104,6 +165,9 @@
 class ExtFile(BaseExtFile):
     """Generic external file persistent class"""
 
+    icon_class = 'fa-file-o'
+    icon_hint = _("Standard file")
+
     data = I18nFileProperty(IExtFile['data'])
 
 register_file_factory('file', ExtFile, _("Standard file"))
@@ -113,7 +177,23 @@
 class ExtImage(BaseExtFile):
     """External image persistent class"""
 
-    data = I18nFileProperty(IExtImage['data'])
+    icon_class = 'fa-file-image-o'
+    icon_hint = _("Image")
+
+    title = FieldProperty(IExtMedia['title'])
+    alt_title = FieldProperty(IExtImage['alt_title'])
+    _data = I18nFileProperty(IExtImage['data'])
+
+    @property
+    def data(self):
+        return self._data
+
+    @data.setter
+    def data(self, value):
+        self._data = value
+        for data in value.values():
+            if (data is not None) and (data is not DELETED_FILE):
+                alsoProvides(data, IResponsiveImage)
 
 register_file_factory('image', ExtImage, _("Image"))
 
@@ -122,6 +202,10 @@
 class ExtVideo(BaseExtFile):
     """External video file persistent class"""
 
+    icon_class = 'fa-file-video-o'
+    icon_hint = _("Video")
+
+    title = FieldProperty(IExtMedia['title'])
     data = I18nFileProperty(IExtVideo['data'])
 
 register_file_factory('video', ExtVideo, _("Video"))
@@ -131,6 +215,10 @@
 class ExtAudio(BaseExtFile):
     """External audio file persistent class"""
 
+    icon_class = 'fa-file-audio-o'
+    icon_hint = _("Audio file")
+
+    title = FieldProperty(IExtMedia['title'])
     data = I18nFileProperty(IExtAudio['data'])
 
 register_file_factory('audio', ExtAudio, _("Audio file"))