root/qTopic/trunk/patch.py

Revision 397 (checked in by crchemist, 2 years ago)

Added new tests and fix errors.

Line 
1 from Products.ATContentTypes.tool.topic import ATTopicsTool
2
3 from Globals import InitializeClass
4 from Products.CMFCore.utils import getToolByName
5 from Products.ATContentTypes.criteria import _criterionRegistry
6 from AccessControl import ClassSecurityInfo
7 import Persistence
8 from OFS.SimpleItem import SimpleItem
9 from ExtensionClass import Base
10 from Acquisition import aq_base
11
12 from Products.CMFCore.permissions import ManagePortal
13 from Products.ATContentTypes.interfaces import IATCTTopicsTool
14
15 from Products.Archetypes.public import DisplayList
16 from Products.CMFPlone.CatalogTool import CatalogTool
17 from Products.ATContentTypes.config import TOOLNAME
18
19 from Products.ATContentTypes.tool.topic import TopicIndex
20 from Products.ATContentTypes.configuration import zconf
21 tool_config = zconf.atct_tool.topic_tool
22
23 def __init__(self):
24         self.topic_indexes = {}
25         self.topic_indexes[CatalogTool.id] = {}
26         self.topic_metadata = {}
27         self.topic_metadata[CatalogTool.id] = {}
28         self.allowed_portal_types = []
29
30 def _initializeTopicTool(self):
31     """Helper method to initialize the topic tool
32     """
33     metadata = getattr(aq_base(self), 'topic_metadata', None)
34     #test if metadata is empty or non existant, if so reinit.
35     if not metadata:
36         self.topic_indexes = {}
37         self.topic_indexes[CatalogTool.id] = {}
38         self.topic_metadata = {}
39         self.topic_metadata[CatalogTool.id] = {}
40         self.allowed_portal_types = []
41         self.createInitialIndexes()
42         self.createInitialMetadata()
43         catalog_name = CatalogTool.id
44         for index in tool_config.indexes:
45             fn = getattr(index,'friendlyName',None)
46             desc = getattr(index,'description',None)
47             enabled = getattr(index,'enabled',None)
48             criteria = getattr(index,'criteria',None)
49             self.updateIndex(index.name, fn, desc, enabled, criteria, catalog_name)
50         for meta in tool_config.metadata:
51             fn = getattr(meta,'friendlyName',None)
52             desc = getattr(meta,'description',None)
53             enabled = getattr(meta,'enabled',None)
54             self.updateMetadata(meta.name, fn, desc, enabled, catalog_name)
55         return True
56     else:
57         return False
58
59 def getCriteriaForIndex(self, index, as_dict=False, catalog_name=CatalogTool.id):
60     """ Returns the valid criteria for a given index """
61     catalog_tool = getToolByName(self, catalog_name)
62     try:
63          indexObj = catalog_tool.Indexes[index]
64     except KeyError:
65         return ()
66     criteria = tuple(_criterionRegistry.criteriaByIndex(indexObj.meta_type))
67     search_criteria = _criterionRegistry.listSearchTypes()
68     if as_dict:
69         criteria = [{'name': a, 'description': _criterionRegistry[a].shortDesc}
70                             for a in criteria if a in search_criteria]
71     else:
72         criteria = [a for a in criteria if a in search_criteria]
73     criteria.sort()
74     return criteria
75
76
77
78 def addIndex(self, index, friendlyName='', description='', enabled=False, criteria=None, catalog_name=CatalogTool.id):
79     """ Add a new index along with descriptive information to the index
80         registry """
81
82     if not self.topic_indexes.has_key(catalog_name):
83         self.topic_indexes[catalog_name]={}
84
85     if criteria is None: criteria = self.getCriteriaForIndex(index, catalog_name)
86     if self.topic_indexes[catalog_name].has_key(index):
87         objIndex = self.topic_indexes[catalog_name][index]
88         objIndex.friendlyName=friendlyName
89         objIndex.description=description
90         objIndex.enabled=enabled
91         objIndex.criteria=tuple(criteria)
92     else:
93         objIndex = TopicIndex(index, friendlyName, description, enabled, criteria)
94
95     self.topic_indexes[catalog_name][index]=objIndex
96     self._p_changed=1
97
98
99 def addMetadata(self, metadata, friendlyName='', description='', enabled=False, catalog_name=CatalogTool.id):
100     """ Add a new metadata field along with descriptive information to the
101         metadata registry """
102
103     if not self.topic_metadata.has_key(catalog_name):
104         self.topic_metadata[catalog_name]={}
105
106     if self.topic_metadata[catalog_name].has_key(metadata):
107         objMeta = self.topic_metadata[catalog_name][metadata]
108         objMeta.friendlyName=friendlyName
109         objMeta.description=description
110         objMeta.enabled=enabled
111     else:
112         objMeta = TopicIndex(metadata, friendlyName, description, enabled)
113
114     if not self.topic_metadata[catalog_name]:
115         self.topic_metadata[catalog_name] = {}
116     self.topic_metadata[catalog_name][metadata]=objMeta
117     self._p_changed=1
118
119
120
121 def updateIndex(self, index, friendlyName=None, description=None, enabled=None, criteria=None, catalog_name=CatalogTool.id):
122     """ Updates an existing index in the registry, unrecognized values are
123         added """
124
125     indexes = self.topic_indexes[catalog_name]
126     if friendlyName == None:
127         friendlyName = indexes[index].friendlyName
128     if description == None:
129         description = indexes[index].description
130     if enabled == None:
131         enabled = indexes[index].enabled
132     if criteria == None:
133         criteria = indexes[index].criteria
134     self.addIndex(index, friendlyName, description, enabled, criteria, catalog_name)
135
136
137 def updateMetadata(self, metadata, friendlyName=None, description=None, enabled=None, catalog_name=CatalogTool.id):
138     """ Updates an existing metadata field in the registry, unrecognized values are
139         added """
140     if not self.topic_metadata.has_key(catalog_name):
141         self.topic_metadata[catalog_name]={}
142     meta = self.topic_metadata[catalog_name]
143     if friendlyName == None:
144         friendlyName = meta[metadata].friendlyName
145     if description == None:
146         description = meta[metadata].description
147     if enabled == None:
148         enabled = meta[metadata].enabled
149     self.addMetadata(metadata, friendlyName, description, enabled, catalog_name)
150
151
152
153 def removeIndex(self, index, catalog_name=CatalogTool.id):
154     """ Removes an existing index from the registry """
155     if not self.topic_indexes.has_key(catalog_name):
156         self.topic_indexes[catalog_name]={}
157     if self.topic_indexes[catalog_name].has_key(index):
158         del self.topic_indexes[catalog_name][index]
159         self._p_changed=1
160
161
162 def removeMetadata(self, metadata, catalog_name=CatalogTool.id):
163     """ Removes an existing metadata field from the registry """
164     m = metadata
165     if self.topic_metadata[catalog_name].has_key(metadata):
166         del self.topic_metadata[catalog_name][metadata]
167         self._p_changed=1
168
169
170 def createInitialIndexes(self, catalog_name=CatalogTool.id):
171     """ create indexes for all indexes in the catalog """
172     indexes = self.listCatalogFields()
173
174     if not self.topic_indexes.has_key(catalog_name):
175         self.topic_indexes[catalog_name]={}
176
177     for i in indexes:
178         if not self.topic_indexes[catalog_name].has_key(i):
179             enabled = False
180             self.addIndex(i, friendlyName='', enabled=enabled, catalog_name=catalog_name)
181     return True
182
183
184 def createInitialMetadata(self, catalog_name=CatalogTool.id):
185     """ create metadata for all indexes in the catalog """
186     metas = self.listCatalogMetadata(catalog_name)
187
188     if not self.topic_metadata.has_key(catalog_name):
189         self.topic_metadata[catalog_name]={}
190
191     for i in metas:
192         if not self.topic_metadata[catalog_name].has_key(i):
193             enabled = False
194             self.addMetadata(i, friendlyName='', enabled=enabled, catalog_name=catalog_name)
195     return True
196
197
198
199 def updateIndexesFromCatalog(self, catalog_name=CatalogTool.id):
200     """ check if there are new indexes or if indexes must be removed from
201         the collection because they do no longer exist in the catalog """
202     indexes = self.listCatalogFields(catalog_name)
203     configured_indexes = {}
204     for index in tool_config.indexes:
205         configured_indexes[index.name]=(getattr(index,'friendlyName',None),
206                                         getattr(index,'description',None),
207                                         getattr(index,'enabled',None),
208                                         getattr(index,'criteria',None))
209
210     # first add new indexes
211     if not self.topic_indexes.has_key(catalog_name):
212         self.topic_indexes[catalog_name]={}
213     for i in indexes:
214         if not self.topic_indexes[catalog_name].has_key(i):
215             enabled = False
216             defaults = (configured_indexes.has_key(i) and configured_indexes[i]) or \
217                         ('','',enabled,self.getCriteriaForIndex(i,True,catalog_name))
218             self.addIndex(i, friendlyName=defaults[0],
219                         description=defaults[1], enabled=defaults[2],
220                         criteria=defaults[3], catalog_name=catalog_name)
221
222     # now check the other way round
223     keys = self.topic_indexes[catalog_name].keys()
224     for k in keys:
225         if k not in indexes:
226             self.removeIndex(k, catalog_name)
227
228
229 def updateMetadataFromCatalog(self, catalog_name=CatalogTool.id):
230     """ check if there are new metadata fields or if fields must be
231         removed from the collection because they do no longer exist in the
232         catalog """
233     metas = self.listCatalogMetadata(catalog_name)
234     configured_metadata = {}
235     for meta in tool_config.metadata:
236         configured_metadata[meta.name]=(getattr(meta,'friendlyName',None),
237                                         getattr(meta,'description',None),
238                                         getattr(meta,'enabled',None))
239
240     # first add new indexes
241     if not self.topic_metadata.has_key(catalog_name):
242         self.topic_metadata[catalog_name]={}
243     for i in metas:
244         if not self.topic_metadata[catalog_name].has_key(i):
245             enabled = False
246             defaults = (configured_metadata.has_key(i) and
247                                     configured_metadata[i]) or ('','',enabled)
248             self.addMetadata(i, friendlyName=defaults[0],
249                             description=defaults[1], enabled=defaults[2], catalog_name=catalog_name)
250
251     # now check the other way round
252     keys = self.topic_metadata[catalog_name].keys()
253     for k in keys:
254         if k not in metas:
255             self.removeMetadata(k, catalog_name)
256
257
258 def listCatalogFields(self, catalog_name=CatalogTool.id):
259     """ Return a list of fields from catalog_name. """
260     pcatalog = getToolByName( self, catalog_name)
261     available = pcatalog.indexes()
262     val = [ field for field in available ]
263     val.sort()
264     return val
265
266
267 def listCatalogMetadata(self, catalog_name=CatalogTool.id):
268     """ Return a list of columns from portal_catalog. """
269     pcatalog = getToolByName(self, catalog_name)
270     available = pcatalog.schema()
271     val = [ field for field in available ]
272     val.sort()
273     return val
274
275
276 def getEnabledIndexes(self, catalog_name=CatalogTool.id):
277     """ Returns all TopicIndex objects for enabled indexes """
278     # first resync with the catalog
279     self.updateIndexesFromCatalog(catalog_name)
280
281     indexes = self.topic_indexes[catalog_name]
282     results = [i for i in indexes.values() if i.enabled]
283
284     return results
285
286 def getEnabledMetadata(self, catalog_name=CatalogTool.id):
287     """ Returns all TopicIndex objects for enabled metadata """
288     # first resync with the catalog
289     self.updateMetadataFromCatalog(catalog_name)
290
291     meta = self.topic_metadata[catalog_name]
292     results = [i for i in meta.values() if i.enabled]
293
294     return results
295
296
297 def getIndexDisplay(self, enabled=True, catalog_name=CatalogTool.id):
298     """ Return DisplayList of Indexes and their friendly names """
299     if enabled:
300         index_names = self.getIndexes(True, catalog_name)
301     else:
302         index_names = self.getIndexes(False, catalog_name)
303     index_dict = self.topic_indexes[catalog_name]
304     indexes = [index_dict[i] for i in index_names]
305
306     field_list=[(f.index, f.friendlyName or f.index) for f in indexes]
307
308     return DisplayList(field_list)
309
310 def getMetadataDisplay(self, enabled=True, catalog_name=CatalogTool.id):
311     """ Return DisplayList of Metadata and their friendly names """
312     if enabled:
313         meta_names = self.getAllMetadata(True, catalog_name)
314     else:
315         meta_names = self.getAllMetadata(False, catalog_name)
316     meta_dict = self.topic_metadata[catalog_name]
317     meta = [meta_dict[i] for i in meta_names]
318
319     field_list=[(f.index, f.friendlyName or f.index) for f in meta]
320
321     return DisplayList(field_list)
322
323
324 def getEnabledFields(self, catalog_name=CatalogTool.id):
325     """ Returns a list of tuples containing the index name, friendly name,
326         and description for each enabled index. """
327     enabledIndexes = self.getEnabledIndexes(catalog_name)
328
329     dec_fields = [(i.friendlyName.lower() or i.index.lower(), i.index, i.friendlyName or i.index, i.description) for i in enabledIndexes]
330
331     dec_fields.sort()
332
333     fields = [(a[1],a[2],a[3]) for a in dec_fields]
334
335     return fields
336
337
338 def getFriendlyName(self, index, catalog_name=CatalogTool.id):
339     """ Returns the friendly name for a given index name, or the given
340         index if the firendlyname is empty or the index is not recognized
341     """
342     if not self.topic_indexes.has_key(catalog_name):
343         self.topic_indexes[catalog_name]={}
344
345     if self.topic_indexes[catalog_name].has_key(index):
346         return self.getIndex(index, catalog_name).friendlyName or index
347     else:
348         return index
349
350
351 def getIndexes(self, enabledOnly=False, catalog_name=CatalogTool.id):
352     """ Returns the full list of available indexes, optionally filtering
353         out those that are not marked enabled """
354     # first resync with the catalog
355     if  enabledOnly:
356         indexes_dec = [(i.index.lower(), i.index) for i in self.getEnabledIndexes(catalog_name)]
357     else:
358         self.updateIndexesFromCatalog(catalog_name)
359         indexes_dec = [(i.lower(), i) for i in self.topic_indexes[catalog_name].keys()]
360
361     indexes_dec.sort()
362     indexes = [i[1] for i in indexes_dec]
363     return indexes
364
365 def getAllMetadata(self, enabledOnly=False, catalog_name=CatalogTool.id):
366     """ Returns the full list of available metadata fields, optionally
367         filtering out those that are not marked enabled """
368     # first resync with the catalog
369     self.updateMetadataFromCatalog(catalog_name)
370     if enabledOnly:
371         meta_dec = [(i.index.lower(), i.index) for i in self.getEnabledMetadata(catalog_name)]
372     else:
373         meta_dec = [(i.lower(), i) for i in self.topic_metadata[catalog_name].keys()]
374     meta_dec.sort()
375     metadata = [i[1] for i in meta_dec]
376     return metadata
377
378
379 def getIndex(self, index, catalog_name=CatalogTool.id):
380     """ Returns the TopicIndex object for a given index name """
381
382     self.updateIndexesFromCatalog(catalog_name)
383     if self.topic_indexes[catalog_name].has_key(index):
384         return self.topic_indexes[catalog_name][index]
385     else:
386         raise AttributeError('Index ' + str(index) + ' not found')
387
388 def getMetadata(self, metadata, catalog_name=CatalogTool.id):
389     """ Returns the TopicIndex object for a given metadata name """
390
391     self.updateMetadataFromCatalog(catalog_name)
392     if self.topic_metadata[catalog_name].has_key(metadata):
393         return self.topic_metadata[catalog_name][metadata]
394     else:
395         raise AttributeError('Metadata ' + str(metadata) + ' not found')
396
397 def manage_saveTopicSetup(self, REQUEST=None):
398     """ Set indexes and metadata from form """
399     if REQUEST==None:
400         return  'Nothing saved.'
401
402     catalog_name=REQUEST.get('catalog', CatalogTool.id)
403
404     data = REQUEST.get('index', [])
405     for index in data:
406         enabled = index.has_key('enabled')
407         criteria = index.get('criteria', ())
408         self.updateIndex(index['index'], index['friendlyName'], index['description'], enabled, criteria, catalog_name)
409
410     meta = REQUEST.get('metadata', [])
411     for metadata in meta:
412         enabled = metadata.has_key('enabled')
413         self.updateMetadata(metadata['index'], metadata['friendlyName'], metadata['description'], enabled, catalog_name)
414
415     return 1
416
417 def clearIndexes(self, catalog_name=None):
418     if not catalog_name:
419         self.topic_indexes={}
420         self.topic_metadata={}
421