Class: Pincerna::Weather

Inherits:
Base
  • Object
show all
Defined in:
lib/pincerna/weather.rb

Overview

Gets weather forecast from Yahoo! Weather.

Constant Summary

MATCHER =

The expression to match.

/^
  (?<place>.+?)
  (\s+in\s+(?<scale>[cf]))?
$/mix
RELEVANT_MATCHES =

Relevant groups in the match.

{
  "place" => ->(_, value) { value }, # Place or WOEID
  "scale" => ->(_, value) { value.nil? ? "c" : value.downcase } # Temperature scale
}
ICON =

The icon to show for each feedback item.

Pincerna::Base::ROOT + "/images/weather.png"
URL =

The URL of the webservice.

"http://where.yahooapis.com/v1/places.q(%s);count=5"
API_KEY =

Yahoo! API key.

"dj0yJmk9ZUpBZk1hQTJGRHM5JmQ9WVdrOVlUSnBjMGhUTjJVbWNHbzlOemsyTURNeU5EWXkmcz1jb25zdW1lcnNlY3JldCZ4PWRi"

Constants inherited from Base

Base::CACHE_ROOT, Base::FULL_NAME, Base::ROOT, Base::TYPES, Base::WORKFLOW_ROOT

Instance Attribute Summary

Attributes inherited from Base

#format, #format_content_type, #output

Instance Method Summary (collapse)

Methods inherited from Base

#add_feedback_item, execute!, #filter, #format_float, #initialize, #output_feedback, #round_float

Constructor Details

This class inherits a constructor from Pincerna::Base

Instance Method Details

- (Array|NilClass) get_forecast(places, scale = "c")

Gets weather forecast for one or more places.

Parameters:

  • places (Array)

    The places to query.

  • scale (String) (defaults to: "c")

    The unit system to use: f for the US system (Farenheit) and c for the International System one (Celsius).

Returns:

  • (Array|NilClass)

    An array with forecasts data or nil if the query failed.



76
77
78
79
80
81
82
83
84
85
# File 'lib/pincerna/weather.rb', line 76

def get_forecast(places, scale = "c")
  client = Weatherman::Client.new(unit: scale)
  temperature_unit = "°#{scale.upcase}"

  places.map do |place|
    Pincerna::Cache.instance.use("forecast:#{place[:woeid]}", Pincerna::Cache::EXPIRATIONS[:short]) {
      parse_forecast_response(place, client.lookup_by_woeid(place[:woeid]), temperature_unit)
    }
  end
end

- (String) get_wind_direction(degrees)

Converts the degrees direction of the wind to the cardinal points notation (like NE or SW).

Parameters:

  • degrees (Fixnum)

    The direction in degrees.

Returns:

  • (String)

    The direction in cardinal points notation.



91
92
93
94
95
96
97
98
99
100
# File 'lib/pincerna/weather.rb', line 91

def get_wind_direction(degrees)
  # Normalize value
  degrees += 360 if degrees < 0
  degrees = degrees % 360

  # Get the position
  directions = ["N", "NE", "NE", "E", "E", "SE", "SE", "S", "S", "SW", "SW", "W", "W", "NW", "NW", "N"]
  position = ((degrees.to_f / 22.5) - 0.5).ceil.to_i % directions.count # The mod operation is needed for values close to 360 who, after ceiling, would otherwise overflow.
  directions[position]
end

- (Array) lookup_places(query)

Lookups a place on Yahoo! to obtain WOEID(s).

Parameters:

  • query (String)

    The place to search.

Returns:

  • (Array)

    A list of matching places data.



59
60
61
62
63
64
65
66
67
68
69
# File 'lib/pincerna/weather.rb', line 59

def lookup_places(query)
  if query !~ /^(\d+)$/ then
    Pincerna::Cache.instance.use("woeid:#{query}", Pincerna::Cache::EXPIRATIONS[:long]) do
      response = fetch_remote_resource(URL % CGI.escape(query), {appid: API_KEY, format: :json})
      response["places"].fetch("place", []).map { |place| parse_place(place) }
    end
  else
    # We already have the woeid. The name will be given by Yahoo!
    [{woeid: query}]
  end
end

- (Array) perform_filtering(query, scale)

Gets forecast for a place.

Parameters:

  • query (String)

    A place to search.

Returns:

  • (Array)

    A list of items to process.



35
36
37
38
# File 'lib/pincerna/weather.rb', line 35

def perform_filtering(query, scale)
  places = lookup_places(query)
  places.empty? ? nil : get_forecast(places, scale) if !places.empty?
end

- (Array) process_results(results)

Processes items to obtain feedback items.

Parameters:

  • results (Array)

    The items to process.

Returns:

  • (Array)

    The feedback items.



44
45
46
47
48
49
50
51
52
53
# File 'lib/pincerna/weather.rb', line 44

def process_results(results)
  results.map do |result|
    # Format results
    current = result[:current]
    forecast = result[:forecast]
    combined = "#{current[:temperature]}, #{current[:description].downcase.capitalize}, wind #{current[:wind][:speed]} #{current[:wind][:direction]} - Next: #{forecast[:high]} / #{forecast[:low]}, #{forecast[:description]}"

    {title: result[:name], arg: result[:link], subtitle: combined, icon: result[:image]}
  end
end