yahoo_weatherman 0.2

Sign up to get free protection for your applications and to get access to all the features.
data/i18n/pt-br.yml ADDED
@@ -0,0 +1,54 @@
1
+ 0: Tornado
2
+ 1: Tempestade Tropical
3
+ 2: Furacão
4
+ 3: Tempestades Severas
5
+ 4: Tempestades
6
+ 5: Chuva com Neve
7
+ 6: Chuva com Granizo
8
+ 7: Chova com Neve e Granizo
9
+ 8: Geada
10
+ 9: Garoa
11
+ 10: Geada
12
+ 11: Chuva
13
+ 12: Chuva
14
+ 13: Flocos de Neve
15
+ 14: Neve Calma
16
+ 15: Nevasca
17
+ 16: Neve
18
+ 17: Granizo
19
+ 18: Granizo
20
+ 19: Poeira
21
+ 20: Neblina
22
+ 21: Nevoeiro
23
+ 22: Nevoeiro
24
+ 23: Tempestuoso
25
+ 24: Ventoso
26
+ 25: Frio
27
+ 26: Nublado
28
+ 27: Predominantemente Nublado (noite)
29
+ 28: Predominantemente Nublado
30
+ 29: Parcialmente Nublado (noite)
31
+ 30: Parcialmente Nublado
32
+ 31: Céu Limpo
33
+ 32: Ensolarado
34
+ 33: Limpo
35
+ 34: Limpo
36
+ 35: Misto de Chuva e Granizo
37
+ 36: Quente
38
+ 37: Tempestades Isoladas
39
+ 38: Tempestades Intermitentes
40
+ 39: Tempestades Intermitentes
41
+ 40: Chuvas Intermitentes
42
+ 41: Bastante Neve
43
+ 42: Neve
44
+ 43: Bastante Neve
45
+ 44: Parcialmente Nublado
46
+ 45: Tempestade
47
+ 46: Neve
48
+ 47: Chuvas Isoladas
49
+ 3200: Não Disponível
50
+
51
+ locations:
52
+ Brazil: Brasil
53
+ Belo Horizonte: Belzonti
54
+ MG: Minas Gerais
@@ -0,0 +1,15 @@
1
+ module Weatherman
2
+ # == Image
3
+ #
4
+ # A hash-like object with the weather image attributes (width, height, url, etc..)
5
+ #
6
+ class Image
7
+ def initialize(doc)
8
+ @image_root = doc
9
+ end
10
+
11
+ def [](attr)
12
+ @image_root.xpath(attr).first.content
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,203 @@
1
+ module Weatherman
2
+
3
+ # = Response
4
+ #
5
+ # This is where we get access to the contents parsed by Nokogiri in a object-oriented way.
6
+ # We also use this class to do the i18n stuff.
7
+ #
8
+ class Response
9
+ attr_accessor :document_root
10
+
11
+ def initialize(raw, language = nil)
12
+ @document_root = Nokogiri::XML.parse(raw).xpath('rss/channel')
13
+ @language = !!language
14
+ load_language_yaml!(language) if @language
15
+ end
16
+
17
+ #
18
+ # Returns a hash containing the actual weather condition details:
19
+ #
20
+ # condition = response.condition
21
+ # condition['text'] => "Tornado"
22
+ # condition['code'] => 0
23
+ # condition['temp'] => 21
24
+ # condition['date'] => #<Date: -1/2,0,2299161>
25
+ #
26
+ def condition
27
+ condition = item_attribute 'yweather:condition'
28
+ condition = do_convertions(condition, [:code, :to_i], [:temp, :to_i], [:date, :to_date], :text)
29
+ translate!(condition)
30
+ end
31
+
32
+ #
33
+ # Wind's details:
34
+ #
35
+ # wind = response.wind
36
+ # wind['chill'] => 21
37
+ # wind['direction'] => 340
38
+ # wind['chill'] => 9.66
39
+ #
40
+ def wind
41
+ wind = attribute 'yweather:wind'
42
+ do_convertions(wind, [:chill, :to_i], [:direction, :to_i], [:speed, :to_f])
43
+ end
44
+
45
+ #
46
+ # Forecasts for the next 2 days.
47
+ #
48
+ # forecast = response.forecasts.first
49
+ # forecast['low'] => 20
50
+ # forecast['high'] => 31
51
+ # forecast['text'] => "Tornado"
52
+ # forecast['code'] => 0
53
+ # forecast['day'] => "Sat"
54
+ #
55
+ def forecasts
56
+ item_attribute('yweather:forecast').collect do |forecast|
57
+ do_convertions(forecast, [:date, :to_date], [:low, :to_i], [:high, :to_i], [:code, :to_i], :day, :text)
58
+ end
59
+ end
60
+
61
+ #
62
+ # Location:
63
+ #
64
+ # location = response.location
65
+ # location['country'] => "Brazil"
66
+ # location['region'] => "MG"
67
+ # location['city'] => Belo Horizonte
68
+ #
69
+ def location
70
+ location = attribute 'yweather:location'
71
+ translate!(location)
72
+ end
73
+
74
+ # Units:
75
+ #
76
+ # units = response.units
77
+ # units['temperature'] => "C"
78
+ # units['distance'] => "km"
79
+ # units['pressure'] => "mb"
80
+ # units['speed'] => "km/h"
81
+ #
82
+ def units
83
+ attribute 'yweather:units'
84
+ end
85
+
86
+ #
87
+ # Astronomy:
88
+ #
89
+ # astronomy = response.astronomy
90
+ # astronomy['sunrise'] => "6:01 am"
91
+ # astronomy['sunset'] => "7:20 pm"
92
+ #
93
+ def astronomy
94
+ attribute 'yweather:astronomy'
95
+ end
96
+
97
+ #
98
+ # Latitude:
99
+ #
100
+ # response.latitude => -49.90
101
+ def latitude
102
+ geo_attribute('lat').to_f
103
+ end
104
+
105
+ #
106
+ # Longitude;
107
+ #
108
+ # response.longitude => -45.32
109
+ #
110
+ def longitude
111
+ geo_attribute('long').to_f
112
+ end
113
+
114
+ #
115
+ # A hash like object providing image info:
116
+ #
117
+ # image = reponse.image
118
+ # image['width'] => 142
119
+ # image['height'] => 18
120
+ # image['title'] => "Yahoo! Weather"
121
+ # image['link'] => "http://weather.yahoo.com"
122
+ #
123
+ def image
124
+ image = Weatherman::Image.new(attribute 'image')
125
+ do_convertions(image, [:width, :to_i], [:height, :to_i], :title, :link, :url)
126
+ end
127
+
128
+ #
129
+ # A short HTML snippet with a simple weather description.
130
+ #
131
+ def description
132
+ text_attribute 'description'
133
+ end
134
+
135
+ private
136
+ def attribute(attr, root = @document_root)
137
+ elements = root.xpath(attr)
138
+ elements.size == 1 ? elements.first : elements
139
+ end
140
+
141
+ def item_attribute(attr)
142
+ item = document_root.xpath('item').first
143
+ attribute(attr, item)
144
+ end
145
+
146
+ def geo_attribute(attr)
147
+ geo = item_attribute('geo:' + attr)
148
+ geo.children.first.text
149
+ end
150
+
151
+ def text_attribute(attr)
152
+ item_attribute(attr).content
153
+ end
154
+
155
+ def do_convertions(attributes, *pairs)
156
+ pairs.inject({}) do |hash, (attr, method)|
157
+ value = attributes[attr.to_s]
158
+ hash[attr.to_s] = convert(value, method)
159
+ hash
160
+ end
161
+ end
162
+
163
+ def convert(value, method)
164
+ if method == :to_date
165
+ Date.parse(value)
166
+ else
167
+ method ? value.send(method) : value
168
+ end
169
+ end
170
+
171
+ def load_language_yaml!(language)
172
+ stream = File.read(File.join([I18N_YAML_DIR, language + '.yml']))
173
+ @language_config = YAML.load(stream)
174
+ end
175
+
176
+ def make_translations!(condition)
177
+ if condition['text']
178
+ condition['text'] = @language_config[condition['code']]
179
+ end
180
+
181
+ %w(city country region).each do |attr|
182
+ next unless condition[attr]
183
+ if translated = @language_config['locations'][condition[attr]]
184
+ condition[attr] = translated
185
+ end
186
+ end
187
+
188
+ condition
189
+ end
190
+
191
+ def translate!(attribute)
192
+ if i18n?
193
+ make_translations! attribute
194
+ else
195
+ attribute
196
+ end
197
+ end
198
+
199
+ def i18n?
200
+ @language
201
+ end
202
+ end
203
+ end
@@ -0,0 +1,56 @@
1
+ path = File.expand_path(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(path) unless $LOAD_PATH.include?(path)
3
+
4
+ require 'open-uri'
5
+ require 'nokogiri'
6
+ require 'yaml'
7
+
8
+ require 'yahoo_weatherman/image'
9
+ require 'yahoo_weatherman/response'
10
+
11
+ module Weatherman
12
+
13
+ VERSION = '0.2'
14
+
15
+ URI = 'http://weather.yahooapis.com/forecastrss'
16
+
17
+ I18N_YAML_DIR = File.expand_path(File.dirname(__FILE__) + '/../i18n/')
18
+
19
+ # = Client
20
+ #
21
+ # The weatherman client. Where it all begins.
22
+ #
23
+ class Client
24
+ attr_reader :options
25
+
26
+ def initialize(options = {})
27
+ @options = options
28
+ end
29
+
30
+ #
31
+ # Just pass in a +woeid+ and it will return a Weatherman::Response object:w
32
+ #
33
+ def lookup_by_woeid(woeid)
34
+ raw = get request_url(woeid)
35
+ Response.new(raw, options[:lang])
36
+ end
37
+
38
+ private
39
+ def request_url(woeid)
40
+ URI + query_string(woeid)
41
+ end
42
+
43
+ def query_string(woeid)
44
+ "?w=#{woeid}&u=#{degrees_units}"
45
+ end
46
+
47
+ def degrees_units
48
+ options[:degrees_units] || 'c'
49
+ end
50
+
51
+ def get(url)
52
+ open(url) { |stream| stream.read }
53
+ end
54
+ end
55
+
56
+ end
@@ -0,0 +1,49 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
2
+ <rss version="2.0" xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
3
+ <channel>
4
+
5
+ <title>Yahoo! Weather - Belo Horizonte, BR</title>
6
+ <link>http://us.rd.yahoo.com/dailynews/rss/weather/Belo_Horizonte__BR/*http://weather.yahoo.com/forecast/BRXX0033_c.html</link>
7
+ <description>Yahoo! Weather for Belo Horizonte, BR</description>
8
+ <language>en-us</language>
9
+ <lastBuildDate>Sat, 13 Mar 2010 6:00 pm LST</lastBuildDate>
10
+ <ttl>60</ttl>
11
+ <yweather:location city="Belo Horizonte" region="MG" country="Brazil"/>
12
+
13
+ <yweather:units temperature="C" distance="km" pressure="mb" speed="km/h"/>
14
+ <yweather:wind chill="28" direction="340" speed="9.66" />
15
+ <yweather:atmosphere humidity="62" visibility="9.99" pressure="982.05" rising="0" />
16
+ <yweather:astronomy sunrise="5:57 am" sunset="6:13 pm"/>
17
+ <image>
18
+ <title>Yahoo! Weather</title>
19
+ <width>142</width>
20
+ <height>18</height>
21
+ <link>http://weather.yahoo.com</link>
22
+ <url>http://l.yimg.com/a/i/us/nws/th/main_142b.gif</url>
23
+ </image>
24
+ <item>
25
+
26
+ <title>Conditions for Belo Horizonte, BR at 6:00 pm LST</title>
27
+ <geo:lat>-19.95</geo:lat>
28
+ <geo:long>-43.93</geo:long>
29
+ <link>http://us.rd.yahoo.com/dailynews/rss/weather/Belo_Horizonte__BR/*http://weather.yahoo.com/forecast/BRXX0033_c.html</link>
30
+ <pubDate>Sat, 13 Mar 2010 6:00 pm LST</pubDate>
31
+ <yweather:condition text="Mostly Cloudy" code="28" temp="28" date="Sat, 13 Mar 2010 6:00 pm LST" />
32
+ <description><![CDATA[
33
+ <img src="http://l.yimg.com/a/i/us/we/52/28.gif"/><br />
34
+ <b>Current Conditions:</b><br />
35
+ Mostly Cloudy, 28 C<BR />
36
+ <BR /><b>Forecast:</b><BR />
37
+ Sat - Showers. High: 27 Low: 18<br />
38
+ Sun - Scattered Thunderstorms. High: 27 Low: 18<br />
39
+ <br />
40
+ <a href="http://us.rd.yahoo.com/dailynews/rss/weather/Belo_Horizonte__BR/*http://weather.yahoo.com/forecast/BRXX0033_c.html">Full Forecast at Yahoo! Weather</a><BR/><BR/>
41
+ (provided by <a href="http://www.weather.com" >The Weather Channel</a>)<br/>
42
+ ]]></description>
43
+ <yweather:forecast day="Sat" date="13 Mar 2010" low="18" high="27" text="Showers" code="11" />
44
+ <yweather:forecast day="Sun" date="14 Mar 2010" low="18" high="27" text="Scattered Thunderstorms" code="38" />
45
+ <guid isPermaLink="false">BRXX0033_2010_03_13_18_00_LST</guid>
46
+ </item>
47
+
48
+ </channel>
49
+ </rss><!-- api5.weather.ac4.yahoo.com compressed/chunked Sat Mar 13 14:29:51 PST 2010 -->
@@ -0,0 +1,15 @@
1
+ path = File.expand_path(File.dirname(__FILE__) + "/../lib/")
2
+ $LOAD_PATH.unshift(path) unless $LOAD_PATH.include?(path)
3
+
4
+ require 'rubygems'
5
+ require 'fakeweb'
6
+ require 'yahoo_weatherman'
7
+ require 'spec'
8
+
9
+ def fixture
10
+ filepath = File.expand_path(File.dirname(__FILE__) + "/files/belo_horizonte.rss")
11
+ File.read filepath
12
+ end
13
+
14
+ FakeWeb.allow_net_connect = false
15
+ FakeWeb.register_uri(:get, "http://weather.yahooapis.com/forecastrss?w=455821&u=c", :body => fixture)
@@ -0,0 +1,104 @@
1
+ require 'spec_helper'
2
+
3
+ describe Weatherman::Response do
4
+ before do
5
+ @response = Weatherman::Client.new.lookup_by_woeid 455821
6
+ end
7
+
8
+ it 'should provide a location' do
9
+ @response.location['city'].should == 'Belo Horizonte'
10
+ @response.location['region'].should == 'MG'
11
+ @response.location['country'].should == 'Brazil'
12
+ end
13
+
14
+ it 'should provide a weather condition' do
15
+ @response.condition['code'].should == 28
16
+ @response.condition['temp'].should == 28
17
+ @response.condition['text'].should == 'Mostly Cloudy'
18
+ @response.condition['date'].should == Date.parse('Sat, 13 Mar 2010 11:00 pm LST')
19
+ end
20
+
21
+ it 'should provide the units used' do
22
+ @response.units['temperature'].should == 'C'
23
+ @response.units['distance'].should == 'km'
24
+ @response.units['pressure'].should == 'mb'
25
+ @response.units['speed'].should == 'km/h'
26
+ end
27
+
28
+ it 'should provide information about the wind' do
29
+ @response.wind['chill'].should == 28
30
+ @response.wind['direction'].should == 340
31
+ @response.wind['speed'].should == 9.66
32
+ end
33
+
34
+ it 'should provide astronomy information' do
35
+ @response.astronomy['sunrise'].should == '5:57 am'
36
+ @response.astronomy['sunset'].should == '6:13 pm'
37
+ end
38
+
39
+ it 'should get the next 2 forecasts' do
40
+ first = @response.forecasts.first
41
+ first['day'].should == 'Sat'
42
+ first['date'].should == Date.parse('13 Mar 2010')
43
+ first['low'].should == 18
44
+ first['high'].should == 27
45
+ first['text'].should == 'Showers'
46
+ first['code'].should == 11
47
+
48
+ last = @response.forecasts.last
49
+ last['day'].should == 'Sun'
50
+ last['date'].should == Date.parse('14 Mar 2010')
51
+ last['low'].should == 18
52
+ last['high'].should == 27
53
+ last['text'].should == 'Scattered Thunderstorms'
54
+ last['code'].should == 38
55
+ end
56
+
57
+ it 'it should provide latitude and longitude' do
58
+ @response.latitude.should == -19.95
59
+ @response.longitude.should == -43.93
60
+ end
61
+
62
+ it 'should provide a description' do
63
+ description = <<-DESCRIPTION
64
+
65
+ <img src="http://l.yimg.com/a/i/us/we/52/28.gif"/><br />
66
+ <b>Current Conditions:</b><br />
67
+ Mostly Cloudy, 28 C<BR />
68
+ <BR /><b>Forecast:</b><BR />
69
+ Sat - Showers. High: 27 Low: 18<br />
70
+ Sun - Scattered Thunderstorms. High: 27 Low: 18<br />
71
+ <br />
72
+ <a href="http://us.rd.yahoo.com/dailynews/rss/weather/Belo_Horizonte__BR/*http://weather.yahoo.com/forecast/BRXX0033_c.html">Full Forecast at Yahoo! Weather</a><BR/><BR/>
73
+ (provided by <a href="http://www.weather.com" >The Weather Channel</a>)<br/>
74
+ DESCRIPTION
75
+
76
+ @response.description.should == description
77
+ end
78
+
79
+ it 'should provide the weather image attributes' do
80
+ image = @response.image
81
+ image['width'].should == 142
82
+ image['height'].should == 18
83
+ image['title'].should == 'Yahoo! Weather'
84
+ image['link'].should == 'http://weather.yahoo.com'
85
+ image['url'].should == 'http://l.yimg.com/a/i/us/nws/th/main_142b.gif'
86
+ end
87
+
88
+ context 'using internationalization' do
89
+ before do
90
+ @response = Weatherman::Client.new(:lang => 'pt-br').lookup_by_woeid 455821
91
+ end
92
+
93
+ it 'should translate the response#conditions attributes' do
94
+ @response.condition['text'].should == 'Predominantemente Nublado'
95
+ end
96
+
97
+ it 'should translate the location details' do
98
+ @response.location['country'].should == 'Brasil'
99
+ @response.location['region'].should == 'Minas Gerais'
100
+ @response.location['city'].should == 'Belzonti'
101
+ end
102
+
103
+ end
104
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe Weatherman::Client do
4
+ before do
5
+ @client = Weatherman::Client.new
6
+ end
7
+
8
+ it 'should lookup by woeid' do
9
+ response = @client.lookup_by_woeid 455821
10
+ response.should be_instance_of Weatherman::Response
11
+ end
12
+
13
+ end
@@ -0,0 +1,14 @@
1
+ Gem::Specification.new do |gem|
2
+ gem.name = "yahoo_weatherman"
3
+ gem.version = "0.2"
4
+ gem.authors = ["Dalto Curvelano Junior"]
5
+ gem.description = "A ruby wrapper to the Yahoo! Weather feed with i18n support."
6
+ gem.summary = "A ruby wrapper to the Yahoo! Weather feed with i18n support."
7
+ gem.files = [
8
+ "yahoo_weatherman.gemspec",
9
+ "lib/yahoo_weatherman/image.rb", "lib/yahoo_weatherman/response.rb", "lib/yahoo_weatherman.rb",
10
+ "i18n/pt-br.yml", "spec/files/belo_horizonte.rss", "spec/spec_helper.rb",
11
+ "spec/yahoo_weatherman/response_spec.rb", "spec/yahoo_weatherman/yahoo_weatherman_spec.rb"
12
+ ]
13
+ gem.homepage = "http://github.com/dlt/yahoo_weatherman"
14
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: yahoo_weatherman
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 2
8
+ version: "0.2"
9
+ platform: ruby
10
+ authors:
11
+ - Dalto Curvelano Junior
12
+ autorequire:
13
+ bindir: bin
14
+ cert_chain: []
15
+
16
+ date: 2010-03-15 00:00:00 -03:00
17
+ default_executable:
18
+ dependencies: []
19
+
20
+ description: A ruby wrapper to the Yahoo! Weather feed with i18n support.
21
+ email:
22
+ executables: []
23
+
24
+ extensions: []
25
+
26
+ extra_rdoc_files: []
27
+
28
+ files:
29
+ - yahoo_weatherman.gemspec
30
+ - lib/yahoo_weatherman/image.rb
31
+ - lib/yahoo_weatherman/response.rb
32
+ - lib/yahoo_weatherman.rb
33
+ - i18n/pt-br.yml
34
+ - spec/files/belo_horizonte.rss
35
+ - spec/spec_helper.rb
36
+ - spec/yahoo_weatherman/response_spec.rb
37
+ - spec/yahoo_weatherman/yahoo_weatherman_spec.rb
38
+ has_rdoc: true
39
+ homepage: http://github.com/dlt/yahoo_weatherman
40
+ licenses: []
41
+
42
+ post_install_message:
43
+ rdoc_options: []
44
+
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ segments:
52
+ - 0
53
+ version: "0"
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ requirements: []
62
+
63
+ rubyforge_project:
64
+ rubygems_version: 1.3.6
65
+ signing_key:
66
+ specification_version: 3
67
+ summary: A ruby wrapper to the Yahoo! Weather feed with i18n support.
68
+ test_files: []
69
+