misc/plugin/amazon.rb in tdiary-5.0.0 vs misc/plugin/amazon.rb in tdiary-5.0.1

- old
+ new

@@ -48,10 +48,31 @@ add_js_setting( '$tDiary.plugin.bitly.apiKey', "'#{@conf['bitly.key']}'" ) end class AmazonRedirectError < StandardError; end +class AmazonItem + def initialize(xml, parser = :rexml) + @parser = parser + if parser == :oga + doc = Oga.parse_xml(xml) + @item = doc.xpath('*/*/Item')[0] + else + doc = REXML::Document::new( REXML::Source::new( xml ) ).root + @item = doc.elements.to_a( '*/Item' )[0] + end + end + + def nodes(path) + if @parser == :oga + @item.xpath(path) + else + @item.elements.to_a(path) + end + end +end + def amazon_fetch( url, limit = 10 ) raise ArgumentError, 'HTTP redirect too deep' if limit == 0 px_host, px_port = (@conf['proxy'] || '').split( /:/ ) px_port = 80 if px_host and !px_port @@ -98,37 +119,41 @@ def amazon_author( item ) begin author = [] %w(Author Creator Artist).each do |elem| - item.elements.each( "*/#{elem}" ) do |a| + item.nodes( "*/#{elem}" ).each do |a| author << a.text end end @conf.to_native( author.uniq.join( '/' ), 'utf-8' ) rescue '-' end end def amazon_title( item ) - @conf.to_native( item.elements.to_a( '*/Title' )[0].text, 'utf-8' ) + @conf.to_native( item.nodes( '*/Title' )[0].text, 'utf-8' ) end def amazon_image( item ) image = {} begin size = case @conf['amazon.imgsize'] when 0; 'Large' when 2; 'Small' else; 'Medium' end - img = item.elements.to_a("#{size}Image")[0] || item.elements.to_a("ImageSets/ImageSet/#{size}Image")[0] - image[:src] = img.elements['URL'].text + if item.nodes("#{size}Image")[0] + node_prefix = "#{size}Image" + elsif item.nodes("ImageSets/ImageSet/#{size}Image")[0] + node_prefix = "ImageSets/ImageSet/#{size}Image" + end + image[:src] = item.nodes("#{node_prefix}/URL")[0].text image[:src].gsub!(/http:\/\/ecx\.images-amazon\.com/, 'https://images-na.ssl-images-amazon.com') - image[:height] = img.elements['Height'].text - image[:width] = img.elements['Width'].text + image[:height] = item.nodes("#{node_prefix}/Height")[0].text + image[:width] = item.nodes("#{node_prefix}/Width")[0].text rescue base = @conf['amazon.default_image_base'] || 'http://www.tdiary.org/images/amazondefaults/' case @conf['amazon.imgsize'] when 0 image[:src] = "#{base}large.png" @@ -146,27 +171,27 @@ end image end def amazon_url( item ) - item.elements.to_a( 'DetailPageURL' )[0].text + item.nodes( 'DetailPageURL' )[0].text end def amazon_label( item ) begin - @conf.to_native( item.elements.to_a( '*/Label' )[0].text, 'utf-8' ) + @conf.to_native( item.nodes( '*/Label' )[0].text, 'utf-8' ) rescue '-' end end def amazon_price( item ) begin - @conf.to_native( item.elements.to_a( '*/LowestNewPrice/FormattedPrice' )[0].text, 'utf-8' ) + @conf.to_native( item.nodes( '*/LowestNewPrice/FormattedPrice' )[0].text, 'utf-8' ) rescue begin - @conf.to_native( item.elements.to_a( '*/ListPrice/FormattedPrice' )[0].text, 'utf-8' ) + @conf.to_native( item.nodes( '*/ListPrice/FormattedPrice' )[0].text, 'utf-8' ) rescue '(no price)' end end end @@ -245,12 +270,12 @@ xml = File::read( "#{cache}/#{country}#{asin}.xml" ) rescue Errno::ENOENT xml = amazon_call_ecs( asin, id_type, country ) File::open( "#{cache}/#{country}#{asin}.xml", 'wb' ) {|f| f.write( xml )} end - doc = REXML::Document::new( REXML::Source::new( xml ) ).root - item = doc.elements.to_a( '*/Item' )[0] + parser = defined?(Oga) ? :oga : :rexml + item = AmazonItem.new(xml, parser) if pos == 'detail' then amazon_detail_html( item ) else amazon_to_html( item, with_image, label, pos ) end @@ -263,10 +288,10 @@ message rescue NoMethodError message = label || asin if @mode == 'preview' then if item == nil then - m = doc.elements.to_a( 'Items/Request/Errors/Error/Message' )[0].text + m = item.nodes( 'Items/Request/Errors/Error/Message' )[0].text message << %Q|<span class="message">(#{h @conf.to_native( m, 'utf-8' )})</span>| else message << %Q|<span class="message">(#{h $!}\n#{h $@.join( ' / ' )})</span>| end end