ソースコード公開(その2)
昨日はバッチ部分を掲載したので、今日はオンライン部分ですね。
オンライン部分は、大きく以下の4つの部分に分かれています。
- トップページを表示する部分(リスト6)
- 検索結果一覧を表示する部分(リスト7)
- 検索結果詳細を表示する部分(リスト8)
- Rimoと連携する部分(リスト9、10)
さてと、これでRetroTube内で動いている全てのプログラムのソースコードを公開したことになりますが、ちょっとコードを読める方であれば、シンプルな仕組みで動いていることに驚かれたのではないでしょうか?
てっきりRailsを使ったDBアプリだと勘違いされていた方もいらっしゃると思いますが、そのような小難しいことは一切やっていないのです。
ひたすら移送と分岐と繰り返しの羅列なので、このままCOBOLでリメイクできそうな気がしますね。
では、何故Rubyで書いたのかと興味深く思われた方は、是非雑誌の方の記事を参照していただきたいです。
今後も暇を見ては(RetroTubeの)改良を続けていくつもりですが、既に別のサービスの開発に取り掛かっているところなので、徐々にそちらの方へ注力していくことになると思います。
そちらの方もご期待ください。
【リスト6】index.cgi
#!/usr/local/bin/ruby print "Content-type: text/html\n\n" ##################################### #【RetroTube】トップページ表示プログラム ##################################### require "csv" #ここからHTML生成 #HTMLヘッダ print '<html><head> <title>RetroTube</title> <meta http-equiv="content-type" content="text/html; charset=Shift_JIS"> <meta http-equiv="Content-Style-Type" content="text/css"> <link rel="alternate" type="application/rss+xml" title="RetroTube RSS" href="http://www.retro-tube.com/rss.rdf"> <link rel="stylesheet" type="text/css" href="title.css"> </head><body>' #開発者 print '<p class="header">This service is created by <a href="http://d.hatena.ne.jp/quill3/" target="_blank" class="cursor">quill3</a>. </p><br>' #ロゴ print '<div align=center> <img src="logo.gif" alt="RetroTube"> <br><br>' #検索フォーム print '<form action="search.cgi" method="GET"> <select name="year">' for i in 1976..2004 print '<option>' + i.to_s + '</option>' end print '</select> 年の <select name="category"> <option value="music">邦楽</option> <option value="anime">アニメ</option> <option value="movie_j">邦画</option> <option value="movie_a">洋画</option> </select> を <input type="submit" value="YouTube検索"> </form>' print '</div><br><br>' #新着動画 print '<h4>新着動画 <a href="http://rssicon20.com/rss.php?u=http%3A%2F%2Fwww.retro-tube.com%2F&s=1"> <img src="rsslogo.gif" alt="RSS" title="RSS" align="absmiddle" border="0" style="margin-left:5px"></a></h4>' csv = CSV.open('compare.csv', 'r') csv.each { |line| print '<div class="video" ><p><a href="detail.cgi?movieid=' + line[3] + '&category=' + line[6] + '" target="_blank"><img src="' + line[4] + '" alt="' + line[2] + ' - ' + line[1] + '" title="' + line[2] + ' - ' + line[1] + '" class="video-thumbnail"/></a></p> <p><a href="detail.cgi?movieid=' + line[3] + '&category=' + line[6] + '" target="_blank" class="cursor">' + line[2] + '</a></p> <p><a href="detail.cgi?movieid=' + line[3] + '&category=' + line[6] + '" target="_blank" class="cursor">' + line[1] + '</a></p> </div>' } #Google Analytics print '<script src="http://www.google-analytics.com/urchin.js" type="text/javascript"></script> <script type="text/javascript">_uacct = "UA-568420-2";urchinTracker();</script>' print '</body></html>'
【リスト7】search.cgi
#!/usr/local/bin/ruby print "Content-type: text/html\n\n" ##################################### #【RetroTube】検索結果一覧表示プログラム ##################################### require "cgi-lib" require "kconv" require "csv" #他ページからの入力パラメータ(年代とカテゴリ) input = CGI.new inputyear = input["year"] inputcategory = input["category"] #カテゴリ表示用クラス class ShowCategory def initialize(parm_category) @categorytable = [["music","邦楽"], ["anime","アニメ"], ["movie_j","邦画"], ["movie_a","洋画"]] @categorytable.each { |elem| if parm_category == elem[0] @category = elem[1] break end } end def show print @category end def select @categorytable.each { |elem| print '<option' if @category == elem[1] print ' selected="selected"' end print ' value="' + elem[0] + '">' + elem[1] + '</option>' } end end show_category = ShowCategory.new(inputcategory) #ここからHTML生成 #HTMLヘッダ print '<html><head> <title>RetroTube : ' + inputyear + '年の' show_category.show print '</title> <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> <meta http-equiv="Content-Style-Type" content="text/css"> <link rel="stylesheet" type="text/css" href="basic.css"> </head><body>' #ロゴ print '<a href="http://www.retro-tube.com/"> <img src="logo.gif" alt="RetroTube" width=250 border="0"></a>' #検索フォーム print '<form action="search.cgi" method="GET"> <select name="year">' for i in 1976..2004 if i.to_s == inputyear print '<option selected="selected">' + inputyear + '</option>' else print '<option>' + i.to_s + '</option>' end end print '</select> 年の <select name="category">' show_category.select print '</select> を <input type="submit" value="YouTube検索"> </form>' #前後の年代へのリンク print '<div align=right>' beforeyear = inputyear.to_i - 1 nextyear = inputyear.to_i + 1 if beforeyear >= 1976 print '<a href="search.cgi?year=' + beforeyear.to_s + '&category=' + inputcategory + '">' print '<' + beforeyear.to_s + '年</a> ' end if nextyear <= 2004 print '<a href="search.cgi?year=' + nextyear.to_s + '&category=' + inputcategory + '">' print nextyear.to_s + '年></a>' end print '</div>' #検索結果動画一覧 print '<h3>' + inputyear + '年の' show_category.show print '<a href="remo.cgi?year=' + inputyear + '&category=' + inputcategory + '" target="_blank"><img src="show_rimo.gif"' print ' alt="Rimo" title="Rimo" align="absmiddle" height="25" border="0" style="margin-left:10px"></a>' print '</h3>' csv = CSV.open(inputcategory + '.csv', 'r') csv.each { |line| if line[0] == inputyear print '<div class="video" ><p><a href="detail.cgi?movieid=' + line[3] + '&category=' + inputcategory + '" target="_blank"><img src="' + line[4] + '" alt="' + line[2] + ' - ' + line[1] + '" title="' + line[2] + ' - ' + line[1] +'" class="video-thumbnail"/></a></p>' print '<p><a href="detail.cgi?movieid=' + line[3] + '&category=' + inputcategory + '" target="_blank" class="cursor">' + line [2] #アニメだけはOPとEDの区別を表示する(特殊ロジック) if inputcategory == "anime" if line[6] != "NA" print ' ' + line[6] end end #ここまで特殊ロジック print '</a></p>' print '<p><a href="detail.cgi?movieid=' + line[3] + '&category=' + inputcategory + '" target="_blank" class="cursor">' + line [1] + '</a></p>' print '</div>' end } #開発者 print '<p class="footer"><br>This service is created by <a href="http://d.hatena.ne.jp/quill3/" target="_blank" class="cursor">quill3</a>.</p>' #Google Analytics print '<script src="http://www.google-analytics.com/urchin.js" type="text/javascript"></script> <script type="text/javascript">_uacct = "UA-568420-2";urchinTracker();</script>' print '</body></html>'
【リスト8】detail.cgi
#!/usr/local/bin/ruby print "Content-type: text/html\n\n" ##################################### #【RetroTube】検索結果詳細表示プログラム ##################################### require "cgi-lib" require "kconv" require "csv" require "net/http" ##AmazonAPIアクセス用ライブラリ require "amazon/search" include Amazon::Search assoc_id = "retr-22" dev_token = "0Z2TJZWAYA1T2ZNW4482" #他ページからの入力パラメータ(動画IDとカテゴリ) input = CGI.new inputmovieid = input["movieid"] inputcategory = input["category"] #動画IDとカテゴリを使用して、検索結果一覧から対象動画を引き当てる csv = CSV.open(inputcategory + '.csv', 'r') csv.each { |line| if line[3] == inputmovieid $tyear = line[0] $tartist = line[1] $ttitle = line[2] $tmovieid = line[3] if inputcategory == "anime" if line[6] == "NA" $show_title = line[2] else $show_title = line[2] + " " + line[6] end else $show_title = line[2] end break end } #ここからHTML生成 #HTMLヘッダ print '<html><head> <title>RetroTube : [' case inputcategory when "music" print '邦楽' when "anime" print 'アニメ' when "movie_j" print '邦画' when "movie_a" print '洋画' end print '] ' + $show_title + ' - ' + $tartist + ' (' + $tyear +')' print '</title> <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> <meta http-equiv="Content-Style-Type" content="text/css"> <link rel="stylesheet" type="text/css" href="basic.css"> </head><body>' #ロゴ print '<a href="http://www.retro-tube.com/"> <img src="logo.gif" alt="RetroTube" width=250 border="0"></a>' #大見出し print'<h3>' + $show_title + ' - ' + $tartist + ' (' + $tyear + ')</h3>' #対象動画を埋め込みで表示 print'<div class="movieinfo"> <object width="425" height="350"> <param name="movie" value="http://www.youtube.com/v/' + $tmovieid + '"></param> <param name="wmode" value="transparent"></param> <embed src="http://www.youtube.com/v/' + $tmovieid + '" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"></embed> </object> </div>' #Wikipedia情報の表示(simpleAPIを使用して情報取得) address = "wikipedia.simpleapi.net" case inputcategory when "music" path = "/api?keyword=" + Kconv.toutf8($tartist) + "&output=html" when "anime","movie_j","movie_a" path = "/api?keyword=" + Kconv.toutf8($ttitle) + "&output=html" end convpath = path.gsub(' ','%20') body = Net::HTTP.get( address , convpath ) sjisbody = Kconv.tosjis(body) convbody = sjisbody.gsub('Wikipedia:<a href=','Wikipedia:<a target="_blank" href=') print '<div class="wikiinfo">' + convbody + '</div>' #Amazon広告の表示(AmazonAPIアクセス用ライブラリ使用) request = Request.new(dev_token, assoc_id, "jp", false) print '<br><br><div class="amazonad">' case inputcategory when "music" k = 1 request.artist_search(Kconv.toutf8($tartist),"music",HEAVY) do |product| j = 1 product.artists.each { |temp| if temp.upcase == Kconv.toutf8($tartist).upcase print '<div class="adspace">' print '<a href="' + product.url + '" target="_blank"> <img src="' + product.image_url_medium + '" alt="thumbnail" style="float:left; margin: 0 15px 10px 10px; padding: 0;border:none;"> </a>' print '<dl style="margin-bottom:0.5em; text-align:left; min-height: 168px;font-size:12px;line-height:16px;">' print '<dt><a href="' + product.url + '" target="_blank">' + Kconv.tosjis(product.product_name) + '</a></dt>' print '<dd>' i = 1 product.artists.each { |temp2| print Kconv.tosjis(temp2) + ' ' i += 1 if i > 3 #表示するアーティストの数 break end } print '</dd>' print '<dd>' + Kconv.tosjis(product.manufacturer) + ' ' + Kconv.tosjis(product.release_date) + '</dd><br>' if product.our_price != nil print '<dd>価格 : <strong>' + Kconv.tosjis(product.our_price) + '</strong></dd>' end print '<dd>(' + Kconv.tosjis(product.availability) + ')</dd><br>' print '<dd><a href="' + product.url + '" target="_blank">Ads by Amazon.co.jp</a></dd>' print '</dl></div>' k += 1 break end j += 1 if j > 3 #検索精度(この数字が少ないほど精度が高い) break end } if k > 2 #表示する商品の数 break end end when "anime","movie_j","movie_a" begin j = 1 if inputcategory == "anime" searchword = Kconv.toutf8($ttitle) else searchword = Kconv.toutf8($ttitle) + " " + Kconv.toutf8($tartist) end request.keyword_search(searchword,"dvd",HEAVY) do |product| print '<div class="adspace">' if product.image_url_medium != nil print '<a href="' + product.url + '" target="_blank"> <img src="' + product.image_url_medium + '" alt="thumbnail" style="float:left; margin: 0 15px 10px 10px; padding: 0;border:none;"> </a>' end print '<dl style="margin-bottom:0.5em; text-align:left; min-height: 168px;font-size:12px;line-height:16px;">' print '<dt><a href="' + product.url + '" target="_blank">' + Kconv.tosjis(product.product_name) + '</a></dt>' print '<dd>' i = 1 if product.starring != nil product.starring.each { |temp2| print Kconv.tosjis(temp2) + ' ' i += 1 if i > 3 #表示する出演者の数 break end } end print '</dd>' print '<dd>' + Kconv.tosjis(product.manufacturer) + ' ' + Kconv.tosjis(product.release_date) + '</dd><br>' if product.our_price != nil print '<dd>価格 : <strong>' + Kconv.tosjis(product.our_price) + '</strong></dd>' end print '<dd>(' + Kconv.tosjis(product.availability) + ')</dd><br>' print '<dd><a href="' + product.url + '" target="_blank">Ads by Amazon.co.jp</a></dd>' print '</dl></div>' j += 1 if j > 2 #表示する商品の数 break end end rescue end end print '</div>' #関連動画表示 case inputcategory when "music" print '<h4>' + $tartist + 'の曲一覧</h4>' when "anime" print '<h4>' + $tartist + ' 製作アニメ一覧</h4>' when "movie_j","movie_a" print '<h4>' + $tartist + ' 監督作品一覧</h4>' end scsv = CSV.open(inputcategory + '.csv', 'r') scsv.each { |sline| if $tartist == sline[1] print '<div class="video" >' print '<p><a href="detail.cgi?movieid=' + sline[3] + '&category=' + inputcategory + '" > <img src="' + sline[4] + '" alt="' + sline[1] + ' - ' + sline[2] + '" title="' + sline[1] + ' - ' + sline[2] +'" class="video-thumbnail"/></a></p>' print '<p><a href="detail.cgi?movieid=' + sline[3] + '&category=' + inputcategory + '" class="cursor">' + sline[2] if inputcategory == "anime" if sline[6] != "NA" print ' ' + sline[6] end end print '</a></p>' print '<p><a href="detail.cgi?movieid=' + sline[3] + '&category=' + inputcategory + '" class="cursor">' + sline[0] + '</a></p>' print '</div>' end } #開発者 print '<p class="footer"><br>This service is created by <a href="http://d.hatena.ne.jp/quill3/" target="_blank" class="cursor">quill3</a>.</p>' #Google Analytics print '<script src="http://www.google-analytics.com/urchin.js" type="text/javascript"></script> <script type="text/javascript">_uacct = "UA-568420-2";urchinTracker();</script>' print '</body></html>'
【リスト9】remo.cgi
#!/usr/local/bin/ruby ##################################### #【RetroTube】Rimo動画連続再生リクエスト用プログラム ##################################### require "cgi-lib" require "net/http" #他ページからの入力パラメータ(年代とカテゴリ) input = CGI.new inputyear = input["year"] inputcategory = input["category"] #RimoAPIコール(Rimoへ動画一覧を渡し、連続再生をリクエストする) remoch_url = 'http%3A%2F%2Fwww.retro-tube.com%2Fremoch.cgi%3Fyear%3D' + inputyear + '%26category%3D' + inputcategory address = "rimo.tv" path = "/channel/xml?url=" + remoch_url body = Net::HTTP.get( address , path ) #Rimoの動画連続再生ページへリダイレクト remoch_url = "http://www.retro-tube.com/remoch.cgi?year=" + inputyear + "&category=" + inputcategory print "Location: http://rimo.tv/#/channel?url=" + remoch_url + "\n\n"
【リスト10】remoch.cgi
#!/usr/local/bin/ruby print "Content-type: text/html\n\n" ##################################### #【RetroTube】Rimoリクエスト用動画一覧生成プログラム ##################################### require "cgi-lib" require "csv" #他ページからの入力パラメータ(年代とカテゴリ) input = CGI.new inputyear = input["year"] inputcategory = input["category"] #ここからHTML生成 #HTMLヘッダ print '<html><head><title>RetroTube : ' + inputyear + '年の' case inputcategory when "music" print '邦楽' when "anime" print 'アニメ' when "movie_j" print '邦画' when "movie_a" print '洋画' end print '</title><meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"></head><body>' #ロゴ print '<a href="http://www.retro-tube.com/"><img src="logo.gif" alt="RetroTube" width=250 border="0"></a>' #連続再生対象動画の一覧を生成 csv = CSV.open(inputcategory + '.csv', 'r') csv.each { |line| if line[0] == inputyear print '<br><a href="http://www.youtube.com/watch?v=' + line[3] + '">' + line[2] + '</a>' end } print '</body></html>'