vendor/CMF/1.6.3/CMFCore

view FSFile.py @ 2:4c712d7bd1d7

Added tag 1.6.3 for changeset 1babb9d61518
author Georges Racinet on purity.racinet.fr <georges@racinet.fr>
date Fri, 09 Sep 2011 12:44:00 +0200
parents
children
line source
1 ##############################################################################
2 #
3 # Copyright (c) 2001 Zope Corporation and Contributors. 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 """ Customizable image objects that come from the filesystem.
15 $Id$
16 """
18 import codecs
19 import Globals
20 from AccessControl import ClassSecurityInfo
21 from DateTime import DateTime
22 from OFS.Cache import Cacheable
23 from OFS.Image import File
24 try:
25 from zope.contenttype import guess_content_type
26 except ImportError:
27 # BBB: for Zope < 2.10
28 try:
29 from zope.app.content_types import guess_content_type
30 except ImportError:
31 # BBB: for Zope < 2.9
32 from OFS.content_types import guess_content_type
34 from DirectoryView import registerFileExtension
35 from DirectoryView import registerMetaType
36 from FSObject import FSObject
37 from permissions import FTPAccess
38 from permissions import View
39 from permissions import ViewManagementScreens
40 from utils import _dtmldir
41 from utils import _setCacheHeaders, _ViewEmulator
42 from utils import expandpath, _FSCacheHeaders, _checkConditionalGET
45 class FSFile(FSObject):
46 """FSFiles act like images but are not directly
47 modifiable from the management interface."""
48 # Note that OFS.Image.File is not a base class because it is mutable.
50 meta_type = 'Filesystem File'
52 manage_options=(
53 {'label':'Customize', 'action':'manage_main'},
54 ) + Cacheable.manage_options
56 security = ClassSecurityInfo()
57 security.declareObjectProtected(View)
59 def __init__(self, id, filepath, fullname=None, properties=None):
60 id = fullname or id # Use the whole filename.
61 FSObject.__init__(self, id, filepath, fullname, properties)
63 security.declareProtected(ViewManagementScreens, 'manage_main')
64 manage_main = Globals.DTMLFile('custfile', _dtmldir)
65 content_type = 'unknown/unknown'
67 def _createZODBClone(self):
68 return File(self.getId(), '', self._readFile(1))
70 def _get_content_type(self, file, body, id, content_type=None):
71 # Consult self.content_type first, this is either
72 # the default (unknown/unknown) or it got a value from a
73 # .metadata file
74 default_type = 'unknown/unknown'
75 if getattr(self, 'content_type', default_type) != default_type:
76 return self.content_type
78 # Next, look at file headers
79 headers=getattr(file, 'headers', None)
80 if headers and headers.has_key('content-type'):
81 content_type=headers['content-type']
82 else:
83 # Last resort: Use the (imperfect) content type guessing
84 # mechanism from OFS.Image, which ultimately uses the
85 # Python mimetypes module.
86 if not isinstance(body, basestring):
87 body = body.data
88 content_type, enc=guess_content_type(
89 getattr(file, 'filename',id), body, content_type)
90 if (enc is None
91 and (content_type.startswith('text/') or
92 content_type.startswith('application/'))
93 and body.startswith(codecs.BOM_UTF8)):
94 content_type += '; charset=utf-8'
96 return content_type
98 def _readFile(self, reparse):
99 fp = expandpath(self._filepath)
100 file = open(fp, 'rb')
101 try: data = file.read()
102 finally: file.close()
103 if reparse or self.content_type == 'unknown/unknown':
104 self.ZCacheable_invalidate()
105 self.content_type=self._get_content_type(file, data, self.id)
106 return data
108 #### The following is mainly taken from OFS/File.py ###
110 def __str__(self):
111 self._updateFromFS()
112 return str( self._readFile( 0 ) )
114 def modified(self):
115 return self.getModTime()
117 security.declareProtected(View, 'index_html')
118 def index_html(self, REQUEST, RESPONSE):
119 """
120 The default view of the contents of a File or Image.
122 Returns the contents of the file or image. Also, sets the
123 Content-Type HTTP header to the objects content type.
124 """
125 self._updateFromFS()
126 view = _ViewEmulator().__of__(self)
128 # If we have a conditional get, set status 304 and return
129 # no content
130 if _checkConditionalGET(view, extra_context={}):
131 return ''
133 RESPONSE.setHeader('Content-Type', self.content_type)
135 # old-style If-Modified-Since header handling.
136 if self._setOldCacheHeaders():
137 # Make sure the CachingPolicyManager gets a go as well
138 _setCacheHeaders(view, extra_context={})
139 return ''
141 data = self._readFile(0)
142 data_len = len(data)
143 RESPONSE.setHeader('Content-Length', data_len)
145 #There are 2 Cache Managers which can be in play....
146 #need to decide which to use to determine where the cache headers
147 #are decided on.
148 if self.ZCacheable_getManager() is not None:
149 self.ZCacheable_set(None)
150 else:
151 _setCacheHeaders(view, extra_context={})
152 return data
154 def _setOldCacheHeaders(self):
155 # return False to disable this simple caching behaviour
156 return _FSCacheHeaders(self)
158 security.declareProtected(View, 'getContentType')
159 def getContentType(self):
160 """Get the content type of a file or image.
162 Returns the content type (MIME type) of a file or image.
163 """
164 self._updateFromFS()
165 return self.content_type
167 security.declareProtected(FTPAccess, 'manage_FTPget')
168 manage_FTPget = index_html
170 Globals.InitializeClass(FSFile)
172 registerFileExtension('doc', FSFile)
173 registerFileExtension('pdf', FSFile)
174 registerFileExtension('swf', FSFile)
175 registerFileExtension('jar', FSFile)
176 registerFileExtension('cab', FSFile)
177 registerFileExtension('ico', FSFile)
178 registerFileExtension('js', FSFile)
179 registerFileExtension('css', FSFile)
180 registerMetaType('File', FSFile)