はじめに
Youtubeの提供するData APIを使用して、動画を検索するサンプルアプリケーションをRuby on Railsで作ってみた。前回のエントリRuby on RailsでYoutubeから動画を検索するサンプルアプリケーション - 大人になったら肺呼吸では、Data APIが返すXMLを解析する際に、REXMLという標準のXMLライブラリを使用したが、今回はLibxml-Rubyという別のXMLライブラリを使用した。
※以下の手順は、さくらインターネットのレンタルサーバ上にアプリケーションを作成していくことを前提としている。
事前準備
Libxml-Rubyのインストール
以下のコマンドを実行し、Libxml-Rubyをインストールする。
%setenv RB_USER_INSTALL true %gem18 install libxml-ruby
プロジェクトの作成
Youtubeという名前でプロジェクトを作成する。データベースは使用しないが、とりあえずMySQL用でプロジェクトを作成しておく。
mkdir Rails cd Rails rails Youtube -d mysql cd Youtube chmod -R o+w log tmp
コントローラの作成
script/generate controller youtube
公開用ディレクトリにシンボリックリンクを張る
ln -s $HOME/Rails/Youtube/public $HOME/www/Youtube
各種設定ファイルを編集する
- /publc/.htaccess
- /config/database.yml
- /config/environment.rb
上記ファイルの編集方法は、以下のエントリを参照してほしい。
Ruby On Rails2.2で作るサンプルアプリケーション(ON さくらインターネット) - 大人になったら肺呼吸
検索機能の作成
検索画面となるビューを作成する。
app/views/youtube/配下にindex.html.erbを作成する。
<h1>Youtube検索</h1> <% form_tag :action => :searchForLibXML do %> <fieldset> <legend>検索フォーム</legend> <%= text_field_tag :keyword, @keyword, :style=>"width:300px" %> <%= submit_tag '検索', :style=>"width:100px" %> </fieldset> <% end %> <ul> <% if @data != nil %> <% for x, y in @data %> <li><%= x %></li> <li><%= y %></li> <object width="200" height="200"> <param name="movie" value="<%= y %>"</param> <param name="wmode" value="transparent"> <param name="allowFullScreen" value="false"></param> <embed src="<%= y %>" type="application/x-shockwave-flash" wmode="transparent" width="425" height="336" allowfullscreen="false"></embed> </object> <% end %> <% end %> </ul>
検索処理をコントローラに追加する
/app/controllers/youtube_controller.rbを以下のように編集する
class YoutubeController < ApplicationController # libxmlライブラリの読み込み require 'xml/libxml' # indexアクション def index respond_to do |format| format.html end end # searchForLibXMLアクション def searchForLibXML site = Net::HTTP.start('gdata.youtube.com') # 検索語をクエリにセットして、リクエストする @keyword = params[:keyword] requestURL = "/feeds/api/videos?vq=" + @keyword requestURL = URI.escape(requestURL) response = site.get(requestURL) # 検索結果を変数にセットする resXML = response.body site.finish # XMLを解析して、タイトルだけを取り出す @titles = getTitlesByLibXML(resXML) # XMLを解析して、動画のURLだけを取り出す @movies = getMoviesByLibXML(resXML) # 画面に5件だけ表示するため、ハッシュを生成して # 5件分のタイトルと動画のURLを追加する h = Hash::new 5.times { |i| h.store(@titles[i], @movies[i]) } @data = h render :action => 'index' end # XMLを解析して、タイトルだけを取り出す関数 def getTitlesByLibXML xml nameSpace = [ 'atom'=>'http://www.w3.org/2005/Atom', 'os'=>'http://a9.com/-/spec/opensearchrss/1.0/' ] xp = XML::Parser.new # XMLパーサを生成する xp.string = xml # stringプロパティに引数で受け取ったxmlを渡す doc = xp.parse # パースした結果をdocに格納する ary = Array.new() # entry/titleを一覧で出力する doc.root.find('//atom:entry/atom:title', nameSpace).each do |entry| ary.push(entry.content) end return ary end # XMLを解析して、動画のURLを取り出す関数 def getMoviesByLibXML xml nameSpace = [ 'atom'=>'http://www.w3.org/2005/Atom', 'os'=>'http://a9.com/-/spec/opensearchrss/1.0/' ] xp = XML::Parser.new # XMLパーサを生成する xp.string = xml # stringプロパティに引数で受け取ったxmlを渡す doc = xp.parse # パースした結果をdocに格納する ary = Array.new() # entry/media:group/media:contentのurl属性を一覧で出力する doc.root.find('//atom:entry', nameSpace).each do |entry| tmp = entry.find_first('media:group/media:content', nameSpace) if tmp != nil then tmp = tmp.attributes tmp = tmp.get_attribute('url') # http:ではじまるものだけを取り出す if tmp.value.slice(0,5) == "http:" then ary.push(tmp.value) end end end return ary end end
ルーティングの設定
- public/index.htmlを削除するか、リネームする
- config/route.rbに以下の行を追加する。
map.connect '', :controller => 'youtube'
これにより、http://xxx.sakura.ne.jp/Youtube/にアクセスした際に、自動的にYoutubeコントローラに処理が渡されるようになる。
動作確認
http://xxx.sakura.ne.jp/Youtube/にアクセスする。