Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # coding: utf-8
- require 'geocoder'
- require 'json'
- require 'open-uri'
- set_items = :minimal
- set_units = :both
- apikey = "NOTTELLINGYOU"
- # Take the supplied query and geocode it
- results = Geocoder.search("Amherst, NS").first
- # Get the current conditions for the geocoded query using latlong.
- conditions = JSON.parse open("http://api.wunderground.com/api/#{apikey}/conditions/almanac/astronomy/q/#{results.latitude},#{results.longitude}.json").read
- observations = conditions["current_observation"]
- almanac = conditions["almanac"]
- moon = conditions["moon_phase"]
- Temperature = Struct.new(:celsius, :fahrenheit, :unit) do
- def to_s *args
- return "" if self.celsius.eql?("NA") || self.celsius.to_s.empty? || self.celsius.nil?
- case self.unit
- when :both then "#{self.celsius}°C (#{self.fahrenheit}°F)"
- when :metric then "#{self.celsius}°C"
- when :imperial then "#{self.fahrenheit}°F"
- else
- "#{self.celsius}°C (#{self.fahrenheit}°F)"
- end
- end
- end
- Distance = Struct.new(:km, :mi, :perhour, :unit) do
- def to_s *args
- return "" if self.km.eql?("NA") || self.km.eql?("N/A") || self.km.nil?
- u = {
- km: (self.perhour ? "km/h" : "km"),
- mi: (self.perhour ? "mph" : "mi")
- }
- case self.unit
- when :both then "#{self.km} #{u[:km]} (#{self.mi} #{u[:mi]})"
- when :metric then "#{self.km} #{u[:km]}"
- when :imperial then "#{self.mi} #{u[:mi]}"
- else
- "#{self.km} #{u[:km]} (#{self.mi} #{u[:mi]})"
- end
- end
- end
- Fluid = Struct.new(:mm, :in, :unit) do
- def to_s *args
- return "" if self.mm.to_i == 0 || self.mm.nil?
- case self.unit
- when :both then "#{self.mm} mm (#{self.in} in)"
- when :metric then "#{self.mm} mm"
- when :imperial then "#{self.in} in"
- else
- "#{self.mm} mm (#{self.in} in)"
- end
- end
- end
- pressure_trend = ->(pt) {
- case pt.to_s
- when "+" then "rising"
- when "0" then "steady"
- when "-" then "falling"
- else
- nil
- end
- }
- precip = ->(onehour_mm, today_mm, onehour_in, today_in) {
- return "" if onehour_mm.to_i < 1 && today_mm.to_i < 1
- parts = []
- parts << "#{Fluid.new(onehour_mm.to_i, onehour_in.to_i, set_units).to_s} in the past hour" unless onehour_mm.to_i < 1
- parts << "#{Fluid.new(today_mm.to_i, today_in.to_i, set_units).to_s} today" unless today_mm.to_i < 1
- parts.join(", and ")
- }
- wind = ->(dir, kph, gust_kph, mph, gust_mph) {
- return nil if [kph, gust_kph, mph, gust_mph].all? {|i| i.to_f <= 0.00 }
- parts = []
- parts << "#{dir} at #{Distance.new(kph, mph, true, set_units).to_s}"
- parts << "gusting to #{Distance.new(gust_kph, gust_mph, true, set_units).to_s}" if gust_mph.to_f > 0
- parts.join(", ")
- }
- uv = ->(index) {
- case index.to_f
- when 0..2 then "Low" #Format(:green,"Low")
- when 3..5 then "Moderate" #Format(:yellow,"Moderate")
- when 6..7 then "High" #Format(:orange,"High")
- when 8..10 then "Very High" #Format(:red,"Very High")
- when 11..Float::INFINITY then "Extreme" #Format(:violet,"Extreme")
- else
- index.to_s
- end
- }
- outside = []
- outside << observations["weather"] unless observations["weather"].empty?
- outside << "#{Temperature.new(observations["temp_c"], observations["temp_f"], set_units).to_s}, feels like #{Temperature.new(observations["feelslike_c"], observations["feelslike_f"], set_units).to_s}"
- data = {
- "High/Low" => Temperature.new(almanac["temp_high"]["normal"]["C"], almanac["temp_high"]["normal"]["F"], set_units).to_s + "/" + Temperature.new(almanac["temp_low"]["normal"]["C"], almanac["temp_low"]["normal"]["F"], set_units).to_s,
- "Dew point" => Temperature.new(observations["dewpoint_c"], observations["dewpoint_f"], set_units),
- "Humidity" => (observations["relative_humidity"].to_i < 0 ? "N/A" : observations["relative_humidity"]),
- "Precip" => precip.call(observations["precip_1hr_metric"], observations["precip_today_metric"], observations["precip_1hr_in"], observations["precip_today_in"]),
- "Wind" => wind.call(observations["wind_dir"], observations["wind_kph"], observations["wind_gust_kph"], observations["wind_mph"], observations["wind_gust_mph"]),
- "Wind chill" => Temperature.new(observations["windchill_c"], observations["windchill_f"], set_units),
- "Heat index" => Temperature.new(observations["heat_index_c"], observations["heat_index_f"], set_units),
- "Pressure" => "#{(observations["pressure_mb"].to_i / 10.00).round(2)} kPa #{pressure_trend.call(observations["pressure_trend"])}",
- "Visibility" => Distance.new(observations["visibility_km"], observations["visibility_mi"], false, set_units),
- "UV Index" => ((uv.call(observations["UV"]) + " (#{observations["UV"]})") unless observations["UV"].to_i < 0),
- "Sunrise/set" => "#{DateTime.parse(moon["sunrise"].values.join(":")).strftime("%-l:%M%P")}, #{DateTime.parse(moon["sunset"].values.join(":")).strftime("%-l:%M%P")}"
- }
- minimal_data = ["Wind","Visibility","UV Index","Sunrise/set"]
- data.reject! {|k,v| v.to_s.empty? || (set_items == :minimal && !minimal_data.include?(k)) }
- collected = data.collect {|k,v|
- "#{k}: #{v}"
- }.join("; ")
- head = "Current observations for %<location>s (#{observations["station_id"]}) at %<observation_time>s:" % {
- location: observations["display_location"]["full"],
- observation_time: DateTime.parse(observations["local_time_rfc822"]).strftime("%b %-d, %Y, %-l:%M%P")
- }
- foot = "The full forecast can be viewed at #{observations["forecast_url"] + "?apiref=3fc95544aab994a0"}"
- puts [head,[*outside,collected].join(", "),foot].join("\n")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement