Implémentation complète de l'ordonnancement.
[Plinn.git] / File.py
diff --git a/File.py b/File.py
index 11bdafa..53a9154 100755 (executable)
--- a/File.py
+++ b/File.py
 #   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.   #
 #######################################################################################
 """ This module implements a portal-managed File class that's inherits of CMFDefault
-       File. If exists, portal_transforms is called to extract text content, and publish
-       attachments.
+    File. If exists, portal_transforms is called to extract text content, and publish
+    attachments.
+
+
 
-$Id: File.py 1261 2008-01-07 01:34:23Z pin $
-$URL: http://svn.cri.ensmp.fr/svn/Plinn/branches/CMF-2.1/File.py $
 """
 
 from Globals import InitializeClass
@@ -30,109 +30,168 @@ from AccessControl import ClassSecurityInfo
 import OFS
 from zope.component.factory import Factory
 
-from Products.CMFDefault.File import File as BaseFile
+from Products.CMFDefault.File import File as CMFFile
+from Products.Photo.blobbases import File as BlobFile
+from Products.CMFDefault.DublinCore import DefaultDublinCoreImpl
 from Products.CMFCore.permissions import View, ModifyPortalContent
 from Products.CMFCore.utils import getToolByName
-
-class File(BaseFile) :
-       """ file class with portal_transforms support """
-       
-       security = ClassSecurityInfo()
-       
-       _properties = BaseFile._properties + ({'id':'orig_name', 'type':'string', 'mode':'w', 'label':"Original Name"},)
-       orig_name = ''
-
-
-       def __getattr__(self, name) :
-               try : return BaseFile.__getattr__(self, name)
-               except :
-                       selfAttrs = self.__dict__
-                       if selfAttrs.has_key('_v_transform_cache') :
-                               cache = selfAttrs['_v_transform_cache']
-                               cacheTuple = cache.get('text_html', None) # (time, value)
-                               if cacheTuple :
-                                       cacheData = cacheTuple[1]
-                               
-                               subObDict = cacheData.getSubObjects()
-                               if subObDict.has_key(name) :
-                                       fileOb = OFS.Image.File(name, name, subObDict[name])
-                                       return fileOb
-                               
-                       raise AttributeError, name
-       
-       security.declareProtected(ModifyPortalContent, 'edit')
-       def edit(self, precondition='', file=''):
-               orig_name = OFS.Image.cookId('', '', file)[0]
-               if orig_name :
-                       self.orig_name = orig_name
-               BaseFile.edit(self, precondition=precondition, file=file)
-               if hasattr(self, '_v_transform_cache') :
-                       del self._v_transform_cache
-       
-       
-       security.declareProtected(View, 'SearchableText')
-       def SearchableText(self) :
-               """ Return full text"""
-               baseSearchableText = BaseFile.SearchableText(self)
-               transformTool = getToolByName(self, 'portal_transforms', default=None)
-               if transformTool is None :
-                       return baseSearchableText
-               else :
-                       datastream_text =  transformTool.convertTo('text/plain',
-                                                                                                               str(self.data),
-                                                                                                               mimetype = self.content_type
-                                                                                                               )
-                       full_text = ''
-                       if datastream_text is not None :
-                               full_text = datastream_text.getData()
-                       
-                       return baseSearchableText + full_text
-                       
-       security.declareProtected(View, 'preview')
-       def preview(self) :
-               """Return HTML preview if it's possible or empty string """
-               transformTool = getToolByName(self, 'portal_transforms', default = None)
-               if transformTool is None :
-                       return ''
-               else :
-                       filename = self.getId().replace(' ', '_')
-                       datastream = transformTool.convertTo('text/html',
-                                                                                               str(self.data),
-                                                                                               object=self,
-                                                                                               mimetype = self.content_type,
-                                                                                               filename = filename)
-
-                       if datastream is not None : return datastream.getData()
-                       else : return ''
-
-       security.declareProtected(View, 'download')
-       def download(self, REQUEST, RESPONSE):
-               """Download this item.
-               
-               Calls OFS.Image.File.index_html to perform the actual transfer after
-               first setting Content-Disposition to suggest a filename.
-               
-               This method is deprecated, use the URL of this object itself. Because
-               the default view of a File object is to download, rather than view,
-               this method is obsolete. Also note that certain browsers do not deal
-               well with a Content-Disposition header.
-
-               """
-
-               RESPONSE.setHeader('Content-Disposition',
-                                                  'attachment; filename=%s' % (self.orig_name or self.getId()))
-               return OFS.Image.File.index_html(self, REQUEST, RESPONSE)
-       
-       security.declarePublic('getIcon')
-       def getIcon(self, relative_to_portal=0):
-               """ return icon corresponding to mime-type
-               """
-               regTool = getToolByName(self, 'mimetypes_registry', default=None)
-               if regTool :
-                       mime = regTool(str(self.data), mimetype=self.content_type)[2]
-                       return mime.icon_path
-               else :
-                       return BaseFile.getIcon(self, relative_to_portal=relative_to_portal)
+from hexagonit.swfheader import parse as parseswf
+
+class File(BlobFile, CMFFile) :
+    """ file class with portal_transforms support """
+    
+    security = ClassSecurityInfo()
+    
+    _properties = CMFFile._properties + ({'id':'orig_name', 'type':'string', 'mode':'w', 'label':"Original Name"},)
+    orig_name = ''
+
+    def __init__( self
+                , id
+                , title=''
+                , file=''
+                , content_type=''
+                , precondition=''
+                , subject=()
+                , description=''
+                , contributors=()
+                , effective_date=None
+                , expiration_date=None
+                , format=None
+                , language='en-US'
+                , rights=''
+                ):
+        self._setId(id)
+        if format is None:
+            format = self.content_type or 'application/octet-stream'
+        
+        DefaultDublinCoreImpl.__init__( self, title, subject, description
+                               , contributors, effective_date, expiration_date
+                               , format, language, rights )
+        BlobFile.__init__(self, id, title, file, content_type=content_type, precondition=precondition)
+
+
+    def __getattr__(self, name) :
+        try : return CMFFile.__getattr__(self, name)
+        except :
+            selfAttrs = self.__dict__
+            if selfAttrs.has_key('_v_transform_cache') :
+                cache = selfAttrs['_v_transform_cache']
+                cacheTuple = cache.get('text_html', None) # (time, value)
+                if cacheTuple :
+                    cacheData = cacheTuple[1]
+                
+                    subObDict = cacheData.getSubObjects()
+                    if subObDict.has_key(name) :
+                        fileOb = OFS.Image.File(name, name, subObDict[name])
+                        return fileOb
+                
+            raise AttributeError, name
+    
+    def manage_upload(self,file='',REQUEST=None):
+        ret = super(File, self).manage_upload(file=file, REQUEST=REQUEST)
+
+        orig_name = OFS.Image.cookId('', '', file)[0]
+        if orig_name :
+            self.orig_name = orig_name
+
+        if self.Format() == 'application/x-shockwave-flash' :
+            if file :
+                try :
+                    swfmetadata = parseswf(file)
+                except IOError :
+                    swfmetadata = {'width':600, 'height':600}
+
+            for name in ('width', 'height') :
+                value = swfmetadata[name]
+                if self.hasProperty(name) :
+                    self._updateProperty(name, value)
+                else :
+                    self.manage_addProperty(name, value, 'int')
+        self.reindexObject()
+        return ret
+        
+        
+    
+    security.declareProtected(ModifyPortalContent, 'edit')
+    def edit(self, precondition='', file=''):
+        orig_name = OFS.Image.cookId('', '', file)[0]
+        if orig_name :
+            self.orig_name = orig_name
+        CMFFile.edit(self, precondition=precondition, file=file)
+        if hasattr(self, '_v_transform_cache') :
+            del self._v_transform_cache
+    
+    
+    security.declareProtected(View, 'SearchableText')
+    def SearchableText(self) :
+        """ Return full text"""
+        baseSearchableText = CMFFile.SearchableText(self)
+        transformTool = getToolByName(self, 'portal_transforms', default=None)
+        if transformTool is None :
+            return baseSearchableText
+        else :
+            f = self.bdata.open()
+            orig = f.read()
+            datastream_text =  transformTool.convertTo('text/plain',
+                                                        orig,
+                                                        mimetype = self.content_type
+                                                        )
+            f.close()
+            full_text = ''
+            if datastream_text is not None :
+                full_text = datastream_text.getData()
+            
+            return baseSearchableText + full_text
+            
+    security.declareProtected(View, 'preview')
+    def preview(self) :
+        """Return HTML preview if it's possible or empty string """
+        transformTool = getToolByName(self, 'portal_transforms', default = None)
+        if transformTool is None :
+            return ''
+        else :
+            filename = self.getId().replace(' ', '_')
+            f = self.bdata.open()
+            orig = f.read()
+            datastream = transformTool.convertTo('text/html',
+                                                orig,
+                                                object=self,
+                                                mimetype = self.content_type,
+                                                filename = filename)
+            f.close()
+            if datastream is not None : return datastream.getData()
+            else : return ''
+
+    security.declareProtected(View, 'download')
+    def download(self, REQUEST, RESPONSE):
+        """Download this item.
+        
+        Calls OFS.Image.File.index_html to perform the actual transfer after
+        first setting Content-Disposition to suggest a filename.
+        
+        This method is deprecated, use the URL of this object itself. Because
+        the default view of a File object is to download, rather than view,
+        this method is obsolete. Also note that certain browsers do not deal
+        well with a Content-Disposition header.
+
+        """
+
+        RESPONSE.setHeader('Content-Disposition',
+                           'attachment; filename=%s' % (self.orig_name or self.getId()))
+        return OFS.Image.File.index_html(self, REQUEST, RESPONSE)
+    
+    security.declarePublic('getIcon')
+    def getIcon(self, relative_to_portal=0):
+        """ return icon corresponding to mime-type
+        """
+        regTool = getToolByName(self, 'mimetypes_registry', default=None)
+        if regTool :
+            f = self.bdata.open()
+            mime = regTool(f, mimetype=self.content_type)[2]
+            f.close()
+            return mime.icon_path
+        else :
+            return CMFFile.getIcon(self, relative_to_portal=relative_to_portal)
 
 
 InitializeClass(File)
@@ -140,41 +199,41 @@ FileFactory = Factory(File)
 
 
 def addFile( dispatcher
-                        , id
-                        , title=''
-                        , file=''
-                        , content_type=''
-                        , precondition=''
-                        , subject=()
-                        , description=''
-                        , contributors=()
-                        , effective_date=None
-                        , expiration_date=None
-                        , format='text/html'
-                        , language=''
-                        , rights=''
-                        ):
-       """
-       Add a File
-       """
-
-       # cookId sets the id and title if they are not explicity specified
-       id, title = OFS.Image.cookId(id, title, file)
-
-       container = dispatcher.Destination()
-
-       # Instantiate the object and set its description.
-       fobj = File( id, title=title, file='', content_type=content_type,
-                                precondition=precondition, subject=subject, description=description,
-                                contributors=contributors, effective_date=effective_date,
-                                expiration_date=expiration_date, format=format,
-                                language=language, rights=rights
-                                 )
-       
-       # Add the File instance to self
-       container._setObject(id, fobj)
-
-       # 'Upload' the file.  This is done now rather than in the
-       # constructor because the object is now in the ZODB and
-       # can span ZODB objects.
-       container._getOb(id).manage_upload(file)
\ No newline at end of file
+             , id
+             , title=''
+             , file=''
+             , content_type=''
+             , precondition=''
+             , subject=()
+             , description=''
+             , contributors=()
+             , effective_date=None
+             , expiration_date=None
+             , format='text/html'
+             , language=''
+             , rights=''
+             ):
+    """
+    Add a File
+    """
+
+    # cookId sets the id and title if they are not explicity specified
+    id, title = OFS.Image.cookId(id, title, file)
+
+    container = dispatcher.Destination()
+
+    # Instantiate the object and set its description.
+    fobj = File( id, title=title, file='', content_type=content_type,
+                 precondition=precondition, subject=subject, description=description,
+                 contributors=contributors, effective_date=effective_date,
+                 expiration_date=expiration_date, format=format,
+                 language=language, rights=rights
+                  )
+    
+    # Add the File instance to self
+    container._setObject(id, fobj)
+
+    # 'Upload' the file.  This is done now rather than in the
+    # constructor because the object is now in the ZODB and
+    # can span ZODB objects.
+    container._getOb(id).manage_upload(file)
\ No newline at end of file