2012年のアクセスランキングベスト10

「倖せの迷う森」内で、2012年の1年間に最も読まれたエントリー10個をまとめてみました。
全体的に Spring のエントリーが多くランクインしていますが、普遍的な Tips もいくつかあります。やはり、他のサイトで扱っていないような細かいネタやマイナーなネタが多いですね。

第1位 1637pt iText で大量の PDF をマージする

iText の情報が少ないためでしょうか、このエントリーが多くのアクセスを集めました。記事の核心は partial mode の存在とそれを有効にする方法です。

第2位 1450pt 配列を分割する(Generics版)

大きな配列を適当なサイズで分割して List に並べていくだけの Tips です。意外と需要があるのか、記事が公開された 2009 年以降、安定したアクセスを保っています。

第3位 1292pt SpringFramework のアノテーションで List や Map に外部から値を注入する

Spring ネタです。はてブ的にはまったく注目されていないのですが、他のサイトではあまり扱っていない情報のためかアクセスが多いようです。*1

第4位 1170pt Spring MVC 3 のアノテーションスタイルで、複数の Submit ボタンがあるフォームに対応する

これも Spring ネタです。他のサイトでも触れられていそうで意外と触れられていなかったりして、この手の Tips は根強い需要があるようです。

第5位 1076pt Spring Framework Advent Calendar 2011 part.4 - Spring MVC 3.1 で導入される Flash Scope

Spring 3.1 の Flash scope を先取り解説したエントリーです。入力系の画面を作っているとやはり欲しくなるこの機能が正式サポートされたのは喜ばしいことですね。PRGパターンの画面遷移を構成している場合には、Flash scope が大活躍するでしょう。

第6位 935pt yum や rpm でインストールした Jenkins の利用ポートを変更する

jenkins のちょっとした Tips です。大したことは書いていないのですが、こうしたエントリーが上位に食い込んでくるあたり Jenkins の人気の高さを伺わせます。

第7位 893pt ターミナルで exit したときにウィンドウを閉じる

Mac に関する Tips です。このターミナル閉じないんだけど問題は、みんな意外と困ってるのでしょうか。

第8位 885pt Spring Framework Advent Calendar 2011 part.1 - Spring MVC で JSR-303 Validator を使う

JSR-303 Validator の話。ちなみに上記のエントリーでは触れていませんが、Spring 3.1 ではバリデーションのグループ化もできるようになっています。Spring3本のP214に解説がありますのでご参照あれ。

第9位 879pt Spring Security でアカウントロック機構を実現する

書くのに結構エネルギーを使った記憶がある Spring Security ネタです。といっても、核心部は AuthenticationFailureBadCredentialsEvent を使えというだけのことで、内容はシンプル。
AuthenticationFailureBadCredentialsEvent でググっても日本語サイトはほぼヒットしませんので、こうしたところが需要を生んでいるのでしょうか。取っ掛かりのキーワードが日本語サイトで拾えれば、情報を探す際の自由度が広がるという面もあるかもしれません。

第10位 854pt S2Dao の IN 句で 1000 件以上のリストを渡すにはどうするか

2009年のエントリーですが、これが 10 位にランクイン。2012年でも S2Dao + Oracle の組み合わせはバリバリ使われているようですね。

*1:たとえば ListFactoryBean でググっても日本語の情報はほぼヒットしません。

Pyramidを使ってみる

Creating a Pyramid Project — The Pyramid Web Application Development Framework v1.4.9 を参考にしながら作ってみます。


とりあえず環境を作ります。virtualenv + virtualenvwrapper は導入済みとします。

$ mkvirtualenv pyramid
$ pip install pyramid
$ pip freeze > requirements.txt


導入されたパッケージはこんな感じ。

$ cat requirements.txt 
Chameleon==2.11
Mako==0.7.3
MarkupSafe==0.15
PasteDeploy==1.5.0
WebOb==1.2.3
distribute==0.6.28
pyramid==1.4
repoze.lru==0.6
translationstring==1.1
venusian==1.0a7
wsgiref==0.1.2
zope.deprecation==4.0.1
zope.interface==4.0.2


適当にディレクトリーを掘って、scaffoldを生成します。

$ cd path/to/your/application
$ pcreate -s alchemy MyWebsite


setup.py を叩くと、足りないパッケージを勝手にダウンロードしてくれるようです。

$ cd MyWebsite
$ python setup.py develop


依存するパッケージが増えました。

$ pip freeze
Chameleon==2.11
Mako==0.7.3
MarkupSafe==0.15
MyWebsite==0.0
PasteDeploy==1.5.0
Pygments==1.5
SQLAlchemy==0.8.0b2
WebOb==1.2.3
distribute==0.6.28
pyramid==1.4
pyramid-debugtoolbar==1.0.3
pyramid-tm==0.6
repoze.lru==0.6
transaction==1.4.0b1
translationstring==1.1
venusian==1.0a7
waitress==0.8.2
wsgiref==0.1.2
zope.deprecation==4.0.1
zope.interface==4.0.2
zope.sqlalchemy==0.7.1


requirements.txt を作り直しておきます。

$ pip freeze > requirements.txt


テストを走らせてみます。

$ cd MyWebsite
$ python setup.py test   
running test
running egg_info
writing requirements to MyWebsite.egg-info/requires.txt
writing MyWebsite.egg-info/PKG-INFO
writing top-level names to MyWebsite.egg-info/top_level.txt
writing dependency_links to MyWebsite.egg-info/dependency_links.txt
writing entry points to MyWebsite.egg-info/entry_points.txt
reading manifest file 'MyWebsite.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no files found matching '*.rst'
warning: no files found matching '*.jpg' under directory 'mywebsite'
warning: no files found matching '*.txt' under directory 'mywebsite'
warning: no files found matching '*.mak' under directory 'mywebsite'
warning: no files found matching '*.mako' under directory 'mywebsite'
warning: no files found matching '*.js' under directory 'mywebsite'
warning: no files found matching '*.html' under directory 'mywebsite'
warning: no files found matching '*.xml' under directory 'mywebsite'
writing manifest file 'MyWebsite.egg-info/SOURCES.txt'
running build_ext
test_it (mywebsite.tests.TestMyView) ... ok

----------------------------------------------------------------------
Ran 1 test in 0.030s

OK


OKでした。
アプリを立ち上げてみます。

$ pserve development.ini 
Starting server in PID 12817.
serving on http://0.0.0.0:6543


Webブラウザhttp://localhost:6543/ にアクセスしてみます。


なにやらうまくいっていない雰囲気です。メッセージを読んでみます。

Pyramid is having a problem using your SQL database.  The problem
might be caused by one of the following things:

1.  You may need to run the "initialize_MyWebsite_db" script
    to initialize your database tables.  Check your virtual 
    environment's "bin" directory for this script and try to run it.

2.  Your database server may not be running.  Check that the
    database server referred to by the "sqlalchemy.url" setting in
    your "development.ini" file is running.

After you fix the problem, please restart the Pyramid application to
try it again.


DBを初期化していないのでエラーになっているようです。メッセージの指示通りに initialize_MyWebsite_db を実行してみます。

$ initialize_MyWebsite_db
usage: initialize_MyWebsite_db <config_uri>
(example: "initialize_MyWebsite_db development.ini")


引数が必要なようです。もう一度実行します。

$ initialize_MyWebsite_db development.ini
2012-12-29 22:11:39,357 INFO  [sqlalchemy.engine.base.Engine][MainThread] PRAGMA table_info("models")
2012-12-29 22:11:39,357 INFO  [sqlalchemy.engine.base.Engine][MainThread] ()
2012-12-29 22:11:39,358 INFO  [sqlalchemy.engine.base.Engine][MainThread] 
CREATE TABLE models (
	id INTEGER NOT NULL, 
	name TEXT, 
	value INTEGER, 
	PRIMARY KEY (id), 
	UNIQUE (name)
)


2012-12-29 22:11:39,358 INFO  [sqlalchemy.engine.base.Engine][MainThread] ()
2012-12-29 22:11:39,362 INFO  [sqlalchemy.engine.base.Engine][MainThread] COMMIT
2012-12-29 22:11:39,365 INFO  [sqlalchemy.engine.base.Engine][MainThread] BEGIN (implicit)
2012-12-29 22:11:39,366 INFO  [sqlalchemy.engine.base.Engine][MainThread] INSERT INTO models (name, value) VALUES (?, ?)
2012-12-29 22:11:39,366 INFO  [sqlalchemy.engine.base.Engine][MainThread] ('one', 1)
2012-12-29 22:11:39,367 INFO  [sqlalchemy.engine.base.Engine][MainThread] COMMIT


もう一度アプリを立ち上げて、ブラウザでアクセスしてみます。

$ pserve development.ini
Starting server in PID 12897.
serving on http://0.0.0.0:6543


今度はうまくいきました。
開発時には、ファイルを変更したら自動でデプロイしてくれる方が便利です。--reload オプション付きでアプリを立ち上げると、そのモードになるようです。

$ pserve development.ini --reload
Starting subprocess with file monitor
Starting server in PID 12948.
serving on http://0.0.0.0:6543


画面の右側に出ているデバッグツールバーを消すには、development.ini を変更してデバッグツールバーの読み込みを外せば良いようです。別ターミナルで development.ini を編集します。

----- development.ini ---
...
14 pyramid.includes =
15     #pyramid_debugtoolbar
16     pyramid_tm
...


おっと、development.iniのリロードがかかってアプリが落ちました。

development.ini changed; reloading...
-------------------- Restarting --------------------
Traceback (most recent call last):
...
ImportError: No module named #pyramid_debugtoolbar


コメントアウトは行頭でないといけないようです。ini ファイルだからでしょうか?

----- development.ini ---
...
14 pyramid.includes =
15 #    pyramid_debugtoolbar
16     pyramid_tm
...


落ちてしまったアプリを立ち上げ直します。

$ pserve development.ini --reload
Starting subprocess with file monitor
Starting server in PID 13029.
serving on http://0.0.0.0:6543


今度は大丈夫でした。


全体のディレクトリー構成は以下のようになっています。

$ tree
.
├── CHANGES.txt
├── MANIFEST.in
├── MyWebsite.egg-info
│&#160;&#160; ├── PKG-INFO
│&#160;&#160; ├── SOURCES.txt
│&#160;&#160; ├── dependency_links.txt
│&#160;&#160; ├── entry_points.txt
│&#160;&#160; ├── not-zip-safe
│&#160;&#160; ├── requires.txt
│&#160;&#160; └── top_level.txt
├── MyWebsite.sqlite
├── README.txt
├── development.ini
├── mywebsite
│&#160;&#160; ├── __init__.py
│&#160;&#160; ├── __init__.pyc
│&#160;&#160; ├── models.py
│&#160;&#160; ├── models.pyc
│&#160;&#160; ├── scripts
│&#160;&#160; │&#160;&#160; ├── __init__.py
│&#160;&#160; │&#160;&#160; ├── __init__.pyc
│&#160;&#160; │&#160;&#160; ├── initializedb.py
│&#160;&#160; │&#160;&#160; └── initializedb.pyc
│&#160;&#160; ├── static
│&#160;&#160; │&#160;&#160; ├── favicon.ico
│&#160;&#160; │&#160;&#160; ├── footerbg.png
│&#160;&#160; │&#160;&#160; ├── headerbg.png
│&#160;&#160; │&#160;&#160; ├── ie6.css
│&#160;&#160; │&#160;&#160; ├── middlebg.png
│&#160;&#160; │&#160;&#160; ├── pylons.css
│&#160;&#160; │&#160;&#160; ├── pyramid-small.png
│&#160;&#160; │&#160;&#160; ├── pyramid.png
│&#160;&#160; │&#160;&#160; └── transparent.gif
│&#160;&#160; ├── templates
│&#160;&#160; │&#160;&#160; └── mytemplate.pt
│&#160;&#160; ├── tests.py
│&#160;&#160; ├── tests.pyc
│&#160;&#160; ├── views.py
│&#160;&#160; └── views.pyc
├── production.ini
├── setup.cfg
└── setup.py

5 directories, 37 files


とりあえず、今日はここまで。

書籍「Spring3入門」を献本頂きました

Spring3入門 ――Javaフレームワーク・より良い設計とアーキテクチャ

Spring3入門 ――Javaフレームワーク・より良い設計とアーキテクチャ

11/2発売なので、すでに入手されている方もいらっしゃるかと思いますが、表題のとおり、書籍 Spring3入門 Javaフレームワーク・より良い設計とアーキテクチャ を献本頂きました。誠にありがとうございます。実は本書にはレビュアーとして微力ながらお力添えをしており、ポジション的には中の人寄りだったりします。

本書は、前著の Spring入門Spring 2.0 入門 をベースにしつつも、全体の内容は刷新されています。改訂版ではなく、新たに書き下ろしたといってもいいほどです。昔と比べて Spring の記述スタイルが大きく変化したという見方もできます。
最大の特長は、なんといっても Spring 3.1 への対応でしょう。Spring 関連の書籍はもともとそれほど多くありません(いちフレームワークですから当然ですが)。その中で、Spring 3 関連の日本語による情報が体系的にまとめられ、検証された書籍という形で世に出ることの意味は大きいと思います。
また、2.5 で大幅な進化を遂げた Spring MVC 関連の情報を厚めに取っている点も Good です。ページ数でいうと90ページほど。目次や付録を除く全体のページ数が440ページほどですから、全体のうち実に20%のボリュームを占めているのです。実際、それだけのページ数をかけるだけの情報量になっています。もちろん Spring 3.1 でサポートされた RedirectAttributes@Validated にも対応していますよ。
これまで書籍や Web での情報がほとんどなかった Spring Web Flow についても触れられています。40ページ近くを割いて丁寧に解説されていますので、知識ゼロの方の足がかりとして十分な内容でしょう。
逆に、書かれていないこととしては

などが挙げられます。Hibernate 4.x サポートは、Spring 側も 3.1 リリース直前にぎりぎりで入れてきた新機能で、本家ですらドキュメンテーションが追いついていないため書籍での解説は見送ることにしたようです。Java-based Configuration は、それほど重要な機能ではないですし、著者たちが想定する一定規模以上の開発においては使われることは少ないでしょうから、見送ったのだと考えられます。Spring Security の解説がないのは少し残念ですが、これをきちんと解説すると少なく見積もっても50〜60ページは追加で必要になるでしょうから、書籍の分量から考えても難しかったのかもしれません。意欲的な読者の方は、本書で得た知識をベースに自力でマスターしましょう。


というわけで、バリバリの Spring 3.1 ユーザーにはちょっと物足りなさがあるかもしれませんが、

  • これから Spring 3 に入っていこうとするユーザー
  • プロジェクトで Spring 3 を何となく使っていたけど、これを機にきちんと勉強し直したいユーザー
  • Spring 自体初めてなユーザー

には最適な入門書となっています。どうぞお試しあれ。

当日スタッフからみた PyCon JP 2012

PyCon JP 2012 に今年も当日スタッフとして参加してきました。

1日目

会場到着 -> 受付セットアップ -> 11:00まで受付 -> 食堂/テラスのお手伝い -> 433教室ヘルプ -> 休憩 -> 受付 -> LT視聴 -> 片付け -> Party だいたいこんな流れでした。
初っ端の受付をさばくのが大変でした。とにかく名札を探し出すのが大変。

  • 名前順でソートされているところに姓と名を逆に登録している人とか
  • 本名をいうのをためらう人とか
  • 名前のイニシャル H, K, T の枚数がやたら多くて探すのに手間がかかったりとか
  • いくら探してもないと思ったらスポンサー/スピーカー枠の人だったりとか

去年洗い出された受付における課題の多くは改善したように思いますが、名札を事前に印字したことにより新たな問題が浮かび上がりました。ここはまた来年に向けて、知恵の絞りどころですね。
ノベルティを袋にまとめたのは Good でした。余談ですが、パンフレットのクオリティが高かったです。すばらしい。

あと、なぜか Party で XBox360 が当たりました。クラウディアさんに感謝!!*1

2日目

会場到着 -> 受付セットアップ -> 11:00まで受付等 -> 食堂/テラスのお手伝い -> 休憩と教室ヘルプを交互に -> フレームワーク対決のセッション視聴 -> 片付け

名札は翌日持ち越しなので、受付は楽勝でした。ただ、体力的に消耗してきたためか午後からは疲労、眠気と戦いながらのスタッフ業となりました。なんとか乗り切り、Closing、片付けを経て大団円。最後は座長の一本締め。

3日目

関西に帰るためパス。

総括

  • 参加者の皆様、スタッフの皆様おつかれさまでした。
  • 初日は人足りない足りないと思ってましたけど、振り返ってみてどうかな。人数が多ければいいってものでもないし、意外と適正規模だったんではないかなと。
  • 食堂関連。1日目の反省点が2日目に即座に活かされたのは素晴らしかった。スタッフさんいい仕事してます。(ペットボトル圧縮機使用禁止の張り紙、ペットボトル捨て用ゴミ袋の設置)
  • 受付フローは、スケールアウトできるようにこれから知恵を絞りましょう。ただ、参加者倍増した割にはよく捌いたとおもう。

*1:こういうのって、なぜかゲームやらない人のところに来るよね。

Fabricでサーバー管理をDRYにしよう

kyoto.py in 高槻でLTしてきました。LTといいつつ、たぶん5分以上かかってたと思う。


簡単なデモとかも用意はしていたんですが、明らかに時間足りなさそうだったのでカットしました。興味ある方は自分で触ってみるだろうし、いいかな。
懇親会でも話があったのですけど、こうしたツールをそもそも知らなかったという方もいます。そうした方々に知ってもらえただけでも、きっと発表の甲斐はあった。笑いは取れなかったけどな。

CentOS 6.2 で yum install byobu する

端的にいうと、epel-testing リポジトリを使えばできます。--enablerepo オプションを使いましょう。*1

$ sudo yum install byobu --enablerepo=epel-testing

epel-testing リポジトリの追加手順は検索エンジンなどで調べれば分かりますが、たとえば http://nemf.info/2012/04/epel6-memo/ とかを参照すると良いのではないかと。

*1:--enablerepo オプションを使わないでもインストールできてる人はこの記事を読んでないですよね。

percol を使って zsh のディレクトリスタックにお手軽にアクセスする

zsh には cd -[tab] などでディレクトリスタックにアクセスする機能があり、setopt auto_pushd と併用すると幸せになれるのは有名かと思います。


しかし、ディレクトリスタックの数が多くなってくると、スタックの番号を指定するのが億劫になってきます。そこで percol*1 を併用し、ディレクトリスタックへのアクセスをお手軽にする方法を考えてみます。
少し調べてみたところ、ディレクトリスタックを標準出力に表示するには、シェルの組み込みコマンド dirs を使えばよいことが分かりました。-p オプションでディレクトリスタックを行区切りに、 -l オプションでフルパス表示にしてくれます。これを踏まえて、以下のようなシェルスクリプトを .zshrc に書き足しましょう。キーバインドはお好みで変更してください。

function percol_select_dirstack_entry() {
    BUFFER=$(dirs -pl | percol --query "$LBUFFER")
    CURSOR=$#BUFFER
    zle -R -c
}
zle -N percol_select_dirstack_entry
bindkey '^K' percol_select_dirstack_entry

これで percol による絞り込み機能の恩恵を受けられるようになります。zsh の場合、$ cd [path] としなくてもパス名だけで cd してくれますので、percol で対象を決定した後は Enter キーを連打するだけで良いです。

もう一歩前へ

さらに、ディレクトリスタックを history ファイルなどに吐き出すようにしておけば、不意に C-d を押しすぎてターミナルを閉じてしまっても安心ですね。これを実現するには http://sanrinsha.lolipop.jp/blog/2012/02/%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%82%B9%E3%82%BF%E3%83%83%E3%82%AF%E3%82%92%E7%AB%AF%E6%9C%AB%E9%96%93%E3%81%A7%E5%85%B1%E6%9C%89%E3%81%97%E3%81%9F%E3%82%8A%E3%80%81%E4%BF%9D.html などを参照すると良いでしょう。

*1:percol についてご存知ない方は anything 的な絞りこみコマンド percol の紹介 - 備忘録 などをお読み下さい。