!#/usr/local/bin/ruby -Ku require 'rexml/document' require 'open-uri' require 'cgi' class HotpepperAPI API_KEY = 'guest' module Util def Util.to_query_string(request={}) query = [] request.each do |key,value| query << "#{key}=#{CGI.escape(value.to_s)}" end query_str = query.join("&") '?' << query_str end end class Base def initialize(options={}) @options = { :Count => 10, :key => API_KEY }.update options @result = {} @request = {} end def key=(key) @options[:key] = key end def count=(count) @options[:Count] = count end def order=(order) @options[:Order] = order end def api_uri 'http://api.hotpepper.jp/' end def uri(request={}) query=@options.dup.update request uri = "#{api_uri}" << Util.to_query_string(query) end def search(request={}) @request = request body = '' open(uri(request)) do |f| while line = f.gets body << line end end doc = REXML::Document.new(body).elements['Results'] @result = ResultSet.new(request) parse(doc,@result) end def parse(doc,result) end def uncamelise(str) str.gsub(/(.[a-z])(?=[A-Z])/, "\\1_\\2").downcase end private :uncamelise end class Gourmet < Base def api_uri 'http://api.hotpepper.jp/GourmetSearch/V1/' end def parse(doc,result) result.pager.number_of_results = doc.elements['NumberOfResults'].text.to_i result.pager.display_per_page = doc.elements['DisplayPerPage'].text.to_i result.pager.display_from = doc.elements['DisplayFrom'].text.to_i doc.elements.each('Shop') do |item| shop = Shop.new item.elements.each do |property| if property.has_elements? if property.name == 'PictureUrl' value = parse_picture_url property end else value = property.text end iv = uncamelise(property.name) shop.instance_variable_set("@#{iv}".to_sym, value) end result.items << shop end return result end def parse_picture_url(item) picture_url = PictureUrl.new item.elements.each do |property| if !property.has_elements? value = property.text iv = uncamelise(property.name) picture_url.instance_variable_set("@#{iv}".to_sym, value) end end picture_url end class Shop < String attr_reader :shop_id_front,:shop_name,:shop_name_kana,:shop_address, :station_name,:ktai_coupon, :large_service_area_cd,:large_service_area_name, :service_area_cd,:service_area_name, :large_area_cd,:large_area_name, :middle_area_cd,:middle_area_name, :small_area_cd,:small_area_name, :genre_cd,:genre_name,:budget_desc,:genre_catch,:shop_catch, :capacity,:access,:ktai_access,:shop_url,:ktai_shop_url,:ktai_qrurl, :picture_url end class PictureUrl < String attr_reader :pc_large_img,:pc_middle_img,:pc_small_img,:mb_large_img,:mb_small_img end end class Pager def initialize(request) @request = request end def current (@display_from / @display_per_page) + 1 end def last (@number_of_results / @display_per_page) + 1 end def next i = current + 1 i <= last ? i : nil end def prev i = current - 1 i > 0 ? i : nil end def start(n=nil) n = current unless n i = (n -1) * @display_per_page + 1 return nil if i > @number_of_results return nil if i <= 0 return i end def link_to_page(n=nil) request = {"Start"=>start(n)} link_to(request) end def link_to(request={}) query = @request.dup.update request Util.to_query_string(query) end attr_accessor :request,:number_of_results,:display_per_page,:display_from end class ResultSet def initialize(request) @items = [] @request = request @pager = Pager.new(request) end attr_accessor :items,:pager,:owner,:request end end