class Weathercom::Client
Constants
- API_KEY_URL
Attributes
configured_api_key[R]
connection[R]
Public Class Methods
new(api_key: nil, cache: nil)
click to toggle source
# File lib/weathercom/client.rb, line 16 def initialize(api_key: nil, cache: nil) @configured_api_key = api_key @cache = cache @connection ||= Faraday.new("https://api.weather.com") do |f| f.request :url_encoded #f.response :detailed_logger f.adapter Faraday.default_adapter f.headers['user-agent'] = 'Mozilla/5.0 (Compatible)' end if api_key.nil? @api_key = cache.get('weathercom:api_key') end end
Public Instance Methods
api_key()
click to toggle source
# File lib/weathercom/client.rb, line 33 def api_key configured_api_key or begin @api_key ||= scrape_api_key if @cache @cache.set('weathercom:api_key', @api_key) end @api_key end end
geocode(query, ttl: nil)
click to toggle source
endpoints
# File lib/weathercom/client.rb, line 111 def geocode(query, ttl: nil) if @cache && ttl cache_key = "weathercom:geocode:#{query}" result = @cache.get(cache_key) if result && result['expires_at'] && result['expires_at'] > Time.now.to_i return GeocodedLocation.new(result['location'], self) end end payload = raw_geocode(query) if @cache && ttl @cache.set(cache_key, 'expires_at' => Time.now.to_i + ttl, 'location' => payload) end GeocodedLocation.new(payload, self) end
get_json(url)
click to toggle source
# File lib/weathercom/client.rb, line 50 def get_json(url) request_json(:get, url) end
get_json_with_cache(url)
click to toggle source
# File lib/weathercom/client.rb, line 54 def get_json_with_cache(url) request_json_with_cache(:get, url) end
location(lat, lng)
click to toggle source
# File lib/weathercom/client.rb, line 129 def location(lat, lng) Location.new(lat, lng, self) end
request_json(meth, url)
click to toggle source
# File lib/weathercom/client.rb, line 58 def request_json(meth, url) attempt = 1 loop do if url.include?('?') full_url = "#{url}&apiKey=#{URI.encode(api_key)}" else full_url = "#{url}?apiKey=#{URI.encode(api_key)}" end response = connection.send(meth) do |req| req.url(full_url) end if response.status == 401 && configured_api_key.nil? && attempt == 1 clear_api_key attempt += 1 next end unless response.status == 200 error = nil begin error = JSON.parse(response.body)['error'] rescue end msg = "Weathercom #{meth.to_s.upcase} #{url} failed: #{response.status}" if error msg += ": #{error}" end raise ApiError.new(msg, status: response.status) end return JSON.parse(response.body) end end
request_json_with_cache(meth, url)
click to toggle source
# File lib/weathercom/client.rb, line 91 def request_json_with_cache(meth, url) cache_key = "weathercom:#{meth}:#{url}" if @cache && (data = @cache.get(cache_key)) if data.key?('metadata') && data['metadata'].key?('expire_time_gmt') && data['metadata']['expire_time_gmt'] > Time.now.to_i then return data end @cache.set(cache_key, nil) end request_json(meth, url).tap do |data| if @cache @cache.set(cache_key, data) end end end
Private Instance Methods
clear_api_key()
click to toggle source
# File lib/weathercom/client.rb, line 43 def clear_api_key @api_key = nil if @cache @cache.set('weathercom:api_key', nil) end end
raw_geocode(query)
click to toggle source
# File lib/weathercom/client.rb, line 150 def raw_geocode(query) url = "/v3/location/search?language=EN&query=#{URI.encode(query)}&format=json" payload = get_json(url) payload = Hash[payload['location'].map do |key, values| [key, values.first] end] end
scrape_api_key()
click to toggle source
# File lib/weathercom/client.rb, line 137 def scrape_api_key resp = connection.get(API_KEY_URL) if resp.status != 200 raise ApiKeyScrapeError, "Non-200 status while scraping API key: #{resp.status}" end unless resp.body =~ /apiKey=([a-zA-Z0-9]{10,})/ raise ApiKeyScrapeError, "Could not locate API key in response" end $1 end