Back to index

plone3  3.1.7
Image.py
Go to the documentation of this file.
00001 ##############################################################################
00002 #
00003 # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
00004 #
00005 # This software is subject to the provisions of the Zope Public License,
00006 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
00007 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
00008 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00009 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
00010 # FOR A PARTICULAR PURPOSE.
00011 #
00012 ##############################################################################
00013 """ This module implements a portal-managed Image class. It is based on
00014 Zope's built-in Image object.
00015 
00016 $Id: Image.py 77345 2007-07-03 13:46:57Z yuppie $
00017 """
00018 
00019 import OFS.Image
00020 from AccessControl import ClassSecurityInfo
00021 from Globals import InitializeClass
00022 from OFS.Cache import Cacheable
00023 from zope.component.factory import Factory
00024 from zope.interface import implements
00025 
00026 from Products.CMFCore.PortalContent import PortalContent
00027 from Products.CMFCore.utils import _checkConditionalGET
00028 from Products.CMFCore.utils import _OldCacheHeaders
00029 from Products.CMFCore.utils import _setCacheHeaders
00030 from Products.CMFCore.utils import _ViewEmulator
00031 from Products.GenericSetup.interfaces import IDAVAware
00032 
00033 from DublinCore import DefaultDublinCoreImpl
00034 from interfaces import IImage
00035 from interfaces import IMutableImage
00036 from permissions import ModifyPortalContent
00037 from permissions import View
00038 
00039 
00040 def addImage( self
00041             , id
00042             , title=''
00043             , file=''
00044             , content_type=''
00045             , precondition=''
00046             , subject=()
00047             , description=''
00048             , contributors=()
00049             , effective_date=None
00050             , expiration_date=None
00051             , format='image/png'
00052             , language=''
00053             , rights=''
00054             ):
00055     """
00056         Add an Image
00057     """
00058 
00059     # cookId sets the id and title if they are not explicity specified
00060     id, title = OFS.Image.cookId(id, title, file)
00061 
00062     self=self.this()
00063 
00064     # Instantiate the object and set its description.
00065     iobj = Image( id, title, '', content_type, precondition, subject
00066                 , description, contributors, effective_date, expiration_date
00067                 , format, language, rights
00068                 )
00069 
00070     # Add the Image instance to self
00071     self._setObject(id, iobj)
00072 
00073     # 'Upload' the image.  This is done now rather than in the
00074     # constructor because it's faster (see File.py.)
00075     self._getOb(id).manage_upload(file)
00076 
00077 
00078 class Image(PortalContent, OFS.Image.Image, DefaultDublinCoreImpl):
00079 
00080     """A Portal-managed Image.
00081     """
00082 
00083     implements(IMutableImage, IImage, IDAVAware)
00084     __implements__ = ( PortalContent.__implements__
00085                      , DefaultDublinCoreImpl.__implements__
00086                      )
00087 
00088     effective_date = expiration_date = None
00089     icon = PortalContent.icon
00090 
00091     manage_options = ( PortalContent.manage_options
00092                      + Cacheable.manage_options
00093                      )
00094 
00095     security = ClassSecurityInfo()
00096 
00097     def __init__( self
00098                 , id
00099                 , title=''
00100                 , file=''
00101                 , content_type=''
00102                 , precondition=''
00103                 , subject=()
00104                 , description=''
00105                 , contributors=()
00106                 , effective_date=None
00107                 , expiration_date=None
00108                 , format=None
00109                 , language='en-US'
00110                 , rights=''
00111                 ):
00112         OFS.Image.File.__init__( self, id, title, file
00113                                , content_type, precondition )
00114         self._setId(id)
00115         delattr(self, '__name__')
00116 
00117         # If no file format has been passed in, rely on what OFS.Image.File
00118         # detected.
00119         if format is None:
00120             format = self.content_type
00121 
00122         DefaultDublinCoreImpl.__init__( self, title, subject, description
00123                                , contributors, effective_date, expiration_date
00124                                , format, language, rights )
00125 
00126     # For old instances where bases had OFS.Image.Image first,
00127     # the id was actually stored in __name__.
00128     # getId() will do the correct thing here, as id() is callable
00129     def id(self):
00130         return self.__name__
00131 
00132     security.declareProtected(View, 'SearchableText')
00133     def SearchableText(self):
00134         """
00135             SeachableText is used for full text seraches of a portal.
00136             It should return a concatanation of all useful text.
00137         """
00138         return "%s %s" % (self.title, self.description)
00139 
00140     security.declarePrivate('_isNotEmpty')
00141     def _isNotEmpty(self, file):
00142         """ Do various checks on 'file' to try to determine non emptiness. """
00143         if not file:
00144             return 0                    # Catches None, Missing.Value, ''
00145         elif file and (type(file) is type('')):
00146             return 1
00147         elif getattr(file, 'filename', None):
00148             return 1
00149         elif not hasattr(file, 'read'):
00150             return 0
00151         else:
00152             file.seek(0,2)              # 0 bytes back from end of file
00153             t = file.tell()             # Report the location
00154             file.seek(0)                # and return pointer back to 0
00155             if t: return 1
00156             else: return 0
00157 
00158     security.declarePrivate('_edit')
00159     def _edit(self, precondition='', file=''):
00160         """ Update image. """
00161         if precondition: self.precondition = precondition
00162         elif self.precondition: del self.precondition
00163 
00164         if self._isNotEmpty(file):
00165             self.manage_upload(file)
00166 
00167     security.declareProtected(ModifyPortalContent, 'edit')
00168     def edit(self, precondition='', file=''):
00169         """ Update and reindex. """
00170         self._edit( precondition, file )
00171         self.reindexObject()
00172 
00173     security.declareProtected(View, 'index_html')
00174     def index_html(self, REQUEST, RESPONSE):
00175         """
00176         Display the image, with or without standard_html_[header|footer],
00177         as appropriate.
00178         """
00179         view = _ViewEmulator().__of__(self)
00180 
00181         # If we have a conditional get, set status 304 and return
00182         # no content
00183         if _checkConditionalGET(view, extra_context={}):
00184             return ''
00185 
00186         # old-style If-Modified-Since header handling.
00187         if self._setOldCacheHeaders():
00188             # Make sure the CachingPolicyManager gets a go as well
00189             _setCacheHeaders(view, extra_context={})
00190             return ''
00191 
00192         rendered = OFS.Image.Image.index_html(self, REQUEST, RESPONSE)
00193 
00194         if self.ZCacheable_getManager() is None:
00195             # not none cache manager already taken care of
00196             _setCacheHeaders(view, extra_context={})
00197         else:
00198             self.ZCacheable_set(None)
00199 
00200         return rendered
00201 
00202     security.declarePrivate('_setOldCacheHeaders')
00203     def _setOldCacheHeaders(self):
00204         # return False to disable this simple caching behaviour
00205         return _OldCacheHeaders(self)
00206 
00207     security.declareProtected(View, 'Format')
00208     def Format(self):
00209         """ Dublin Core element - resource format """
00210         return self.content_type
00211 
00212     security.declareProtected(ModifyPortalContent, 'setFormat')
00213     def setFormat(self, format):
00214         """ Dublin Core element - resource format """
00215         self.manage_changeProperties(content_type=format)
00216 
00217     security.declareProtected(ModifyPortalContent, 'PUT')
00218     def PUT(self, REQUEST, RESPONSE):
00219         """ Handle HTTP (and presumably FTP?) PUT requests """
00220         OFS.Image.Image.PUT( self, REQUEST, RESPONSE )
00221         self.reindexObject()
00222 
00223 InitializeClass(Image)
00224 
00225 ImageFactory = Factory(Image)