| @技術/プログラミング

Jekyllを使いだしてから気がつくと一年経ってました。いろいろ便利に使えており気に入っております。

PygmentでコードをシンタックスハイライトしたりLSIで関連記事表示したりと結構手を入れてはいたんだけど、いわゆる世間の一般のブログにあるようなカテゴリ一覧表示機能と、カテゴリごとの記事アーカイブ機能がなくて、それを若干不便に思っておりました。

ググってみたところ、プログラマー向けなブログツールなだけあっていろんな方法が出てきました。以下そのまとめ。

カテゴリ一覧

JekyllのLiquid (テンプレート言語) には {{ "{{ sites.categories " }}}} みたいタグがあるんだけど、こいつが意図したとおりに動かない。普通のRuby使いの感覚からすると site.categories ってカテゴリを沢山持った配列になってそうな気がするんだけどこれが違う。

<ul>
{{ "{{ for category in sites.categories " }}}}
  <li>{{ "{{ category.name " }}}}</li>
{{ "{{ endfor " }}}}
</ul>

↑みたいな感じのコード書くと何も表示されない。 site.categoires はHashで、{ "カテゴリ名" => カテゴリ内の記事一覧 } みたいな構造になってる。LiquidでHashのキーを取りだす方法が分からず、どうにもこうにもいかなかったので他の人が作っているプラグインを利用することにした。

↑のファイルを JEKYLL_ROOT/_plugins にコピーする。(_plugins というディレクトリがなければ作る)。そんでテンプレートを変更する。↑のやつを↓みたいにする。

<ul>
{{ "{{ for category in sites.iterable.categories " }}}}
  <li>{{ "{{ category.name " }}}}</li>
{{ "{{ endfor " }}}}
</ul>

2行目のところが変更点です。これでカテゴリ一覧表示ができるようになる。

カテゴリごとの記事一覧

カテゴリごとの記事一覧を表示する方法だけど、こういうのを発見した。

ここの generate_categories.rb を使えばカテゴリ内の記事一覧を作成できる。こんな感じ。

これもさっきのと同じように、JEKYLL_ROOT/_plugins にファイルをコピーする。そんでLiquidテンプレートを書き換えるんだけど詳細はプラグイン内の記事をご確認くだしあ。

| @労働

こういう会社で働けたら幸せだろうなと思います。

理想の会社

  1. Gitでソースコード管理している。
  2. 会社のGithubアカウントがある。
  3. 外部に公開されている技術ブログがある。
  4. IDEよりVimやEmacsを使うことが奨励されている。
  5. 社員が勉強会に参加することを奨励している。
  6. オープンソースコミュニティに貢献している。
  7. 音楽を聞きながら仕事できる。
  8. Rubyで開発できる。
  9. 会議が短い。
  10. アジャイル開発を実践している。
  11. テストコードがある。
  12. エンジニアは全員ノートパソコンで開発して、好きかってに席を替わってペアプログラミングとかやってる。
  13. MacとLinuxしかない。
  14. 優秀なデザイナーがいる。
  15. でかい本屋が近くにある。
  16. プログラムを書くことが好きな人たちが集まっている。
  17. SEという肩書きの人がいない。
  18. 大所帯でない。
  19. 金曜の夜はみんなはやく帰る。
  20. イスに金をかけている。
  21. 社員がfoursquareで会社のMayorの座を競い合っている。

| @技術/プログラミング

ポータルシットをLokkaで置き換えました。

Lokkaでリプレースしようと決めたのが2月8日なので(たぶんLokka - portal shit!)、5ヶ月弱要したことになります。

今回こだわったのが、

  1. P_BLOGから記事本文はもちろん、コメントも移行する
  2. 移行スクリプトはテスト駆動で開発する
  3. Markdownで本文を書けるようにする
  4. 旧記事へのアクセスをリダイレクトする (未実装)

の4点。

TDDデビュー

移行スクリプトについては初めてテストファーストで開発してみましたが、なかなか勉強になりました。やたら長いメソッドを書かないように気を付けたり。長いメソッドはテストしにくいですね。あと途中でLokkaの仕様不足が露呈してコードを書き直したりしたんですが、そういうときもきちんとテストを書いているおかげで、一ヶ所変更したらプログラム全体がぶっ壊れるというような事態を避けることができ、大変良かったです。

herokuデビュー

最初はさくらVPSで運用しようかと思っていましたが、herokuで簡単に使えるのがLokkaの売りなわけですし、heroku使ったことがないのは若干まずいだろと思っていたのでとりあえずherokuで運用することにしました。楽でいいです。失業者が出るレベル。

ただ旧記事(/article.php?id=***)へのアクセスをリダイレクトするつもりで移行スクリプト書いたりしてたんですが、herokuで運用する限りにおいては nginx.conf を編集したりできないのでリダイレクトは実現できなそう。Sinatraで拡張子phpへのアクセスをリダイレクトするという変態的な処理はできないのでしょうか。クエリストリングの扱いがネックになりそう。場合によっちゃ結局さくらVPSで運用するかもです。

加えてherokuは画像のアップロードができないので、画像のアップロード先は別に用意する必要があります。プラグイン使ってAWSをストレージとして利用するとか。JAWS九州の勉強会に二回ほど参加して、Amazonのエバンジェリスト玉川さんの話とか聞いてAWS使わないと来年の今頃は失業してそうな空気を感じ取ったのでそのAWSにも手を出してみたいですね。

まとめ

Lokka、プラグインが簡単に作れるので本体のロジックにほとんど変更を加えることなくいろいろできて楽しいです。Sinatraベースなので困ったことがあったらSinatraのドキュメントを見ると大体なんとかなりそうな感じがします。リストカット感覚でブログ作ったり消してる人におすすめです。

| @Mac/iPhone

Google Chromeの拡張機能に、Chrome Keyconfig ってのがあります。これはMinibuffer + LDRizeとまではいかないまでも似たような機能を提供してくれるエクステンションで便利に使っていたんですけど、最近、一旦Google Chromeを終了すると前回使用時に変更した拡張機能設定項目の内容が読み込まれないという不具合が発生するようになり、非常に不便でした。

Chrome KeyconfigとTberarelooの組み合わせで、Firefox + Greasemonkey + Minibuffer + LDRize + Reblog Command とほぼ同様の快適さでTumblrが閲覧できるようになるわけでして(Google ChromeでFirefoxのようなReblogしまくれる環境を構築する - Syoichi's Tumblr)、毎回Tumblr閲覧時にChrome Keyconfigの設定画面を開いて設定を変更するのは面倒くさいこと極まりありませんでした。

ちょっと調べてみたところ、以下のような原因でChrome Keyconfigの設定項目の変更内容が反映されないようです。すなわち、Chrome Keyconfigの設定項目の内容を保存しているDBの "ItemTable" というテーブルに "Config" という key を持つレコードと "Keyconfig" という key を持つレコードがあって、設定項目の変更内容は "Keyconfig" に保存されるけどChrome KeyconfigはGoogle Chromeを一旦終了して再起動すると "Config" の方を読みに行っちゃう、ということらしいです。

したがってChrome Keyconfigの設定内容を保存しているSQLite3のDBを直接開いて編集してやればよいわけですね。"Config" という key を持つレコードの value を "Keyconfig" の値で上書きしてやればよい。上記リンク先ではWindows環境で、SQLiteを編集するソフトを使って値を変更する方法が紹介されていますが、Macでは以下のコマンドで行けます。

cd ~/Library/Application Support/Google/Chrome/Default/Local Storage  
sqlite3 chrome-extension_okneonigbfnolfkmfgjmaeniipdjkgkl_0.localstorage "update ItemTable set value = (select value from ItemTable where key = 'Config') where key = 'Keyconfig';"
{: .console }

よろしければお試し下さい。

| @WWW

IMG_0109

先々週になるけど、福岡に新しくできた アラタナ研究所 のレセプションに行った。研究所の所長であらせられる @rytich さんに招待してもらった。

なんと同研究所には熊本にいた頃からお会いしてみたいと思っていた @shunsuk さんもお勤めであり、お目にかかってご挨拶することができた。

@shunsuk さんのブログ「 で写真が見られるけど、パーティションが全面ホワイトボードのオフィスはとてもかっちょよい。ホワイトボードに↑の落書きを施した後、他の人が書いたのを見てたらウェブアプリケーションのスキーマを書いたとおぼしき走り書きが目にとまった。前の職場で一人でプログラム書いてた頃が無性に懐かしくなった。ああでもない、こうでもないと考えながら、作っては壊し、作っては壊しを繰り返してプログラムを書いていくのがとても楽しかったことを思い出した。

レセプションの最後に若くてイケメンな株式会社アラタナの濱渦社長が「九州から面白いサービスを作っていきましょう」とスピーチしていたけど、すごく楽しそうで羨ましかったし、自分もなんかしなきゃと焦ってしまった。

何はともあれアラタナ研究所オープンおめでとうございます。

| @技術/プログラミング

ポータルシットをLokkaに置き換えたくていろいろやってる。ポータルシットの過去記事をYAMLでエクスポートし、それをLokkaのDBに取り込む作業をやってる。TDD BootCampに参加したので、テストファーストしながらの作業。RSpecでテストコードを書き、ログが正しくインポートできることを確認する。テスト終了時 after(:all) フックで、取り込んだログを削除してる。コードはこんな感じ。ちなみにLokkaはDataMapperをORMに採用してるので以下はDataMapperでの話。

after(:all) do
  Category.all.destroy
  Entry.all.destroy
end

しかしこれでは AUTO INCREMENT の値がリセットされず、テストを繰り返す度に AUTO INCREMENT の値が増えていってうざかった。

DataMapperの機能で AUTO INCREMENT 値をリセットするのってないのかなと5秒くらい探してみたけど見つからなかったので、SQLを直接実行する方法を採用した。

ちなみにRDBMSに採用してるのはSQLite3。SQLiteでは UPDTE sqlite_sequence SET seq=0 WHERE name='テーブル名'; みたいなコードで AUTO INCREMENT 値を任意の値に設定できるみたい。

最終的な after(:all) フックはこんな感じ。

  after(:all) do
    Category.all.destroy
    Entry.all.destroy
    Entry.repository.adapter.execute('update sqlite_sequence set seq=0 where name="entries";')
  end

テスト実行後にはすべてのデータがデータベースから削除されて、AUTO INCREMENT の値もリセットされる。人畜無害なテストコード万歳。

| @技術/プログラミング

NECの安サーバーを買ってサーバーを作ってるんですけど、SSHでエラーが出て困ってます。OSはUbuntu Server 10.04.1 LTS。

まずSSHのおさらいを。クライアント側で

$ mkdir -p .ssh
$ ssh-keygen -t rsa (以下略)

したのち、サーバー側の /etc/ssh/sshd_configPasswordAuthenticationon にし、パスワードでSSH接続できるようにして

$ scp id_rsa.pub username@hoge.com:.ssh/authorized_keys

するか、あるいはUSBフラッシュメモリで鍵をサーバーに移す。その後サーバー側で .ssh/.ssh/authorized_keys のパーミッションをそれぞれ700と600に変えてあげるわけですよね。

いっぺんクライアント側で id_rsa.pub を作ってたらそれ以降は単純にこれを接続先のサーバーにコピーしてあげればおk。ここまで合ってますかね?

前から使ってる職場内だけで使うサーバーにも同じUbuntu Serverを入れてるんですけど、こっちでは全くトラブルがない。それなのに新しいサーバーでは

Permission denied (publickey).

というエラーが頻繁にお出になるのですよ。

しかしこのエラー、常に出る訳じゃないんですね。サーバーを直接操作して

$ sudo /etc/init.d/ssh restart

してあげると消える訳ですね。そんでしばらくクライアントからSSHで接続したり切断したりを繰り返していると、あるとき突然、

Permission denied (publickey).

となるわけです。まじでストレスフル。つか、このサーバーは公開用に使うものなので、こんな感じでSSHが不安定だとかまじで困るんですけど。

前述の PasswordAuthenticationon にしとけば、公開鍵認証に失敗した後もパスワードで認証することができるんですが、パスワード認証はなんだか怖いので使いたくないのですよね。どいうしたものか。

ググったらSSHのプロトコルを1と2併用にしたら解決するという情報が出てきたのですけど、これやったら "Disabling protocol version 1. Could not load host key" というエラー?が出てしまったので多分僕の環境では意味なし。「RSAキーやめてDSAにしたらエラーでなくなった」(ぷらぷらブログ | OpenSSH を導入。接続に四苦八苦!)という情報もあるけど面倒くさいのでまだ試していません。