Pepperでファイル保存したり取り出したり

Pepperに何か情報を保存したり、取り出したりする際には[ALMemory](http://qiita.com/Atelier-Akihabara/items/4162192129f366da1240#almemory%E3%82%92%E4%BB%8B%E3%81%97%E3%81%9F%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E5%80%A4%E3%81%AE%E5%8F%96%E5%BE%97)を利用するのが王道なわけですが、ちょっとサイズ大き目のテキストとかをアプリケーションで保存して開発用PCで取り出そうとか考えるとファイルのほうが都合よかったりする場面もあります。

そんな際の処理として、テキストファイルを書き出すボックスを作ってみて、Pepperからローカル環境にそのファイルを取り出すということをお試し的にやってみたのでメモ。

#テキストファイルの書き出しボックス

ボックスは https://github.com/yacchin1205/pepper-web-boxes の`web-boxes`ディレクトリにあります。

cloneするなりDownload ZIPするなりして、[ボックスライブラリの読み込み](http://qiita.com/Atelier-Akihabara/items/db907ed319b8af0984db#%E3%83%9C%E3%83%83%E3%82%AF%E3%82%B9%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%81%AE%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%81%BF)の手順でボックスライブラリを読み込むと使えるようになります。

作ったボックスはボックスライブラリの `IO` フォルダにあり、以下のような感じ。ボックスのドキュメント生成ツール的なものはどこかにないものか・・・


##IO > Write Textボックス

ファイルにテキストを書き出します。

![write-text-box.png](https://qiita-image-store.s3.amazonaws.com/0/28770/e55e9aef-b1ce-3a3b-beb2-9317c30073b4.png)

###onStart入力

書き出すテキストを入力します。
この入力が発火すると、後述のFile pathパラメータで指示されたファイルに入力された文字列を書き出します。

###onStopped出力

書き出し成功時に出力します。

###onFailure出力

書き出し失敗時に、エラーの内容を示す文字列を出力します。


###File pathパラメータ

読み込むテキストファイルのパスを指定します。ビヘイビア実行中のカレントディレクトリを基準に作成されます。

###Encodingパラメータ

読み込むテキストファイルの文字エンコードを指定します。デフォルトは `utf8` です。どのような値を指定できるのかは http://docs.python.jp/2.7/library/codecs.html を参考にしてください。


##ハマった: Pythonボックスでのunicodeの扱い

このWrite Textボックスではないのだけど、一緒に作っていたRead Textボックスの以下のコードでUnicodeの罠にハマった。

```py
with codecs.open(self.getParameter("File path"), "r", self.getParameter("Encoding")) as f:
    text = f.read()
self.onStopped(text.encode("utf8"))
```

onStoppedのタイプには`文字列`を指定しているのだけど、`read()`で得られたunicode型の文字列をそのまま引数として与えると、次の入力には `None` が渡されてしまうよう。
いくつかテストコード書いてみたけど、どうもChoregrapheのドキュメントで String というと、Pythonのstr型しか考慮しておらず、unicode型は処理できていないような感じが。とりあえず `encode("utf8")` でバイト配列化して与えることで回避しているけど、このChoregrapheの挙動はPythonの文字列の考え方と合致しておらず、混乱を招きそうという点であまりイケていない感じがする。


日本人的にはこういうのは明確にしておいたほうがいい感じがするので、Aldebaran Communityで聞いてみた([String in Choregraphe's python box](https://community.aldebaran.com/en/forum/string-choregraphes-python-box-2651))けど、今はunicode型はサポートしてないよという回答・・・ううむ。

##テスト

とりあえず簡単なテストをリポジトリの `tests/test-io-text/` で記述している。たとえば、以下のようにRead Textボックスで得られた内容が予期した内容になっているかといったレベルでテスト。たとえばRead Textのテストはこんな感じ。

![read-text-test.png](https://qiita-image-store.s3.amazonaws.com/0/28770/7a5ca982-9f1c-9427-3a10-d9cfda7d839c.png)

考え方は[Pepperボックスライブラリのテスト考](http://qiita.com/yacchin1205/items/a2d26ce8f60e8f66e32c)あたりを、参考まで。


#ファイルのローカル環境への取り出し

これらのボックスで保存したファイルをどう取り出すかについていくつか。

##Choregrapheを使う

Pepperのファイルシステムに対しては、Choregrapheでファイルをアップロード、ダウンロードすることができる。
[上級向けメニューにファイルの転送](http://qiita.com/tonosamart/items/fe3948a45ccc97ddbbab#choregraphe%E3%81%A7%E3%81%A4%E3%81%AA%E3%81%84%E3%81%A7%E3%81%BF%E3%82%8B%EF%BC%92)という機能があるのでそれを使うのが王道。

##HTTPを使ってPepperからファイルダウンロード

自動化とか考えると、Choregrapheがない環境でもファイルを取り出したくなったりする。ドキュメントの NAOqi Developer guide > Programming > Connecting Choregraphe / your robot > Connection Management とか見ると、FTPが動いていることは前提として考えてよさそうなのだけど、あえてHTTPを使ってみようとか思って試してみた。

プロジェクト内に[htmlというディレクトリを作るとタブレットから見える](http://qiita.com/Atelier-Akihabara/items/716e88b306db12751c9b#%E7%B0%A1%E5%8D%98%E3%81%AAhtml%E3%82%92%E3%82%BF%E3%83%96%E3%83%AC%E3%83%83%E3%83%88%E3%81%AB%E8%A1%A8%E7%A4%BA)ようになるのだけど、この状態で `http://(Pepperの名前.local.もしくはIPアドレス)/apps/.lastUploadedChoregrapheBehavior/` とかするとこのhtmlディレクトリの内容が見える。たぶん、Webサーバとかでホームディレクトリに `public_html` ディレクトリを置くのと同じ考え方なんだと思われる。

そんなわけで、`html`ディレクトリに、ダウンロード可能にしたいファイルを生成してあげればいいのではないか？と思って作ったのが、リポジトリの `samples/dump-info` プロジェクト。ここでは、ALMemoryの内容すべてとPreferencesの内容すべてをダンプしてテキストファイルに保存、外部PCからダウンロードみたいなことを実装している。

![dump-info-flow.png](https://qiita-image-store.s3.amazonaws.com/0/28770/4eb2aa65-2e47-6fd9-5b1d-60b6497446cb.png)

ポイントは以下の2点。

1. Write Textボックスに与えるFile pathパラメータを独自のGet HTML Fileボックスの出力値で設定している(これも `web-boxes` に置いてある)。Get HTML Fileボックスでは、自身のアプリケーション内のhtmlディレクトリの絶対パスに基づき、出力先ファイルパスを生成している。
2. html/index.htmlでは、Get HTML Fileボックスに指定したファイルへのリンクを張っている。

このアプリケーションを実行後、`http://PepperのIP/apps/.lastUploadedChoregrapheBehavior/` のようなURLを、Pepperと同じLANにつながっているPCなどで開く。するとプロジェクトのindex.htmlをPCから確認することができる。ここで、ファイルへのリンク(2.)をクリックするとWrite Textボックスで書き出されたファイル(1.)をダウンロードすることができる。

こんな感じで、プロジェクトで何かファイルを作ってPCから引っ張り出したければ、プロジェクトのhtmlディレクトリ内にファイルを作ればいいんでは、という話。しばらくこれで使ってみよう・・・