root/CPS3/products/CPSLuceneCatalog/trunk/wrapper.py

Revision 50872, 7.5 kB (checked in by gracinet, 3 years ago)

Dublin core dates weren't properly indexed.

Line 
1 # (C) Copyright 2006 Nuxeo SAS <http://nuxeo.com>
2 # Author: Julien Anguenot <ja@nuxeo.com>
3 #
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License version 2 as published
6 # by the Free Software Foundation.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
16 # 02111-1307, USA.
17 #
18 # $Id: catalog.py 31177 2006-03-10 15:39:31Z janguenot $
19 """Indexable Object Wrapper for CPS.
20 """
21
22 from zLOG import LOG, WARNING
23
24 from Acquisition import aq_parent
25 from Acquisition import aq_inner
26 from Acquisition import aq_base
27
28 from DateTime.DateTime import DateTime
29
30 from Products.CMFCore.utils import getToolByName
31
32 from Products.CPSCore.ProxyBase import ProxyBase
33 from Products.CPSCore import utils as cpsutils
34 from Products.CPSDocument.CPSDocument import CPSDocument
35
36 DUBLIN_CORE_DATES = ('created', 'effective', 'expires', 'modified')
37
38 class IndexableObjectWrapper:
39     """This is a CPS adaptation of
40     CMFCore.CatalogTool.IndexableObjectWrapper"""
41
42     def __init__(self, vars, ob, lang=None, uid=None):
43         self.__vars = vars
44         self.__ob = ob
45         self.__lang = lang
46         self.__uid = uid
47
48         # lazy attributes (getattr makes infinite loops)
49         self.__ob_repo = None
50         self.__datamodel = None
51
52     def getRepoDoc(self):
53         doc = self.__ob_repo
54         if doc is not None:
55             return doc
56
57         self.__ob_repo = self.__ob.getContent(lang=self.__lang)
58         return self.__ob_repo
59        
60     def getDataModel(self):
61         dm = self.__datamodel
62         if dm is not None:
63             return dm
64
65         self.__datamodel = self.getRepoDoc().getDataModel(proxy=self.__ob)
66         return self.__datamodel
67
68     def __getattr__(self, name):
69         """This is the indexable wrapper getter for CPS,
70         proxy try to get the repository document attributes,
71         document in the repository hide some attributes to save some space."""
72         vars = self.__vars
73         if vars.has_key(name):
74             ret = vars[name]
75             # Here, deal with DateTime object values.
76             if isinstance(ret, DateTime):
77                 ret = ret.ISO()
78             return ret
79         ob = self.__ob
80         proxy = None
81         if isinstance(ob, ProxyBase):
82             proxy = ob
83             if name not in ('getId', 'id', 'getPhysicalPath', 'uid',
84                             'modified',
85                             'getDocid', 'isCPSFolderish'):
86                 # These attributes are computed from the proxy
87                 ob = self.getRepoDoc()
88
89         if isinstance(ob, CPSDocument):
90             # get the computed field value
91             ret = self.getDataModel().get(name)
92         if not isinstance(ob, CPSDocument) or ret is None:
93             try:
94                 ret = getattr(ob, name)
95             except AttributeError:
96                 if name == 'meta_type':
97                     # this is a fix for TextIndexNG2
98                     return None
99                 raise
100    
101         if proxy is not None and name == 'SearchableText':
102             # we add proxy id to searchableText
103             ret = ret() + ' ' + proxy.getId()
104
105         # use callable result if needed
106         # XXX GR: problem when it is portal_url for instance (think ack).
107         # It's useless except in the case of DateTime instances, because
108         # it is done by the next layer, nuxeo.lucene, which doesn't know about DateTime.
109         if callable(ret) and name in DUBLIN_CORE_DATES:
110             ret = ret()
111
112         # Check here if it's a date and return a string representation
113         # of the date since DateTime is not a Python standard object
114         if isinstance(ret, DateTime):
115             ret = ret.ISO()
116
117         return ret
118
119     def allowedRolesAndUsers(self):
120         """
121         Return a list of roles, users and groups with View permission.
122         Used by PortalCatalog to filter out items you're not allowed to see.
123         """
124         return cpsutils.getAllowedRolesAndUsersOfObject(self.__ob)
125
126     def localUsersWithRoles(self):
127         """
128         Return a list of users and groups having local roles.
129         Used by PortalCatalog to find which objects have roles for given
130         users and groups.
131         Only return proxies: see above __getattr__ raises
132         AttributeError when accessing this attribute.
133         """
134         ob = self.__ob
135         local_roles = ['user:%s' % r[0] for r in ob.get_local_roles()]
136         local_roles.extend(
137             ['group:%s' % r[0] for r in ob.get_local_group_roles()])
138         return local_roles
139
140     def path(self):
141         """PathIndex needs a path attribute, otherwise it uses
142         getPhysicalPath which fails for viewLanguage paths."""
143         if self.__uid is not None:
144             return self.__uid
145         else:
146             return self.__ob.getPhysicalPath()
147
148     def container_path(self):
149         """This is used to produce an index
150         return the parent full path."""
151         return '/'.join(self.__ob.getPhysicalPath()[:-1])
152
153     def relative_path(self):
154         """This is used to produce a metadata
155         return a path relative to the portal."""
156         utool = getToolByName(self, 'portal_url', None)
157         ret = ''
158         if utool:
159             # broken object can't aquire portal_url
160             ret = utool.getRelativeContentURL(self.__ob)
161         return ret
162
163     def relative_path_depth(self):
164         """This is used to produce an index
165         return the path depth relative to the portal."""
166         rpath = self.relative_path()
167         ret = -1
168         if rpath:
169             ret = rpath.count('/')+1
170         return ret
171
172     def position_in_container(self):
173         """Return the object position in the container."""
174         ob = self.__ob
175         container = aq_parent(aq_inner(ob))
176         if getattr(aq_base(container), 'getObjectPosition', None) is not None:
177             try:
178                 return container.getObjectPosition(ob.getId())
179             except ValueError, err:
180                 # Trying to index a doc before it is created ?
181                 LOG('position_in_container', WARNING,
182                     'got a Value Error %s' % err)
183                 return 0
184             except AttributeError, err:
185                 # Container without ordering support such as
186                 # BTreeFolder based folders. (proxy or not)
187                 LOG('position_in_container', WARNING,
188                     'got an AttributeError %s' % err)
189                 return 0
190         return 0
191
192     def match_languages(self):
193         """Return a list of languages that the proxy matches."""
194         ob = self.__ob
195         proxy_language = self.__lang
196         if proxy_language is None:
197             utool = getToolByName(self, 'portal_url', None)
198             if utool:
199                 # match_languages is used only with UI locales
200                 portal = utool.getPortalObject()
201                 return portal.getProperty('available_languages',
202                                           cpsutils.ALL_LOCALES)
203             return cpsutils.ALL_LOCALES
204         languages = [proxy_language]
205         if ob.getDefaultLanguage() == proxy_language:
206             languages.extend([lang for lang in cpsutils.ALL_LOCALES
207                               if lang not in ob.getProxyLanguages()])
208         return languages
209
Note: See TracBrowser for help on using the browser.