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

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