lib/gendered/guesser.rb in gendered-0.0.7 vs lib/gendered/guesser.rb in gendered-0.0.8
- old
+ new
@@ -1,51 +1,84 @@
+require "json"
+
module Gendered
class Guesser
+ ENDPOINT = "https://api.genderize.io".freeze
+ USAGE_HEADERS = {
+ "X-Rate-Limit-Limit" => :limit,
+ "X-Rate-Limit-Remaining" => :remaining,
+ "X-Rate-Reset" => :reset
+ }.freeze
- attr_accessor :names, :country_id
+ attr_reader :usage
+ attr_accessor :names, :options
- def initialize(values, country_id = nil)
- raise ArgumentError, "cannot be empty" if Array(values).empty?
+ def initialize(names, options = {})
+ @names = Array(names)
+ raise ArgumentError, "names cannot be empty" if @names.empty?
- @names = Array(values)
- @country_id = country_id
+ @options = Gendered.config.merge(options || {})
+ @options[:connection] ||= {}
+ @usage = { :limit => nil, :remaining => nil, :reset => nil }
end
def guess!
- response = HTTP.get(url)
+ response = request(request_options)
+ update_usage(response)
+ body = parse(response.body)
case response.code
when 200
+ create_names(body)
+ when 429
+ raise RateLimitError.new(body["error"], *@usage.values_at(:limit, :remaining, :reset))
+ else
+ raise GenderedError.new(body["error"])
+ end
+ end
- guesses = JSON.parse(response.body)
+ private
- names.collect do |name|
- name = Name.new(name) if name.is_a?(String)
+ def update_usage(response)
+ USAGE_HEADERS.each { |header, key| @usage[key] = response[header].to_i }
+ end
- guess = case
- when guesses.is_a?(Array)
- guesses.find { |g| g["name"] == name.value }
- else
- guesses
- end
+ def create_names(guesses)
+ names.collect do |name|
+ name = Name.new(name) if name.is_a?(String)
+ guess = case
+ when guesses.is_a?(Array)
+ guesses.find { |g| g["name"] == name.value }
+ else
+ guesses
+ end
- if guess["gender"]
- name.gender = guess["gender"].to_sym
- name.probability = guess["probability"]
- name.sample_size = guess["count"]
- end
-
- name
+ if guess["gender"]
+ name.gender = guess["gender"].to_sym
+ name.probability = guess["probability"]
+ name.sample_size = guess["count"]
end
+
+ name
end
end
- def url
- url = "https://api.genderize.io/?"
- url += "country_id=#{country_id}&" if country_id
+ def request_options
+ options = {}
+ options[:params] = @options.reject { |k, v| k == :connection || v.nil? }
+ options[:params]["name[]"] = @names
+ options[:connection] = @options[:connection] unless @options[:connection].empty?
+ options
+ end
- name_queries = names.collect.with_index do |name, index|
- "name[#{index}]=#{CGI.escape(name.to_s)}"
- end
- url + name_queries.join("&")
+ def request(options)
+ HTTP.get(ENDPOINT, options)
+ rescue => e
+ raise GenderedError, "request failed: #{e}"
+ end
+
+ def parse(response)
+ JSON.parse(response)
+ rescue JSON::ParserError => e
+ raise GenderedError, "cannot parse response JSON: #{e}"
end
end
end