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 ############################################################
12 $Id: photo.py 1202 2009-07-15 08:48:42Z pin $
13 $URL: http://svn.luxia.fr/svn/labo/projects/zope/Portfolio/trunk/photo.py $
16 from Globals
import InitializeClass
17 from AccessControl
import ClassSecurityInfo
18 from AccessControl
.requestmethod
import postonly
19 from DateTime
import DateTime
20 from Products
.CMFCore
.permissions
import View
, AccessContentsInformation
, \
21 ModifyPortalContent
, ManageProperties
, \
23 from permissions
import ViewRawImage
24 from zope
.component
.factory
import Factory
25 from zope
.interface
import implements
26 from webdav
.WriteLockInterface
import WriteLockInterface
as z2IWriteLock
27 from Products
.CMFCore
.interfaces
import IContentish
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
)
43 __implements__
= (z2IContentish
, z2IWriteLock
, 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 BasePhoto
.__init
__(self
, id, title
, file, content_type
=content_type
, precondition
=precondition
, **kw
)
58 self
.creation_date
= now
59 self
.modification_date
= now
61 def update_data(self
, data
, content_type
=None) :
62 BasePhoto
.update_data(self
, data
, content_type
=content_type
)
66 def _getAfterResizingHooks(self
) :
67 pim
= getToolByName(self
, 'portal_image_manipulation')
68 return pim
.image
.objectValues(['Script (Python)'])
70 def _getAfterTilingHooks(self
) :
71 pim
= getToolByName(self
, 'portal_image_manipulation')
72 return pim
.tile
.objectValues(['Script (Python)'])
75 # Dublin Core interface
78 security
.declareProtected(View
, 'Title')
81 """ returns dc:title from xmp
83 photoshopHeadline
= self
.getXmpValue('photoshop:Headline')
84 dcTitle
= self
.getXmpValue('dc:title')
86 return dcTitle
or photoshopHeadline
89 security
.declareProtected(View
, 'listCreators')
91 def listCreators(self
):
92 """ returns creator from dc:creator from xmp
94 return self
.getXmpValue('dc:creator')
97 security
.declareProtected(View
, 'Description')
99 def Description(self
) :
100 """ returns dc:description from xmp """
101 return self
.getXmpValue('dc:description')
104 security
.declareProtected(View
, 'Subject')
107 """ returns subject from dc:subject from xmp
109 return self
.getXmpValue('dc:subject')
111 security
.declareProtected(View
, 'Rights')
114 """ returns rights from dc:rights from xmp
116 return self
.getXmpValue('dc:rights')
118 security
.declareProtected(ModifyPortalContent
, 'editMetadata')
119 def editMetadata(self
, **kw
):
121 Need to add check for webDAV locked resource for TTW methods.
123 # as per bug #69, we cant assume they use the webdav
124 # locking interface, and fail gracefully if they dont
125 if hasattr(self
, 'failIfLocked'):
128 self
.setXmpFields(**kw
)
129 for name
in ('Title', 'listCreators', 'Description', 'Subject', 'Rights') :
130 self
._clearCacheFor
(name
)
134 def _clearCacheFor(self
, name
) :
136 del self
._methodResultsCache
[name
]
137 except KeyError : pass
140 security
.declareProtected(View
, 'SearchableText')
141 def SearchableText(self
):
142 """ Return textuals metadata"""
144 searchable
= (self
.Title()
146 , ' '.join(self
.Subject())
149 return ' '.join(searchable
)
151 security
.declareProtected(View
, 'DateTimeOriginal')
153 def DateTimeOriginal(self
) :
154 """ return DateTimeOriginal exif tag value or created """
155 dto
= self
.getXmpValue('exif:DateTimeOriginal')
159 return self
.created()
162 CreationDate
= DefaultDublinCoreImpl
.CreationDate
164 Format
= BasePhoto
.getContentType
166 security
.declareProtected(ReviewPortalContent
, 'hideForAnonymous')
168 def hideForAnonymous(self
, REQUEST
=None):
170 modifyRolesForPermission(self
, View
, ( 'Contributor'
176 self
._hiddenForAnon
= True
177 self
.reindexObjectSecurity()
178 self
.reindexObject(idxs
=['hiddenForAnonymous'])
181 security
.declareProtected(ReviewPortalContent
, 'resetHide')
183 def resetHide(self
, REQUEST
=None):
185 modifyRolesForPermission(self
, View
, [])
186 self
._hiddenForAnon
= False
187 self
.reindexObjectSecurity()
188 self
.reindexObject(idxs
=['hiddenForAnonymous'])
190 security
.declareProtected(View
, 'hiddenForAnonymous')
191 def hiddenForAnonymous(self
):
192 return getattr(self
, '_hiddenForAnon', False)
195 # security.declareProtected(AccessContentsInformation, 'position')
196 # def position(self):
197 # " returns position of self in parent container "
198 # parent = self.getParentNode()
199 # position = parent.getObjectPosition(self.getId())
204 # SimpleItem interface
207 def title_or_id(self
):
208 """Return the title if it is not blank and the id otherwise.
210 return self
.Title().strip() or self
.getId()
212 def title_and_id(self
):
213 """Return the title if it is not blank and the id otherwise.
215 If the title is not blank, then the id is included in parens.
219 return title
and ("%s (%s)" % (title
,id)) or id
222 InitializeClass(Photo
)
224 PhotoFactory
= Factory(Photo
)