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 Products
.CMFCore
.interfaces
import IContentish
26 from Products
.CMFCore
.interfaces
.Contentish
import Contentish
as z2IContentish
28 from Products
.CMFCore
.DynamicType
import DynamicType
29 from Products
.CMFCore
.CMFCatalogAware
import CMFCatalogAware
30 from Products
.Photo
.Photo
import Photo
as BasePhoto
31 from Products
.CMFDefault
.DublinCore
import DefaultDublinCoreImpl
32 from Products
.CMFCore
.utils
import getToolByName
33 from Products
.Photo
.cache
import memoizedmethod
34 from Products
.DCWorkflow
.utils
import modifyRolesForPermission
35 from interfaces
import IPhoto
37 class Photo(DynamicType
, CMFCatalogAware
, BasePhoto
, DefaultDublinCoreImpl
) :
38 """ Photo CMF aware """
40 implements(IPhoto
, IContentish
)
41 __implements__
= (z2IContentish
, z2IWriteLock
, DynamicType
.__implements
__)
43 meta_type
= BasePhoto
.meta_type
44 manage_options
= BasePhoto
.manage_options
45 security
= ClassSecurityInfo()
47 security
.declareProtected(ViewRawImage
, 'index_html')
48 security
.declareProtected(ViewRawImage
, 'getJpegImage')
50 def __init__(self
, id, title
='', file='', content_type
='', precondition
='', **kw
) :
51 BasePhoto
.__init
__(self
, id, title
, file, content_type
=content_type
, precondition
=precondition
, **kw
)
56 self
.creation_date
= now
57 self
.modification_date
= now
59 def update_data(self
, data
, content_type
=None) :
60 BasePhoto
.update_data(self
, data
, content_type
=content_type
)
64 def _getAfterResizingHooks(self
) :
65 pim
= getToolByName(self
, 'portal_image_manipulation')
66 return pim
.image
.objectValues(['Script (Python)'])
68 def _getAfterTilingHooks(self
) :
69 pim
= getToolByName(self
, 'portal_image_manipulation')
70 return pim
.tile
.objectValues(['Script (Python)'])
73 # Dublin Core interface
76 security
.declareProtected(View
, 'Title')
79 """ returns dc:title from xmp
81 photoshopHeadline
= self
.getXmpValue('photoshop:Headline')
82 dcTitle
= self
.getXmpValue('dc:title')
84 return dcTitle
or photoshopHeadline
87 security
.declareProtected(View
, 'listCreators')
89 def listCreators(self
):
90 """ returns creator from dc:creator from xmp
92 return self
.getXmpValue('dc:creator')
95 security
.declareProtected(View
, 'Description')
97 def Description(self
) :
98 """ returns dc:description from xmp """
99 return self
.getXmpValue('dc:description')
102 security
.declareProtected(View
, 'Subject')
105 """ returns subject from dc:subject from xmp
107 return self
.getXmpValue('dc:subject')
109 security
.declareProtected(View
, 'Rights')
112 """ returns rights from dc:rights from xmp
114 return self
.getXmpValue('dc:rights')
116 security
.declareProtected(ModifyPortalContent
, 'editMetadata')
117 def editMetadata(self
, **kw
):
119 Need to add check for webDAV locked resource for TTW methods.
121 # as per bug #69, we cant assume they use the webdav
122 # locking interface, and fail gracefully if they dont
123 if hasattr(self
, 'failIfLocked'):
126 self
.setXmpFields(**kw
)
127 for name
in ('Title', 'listCreators', 'Description', 'Subject', 'Rights') :
128 self
._clearCacheFor
(name
)
132 def _clearCacheFor(self
, name
) :
134 del self
._methodResultsCache
[name
]
135 except KeyError : pass
138 security
.declareProtected(View
, 'SearchableText')
139 def SearchableText(self
):
140 """ Return textuals metadata"""
142 searchable
= (self
.Title()
144 , ' '.join(self
.Subject())
147 return ' '.join(searchable
)
149 security
.declareProtected(View
, 'DateTimeOriginal')
151 def DateTimeOriginal(self
) :
152 """ return DateTimeOriginal exif tag value or created """
153 dto
= self
.getXmpValue('exif:DateTimeOriginal')
157 return self
.created()
160 CreationDate
= DefaultDublinCoreImpl
.CreationDate
162 Format
= BasePhoto
.getContentType
164 security
.declareProtected(ReviewPortalContent
, 'hideForAnonymous')
166 def hideForAnonymous(self
, REQUEST
=None):
168 modifyRolesForPermission(self
, View
, ( 'Contributor'
174 self
._hiddenForAnon
= True
175 self
.reindexObjectSecurity()
176 self
.reindexObject(idxs
=['hiddenForAnonymous'])
179 security
.declareProtected(ReviewPortalContent
, 'resetHide')
181 def resetHide(self
, REQUEST
=None):
183 modifyRolesForPermission(self
, View
, [])
184 self
._hiddenForAnon
= False
185 self
.reindexObjectSecurity()
186 self
.reindexObject(idxs
=['hiddenForAnonymous'])
188 security
.declareProtected(View
, 'hiddenForAnonymous')
189 def hiddenForAnonymous(self
):
190 return getattr(self
, '_hiddenForAnon', False)
193 # security.declareProtected(AccessContentsInformation, 'position')
194 # def position(self):
195 # " returns position of self in parent container "
196 # parent = self.getParentNode()
197 # position = parent.getObjectPosition(self.getId())
202 # SimpleItem interface
205 def title_or_id(self
):
206 """Return the title if it is not blank and the id otherwise.
208 return self
.Title().strip() or self
.getId()
210 def title_and_id(self
):
211 """Return the title if it is not blank and the id otherwise.
213 If the title is not blank, then the id is included in parens.
217 return title
and ("%s (%s)" % (title
,id)) or id
220 InitializeClass(Photo
)
222 PhotoFactory
= Factory(Photo
)