yahoo_weatherman 0.2

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.
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
+