diff --git a/ZCTextIndex.py b/ZCTextIndex.py index cf60fdb..4e4e1b2 100644 --- a/ZCTextIndex.py +++ b/ZCTextIndex.py @@ -8,29 +8,30 @@ # 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 +# FOR A PARTICULAR PURPOSE. # ############################################################################## +"""Plug in text index for ZCatalog with relevance ranking. -"""Plug in text index for ZCatalog with relevance ranking.""" +$Id$ +""" from cgi import escape -from types import TupleType -import ZODB from Persistence import Persistent import Acquisition from Acquisition import aq_base, aq_inner, aq_parent from OFS.SimpleItem import SimpleItem - from Globals import DTMLFile, InitializeClass from AccessControl.SecurityInfo import ClassSecurityInfo from AccessControl.Permissions import manage_zcatalog_indexes, search_zcatalog +from zope.interface import implements from Products.PluginIndexes.common.PluggableIndex import \ PluggableIndexInterface from Products.PluginIndexes.common.util import parseIndexRequest from Products.PluginIndexes.common import safe_callable +from Products.PluginIndexes.interfaces import IPluggableIndex from Products.ZCTextIndex.ILexicon import ILexicon from Products.ZCTextIndex.Lexicon import \ @@ -38,16 +39,23 @@ from Products.ZCTextIndex.NBest import NBest from Products.ZCTextIndex.QueryParser import QueryParser from PipelineFactory import element_factory +from interfaces import IZCLexicon +from interfaces import IZCTextIndex from Products.ZCTextIndex.CosineIndex import CosineIndex from Products.ZCTextIndex.OkapiIndex import OkapiIndex + index_types = {'Okapi BM25 Rank':OkapiIndex, 'Cosine Measure':CosineIndex} + class ZCTextIndex(Persistent, Acquisition.Implicit, SimpleItem): - """Persistent TextIndex""" + + """Persistent text index. + """ __implements__ = PluggableIndexInterface + implements(IZCTextIndex, IPluggableIndex) ## Magic class attributes ## @@ -72,7 +80,8 @@ def __init__(self, id, extra=None, caller=None, index_factory=None, # via the silly "extra" record. self._fieldname = field_name or getattr(extra, 'doc_attr', '') or id self._indexed_attrs = self._fieldname.split(',') - self._indexed_attrs = [ attr.strip() for attr in self._indexed_attrs if attr ] + self._indexed_attrs = [ attr.strip() + for attr in self._indexed_attrs if attr ] lexicon_id = lexicon_id or getattr(extra, 'lexicon_id', '') lexicon = getattr(caller, lexicon_id, None) @@ -254,7 +263,7 @@ def clear(self): def getIndexSourceNames(self): """Return sequence of names of indexed attributes""" try: - return self._indexed_attrs + return self._indexed_attrs except: return [self._fieldname] @@ -270,7 +279,6 @@ def getLexiconURL(self): return None else: return lex.absolute_url() - InitializeClass(ZCTextIndex) @@ -314,8 +322,13 @@ def manage_addLexicon(self, id, title='', elements=[], REQUEST=None): LexiconQueryPerm = 'Query Vocabulary' LexiconMgmtPerm = 'Manage Vocabulary' + class PLexicon(Lexicon, Acquisition.Implicit, SimpleItem): - """Lexicon for ZCTextIndex""" + + """Lexicon for ZCTextIndex. + """ + + implements(IZCLexicon) meta_type = 'ZCTextIndex Lexicon' diff --git a/interfaces.py b/interfaces.py new file mode 100644 index 0000000..c518a11 --- /dev/null +++ b/interfaces.py @@ -0,0 +1,30 @@ +############################################################################## +# +# Copyright (c) 2005 Zope Corporation and Contributors. 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. +# +############################################################################## +"""ZCTextIndex z3 interfaces. + +$Id$ +""" + +from zope.interface import Interface + + +class IZCTextIndex(Interface): + + """Persistent text index. + """ + + +class IZCLexicon(Interface): + + """Lexicon for ZCTextIndex. + """ diff --git a/tests/testZCTextIndex.py b/tests/testZCTextIndex.py index 6aacc06..7dc0c36 100644 --- a/tests/testZCTextIndex.py +++ b/tests/testZCTextIndex.py @@ -11,14 +11,21 @@ # FOR A PARTICULAR PURPOSE. # ############################################################################## +"""ZCTextIndex unit tests. + +$Id$ +""" + +import unittest +import Testing +import Zope2 +Zope2.startup() + +import re -from Interface.Verify import verifyClass import Acquisition from zExceptions import NotFound -from Products.PluginIndexes.common.PluggableIndex import \ - PluggableIndexInterface - from Products.ZCTextIndex.ZCTextIndex import ZCTextIndex, PLexicon from Products.ZCTextIndex.tests import \ testIndex, testQueryEngine, testQueryParser @@ -32,8 +39,6 @@ from Products.ZCTextIndex.StopDict import get_stopdict from Products.ZCTextIndex.ParseTree import ParseError -import re -import unittest class Indexable: def __init__(self, text): @@ -250,9 +255,21 @@ class CosineIndexTests(ZCIndexTestsBase, testIndex.CosineIndexTest): # Gigabytes, pp. 180-188. This test peeks into many internals of the # cosine indexer. - def testInterface(self): + def test_z2interfaces(self): + from Interface.Verify import verifyClass + from Products.PluginIndexes.common.PluggableIndex \ + import PluggableIndexInterface + verifyClass(PluggableIndexInterface, ZCTextIndex) + def test_z3interfaces(self): + from Products.PluginIndexes.interfaces import IPluggableIndex + from Products.ZCTextIndex.interfaces import IZCTextIndex + from zope.interface.verify import verifyClass + + verifyClass(IPluggableIndex, ZCTextIndex) + verifyClass(IZCTextIndex, ZCTextIndex) + def testRanking(self): self.words = ["cold", "days", "eat", "hot", "lot", "nine", "old", "pease", "porridge", "pot"] @@ -548,18 +565,28 @@ def compareSet(self, set, dict): dictkeys.sort() self.assertEqual(setkeys, dictkeys) + class CosineQueryTests(QueryTestsBase): IndexFactory = CosineIndex + class OkapiQueryTests(QueryTestsBase): IndexFactory = OkapiIndex -############################################################################ + +class PLexiconTests(unittest.TestCase): + + def test_z3interfaces(self): + from Products.ZCTextIndex.interfaces import IZCLexicon + from zope.interface.verify import verifyClass + + verifyClass(IZCLexicon, PLexicon) + def test_suite(): s = unittest.TestSuite() for klass in (CosineIndexTests, OkapiIndexTests, - CosineQueryTests, OkapiQueryTests): + CosineQueryTests, OkapiQueryTests, PLexiconTests): s.addTest(unittest.makeSuite(klass)) return s