Class: Barometer::Query

Inherits:
Object
  • Object
show all
Defined in:
lib/barometer/query.rb

Overview

This class represents a query and can answer the questions that a Barometer will need to measure the weather

Summary:

When you create a new Query, you set the query string
ie: "New York, NY" or "90210"
The class will then determine the query string format
ie: :zipcode, :postalcode, :geocode, :coordinates
Now, when a Weather API driver asks for the query, it will prefer
certain formats, and only permit certain formats.  The Query class
will attempt to either return the query string as-is if acceptable,
or it will attempt to convert it to a format that is acceptable
(most likely this conversion will use Googles geocoding service using
the Graticule gem).  Worst case scenario is that the Weather API will
not accept the query string.

Defined Under Namespace

Classes: Format

Constant Summary collapse

FORMATS =

This array defines the order to check a query for the format

%w(
  ShortZipcode Zipcode Postalcode WeatherID Coordinates Icao Geocode
)
FORMAT_MAP =
{
  :short_zipcode => "ShortZipcode", :zipcode => "Zipcode",
  :postalcode => "Postalcode", :weather_id => "WeatherID",
  :coordinates => "Coordinates", :icao => "Icao",
  :geocode => "Geocode"
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(query = nil) ⇒ Query

Returns a new instance of Query.



35
36
37
38
39
# File 'lib/barometer/query.rb', line 35

def initialize(query=nil)
  return unless query
  @q = query
  self.analyze!
end

Instance Attribute Details

#country_codeObject

Returns the value of attribute country_code.



33
34
35
# File 'lib/barometer/query.rb', line 33

def country_code
  @country_code
end

#formatObject

Returns the value of attribute format.



33
34
35
# File 'lib/barometer/query.rb', line 33

def format
  @format
end

#geoObject

Returns the value of attribute geo.



33
34
35
# File 'lib/barometer/query.rb', line 33

def geo
  @geo
end

#qObject

Returns the value of attribute q.



33
34
35
# File 'lib/barometer/query.rb', line 33

def q
  @q
end

Instance Method Details

#analyze!Object

analyze the saved query to determine the format. this delegates the detection to each formats class until th right one is found



45
46
47
48
49
50
51
52
53
54
# File 'lib/barometer/query.rb', line 45

def analyze!
  return unless @q
  FORMATS.each do |format|
    if Query::Format.const_get(format.to_s).is?(@q)
      @format = Query::Format.const_get(format.to_s).format
      @country_code = Query::Format.const_get(format.to_s).country_code(@q)
      break
    end
  end
end

#convert!(preferred_formats = nil) ⇒ Object

take a list of acceptable (and ordered by preference) formats and convert the current query (q) into the most preferred and acceptable format. a side effect of the conversions may reveal the country_code, if so save it

Raises:

  • (ArgumentError)


60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/barometer/query.rb', line 60

def convert!(preferred_formats=nil)
  raise ArgumentError unless (preferred_formats && preferred_formats.size > 0)
  
  # why convert if we are already there?
  skip_conversion = false
  if preferred_formats.include?(@format.to_sym)
    skip_conversion = true
    converted_query = self.dup
  end
  
  unless skip_conversion
    # go through each acceptable format and try to convert to that
    converted = false
    converted_query = Barometer::Query.new
    preferred_formats.each do |preferred_format|
      klass = FORMAT_MAP[preferred_format.to_sym]
      if preferred_format == @format
        converted = true
        converted_query = Barometer::Query.new(@q)
      end
      unless converted
        converted_query =  Query::Format.const_get(klass.to_s).to(self)
        converted = true if converted_query
      end
      if converted
        converted_query.country_code ||= Query::Format.const_get(klass.to_s).country_code(converted_query.q)
        break
      end
    end
  end
  
  # force geocode?, unless we already did
  #
  if Barometer.force_geocode && !@geo
    if converted_query && converted_query.geo
      @geo = converted_query.geo
    else
      geo_query = Query::Format::Coordinates.to(converted_query)
      @geo = geo_query.geo if (geo_query && geo_query.geo)
    end
  end
  
  converted_query
end