[Checkins] SVN: z3ext.lucene/ initial import
Nikolay Kim
fafhrd at datacom.kz
Tue Mar 25 12:36:06 EDT 2008
Log message for revision 84935:
initial import
Changed:
A z3ext.lucene/
A z3ext.lucene/branches/
A z3ext.lucene/tags/
A z3ext.lucene/trunk/
A z3ext.lucene/trunk/AUTHOR.txt
A z3ext.lucene/trunk/CHANGES.txt
A z3ext.lucene/trunk/LICENSE.txt
A z3ext.lucene/trunk/bootstrap.py
A z3ext.lucene/trunk/buildout.cfg
A z3ext.lucene/trunk/setup.py
A z3ext.lucene/trunk/src/
A z3ext.lucene/trunk/src/z3ext/
A z3ext.lucene/trunk/src/z3ext/__init__.py
A z3ext.lucene/trunk/src/z3ext/lucene/
A z3ext.lucene/trunk/src/z3ext/lucene/README.txt
A z3ext.lucene/trunk/src/z3ext/lucene/__init__.py
A z3ext.lucene/trunk/src/z3ext/lucene/browser/
A z3ext.lucene/trunk/src/z3ext/lucene/browser/__init__.py
A z3ext.lucene/trunk/src/z3ext/lucene/browser/configure.zcml
A z3ext.lucene/trunk/src/z3ext/lucene/browser/indexedit.py
A z3ext.lucene/trunk/src/z3ext/lucene/browser/indexview.pt
A z3ext.lucene/trunk/src/z3ext/lucene/browser/indexview.py
A z3ext.lucene/trunk/src/z3ext/lucene/browser/lucene-icon.gif
A z3ext.lucene/trunk/src/z3ext/lucene/browser/product.pt
A z3ext.lucene/trunk/src/z3ext/lucene/browser/product.py
A z3ext.lucene/trunk/src/z3ext/lucene/browser/product.zcml
A z3ext.lucene/trunk/src/z3ext/lucene/configure.zcml
A z3ext.lucene/trunk/src/z3ext/lucene/i18n.py
A z3ext.lucene/trunk/src/z3ext/lucene/index.py
A z3ext.lucene/trunk/src/z3ext/lucene/interfaces.py
A z3ext.lucene/trunk/src/z3ext/lucene/product.py
A z3ext.lucene/trunk/src/z3ext/lucene/product.zcml
A z3ext.lucene/trunk/src/z3ext/lucene/server/
A z3ext.lucene/trunk/src/z3ext/lucene/server/__init__.py
A z3ext.lucene/trunk/src/z3ext/lucene/server/client.py
A z3ext.lucene/trunk/src/z3ext/lucene/server/configure.zcml
A z3ext.lucene/trunk/src/z3ext/lucene/server/indexserver.py
A z3ext.lucene/trunk/src/z3ext/lucene/server/interfaces.py
A z3ext.lucene/trunk/src/z3ext/lucene/server/jar/
A z3ext.lucene/trunk/src/z3ext/lucene/server/jar/commons-logging-1.1.jar
A z3ext.lucene/trunk/src/z3ext/lucene/server/jar/lucene-core-2.2.0.jar
A z3ext.lucene/trunk/src/z3ext/lucene/server/jar/lucene-queries-2.2.0.jar
A z3ext.lucene/trunk/src/z3ext/lucene/server/jar/lucene-snowball-2.2.0.jar
A z3ext.lucene/trunk/src/z3ext/lucene/server/jar/xmlrpc-1.2-b1.jar
A z3ext.lucene/trunk/src/z3ext/lucene/server/server.py
A z3ext.lucene/trunk/src/z3ext/lucene/server/server.sh
A z3ext.lucene/trunk/src/z3ext/lucene/server/subscribers.py
A z3ext.lucene/trunk/src/z3ext/lucene/server/vocabulary.py
A z3ext.lucene/trunk/src/z3ext/lucene/subscribers.py
A z3ext.lucene/trunk/src/z3ext/lucene/tests.py
A z3ext.lucene/trunk/src/z3ext/lucene/utils.py
A z3ext.lucene/trunk/src/z3ext/lucene/vocabulary.py
-=-
Property changes on: z3ext.lucene/trunk
___________________________________________________________________
Name: svn:ignore
+ bin
coverage
develop-eggs
eggs
parts
.installed.cfg
Added: z3ext.lucene/trunk/AUTHOR.txt
===================================================================
--- z3ext.lucene/trunk/AUTHOR.txt (rev 0)
+++ z3ext.lucene/trunk/AUTHOR.txt 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1 @@
+Nikolay Kim (fafhrd91 <at> gmail <dot> com)
Added: z3ext.lucene/trunk/CHANGES.txt
===================================================================
--- z3ext.lucene/trunk/CHANGES.txt (rev 0)
+++ z3ext.lucene/trunk/CHANGES.txt 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,30 @@
+=======
+CHANGES
+=======
+
+1.1.2 (2008-03-25)
+------------------
+
+- fix: don't split query if it is string
+
+- code moved to svn.zope.org
+
+
+1.1.1 (2008-02-21)
+------------------
+
+- Use z3ext.layoutform for product configuration
+
+- Catch exception during server startup and indexing
+
+
+1.1.0 (2008-02-01)
+------------------
+
+- Added support for z3ext.product
+
+
+1.0.0 (2007-12-08)
+------------------
+
+- Initial release.
Added: z3ext.lucene/trunk/LICENSE.txt
===================================================================
--- z3ext.lucene/trunk/LICENSE.txt (rev 0)
+++ z3ext.lucene/trunk/LICENSE.txt 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,54 @@
+Zope Public License (ZPL) Version 2.1
+-------------------------------------
+
+A copyright notice accompanies this license document that
+identifies the copyright holders.
+
+This license has been certified as open source. It has also
+been designated as GPL compatible by the Free Software
+Foundation (FSF).
+
+Redistribution and use in source and binary forms, with or
+without modification, are permitted provided that the
+following conditions are met:
+
+1. Redistributions in source code must retain the
+ accompanying copyright notice, this list of conditions,
+ and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the accompanying
+ copyright notice, this list of conditions, and the
+ following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+3. Names of the copyright holders must not be used to
+ endorse or promote products derived from this software
+ without prior written permission from the copyright
+ holders.
+
+4. The right to distribute this software or to use it for
+ any purpose does not give you the right to use
+ Servicemarks (sm) or Trademarks (tm) of the copyright
+ holders. Use of them is covered by separate agreement
+ with the copyright holders.
+
+5. If any files are modified, you must cause the modified
+ files to carry prominent notices stating that you changed
+ the files and the date of any change.
+
+Disclaimer
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS''
+ AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
+ NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ NO EVENT SHALL THE COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGE.
Added: z3ext.lucene/trunk/bootstrap.py
===================================================================
--- z3ext.lucene/trunk/bootstrap.py (rev 0)
+++ z3ext.lucene/trunk/bootstrap.py 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,52 @@
+##############################################################################
+#
+# Copyright (c) 2006 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.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+
+$Id: bootstrap.py 1828 2008-03-21 12:51:56Z fafhrd91 $
+"""
+
+import os, shutil, sys, tempfile, urllib2
+
+tmpeggs = tempfile.mkdtemp()
+
+ez = {}
+exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
+ ).read() in ez
+ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
+
+import pkg_resources
+
+cmd = 'from setuptools.command.easy_install import main; main()'
+if sys.platform == 'win32':
+ cmd = '"%s"' % cmd # work around spawn lamosity on windows
+
+ws = pkg_resources.working_set
+assert os.spawnle(
+ os.P_WAIT, sys.executable, sys.executable,
+ '-c', cmd, '-mqNxd', tmpeggs, 'zc.buildout',
+ dict(os.environ,
+ PYTHONPATH=
+ ws.find(pkg_resources.Requirement.parse('setuptools')).location
+ ),
+ ) == 0
+
+ws.add_entry(tmpeggs)
+ws.require('zc.buildout')
+import zc.buildout.buildout
+zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
+shutil.rmtree(tmpeggs)
Added: z3ext.lucene/trunk/buildout.cfg
===================================================================
--- z3ext.lucene/trunk/buildout.cfg (rev 0)
+++ z3ext.lucene/trunk/buildout.cfg 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,18 @@
+[buildout]
+develop = .
+parts = test coverage-test coverage-report
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = z3ext.lucene [test]
+
+[coverage-test]
+recipe = zc.recipe.testrunner
+eggs = z3ext.lucene [test]
+defaults = ['--coverage', '../../coverage']
+
+[coverage-report]
+recipe = zc.recipe.egg
+eggs = z3c.coverage
+scripts = coverage=coverage-report
+arguments = ('coverage', 'coverage/report')
Added: z3ext.lucene/trunk/setup.py
===================================================================
--- z3ext.lucene/trunk/setup.py (rev 0)
+++ z3ext.lucene/trunk/setup.py 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,76 @@
+##############################################################################
+#
+# Copyright (c) 2007 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.
+#
+##############################################################################
+"""Setup for z3ext.lucene package
+
+$Id: setup.py 1828 2008-03-21 12:51:56Z fafhrd91 $
+"""
+import sys, os
+from setuptools import setup, find_packages
+
+def read(*rnames):
+ return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
+
+version = '1.1.2dev'
+
+
+setup(name='z3ext.lucene',
+ version=version,
+ description="Lucene zope index",
+ long_description=(
+ 'Detailed Dcoumentation\n' +
+ '======================\n'
+ + '\n\n' +
+ read('src', 'z3ext', 'lucene', 'README.txt')
+ + '\n\n' +
+ read('CHANGES.txt')
+ ),
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Web Environment',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: Zope Public License',
+ 'Programming Language :: Python',
+ 'Natural Language :: English',
+ 'Operating System :: OS Independent',
+ 'Topic :: Internet :: WWW/HTTP',
+ 'Framework :: Zope3'],
+ author='Nikolay Kim',
+ author_email='fafhrd91 at gmail.com',
+ url='http://z3ext.net/',
+ license='ZPL 2.1',
+ package_dir = {'':'src'},
+ packages=find_packages('src'),
+ namespace_packages=['z3ext'],
+ install_requires = ['setuptools',
+ 'zope.component',
+ 'zope.interface',
+ 'zope.publisher',
+ 'zope.schema',
+ 'zope.proxy',
+ 'zope.index',
+ 'zope.i18nmessageid',
+ 'zope.app.twisted',
+ 'zope.app.intid',
+ 'zope.app.appsetup',
+ 'zope.app.pagetemplate',
+ 'zope.app.container',
+ 'zope.app.catalog',
+ ],
+ extras_require = dict(test=['zope.traversing',
+ 'zope.app.testing',
+ 'zope.testing',
+ ]),
+ include_package_data = True,
+ zip_safe = False
+ )
Property changes on: z3ext.lucene/trunk/setup.py
___________________________________________________________________
Name: svn:executable
+ *
Added: z3ext.lucene/trunk/src/z3ext/__init__.py
===================================================================
--- z3ext.lucene/trunk/src/z3ext/__init__.py (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/__init__.py 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,6 @@
+# namespace package boilerplate
+try:
+ __import__('pkg_resources').declare_namespace(__name__)
+except ImportError, e:
+ from pkgutil import extend_path
+ __path__ = extend_path(__path__, __name__)
Added: z3ext.lucene/trunk/src/z3ext/lucene/README.txt
===================================================================
--- z3ext.lucene/trunk/src/z3ext/lucene/README.txt (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/lucene/README.txt 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,159 @@
+=================
+Lucene Text index
+=================
+
+Apache Lucene index for zope3. Jython is required.
+
+For configure default settings, add following code to zope.conf
+
+<product-config z3ext.lucene>
+ server1 testing server,8981,/path-to-lucene/Zope3/var/luceneindex
+</product-config>
+
+First server record, then parameters seperated by ','
+First title of lucene server also this title is using for utility name,
+port, directory where lucene should create it's data
+
+We need temporary directory
+
+ >>> import tempfile
+ >>> lucene_dir = tempfile.mkdtemp()
+
+We'll try emulate <product-config z3ext.lucene>
+
+ >>> from z3ext.lucene.tests import JYTHON
+ >>> from zope.app.appsetup import product
+ >>> product._configs['z3ext.lucene'] = {'server1': \
+ ... 'testing server,56999,%s'%lucene_dir, 'jython': JYTHON}
+
+Let's check this
+
+ >>> product.getProductConfiguration('z3ext.lucene')
+ {'jython': '...jython', 'server1': 'testing server,56999,...'}
+
+
+Usually startLucene() function is colled during IDatabaseOpenedEvent event,
+we simply call it directly:
+
+ >>> from z3ext.lucene.server.subscribers import startLucene
+ >>> startLucene(None)
+
+Lucene server registers in system as ILucene with name.
+
+ >>> from zope.component import getUtility
+ >>> from z3ext.lucene.server.interfaces import ILucene
+
+ >>> server = getUtility(ILucene, 'testing server')
+ >>> print server
+ LuceneServer<testing server,port=56999>
+
+We need give some time to lucene server to start
+
+ >>> import time
+ >>> time.sleep(5)
+
+Now we need catalog index
+
+ >>> from z3ext.lucene.index import LuceneTextIndex
+
+ >>> index = LuceneTextIndex('testing server')
+
+ >>> from zope import interface
+ >>> from zope.index.text.interfaces import ISearchableText
+
+Indexed document you have ISearchableText adapter to get indexed.
+We will create simple object that implements ISearchableText
+
+ >>> class Document(object):
+ ... interface.implements(ISearchableText)
+ ... def __init__(self, text):
+ ... self.text = text
+ ... def getSearchableText(self):
+ ... return self.text
+
+ >>> doc1 = Document(\
+ ... "A utility is registered to provide an interface with a "\
+ ... "name. If a component provides only one interface, then the"\
+ ... "provides argument can be omitted and the provided interface"\
+ ... "will be used. (In this case, provides argument can still be"\
+ ... "provided to provide a less specific interface.)")
+ >>> doc2 = Document(\
+ ... "Return a list of adapters that match. If an adapter is named, "\
+ ... "only the most specific adapter of a given name is returned." \
+ ... "If context is None, an application-defined policy is used to choose "\
+ ... "an appropriate service manager from which to get an 'Adapters' service.")
+
+
+Let's index documents
+
+ >>> index.index_doc('1', doc1)
+ >>> index.index_doc('2', doc2)
+
+Now we can search text
+
+ >>> list(index.apply('component provides'))
+ [1]
+
+ >>> list(index.apply('service manager'))
+ [2]
+
+ >>> list(index.apply('name'))
+ [1, 2]
+
+
+Statistics
+
+ >>> index.documentCount(), index.wordCount()
+ (2, 0)
+
+We can use any number of Luxene indexes with one lucene server
+
+ >>> index2 = LuceneTextIndex('testing server')
+
+ >>> list(index2.apply('component provides'))
+ []
+ >>> list(index2.apply('service manager'))
+ []
+ >>> list(index2.apply('name'))
+ []
+
+
+ZEO setup
+---------
+
+With zeo setup we should run only one copy of Lucene Server. So we can start
+lucene server on one zope instance (or by using
+z3ext/lucene/server/server.sh script we can run lucene server anywhere)
+and on other instances we can use LuceneClient
+
+Configuration for zope.conf
+
+<product-config z3ext.lucene>
+ client1 lucene client,http://127.0.0.1:56999/lucene/
+</product-config>
+
+ >>> from zope.component import provideUtility
+ >>> from z3ext.lucene.server.client import LuceneClient
+ >>> client = LuceneClient('lucene client', 'http://127.0.0.1:56999/lucene/')
+ >>> provideUtility(client, ILucene, 'lucene client')
+
+ >>> index.utility = 'lucene client'
+
+ >>> list(index.apply('component provides'))
+ [1]
+
+ >>> list(index.apply('service manager'))
+ [2]
+
+ >>> list(index.apply('name'))
+ [1, 2]
+
+
+unindex_doc
+-----------
+
+ >>> index.unindex_doc('2')
+ >>> list(index.apply('service manager'))
+ []
+
+ >>> index.clear()
\ No newline at end of file
Added: z3ext.lucene/trunk/src/z3ext/lucene/__init__.py
===================================================================
--- z3ext.lucene/trunk/src/z3ext/lucene/__init__.py (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/lucene/__init__.py 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1 @@
+# This file is necessary to make this directory a package.
Added: z3ext.lucene/trunk/src/z3ext/lucene/browser/__init__.py
===================================================================
--- z3ext.lucene/trunk/src/z3ext/lucene/browser/__init__.py (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/lucene/browser/__init__.py 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1 @@
+# This file is necessary to make this directory a package.
Added: z3ext.lucene/trunk/src/z3ext/lucene/browser/configure.zcml
===================================================================
--- z3ext.lucene/trunk/src/z3ext/lucene/browser/configure.zcml (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/lucene/browser/configure.zcml 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,52 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:browser="http://namespaces.zope.org/browser"
+ i18n_domain="z3ext">
+
+ <browser:icon
+ name="zmi_icon"
+ for="..interfaces.ILuceneIndex"
+ file="lucene-icon.gif" />
+
+ <browser:addform
+ name="addLuceneIndex"
+ label="Add a lucene index"
+ schema="..interfaces.ILuceneIndex"
+ permission="zope.ManageServices"
+ content_factory="..index.LuceneTextIndex" />
+
+ <browser:addMenuItem
+ title="Lucene Index"
+ description="Index based on a apache lucene index"
+ class="..index.LuceneTextIndex"
+ permission="zope.ManageServices"
+ view="addLuceneIndex" />
+
+ <browser:menuItem
+ for="..interfaces.ILuceneIndex"
+ menu="zmi_views"
+ title="View"
+ action="@@index.html"
+ permission="zope.ManageServices" />
+
+ <browser:page
+ for="..interfaces.ILuceneIndex"
+ name="index.html"
+ template="indexview.pt"
+ class=".indexview.IndexView"
+ permission="zope.ManageServices" />
+
+ <browser:menuItem
+ for="..interfaces.ILuceneIndex"
+ menu="zmi_views"
+ title="Edit"
+ action="@@edit.html"
+ permission="zope.ManageServices" />
+
+ <browser:page
+ for="..interfaces.ILuceneIndex"
+ name="edit.html"
+ class=".indexedit.LuceneConfiguration"
+ permission="zope.ManageServices" />
+
+</configure>
Added: z3ext.lucene/trunk/src/z3ext/lucene/browser/indexedit.py
===================================================================
--- z3ext.lucene/trunk/src/z3ext/lucene/browser/indexedit.py (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/lucene/browser/indexedit.py 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,30 @@
+##############################################################################
+#
+# Copyright (c) 2007 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.
+#
+##############################################################################
+"""
+
+$Id: indexedit.py 1523 2008-02-20 09:40:53Z fafhrd91 $
+"""
+from zope.formlib import form
+
+from z3ext.lucene.i18n import _
+from z3ext.lucene.interfaces import ILuceneIndex
+
+
+class LuceneConfiguration(form.EditForm):
+
+ form_fields = form.Fields(ILuceneIndex, render_context=True)
+
+ label = _(u'Lucene Text Index')
+ description = _(u'Using lucene text search engine '\
+ 'for full text searching.')
Added: z3ext.lucene/trunk/src/z3ext/lucene/browser/indexview.pt
===================================================================
--- z3ext.lucene/trunk/src/z3ext/lucene/browser/indexview.pt (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/lucene/browser/indexview.pt 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,31 @@
+<html metal:use-macro="context/@@standard_macros/view" i18n:domain="z3ext">
+ <body>
+ <div metal:fill-slot="body"
+ tal:define="stats view/getStatistics">
+ <h1 i18n:translate="">Lucene Text Index</h1>
+ <div class="documentDescription" i18n:translate="">
+ Using lucene text search engine for full text searching.
+ </div>
+
+ <tal:block i18n:translate="">Document count:
+ <tal:block i18n:name="documents" content="stats/documents" />
+ </tal:block>
+ </div>
+
+ <div metal:fill-slot="page-bottom" class="frame">
+ <h1 i18n:translate="">Advanced actions</h1>
+ <br />
+
+ <form action="@@index.html" method="post">
+ <div i18n:translate="">Reindex all indexed documents.</div>
+ <input class="context" type="submit" name="advanced.reindexAll"
+ value="Process" i18n:attributes="value" />
+ <br /><br />
+
+ <div i18n:translate="">Search and reindex all possible documents.</div>
+ <input class="context" type="submit" name="advanced.reindexAll"
+ value="Process" i18n:attributes="value" />
+ </form>
+ </div>
+ </body>
+</html>
Added: z3ext.lucene/trunk/src/z3ext/lucene/browser/indexview.py
===================================================================
--- z3ext.lucene/trunk/src/z3ext/lucene/browser/indexview.py (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/lucene/browser/indexview.py 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,51 @@
+##############################################################################
+#
+# Copyright (c) 2007 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.
+#
+##############################################################################
+"""
+
+$Id: indexview.py 671 2007-12-07 18:20:27Z fafhrd91 $
+"""
+
+from zope.component import getUtility
+from zope.app.intid.interfaces import IIntIds
+
+from z3ext.lucene.utils import indexObject
+from z3ext.lucene.interfaces import ILuceneIndex
+
+
+class IndexView(object):
+
+ def __call__(self):
+ self.update()
+ return self.index()
+
+ def getStatistics(self):
+ index = self.context
+
+ try:
+ return {'documents': index.documentCount(),
+ 'words': index.wordCount()}
+ except:
+ return {'documents': 'Unknown', 'words': 'Unknown'}
+
+ def update(self):
+ request = self.request
+
+ if request.has_key('advanced.reindexAll'):
+ intids = getUtility(IIntIds)
+ index = getUtility(ILuceneIndex)
+
+ for id in intids:
+ ob = intids.queryObject(id)
+ if ob is not None:
+ indexObject(ob, index, intids)
Added: z3ext.lucene/trunk/src/z3ext/lucene/browser/lucene-icon.gif
===================================================================
(Binary files differ)
Property changes on: z3ext.lucene/trunk/src/z3ext/lucene/browser/lucene-icon.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3ext.lucene/trunk/src/z3ext/lucene/browser/product.pt
===================================================================
--- z3ext.lucene/trunk/src/z3ext/lucene/browser/product.pt (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/lucene/browser/product.pt 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,21 @@
+<div class="frame" tal:define="stats view/getStatistics" i18n:domain="z3ext">
+ <h1 i18n:translate="">Lucene Text Index</h1>
+ <div class="documentDescription" i18n:translate="">
+ Using lucene text search engine for full text searching.
+ </div>
+
+ <tal:block i18n:translate="">Document count:
+ <tal:block i18n:name="documents" content="stats/documents" />
+ </tal:block>
+</div>
+
+<div class="frame">
+ <h1 i18n:translate="">Advanced actions</h1>
+ <br />
+
+ <form action="@@index.html" method="post">
+ <div i18n:translate="">Reindex all indexed documents.</div>
+ <input class="context" type="submit" name="advanced.reindexAll"
+ value="Process" i18n:attributes="value" />
+ </form>
+</div>
Added: z3ext.lucene/trunk/src/z3ext/lucene/browser/product.py
===================================================================
--- z3ext.lucene/trunk/src/z3ext/lucene/browser/product.py (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/lucene/browser/product.py 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,74 @@
+##############################################################################
+#
+# Copyright (c) 2007 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.
+#
+##############################################################################
+"""
+
+$Id: product.py 1828 2008-03-21 12:51:56Z fafhrd91 $
+"""
+from zope.component import getUtility
+from zope.traversing.browser import absoluteURL
+from zope.app.intid.interfaces import IIntIds
+from zope.app.pagetemplate import ViewPageTemplateFile
+
+from z3ext.layoutform import Fields, PageletEditForm
+from z3ext.statusmessage.interfaces import IStatusMessage
+
+from z3ext.lucene.i18n import _
+from z3ext.lucene.utils import indexObject
+from z3ext.lucene.interfaces import ILuceneIndex
+
+
+class LuceneProduct(PageletEditForm):
+
+ fields = Fields(ILuceneIndex)
+
+ label = _(u'Lucene Text Index')
+ description = _(u'Using lucene text search engine for full text searching.')
+
+ info = ViewPageTemplateFile('product.pt')
+
+ def getContent(self):
+ return getUtility(ILuceneIndex)
+
+ def cancelURL(self):
+ return absoluteURL(self.context.__parent__, self.request) + '/'
+
+ def getStatistics(self):
+ index = getUtility(ILuceneIndex)
+
+ try:
+ return {'documents': index.documentCount(),
+ 'words': index.wordCount()}
+ except:
+ return {'documents': 'Unknown', 'words': 'Unknown'}
+
+ def update(self):
+ super(LuceneProduct, self).update()
+
+ request = self.request
+
+ if request.has_key('advanced.reindexAll'):
+ intids = getUtility(IIntIds)
+ index = getUtility(ILuceneIndex)
+
+ for id in intids:
+ ob = intids.queryObject(id)
+ if ob is not None:
+ indexObject(ob, index, intids)
+
+ IStatusMessage(request).add(_(u'Reindex process has been completed.'))
+
+ def render(self):
+ rendered = super(LuceneProduct, self).render()
+
+ return rendered + self.info()
Added: z3ext.lucene/trunk/src/z3ext/lucene/browser/product.zcml
===================================================================
--- z3ext.lucene/trunk/src/z3ext/lucene/browser/product.zcml (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/lucene/browser/product.zcml 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,21 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:browser="http://namespaces.zope.org/browser"
+ i18n_domain="z3ext">
+
+ <registerIn registry="z3ext.product.z3ext-lucene">
+ <browser:menuItem
+ for="..interfaces.ILuceneProduct"
+ menu="zmi_views"
+ title="View"
+ action="@@index.html"
+ permission="z3ext.ManageProducts" />
+
+ <browser:page
+ for="..interfaces.ILuceneProduct"
+ name="index.html"
+ class=".product.LuceneProduct"
+ permission="z3ext.ManageProducts" />
+ </registerIn>
+
+</configure>
Added: z3ext.lucene/trunk/src/z3ext/lucene/configure.zcml
===================================================================
--- z3ext.lucene/trunk/src/z3ext/lucene/configure.zcml (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/lucene/configure.zcml 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,33 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ i18n_domain="z3ext">
+
+ <include package="z3ext.lucene.server" />
+ <include package="z3ext.lucene.browser" />
+
+ <class class=".index.LuceneTextIndex">
+ <factory
+ id="z3ext.lucene.LuceneTextIndex"
+ title="Lucene Text Index" />
+
+ <require
+ permission="zope.ManageContent"
+ interface=".interfaces.ILuceneIndex"
+ set_schema=".interfaces.ILuceneIndex" />
+ </class>
+
+ <subscriber
+ for="zope.app.intid.interfaces.IIntIdAddedEvent"
+ handler=".subscribers.modifiedHandler" />
+
+ <subscriber
+ for="zope.lifecycleevent.interfaces.IObjectModifiedEvent"
+ handler=".subscribers.modifiedHandler" />
+
+ <subscriber
+ for="zope.app.intid.interfaces.IIntIdRemovedEvent"
+ handler=".subscribers.removedHandler" />
+
+ <include file="product.zcml" />
+
+</configure>
Added: z3ext.lucene/trunk/src/z3ext/lucene/i18n.py
===================================================================
--- z3ext.lucene/trunk/src/z3ext/lucene/i18n.py (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/lucene/i18n.py 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,19 @@
+##############################################################################
+#
+# Copyright (c) 2007 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.
+#
+##############################################################################
+""" i18n
+
+$Id: i18n.py 1828 2008-03-21 12:51:56Z fafhrd91 $
+"""
+from zope.i18nmessageid import MessageFactory
+_ = MessageFactory('z3ext')
Added: z3ext.lucene/trunk/src/z3ext/lucene/index.py
===================================================================
--- z3ext.lucene/trunk/src/z3ext/lucene/index.py (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/lucene/index.py 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,150 @@
+##############################################################################
+#
+# Copyright (c) 2007 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.
+#
+##############################################################################
+""" index implementation
+
+$Id: index.py 1840 2008-03-25 16:28:43Z fafhrd91 $
+"""
+import sys, random, logging
+from datetime import datetime
+from persistent import Persistent
+from BTrees.IFBTree import IFSet
+
+from zope import interface
+from zope.component import queryUtility, getAdapters
+
+from zope.app.container.contained import Contained
+
+from zope.app.catalog.interfaces import ICatalogIndex
+from zope.index.text.interfaces import ISearchableText
+
+from z3ext.lucene.interfaces import ILuceneIndex
+from z3ext.lucene.server.interfaces import ILucene
+
+
+class BaseLuceneTextIndex(Persistent, Contained):
+ """Lucene Text Index."""
+ interface.implements(ILuceneIndex)
+
+ utility = ''
+ language = 'English'
+
+ _instance = None
+
+ def __init__(self, utility=''):
+ self.utility = utility
+
+ @property
+ def instance(self):
+ id = self._instance
+ if id is None:
+ id = u'%010d-%s' % (random.randrange(sys.maxint), datetime.now().toordinal())
+ self._instance = id
+ return id
+
+ def connect(self):
+ if not hasattr(self, '_v_connection') or \
+ self._v_connection is None:
+ self._v_connection = queryUtility(ILucene, self.utility)
+ return self._v_connection
+
+ def disconnect(self):
+ self._v_connection = None
+
+ def clear(self):
+ pass
+
+ def index_doc(self, docid, obj):
+ """See zope.textindex.textindexinterfaces.IInjection"""
+ server = self.connect()
+ if server is None:
+ return
+
+ text = []
+ st = ISearchableText(obj, None)
+ if st is not None:
+ text.append(st.getSearchableText())
+
+ for name, st in getAdapters((obj,), ISearchableText):
+ text.append(st.getSearchableText())
+
+ text = u' '.join(text)
+ if text:
+ try:
+ server.indexDocument(self.instance, str(docid), text)
+ except Exception, e:
+ logging.getLogger('z3ext.lucene').log(logging.WARNING, e)
+
+ def unindex_doc(self, docid):
+ """See zope.textindex.textindexinterfaces.IInjection"""
+ server = self.connect()
+ try:
+ server.unindexDocument(self.instance, str(docid))
+ except:
+ pass
+
+ def apply(self, querytext, start=0, count=None):
+ """See zope.textindex.textindexinterfaces.IQuerying"""
+ if type(querytext) is dict:
+ if len(querytext) > 1:
+ raise ValueError('may only pass one of key, value pair')
+ elif not querytext:
+ return None
+
+ query_type, query = querytext.items()[0]
+ query_type = query_type.lower()
+
+ if isinstance(query, basestring):
+ query = (query,)
+
+ values = []
+ for value in query:
+ values.append(' AND '.join(unicode(value).split()))
+
+ if query_type == 'any_of':
+ querytext = ' OR '.join(values)
+ elif query_type == 'all_of':
+ querytext = ' AND '.join(values)
+ else:
+ return None
+
+ server = self.connect()
+ try:
+ results = server.query(self.instance, querytext)
+ except:
+ return None
+
+ return IFSet([int(x[0]) for x in results])
+
+ def _getStatistics(self):
+ if not hasattr(self, '_v_stats') or self._v_stats is None:
+ server = self.connect()
+ try:
+ return server.getStatistics(self.instance)
+ except:
+ return [-1, -1]
+ self._v_stats = server.getStatistics(self.instance)
+
+ return self._v_stats
+
+ def documentCount(self):
+ """See zope.textindex.textindexinterfaces.IStatistics"""
+ return self._getStatistics()[0]
+
+ def wordCount(self):
+ """See zope.textindex.textindexinterfaces.IStatistics"""
+ return self._getStatistics()[1]
+
+
+class LuceneTextIndex(BaseLuceneTextIndex):
+ interface.implements(ICatalogIndex)
Added: z3ext.lucene/trunk/src/z3ext/lucene/interfaces.py
===================================================================
--- z3ext.lucene/trunk/src/z3ext/lucene/interfaces.py (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/lucene/interfaces.py 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,51 @@
+##############################################################################
+#
+# Copyright (c) 2007 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.
+#
+##############################################################################
+""" z3ext.lucene interfaces
+
+$Id: interfaces.py 1828 2008-03-21 12:51:56Z fafhrd91 $
+"""
+from zope import schema, interface
+from zope.index.interfaces import IInjection, IIndexSearch, IStatistics
+
+from i18n import _
+from vocabulary import languages
+
+
+class ILuceneIndex(IInjection, IIndexSearch, IStatistics):
+ """This is a general interface for indexes that use remote engines
+ to index documents, such as Lucene."""
+
+ utility = schema.Choice(
+ title=_(u'Lucene Server'),
+ description=_(u'Select configured lucene server.'),
+ vocabulary='z3ext.lucene.servers',
+ missing_value=u'',
+ required=False)
+
+ language = schema.Choice(
+ title=_(u'Default language'),
+ description=_(u'Select default language of indexed text.'),
+ default='English',
+ vocabulary=languages,
+ required = False)
+
+ def connect():
+ """Connect to the server."""
+
+ def disconnect():
+ """Disconnect from the server."""
+
+
+class ILuceneProduct(interface.Interface):
+ """ lucene configuration interface """
Added: z3ext.lucene/trunk/src/z3ext/lucene/product.py
===================================================================
--- z3ext.lucene/trunk/src/z3ext/lucene/product.py (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/lucene/product.py 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,45 @@
+##############################################################################
+#
+# Copyright (c) 2007 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.
+#
+##############################################################################
+""" installer for z3ext.poduct
+
+$Id: product.py 860 2008-01-09 08:48:08Z fafhrd91 $
+"""
+from zope import interface
+from zope.app.catalog.interfaces import ICatalogIndex
+
+from z3ext.product.utils import registerUtility, unregisterUtility
+
+from z3ext.lucene.i18n import _
+from z3ext.lucene.interfaces import ILuceneIndex, ILuceneProduct
+
+from z3ext.lucene.index import BaseLuceneTextIndex
+
+
+class PortalLuceneIndex(BaseLuceneTextIndex):
+ """ portal index """
+
+
+class LuceneInstaller(object):
+ interface.implements(ILuceneProduct)
+
+ def update(self):
+ registerUtility('z3ext.lucene', PortalLuceneIndex,
+ ((ILuceneIndex, ''),
+ (ICatalogIndex, 'searchableText')))
+ super(LuceneInstaller, self).update()
+
+ def uninstall(self):
+ unregisterUtility('z3ext.lucene',
+ ((ILuceneIndex, ''), (ICatalogIndex, 'searchableText')))
+ super(LuceneInstaller, self).uninstall()
Added: z3ext.lucene/trunk/src/z3ext/lucene/product.zcml
===================================================================
--- z3ext.lucene/trunk/src/z3ext/lucene/product.zcml (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/lucene/product.zcml 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,33 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:zcml="http://namespaces.zope.org/zcml"
+ xmlns:z3ext="http://namespaces.zope.org/z3ext"
+ i18n_domain="z3ext">
+
+ <zcml:configure zcml:condition="installed z3ext.product">
+ <include package="z3ext.product" />
+
+ <z3ext:product
+ name="z3ext-lucene"
+ title="Lucene Text Index"
+ description="Using lucene text search engine for full text searching."
+ schema=".interfaces.ILuceneProduct"
+ class=".product.LuceneInstaller"
+ configurable="true" />
+
+ <class class=".product.PortalLuceneIndex">
+ <require
+ permission="z3ext.ManageProducts"
+ interface=".interfaces.ILuceneIndex"
+ set_schema=".interfaces.ILuceneIndex" />
+ </class>
+
+ <class class=".product.PortalLuceneIndex"
+ zcml:condition="installed z3ext.catalog">
+ <implements interface="z3ext.catalog.interfaces.IFullTextIndex" />
+ </class>
+
+ <include package="z3ext.lucene.browser" file="product.zcml" />
+ </zcml:configure>
+
+</configure>
Added: z3ext.lucene/trunk/src/z3ext/lucene/server/__init__.py
===================================================================
--- z3ext.lucene/trunk/src/z3ext/lucene/server/__init__.py (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/lucene/server/__init__.py 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1 @@
+# This file is necessary to make this directory a package.
Added: z3ext.lucene/trunk/src/z3ext/lucene/server/client.py
===================================================================
--- z3ext.lucene/trunk/src/z3ext/lucene/server/client.py (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/lucene/server/client.py 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,42 @@
+##############################################################################
+#
+# Copyright (c) 2007 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.
+#
+##############################################################################
+""" zope lucene client interfaces
+
+$Id: client.py 671 2007-12-07 18:20:27Z fafhrd91 $
+"""
+
+import xmlrpclib
+from zope import interface
+from interfaces import ILuceneClient
+
+
+class LuceneClient(object):
+ interface.implements(ILuceneClient)
+
+ def __init__(self, name, url):
+ self.url = url
+ self.name = name
+ self.connection = None
+
+ def stop(self):
+ self.connection = None
+
+ def start(self):
+ self.connection = xmlrpclib.ServerProxy(self.url)
+
+ def __str__(self):
+ return 'LuceneClient<%s,url=%s>'%(self.name, self.url)
+
+ def __getattr__(self, name):
+ return getattr(self.connection.lucene, name)
Added: z3ext.lucene/trunk/src/z3ext/lucene/server/configure.zcml
===================================================================
--- z3ext.lucene/trunk/src/z3ext/lucene/server/configure.zcml (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/lucene/server/configure.zcml 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,10 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+ <subscriber handler=".subscribers.startLucene" />
+
+ <utility
+ name="z3ext.lucene.servers"
+ provides="zope.schema.interfaces.IVocabularyFactory"
+ factory=".vocabulary.LuceneVocabulary" />
+
+</configure>
Added: z3ext.lucene/trunk/src/z3ext/lucene/server/indexserver.py
===================================================================
--- z3ext.lucene/trunk/src/z3ext/lucene/server/indexserver.py (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/lucene/server/indexserver.py 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,137 @@
+#!/usr/bin/jython
+# -*- coding: utf-8 -*-
+# -*- Mode: Python; py-indent-offset: 4 -*-
+# * Author: Nikolay Kim <fafhrd91 at gmail.com>
+""" lucene index server implementation
+
+$Id: indexserver.py 868 2008-01-09 10:37:45Z fafhrd91 $
+"""
+
+import os, sys, time
+
+from java.util import Vector
+
+from org.apache.xmlrpc import WebServer, XmlRpcHandler
+
+from org.apache.lucene.document import Document, Field
+from org.apache.lucene.analysis import StopAnalyzer, SimpleAnalyzer
+from org.apache.lucene.index import IndexReader, IndexWriter, Term
+from org.apache.lucene.search import IndexSearcher, Hits, BooleanClause
+from org.apache.lucene.search import BooleanFilter, RangeFilter, FilterClause
+
+from org.apache.lucene.store import FSDirectory
+from org.apache.lucene.queryParser import QueryParser
+
+# Jython is not yet Python 2.2 compatible.
+True = 1
+False = 0
+
+def log(msg='', subsystem='lucene indexserver'):
+ #log = logging.getLogger(subsystem)
+ #log.log(logging.INFO, msg)
+ #print msg
+ pass
+
+
+class LuceneXMLRPCHandler(XmlRpcHandler):
+
+ def __init__(self, indexPath):
+ """Instantiate the handler object."""
+ self.indexPath = indexPath
+ self.analyzer = StopAnalyzer()
+
+ # Make sure the path exists
+ if not os.path.exists(self.indexPath):
+ os.mkdir(self.indexPath)
+
+ if not os.path.exists(os.path.join(self.indexPath, 'segments.gen')):
+ log('Creating new index.')
+ writer = IndexWriter(self.indexPath, self.analyzer, 1)
+ writer.close()
+
+ def execute(self, name, args):
+ """See interface XmlRpcHandler."""
+ if name.startswith('lucene.'):
+ name = name[7:]
+ return getattr(self, 'xmlrpc_'+name)(*args)
+
+ def xmlrpc_unindexDocument(self, instance, id):
+ """ Unindex document """
+ filter = BooleanFilter()
+
+ filter.add(FilterClause(RangeFilter('id', id, id, 1, 1),
+ BooleanClause.Occur.MUST))
+ filter.add(FilterClause(RangeFilter('instance', instance, instance, 1, 1),
+ BooleanClause.Occur.MUST))
+
+ reader = IndexReader.open(self.indexPath)
+
+ bits = filter.bits(reader)
+
+ docId = bits.nextSetBit(0)
+ while docId >= 0:
+ reader.deleteDocument(docId)
+ docId = bits.nextSetBit(docId+1)
+
+ reader.close()
+
+ def xmlrpc_indexDocument(self, instance, id, text):
+ """Index a new document."""
+ self.xmlrpc_unindexDocument(instance, id)
+
+ # Create a document and add two fields to it.
+ doc = Document()
+ doc.add(Field('id', id, Field.Store.YES, Field.Index.UN_TOKENIZED))
+ doc.add(Field('text', text, Field.Store.YES, Field.Index.TOKENIZED))
+ doc.add(Field('instance', instance, Field.Store.YES, Field.Index.UN_TOKENIZED))
+
+ # Write the document into the index.
+ writer = IndexWriter(self.indexPath, self.analyzer, 0)
+ writer.addDocument(doc)
+ writer.optimize()
+ writer.close()
+ log('Insert: Instance: %s Document: %s' %(instance, id))
+ return 1
+
+ def xmlrpc_query(self, instance, querytext):
+ """Query the index."""
+ query = QueryParser('text', self.analyzer)
+ log('Instance: %s, Query: %s' %(instance, querytext))
+
+ searcher = IndexSearcher(self.indexPath)
+ results = searcher.search(query.parse(querytext),
+ RangeFilter('instance', instance, instance, 1, 1))
+
+ # Prepare the result for XML-RPC.
+ ids = Vector()
+ for hitid in range(results.length()):
+ entry = Vector()
+ entry.add(results.doc(hitid).getField('id').stringValue())
+ entry.add(results.score(hitid))
+ ids.add(entry)
+
+ return ids
+
+ def xmlrpc_getStatistics(self, instance):
+ reader = IndexReader.open(self.indexPath)
+
+ filter = RangeFilter('instance', instance, instance, 1, 1)
+
+ num = filter.bits(reader).cardinality()
+
+ stat = Vector()
+ stat.add(num)
+ stat.add(0)#len(index.terms()))
+ reader.close()
+ return stat
+
+
+if __name__ == '__main__':
+ if len(sys.argv) < 3:
+ print 'usage: indexserver.py port index_dir'
+ sys.exit(1)
+
+ web = WebServer(int(sys.argv[1]))
+ web.addHandler('lucene', LuceneXMLRPCHandler(sys.argv[2]))
+ log('Starting Lucene XML-RPC Server on port %s' %sys.argv[1])
+ web.start()
Added: z3ext.lucene/trunk/src/z3ext/lucene/server/interfaces.py
===================================================================
--- z3ext.lucene/trunk/src/z3ext/lucene/server/interfaces.py (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/lucene/server/interfaces.py 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+# -*- Mode: Python; py-indent-offset: 4 -*-
+# * Author: Nikolay Kim <fafhrd91 at gmail.com>
+""" zope lucene server/client interfaces
+
+$Id: interfaces.py 498 2007-11-04 08:53:42Z fafhrd91 $
+"""
+
+from zope import interface
+
+class ILucene(interface.Interface):
+ """ lucene server/client """
+
+ name = interface.Attribute('Name')
+
+ def stop(self):
+ """ stop lucene """
+
+ def start():
+ """ start lucene """
+
+ def __str__():
+ """ """
+
+class ILuceneClient(ILucene):
+ """ client """
+
+ URL = interface.Attribute('Server URL')
+
+
+class ILuceneServer(ILucene):
+ """ server """
+
+ port = interface.Attribute('Port')
+ fspath = interface.Attribute('Filesystem directory path')
Added: z3ext.lucene/trunk/src/z3ext/lucene/server/jar/commons-logging-1.1.jar
===================================================================
(Binary files differ)
Property changes on: z3ext.lucene/trunk/src/z3ext/lucene/server/jar/commons-logging-1.1.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3ext.lucene/trunk/src/z3ext/lucene/server/jar/lucene-core-2.2.0.jar
===================================================================
(Binary files differ)
Property changes on: z3ext.lucene/trunk/src/z3ext/lucene/server/jar/lucene-core-2.2.0.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3ext.lucene/trunk/src/z3ext/lucene/server/jar/lucene-queries-2.2.0.jar
===================================================================
(Binary files differ)
Property changes on: z3ext.lucene/trunk/src/z3ext/lucene/server/jar/lucene-queries-2.2.0.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3ext.lucene/trunk/src/z3ext/lucene/server/jar/lucene-snowball-2.2.0.jar
===================================================================
(Binary files differ)
Property changes on: z3ext.lucene/trunk/src/z3ext/lucene/server/jar/lucene-snowball-2.2.0.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3ext.lucene/trunk/src/z3ext/lucene/server/jar/xmlrpc-1.2-b1.jar
===================================================================
(Binary files differ)
Property changes on: z3ext.lucene/trunk/src/z3ext/lucene/server/jar/xmlrpc-1.2-b1.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3ext.lucene/trunk/src/z3ext/lucene/server/server.py
===================================================================
--- z3ext.lucene/trunk/src/z3ext/lucene/server/server.py (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/lucene/server/server.py 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,63 @@
+##############################################################################
+#
+# Copyright (c) 2007 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.
+#
+##############################################################################
+""" zope lucene server implementation
+
+$Id: server.py 671 2007-12-07 18:20:27Z fafhrd91 $
+"""
+
+import xmlrpclib, signal, os, os.path, copy
+from subprocess import Popen
+
+from zope import interface
+from interfaces import ILuceneServer
+
+dir = os.path.dirname(__file__)
+
+classpath = []
+for jar in ('lucene-core-2.2.0.jar', 'lucene-queries-2.2.0.jar',
+ 'lucene-snowball-2.2.0.jar', 'xmlrpc-1.2-b1.jar'):
+ classpath.append(os.path.join(dir, 'jar', jar))
+
+CLASSPATH = ':'.join(classpath)
+SCRIPT = os.path.join(dir, 'indexserver.py')
+
+
+class LuceneServer(object):
+ interface.implements(ILuceneServer)
+
+ def __init__(self, name, port, fspath, jython='/usr/bin/jython'):
+ self.port = port
+ self.name = name
+ self.fspath = fspath
+ self.jython = jython
+ self.connection = None
+
+ def stop(self):
+ self.connection = None
+ os.kill(self.proc.pid, signal.SIGTERM)
+
+ def start(self):
+ dir = os.path.dirname(__file__)
+
+ env = copy.copy(os.environ)
+ env['CLASSPATH'] = CLASSPATH
+
+ self.proc = Popen([self.jython, SCRIPT, self.port, self.fspath], env=env)
+ self.connection = xmlrpclib.ServerProxy('http://127.0.0.1:%s/lucene/'%self.port)
+
+ def __str__(self):
+ return 'LuceneServer<%s,port=%s>'%(self.name, self.port)
+
+ def __getattr__(self, name):
+ return getattr(self.connection.lucene, name)
Added: z3ext.lucene/trunk/src/z3ext/lucene/server/server.sh
===================================================================
--- z3ext.lucene/trunk/src/z3ext/lucene/server/server.sh (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/lucene/server/server.sh 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# Path to the Jython startup script
+JYTHON=/usr/bin/jython
+
+# Index Data directory
+INDEX=./indexdata
+
+# XML-RPC Server Port
+PORT=19980
+
+# Path to the Lucene library
+LUCENE=./jar/lucene-core-2.2.0.jar:./jar/lucene-queries-2.2.0.jar:./jar/lucene-snowball-2.2.0.jar
+
+# Path to the XML-RPC library
+XMLRPC=./jar/xmlrpc-1.2-b1.jar
+
+export CLASSPATH=$LUCENE:$XMLRPC
+
+# Start the server
+$JYTHON indexserver.py $PORT $INDEX
Property changes on: z3ext.lucene/trunk/src/z3ext/lucene/server/server.sh
___________________________________________________________________
Name: svn:executable
+ *
Added: z3ext.lucene/trunk/src/z3ext/lucene/server/subscribers.py
===================================================================
--- z3ext.lucene/trunk/src/z3ext/lucene/server/subscribers.py (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/lucene/server/subscribers.py 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,65 @@
+##############################################################################
+#
+# Copyright (c) 2007 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.
+#
+##############################################################################
+"""
+
+$Id: subscribers.py 1545 2008-02-21 12:15:34Z fafhrd91 $
+"""
+import logging
+from twisted.internet import reactor
+
+from zope import component
+from zope.component import getGlobalSiteManager
+from zope.app.appsetup.product import getProductConfiguration
+from zope.app.appsetup.interfaces import IDatabaseOpenedEvent
+
+from interfaces import ILucene
+from client import LuceneClient
+from server import LuceneServer
+
+
+ at component.adapter(IDatabaseOpenedEvent)
+def startLucene(event):
+ config = getProductConfiguration('z3ext.lucene')
+ if config is None:
+ return
+
+ jython = config.get('jython', '/usr/bin/jython')
+
+ sm = getGlobalSiteManager()
+
+ for name, data in config.items():
+ data = [s.strip() for s in data.split(',')]
+
+ if name.startswith('server'):
+ lucene = LuceneServer(*data, **{'jython': jython})
+ elif name.startswith('client'):
+ lucene = LuceneClient(*data)
+ else:
+ continue
+
+ try:
+ lucene.start()
+ sm.registerUtility(lucene, ILucene, data[0])
+ except Exception, e:
+ logging.getLogger('z3ext.lucene').log(logging.WARNING, e)
+
+ reactor.addSystemEventTrigger('before', 'shutdown', stopLucene)
+
+
+def stopLucene():
+ # stop all registered lucene
+ sm = getGlobalSiteManager()
+
+ for name, utility in sm.getUtilitiesFor(ILucene):
+ utility.stop()
Added: z3ext.lucene/trunk/src/z3ext/lucene/server/vocabulary.py
===================================================================
--- z3ext.lucene/trunk/src/z3ext/lucene/server/vocabulary.py (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/lucene/server/vocabulary.py 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,33 @@
+##############################################################################
+#
+# Copyright (c) 2007 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.
+#
+##############################################################################
+"""
+
+$Id: vocabulary.py 671 2007-12-07 18:20:27Z fafhrd91 $
+"""
+
+from interfaces import ILucene
+from zope.component import getUtilitiesFor
+from zope.schema.vocabulary import SimpleTerm, SimpleVocabulary
+
+
+class LuceneVocabulary(object):
+
+ def __call__(self, context):
+ terms = []
+ for name, utility in getUtilitiesFor(ILucene):
+ terms.append((str(utility),
+ SimpleTerm(utility.name, utility.name, str(utility))))
+
+ terms.sort()
+ return SimpleVocabulary([term for t, term in terms])
Added: z3ext.lucene/trunk/src/z3ext/lucene/subscribers.py
===================================================================
--- z3ext.lucene/trunk/src/z3ext/lucene/subscribers.py (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/lucene/subscribers.py 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,24 @@
+##############################################################################
+#
+# Copyright (c) 2007 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.
+#
+##############################################################################
+"""
+
+$Id: subscribers.py 1828 2008-03-21 12:51:56Z fafhrd91 $
+"""
+from utils import indexObject, unindexObject
+
+def modifiedHandler(event):
+ indexObject(event.object)
+
+def removedHandler(event):
+ unindexObject(event.object)
Added: z3ext.lucene/trunk/src/z3ext/lucene/tests.py
===================================================================
--- z3ext.lucene/trunk/src/z3ext/lucene/tests.py (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/lucene/tests.py 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,47 @@
+##############################################################################
+#
+# Copyright (c) 2007 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.
+#
+##############################################################################
+""" z3ext.lucene tests
+
+$Id: tests.py 1828 2008-03-21 12:51:56Z fafhrd91 $
+"""
+__docformat__ = "reStructuredText"
+
+import os, sys
+import unittest, doctest
+from zope import interface, schema
+from zope.component import provideAdapter
+from zope.app.testing import setup
+from zope.traversing.namespace import view
+from zope.traversing.interfaces import ITraversable
+
+from z3ext.lucene.server.subscribers import stopLucene
+
+JYTHON = '/usr/bin/jython'
+
+
+def setUp(test):
+ setup.placelessSetUp()
+
+
+def tearDown(test):
+ stopLucene()
+ setup.placelessTearDown()
+
+def test_suite():
+ return unittest.TestSuite((
+ doctest.DocFileSuite(
+ 'README.txt',
+ setUp=setUp, tearDown=tearDown,
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS),
+ ))
Added: z3ext.lucene/trunk/src/z3ext/lucene/utils.py
===================================================================
--- z3ext.lucene/trunk/src/z3ext/lucene/utils.py (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/lucene/utils.py 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,51 @@
+##############################################################################
+#
+# Copyright (c) 2007 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.
+#
+##############################################################################
+"""
+
+$Id: utils.py 1828 2008-03-21 12:51:56Z fafhrd91 $
+"""
+from zope.component import queryUtility
+from zope.app.intid.interfaces import IIntIds
+
+from interfaces import ILuceneIndex
+
+
+def indexObject(object, index=None, intids=None):
+ if index is None:
+ index = queryUtility(ILuceneIndex)
+
+ if index is not None:
+ if intids is None:
+ intids = queryUtility(IIntIds)
+
+ if intids is not None:
+ id = intids.queryId(object)
+
+ if id is not None:
+ index.index_doc(id, object)
+
+
+def unindexObject(object, index=None, intids=None):
+ if index is None:
+ index = queryUtility(ILuceneIndex)
+
+ if index is not None:
+ if intids is None:
+ intids = queryUtility(IIntIds)
+
+ if intids is not None:
+ id = intids.getId(object)
+
+ if id is not None:
+ index.unindex_doc(id)
Added: z3ext.lucene/trunk/src/z3ext/lucene/vocabulary.py
===================================================================
--- z3ext.lucene/trunk/src/z3ext/lucene/vocabulary.py (rev 0)
+++ z3ext.lucene/trunk/src/z3ext/lucene/vocabulary.py 2008-03-25 16:36:06 UTC (rev 84935)
@@ -0,0 +1,33 @@
+##############################################################################
+#
+# Copyright (c) 2007 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.
+#
+##############################################################################
+"""
+
+$Id: vocabulary.py 1828 2008-03-21 12:51:56Z fafhrd91 $
+"""
+from zope.schema.vocabulary import SimpleTerm, SimpleVocabulary
+
+
+languages = SimpleVocabulary((
+ SimpleTerm('Danish', 'Danish', 'Danish'),
+ SimpleTerm('Dutch', 'Dutch', 'Dutch'),
+ SimpleTerm('English', 'English', 'English'),
+ SimpleTerm('Finnish', 'Finnish', 'Finnish'),
+ SimpleTerm('French', 'French', 'French'),
+ SimpleTerm('German', 'German', 'German'),
+ SimpleTerm('Italian', 'Italian', 'Italian'),
+ SimpleTerm('Norwegian', 'Norwegian', 'Norwegian'),
+ SimpleTerm('Portuguese', 'Portuguese', 'Portuguese'),
+ SimpleTerm('Russian', 'Russian', 'Russian'),
+ SimpleTerm('Spanish', 'Spanish', 'Spanish'),
+ SimpleTerm('Swedish', 'Swedish', 'Swedish')))
More information about the Checkins
mailing list