<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns="http://purl.org/rss/1.0/"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:admin="http://webns.net/mvcb/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">
  <channel rdf:about="http://www.fraction.jp/log/category/47/">
    <title>Program/Ruby -- BONNOH FRACTION 14</title>
    <link>http://www.fraction.jp/log/category/47/</link>
    <description>世の中に寝るより楽はなかりけり&lt;br /&gt;浮世の馬鹿は起きて働く</description>
    
    <dc:creator>Yuanying</dc:creator>
	<dc:date>2018-06-18T09:39:54+09:00</dc:date>
	<admin:generatorAgent rdf:resource="http://webby.rubyforge.org/?v=0.9.4"/>
    <items>
      <rdf:Seq>
        <rdf:li rdf:resource="http://www.fraction.jp/log/archives/2014/01/14/ruby-png-dpi" />
        <rdf:li rdf:resource="http://www.fraction.jp/log/archives/2013/12/06/stubbing-sinatra-helper" />
        <rdf:li rdf:resource="http://www.fraction.jp/log/archives/2012/05/16/sync-garmin-connect-with-runkeeper" />
        <rdf:li rdf:resource="http://www.fraction.jp/log/archives/2012/01/26/nginx-ssl-rails" />
        <rdf:li rdf:resource="http://www.fraction.jp/log/archives/2011/12/22/rbenv-with-textmate" />
        <rdf:li rdf:resource="http://www.fraction.jp/log/archives/2011/11/16/rspec-fail-on-i18n-translation-missing" />
        <rdf:li rdf:resource="http://www.fraction.jp/log/archives/2011/10/24/vlad-with-sudo" />
        <rdf:li rdf:resource="http://www.fraction.jp/log/archives/2011/08/17/rails3-with-nginx-unicorn" />
        <rdf:li rdf:resource="http://www.fraction.jp/log/archives/2011/08/09/restart-unicorn-server-with-capistrano" />
        <rdf:li rdf:resource="http://www.fraction.jp/log/archives/2011/07/29/opencv-objectdetect-with-ruby192" />
      </rdf:Seq>
    </items>
  </channel>
  <item rdf:about="http://www.fraction.jp/log/archives/2014/01/14/ruby-png-dpi">
    <title>Ruby で PNG 画像を解析する</title>
    <link>http://www.fraction.jp/log/archives/2014/01/14/ruby-png-dpi</link>
    <description>なんで解析する羽目になったかnwdiag や blockdiagで PNG ファイルを生成してウハウハしてたのだが、画像生成オプションに解像度 (dpi) 指定が無いために印刷する際に微妙に困った。ImageMagick とか使えば指定はできるんだ(ろう)けど ImageMagick とかインストールしたくないし…。PNG なんだからフォーマット公開されてるし簡単に解像度くらい指定できるのでは？PNG 画像についてフォーマットについて簡単に調べてみた。PNG 画像の解析と最適化ツール : docu...</description>
    <content:encoded><![CDATA[
        

<p>
<img  src='/log/2014/01/png-title.png'
      width='600' 
      height='396' 
      alt=''  />
</p>


<h2>なんで解析する羽目になったか</h2>

<p><a href="http://blockdiag.com/ja/nwdiag/">nwdiag</a> や <a href="http://blockdiag.com/ja/">blockdiag</a>
で PNG ファイルを生成してウハウハしてたのだが、
画像生成オプションに解像度 (dpi) 指定が無いために印刷する際に微妙に困った。
ImageMagick とか使えば指定はできるんだ(ろう)けど ImageMagick とかインストールしたくないし…。</p>

<p>PNG なんだからフォーマット公開されてるし簡単に解像度くらい指定できるのでは？</p>

<h2>PNG 画像について</h2>

<p>フォーマットについて簡単に調べてみた。</p>

<ul>
<li><a href="http://imaya.blog.jp/archives/6136997.html">PNG 画像の解析と最適化ツール : document</a></li>
<li><a href="http://homepage2.nifty.com/sophia0/png.html">PNGについて</a></li>
</ul>


<p>要するに <code>チャンク</code> と呼ばれるブロックの配列らしい。なんと単純。</p>

<h2>chunky_png</h2>

<p>Ruby で png 画像を解析する簡単なライブラリがあった。</p>

<ul>
<li><a href="https://github.com/wvanbergen/chunky_png">chunky_png</a></li>
</ul>


<p>ファイルパスを渡すと <code>チャンク</code> の配列にして返してくれる。</p>

<pre>
require 'chunky_png'

stream = ChunkyPNG::Datastream.from_file('portal-network.png')
stream.each_chunk do |chunk|
  puts chunk.type
end
</pre>


<p>画像サイズなどのメタデータは <code>IHDR</code> というタイプの <code>チャンク</code> に含まれているらしい。
<code>chunky_png</code> の <code>Datastream</code> では、<code>header_chunk</code> という属性で取得できる。</p>

<pre>
irb(main):018:0&gt; stream.header_chunk.type
=&gt; "IHDR"
irb(main):019:0&gt; stream.header_chunk.width
=&gt; 1413
irb(main):020:0&gt; stream.header_chunk.height
=&gt; 1069
</pre>


<h2>PNG 画像の解像度について</h2>

<h3>解像度を読む</h3>

<p>PNG 画像の解像度は <code>pHYs</code> というタイプの <code>チャンク</code> に含まれており、オプショナルである。
このチャンクのフォーマットはこんな感じ。</p>

<ul>
<li>X軸方向画素数 (単位あたり) 4バイト</li>
<li>Y軸方向画素数 (単位あたり) 4バイト</li>
<li>単位指示子 1バイト</li>
</ul>


<p>「X軸方向画素数/Y軸方向画素数」というのは 「単位指示子」に 1 が指定されていた場合、
1メートルあたりのピクセル数となるそうだ。
普通、解像度というとインチあたりのピクセル数 (dpi) なので dpi で指定したかったら変換が必要のようだ。</p>

<p><code>chunky_png</code> の <code>Datastream</code> で <code>pHYs</code> タイプのチャンクの中身を見てみる。</p>

<pre>
irb(main):036:0&gt; stream.each_chunk do |c|
irb(main):037:1*   if c.type == 'pHYs'
irb(main):038:2&gt;     p c.content
irb(main):039:2&gt;     p encoded_content = c.content.unpack('N2C')
irb(main):040:2&gt;     puts encoded_content[0] / 39.3700787
irb(main):041:2&gt;   end
irb(main):042:1&gt; end
"\x00\x00.$\x00\x00.$\x01"
[11812, 11812, 1]
300.02480030602527
=&gt; nil
</pre>


<p>X 軸および Y 軸ともに、1メートルあたり 11812 ピクセルの解像度が指定されていることがわかる。
"1メートル" は "39.3700787 インチ" なので、<code>39.3700787</code> で割ってやると、
おおよそ、300 dpi の解像度のファイルということがわかった。</p>

<h3>解像度の変更</h3>

<p>読み込んだファイルの <code>pHYs</code> チャンクの値を変えてやれば解像度を変更できるのでやってみた。
150 dpi を指定するには 5906 dot/m ということになる。</p>

<pre>
irb(main):044:0&gt; stream.each_chunk do |c|
irb(main):045:1*   if c.type == 'pHYs'
irb(main):046:2&gt;     c.content = [5906, 5906, 1].pack('N2C')
irb(main):047:2&gt;   end
irb(main):048:1&gt; end
=&gt; nil
irb(main):049:0&gt; 
irb(main):050:0* stream.save('../portal-network.png')
=> #&lt;File:../portal-network.png (closed)&gt;
</pre>




<p>
<img  src='/log/2014/01/dpi-150.png'
      width='334' 
      height='263' 
      alt=''  />
</p>


<p>うまくいった模様。</p>

    ]]></content:encoded>
    <dc:subject>Program/Ruby</dc:subject>
    <dc:subject>Program/技術</dc:subject>
    <dc:creator>Yuanying</dc:creator>
    <dc:date>2014-01-14T14:44:23+09:00</dc:date>
  </item>
  <item rdf:about="http://www.fraction.jp/log/archives/2013/12/06/stubbing-sinatra-helper">
    <title>Sinatra のヘルパーをスタブする</title>
    <link>http://www.fraction.jp/log/archives/2013/12/06/stubbing-sinatra-helper</link>
    <description>最近さっぱり Sinatra の話題を聞かなくなったので需要があるのかどうかわからぬが、Sinatra アプリのテストを書いてるときにヘルパーメソッドのスタブ化にちょい一苦労したのでその話題。とりあえずスタブしてみた簡単な Hello World を出力する Sinatra アプリのヘルパーをスタブしてテストしてみた。以下のような出力でテスト失敗する。$ rspec sinatra_helper.rb .FFailures:  1) Sinatra::Application hello をスタブし...</description>
    <content:encoded><![CDATA[
        

<p>
<img  src='/log/2013/12/sinatra-helper.png'
      width='700' 
      height='283' 
      alt=''  />
</p>


<p>最近さっぱり <a href="http://www.sinatrarb.com">Sinatra</a> の話題を聞かなくなったので需要があるのかどうかわからぬが、
Sinatra アプリのテストを書いてるときにヘルパーメソッドのスタブ化にちょい一苦労したのでその話題。</p>

<h2>とりあえずスタブしてみた</h2>

<p>簡単な <code>Hello World</code> を出力する Sinatra アプリのヘルパーをスタブしてテストしてみた。</p>

<script src="https://gist.github.com/yuanying/7818151.js"></script>


<p>以下のような出力でテスト失敗する。</p>

<pre><code>$ rspec sinatra_helper.rb 
.F

Failures:

  1) Sinatra::Application hello をスタブしてるとき、 Hello Stub! を返す。
     Failure/Error: expect(last_response.body).to eq('Hello Stub!')

       expected: "Hello Stub!"
            got: "Hello World!"

       (compared using ==)
     # ./sinatra_helper.rb:30:in `block (3 levels) in &lt;top (required)&gt;'

Finished in 0.02583 seconds
2 examples, 1 failure

Failed examples:

rspec ./sinatra_helper.rb:28 # Sinatra::Application hello をスタブしてるとき、 Hello Stub! を返す。
</code></pre>

<p>スタブされてなーい！</p>

<h2>Sinatra のソースを読んでみた</h2>

<p>読んでみたところ、
<a href="https://github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb#L877">アプリケーションが call される直前で dup されてやがる</a>…。</p>

<p><code>allow_any_instance_of</code> は逃げだと思ったのでいろいろこねくり回したところ、以下のようになった。</p>

<script src="https://gist.github.com/yuanying/7818242.js"></script>


<p>要するに <code>dup</code> される前に <code>dup</code> をスタブして、
事前に dup しておいたアプリケーションインスタンスを返すようにしておき、
そのアプリケーションインスタンスをスタブするという…。</p>

<p>なんかとてもバッドノウハウな気がしてきた。</p>

<p>とりあえず rails でテスト書いた後に Sinatra や <a href="http://www.padrinorb.com">Padrino</a>
でテスト書く羽目になると、どれだけ rails が恵まれていたか再認識できますな！</p>

    ]]></content:encoded>
    <dc:subject>Program/Ruby</dc:subject>
    <dc:creator>Yuanying</dc:creator>
    <dc:date>2013-12-06T12:36:23+09:00</dc:date>
  </item>
  <item rdf:about="http://www.fraction.jp/log/archives/2012/05/16/sync-garmin-connect-with-runkeeper">
    <title>Garmin Connect と RunKeeper を同期したい</title>
    <link>http://www.fraction.jp/log/archives/2012/05/16/sync-garmin-connect-with-runkeeper</link>
    <description>たぶん、iPhone ユーザがランニングを始めてまず使い始めるソフトと言えば「RunKeeper」なんじゃなかろうか。StreatTeam を作って友達とランニングを競うこともできるし、何よりページが見やすくて良い。かといって、だんだんランニングにはまってくると、iPhone アプリの RunKeeper じゃフラストレーションが溜まってくるのも事実。ピカピカの Garmin の腕時計を買って安堵するのも一瞬、Garmin のデータを RunKeeper にアップするのが結構メンドイ。いちいちブラ...</description>
    <content:encoded><![CDATA[
        <p>たぶん、iPhone ユーザがランニングを始めてまず使い始めるソフトと言えば「<a href="http://runkeeper.com/">RunKeeper</a>」なんじゃなかろうか。
StreatTeam を作って友達とランニングを競うこともできるし、何よりページが見やすくて良い。</p>

<p>かといって、だんだんランニングにはまってくると、iPhone アプリの RunKeeper じゃフラストレーションが溜まってくるのも事実。
ピカピカの Garmin の腕時計を買って安堵するのも一瞬、
Garmin のデータを RunKeeper にアップするのが結構メンドイ。
いちいちブラウザから手動で入力しなければならない。</p>

<p><a href="http://connect.garmin.com/">Garmin Connect</a> へのアップロードなら無線経由で勝手にやってくれるのに…。</p>

<p>
<img  src='/log/2012/05/connect_importer.jpg'
      width='400' 
      height='335' 
      alt=''  />
</p>


<p>と、いうことで、「<a href="http://labs.3machinae.com/garmin2runkeeper/">ConnectImporter</a>」というウェブアプリを作ってみました。
このアプリは、Garmin Connect の公開データを自動で(1時間おきに) RunKeeper に同期してくれると言うもの。</p>

<p>本当は、非公開データも同期したかったのだが <a href="http://developer.garmin.com/web-products/web-services/">Garmin Connect の準備が整っていない</a>ようなので、
とりあえず。</p>

<div class="sticky-itslink">
  <a href="http://click.linksynergy.com/fs-bin/stat?id=XLkWH7mRISo&amp;offerid=94348&amp;type=3&amp;subid=0&amp;tmpid=2192&amp;RD_PARM1=http%253A%252F%252Fitunes.apple.com%252Fjp%252Fapp%252Frunkeeper%252Fid300235330%253Fmt%253D8%2526uo%253D4%2526partnerId%253D30" rel="nofollow" target="_blank">
    <img src="http://a4.mzstatic.com/us/r1000/112/Purple/v4/f6/35/9c/f6359cc0-0770-d45d-31ac-a576bbd6134f/icon-pro.png" alt="RunKeeper" title="RunKeeper" />
  </a>
  <ul class="sticky-itslinktext">
    <li class='title'><a href="http://click.linksynergy.com/fs-bin/stat?id=XLkWH7mRISo&amp;offerid=94348&amp;type=3&amp;subid=0&amp;tmpid=2192&amp;RD_PARM1=http%253A%252F%252Fitunes.apple.com%252Fjp%252Fapp%252Frunkeeper%252Fid300235330%253Fmt%253D8%2526uo%253D4%2526partnerId%253D30" rel="nofollow" target="_blank">RunKeeper</a></li>
    <li>FitnessKeeper, Inc.</li>
    <li>価格： 0円 <a href="http://click.linksynergy.com/fs-bin/stat?id=XLkWH7mRISo&amp;offerid=94348&amp;type=3&amp;subid=0&amp;tmpid=2192&amp;RD_PARM1=http%253A%252F%252Fitunes.apple.com%252Fjp%252Fapp%252Frunkeeper%252Fid300235330%253Fmt%253D8%2526uo%253D4%2526partnerId%253D30" rel="nofollow" target="_blank"><img src="http://ax.phobos.apple.com.edgesuite.net/ja_jp/images/web/linkmaker/badge_appstore-sm.gif" alt ="iTunesで見る" style="border-style:none;" /></a></li>
    <li class='sticky'><span>posted with <a href="http://sticky.linclip.com/linkmaker/" target="_blank">sticky</a> on 2012.5.16</span></li>
  </ul>
</div>


<h2>実装</h2>

<p>あんまり興味が無い人の方が多いと思うけど、使ったライブラリその他。</p>

<ul>
<li>Mongoid

<ul>
<li>MongoDB</li>
</ul>
</li>
<li>Padrino</li>
<li>Twitter Bootstrap</li>
<li>OmniAuth RunKeeper

<ul>
<li>OmniAuth</li>
</ul>
</li>
</ul>


<p>OAuth とか、KVS とか、Padrino とか、初めて使ったよ。</p>

    ]]></content:encoded>
    <dc:subject>Program/Ruby</dc:subject>
    <dc:subject>Program/技術</dc:subject>
    <dc:subject>トライアスロン</dc:subject>
    <dc:creator>Yuanying</dc:creator>
    <dc:date>2012-05-16T12:00:40+09:00</dc:date>
  </item>
  <item rdf:about="http://www.fraction.jp/log/archives/2012/01/26/nginx-ssl-rails">
    <title>Nginx + SSL + Rails</title>
    <link>http://www.fraction.jp/log/archives/2012/01/26/nginx-ssl-rails</link>
    <description>普通に nginx をフロントに置いて、バックエンドに Rails を置いた場合の nginx の設定ファイルは、半年くらい前に書いた。これはこれで良いのだが、今度は HTTPS でもアプリケーションにアクセスしたくなった場合、listen 80 の server セクションをコピーして、listen 443 で SSL を利用する server セクションを追加すれば良いだけの気もするのだが。単純にコピーして SSL の設定をしただけだとはまることがある。force_sslRails 3.x か...</description>
    <content:encoded><![CDATA[
        <p>普通に nginx をフロントに置いて、バックエンドに Rails を置いた場合の nginx の設定ファイルは、
<a href="/log/archives/2011/08/17/rails3-with-nginx-unicorn">半年くらい前に書いた</a>。</p>

<p>これはこれで良いのだが、今度は HTTPS でもアプリケーションにアクセスしたくなった場合、
listen 80 の server セクションをコピーして、listen 443 で SSL を利用する server セクションを追加すれば良いだけの気もするのだが。
単純にコピーして SSL の設定をしただけだとはまることがある。</p>

<h2>force_ssl</h2>

<p>Rails 3.x からだと思うが、ActionController に force_ssl というクラスメソッドが追加された。</p>

<pre><code class='prettyprint'># Force the request to this particular controller or specified actions to be
# under HTTPS protocol.
#
# Note that this method will not be effective on development environment.
#
# ==== Options
# * <tt>only</tt>   - The callback should be run only for this action
# * <tt>except</tt>  - The callback should be run for all actions except this action
def force_ssl(options = {})
  host = options.delete(:host)
  before_filter(options) do
    if !request.ssl? &amp;&amp; !Rails.env.development?
      redirect_options = {:protocol => 'https://', :status => :moved_permanently}
      redirect_options.merge!(:host => host) if host
      redirect_to redirect_options
    end
  end
end</code></pre>


<p>ようするに SSL でアクセスしているかを判断して、SSL 以外でアクセスしていた場合、
SSL を利用した URL にリダイレクトしてくれる before_filter だ。</p>

<p>ただ、フロントに nginx を置いて、バックエンドに Rails を置いた場合は、
普通、SSL の処理をフロントに任せるので以下のようになる。</p>

<p>
<img  src='/log/2012/01/nginx-ssl-rails.jpg'
      width='164' 
      height='229' 
      alt=''  />
</p>


<p>何も対策を施さなければ、force_ssl 処理内の request.ssl? が false を返して、
リダイレクトの無限ループになってしまう。ってかなった。</p>

<h2>X-FORWARDED_PROTO</h2>

<p>そんなバックエンドが SSL を利用された後であるかどうかを判断するために、
HTTP には X-FORWARDED_PROTO とかいうヘッダが用意されているらしい。へえー。</p>

<p>と、言う訳でリバースプロキシの設定に以下の記述を行えばおk。</p>

<pre>
try_files /system/maintenance.html $uri $uri/index.html $uri.html @application;

location @application {
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        <strong>proxy_set_header X-FORWARDED_PROTO https;</strong>
        proxy_pass http://application;
}
</pre>




    ]]></content:encoded>
    <dc:subject>Program/Ruby</dc:subject>
    <dc:subject>Program/技術</dc:subject>
    <dc:creator>Yuanying</dc:creator>
    <dc:date>2012-01-26T08:54:28+09:00</dc:date>
  </item>
  <item rdf:about="http://www.fraction.jp/log/archives/2011/12/22/rbenv-with-textmate">
    <title>rbenv with Textmate</title>
    <link>http://www.fraction.jp/log/archives/2011/12/22/rbenv-with-textmate</link>
    <description>Textmate で CMD+R を使った時に、rbenv で指定した Ruby を利用する方法。基本的には、uberfork: Integrate rbenv with Textmate上記のブログの通りで良いのだけど、それだけだと rbenv コマンドが無いよと言われるので、 PATH に /usr/local/bin も通しておく必要がある。まとめると、  PATH  /Users/USERNAME/.rbenv/shims:/usr/local/bin:/usr/bin:/bin:/usr...</description>
    <content:encoded><![CDATA[
        <p>Textmate で <code>CMD+R</code> を使った時に、rbenv で指定した Ruby を利用する方法。</p>

<p>
<img  src='/log/2011/12/rbenv-with-textmate.jpg'
      width='389' 
      height='385' 
      alt=''  />
</p>


<p>基本的には、</p>

<ul>
<li><a href="http://uberfork.com/post/12280974742/integrate-rbenv-with-textmate">uberfork: Integrate rbenv with Textmate</a></li>
</ul>


<p>上記のブログの通りで良いのだけど、
それだけだと rbenv コマンドが無いよと言われるので、 <code>PATH</code> に <code>/usr/local/bin</code> も通しておく必要がある。</p>

<p>まとめると、</p>

<dl>
  <dt>PATH</dt>
  <dd><strong>/Users/USERNAME/.rbenv/shims:/usr/local/bin:</strong>/usr/bin:/bin:/usr/sbin:/sbin</dd>

  <dt>RBENV_VERSION</dt>
  <dd>1.9.3-p0</dd>

  <dt>TM_RUBY</dt>
  <dd>/Users/USERNAME/.rbenv/shims/ruby</dd>

</dl>


    ]]></content:encoded>
    <dc:subject>Program/Ruby</dc:subject>
    <dc:creator>Yuanying</dc:creator>
    <dc:date>2011-12-22T13:45:57+09:00</dc:date>
  </item>
  <item rdf:about="http://www.fraction.jp/log/archives/2011/11/16/rspec-fail-on-i18n-translation-missing">
    <title>Rails で翻訳に失敗したらテストが失敗するようにしてみた</title>
    <link>http://www.fraction.jp/log/archives/2011/11/16/rspec-fail-on-i18n-translation-missing</link>
    <description>View のテスト中に、翻訳テキストが存在しなかったらテストに失敗するといいなあと思った。通常は翻訳に失敗してもレンダリングされる html 中に「翻訳に失敗したよ！」というメッセージが出るだけなので、テストが失敗しないので翻訳できてるのかできてないのかチェックできない。翻訳漏れが発生！とかなってしまう。というわけで、以下を spec_helper に追加。I18n.exception_handler = lambda do |exception, locale, key, options|  r...</description>
    <content:encoded><![CDATA[
        

<p>
<img  src='/log/2011/11/translation-missing.jpg'
      width='404' 
      height='206' 
      alt=''  />
</p>


<p>View のテスト中に、翻訳テキストが存在しなかったらテストに失敗するといいなあと思った。</p>

<p>通常は翻訳に失敗してもレンダリングされる html 中に「翻訳に失敗したよ！」というメッセージが出るだけなので、</p>

<ol>
<li>テストが失敗しないので翻訳できてるのかできてないのかチェックできない。</li>
<li>翻訳漏れが発生！</li>
</ol>


<p>とかなってしまう。</p>

<p>というわけで、以下を <code>spec_helper</code> に追加。</p>

<pre><code class='prettyprint'>I18n.exception_handler = lambda do |exception, locale, key, options|
  raise exception.message
end</code></pre>


<p>まあ、ちょっと問題がある訳でもないが、
どちらかというと rspec-rails のバグのような気がしないでもないので気にしない。</p>

    ]]></content:encoded>
    <dc:subject>Program/Ruby</dc:subject>
    <dc:creator>Yuanying</dc:creator>
    <dc:date>2011-11-16T10:20:39+09:00</dc:date>
  </item>
  <item rdf:about="http://www.fraction.jp/log/archives/2011/10/24/vlad-with-sudo">
    <title>Vlad で sudo</title>
    <link>http://www.fraction.jp/log/archives/2011/10/24/vlad-with-sudo</link>
    <description>最近、Capistrano を使い始めたのだが、何気に使い方を調べようとソースコードを読むと、長くて大変。全体像を把握するのが大変だなあと何となく思っていたところに発見。Vlad the DeployerCapistrano の代替として使えそう。それでいてソースコードはシンプルで読みやすくてよい。まあ、ぶっちゃけ、ツールの使い方について、ネットを徘徊して調べるか？ソースコードを徘徊して調べるか？のどっちが好みかで、Capistrano を使うか Vlad を使うかが変わる気がするが。sudo し...</description>
    <content:encoded><![CDATA[
        

<p>
<img  src='/log/2011/10/Vlad-the-Deployer.png'
      width='338' 
      height='159' 
      alt=''  />
</p>


<p>最近、Capistrano を使い始めたのだが、
何気に使い方を調べようとソースコードを読むと、長くて大変。
全体像を把握するのが大変だなあと何となく思っていたところに発見。</p>

<ul>
<li><a href="http://rubyhitsquad.com/Vlad_the_Deployer.html">Vlad the Deployer</a></li>
</ul>


<p>Capistrano の代替として使えそう。それでいてソースコードはシンプルで読みやすくてよい。</p>

<p>まあ、ぶっちゃけ、ツールの使い方について、</p>

<ol>
<li>ネットを徘徊して調べるか？</li>
<li>ソースコードを徘徊して調べるか？</li>
</ol>


<p>のどっちが好みかで、Capistrano を使うか Vlad を使うかが変わる気がするが。</p>

<h2>sudo してみた</h2>

<p>で、まあ、Capistrano や Vlad の使い方はおいといて、
Remote のタスクを sudo 権限で実行してみたところ、</p>

<pre><code>$ rake vlad:test --trace 
** Invoke vlad:test (first_time)
** Execute vlad:test
ssh localhost 'sudo -p Password: echo sudo'
__sudo: no tty present and no askpass program specified__
rake aborted!
execution failed with status 1: ssh localhost sudo -p Password: echo sudo
</code></pre>

<p>みたいに言われて実行できないことがある。
Capistrano の場合は、<code>default\_run\_options[:pty] = true</code>
すればいいらしいが…。</p>

<p>色々調べたところ、</p>

<pre><code>set :sudo_flags, sudo_flags &lt;&lt; '-S'
</code></pre>

<p>で解決だった。</p>

    ]]></content:encoded>
    <dc:subject>Program/Ruby</dc:subject>
    <dc:subject>Program/技術</dc:subject>
    <dc:creator>Yuanying</dc:creator>
    <dc:date>2011-10-24T10:15:16+09:00</dc:date>
  </item>
  <item rdf:about="http://www.fraction.jp/log/archives/2011/08/17/rails3-with-nginx-unicorn">
    <title>Rails3.1@Unicorn で nginx の設定</title>
    <link>http://www.fraction.jp/log/archives/2011/08/17/rails3-with-nginx-unicorn</link>
    <description>Rails3.1 のアプリケーションを Unicorn で動かして、静的ファイルは nginx におまかせ！ってしようとした時に nginx の設定で少しはまったのでメモ。前提nginx を 127.0.0.1:80 で動かしている。Unicorn を 127.0.0.1:8080 で動かしている。Rails3.1 の assets を 事前に rake assets:precompile してある。nginx の設定/assets ディレクトリ以下のファイルを expire max  で永久にブ...</description>
    <content:encoded><![CDATA[
        

<p>
<img  src='/log/2011/08/kona.jpg'
      width='400' 
      height='327' 
      alt=''  />
</p>


<p>Rails3.1 のアプリケーションを Unicorn で動かして、静的ファイルは nginx におまかせ！
ってしようとした時に nginx の設定で少しはまったのでメモ。</p>

<h2>前提</h2>

<ul>
<li>nginx を 127.0.0.1:80 で動かしている。</li>
<li>Unicorn を 127.0.0.1:8080 で動かしている。</li>
<li>Rails3.1 の assets を 事前に <code>rake assets:precompile</code> してある。</li>
</ul>


<h2>nginx の設定</h2>

<ul>
<li>/assets ディレクトリ以下のファイルを expire max  で永久にブラウザ側にキャッシュさせる。

<ul>
<li>assets 内のファイルは内容が変わればファイル名も変わるため、永久にキャッシュさせておーけー。</li>
</ul>
</li>
<li>try_files で すでに存在する静的ファイルはすべて nginx で処理。</li>
</ul>


<pre class='prettyprint'><code>upstream apps-server {
    server 127.0.0.1:8080;
}

server {
    listen  80;
    server_name     app.example.com;
    
    root /path/to/app/current/public;
    error_log /path/to/app/current/log/error.log;

    location ~* ^/assets {
            expires max;
            add_header Cache-Control public;
            break;
    }

    try_files /system/maintenance.html $uri $uri/index.html $uri.html @unicorn;

    location @unicorn {
            proxy_set_header X-Real-IP  $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_pass http://apps-server;
    }
}</code></pre>




    ]]></content:encoded>
    <dc:subject>Apple</dc:subject>
    <dc:subject>Program/Ruby</dc:subject>
    <dc:subject>Program/技術</dc:subject>
    <dc:creator>Yuanying</dc:creator>
    <dc:date>2011-08-17T11:09:18+09:00</dc:date>
  </item>
  <item rdf:about="http://www.fraction.jp/log/archives/2011/08/09/restart-unicorn-server-with-capistrano">
    <title>CapistranoでUnicornの起動と停止と再起動</title>
    <link>http://www.fraction.jp/log/archives/2011/08/09/restart-unicorn-server-with-capistrano</link>
    <description>CapistranoでUnicornの起動と停止と再起動をしたくなった。CapistranoでUnicornの起動と停止と再起動 | ひげろぐ以上のエントリを参考にしたが、再起同時に空振り上等だったのでちょっといじった。 以上。...</description>
    <content:encoded><![CDATA[
        

<p>
<img  src='/log/2011/08/deploy-unicorn-rb.jpg'
      width='415' 
      height='278' 
      alt=''  />
</p>


<p>CapistranoでUnicornの起動と停止と再起動をしたくなった。</p>

<ul>
<li><a href="http://higelog.brassworks.jp/?p=1533">CapistranoでUnicornの起動と停止と再起動 | ひげろぐ</a></li>
</ul>


<p>以上のエントリを参考にしたが、再起同時に空振り上等だったのでちょっといじった。</p>

<script src="https://gist.github.com/1133608.js"> </script>


<p>以上。</p>

    ]]></content:encoded>
    <dc:subject>Program/Ruby</dc:subject>
    <dc:creator>Yuanying</dc:creator>
    <dc:date>2011-08-09T17:28:27+09:00</dc:date>
  </item>
  <item rdf:about="http://www.fraction.jp/log/archives/2011/07/29/opencv-objectdetect-with-ruby192">
    <title>Ruby 1.9.2 で顔認識してみた</title>
    <link>http://www.fraction.jp/log/archives/2011/07/29/opencv-objectdetect-with-ruby192</link>
    <description>4年ほど前に流行った Ruby の OpenCV ラッパである objectdetectを今更ながらに使ってみたら意外にハマッタのでメモ。環境とりあえず環境は、Ubuntu 10.10Ruby 1.9.2p180 (2011-02-18 revision 30909) [x86_64-linux]hoe (2.10.0)objectdetect (0.0.3)rake (0.9.2)OpenCV 2.1と言う感じ。OpenCV のインストールUbuntu の場合、OpenCV のライブラリがいくつ...</description>
    <content:encoded><![CDATA[
        

<p>
<img  src='/log/2011/07/objectdetect.jpg'
      width='388' 
      height='179' 
      alt=''  />
</p>


<p>4年ほど前に流行った Ruby の OpenCV ラッパである <a href="http://objectdetect.rubyforge.org/objectdetect/">objectdetect</a>
を今更ながらに使ってみたら意外にハマッタのでメモ。</p>

<h2>環境</h2>

<p>とりあえず環境は、</p>

<ul>
<li>Ubuntu 10.10</li>
<li>Ruby 1.9.2p180 (2011-02-18 revision 30909) [x86_64-linux]</li>
<li>hoe (2.10.0)</li>
<li>objectdetect (0.0.3)</li>
<li>rake (0.9.2)</li>
<li>OpenCV 2.1</li>
</ul>


<p>と言う感じ。</p>

<h2>OpenCV のインストール</h2>

<p>Ubuntu の場合、OpenCV のライブラリがいくつかに別れてるらしく、
<code>gem install objectdetect</code> するたびにあのライブラリが無いこのライブラリが無いと言われてむかついた。
どんな感じでむかついたのかはわざわざログにする必要も無いので、必要なライブラリを以下に晒す。</p>

<pre><code>$ sudo apt-get install libcv-dev
$ sudo apt-get install libhighgui-dev
$ sudo apt-get install libcvaux-dev
</code></pre>

<h2>objectdetect のインストール</h2>

<p>そもそも objectdetect は Ruby 1.9 に対応してないらしく、
native extention がコンパイルできないのでそこから直してやる必要がある。</p>

<h3>objectdetect 0.0.3 のソースコードの修正</h3>

<p>とりあえずどっかから、<code>objectdetect-0.0.3.gem</code> を拾ってきて <code>unpack</code> する。</p>

<pre><code>$ gem unpack objectdetect-0.0.3.gem
</code></pre>

<p><code>unpack</code> されて出てきたソースコードの中から、 <code>ext/objectdetect.c</code> を修正する。</p>

<pre><code>--- objectdetect.c.org  2011-07-29 15:09:32.000000000 +0900
+++ objectdetect.c  2011-07-29 15:10:03.000000000 +0900
@@ -25,13 +25,13 @@
   Check_Type(target_path, T_STRING);

   /* load the model */
-  CvHaarClassifierCascade* cascade = cvLoad(RSTRING(model_path)-&gt;ptr, 0, 0, 0);
+  CvHaarClassifierCascade* cascade = cvLoad(RSTRING_PTR(model_path), 0, 0, 0);
   if( cascade == 0 ) {
     rb_raise(rb_eArgError, "Can't load the cascade file");
   }

   /* load the target picture */
-  IplImage *img = cvLoadImage(RSTRING(target_path)-&gt;ptr, 1);
+  IplImage *img = cvLoadImage(RSTRING_PTR(target_path), 1);
   if( !img ) {
     cvReleaseHaarClassifierCascade(&amp;cascade);
     rb_raise(rb_eArgError, "Can't load the image file");
</code></pre>

<h3>インストール</h3>

<p>修正し終わったら <code>rake gem</code> して解凍したソースコードを gem 化しインストール。</p>

<pre><code>$ rake gem
$ gem install pkg/objectdetect-0.0.3.gem
</code></pre>

<p><code>rake gem</code> した時にエラーが出るようだったら、たぶん <code>hoe</code> が入ってないのでインストールしておく。</p>

<h2>試す</h2>

<pre><code class='prettyprint'>require 'rubygems'
require 'objectdetect'

model_path = 'haarcascade_frontalface_alt2.xml'

p ObjectDetect::detect(model_path, '01kiribati1.jpg')</code></pre>


<p>適当な名前で上のコードを保存して、</p>

<pre><code>$ rvm use 1.9.2@opencv                
Using /home/yuanying/.rvm/gems/ruby-1.9.2-p180 with gemset opencv

$ ruby test.rb        
libdc1394 error: Failed to initialize libdc1394
[[188, 27, 41, 41], [40, 35, 46, 46]]
</code></pre>

<p>認識されたことを確認してヨロコブ。
なんかエラーが出てますが、問題ない！</p>

<p>ちなみにさらっと書いてるように見えるがけっこー時間かかった！</p>

<h2>参考文献</h2>

<ul>
<li><a href="http://elpeo.jp/diary/20070312.html#p03">「顔面認識→笑い男貼り付け」ツールを Ruby で書く</a></li>
<li><a href="http://d.hatena.ne.jp/darashi/20070313/1173791243">[facedetector] gem objectdetect を公開しました</a></li>
</ul>


    ]]></content:encoded>
    <dc:subject>Program/Ruby</dc:subject>
    <dc:creator>Yuanying</dc:creator>
    <dc:date>2011-07-29T15:25:47+09:00</dc:date>
  </item>
</rdf:RDF>
