1 # -*- coding: utf-8 -*-
2 ############################################################
3 # Copyright © 2005-2008 Benoît PIN <benoit.pin@ensmp.fr> #
4 # Plinn - http://plinn.org #
6 # This program is free software; you can redistribute it #
7 # and/or modify it under the terms of the Creative Commons #
8 # "Attribution-Noncommercial 2.0 Generic" #
9 # http://creativecommons.org/licenses/by-nc/2.0/ #
10 ############################################################
14 from Globals
import InitializeClass
15 from AccessControl
import ClassSecurityInfo
16 from AccessControl
.requestmethod
import postonly
17 from DateTime
import DateTime
18 from Products
.CMFCore
.permissions
import View
, AccessContentsInformation
, \
19 ModifyPortalContent
, ManageProperties
, \
21 from permissions
import ViewRawImage
22 from zope
.component
.factory
import Factory
23 from zope
.interface
import implements
24 #from webdav.WriteLockInterface import WriteLockInterface as z2IWriteLock
25 from webdav
.interfaces
import IWriteLock
26 from Products
.CMFCore
.interfaces
import IContentish
27 from Products
.CMFCore
.interfaces
import IDynamicType
28 #from Products.CMFCore.interfaces.Contentish import Contentish as z2IContentish
30 from Products
.CMFCore
.DynamicType
import DynamicType
31 from Products
.CMFCore
.CMFCatalogAware
import CMFCatalogAware
32 from Products
.Photo
.Photo
import Photo
as BasePhoto
33 from Products
.CMFDefault
.DublinCore
import DefaultDublinCoreImpl
34 from Products
.CMFCore
.utils
import getToolByName
35 from Products
.Photo
.cache
import memoizedmethod
36 from Products
.DCWorkflow
.utils
import modifyRolesForPermission
37 from interfaces
import IPhoto
39 class Photo(DynamicType
, CMFCatalogAware
, BasePhoto
, DefaultDublinCoreImpl
) :
40 """ Photo CMF aware """
42 implements(IPhoto
, IContentish
, IWriteLock
, IDynamicType
)
43 #__implements__ = (z2IContentish, IWriteLock, DynamicType.__implements__)
45 meta_type
= BasePhoto
.meta_type
46 manage_options
= BasePhoto
.manage_options
47 security
= ClassSecurityInfo()
49 security
.declareProtected(ViewRawImage
, 'index_html')
50 security
.declareProtected(ViewRawImage
, 'getJpegImage')
52 def __init__(self
, id, title
='', file='', content_type
='', precondition
='', **kw
) :
53 DefaultDublinCoreImpl
.__init
__(self
, title
=title
)
54 BasePhoto
.__init
__(self
, id, title
, file, content_type
=content_type
, precondition
=precondition
, **kw
)
59 self
.creation_date
= now
60 self
.modification_date
= now
62 def update_data(self
, data
, content_type
=None) :
63 BasePhoto
.update_data(self
, data
, content_type
=content_type
)
67 def _getAfterResizingHooks(self
) :
68 pim
= getToolByName(self
, 'portal_image_manipulation')
69 return pim
.image
.objectValues(['Script (Python)'])
71 def _getAfterTilingHooks(self
) :
72 pim
= getToolByName(self
, 'portal_image_manipulation')
73 return pim
.tile
.objectValues(['Script (Python)'])
76 # Dublin Core interface
79 security
.declareProtected(View
, 'Title')
82 """ returns dc:title from xmp
84 photoshopHeadline
= self
.getXmpValue('photoshop:Headline')
85 dcTitle
= self
.getXmpValue('dc:title')
87 return dcTitle
or photoshopHeadline
90 security
.declareProtected(View
, 'listCreators')
92 def listCreators(self
):
93 """ returns creator from dc:creator from xmp
95 return self
.getXmpValue('dc:creator')
98 security
.declareProtected(View
, 'Description')
100 def Description(self
) :
101 """ returns dc:description from xmp """
102 return self
.getXmpValue('dc:description')
105 security
.declareProtected(View
, 'Subject')
108 """ returns subject from dc:subject from xmp
110 return self
.getXmpValue('dc:subject')
112 security
.declareProtected(View
, 'Rights')
115 """ returns rights from dc:rights from xmp
117 return self
.getXmpValue('dc:rights')
119 security
.declareProtected(ModifyPortalContent
, 'editMetadata')
120 def editMetadata(self
, **kw
):
122 Need to add check for webDAV locked resource for TTW methods.
124 # as per bug #69, we cant assume they use the webdav
125 # locking interface, and fail gracefully if they dont
126 if hasattr(self
, 'failIfLocked'):
129 self
.setXmpFields(**kw
)
130 for name
in ('Title', 'listCreators', 'Description', 'Subject', 'Rights') :
131 self
._clearCacheFor
(name
)
135 def _clearCacheFor(self
, name
) :
137 del self
._methodResultsCache
[name
]
138 except KeyError : pass
141 security
.declareProtected(View
, 'SearchableText')
142 def SearchableText(self
):
143 """ Return textuals metadata"""
145 searchable
= (self
.Title()
147 , ' '.join(self
.Subject())
150 return ' '.join(searchable
)
152 security
.declareProtected(View
, 'DateTimeOriginal')
154 def DateTimeOriginal(self
) :
155 """ return DateTimeOriginal exif tag value or created """
156 dto
= self
.getXmpValue('exif:DateTimeOriginal')
160 return self
.created()
163 CreationDate
= DefaultDublinCoreImpl
.CreationDate
165 Format
= BasePhoto
.getContentType
167 security
.declareProtected(ReviewPortalContent
, 'hideForAnonymous')
169 def hideForAnonymous(self
, REQUEST
=None):
171 modifyRolesForPermission(self
, View
, ( 'Contributor'
177 self
._hiddenForAnon
= True
178 self
.reindexObjectSecurity()
179 self
.reindexObject(idxs
=['hiddenForAnonymous'])
182 security
.declareProtected(ReviewPortalContent
, 'resetHide')
184 def resetHide(self
, REQUEST
=None):
186 modifyRolesForPermission(self
, View
, [])
187 self
._hiddenForAnon
= False
188 self
.reindexObjectSecurity()
189 self
.reindexObject(idxs
=['hiddenForAnonymous'])
191 security
.declareProtected(View
, 'hiddenForAnonymous')
192 def hiddenForAnonymous(self
):
193 return getattr(self
, '_hiddenForAnon', False)
196 # security.declareProtected(AccessContentsInformation, 'position')
197 # def position(self):
198 # " returns position of self in parent container "
199 # parent = self.getParentNode()
200 # position = parent.getObjectPosition(self.getId())
205 # SimpleItem interface
208 def title_or_id(self
):
209 """Return the title if it is not blank and the id otherwise.
211 return self
.Title().strip() or self
.getId()
213 def title_and_id(self
):
214 """Return the title if it is not blank and the id otherwise.
216 If the title is not blank, then the id is included in parens.
220 return title
and ("%s (%s)" % (title
,id)) or id
223 InitializeClass(Photo
)
225 PhotoFactory
= Factory(Photo
)