Back to index

plone3  3.1.7
DublinCore.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 """ Dublin Core support for content types.
00014 
00015 $Id: DublinCore.py 77186 2007-06-28 19:06:19Z yuppie $
00016 """
00017 
00018 from AccessControl import ClassSecurityInfo
00019 from Acquisition import aq_base
00020 from DateTime.DateTime import DateTime
00021 from Globals import DTMLFile
00022 from Globals import InitializeClass
00023 from OFS.PropertyManager import PropertyManager
00024 from zope.interface import implements
00025 
00026 from Products.CMFCore.interfaces import ICatalogableDublinCore
00027 from Products.CMFCore.interfaces import IDublinCore
00028 from Products.CMFCore.interfaces import IMutableDublinCore
00029 from Products.CMFCore.interfaces.DublinCore \
00030         import CatalogableDublinCore as z2ICatalogableDublinCore
00031 from Products.CMFCore.interfaces.DublinCore \
00032         import DublinCore as z2IDublinCore
00033 from Products.CMFCore.interfaces.DublinCore \
00034         import MutableDublinCore as z2IMutableDublinCore
00035 from Products.CMFCore.utils import getToolByName
00036 
00037 from permissions import ModifyPortalContent
00038 from permissions import View
00039 from utils import _dtmldir
00040 from utils import semi_split
00041 from utils import tuplize
00042 
00043 _marker=[]
00044 
00045 # For http://www.zope.org/Collectors/CMF/325
00046 # We only really need this once, at startup.
00047 _zone = DateTime().timezone()
00048 
00049 
00050 class DefaultDublinCoreImpl( PropertyManager ):
00051 
00052     """ Mix-in class which provides Dublin Core methods.
00053     """
00054 
00055     implements(IDublinCore, ICatalogableDublinCore, IMutableDublinCore)
00056     __implements__ = (z2IDublinCore, z2ICatalogableDublinCore,
00057                       z2IMutableDublinCore)
00058 
00059     security = ClassSecurityInfo()
00060 
00061     def __init__( self
00062                 , title=''
00063                 , subject=()
00064                 , description=''
00065                 , contributors=()
00066                 , effective_date=None
00067                 , expiration_date=None
00068                 , format='text/html'
00069                 , language=''
00070                 , rights=''
00071                 ):
00072         now = DateTime()
00073         self.creation_date = now
00074         self.modification_date = now
00075         self.creators = ()
00076         self._editMetadata( title
00077                           , subject
00078                           , description
00079                           , contributors
00080                           , effective_date
00081                           , expiration_date
00082                           , format
00083                           , language
00084                           , rights
00085                           )
00086 
00087     #
00088     #  Set-modification-date-related methods.
00089     #  In DefaultDublinCoreImpl for lack of a better place.
00090     #
00091 
00092     # Class variable default for an upgrade.
00093     modification_date = None
00094 
00095     security.declarePrivate('notifyModified')
00096     def notifyModified(self):
00097         """ Take appropriate action after the resource has been modified.
00098 
00099         Update creators and modification_date.
00100         """
00101         self.addCreator()
00102         self.setModificationDate()
00103 
00104     security.declareProtected(ModifyPortalContent, 'addCreator')
00105     def addCreator(self, creator=None):
00106         """ Add creator to Dublin Core creators.
00107         """
00108         if creator is None:
00109             mtool = getToolByName(self, 'portal_membership', None)
00110             creator = mtool and mtool.getAuthenticatedMember().getId()
00111 
00112         # call self.listCreators() to make sure self.creators exists
00113         if creator and not creator in self.listCreators():
00114             self.creators = self.creators + (creator, )
00115 
00116     security.declareProtected(ModifyPortalContent, 'setModificationDate')
00117     def setModificationDate(self, modification_date=None):
00118         """ Set the date when the resource was last modified.
00119 
00120         When called without an argument, sets the date to now.
00121         """
00122         if modification_date is None:
00123             self.modification_date = DateTime()
00124         else:
00125             self.modification_date = self._datify(modification_date)
00126 
00127     #
00128     #  DublinCore interface query methods
00129     #
00130     security.declareProtected(View, 'Title')
00131     def Title( self ):
00132         """ Dublin Core Title element - resource name.
00133         """
00134         return self.title
00135 
00136     security.declareProtected(View, 'listCreators')
00137     def listCreators(self):
00138         """ List Dublin Core Creator elements - resource authors.
00139         """
00140         if not hasattr(aq_base(self), 'creators'):
00141             # for content created with CMF versions before 1.5
00142             owner_tuple = self.getOwnerTuple()
00143             if owner_tuple:
00144                 self.creators = (owner_tuple[1],)
00145             else:
00146                 self.creators = ()
00147         return self.creators
00148 
00149     security.declareProtected(View, 'Creator')
00150     def Creator(self):
00151         """ Dublin Core Creator element - resource author.
00152         """
00153         creators = self.listCreators()
00154         return creators and creators[0] or ''
00155 
00156     security.declareProtected(View, 'Subject')
00157     def Subject( self ):
00158         """ Dublin Core Subject element - resource keywords.
00159         """
00160         return getattr( self, 'subject', () ) # compensate for *old* content
00161 
00162     security.declareProtected(View, 'Description')
00163     def Description( self ):
00164         """ Dublin Core Description element - resource summary.
00165         """
00166         return self.description
00167 
00168     security.declareProtected(View, 'Publisher')
00169     def Publisher( self ):
00170         """ Dublin Core Publisher element - resource publisher.
00171         """
00172         tool = getToolByName(self, 'portal_metadata', None)
00173 
00174         if tool is not None:
00175             return tool.getPublisher()
00176 
00177         return 'No publisher'
00178 
00179     security.declareProtected(View, 'listContributors')
00180     def listContributors(self):
00181         """ Dublin Core Contributor elements - resource collaborators.
00182         """
00183         return self.contributors
00184 
00185     security.declareProtected(View, 'Contributors')
00186     def Contributors(self):
00187         """ Deprecated alias of listContributors.
00188         """
00189         return self.listContributors()
00190 
00191     security.declareProtected(View, 'Date')
00192     def Date( self, zone=None ):
00193         """ Dublin Core Date element - default date.
00194         """
00195         if zone is None:
00196             zone = _zone
00197         # Return effective_date if set, modification date otherwise
00198         date = getattr(self, 'effective_date', None )
00199         if date is None:
00200             date = self.modified()
00201         return date.toZone(zone).ISO()
00202 
00203     security.declareProtected(View, 'CreationDate')
00204     def CreationDate( self, zone=None ):
00205         """ Dublin Core Date element - date resource created.
00206         """
00207         if zone is None:
00208             zone = _zone
00209         # return unknown if never set properly
00210         if self.creation_date:
00211             return self.creation_date.toZone(zone).ISO()
00212         else:
00213             return 'Unknown'
00214 
00215     security.declareProtected(View, 'EffectiveDate')
00216     def EffectiveDate( self, zone=None ):
00217         """ Dublin Core Date element - date resource becomes effective.
00218         """
00219         if zone is None:
00220             zone = _zone
00221         ed = getattr( self, 'effective_date', None )
00222         return ed and ed.toZone(zone).ISO() or 'None'
00223 
00224     security.declareProtected(View, 'ExpirationDate')
00225     def ExpirationDate( self, zone=None ):
00226         """ Dublin Core Date element - date resource expires.
00227         """
00228         if zone is None:
00229             zone = _zone
00230         ed = getattr( self, 'expiration_date', None )
00231         return ed and ed.toZone(zone).ISO() or 'None'
00232 
00233     security.declareProtected(View, 'ModificationDate')
00234     def ModificationDate( self, zone=None ):
00235         """ Dublin Core Date element - date resource last modified.
00236         """
00237         if zone is None:
00238             zone = _zone
00239         return self.modified().toZone(zone).ISO()
00240 
00241     security.declareProtected(View, 'Type')
00242     def Type( self ):
00243         """ Dublin Core Type element - resource type.
00244         """
00245         ti = self.getTypeInfo()
00246         return ti is not None and ti.Title() or 'Unknown'
00247 
00248     security.declareProtected(View, 'Format')
00249     def Format( self ):
00250         """ Dublin Core Format element - resource format.
00251         """
00252         return self.format
00253 
00254     security.declareProtected(View, 'Identifier')
00255     def Identifier( self ):
00256         """ Dublin Core Identifier element - resource ID.
00257         """
00258         # XXX: fixme using 'portal_metadata' (we need to prepend the
00259         #      right prefix to self.getPhysicalPath().
00260         return self.absolute_url()
00261 
00262     security.declareProtected(View, 'Language')
00263     def Language( self ):
00264         """ Dublin Core Language element - resource language.
00265         """
00266         return self.language
00267 
00268     security.declareProtected(View, 'Rights')
00269     def Rights( self ):
00270         """ Dublin Core Rights element - resource copyright.
00271         """
00272         return self.rights
00273 
00274     #
00275     #  DublinCore utility methods
00276     #
00277     def content_type( self ):
00278         """ WebDAV needs this to do the Right Thing (TM).
00279         """
00280         return self.Format()
00281 
00282     __FLOOR_DATE = DateTime( 1970, 0 ) # always effective
00283 
00284     security.declareProtected(View, 'isEffective')
00285     def isEffective( self, date ):
00286         """ Is the date within the resource's effective range?
00287         """
00288         pastEffective = ( self.effective_date is None
00289                        or self.effective_date <= date )
00290         beforeExpiration = ( self.expiration_date is None
00291                           or self.expiration_date >= date )
00292         return pastEffective and beforeExpiration
00293 
00294     #
00295     #  CatalogableDublinCore methods
00296     #
00297     security.declareProtected(View, 'created')
00298     def created( self ):
00299         """ Dublin Core Date element - date resource created.
00300         """
00301         # allow for non-existent creation_date, existed always
00302         date = getattr( self, 'creation_date', None )
00303         return date is None and self.__FLOOR_DATE or date
00304 
00305     security.declareProtected(View, 'effective')
00306     def effective( self ):
00307         """ Dublin Core Date element - date resource becomes effective.
00308         """
00309         marker = []
00310         date = getattr( self, 'effective_date', marker )
00311         if date is marker:
00312             date = getattr( self, 'creation_date', None )
00313         return date is None and self.__FLOOR_DATE or date
00314 
00315     __CEILING_DATE = DateTime( 2500, 0 ) # never expires
00316 
00317     security.declareProtected(View, 'expires')
00318     def expires( self ):
00319         """ Dublin Core Date element - date resource expires.
00320         """
00321         date = getattr( self, 'expiration_date', None )
00322         return date is None and self.__CEILING_DATE or date
00323 
00324     security.declareProtected(View, 'modified')
00325     def modified( self ):
00326         """ Dublin Core Date element - date resource last modified.
00327         """
00328         date = self.modification_date
00329         if date is None:
00330             # Upgrade.
00331             date = self.bobobase_modification_time()
00332             self.modification_date = date
00333         return date
00334 
00335     security.declareProtected(View, 'getMetadataHeaders')
00336     def getMetadataHeaders( self ):
00337         """ Return RFC-822-style headers.
00338         """
00339         hdrlist = []
00340         hdrlist.append( ( 'Title', self.Title() ) )
00341         hdrlist.append( ( 'Subject', ', '.join( self.Subject() ) ) )
00342         hdrlist.append( ( 'Publisher', self.Publisher() ) )
00343         hdrlist.append( ( 'Description', self.Description() ) )
00344         hdrlist.append( ( 'Contributors', '; '.join( self.Contributors() ) ) )
00345         hdrlist.append( ( 'Effective_date', self.EffectiveDate() ) )
00346         hdrlist.append( ( 'Expiration_date', self.ExpirationDate() ) )
00347         hdrlist.append( ( 'Type', self.Type() ) )
00348         hdrlist.append( ( 'Format', self.Format() ) )
00349         hdrlist.append( ( 'Language', self.Language() ) )
00350         hdrlist.append( ( 'Rights', self.Rights() ) )
00351         return hdrlist
00352 
00353     #
00354     #  MutableDublinCore methods
00355     #
00356     security.declarePrivate( '_datify' )
00357     def _datify( self, attrib ):
00358         if attrib == 'None':
00359             attrib = None
00360         elif not isinstance( attrib, DateTime ):
00361             if attrib is not None:
00362                 attrib = DateTime( attrib )
00363         return attrib
00364 
00365     security.declareProtected(ModifyPortalContent, 'setTitle')
00366     def setTitle( self, title ):
00367         """ Set Dublin Core Title element - resource name.
00368         """
00369         self.title = title
00370 
00371     security.declareProtected(ModifyPortalContent, 'setCreators')
00372     def setCreators(self, creators):
00373         """ Set Dublin Core Creator elements - resource authors.
00374         """
00375         self.creators = tuplize('creators', creators)
00376 
00377     security.declareProtected(ModifyPortalContent, 'setSubject')
00378     def setSubject( self, subject ):
00379         """ Set Dublin Core Subject element - resource keywords.
00380         """
00381         self.subject = tuplize( 'subject', subject )
00382 
00383     security.declareProtected(ModifyPortalContent, 'setDescription')
00384     def setDescription( self, description ):
00385         """ Set Dublin Core Description element - resource summary.
00386         """
00387         self.description = description
00388 
00389     security.declareProtected(ModifyPortalContent, 'setContributors')
00390     def setContributors( self, contributors ):
00391         """ Set Dublin Core Contributor elements - resource collaborators.
00392         """
00393         # XXX: fixme
00394         self.contributors = tuplize('contributors', contributors, semi_split)
00395 
00396     security.declareProtected(ModifyPortalContent, 'setEffectiveDate')
00397     def setEffectiveDate( self, effective_date ):
00398         """ Set Dublin Core Date element - date resource becomes effective.
00399         """
00400         self.effective_date = self._datify( effective_date )
00401 
00402     security.declareProtected(ModifyPortalContent, 'setExpirationDate')
00403     def setExpirationDate( self, expiration_date ):
00404         """ Set Dublin Core Date element - date resource expires.
00405         """
00406         self.expiration_date = self._datify( expiration_date )
00407 
00408     security.declareProtected(ModifyPortalContent, 'setFormat')
00409     def setFormat( self, format ):
00410         """ Set Dublin Core Format element - resource format.
00411         """
00412         self.format = format
00413 
00414     security.declareProtected(ModifyPortalContent, 'setLanguage')
00415     def setLanguage( self, language ):
00416         """ Set Dublin Core Language element - resource language.
00417         """
00418         self.language = language
00419 
00420     security.declareProtected(ModifyPortalContent, 'setRights')
00421     def setRights( self, rights ):
00422         """ Set Dublin Core Rights element - resource copyright.
00423         """
00424         self.rights = rights
00425 
00426     #
00427     #  Management tab methods
00428     #
00429 
00430     security.declarePrivate( '_editMetadata' )
00431     def _editMetadata( self
00432                      , title=_marker
00433                      , subject=_marker
00434                      , description=_marker
00435                      , contributors=_marker
00436                      , effective_date=_marker
00437                      , expiration_date=_marker
00438                      , format=_marker
00439                      , language=_marker
00440                      , rights=_marker
00441                      ):
00442         """ Update the editable metadata for this resource.
00443         """
00444         if title is not _marker:
00445             self.setTitle( title )
00446         if subject is not _marker:
00447             self.setSubject( subject )
00448         if description is not _marker:
00449             self.setDescription( description )
00450         if contributors is not _marker:
00451             self.setContributors( contributors )
00452         if effective_date is not _marker:
00453             self.setEffectiveDate( effective_date )
00454         if expiration_date is not _marker:
00455             self.setExpirationDate( expiration_date )
00456         if format is not _marker:
00457             self.setFormat( format )
00458         if language is not _marker:
00459             self.setLanguage( language )
00460         if rights is not _marker:
00461             self.setRights( rights )
00462 
00463     security.declareProtected(ModifyPortalContent, 'manage_metadata')
00464     manage_metadata = DTMLFile( 'zmi_metadata', _dtmldir )
00465 
00466     security.declareProtected(ModifyPortalContent, 'manage_editMetadata')
00467     def manage_editMetadata( self
00468                            , title
00469                            , subject
00470                            , description
00471                            , contributors
00472                            , effective_date
00473                            , expiration_date
00474                            , format
00475                            , language
00476                            , rights
00477                            , REQUEST
00478                            ):
00479         """ Update metadata from the ZMI.
00480         """
00481         self._editMetadata( title, subject, description, contributors
00482                           , effective_date, expiration_date
00483                           , format, language, rights
00484                           )
00485         REQUEST[ 'RESPONSE' ].redirect( self.absolute_url()
00486                                 + '/manage_metadata'
00487                                 + '?manage_tabs_message=Metadata+updated.' )
00488 
00489     security.declareProtected(ModifyPortalContent, 'editMetadata')
00490     def editMetadata(self
00491                    , title=''
00492                    , subject=()
00493                    , description=''
00494                    , contributors=()
00495                    , effective_date=None
00496                    , expiration_date=None
00497                    , format='text/html'
00498                    , language='en-US'
00499                    , rights=''
00500                     ):
00501         """
00502         Need to add check for webDAV locked resource for TTW methods.
00503         """
00504         # as per bug #69, we cant assume they use the webdav
00505         # locking interface, and fail gracefully if they dont
00506         if hasattr(self, 'failIfLocked'):
00507             self.failIfLocked()
00508 
00509         self._editMetadata(title=title
00510                      , subject=subject
00511                      , description=description
00512                      , contributors=contributors
00513                      , effective_date=effective_date
00514                      , expiration_date=expiration_date
00515                      , format=format
00516                      , language=language
00517                      , rights=rights
00518                      )
00519         self.reindexObject()
00520 
00521 InitializeClass(DefaultDublinCoreImpl)