################################################## # ANN_Wrapper ################################################## require "net/http" require "nokogiri" require 'ann_wrapper/ann_anime' require 'ann_wrapper/ann_manga' require 'ann_wrapper/ann_report' # wrapper class for ANN API module ANN_Wrapper extend ANN_Wrapper @@type = "anime" # ANN API anime url ANN_URL = "http://cdn.animenewsnetwork.com/encyclopedia" ANN_API_URL = "#{ANN_URL}/api.xml" ANN_REPORTS_URL = "#{ANN_URL}/reports.xml" # fetch up to 50 items(Animes or Mangas) in one request def batch_items(ids, api_url=ANN_API_URL) # append id to API url and send request url = "#{api_url}?title=#{ids.first.to_s}" ids[1..-1].each do |id| url << "/#{id.to_s}" end ann = fetch(url) return [ann] if ann.is_a?(ANN_Error) all_items = ann.xpath("//ann/#{@@type}") warnings = ann.xpath('//ann/warning') return [ANN_Error.new(get_xml_error(ann))] if all_items.empty? and warnings.empty? all_items = all_items.map { |item| Object.const_get("ANN_#{@@type.capitalize}").new(item) } warnings = warnings.map { |warning| ANN_Error.new(get_xml_error(warning)) } all_items.push(*warnings) end # fetch anime and convert to ANN_Anime def fetch_item(id, api_url=ANN_API_URL) batch_items([id], api_url).first end # fetch list of titles via reports def fetch_titles(options = {}) options[:type] ||= "anime" options[:nskip] ||= 0 options[:nlist] ||= 50 options[:name] ||= "" options[:api_url] ||= ANN_REPORTS_URL url = "#{options[:api_url]}?id=155&type=#{options[:type]}&name=#{options[:name]}&nskip=#{options[:nskip]}&nlist=#{options[:nlist]}" report = fetch(url) return report if report.is_a?(ANN_Error) reports = report.xpath('//report/item') return ANN_Error.new(get_xml_error(report)) if reports.nil? reports.map { |item| ANN_Report.new(item) } end def method_missing(meth, *args, &block) if meth.to_s =~ /^(fetch|batch)_(anime|manga)$/ @@type = $2 $1 == 'fetch' ? fetch_item(*args) : batch_items(*args) else super end end private # fetch data from ANN API via http GET request # returns Nokogiri or ANN_Error def fetch(url) begin # send http GET request with uri parsed from url resp = Net::HTTP.get_response(URI.parse(url)) # get the response body and try converting to Nokogiri object Nokogiri.XML(resp.body) rescue ANN_Error.new("Could not reach valid URL") end end # attempt to grab error message from XMLObject def get_xml_error(xobj) begin xobj.at_xpath('//ann/warning').content rescue NoMethodError "unrecognized response body" end end end