log
基本的にXML-RPCから追加できるすべてのオブジェクトは文字列型のnameというフィールドを持っています。addVertexなどのadd*系メソッドは新しいオブジェクトを作成してそのnameを返します。
鈴木さんの指摘で頂点の一覧を取得する方法がないことに気がついたので getObjectsというメソッドをつけてみました。 getObjects("Vertex")で頂点の一覧が名前とパラメータのマッピングとして取得できます。
それを使ってマインドマップっぽいおもちゃを作ってみました。 詳細は帰ってから書きます(マシン不調のため)
なぜか「 Fault: <Fault 0: 'java.lang.Exception: java.lang.reflect.InvocationTargetException'> 」という例外が2回ほど起きたので原因を究明する。
>>> "保存機能" SyntaxError: EOL while scanning single-quoted string >>> "保存機能\" '\x95\xdb\x91\xb6\x8b@\x94\\'
これってどうやって回避するんでしたっけ。
# # sample of poor mind-map system # # connect to GRINEdit import xmlrpclib g = xmlrpclib.Server("http://localhost:8080/RPC2").grinedit def add(new): g.addBoxVertex(new) def chain(frm, new): v2 = g.addBoxVertex(new) frm = unicode(frm, "sjis") for v in g.getObjects("Vertex").values(): if v["label"] == frm: g.addLinearEdge(v["name"], v2) while True: com = raw_input("command>") if com == "a": add(raw_input("add>")) elif com == "c": chain(raw_input("chain-from>"), raw_input("chain-new>")) else: break
使い勝手は非常に悪いですが、addで頂点を追加し、 chainで新しい頂点を作成して既存の頂点から辺を繋ぎます。 g.getObjectsですべての頂点の情報をマッピングとして取得し、labelが指定された物と一致する頂点を探してそのnameを使って辺を張っています。
>>> import pprint
>>> pprint.pprint(g.getObjects("Vertex"))
{'Vertex0': {'bgcolor': [100, 200, 100],
'bound': [53, 18],
'frameColor': [0, 0, 0],
'label': 'GRINEdit',
'letterColor': [0, 0, 0],
'name': 'Vertex0',
'position': [-0.048417770755790512, 1.1813087342104329],
'selfLink': False,
'velocity': [6.9388939039072284e-018, 0.0]},
'Vertex1': {'bgcolor': [100, 200, 100],
'bound': [67, 18],
'frameColor': [0, 0, 0],
'label': u'\u30de\u30a4\u30f3\u30c9\u30de\u30c3\u30d7',
'letterColor': [0, 0, 0],
'name': 'Vertex1',
'position': [0.49675880770306835, 0.07706468191296624],
'selfLink': False,
'velocity': [0.0, 1.3877787807814457e-017]},
(以下略)
ちなみに
frm = unicode(frm, "sjis")
for v in g.getObjects("Vertex").values():
if v["label"] == frm:
の部分は最初1行目を書いていなかったのですが、 そうするとエラーになりました。 Pythonのxmlrpclibで取得した文字列はアスキー文字だけの時はただの文字列、その他の場合はユニコード文字列になるようです。 「'label': 'GRINEdit',」と 「'label': u'\u30de\u30a4\u30f3\u30c9\u30de\u30c3\u30d7',」で、後者だけu'....'というユニコード文字列になっています。 で、3行目「if v["label"] == frm:」の判定で、v["label"]がユニコード文字列の場合にはfrmをユニコード文字列に変換してから比較しようとするのですが、この時frmのエンコーディングが実際にはsjisなのにasciiだと仮定して変換しようとするので「UnicodeDecodeError: 'ascii' codec can't decode byte 0x8d in position 0: ordinal not in range(128)」というエラーが出ます。 それを避けるためにあらかじめエンコーディングを指定して変換してやっているわけです。
日本語環境でのPython (for Python 2.3 or later)の「デフォルトエンコーディング」のところに書いてある方法でデフォルトエンコーディングを変更してやればこの行自体が必要なくなりますが、スクリプトを使う人に「書き換えてください」というのもアレなので…。
こうやって新しいAPIを追加したときに記事に書くと、やっぱりすぐ試してみたい人がいるわけです。次のいつになるかわからないリリースを待ちたくはないでしょう。かといってちょっと機能を追加するたびにリリース作業をするのは大変。リポジトリを公開してそこから最新版を取って貰うのが次善の策。mavenで開発環境が簡単に整えられるようになればいいな。で、subversionで管理して、svkでローカルリポジトリを作り、 普段はそこに対してコミット。 SVKをレポジトリミラーシステムとして使うノウハウ。 開発が一段落付いたらリモートリポジトリと同期を取ってテストをする、と。 mavenでビルドからjarを作るところまで楽に出来るようになったら、それをFTPするところまで自動化してしまうというのも一つの手か…。