New catalog module to make objects (un-)indexing easier
authorThierry Florac <tflorac@ulthar.net>
Mon, 14 Sep 2009 23:45:39 +0200
changeset 18 f268aaac34e8
parent 17 d2e8f6a30505
child 19 be38bc1fd087
New catalog module to make objects (un-)indexing easier
ztfy/utils/catalog.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ztfy/utils/catalog.py	Mon Sep 14 23:45:39 2009 +0200
@@ -0,0 +1,154 @@
+### -*- coding: utf-8 -*- ####################################################
+##############################################################################
+#
+# Copyright (c) 2008-2009 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+__docformat__ = "restructuredtext"
+
+# import standard packages
+
+# import Zope3 interfaces
+from zope.annotation.interfaces import IAnnotations
+from zope.app.catalog.interfaces import ICatalog
+from zope.app.container.interfaces import IContainer
+from zope.app.file.interfaces import IFile
+from zope.app.intid.interfaces import IIntIds
+
+# import local interfaces
+
+# import Zope3 packages
+from zope.app import zapi
+
+# import local packages
+import request as request_utils
+
+from ztfy.utils import _
+
+
+#
+# IntIds utility functions
+#
+
+def getIntIdUtility(name='', request=None, context=None):
+    """Look for a named IIntIds utility"""
+    if request is None:
+        request = request_utils.getRequest()
+    intids = request_utils.getRequestData('IntIdsUtility::' + name, request)
+    if intids is None:
+        intids = zapi.queryUtility(IIntIds, name, context=context)
+        if intids is not None:
+            request_utils.setRequestData('IntIdsUtility::' + name, intids, request)
+    return intids
+
+
+def getObjectId(object, intids_name='', request=None, context=None):
+    """Look for an object Id as recorded by given IIntIds utility"""
+    if request is None:
+        request = request_utils.getRequest()
+    intids = getIntIdUtility(intids_name, request, context)
+    if intids is not None:
+        return intids.queryId(object)
+    return None
+
+
+def getObject(id, intids_name='', request=None, context=None):
+    """Look for an object recorded by given IIntIds utility and id"""
+    if request is None:
+        request = request_utils.getRequest()
+    intids = getIntIdUtility(intids_name, request, context)
+    if intids is not None:
+        return intids.queryObject(id)
+    return None
+
+
+#
+# Catalog utility functions
+#
+
+def queryCatalog(name='', context=None):
+    """Look for a registered catalog"""
+    return zapi.queryUtility(ICatalog, name, context=context)
+
+
+def indexObject(object, catalog_name='', index_name='', request=None, context=None):
+    """Index object into a registered catalog"""
+    if request is None:
+        request = request_utils.getRequest()
+    intids = getIntIdUtility('', request, context)
+    if intids is not None:
+        catalog = queryCatalog(catalog_name, context)
+        if catalog is not None:
+            id = intids.register(object)
+            if index_name:
+                catalog[index_name].index_doc(id, object)
+            else:
+                catalog.index_doc(id, object)
+            return True
+    return False
+
+
+def unindexObject(object, catalog_name='', index_name='', request=None, context=None):
+    """Remove object from a registered catalog"""
+    if request is None:
+        request = request_utils.getRequest()
+    id = getObjectId(object, '', request, context)
+    if id is not None:
+        catalog = queryCatalog(catalog_name, context)
+        if catalog is not None:
+            if index_name:
+                catalog[index_name].unindex_doc(id)
+            else:
+                catalog.unindex_doc(id)
+            return True
+    return False
+
+
+def _indexObject(object, intids, catalogs):
+    """Index object data into given set of catalogs"""
+    id = intids.register(object)
+    for catalog in catalogs:
+        catalog.index_doc(id, object)
+
+def _indexObjectValues(object, intids, catalogs):
+    """Index object values into given set of catalogs"""
+    container = IContainer(object, None)
+    if container is not None:
+        for subobject in container.values():
+            _indexAllObject(subobject, intids, catalogs)
+
+def _indexObjectAnnotations(object, intids, catalogs):
+    """Index object annotations into given set of catalogs"""
+    annotations = IAnnotations(object, None)
+    if annotations is not None:
+        keys = annotations.keys()
+        for key in keys:
+            _indexAllObject(annotations[key], intids, catalogs)
+            file = IFile(annotations[key], None)
+            if file is not None:
+                _indexObject(file, intids, catalogs)
+
+def _indexAllObject(object, intids, catalogs):
+    """Index object, object values and annotations into given set of catalogs"""
+    _indexObject(object, intids, catalogs)
+    _indexObjectValues(object, intids, catalogs)
+    _indexObjectAnnotations(object, intids, catalogs)
+
+def indexAllObjectValues(object, context=None):
+    """Reindex a whole container properties and contents (including annotations) into site's catalogs"""
+    if context is None:
+        context = object
+    intids = zapi.queryUtility(IIntIds, context=context)
+    if intids is not None:
+        catalogs = zapi.getAllUtilitiesRegisteredFor(ICatalog, context)
+        if catalogs:
+            _indexAllObject(object, intids, catalogs)