Amazondvdver='$Id: amazondvd.rb,v 2.21 2004-01-06 23:58:35+09 waka Exp $'.split(" ")[2] # http://www.double-red.net/ =begin (@DVD:BCBA-0618) (@CD:AMCY-7125) みたいな (@DVD:背表紙にある記号) (@CD:背表紙にある記号) という形式の文字列があると amazon からDVD,CDの情報やらジャケット画像やらを引っ張ってきて置き換えます。 他にも以下のハード・ソフトに対応しています。 ・対応ハード・ソフト 書式 ・PlayStation (@PS:背表紙にある記号) ・PlayStation2 (@PS2:背表紙にある記号) ・GAMECUBE (@GC:背表紙にある記号) ・Xbox (@XBOX:背表紙にある記号) 上記の方法で取得できない場合もままあります。 その時はあらかじめAmazonでASINを調べておいて以下のように 記述する方法があります。こちらが確実です。 (@ASIN:ASIN) @@仕様---------------------------------------------------------- 1行に1つずつ記述 連続して記述する際は空行をいれる(when :AFTER_Pなため) @@キャッシュディレクトリ設定------------------------------------ ndiary.conf の LOG_DIRECTORY で指定したディレクトリに amzcacheDVD というディレクトリを作っておくと取得したデータをキャッシュしておくようになります。 キャッシュの有効期限もスクリプト内で指定しているので必要に応じて変更してください。 @@キャッシュ保持期間-------------------------------------------- キャッシュの有効期限を指定できます。 ndiary.conf にて 変数AMAZON_CACHE_EXPIREに日数(正の整数)を指定してください。 (0は無期限) (例) AMAZON_CACHE_EXPIRE = '30' @@プロキシ設定-------------------------------------------------- ndiary.conf で PROXY = 'proxy.hoge.com:8080' と指定しておくと、情報取得時プロクシを経由するようになります。 @@その他の設定-------------------------------------------------- ndiary.conf にて以下の変数が使用できます(必須ではない) * BOOKSTORE_AMAZON_ID(Amazonアソシエイトに参加している場合に有効) (例) BOOKSTORE_AMAZON_ID = 'hogehoge-foo' * NO_IMAGE_FILE ・ジャケット画像がない場合に代替に表示する画像(imgタグで表記) (例) NO_IMAGE_FILE='no image' @@ Special Thanx------------------------------------------------ == amazondvd.rb は以下の方の助力、影響、恩恵を受けています == - not (のとや) さん -- http://www14.cds.ne.jp/~not/ -- nDiary本体とamazon.rbの作者 -- amazon.rb のソースに少し変更を加えたものが amazondvd.rb - mas さん -- http://home3.highway.ne.jp/mas/ -- バグ報告や動作確認、Amazonアソシエイト対応など - Ace of Diamond さん -- http://every.pobox.ne.jp/ -- Amazonアソシエイト対応コード不具合パッチなど @@ 注意事項------------------------------------------------------ 著作権がらみの情報を取得するため、 www.amazon.co.jpのアソシエイトプログラムを確認の上自己責任でご利用下さい。 =end class Module def attr_my_accessordvd( name ) module_eval %{ def #{name.id2name}() get_dvddata @#{name.id2name} end } end end class Amazondvd require 'net/http' attr_accessor :dvdid attr_accessor :cddvdps2 attr_accessor :skey attr_my_accessordvd :title attr_my_accessordvd :actor attr_my_accessordvd :maker attr_my_accessordvd :director attr_my_accessordvd :size attr_my_accessordvd :pubdate attr_my_accessordvd :price attr_my_accessordvd :desc attr_my_accessordvd :writer attr_my_accessordvd :image_url attr_my_accessordvd :imageL_url attr_my_accessordvd :image_width attr_my_accessordvd :image_height attr_my_accessordvd :media attr_my_accessordvd :site attr_my_accessordvd :time attr_my_accessordvd :voice attr_my_accessordvd :voice_spec attr_my_accessordvd :caption attr_my_accessordvd :stand_in attr_my_accessordvd :screen_size attr_my_accessordvd :pc_spec attr_reader :cache_dir attr_accessor :expire attr_accessor :proxy def initialize @expire = 0 # 0だと存在するキャッシュを必ず使用 @proxy = nil @flag = false end def load_cache if @flag or (File::directory?(@cache_dir.to_s) and File::readable?(@cache_dir + @dvdid) and File::mtime(@cache_dir + @dvdid).to_i < Time::now.to_i - 3600 * 24 * @expire and @expire != 0) then return end @flag = true read_cache end def read_cache begin open(@cache_dir + @dvdid){ |f| @title, @actor, @maker, @size, @pubdate, @price, @desc, @writer, @image_url,@image_width, @image_height, @media, @director, @site, @cddvdps2, @imageL_url, @time, @voice, @voice_spec, @caption, @stand_in, @screen_size, @pc_spec = f.read.split(/\t/) } rescue puts @cache_dir + @dvdid @flag = nil end end def save_cache return unless File::directory?(@cache_dir.to_s) begin open(@cache_dir + @dvdid, 'w'){ |f| f.write [ @title, @actor, @maker,@size, @pubdate, @price, @desc, @writer, @image_url,@image_width, @image_height, @media, @director, @site, @cddvdps2, @imageL_url, @time, @voice, @voice_spec, @caption, @stand_in, @screen_size, @pc_spec ].join("\t") } rescue # end end def httpconnect(str) if @proxy then proxy, port = @proxy.split(':') port = port.to_i else proxy = port = nil end Net::HTTP::Proxy(proxy, port).new( str.to_s, 80 ) end def cache_dir=(dir) dir << '/' unless dir[-1,1] == '/' @cache_dir = dir end def media_get(str) featured_system="プラットフォーム:.*?\n \n(.*?)\n
|sm =~ str then @media = @media + "(#{$1})" end end #エレクトロニクスカテゴリー取得(未完成) if /商品/ =~ @media then if %r!同じ種類の商品を探す(.*)!smi =~ str then media_scope = $1 # if %r!
  • (.+?)
  • !smi =~ media_scope then # media_scope = $1 #なぜかこうしないとスコープがしぼれない…… # end end if %r!カテゴリー別.+?(.+?)!smi =~ media_scope then @media = $1.delete("\n") end end return @media end def response_get(path,url) http = httpconnect(url) a, = http.get2(path) httpurl = 'http://' + url if a.code == '302' then path = a.header['location'].sub(Regexp.new(httpurl), "") a, = http.get2(path) end return(a) end def asin_phase #path = "/exec/obidos/ASIN/#{dvdid}" path = "/exec/obidos/ASIN/#{dvdid}/250-0959300-8075455?val=authorized" url = "www.amazon.co.jp" response_get(path,url) end def dvd_phase path = "/exec/obidos/search-handle-url/index=dvd-jp%26field-keywords=#{dvdid}" url = "www.amazon.co.jp" response_get(path,url) end def cd_phase path = "/exec/obidos/search-handle-url/index=music-jp%26field-keywords=#{dvdid}" url = "www.amazon.co.jp" response_get(path,url) end def blend_phase path = "/exec/obidos/search-handle-url/index=blended%26field-keywords=#{dvdid}" url = "www.amazon.co.jp" response_get(path,url) end def playstation_phase path = "/php/item/#{dvdid}" url = "www.jp.playstation.com" response , = response_get(path,url) if %r|(\w+)| =~ response.body then keyword_trade = $1 if %r|発売日\n([\d\/]+[\d])|s =~ response.body then keyword_date = $1 end keyword = "イメージを拡大" + " " + keyword_date.to_s + " " + keyword_trade.to_s + " playstation" else keyword = "" end return(keyword) end =begin def hmv_phase url = "hmv.co.jp" path = "/search/title.asp?keyword=#{dvdid}&category=CATALOGUENO" response , = response_get(path,url) if %r|([^<]+)| =~ response.body then path = 'http://' + url + $1 keyword_trade = $2 if %r| %20 ; '?' ===> %3f ; '+' ===> %2b ; '%' ===> %25 # '&' ===> %26 ; '=' ===> %3d ; '/' ===> %2f ; ':' ===> %3a url = "www.google.com" path = "/search%3fhl=ja%26inlang=ja%26ie=Shift_JIS%26q=site%3Awww.amazon.co.jp%2b#{skey}" response , = response_get(path,url) if %r|.+]+)>Amazon.co.jp:| =~ response.body then path2 = $1 return(path2) end end def dvd_spec return end def get_dvddata load_cache return if @flag dvdid = @dvdid s = @skey cddvdps2 = @cddvdps2 if cddvdps2 == 'ASIN' then response , = asin_phase path2 = "/exec/obidos/ASIN/#{dvdid}" else response , = blend_phase if %r|^
  • \n" @title << "" @title << "" @title << "" @title << "" @title << "" # @title = "#{keyword_trade}" =end end end if path2.to_s.empty? then @title = "Not Found #{dvdid}" save_cache return if @title else if got_data != "true" then url = "www.amazon.co.jp" http = httpconnect(url) response , = response_get(path2,url) end end end path = path2 def getFileStream(url, proxy) if /^http/ =~ url #return if @diary.config['nonet'] $stderr.puts "CHK; access; #{url}" require 'net/http' domain, port = "", "" if /\/\/(.+?)(?:\/|$)/ =~ url domain = $1.to_s end protocol = url.split(":").first + "://" path = url.gsub(Regexp.new(protocol + domain),"") if proxy proxy, port = proxy.split(':') port = port.to_i else proxy = port = nil end begin http = Net::HTTP::Proxy(proxy, port).new(domain, 80) if /1\.6/ =~ RUBY_VERSION file_info, = http.get2(path) else file_info = http.get(path) end if file_info.code == '302' path = file_info.header['location'].sub(Regexp.new(url), "") file_info = http.get(path) end return(file_info.response.body) rescue return $! end else open(url, "rb").read end end if %r|(^(?:)?.*(?:)?
    .*注文した商品はどこ[??])|sm =~ response.body then image_scope = $1 end #-------------------------------------------------- # DVD Spec #-------------------------------------------------- if %r|
    仕様について| =~ response.body then path3=$1 url = "www.amazon.co.jp" http = httpconnect(url) response_spec , = response_get(path3,url) if %r|時間:([^<]+)<| =~ response_spec.body then @time = $1 end if %r|音声仕様:([^<]+)<| =~ response_spec.body then @voice_spec = $1 end if %r|音声:([^<]+)<| =~ response_spec.body then @voice = $1 end if %r|字幕:([^<]+)<| =~ response_spec.body then @caption = $1 end if %r|吹き替え:([^<]+)<| =~ response_spec.body then @stand_in = $1 end if %r|画面サイズ:([^<]+)<| =~ response_spec.body then @screen_size = $1 end if %r|発売日:([^<]+)<| =~ response_spec.body then @pubdate = $1 end if %r|販売元:(.+?)<| =~ response_spec.body then @maker = $1 end end #-------------------------------------------------- # PC/エレクトロニクス Spec #-------------------------------------------------- #if %r|(?:製品概要・)?仕様[::](.*?)|m =~ response.body then # @pc_spec = $1.gsub(/\n/,"").gsub(/(<\/?font.*?>|<\/?span.+?>||.+?<\/a>)/,"") #end # エレクトロニクスのスペックがうるさいなら上のコメントをはずして # ここから if %r|]+?)"?>詳しい情報を見る|m =~ image_scope then path3 = $1 url = "http://www.amazon.co.jp" + path3.to_s response_spec = getFileStream(url,@proxy) if %r!製品概要・仕様:(.*)!m =~ response_spec @pc_spec = $1.gsub(/\n/,"").gsub(/(<\/?font.*?>|<\/?span.+?>)/,"") end end # エレクトロニクスのスペックがうるさいならここまでをコメントにする #-------------------------------------------------- # Title #-------------------------------------------------- if %r|^Amazon.co.jp:(?:[^:]+:)?(.+?)$| =~ response.body then title_str = $1.strip.gsub(/( +)?<\/title>/,"") @title = "#{title_str}" end if @title.to_s.empty? then @title = "Not Found #{dvdid}" save_cache return if @title end #-------------------------------------------------- # Image #-------------------------------------------------- # if %r|(^(?:)?.*(?:)?
    .*レビューを書)|m =~ response.body then # if %r|(^(?:)?.*(?:)?
    .*同じテーマの)|sm =~ response.body then if %r|.+(?:[^<]+)?)| =~ response.body then maker0 = $1.gsub(%r|  |, ' / ') else if %r!()! =~ image_scope then @maker = $1 end if @maker.nil? then if %r|([^>]+) +- +ASIN[::]| =~ image_scope then @maker = $1 end end end end #-------------------------------------------------- # Price #-------------------------------------------------- if %r|定価:
    \n.+?[^¥]+(¥[\d,]+)|m =~ image_scope then @price = $1 end # 定価表示ではなく価格のみ表示の場合 if @price.nil? then if %r|価格:[^¥]+(¥[\d,]+)| =~ image_scope then @price = $1 elsif %r|(¥[\d,]+)
    | =~ image_scope then @price = $1 end end #-------------------------------------------------- # Actor #-------------------------------------------------- if %r|出演: (.*)| =~ response.body then @actor = $1 end #-------------------------------------------------- # Director #-------------------------------------------------- if %r|監督: (.*)| =~ response.body then @director = $1 end #-------------------------------------------------- # Description #-------------------------------------------------- if %r'
    レビュー
    (.*)'mis =~ response.body then review_scope = $1 end # 何種類かあるみたい… if %r"(出版社/著者からの内容紹介|メーカーより|作品内容|内容(「.+?」データベースより))
    +
    +
    +(.+?) *<[pP]>"s =~ review_scope then @writer =$1 @desc = $2 end if %r!(出版社/著者からの内容紹介|商品紹介|メーカーより|作品内容|内容(「.+?」データベースより))

    \n+(.+?)(?:

    ...)?
    !mis =~ review_scope then @writer =$1 @desc = $2 end if @writer.to_s.empty? and @desc.to_s.empty? then if %r"(メーカーより|作品内容|内容紹介|出版社/著者からの内容紹介|内容(「.+?」データベースより))

    +(.*)

    (?:.*

    )+"s =~ review_scope.to_s.gsub(/\n/,'') then @writer =$1 @desc = $2 end end if @writer.to_s.empty? and @desc.to_s.empty? then if %r"(作品内容|内容(「.+?」データベースより))
    \n(.*?)"mis =~ review_scope then @writer =$1 @desc = $2 end end if @writer.to_s.empty? and @desc.to_s.empty? then if %r|(製品概要)[::](.*?)|mi =~ review_scope then @writer = $1 @desc = $2 end end #-------------------------------------------------- # Published Date #-------------------------------------------------- #(2002/05/24)
    :DVD,CD #発売日:2002/03/28
    :PS2 if %r"(?:発売日[::]|\()([\d\/]+[\d])\)?
    " =~ response.body then @pubdate = $1 elsif %r|\((\d{4}\/[\d\/]+)\)| =~ response.body then @pubdate = $1 end #-------------------------------------------------- # Size(ディスク枚数) #-------------------------------------------------- if %r"(?:)?ディスク枚数:(?:)?(.+)
    " =~ response.body then @size = $1 end #-------------------------------------------------- # CD,DVD or PS2? #-------------------------------------------------- if %r|この(\w+)に\w+レビューを書|s =~ response.body then @media = $1 if @media =~ /商品/ then media_get(response.body) end else media_get(response.body) end if @title.nil? then read_cache else save_cache @flag = true end end end class Filter def add_title(str) d = Array.new str.split(",").each{|i| if i =~ /href/ then a = i.gsub(/\/exec/,"http:\/\/www.amazon.co.jp\/exec") b = a.scan(/>(.+?)/)[0]} title=\"#{b}の作品\">#{b}#{a.scan(/(\(.+?\))/)[0].to_s}" else c = i end d << c } return d.join(",") end def amazondvd(str, type) tagend = (@diary.isXHTML ? ' />' : '>') tag_br = "No Image" if @diary.respond_to?('config') then proxy = @diary.config['PROXY'] amazon_id = @diary.config['BOOKSTORE_AMAZON_ID'].to_s expire = @diary.config['AMAZON_CACHE_EXPIRE'].to_s no_img = @diary.config['NO_IMAGE_FILE'].to_s unless @diary.config['NO_IMAGE_FILE'].to_s.empty? media_icon = @diary.config['AMAZON_MEDIA_ICON'] end begin case type when :AFTER_P str.gsub!(/[\((][@@](CD|DVD|PS|PS2|GC|XBOX|GBA|ASIN)[::](.+)[\))]<\/p>/mi){ cddvdps2 = $1 unless cddvdps2.to_s == 'ASIN' then tmp = $2.gsub(/^([A-Za-z]+)(\d+)$/, "\\1-\\2") dvdid = tmp.gsub(/#.*/,"") skey = tmp.gsub(/.*#/,"") else dvdid = $2 skey = "" end amzdvd = Amazondvd::new amzdvd.cache_dir = @diary.logDirectory + 'amzcacheDVD' amzdvd.dvdid = dvdid amzdvd.cddvdps2 = cddvdps2 amzdvd.skey = skey amzdvd.proxy = proxy # キャッシュの有効日数 #amzdvd.expire = 0 # キャッシュの有効日数 if expire.empty? then amzdvd.expire = 0 else amzdvd.expire = expire.to_i end title = body = img = desc = media = maker = actor = director = size = writer = desc = site = largeimage = asin = titlewithasin = pubdate = price = date_price_size = time = voice_spec = voice = caption = stand_in = screen_size = pc_spec = '' title = "『#{amzdvd.title}』" unless amzdvd.title.to_s.empty? unless amzdvd.title.nil? if amzdvd.title =~ /Not Found/ then print @diary.date.to_s print "\tamazondvd error.#{amzdvd.title}\n" break end if amazon_id.empty? then title = "『#{amzdvd.title}』" unless amzdvd.title.to_s.empty? else if cddvdps2 == 'ASIN' then title_with_id = "#{amzdvd.title.gsub(/#{dvdid}/,"#{dvdid}/ref=ase_#{amazon_id}/")}" title = "『#{title_with_id.scan(/(]+)>/)[0]} title=\"この商品について\">#{title_with_id.scan(/(.*)<\/a>/)[0]}』" unless title_with_id.to_s.empty? else title_with_id = "#{amzdvd.title.gsub(/\/ref[^\">]+/,"/ref=ase_#{amazon_id}/")}" # if amzdvd.site =~ /hmv/ then # title = title_with_id # else title = "『#{title_with_id.scan(/(]+)>/)[0]} title=\"この商品について\">#{title_with_id.scan(/(.*)<\/a>/)[0]}』" unless title_with_id.to_s.empty? # end end end unless amzdvd.image_url.to_s.empty? then unless amzdvd.imageL_url.to_s.empty? then largeimage = amzdvd.imageL_url img = "\"#{amzdvd.title.scan(/<a(.*)<\/a>/)[0]}\" class=\"amazonimg\"#{tagend}" else img = "\"#{amzdvd.title.scan(/<a(.*)<\/a>/)[0]}\" class=\"amazonimg\"#{tagend}" end else img = no_img end unless amzdvd.media.to_s.empty? media = "#{amzdvd.media}" title = title.gsub(/この商品/,"この#{media}") unless media.to_s.empty? xbox_icon="\"#{media}\"/,'\" title=\"この出演者の他の作品を見る\">')}" unless amzdvd.actor.to_s.empty? actor = "#{tag_br}出演者: " + add_title(amzdvd.actor) unless amzdvd.actor.to_s.empty? #director = "#{tag_br}監督: #{amzdvd.director.gsub(/\/exec/,"http:\/\/www.amazon.co.jp\/exec").gsub(/\">/,'\" title=\"この監督の他の作品を見る\">')}" unless amzdvd.director.to_s.empty? director = "#{tag_br}監督: " + add_title(amzdvd.director) unless amzdvd.director.to_s.empty? pubdate = "発売日: #{amzdvd.pubdate}" unless amzdvd.pubdate.to_s.empty? price = "価格: #{amzdvd.price.gsub(/¥/,'\\')}" unless amzdvd.price.to_s.empty? size = "枚数: #{amzdvd.size.gsub(/ /,'')}" unless amzdvd.size.to_s.empty? time = "時間: #{amzdvd.time}" unless amzdvd.time.to_s.empty? date_price_size_time = Array.new date_price_size_time << "#{pubdate}" unless pubdate.to_s.empty? date_price_size_time << "#{price}" unless price.to_s.empty? date_price_size_time << "#{size}" unless size.to_s.empty? date_price_size_time << "#{time}" unless time.to_s.empty? # date_price_size_time = tag_br + date_price_size_time.gsub(/(^,\ )|(,\ $)/,"") dpst = date_price_size_time.join(", ") desc = "#{tag_br}#{amzdvd.desc.gsub(/\/exec/,"http:\/\/www.amazon.co.jp\/exec")}" unless amzdvd.desc.to_s.empty? writer = "#{tag_br}#{tag_br}--#{amzdvd.writer}--" unless amzdvd.writer.to_s.empty? site ="#{tag_br}#{amzdvd.site}" unless amzdvd.site.to_s.empty? voice = "#{tag_br}音声: #{amzdvd.voice}" unless amzdvd.voice.to_s.empty? voice_spec = "#{tag_br}音声仕様: #{amzdvd.voice_spec}" unless amzdvd.voice_spec.to_s.empty? caption = "#{tag_br}字幕: #{amzdvd.caption}" unless amzdvd.caption.to_s.empty? stand_in = "#{tag_br}吹き替え: #{amzdvd.stand_in}" unless amzdvd.stand_in.to_s.empty? screen_size = "#{tag_br}画面サイズ: #{amzdvd.screen_size}" unless amzdvd.screen_size.to_s.empty? pc_spec = "#{tag_br}

    " unless amzdvd.pc_spec.to_s.empty? body = "
    \n" body << "\n" body << " \n" body << " \n" body << " \n" body << " \n" body << "
    \n" #body << " #{img}\n" body << " #{img.gsub(/(\ +)?<\/title>/,"")}" body << " \n" #body << " #{title}\n" body << " #{title.gsub(/(\ +)?<\/title>/,"")}" body << " #{media}#{tag_br}\n" body << " #{maker}\n" body << " #{actor}\n" body << " #{director}\n" #body << " #{pubdate}" #body << " #{price}" #body << " #{size}" #body << " #{date_price_size_time}\n" body << " #{tag_br}#{dpst}\n" body << " #{voice}\n" body << " #{voice_spec}\n" body << " #{caption}\n" body << " #{stand_in}\n" body << " #{screen_size}\n" body << " #{pc_spec}\n" body << " #{writer}\n" body << " #{desc}\n" body << " \n" body << " \n" #body << " #{site}\n" body << "
    \n" body << "
    \n" end body.gsub(/&field/,"%26field").gsub(/^ +\n/m,"") } end rescue puts "#{$!}" end end end =begin Local Variables: mode: ruby coding: sjis-dos End: =end