HyperEstraierのノードサーバから文書ドラフトを取り出す

HyperEstraier 1.30 から データベースのフォーマットに互換性がなくなったとかいう話だったので、HyperEstraier 1.29 のまま使っていたのだが、どんどんバージョンも進んでいるのでいい加減バージョンアップすることにした。
普通なら、インデックスを破棄してバージョンアップ後にインデックスを再構築するんだろうが、Plagger からフィードをノードサーバに送りつけるという使い方をしているので、手元には元ファイルがない。つうことで、スクリプトでノードサーバから文書ドラフトを取り出すことに。

#!/usr/bin/env python

import sys
import urllib
import os
import os.path
import time

def normalize_node_url(url):
    if url.endswith('/'):
        return url
    else:
        return url + '/'

def iter_hest_id(node_url):
    node_url = normalize_node_url(node_url)
    base_url = node_url + 'list?max=100'
    prev_url = None
    target_url = base_url

    while True:
        fp = urllib.urlopen(target_url)
        n = 0
        for line in (x.decode('utf8') for x in fp):
            id, prev_url, remain = line.split('\t', 2)
            yield id
            n += 1
        fp.close()

        if n > 0:
            target_url = base_url + '&prev=' + urllib.quote(prev_url)
        else:
            break

def backup_doc(node_url, backup_dir, id):
    node_url = normalize_node_url(node_url)
    n = int(id)
    subdir = os.path.join(backup_dir, '%03d' % (n / 100))
    filename = '%07d.est' % n
    if not os.path.exists(subdir):
        os.makedirs(subdir)
    get_doc_url = node_url + 'get_doc?id=' + urllib.quote(id)
    urllib.urlretrieve(get_doc_url, os.path.join(subdir, filename))


def usage():
    print >>sys.stderr, 'usage: %s node_url backup_dir' % sys.argv[0]

# check number of arguments
if len(sys.argv) != 3:
    usage()
    sys.exit(1)

node_url = sys.argv[1]
backup_dir = sys.argv[2]
for id in iter_hest_id(node_url):
    backup_doc(node_url, backup_dir, id)
    print 'backup @id=' + id
    time.sleep(0.01)

これで、

./node_back.py http://localhost:1978/node/test test

とかやると、ノードに登録されている文書をまとめてバックアップできる。
で、バージョンアップ後に

find -type f test | xargs -n 1 estcall -auth username password http://localhost:1978/node/test

で、バックアップしたファイルをまとめて登録。

だれでも全文書ドラフトを取り出せる仕様

上のエントリのスクリプトを書いて気づいたのだけれど、HyperEstraierのノードサーバって認証なしで登録されている全文書の文書ドラフトをいとも簡単に取得できるのな。うーむ、この仕様はどうだろう。
運用で回避できそうな気もするけど、あとでメーリングリストで聞こうかな。

ノードサーバがSegmentation Faultで落ちる

スクリプトで文書ドラフトをバックアップして、HyperEstraier と QDBM をバージョンアップして、ノードサーバに文書ドラフトを再登録。
で、ノードサーバの検索UIから検索したらノードサーバが Segmentation Fault で落ちるし。しかも、データベースが WRITER モードで開けなくなってやがる。ぐはぁ。
むかついたので、デバッグオプション付きでリビルドして gdb 使って原因を突き止めてからメーリングリストに報告。そしたら日本時間では夜中なのに、数時間後には新バージョンがリリースされた。対応はえぇ。

アンケートシステム

某所のアンケートシステムを学生の某氏がつくることになっているとかいう話を聞いたのだが、正直、人選間違っている気がした。中島研の某氏か中内研の某氏あたりに振っとけばいい話をなんで素人に振りますか。
怖いなぁ、とりあえず「'」とか「">」とかの入力チェックぐらいはしておいて欲しいところ。リクエストパラメータの意図的な書き換えにも対応できるかな。実物見るのが怖い。