saiten.co

心は今でも千葉在住プログラマー

node-xmlrpcでCDATAを含むデータでエラーが出る

hubotとnode-xmlrpcを使って、 IRC上からconfluenceにページを作成するものを作ってたのだが、 どうも特定のページを元にページを作成しようとするとエラーがでて失敗してしまう。 調べてみると、どうも生成しようとするページ内にCDATAが含まれていると失敗するっぽい。 xmlrpc = require 'xmlrpc' async = require 'async' clientOption = host: "host" path: "/confluence/rpc/xmlrpc" port: 443 space = '~userspace' userName = 'username' password = 'password' client = xmlrpc.createSecureClient clientOption title = "てすと" content = 'hogehoge]]>' async.waterfall [ (callback) -> client.methodCall "confluence2.login", [userName, password], callback (token, callback) -> page = space: space parentId: '0' title: title content: content client.methodCall "confluence2.storePage", [token, page], callback ], (err, page) -> console.log page こんな感じのコードを書いて実行すると、Invalid CDATA textというエラーが出てページが作成できない。 $ coffee confluence.coffee /Users/saiten/local/tmp/confl/node_modules/xmlrpc/node_modules/xmlbuilder/lib/XMLFragment.js:150 throw new Error("Invalid CDATA text: " + value); ^ Error: Invalid CDATA text: hogehoge]]> at XMLFragment.cdata (/Users/saiten/local/tmp/confl/node_modules/xmlrpc/node_modules/xmlbuilder/lib/XMLFragment.js:150:15) at XMLFragment.d (/Users/saiten/local/tmp/confl/node_modules/xmlrpc/node_modules/xmlbuilder/lib/XMLFragment.js:355:19) at appendString (/Users/saiten/local/tmp/confl/node_modules/xmlrpc/lib/serializer.js:172:23) at serializeValue (/Users/saiten/local/tmp/confl/node_modules/xmlrpc/lib/serializer.js:92:11) at /Users/saiten/local/tmp/confl/node_modules/xmlrpc/lib/serializer.js:25:5 at Array.forEach (native) at Object.exports.serializeMethodCall (/Users/saiten/local/tmp/confl/node_modules/xmlrpc/lib/serializer.js:24:10) at Client.methodCall (/Users/saiten/local/tmp/confl/node_modules/xmlrpc/lib/client.js:100:30) at /Users/saiten/local/tmp/confl/test/confluence.coffee:28:5, :38:21 at fn (/Users/saiten/local/tmp/confl/node_modules/async/lib/async.js:579:34) at Object._onImmediate (/Users/saiten/local/tmp/confl/node_modules/async/lib/async.js:495:34) at processImmediate [as _immediateCallback] (timers.js:330:15) どうもCDATAが含まれる文字列なのにCDATAで囲もうとして失敗してるようだったので、 node-xmlrpcのserializer.jsの以下の部分を直したらうまく行った。 ...

June 18, 2013 · 1 分 · saiten

Cookpadの第4回開発コンテスト24に参加したよ

http://info.cookpad.com/24contest4 疲れたー 課題が「年をとった自分が使うサービス」とのことだったのでそのまま年齢に的を絞って、 毎日肉体年齢と脳年齢を測って、その人の推定年齢を記録していくアプリを作ってみました。 年を取ってくると自分はまだ若くありたいという願望というかニーズが強いんじゃないかなーと思っていて、 きっと年をとると、多かれ少なかれ若くあろうとして何かしら努力をしているんじゃないかと。 その中で毎日このアプリで年齢計測をしてもらって、推定年齢が実年齢より高かったりすれば今の生活習慣を見なおしてみたり、 逆に推定年齢が実年齢より低かったりすれば今の習慣を維持しようといった風に、年をとったあとの生活の サポートツールになる…みたいなのを想定しています。 で、どうやって肉体年齢を計測するかというと、iPhoneを使って簡単なバランス感覚のチェックを行うようにしてみました。 iPhoneを水平に持って、片足立ちで15秒間その状態をキープしてもらい、その状態でiPhoneの傾きセンサでブレを検知して、 そのブレの大きさでバランス感覚がどの程度かを判断してます。 脳年齢については某東北大教授よろしく簡単な計算問題を解いてもらって、そのスピードと正答率を使って算出してます。 最後に脳年齢と肉体年齢から推定される年齢を算出して終わり。トップ画面のカレンダーに測定した日に印がつくので、 毎日継続して測定を行い、実年齢より若い推定年齢を維持していこうといった感じのアプリです。 本当は、推定年齢の推移をグラフで表示したり、GameCenterを使ってランキングや実績機能を付けたかったのですが、 時間が無かったので止め。データの管理もCoreDataでやるつもりが、時間ギリギリでNSUserDefaultに 全部突っ込むという悲しい実装になっています。 あと今回作成したアプリのソースはGithubにあげてあります。 sainte/AgeExamination

June 16, 2013 · 1 分 · saiten

iOSアプリ上からユーザ辞書登録を行う方法

友人に質問されたので調査してみました。 かんたん辞書登録というアプリがアプリ上からiOSのユーザ辞書に登録を行えるのですが、公式のリファレンスを探してみたり適当にググってみたりしてみても、そのやり方の情報が見つかりませんでした。 そこでiOSのPrivate frameworkを探してみたところ、どうもそれっぽいメソッドがあったのでサンプルを作ってみました。 UserDictionaryTest やっていることは非常にシンプルで、UITextFieldで入力された文字列を全選択した後に非公開APIである_addShortcut:を叩いているだけです。 [self.textField selectAll:nil]; if([self.textField respondsToSelector:@selector(_addShortcut:)]) { [self.textField performSelector:@selector(_addShortcut:) withObject:nil]; } iOS6からテキストの範囲選択からユーザ辞書に登録する機能が追加されたので、恐らくこのメソッドが使われているんだと思います。実際、iOS5の端末では動作確認できず。 なお、_addShortcut:メソッド自体はUITextField以外に、UITextViewとUIWebViewにも生えていたのでこちらでも同様のやり方で辞書登録が可能だと思います(試してないけど)。 ただし、当然ながら非公開APIなのでこのメソッドを使った場合にAppleの審査に通る保証はありません。

April 25, 2013 · 1 分 · saiten

Octopressを使ってみる

とりあえず作ってみた。思いついたらポチポチ書いていく。

April 18, 2013 · 1 分 · saiten

どや

とりあえず、作成してみた。 続き系もいける。 コードブロック。 - (NSString*)description { NSArray *array = @[@"abc", @"def"]; return [array componentsByJoinString:@"-"]; }

April 17, 2013 · 1 分 · saiten