MJSplitterのインストール
MJSplitterとは、Zope上で動作するプロダクトで、コンテンツを日本語の単語にぶった切ってインデックスを作成してくれるものです。ぶった切りにはMeCabを使用しています。今回の話は結構やっつけなので参考にしないほうがいいかも。
$INSTANCE/Product以下にMJSplitterのリンクを張って、インスタンスを起動するとこんなエラーがでました。環境はVine Linuxです。
$ ./runzope (中略) 2006-10-06T15:21:07 ERROR(200) Zope Could not import Products.MJSplitter Traceback (most recent call last): File "/usr/local/lib/python/OFS/Application.py", line 673, in import_product product=__import__(pname, global_dict, global_dict, silly) File "/usr/local/zope/new_cms/Products/MJSplitter/__init__.py", line 10, in ? import MJSplitter File "/usr/local/zope/new_cms/Products/MJSplitter/MJSplitter.py", line 59, in ? class MJSplitter: File "/usr/local/zope/new_cms/Products/MJSplitter/MJSplitter.py", line 66, in MJSplitter mecabAdaptor = MeCabAdaptor(mecab_module, get_mecab(mecab_module)) File "/usr/local/zope/new_cms/Products/MJSplitter/MJSplitter.py", line 26, in get_mecab libpath = MECAB_LIBPATH File "/usr/local/zope/new_cms/Products/MJSplitter/MeCabLib.py", line 90, in __init__ self._lib = libmap(libpath, _MECAB_LIB_CATALOGUE) File "/usr/local/zope/new_cms/Products/MJSplitter/MeCabLib.py", line 62, in libmap lib_type_map = {"cdll": cdll, "windll": windll, "oledll": oledll} NameError: global name 'windll' is not defined Traceback (most recent call last): File "/usr/local/lib/python/Zope/Startup/run.py", line 50, in ? run() File "/usr/local/lib/python/Zope/Startup/run.py", line 19, in run start_zope(opts.configroot) File "/usr/local/lib/python/Zope/Startup/__init__.py", line 52, in start_zope starter.startZope() File "/usr/local/lib/python/Zope/Startup/__init__.py", line 231, in startZope Zope.startup() File "/usr/local/lib/python/Zope/__init__.py", line 47, in startup _startup() File "/usr/local/lib/python/Zope/App/startup.py", line 45, in startup OFS.Application.import_products() File "/usr/local/lib/python/OFS/Application.py", line 650, in import_products import_product(product_dir, product_name, raise_exc=debug_mode) File "/usr/local/lib/python/OFS/Application.py", line 673, in import_product product=__import__(pname, global_dict, global_dict, silly) File "/usr/local/zope/new_cms/Products/MJSplitter/__init__.py", line 10, in ? import MJSplitter File "/usr/local/zope/new_cms/Products/MJSplitter/MJSplitter.py", line 59, in ? class MJSplitter: File "/usr/local/zope/new_cms/Products/MJSplitter/MJSplitter.py", line 66, in MJSplitter mecabAdaptor = MeCabAdaptor(mecab_module, get_mecab(mecab_module)) File "/usr/local/zope/new_cms/Products/MJSplitter/MJSplitter.py", line 26, in get_mecab libpath = MECAB_LIBPATH File "/usr/local/zope/new_cms/Products/MJSplitter/MeCabLib.py", line 90, in __init__ self._lib = libmap(libpath, _MECAB_LIB_CATALOGUE) File "/usr/local/zope/new_cms/Products/MJSplitter/MeCabLib.py", line 62, in libmap lib_type_map = {"cdll": cdll, "windll": windll, "oledll": oledll} NameError: global name 'windll' is not defined
なんでしょう。windllが定義されてないよって。
該当箇所のソースはこんな感じ。
def libmap(lib_path, func_catalogue, lib_type="cdll"): """Performs restype/argtypes mapping for each function in catalogue. """ lib_type_map = {"cdll": cdll, "windll": windll, "oledll": oledll} lib = lib_type_map[lib_type].LoadLibrary(lib_path) for func_name, res_type, arg_types in func_catalogue: funcbody = getattr(lib, func_name) if res_type: funcbody.restype = res_type if arg_types: funcbody.argtypes = arg_types return lib
ただディクショナリを定義しているだけに見えるんだけどな。ま、定義がないって言うんだから消しちゃえ。ということでこうします。
def libmap(lib_path, func_catalogue, lib_type="cdll"): """Performs restype/argtypes mapping for each function in catalogue. """ lib_type_map = {"cdll": cdll} lib = lib_type_map[lib_type].LoadLibrary(lib_path) for func_name, res_type, arg_types in func_catalogue: funcbody = getattr(lib, func_name) if res_type: funcbody.restype = res_type if arg_types: funcbody.argtypes = arg_types return lib
ちなみにoleddlを残すとそれもundefinedだって言われます。
これでZopeを再起動。
$ ./runzope (中略) ------ 2006-10-06T15:24:36 ERROR(200) Zope Could not import Products.MJSplitter Traceback (most recent call last): File "/usr/local/lib/python/OFS/Application.py", line 673, in import_product product=__import__(pname, global_dict, global_dict, silly) File "/usr/local/zope/new_cms/Products/MJSplitter/__init__.py", line 10, in ? import MJSplitter File "/usr/local/zope/new_cms/Products/MJSplitter/MJSplitter.py", line 59, in ? class MJSplitter: File "/usr/local/zope/new_cms/Products/MJSplitter/MJSplitter.py", line 66, in MJSplitter mecabAdaptor = MeCabAdaptor(mecab_module, get_mecab(mecab_module)) File "/usr/local/zope/new_cms/Products/MJSplitter/MJSplitter.py", line 26, in get_mecab libpath = MECAB_LIBPATH File "/usr/local/zope/new_cms/Products/MJSplitter/MeCabLib.py", line 90, in __init__ self._lib = libmap(libpath, _MECAB_LIB_CATALOGUE) File "/usr/local/zope/new_cms/Products/MJSplitter/MeCabLib.py", line 63, in libmap lib = lib_type_map[lib_type].LoadLibrary(lib_path) File "/usr/lib/python2.3/site-packages/ctypes/__init__.py", line 398, in LoadLibrary return self._dlltype(name) File "/usr/lib/python2.3/site-packages/ctypes/__init__.py", line 315, in __init__ self._handle = _dlopen(self._name, mode) OSError: c:/Program Files/mecab/bin/libmecab.dll: cannot open shared object file: No such file or directory Traceback (most recent call last): File "/usr/local/lib/python/Zope/Startup/run.py", line 50, in ? run() File "/usr/local/lib/python/Zope/Startup/run.py", line 19, in run start_zope(opts.configroot) File "/usr/local/lib/python/Zope/Startup/__init__.py", line 52, in start_zope starter.startZope() File "/usr/local/lib/python/Zope/Startup/__init__.py", line 231, in startZope Zope.startup() File "/usr/local/lib/python/Zope/__init__.py", line 47, in startup _startup() File "/usr/local/lib/python/Zope/App/startup.py", line 45, in startup OFS.Application.import_products() File "/usr/local/lib/python/OFS/Application.py", line 650, in import_products import_product(product_dir, product_name, raise_exc=debug_mode) File "/usr/local/lib/python/OFS/Application.py", line 673, in import_product product=__import__(pname, global_dict, global_dict, silly) File "/usr/local/zope/new_cms/Products/MJSplitter/__init__.py", line 10, in ? import MJSplitter File "/usr/local/zope/new_cms/Products/MJSplitter/MJSplitter.py", line 59, in ? class MJSplitter: File "/usr/local/zope/new_cms/Products/MJSplitter/MJSplitter.py", line 66, in MJSplitter mecabAdaptor = MeCabAdaptor(mecab_module, get_mecab(mecab_module)) File "/usr/local/zope/new_cms/Products/MJSplitter/MJSplitter.py", line 26, in get_mecab libpath = MECAB_LIBPATH File "/usr/local/zope/new_cms/Products/MJSplitter/MeCabLib.py", line 90, in __init__ self._lib = libmap(libpath, _MECAB_LIB_CATALOGUE) File "/usr/local/zope/new_cms/Products/MJSplitter/MeCabLib.py", line 63, in libmap lib = lib_type_map[lib_type].LoadLibrary(lib_path) File "/usr/lib/python2.3/site-packages/ctypes/__init__.py", line 398, in LoadLibrary return self._dlltype(name) File "/usr/lib/python2.3/site-packages/ctypes/__init__.py", line 315, in __init__ self._handle = _dlopen(self._name, mode) OSError: c:/Program Files/mecab/bin/libmecab.dll: cannot open shared object file: No such file or directory
こんどはファイルがないって言われます。
そりゃ、"c:/Program..."なんてWindowsみたいなファイルはないよね。この定義はsettings.pyにあります。
# location of mecab dynamic library # setting for mecablib MECAB_LIBPATH = 'c:/Program Files/mecab/bin/libmecab.dll'
これをこう変えます。
# location of mecab dynamic library # setting for mecablib MECAB_LIBPATH = '/usr/local/lib/libmecab.so'
mecabのライブラリファイルの位置は適時変更してください。
Zopeを再々起動。
$ ./runzope (中略) ------ 2006-10-06T15:28:34 BLATHER(-100) Z2 Installed sighandler for SIGTERM ------ 2006-10-06T15:28:34 BLATHER(-100) Z2 Installed sighandler for SIGINT ------ 2006-10-06T15:28:34 BLATHER(-100) Z2 Installed sighandler for SIGHUP ------ 2006-10-06T15:28:34 BLATHER(-100) Z2 Installed sighandler for SIGUSR2 ------ 2006-10-06T15:28:35 INFO(0) Zope Ready to handle requests
ちゃんと起動しました。Splitがちゃんと動作してるかって?それはこれからですよ。