11bdafaeee52e3efa9b8dc630f60d9b77146745c
1 # -*- coding: utf-8 -*-
2 #######################################################################################
3 # Plinn - http://plinn.org #
4 # Copyright (C) 2005-2007 BenoƮt PIN <benoit.pin@ensmp.fr> #
6 # This program is free software; you can redistribute it and/or #
7 # modify it under the terms of the GNU General Public License #
8 # as published by the Free Software Foundation; either version 2 #
9 # of the License, or (at your option) any later version. #
11 # This program is distributed in the hope that it will be useful, #
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14 # GNU General Public License for more details. #
16 # You should have received a copy of the GNU General Public License #
17 # along with this program; if not, write to the Free Software #
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #
19 #######################################################################################
20 """ This module implements a portal-managed File class that's inherits of CMFDefault
21 File. If exists, portal_transforms is called to extract text content, and publish
24 $Id: File.py 1261 2008-01-07 01:34:23Z pin $
25 $URL: http://svn.cri.ensmp.fr/svn/Plinn/branches/CMF-2.1/File.py $
28 from Globals
import InitializeClass
29 from AccessControl
import ClassSecurityInfo
31 from zope
.component
.factory
import Factory
33 from Products
.CMFDefault
.File
import File
as BaseFile
34 from Products
.CMFCore
.permissions
import View
, ModifyPortalContent
35 from Products
.CMFCore
.utils
import getToolByName
37 class File(BaseFile
) :
38 """ file class with portal_transforms support """
40 security
= ClassSecurityInfo()
42 _properties
= BaseFile
._properties
+ ({'id':'orig_name', 'type':'string', 'mode':'w', 'label':"Original Name"},)
46 def __getattr__(self
, name
) :
47 try : return BaseFile
.__getattr
__(self
, name
)
49 selfAttrs
= self
.__dict
__
50 if selfAttrs
.has_key('_v_transform_cache') :
51 cache
= selfAttrs
['_v_transform_cache']
52 cacheTuple
= cache
.get('text_html', None) # (time, value)
54 cacheData
= cacheTuple
[1]
56 subObDict
= cacheData
.getSubObjects()
57 if subObDict
.has_key(name
) :
58 fileOb
= OFS
.Image
.File(name
, name
, subObDict
[name
])
61 raise AttributeError, name
63 security
.declareProtected(ModifyPortalContent
, 'edit')
64 def edit(self
, precondition
='', file=''):
65 orig_name
= OFS
.Image
.cookId('', '', file)[0]
67 self
.orig_name
= orig_name
68 BaseFile
.edit(self
, precondition
=precondition
, file=file)
69 if hasattr(self
, '_v_transform_cache') :
70 del self
._v
_transform
_cache
73 security
.declareProtected(View
, 'SearchableText')
74 def SearchableText(self
) :
75 """ Return full text"""
76 baseSearchableText
= BaseFile
.SearchableText(self
)
77 transformTool
= getToolByName(self
, 'portal_transforms', default
=None)
78 if transformTool
is None :
79 return baseSearchableText
81 datastream_text
= transformTool
.convertTo('text/plain',
83 mimetype
= self
.content_type
86 if datastream_text
is not None :
87 full_text
= datastream_text
.getData()
89 return baseSearchableText
+ full_text
91 security
.declareProtected(View
, 'preview')
93 """Return HTML preview if it's possible or empty string """
94 transformTool
= getToolByName(self
, 'portal_transforms', default
= None)
95 if transformTool
is None :
98 filename
= self
.getId().replace(' ', '_')
99 datastream
= transformTool
.convertTo('text/html',
102 mimetype
= self
.content_type
,
105 if datastream
is not None : return datastream
.getData()
108 security
.declareProtected(View
, 'download')
109 def download(self
, REQUEST
, RESPONSE
):
110 """Download this item.
112 Calls OFS.Image.File.index_html to perform the actual transfer after
113 first setting Content-Disposition to suggest a filename.
115 This method is deprecated, use the URL of this object itself. Because
116 the default view of a File object is to download, rather than view,
117 this method is obsolete. Also note that certain browsers do not deal
118 well with a Content-Disposition header.
122 RESPONSE
.setHeader('Content-Disposition',
123 'attachment; filename=%s' % (self
.orig_name
or self
.getId()))
124 return OFS
.Image
.File
.index_html(self
, REQUEST
, RESPONSE
)
126 security
.declarePublic('getIcon')
127 def getIcon(self
, relative_to_portal
=0):
128 """ return icon corresponding to mime-type
130 regTool
= getToolByName(self
, 'mimetypes_registry', default
=None)
132 mime
= regTool(str(self
.data
), mimetype
=self
.content_type
)[2]
133 return mime
.icon_path
135 return BaseFile
.getIcon(self
, relative_to_portal
=relative_to_portal
)
138 InitializeClass(File
)
139 FileFactory
= Factory(File
)
142 def addFile( dispatcher
151 , effective_date
=None
152 , expiration_date
=None
161 # cookId sets the id and title if they are not explicity specified
162 id, title
= OFS
.Image
.cookId(id, title
, file)
164 container
= dispatcher
.Destination()
166 # Instantiate the object and set its description.
167 fobj
= File( id, title
=title
, file='', content_type
=content_type
,
168 precondition
=precondition
, subject
=subject
, description
=description
,
169 contributors
=contributors
, effective_date
=effective_date
,
170 expiration_date
=expiration_date
, format
=format
,
171 language
=language
, rights
=rights
174 # Add the File instance to self
175 container
._setObject
(id, fobj
)
177 # 'Upload' the file. This is done now rather than in the
178 # constructor because the object is now in the ZODB and
179 # can span ZODB objects.
180 container
._getOb
(id).manage_upload(file)