読者です 読者をやめる 読者になる 読者になる

kei-s@ブログ苦手

苦手だけど書くときは書きます

家庭 Chatops #家庭を支える技術

このエントリは、家庭を支える技術 Advent Calendar 2015 の6日目です。

シーズン2

昨年につづいて、「家庭を支える技術」アドベントカレンダーを立てました。いろんなかたちの家庭があり、それぞれ違う課題を解決していて、とても楽しいです。あともう少しだけ空いてますので、よろしければご参加ください。

外から家庭のもろもろを操作したい

私達は共働きで、帰宅の時間がほぼ一緒になったりします。そうするとこの季節、帰宅時に部屋が寒くてつらい、という問題があります。
タイマーで起動するにも、帰宅時間は一定ではないですし、無駄につけっぱなしにするのも気が引けます...

そこでまず IRKit を導入して、外からエアコンなどを操作できるようにしました。

エアコンの赤外線受光部が高い位置にあるため、部屋の反対側の壁上部に貼り付けるようにして設置しました。

f:id:kei-s:20151206171938j:plain

貼り付けシールはこちらが便利でした。買っておいて損はないです。

3M コマンド タブ(はがせる両面粘着) S 16枚 CMR2

3M コマンド タブ(はがせる両面粘着) S 16枚 CMR2

IRKit は USB 電源なので、長めの USB ケーブルと小さめの AC アダプタも準備しました。*1

IRKit のセットアップが出来たので、外からエアコンをつけることが可能になりました。

家庭 Chatops

hubot から IRKit を操作できるようにする

私達の家庭では、情報共有に Slack を使っています。Slack に hubot を立て、Slack から IRKit を操作するために ngs/hubot-irkit を導入しました。(下記、妻の発表から抜粋)


最寄り駅についたら Slack に通知する

また、これとは別個に、IFTTT を使って最寄り駅に近づいたら Slack に通知する、というのもやっています。

f:id:kei-s:20151206211133p:plain

これは、IFTTT で "iOS Location" と "Slack" を組み合わせ、最寄り駅を中心とした一定範囲に Enter したら Slack のチャンネルにメッセージを送る、というレシピです。妻と二人とも設定しており、毎度「最寄り駅に着いたよ」という連絡をしなくてよいのでとても便利です。*2

最寄り駅についたらエアコンをつける

今回、上記ふたつを組み合わせて、「最寄り駅についたらエアコンをつける」ができるようにしました。
IFTTT のレシピを新たに作成し、最寄り駅についたら IRKit をキックする URL を叩く、としても実現可能ですが、Chatops の観点から hubot を使い Slack 上で動作を共有できるようにしました。

hitsuji/ifttt-irkit.coffee at master · shiratsuchi/hitsuji

面倒だった点を箇条書きにすると、

  • hubot プラグインの設計の問題で、hubot-irkit プラグインで設定された赤外線情報を、別のプラグインから参照したり実行するのが困難。
    • ほとんどの動作が robot.respond /.../, (msg) -> のように定義されるため、最後の callback だけ動作させるのが厳しい。
  • 幸運なことに hubot-irkit は Webhook を用意してくれているので、上記プラグインから hubot-irkit の Webhook を叩くようにする。
    • フルオープンにならないように、BASIC 認証をかける。
  • IFTTT が Slack に投げる発言を hubot で拾うためには、通常の robot.hear ではなく hubot-slackでbotの発言にも反応させる - 下林明正のブログ のように、SlackBotListener を作成して渡す必要がある。
  • 二人が同時に帰ってきたときに二重起動しないよう、最終起動時刻を記録してブロックするようにする。

というかんじです。

最終的に、

f:id:kei-s:20151206213835p:plain

のように、最寄り駅にたどり着いたらエアコンを起動することができ、家についた頃には部屋が暖かくなっているようになりました。
もし間違って起動していた場合は、Slack で hubot に停止するよう伝えることで止められます。

今後の展望

ホントはエアコンじゃなくて、床暖房をつけたいのですが、床暖房のコントローラには赤外線リモコンがないため、諦めてました。
しかし、最近話題になっている MicroBot Push を見つけて、即 back しました。これを使って床暖房をつけられるか楽しみです(到着予定は4月です...!)。

まとめ

IRKit + Slack + hubot + IFTTT で、最寄り駅に着いたらエアコンを起動できるようになりました。

明日の家庭を支える技術は becyn さんです。

*1:コンセントに直で USB が刺さってほしい。でも USB-C とか新しい規格出て無用になる

*2:範囲を調整すると、ある程度誤爆を防げるとおもいます

定期的に買う必要があるものをアラートする仕組みを作った #家庭を支える技術

このエントリは、家庭を支える技術 Advent Calendar 2014 の一日目です。

「家庭を支える技術 Advent Calendar」とは

エンジニアの友人たちとおしゃべりしているうちに、各ご家庭の生活を豊かにするためにしている技術的な工夫や、これからやりたいアイデアが話題に上がることが多くありました。そんななか、誰が言い出したか『家庭を支える技術』というキーワード*1が出てきていました(もちろん元ネタは WEB+DB PRESS plusシリーズ の「〜を支える技術」です)。
仲間うちだけでも面白い話が出てくるので、いろんな家庭の話を聞いてみたいとおもい、せっかく12月なので「家庭を支える技術 Advent Calendar」として世に問うてみた次第です*2
ありがたいことに公開から数日で全日程が埋まり、「家庭を支える技術」への関心の高まりを感じています。

定期的に買う必要があるものをアラートする仕組みの話

本題です。事前に Adventar に予告した話とは変わってしまいました。

私達の家庭での課題のひとつに、消耗品の入れ替え、買い替えを忘れがち、というものがありました。例えばゴミ箱のニオイとりや防虫剤のような、3ヶ月・半年に一度交換するようなものです。入れ替えすること自体を忘れてしまって、いつの間にか効能が切れてニオイが発生したりするなど、イヤな体験が何度かありました。

この課題に対応するために、まず「買い忘れない」というところから始めることにしました。Amazon からモノが届けば、入れ替え作業を忘れることはなさそう、ということにしました。
解決方法はいくつかあると思いますが、私達の家庭ではこのような技術をつかって解決することにしました。

  • Google Spreadsheet に、消耗品と買い替えサイクルの期間を記録する
  • 別のシートに、消耗品を買ったログを残していく
  • Google App Script を使って、最後に買ってからサイクル期間が過ぎていたらメールを投げる

なぜ Google Spreadsheet かというと、ウチで流行っているからです。実際、「データ投入と編集が簡単」「運用コストがゼロ」「Google App Script で結構いろいろできる」という利点があります。

買い替えサイクルのシート

f:id:kei-s:20141201200354p:plain

こんなかんじです。ASIN カラムと商品名カラムは手入力ではなく、IMPORTXML関数でA列のURLのHTMLをフェッチし xpath で切り出して自動入力にしています。

B2 のセル
=IMPORTXML($A2,"//*[@id='ASIN']/@value")

C2 のセル
=IMPORTXML($A2,"//*[@id='productTitle']")
購入記録のシート

f:id:kei-s:20141201201255p:plain

こちらも同じく、C列、D列はIMPORTXML関数を使って自動入力です。Amazon の商品ページの URL は、商品名が入っていたりと正規化が大変なので、商品ページから ASIN コードを切り出すことで一致をラクにしようという意図です。

最後に買ってからサイクル期間が過ぎていたらメールを投げる Google App Script

Google Spreadsheet のメニューから、「ツール」→「スクリプトエディタ」を選択してエディタが開きます。ここの JavaScript を使ってスクリプトを書くことで、シートのデータを取り出したり加工したりなど、いろんなことができます。
スクリプト自体は https://gist.github.com/kei-s/322aeb83f9284396734a にあります。MailApp.sendEmail メソッドを使えば、自由にメールを投げることができます。
また Google App Script では、いわゆる crontab のような時間によるトリガーを作ることができます。上記のスクリプトを一日一回トリガーすることで、もし買う必要があるものがあればメールを投げるようにしました。

f:id:kei-s:20141201204441p:plain

購入記録を投入する Google Chrome extension

購入記録を簡単に投入するための Google Chrome extension も作りました。

f:id:kei-s:20141201202741p:plain

ソースコードhttps://github.com/shiratsuchi/sorosoro-alert です。Amazon の商品ページで「購入ログに記録する」を押すと、ページの URL をポストします。ポストするのは URL だけで、ASIN や商品タイトルの切り出しは面倒なので先のとおり spreadsheet 側でやっています。

この Spreadsheet はプライベートにしているので、そのままだと API 経由でデータを投入することはできません。
そこでまた Google App Script を頼ります。Google App Script には「Web アプリとして公開する」という機能があります。スクリプトで GET や POST を受け取る処理を書き「Web アプリとして公開する」と、GET/POST 先のエンドポイントが与えられます。

まず、POST を受け取って購入記録シートにデータを追加する、というスクリプトを書いて公開し、Chrome 拡張でオプションから POST 先のエンドポイントを登録できるようにしました。
これで、プライベートなシートにデータを投入することができるようになりました。
Google App Script 側のスクリプト
https://gist.github.com/kei-s/69e65376c37202e103db です。*3

まとめ

Google Spreadsheets を使って、定期的に買うものをアラートする仕組みをつくりました。また Google Chrome で簡単に買ったものを記録する拡張をつくりました。
この仕組み一式を共有したいのですが、Spreadsheet のデータ以外の関数セットやスクリプト一式を簡単に使う方法ってあるのでしょうか...?

明日 12/2 は @negipo さんです。

*1:いましらべたら @darashi さんが初出だった様子

*2:技術評論社さま、いつもお世話になっております。パロディ的なタイトル、ご容赦ください。

*3:https://mashe.hawksey.info/2014/07/google-sheets-as-a-database-insert-with-apps-script-using-postget-methods-with-ajax-example/ を参考にしました。

june29 と mamipeko の結婚式で、Google Chrome 拡張をプレゼントをした

@june29 さんと @mamipeko ちゃんの結婚式が、いい夫婦の日である2014年11月22日の執り行われました。披露宴にて私達夫婦で友人代表スピーチをする機会をいただきました。そこで、なにか二人にプレゼントできるといいなあと考えて、Google Chrome 拡張を作ってプレゼントしました。

あの日のふたり

「あの日のふたり」という名前の拡張をつくりました。日常生活の中で、ふといつかの二人での出来事を思い出すような、そんなプレゼントです。

「あの日のふたり」を入れて Google でキーワード検索をすると、二人の Twitter での発言からそのキーワードを含んだ tweet をポップアップで表示する、というものです。


あの日のふたり - YouTube

拡張本体とソースは https://github.com/shiratsuchi/anohi にあります*1
披露宴でのスピーチで動画を見せてプレゼントしたら、スピーチ後に @darashi@hmsk がそれぞれ、「バックエンドどうしてるんですか?」と質問してきたのが面白かったです。実際のところバックエンドシステムは無く、二人の Tweet*2Google Spreadsheet に記録したものを準備し、拡張の起動時に TSV フォーマットで読み込んでメモリ上に展開しています。リアルタイムにデータを反映するのはできないですが、バックエンドなしのお手軽運用にしました。
ちなみに、二人へのプレゼントなので、元データの取得先はハードコードしています。

素敵な結婚式に参加できて嬉しかったです!
@june29 @mamipeko いつまでもお幸せに!

*1:ガガッと書いたので console.log とか残りっぱなしだ...

*2:二人がお付き合いをはじめた2013年6月23日から

30歳のエンジニアのポエム

まだ前職でお仕事をしていた27歳くらいの時、いつも優しげな、札幌にいるあの先輩エンジニアの方から、こういう質問をされた。


「3年後、30歳のとき、どういう自分になっていたい?」


こう答えた。
「正直、全く想像できてないです。」


心からそう思っていた。
答えが自分の中になにもなかった。
自分がやりたいことはなんなのか、何を大事に思っているのか、言葉にできなかった。


「じゃあ、こうなっていたくない、という姿はある?」
「それならあります。」


「じゃあ、そうならないようにしていれば、悪いことにはならないよ」


悪いことにはならない。



先月30歳になって、悪いことにはなってない。
それどころか、かなり楽しくやれているとおもう。
まだやっぱり、どうなりたいかは見えてないけど。

ありがとうございます。



最近こんな話を何回かして、冒頭の質問を投げかける機会も増えた。
ちょっと節目っぽいかんじになって、記録しておくのもいいかと思って書いた。
おじさんからは以上です。

濱崎、会社やめるってよ

参照: 濱崎、会社やめるってよ - はまさき

「桐島、部活やめるってよ」は読んでないから上手いこと言うのできなさそう。「ゴドーを待ちながら」と同じ構成だっていうのは知ってる。

最初に会ったのはいつなんだっけな。あまり覚えてないけど、なにかしらイベントかなにかで @june29 さん経由で紹介されたんだと思う。そんで、なにかしらで飲みにいったり、RubyKaigi スタッフを一緒にやったり、@june29 の家で飲んだり、#oblove の講演を聴いたり、ゴールデンボンバーの DVD を見たりした。
自分の芯を持ってて、かっこいいなあと素直におもう。あと、たぶん自分に嘘つけないひとなんだろうなあって感じがする。

会社をやめるというのは、やっぱり人生の大きな節目というか転機というか勇気のいることで、勇気をもって新しい環境に飛び出す決断をするのは、ほんとうに素晴らしい*1。自分が前の会社をやめるとき、何人かから「Congratulations. おめでとう」と言ってもらってとてもよかったので、誰かが会社をやめたり新しい環境に行くときは「おつかれさまでした、おめでとう」と言うことにした。

おつかれさまでした、おめでとう。

誰かのことをこんなふうに適当だけど書き散らかすことってなかなかなくて、キッカケと流れっていうのは面白いものだなあとおもう。

桐島もゴドーもまたどっかで会えるといい。

*1:傍から見ている人が、「どうして?」というのもしょうがないのだけれど。心配するし

WEB+DB PRESS #wdpress で Ruby の連載をしていました

WEB+DB PRESS で Ruby の連載をしています。 で書いたとおり、WEB+DB PRESS@june29Ruby の連載をしていました。
最終回の載っている Vol.68 が発売されたので、最終回だし、けっこうがんばったのでブログにして宣伝します。

WEB+DB PRESS Vol.68

WEB+DB PRESS Vol.68

これまでの連載記事は

  1. Vol.63 Ruby 1.9組み込みライブラリをとことん活用! (主に @june29 が執筆)
  2. Vol.64 Railsでサクサク作るTwitterFacebookアプリケーション (主にわたくしが執筆)
  3. Vol.65 Rails 3.1の魅力に迫る!……“Web開発の巨人”に愛された新機能の強力な連携 (主に @june29 が執筆)
  4. Vol.66 Bundlerを使いこなす!……ライブラリの追加・更新・使い分けでもう迷わない (主にわたくしが執筆)
  5. Vol.67 厳選! 用途別Ruby/Railsライブラリ・ツール……機能実装,テスト,開発効率アップ,運用 (分担して執筆)

各回ごとに順番に担当していましたが、第5回の執筆開始あたりからふたりとも忙しくなり、第5回は分担して担当しました*1。連載のお話をいただいたころから、「最終回はなんか独自のものをやりたいっすなー」と話していたものの忙しさでちょっとやばいかなとなっていましたが、せっかくの機会だからと第5回の原稿を提出した直後から最終回に着手したのでした。
最終回にあたって何を書こうかなと考えてみて、「Ruby にまつわる人たちのはなし」を書きたいなとおもいました。

Ruby にまつわる「人たち」のはなし

ここからちょっと回想モード。今回の Ruby 連載のお話をいただいたきっかけは、WEB+DB PRESS 発行元であるところの技術評論社のWeb サイトgihyo.jp での、RubyKaigi 2009, 2010 当日レポートを担当したことでした。RubyKaigi2009 の当日レポートでは、それまでどんな媒体にも執筆したことがなく RubyKaigi スタッフ自体も初めてで、@june29 と試行錯誤しながらどうにかこなしました。いま振り返るとどうやって収めたかわからん、再現できない。RubyKaigi2010 の当日レポートは前年からの学びを踏まえ、@sugamasao@takkanm@ukstudio の三人に参加してもらいチームの体制にしました。るびま直前特集号を出すこともできました。その甲斐あってか RubyKaigi2011 ではめでたくレポート班をクビになり、作ってきた「レポート班」を手渡すことができました。

レポート班のだいじな準備のひとつに「予習」があります。当日はトークを聞きながらレポートを書くわけですが、事前にどんな内容のトークなのか発表概要(CFPにきた応募)を読んでおいたりスピーカーがどんな人なのかを知っておかないと、話の要点がつかめずメモを取るのさえ大変になります(というのを 2009 で学んだ)。特に海外からのスピーカーの場合は名前を見ただけでは誰だかわからなくても、その人が作ったツールを知っていたり、例えば海外のカンファレンスを主催しているのを知っていたりするだけで、理解ががぜん進むし、なによりトーク前のワクワク感が全然違います。たのしい。

Ruby にまつわる人たちを知ることで、Ruby に触れている時間がもっと楽しくなる。その実感から、Ruby にまつわる「人たち」のことを書きたいとおもったのでした。

データで見るRubyGemsの世界

じゃあ Ruby 界の有名人を紹介する記事を書くのがいいかというと、そのままでは自信をもって出せる記事にできないような気がしました。もっと詳しい人はいるし(RubyKaigi のCFP選考中の @takahashim さんとか @kakutani さんとかちょうたのしそうなんですよ)、そのままでは自分たちだからこそできるものにならなそうな。じゃあどうしようか。大学の研究室のときからやってた「データをクローリングして解析しておもしろい結果をだす」というのをやれば、データから客観的に Ruby にまつわるおもしろいものを出せるんじゃないか。データはなにがあるだろ。RubyGems.org って API 公開してるな。作者とか依存関係とか取れる。ダウンロードランキングとか作者のランキングは簡単に出せるし、依存関係のグラフとかだれも見たことないんじゃないの。いけんじゃね。いけそう。よし。

有名人紹介でなく RubyGems.org のデータ解析にしたことで、有名人だけでなく「Ruby をふつうに使っている人たち」も記事のなかに入り込ませることができました。例えば、多くの gem に依存される gem がどうして多く依存されるかというと、出来がよいのはもちろんのこと、たくさんの人が使っているから、という理由もあるとおもいます。もっと例えると、Ruby on Rails を使うのは、Rails がよくできているから(DHH がすごいから)というのもあるかもしれませんが、みんなが使っているから、という理由も無視できないはずです。gem を「作っている人たち」だけでなく「使っている人たち」の存在によって「RubyGems の世界」が形作られていることを示す。それもまた Ruby にまつわる「人たち」の一つの語り口にできそうだなとおもいました。

試行のサイクルを早くまわす

ここでは記事に載らない、記事を書くプロセス、「データを取ってきてなにかおもしろい結果をだす」という問題にどう立ち向かったかというお話を。
締め切りが決まったおしごと*2で、「なにかおもしろい結果」を出すというのは不確実極まりないものです。やってみないとわからない。ではどうやって「やってみないとわからない」をわかるようにするのかというと、はやくやる、というのが答えじゃないかと思います。「試行のサイクルを早くまわす」。どんな結果になるかわからないものは結果を見るまでの時間を短くして、もしイマイチな結果の場合、どうしてイマイチな結果になったのかを考えて次の手を出すための残り時間を確保する。次の手の精度をあげるためにも、イマイチな結果でも結果をだしてそこから学ぶ。リーンなんちゃらとかでもよく聴くはなしですね。そこにプログラミングが入る場合は、次の手を試す自分のためにも、できるだけ丁寧なコードを書きたいものです*3

早くやるために、丁寧に

今回の記事のために書いたコード(クローリング、データ解析、グラフ描画)は wdpress11rb/rubygems-world-analysis で公開してます。試行錯誤のなかでツギハギしてきたコードなので、正直キレイな設計にはなっていません。どんなふうに進めたのかや、細かい Tips なんかを見てもらえればとおもいます。
今回のコードでもいくつか Tips 的なものがあって。
ひとつは「クローリングデータは生のままとっておけ」というもの。今回 RubyGems.org の API からクローリングしてきたデータは JSON なのですが、これをパースさえせず一度 SQLite の String 型のカラムに保存しています*4。クローリングの段階では、そのあとどのような解析をするか決めていませんし、決めないほうが得策です。やろうとしていた解析だけでいい結果がでるとは限らず、最初の想定にない解析手法を選択しなければいけないかもしれません。その際ヘタに構造化してしまったおかげで解析がやりずらくなってしまうことも。必要なデータをとり逃しててもう一度クローリング、というのが一番避けるべき状況です(過去に何度もやりました)。今回は、クローリングしたデータをそのまま格納するのに Sequel を、そこから依存関係などを構造化して解析しやすいようにしたものは ActiveRecord を使っています(wdpress11rb/rubygems-world-analysis の lib/ 以下にあります)。
もうひとつは、「解析結果の出力手順はできるだけ短くする」。解析手法の試行錯誤はいい結果を出すために最も重要で時間のかかる作業ですが、試行錯誤の果てにようやく出した解析結果のグラフや図の出力は、試行錯誤のせいでえらくめんどくさい手順になってしまうことがあります。そして、めんどくさい手順のままにして放置されちゃうことが多い、なぜならいい結果がでて終わりが見えてくるから(これも過去の経験から)。本当はそこで終わりじゃなくて、結果を見やすく整理する作業が残っているものです。ここで解析結果の出力方法をリファクタリングしておくと、その後の作業がとてもラクになります。クソ細かいはなしなのですが、今回初めて使ってえらく便利だったのが rdp/ruby_gnuplotGnuplot を使ってグラフを eps に出力する部分は共通的に gnuplot.rb - wdpress11rb/rubygems-world-analysis に定義しておいて、各種解析結果の出力は generate_author_rank_graph.rb - wdpress11rb/rubygems-world-analysis のように、タイトルやラベルだけ変えられるようにしました。

見えなかったのものが見える瞬間は、たのしい

今回ひさしぶりに「データを取ってきてなにかおもしろい結果をだす」のをやったのですが、やっぱり、おもしろい結果が見えてきた瞬間はたのしいですね。記事にもありますが(詳しくは記事を読んでいただきたいのですが!!!)、「RubyGems.org での gem の増え方の推移」は、自分の予想を裏切られて、なおかつ考察の末、潜んでいた原因が明らかになって、そういうものこそ記事にまとめていてやりがいを感じました。gem の増え方の推移を調べてたのは ガローア会議02 で日光で温泉合宿中だったんだけど、温泉入って眠い頭で考えてて原因に辿りついた瞬間、


やっぱりこういうのやるのはたのしいなー、と再確認しました。

グダグダ書いてたら

ここまで書いてたら*5@june29 さんが WEB+DB PRESSの連載が無事におわりました - 準二級.jp を publish してて、連載を受けた経緯なんかを書いてて、だいぶグッとくるので読んでみてください。

謝辞

編集担当の池田さん。
池田さんが「どうすれば読者に伝わるか、読者はなにを求めているか」と投げかけてくれたことで、ただの文章から「記事」にできたのだとおもいます。お打ち合わせにて、池田さん自身が興味を持つポイントと読者が知りたいだろうポイントをまとめて記事の方向性を作っていく力に、安心してのっからせてもらいました。@june29 さんも書いてたけど、「執筆: 〇〇」だけでなく「編集: 〇〇」も、一緒に作ってきたチームとして並べたいです。

@june29 さん。
無事に終わってよかったですね。最終回の「やってやったぜ感」は、だいぶよかったっすね。いやはやおつかれさまでした。ありがとう。

連載を読んでいただき、声をかけてくださったみなさま。
イベントなどで会った際に「読んだよー」「次回はなに書くの?」と言ってもらったり、Twitter などで「記事のコレ役に立った!」「よくまとまってる」などと反響をいただけて、とても嬉しかったです。

なにより、記事を読んでいただいたみなさま。
あなたが Ruby やプログラミングに触れる時間がすこしでもワクワクするものになっていれば、これ以上うれしいことはありません。ありがとうございました。

次号からの Ruby 連載もたのしみにしています!

*1:分担しやすいようなテーマにした

*2:締め切りの決まってないおしごとほど気楽で難しいものはないとおもいます

*3:研究室時代はこのあたり意識と実力が伴っていなかったなあとふりかえる。まあ今回も完璧にキレイにはできてないですが

*4:MongoDB のほうが...という声への返信としては、データ量がそこまで多くないと予想できたことと、SQLite の DB ファイルをそのまま git でやりとりするポータビリティのメリットをとりました

*5:途中下書き消えて3回くらい書きなおした

こんなブログシステムがほしい

多くは求めてません。

  • :w で下書き保存。ていうか vim キーバインド
  • リアルタイムプレビュー
  • アマゾンの商品リンクははてなの detail っぽいかんじ
  • 画像保存機能とかいらない。skitch とか dropbox/public_dir とか代替はたくさんある
  • タグはまああったらいいかもしれないですね

手元の vim で :w したらブラウザでプレビューする仕組み作ればいいのかも。でも、いまのところブログ書くときはブラウザの textarea に書くのがいい。コンソールでエディタ立ちあげてるとコード書いてる印象になってしまう。
Octpress きょうみあるけど消極的にどうにかしたい。