X-Git-Url: https://scm.cri.ensmp.fr/git/Plinn.git/blobdiff_plain/b3b52f5b0ad754fd9036f816d0ab8e98a5373f40..9b3338dbdd3bb11315f01b571120ccb8f3536064:/File.py?ds=sidebyside diff --git a/File.py b/File.py index c0e37c7..53a9154 100755 --- a/File.py +++ b/File.py @@ -18,11 +18,11 @@ # 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 1549 2010-02-04 13:04:22Z pin $ -$URL: http://svn.cri.ensmp.fr/svn/Plinn/branches/CMF-2.1/File.py $ """ from Globals import InitializeClass @@ -30,136 +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 -from swfheader import parse as parseswf - -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 - - 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 - - print self.absolute_url(), self.Format() - 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 - 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) @@ -167,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