weather-api 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ coverage
@@ -0,0 +1,5 @@
1
+ rvm:
2
+ - 1.8.7
3
+ - 1.9.2
4
+ - 1.9.3
5
+ - rbx
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source :rubygems
2
+
3
+ # Give guard growl notifications, if on OS X
4
+ if RUBY_PLATFORM =~ /darwin/i
5
+ gem "rb-fsevent", :require => false
6
+ gem "ruby_gntp", :require => false
7
+ end
8
+
9
+ gemspec
@@ -0,0 +1,19 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec', :version => 2 do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+
9
+ # Rails example
10
+ watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
11
+ watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
12
+ watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
13
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
14
+ watch('config/routes.rb') { "spec/routing" }
15
+ watch('app/controllers/application_controller.rb') { "spec/controllers" }
16
+ # Capybara request specs
17
+ watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
18
+ end
19
+
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2012 Andrew Stewart
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7
+ of the Software, and to permit persons to whom the Software is furnished to do
8
+ so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
@@ -0,0 +1,42 @@
1
+ # Weather-API
2
+
3
+ A Ruby wrapper for the Yahoo! Weather XML RSS feed.
4
+
5
+ ## Installation
6
+
7
+ [sudo] gem install weather-api
8
+
9
+ ## Description
10
+
11
+ Weather-API provides an object-oriented interface to the Yahoo! Weather XML RSS feed service.
12
+
13
+ Details on the service can be found [here](http://developer.yahoo.com/weather).
14
+
15
+ ## Usage
16
+
17
+ A simple example:
18
+
19
+ require 'rubygems'
20
+ require 'weather-api'
21
+
22
+ client = Weather::API.new
23
+
24
+ # look up WOEID via http://weather.yahoo.com; enter location by city
25
+ # name or zip and WOEID is at end of resulting page url.
26
+ response = client.lookup(9830)
27
+
28
+ print <<EOT
29
+ #{response.title}
30
+ #{response.condition.temp} degrees
31
+ #{response.condition.text}
32
+ EOT
33
+
34
+ This produces:
35
+
36
+ Conditions for Ladysmith, CA at 5:00 pm PDT
37
+ 13 degrees
38
+ Cloudy
39
+
40
+ ## Copyright
41
+
42
+ Copyright (c) 2012 Andrew Stewart. See `LICENSE` file for more details.
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ task :default => :spec
5
+
6
+ require 'rspec/core/rake_task'
7
+ RSpec::Core::RakeTask.new(:spec)
8
+
9
+ desc 'Open an irb session preloaded with this library'
10
+ task :console do
11
+ sh 'pry -Ilib -rweather-api'
12
+ end
@@ -0,0 +1,37 @@
1
+ require 'net/http'
2
+ require 'nokogiri'
3
+
4
+ module Weather
5
+ class << self
6
+
7
+ # Alias for Weather::API.new
8
+ #
9
+ # Returns a Weather::API object
10
+ def new
11
+ Weather::API.new
12
+ end
13
+
14
+ # Delegate to Weather::API
15
+ def method_missing(method, *args, &block)
16
+ return super unless new.respond_to?(method)
17
+ new.send(method, *args, &block)
18
+ end
19
+
20
+ def respond_to?(method, include_private=false)
21
+ new.respond_to?(method, include_private) || super(method, include_private)
22
+ end
23
+ end
24
+
25
+ autoload :API, 'weather-api/api'
26
+ autoload :Astronomy, 'weather-api/astronomy'
27
+ autoload :Atmosphere, 'weather-api/atmosphere'
28
+ autoload :Condition, 'weather-api/condition'
29
+ autoload :Forecast, 'weather-api/forecast'
30
+ autoload :Image, 'weather-api/image'
31
+ autoload :Location, 'weather-api/location'
32
+ autoload :Response, 'weather-api/response'
33
+ autoload :Units, 'weather-api/units'
34
+ autoload :Utils, 'weather-api/utils'
35
+ autoload :Version, 'weather-api/version'
36
+ autoload :Wind, 'weather-api/wind'
37
+ end
@@ -0,0 +1,33 @@
1
+ module Weather
2
+ class API
3
+ # Yahoo! Weather info endpoint
4
+ ENDPOINT = "http://weather.yahooapis.com/forecastrss"
5
+
6
+ # Public: Looks up current weather information using WOEID
7
+ #
8
+ # woeid - Int - Where On Earth IDentifier -- unique ID for
9
+ # location to get weather data for. To find
10
+ # a WOEID, refer to Yahoo!'s documentation
11
+ # at http://developer.yahoo.com/weather/
12
+ #
13
+ # units - String - whether to retrieve data in Farenheit
14
+ # or Celsius. Defaults to Farenheit
15
+ #
16
+ # Returns a Weather::Response object containing forecast
17
+ def lookup(woeid, units = 'f')
18
+ url = ENDPOINT + "?w=#{CGI.escape(woeid.to_s)}&u=#{CGI.escape(units.downcase)}"
19
+
20
+ begin
21
+ response = Net::HTTP.get_response(URI.parse(url)).body.to_s
22
+ rescue => e
23
+ raise RuntimeError.new("Failed to get weather [woeid=#{woeid}, url=#{url}, e=#{e}].")
24
+ end
25
+
26
+ # parse returned XML
27
+ doc = Nokogiri::XML.parse(response)
28
+
29
+ # create response object
30
+ Weather::Response.new(woeid, url, doc)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,14 @@
1
+ module Weather
2
+ class Astronomy
3
+ # a Time object containing the sunrise time for a location
4
+ attr_reader :sunrise
5
+
6
+ # a Time object containing the sunset time for a location
7
+ attr_reader :sunset
8
+
9
+ def initialize(payload)
10
+ @sunrise = Weather::Utils.parse_time payload['sunrise']
11
+ @sunset = Weather::Utils.parse_time payload['sunset']
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,40 @@
1
+ module Weather
2
+ class Atmosphere
3
+ class Barometer
4
+ STEADY = 'steady'
5
+ RISING = 'rising'
6
+ FALLING = 'falling'
7
+
8
+ # list of all possible barometer constants
9
+ ALL = [STEADY, RISING, FALLING]
10
+ end
11
+
12
+ # air humidity
13
+ attr_reader :humidity
14
+
15
+ # visibility of the surroundings
16
+ attr_reader :visibility
17
+
18
+ # air pressure level
19
+ attr_reader :pressure
20
+
21
+ # barometer state, defined as one of the contants
22
+ # in Weather::Atmosphere::Barometer
23
+ attr_reader :barometer
24
+
25
+ def initialize(payload)
26
+ @humidity = payload['humidity'].to_i
27
+ @visibility = payload['visibility'].to_i
28
+ @pressure = payload['pressure'].to_f
29
+
30
+ # map barometric pressure to appropriate constant
31
+ @barometer = nil
32
+
33
+ case payload['rising'].to_i
34
+ when 0 then @barometer = Barometer::STEADY
35
+ when 1 then @barometer = Barometer::RISING
36
+ when 2 then @barometer = Barometer::FALLING
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,22 @@
1
+ module Weather
2
+ class Condition
3
+ # the weather condition code, detailed at http://developer.yahoo.com/weather
4
+ attr_reader :code
5
+
6
+ # the date and time associated with these conditions.
7
+ attr_reader :date
8
+
9
+ # the temperature of the location.
10
+ attr_reader :temp
11
+
12
+ # the brief prose text description of the weather conditions of the location.
13
+ attr_reader :text
14
+
15
+ def initialize(payload)
16
+ @code = payload['code'].to_i
17
+ @date = Weather::Utils.parse_time(payload['date'])
18
+ @temp = payload['temp'].to_i
19
+ @text = payload['text']
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,30 @@
1
+ module Weather
2
+ class Forecast
3
+ # the brief name of the day associated with the forecast
4
+ attr_reader :day
5
+
6
+ # the date associated with the forecast.
7
+ attr_reader :date
8
+
9
+ # the low temperature forecasted.
10
+ attr_reader :low
11
+
12
+ # the high temperature forecasted.
13
+ attr_reader :high
14
+
15
+ # the brief prose text description of the forecasted weather conditions.
16
+ attr_reader :text
17
+
18
+ # the weather condition code, detailed at http://developer.yahoo.com/weather
19
+ attr_reader :code
20
+
21
+ def initialize(payload)
22
+ @day = payload['day']
23
+ @date = Weather::Utils.parse_time(payload['date'])
24
+ @low = payload['low'].to_i
25
+ @high = payload['high'].to_i
26
+ @text = payload['text']
27
+ @code = payload['code'].to_i
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,26 @@
1
+ module Weather
2
+ class Image
3
+ # the image height in pixels
4
+ attr_reader :height
5
+
6
+ # the image width in pixels
7
+ attr_reader :width
8
+
9
+ # the full URL to the image
10
+ attr_reader :url
11
+
12
+ # the link to the Yahoo! Weather home page
13
+ attr_reader :link
14
+
15
+ # the title of the image
16
+ attr_reader :title
17
+
18
+ def initialize(payload)
19
+ @height = payload.xpath('height').first.content.to_i
20
+ @width = payload.xpath('width').first.content.to_i
21
+ @url = payload.xpath('url').first.content
22
+ @link = payload.xpath('link').first.content
23
+ @title = payload.xpath('title').first.content
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,18 @@
1
+ module Weather
2
+ class Location
3
+ # the name of the city
4
+ attr_reader :city
5
+
6
+ # the name of the country
7
+ attr_reader :country
8
+
9
+ # name of the region, such as a state or province
10
+ attr_reader :region
11
+
12
+ def initialize(payload)
13
+ @city = payload['city']
14
+ @country = payload['country']
15
+ @region = payload['region']
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,85 @@
1
+ module Weather
2
+ class Response
3
+ # a Weather::Astronomy object containing sunrise and sunset
4
+ # information for the requested location
5
+ attr_reader :astronomy
6
+
7
+ # a Weather::Location object containing the geographical
8
+ # names of the requested location
9
+ attr_reader :location
10
+
11
+ # a Weather::Units object containig the units corresponding
12
+ # to the information contained in the response
13
+ attr_reader :units
14
+
15
+ # a Weather::Wind object containing the wind information
16
+ # for the requested location
17
+ attr_reader :wind
18
+
19
+ # a Weather::Atmosphere object containing the atmosphere
20
+ # information for the requested location
21
+ attr_reader :atmosphere
22
+
23
+ # a Weather::Condition object detailing the current
24
+ # conditions of the requested location
25
+ attr_reader :condition
26
+
27
+ # a collection of Weather::Forecast objects containing
28
+ # high-level forecasted weather for upcoming days
29
+ attr_reader :forecasts
30
+
31
+ # the HTML summarizing current weather conditions for
32
+ # the requested location
33
+ attr_reader :description
34
+
35
+ # a Weather::Image object containing an image icon
36
+ # representing the current weather for the requested location
37
+ attr_reader :image
38
+
39
+ # the latitude for the requested location
40
+ attr_reader :latitude
41
+
42
+ # the longitude for the requested location
43
+ attr_reader :longitude
44
+
45
+ # the location string initially requested of the service.
46
+ attr_reader :request_location
47
+
48
+ # the url with which the Yahoo! Weather service was
49
+ # accessed to build the response
50
+ attr_reader :request_url
51
+
52
+ # the title of the weather information for the requested location
53
+ attr_reader :title
54
+
55
+ def initialize(request_location, request_url, doc)
56
+ # save the request params
57
+ @request_location = request_location
58
+ @request_url = request_url
59
+
60
+ # parse the xml element to get response data
61
+ root = doc.xpath('/rss/channel').first
62
+
63
+ @astronomy = Weather::Astronomy.new(root.xpath('yweather:astronomy').first)
64
+ @location = Weather::Location.new(root.xpath('yweather:location').first)
65
+ @units = Weather::Units.new(root.xpath('yweather:units').first)
66
+ @wind = Weather::Wind.new(root.xpath('yweather:wind').first)
67
+ @atmosphere = Weather::Atmosphere.new(root.xpath('yweather:atmosphere').first)
68
+ @image = Weather::Image.new(root.xpath('image').first)
69
+
70
+ item = root.xpath('item').first
71
+ @forecasts = []
72
+
73
+ @condition = Weather::Condition.new(item.xpath('yweather:condition').first)
74
+
75
+ item.xpath('yweather:forecast').each do |forecast|
76
+ @forecasts << Weather::Forecast.new(forecast)
77
+ end
78
+
79
+ @latitude = item.xpath('geo:lat').first.content.to_f
80
+ @longitude = item.xpath('geo:long').first.content.to_f
81
+ @title = item.xpath('title').first.content
82
+ @description = item.xpath('description').first.content
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,29 @@
1
+ module Weather
2
+ class Units
3
+ FARENHEIT = 'f'
4
+ CELSIUS = 'c'
5
+
6
+ # the unit in which temperature is measured
7
+ # e.g. F for Farenheit, and C for Celsius
8
+ attr_reader :temperature
9
+
10
+ # the unit in which distance is measured
11
+ # e.g. mi for miles, and km for kilometers
12
+ attr_reader :distance
13
+
14
+ # the unit in which pressure is measured
15
+ # e.g in for inches, and cm for centimeters
16
+ attr_reader :pressure
17
+
18
+ # the unit in which speed is measured
19
+ # e.g. mph for miles per hour, and kph for kilometers per hour
20
+ attr_reader :speed
21
+
22
+ def initialize(payload)
23
+ @temperature = payload['temperature']
24
+ @distance = payload['distance']
25
+ @pressure = payload['pressure']
26
+ @speed = payload['speed']
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,17 @@
1
+ require 'chronic'
2
+
3
+ module Weather
4
+ class Utils
5
+
6
+ # Attempts to convert passed text into a Time object
7
+ #
8
+ # Returns a Time object or nil
9
+ def self.parse_time(text)
10
+ begin
11
+ Time.parse(text)
12
+ rescue ArgumentError
13
+ Chronic.parse(text)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,39 @@
1
+ module Weather
2
+ class Version
3
+
4
+ # The current major version number
5
+ #
6
+ # Returns an int
7
+ def self.major
8
+ 1
9
+ end
10
+
11
+ # The current minor version number
12
+ #
13
+ # Returns an int
14
+ def self.minor
15
+ 0
16
+ end
17
+
18
+ # The current patch version number
19
+ #
20
+ # Returns an int
21
+ def self.patch
22
+ 0
23
+ end
24
+
25
+ # The current pre version number
26
+ #
27
+ # Returns an int
28
+ def self.pre
29
+ nil
30
+ end
31
+
32
+ # Bundles up the version number into a string
33
+ #
34
+ # Returns the current version number as a string
35
+ def self.to_s
36
+ [major, minor, patch, pre].compact.join('.')
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,18 @@
1
+ module Weather
2
+ class Wind
3
+ # the temperature, with wind chill factored in
4
+ attr_reader :chill
5
+
6
+ # the direction of the wind in degrees
7
+ attr_reader :direction
8
+
9
+ # the windspeed
10
+ attr_reader :speed
11
+
12
+ def initialize(payload)
13
+ @chill = payload['chill'].to_i
14
+ @direction = payload['direction'].to_i
15
+ @speed = payload['speed'].to_i
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,8 @@
1
+ require 'helper'
2
+
3
+ describe Weather::API do
4
+ it 'should alias Weather to Weather::API' do
5
+ @api = Weather.new
6
+ @api.should be_a Weather::API
7
+ end
8
+ end
@@ -0,0 +1,15 @@
1
+ require 'helper'
2
+
3
+ describe Weather::Astronomy do
4
+ use_vcr_cassette
5
+
6
+ before do
7
+ @client = Weather::API.new
8
+ @response = @client.lookup(9848)
9
+ end
10
+
11
+ it 'should contain Time objects for sunrise and sunset' do
12
+ @response.astronomy.sunrise.should be_a Time
13
+ @response.astronomy.sunset.should be_a Time
14
+ end
15
+ end
@@ -0,0 +1,23 @@
1
+ require 'helper'
2
+
3
+ describe Weather::Atmosphere do
4
+ use_vcr_cassette
5
+
6
+ before do
7
+ @client = Weather::API.new
8
+ @response = @client.lookup(9848)
9
+ end
10
+
11
+ it 'should contain a string indicating barometric pressure' do
12
+ @response.atmosphere.barometer.should be_a String
13
+ end
14
+
15
+ it 'should contain integers representing humidity and visibility' do
16
+ @response.atmosphere.humidity.should be_a Integer
17
+ @response.atmosphere.visibility.should be_a Integer
18
+ end
19
+
20
+ it 'should contain a float indicating atmospheric pressure' do
21
+ @response.atmosphere.pressure.should be_a Float
22
+ end
23
+ end
@@ -0,0 +1,17 @@
1
+ require 'helper'
2
+
3
+ describe Weather::Condition do
4
+ use_vcr_cassette
5
+
6
+ before do
7
+ @client = Weather::API.new
8
+ @response = @client.lookup(9848)
9
+ end
10
+
11
+ it 'should contain a weather condition code, a date, a temperature, and a description' do
12
+ @response.condition.code.should be_a Integer
13
+ @response.condition.date.should be_a Time
14
+ @response.condition.temp.should be_a Integer
15
+ @response.condition.text.should be_a String
16
+ end
17
+ end
@@ -0,0 +1,32 @@
1
+ require 'helper'
2
+
3
+ describe Weather::Forecast do
4
+ use_vcr_cassette
5
+
6
+ before do
7
+ client = Weather::API.new
8
+ response = client.lookup(9848)
9
+ @forecast = response.forecasts[0]
10
+ end
11
+
12
+ it 'should have an associated date' do
13
+ @forecast.date.should be_a Time
14
+ end
15
+
16
+ it 'should contain high and low forecasts' do
17
+ @forecast.high.should be_a Integer
18
+ @forecast.low.should be_a Integer
19
+ end
20
+
21
+ it 'should contain the name of the day associated with the forecast' do
22
+ @forecast.day.should be_a String
23
+ end
24
+
25
+ it 'should have a weather condition code' do
26
+ @forecast.code.should be_a Integer
27
+ end
28
+
29
+ it 'should have a brief description of the forecasted conditions' do
30
+ @forecast.text.should be_a String
31
+ end
32
+ end
@@ -0,0 +1,21 @@
1
+ require 'helper'
2
+
3
+ describe Weather::Image do
4
+ use_vcr_cassette
5
+
6
+ before do
7
+ @client = Weather::API.new
8
+ @response = @client.lookup(9848)
9
+ end
10
+
11
+ it 'should contain integers for image height and width' do
12
+ @response.image.height.should be_a Integer
13
+ @response.image.width.should be_a Integer
14
+ end
15
+
16
+ it 'should contain strings for the image url, link, and title' do
17
+ @response.image.url.should be_a String
18
+ @response.image.link.should be_a String
19
+ @response.image.title.should be_a String
20
+ end
21
+ end
@@ -0,0 +1,41 @@
1
+ require 'helper'
2
+
3
+ describe Weather::Location do
4
+ use_vcr_cassette
5
+
6
+ before do
7
+ @client = Weather::API.new
8
+ end
9
+
10
+ it 'should contain city, country, and region as strings' do
11
+ response = @client.lookup(9848)
12
+
13
+ response.location.city.should be_a String
14
+ response.location.region.should be_a String
15
+ response.location.country.should be_a String
16
+ end
17
+
18
+ it 'should be able to look up Seattle, WA' do
19
+ response = @client.lookup(2490383)
20
+
21
+ response.location.city.should == 'Seattle'
22
+ response.location.region.should == 'WA'
23
+ response.location.country.should == 'United States'
24
+ end
25
+
26
+ it 'should be able to look up Victoria, BC' do
27
+ response = @client.lookup(9848)
28
+
29
+ response.location.city.should == 'Victoria'
30
+ response.location.region.should == 'BC'
31
+ response.location.country.should == 'Canada'
32
+ end
33
+
34
+ it 'should be able to look up Nice, France' do
35
+ response = @client.lookup(614274)
36
+
37
+ response.location.city.should == 'Nice'
38
+ response.location.region.should == ''
39
+ response.location.country.should == 'France'
40
+ end
41
+ end
@@ -0,0 +1,60 @@
1
+ require 'helper'
2
+
3
+ describe Weather::Response do
4
+ use_vcr_cassette
5
+
6
+ before do
7
+ @client = Weather::API.new
8
+ @response = @client.lookup(9848)
9
+ end
10
+
11
+ it 'should contain a Weather::Astronomy object' do
12
+ @response.astronomy.should be_a Weather::Astronomy
13
+ end
14
+
15
+ it 'should contain a Weather::Location object' do
16
+ @response.location.should be_a Weather::Location
17
+ end
18
+
19
+ it 'should contain a Weather::Units object' do
20
+ @response.units.should be_a Weather::Units
21
+ end
22
+
23
+ it 'should contain a Weather::Wind object' do
24
+ @response.wind.should be_a Weather::Wind
25
+ end
26
+
27
+ it 'should contain a Weather::Atmosphere object' do
28
+ @response.atmosphere.should be_a Weather::Atmosphere
29
+ end
30
+
31
+ it 'should contain a Weather::Condition object' do
32
+ @response.condition.should be_a Weather::Condition
33
+ end
34
+
35
+ it 'should contain a collection of Weather::Forecast objects' do
36
+ @response.forecasts[0].should be_a Weather::Forecast
37
+ end
38
+
39
+ it 'should contain a Weather::Image object' do
40
+ @response.image.should be_a Weather::Image
41
+ end
42
+
43
+ it 'should contain the WOEID of the request location and the requested URL' do
44
+ @response.request_location.should == 9848
45
+ @response.request_url.should == "http://weather.yahooapis.com/forecastrss?w=9848&u=f"
46
+ end
47
+
48
+ it 'should contain a HTML description summarizing weather conditions' do
49
+ @response.description.should be_a String
50
+ end
51
+
52
+ it 'should contain a String title' do
53
+ @response.title.should be_a String
54
+ end
55
+
56
+ it 'should contain latitude and longitude in floats' do
57
+ @response.latitude.should be_a Float
58
+ @response.longitude.should be_a Float
59
+ end
60
+ end
@@ -0,0 +1,36 @@
1
+ require 'helper'
2
+
3
+ describe Weather::Units do
4
+ before do
5
+ @client = Weather::API.new
6
+ end
7
+
8
+ describe 'constants' do
9
+ it 'should have constants for celsius and farenheit' do
10
+ Weather::Units::FARENHEIT.should == 'f'
11
+ Weather::Units::CELSIUS.should == 'c'
12
+ end
13
+ end
14
+
15
+ describe 'defaults' do
16
+ use_vcr_cassette
17
+
18
+ it 'should default to imperial units' do
19
+ response = @client.lookup(9848)
20
+
21
+ response.units.distance.should == 'mi'
22
+ response.units.pressure.should == 'in'
23
+ response.units.speed.should == 'mph'
24
+ response.units.temperature.should == 'F'
25
+ end
26
+
27
+ it 'should switch to metric if specified' do
28
+ response = @client.lookup(9848, 'c')
29
+
30
+ response.units.distance.should == 'km'
31
+ response.units.pressure.should == 'mb'
32
+ response.units.speed.should == 'km/h'
33
+ response.units.temperature.should == 'C'
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,13 @@
1
+ require 'helper'
2
+
3
+ describe Weather::Utils do
4
+ it 'should parse text into a Time object' do
5
+ time = Weather::Utils.parse_time('2007-01-31 12:22:26')
6
+ time.should be_a Time
7
+ end
8
+
9
+ it 'should return nil if passed nothing' do
10
+ time = Weather::Utils.parse_time('')
11
+ time.should == nil
12
+ end
13
+ end
@@ -0,0 +1,8 @@
1
+ require "helper"
2
+
3
+ describe Weather::Version do
4
+ it "should return a string" do
5
+ string = Weather::Version.to_s
6
+ string.should be_a String
7
+ end
8
+ end
@@ -0,0 +1,16 @@
1
+ require 'helper'
2
+
3
+ describe Weather::Wind do
4
+ use_vcr_cassette
5
+
6
+ before do
7
+ @client = Weather::API.new
8
+ @response = @client.lookup(9848)
9
+ end
10
+
11
+ it 'should contain chill, direction, and speed as integers' do
12
+ @response.wind.chill.should be_a Integer
13
+ @response.wind.direction.should be_a Integer
14
+ @response.wind.speed.should be_a Integer
15
+ end
16
+ end
@@ -0,0 +1,19 @@
1
+ require "simplecov"
2
+ SimpleCov.start
3
+
4
+ require "weather-api"
5
+
6
+ require "rspec"
7
+ require "webmock/rspec"
8
+ require "vcr"
9
+
10
+ VCR.configure do |config|
11
+ config.cassette_library_dir = "spec/fixtures/cassettes"
12
+ config.hook_into :webmock
13
+ config.ignore_localhost = true
14
+ config.default_cassette_options = { record: :new_episodes }
15
+ end
16
+
17
+ RSpec.configure do |config|
18
+ config.extend VCR::RSpec::Macros
19
+ end
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/weather-api/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Andrew Stewart"]
6
+ gem.email = ["andrew@averagestudios.com"]
7
+ gem.description = %q{A wrapper for the Yahoo! Weather XML RSS feed}
8
+ gem.summary = %q{Weather-API provides an object-oriented interface to the Yahoo! Weather XML RSS feed service.}
9
+ gem.homepage = "https://github.com/stewart/weather-api"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "weather-api"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Weather::Version.to_s
17
+
18
+ gem.add_dependency "nokogiri", "~> 1.5.2"
19
+ gem.add_dependency "chronic", "~> 0.6.7"
20
+
21
+ gem.add_development_dependency "guard-rspec", "~> 0.7.0"
22
+ gem.add_development_dependency "simplecov", "~> 0.6.1"
23
+ gem.add_development_dependency "rspec", "~> 2.9.0"
24
+ gem.add_development_dependency "webmock", "~> 1.8.6"
25
+ gem.add_development_dependency "guard", "~> 1.0.1"
26
+ gem.add_development_dependency "rake", "~> 0.9.2.2"
27
+ gem.add_development_dependency "vcr", "~> 2.0.1"
28
+ end
metadata ADDED
@@ -0,0 +1,192 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: weather-api
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Andrew Stewart
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-14 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: nokogiri
16
+ requirement: &70196846185740 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.5.2
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70196846185740
25
+ - !ruby/object:Gem::Dependency
26
+ name: chronic
27
+ requirement: &70196846185220 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 0.6.7
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70196846185220
36
+ - !ruby/object:Gem::Dependency
37
+ name: guard-rspec
38
+ requirement: &70196846184760 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 0.7.0
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70196846184760
47
+ - !ruby/object:Gem::Dependency
48
+ name: simplecov
49
+ requirement: &70196846184280 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 0.6.1
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70196846184280
58
+ - !ruby/object:Gem::Dependency
59
+ name: rspec
60
+ requirement: &70196846183820 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: 2.9.0
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70196846183820
69
+ - !ruby/object:Gem::Dependency
70
+ name: webmock
71
+ requirement: &70196846183360 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ version: 1.8.6
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70196846183360
80
+ - !ruby/object:Gem::Dependency
81
+ name: guard
82
+ requirement: &70196846182900 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ~>
86
+ - !ruby/object:Gem::Version
87
+ version: 1.0.1
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *70196846182900
91
+ - !ruby/object:Gem::Dependency
92
+ name: rake
93
+ requirement: &70196846182440 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ~>
97
+ - !ruby/object:Gem::Version
98
+ version: 0.9.2.2
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *70196846182440
102
+ - !ruby/object:Gem::Dependency
103
+ name: vcr
104
+ requirement: &70196846181900 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: 2.0.1
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: *70196846181900
113
+ description: A wrapper for the Yahoo! Weather XML RSS feed
114
+ email:
115
+ - andrew@averagestudios.com
116
+ executables: []
117
+ extensions: []
118
+ extra_rdoc_files: []
119
+ files:
120
+ - .gitignore
121
+ - .travis.yml
122
+ - Gemfile
123
+ - Guardfile
124
+ - LICENSE
125
+ - README.md
126
+ - Rakefile
127
+ - lib/weather-api.rb
128
+ - lib/weather-api/api.rb
129
+ - lib/weather-api/astronomy.rb
130
+ - lib/weather-api/atmosphere.rb
131
+ - lib/weather-api/condition.rb
132
+ - lib/weather-api/forecast.rb
133
+ - lib/weather-api/image.rb
134
+ - lib/weather-api/location.rb
135
+ - lib/weather-api/response.rb
136
+ - lib/weather-api/units.rb
137
+ - lib/weather-api/utils.rb
138
+ - lib/weather-api/version.rb
139
+ - lib/weather-api/wind.rb
140
+ - spec/cases/api_spec.rb
141
+ - spec/cases/astronomy_spec.rb
142
+ - spec/cases/atmosphere_spec.rb
143
+ - spec/cases/condition_spec.rb
144
+ - spec/cases/forecast_spec.rb
145
+ - spec/cases/image_spec.rb
146
+ - spec/cases/location_spec.rb
147
+ - spec/cases/response_spec.rb
148
+ - spec/cases/units_spec.rb
149
+ - spec/cases/utils_spec.rb
150
+ - spec/cases/version_spec.rb
151
+ - spec/cases/wind_spec.rb
152
+ - spec/helper.rb
153
+ - weather-api.gemspec
154
+ homepage: https://github.com/stewart/weather-api
155
+ licenses: []
156
+ post_install_message:
157
+ rdoc_options: []
158
+ require_paths:
159
+ - lib
160
+ required_ruby_version: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ! '>='
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ required_rubygems_version: !ruby/object:Gem::Requirement
167
+ none: false
168
+ requirements:
169
+ - - ! '>='
170
+ - !ruby/object:Gem::Version
171
+ version: '0'
172
+ requirements: []
173
+ rubyforge_project:
174
+ rubygems_version: 1.8.11
175
+ signing_key:
176
+ specification_version: 3
177
+ summary: Weather-API provides an object-oriented interface to the Yahoo! Weather XML
178
+ RSS feed service.
179
+ test_files:
180
+ - spec/cases/api_spec.rb
181
+ - spec/cases/astronomy_spec.rb
182
+ - spec/cases/atmosphere_spec.rb
183
+ - spec/cases/condition_spec.rb
184
+ - spec/cases/forecast_spec.rb
185
+ - spec/cases/image_spec.rb
186
+ - spec/cases/location_spec.rb
187
+ - spec/cases/response_spec.rb
188
+ - spec/cases/units_spec.rb
189
+ - spec/cases/utils_spec.rb
190
+ - spec/cases/version_spec.rb
191
+ - spec/cases/wind_spec.rb
192
+ - spec/helper.rb