[CMF-checkins] CVS: CMF/CMFCollector - Collector.py:1.9

Ken Manheimer klm@zope.com
Thu, 25 Oct 2001 14:49:05 -0400


Update of /cvs-repository/CMF/CMFCollector
In directory cvs.zope.org:/tmp/cvs-serv25329

Modified Files:
	Collector.py 
Log Message:
Implement an internal catalog, to simplify cataloging/searching and
unique values assessment, instead of relying on overloading standard
metadata fields in the portal central catalog.  See
http://new.zope.org/Members/klm/ColDev/25 for details of the issue and
solution.

New class CollectorCatalog: Derives from portal CatalogTool (exploiting
the invaluable added features it builds on standard catalog), with
default schema tailored exactly to collector issue search and
indexing. 

Collector:

._setup_internal_catalog(): Create and situate the new collector catalog.

._get_internal_catalog()

.edit(): Any time we change the supporters roster we need to reindex
the isses, so cataloged allowedRolesAndUsers reflects attendant
changes to local_roles.

.reinstate_catalog(): Recreate and reload internal catalog, to
accommodate drastic changes.

._reindex_issues(): ... for collector events, like supporter roster
changes, which require all issues to be completely reindexed.

.__len__(): reduce by 1, to omit internal catalog from tally.


=== CMF/CMFCollector/Collector.py 1.8 => 1.9 ===
 from Products.CMFCore.PortalContent import PortalContent
 from Products.CMFCore.WorkflowCore import WorkflowAction
+from Products.CMFCore.CatalogTool import CatalogTool
 
 from Products.CMFDefault.SkinnedFolder import SkinnedFolder
 
@@ -32,6 +33,8 @@
 
 from CollectorIssue import addCollectorIssue
 
+INTERNAL_CATALOG_ID = 'collector_catalog'
+
 # Factory type information -- makes Events objects play nicely
 # with the Types Tool (portal_types)
 factory_type_information = (
@@ -91,6 +94,8 @@
 
         SkinnedFolder.__init__(self, id, title)
 
+        self._setup_catalog()
+
         self.last_issue_id = 0
 
         self.description = description
@@ -135,6 +140,17 @@
 
         return self
 
+    def _setup_internal_catalog(self):
+        """Create and situate properly configured collector catalog."""
+        catalog = CollectorCatalog()
+        self._setOb(catalog.id, catalog)
+
+    security.declareProtected(CMFCorePermissions.View, 'get_internal_catalog')
+    def get_internal_catalog(self):
+        """ """
+        return self._getOb(INTERNAL_CATALOG_ID)
+        
+
     security.declareProtected(AddCollectorIssue, 'new_issue_id')
     def new_issue_id(self):
         """Return a new issue id, incrementing the internal counter."""
@@ -186,7 +202,7 @@
              topics=None, classifications=None,
              importances=None, severities=None,
              versions=None, other_versions_spiel=None):
-        changed = 0
+        changed = reindex = 0
         if title is not None and title != self.title:
             self.title = title
             changed = 1
@@ -206,6 +222,7 @@
                 self._adjust_supporters_roster(x)
                 self.supporters = x
                 changed = 1
+                reindex = 1
         if topics is not None:
             x = filter(None, topics)
             if self.topics != x:
@@ -236,6 +253,10 @@
             if self.other_versions_spiel != other_versions_spiel:
                 self.other_versions_spiel = other_versions_spiel
                 changed = 1
+
+        if reindex:
+            self._reindex_issues()
+
         return changed
 
     def _adjust_supporters_roster(self, new_roster):
@@ -261,14 +282,36 @@
             if u not in already:
                 util.add_local_role(self, u, 'Reviewer')
 
+    security.declareProtected(ManageCollector, 'reinstate_catalog')
+    def reinstate_catalog(self, internal_only=0):
+        """Recreate and reload internal catalog, to accommodate drastic
+        changes."""
+        if hasattr(self, INTERNAL_CATALOG_ID):
+            self._delOb(INTERNAL_CATALOG_ID)
+        self._setup_internal_catalog()
+        for i in self.objectValues():
+            # Normalize security_related setting
+            if i.security_related not in [0, 1]:
+                i.security_related = (i.security_related and 1) or 0
+        self._reindex_issues(internal_only=internal_only)
+
+    def _reindex_issues(self, internal_only=0):
+        """For, eg, allowedRolesAndUsers recompute after local_role changes."""
+        for i in self.objectValues():
+            i.reindexObject(internal_only=internal_only)
+
+    security.declareProtected(CMFCorePermissions.View, 'Subject')
+    def Subject(self):
+        return self.topics
+
     security.declareProtected(CMFCorePermissions.View, 'length')
     def length(self):
         """Use length protocol."""
         return self.__len__()
         
     def __len__(self):
-        """Implement length protocol method."""
-        return len(self.objectIds())
+        """length() protocol method."""
+        return len(self.objectIds()) - 1
 
     def __repr__(self):
         return ("<%s %s (%d issues) at 0x%s>"
@@ -277,6 +320,45 @@
 
 InitializeClass(Collector)
     
+class CollectorCatalog(CatalogTool):
+    id = INTERNAL_CATALOG_ID
+    def enumerateIndexes(self):
+        standard = CatalogTool.enumerateIndexes(self)
+        custom = (('status', 'FieldIndex'),
+                  ('topic', 'FieldIndex'),
+                  ('classification', 'FieldIndex'),
+                  ('importance', 'FieldIndex'),
+                  ('security_related', 'FieldIndex'),
+                  ('confidential', 'FieldIndex'),
+                  ('resolution', 'TextIndex'),
+                  ('submitter_email', 'TextIndex'),
+                  ('version_info', 'TextIndex'),
+                  ('assigned_to', 'KeywordIndex'),
+                  ('upload_number', 'KeywordIndex')
+                  )
+        return standard + custom
+
+    def enumerateColumns( self ):
+        """Return field names of data to be cached on query results."""
+        standard = CatalogTool.enumerateColumns(self)
+        custom = ('status',
+                  'topic',
+                  'classification',
+                  'importance',
+                  'security_related',
+                  'confidential',
+                  'version_info',
+                  'assigned_to',
+                  'uploads',
+                  'action_number',
+                  'upload_number',
+                  )
+        return standard + custom
+
+
+InitializeClass(CollectorCatalog)
+
+
 # XXX Enable use of pdb.set_trace() in python scripts
 ModuleSecurityInfo('pdb').declarePublic('set_trace')