にたまごほうれん草アーカイブ

はてなダイアリーで書いてた「にたまごほうれん草」という日記のアーカイブです。現在は「にたまごほうれん草ブログ」を運営中です。

最新のmechanizeでnicovideo gemが動作しない件&gemアップデート(ver 0.1.3)

上記エントリより、バージョンが0.7.1〜0.7.4のmechanizeを使用していると、ダウンロード時に落ちるということを報告いただきました。
これは私のミスで、これまでずっと0.7.0で確認してきました。
というわけで早速mechanizeのバージョンを最新にして確認。やはり落ちる。
原因を大雑把に解説すると以下の通り。

  • WWW::Mechanize#getを使用する際にURL以外の引数を省略すると、mechanizeは一つ前に取得したページをリファラとして設定しようとする
  • HTMLページの場合はWWW::Mechanize::Pageオブジェクトであり、この場合は問題なし。
  • Stringオブジェクト(すなわちget引数でURLを文字列で指定した場合)は、URI.parseでURIオブジェクトを生成したあと、それを引数にPageオブジェクトを新規作成。(→正常動作)
  • さらにそれ以外の場合は、何も考えずにURIを突っ込むべき部分に前に取得したオブジェクトを突っ込む
  • Page#initializeでは、URIオブジェクトだと信じているので、URI#pathを呼び出そうとする→ここで例外発生

動画をダウンロードするとき、直前に取得しているファイルはパラメータが記述されたXMLファイルであり、これはWWW::Mechanize::Fileオブジェクトでpathメソッドが実装されていないため例外が発生していました。
なので、以下の通り修正してバージョン0.1.3としてアップデートしました。

--- lib/nicovideo/mechanize-ext.rb
+++ lib/nicovideo/mechanize-ext.rb
@@ -15,6 +15,12 @@
         add_to_history(page)
         page
       end
+
+      class File
+        def path
+          return @uri.path
+        end
+      end
     }
   end
 end