weather_hacker 0.0.1
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/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +52 -0
- data/Rakefile +2 -0
- data/lib/weather_hacker/client.rb +134 -0
- data/lib/weather_hacker/version.rb +3 -0
- data/lib/weather_hacker.rb +8 -0
- data/spec/fixtures/id_by_city.rb +144 -0
- data/spec/fixtures/pref_by_city.rb +144 -0
- data/spec/fixtures/response_from_weather_api.rb +327 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/weather_hacker/client_spec.rb +49 -0
- data/spec/weather_hacker_spec.rb +9 -0
- data/weather_hacker.gemspec +20 -0
- metadata +88 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Ryo NAKAMURA
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# WeatherHacker
|
2
|
+
|
3
|
+
Library for [Livedoor Weather Web Service](http://weather.livedoor.com/weather_hacks/webservice.html)
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'weather_hacker'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install weather_hacker
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
~~~
|
21
|
+
require "weather_hacker"
|
22
|
+
|
23
|
+
zipcode = "690-0261"
|
24
|
+
client = WeatherHacker::Client.new
|
25
|
+
|
26
|
+
client.get_weather(zipcode)
|
27
|
+
#=> {
|
28
|
+
# "weather" => "晴れ",
|
29
|
+
# "temperature" => { "max" => "18", "min" => "1" }
|
30
|
+
# }
|
31
|
+
|
32
|
+
client.get_weather(zipcode. :tomorrow)
|
33
|
+
#=> {
|
34
|
+
# "weather" => "晴時々曇",
|
35
|
+
# "temperature" => { "max" => 21, "min" => 9 }
|
36
|
+
# }
|
37
|
+
|
38
|
+
|
39
|
+
client.get_weather(zipcode. :tomorrow)
|
40
|
+
#=> {
|
41
|
+
# "weather" => "晴時々曇",
|
42
|
+
# "temperature" => { "max" => nil, "min" => nil }
|
43
|
+
# }
|
44
|
+
~~~
|
45
|
+
|
46
|
+
## Contributing
|
47
|
+
|
48
|
+
1. Fork it
|
49
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
50
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
51
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
52
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module WeatherHacker
|
4
|
+
class Client
|
5
|
+
include HTTParty
|
6
|
+
|
7
|
+
WEATHER_URL = "http://weather.livedoor.com/forecast/webservice/rest/v1"
|
8
|
+
AREA_TABLE_URL = "http://weather.livedoor.com/forecast/rss/forecastmap.xml"
|
9
|
+
ZIPCODE_URL = "http://zip.cgis.biz/xml/zip.php"
|
10
|
+
|
11
|
+
# get weather data by zipcode
|
12
|
+
def get_weather(zipcode, opts = {})
|
13
|
+
city_id = city_id_by_zipcode(zipcode) or return
|
14
|
+
query = { :city => city_id, :day => :today }.merge(opts)
|
15
|
+
hash = get WEATHER_URL, :query => query
|
16
|
+
|
17
|
+
{
|
18
|
+
"weather" => hash["lwws"]["telop"],
|
19
|
+
"temperature" => {
|
20
|
+
"max" => hash["lwws"]["temperature"]["max"]["celsius"],
|
21
|
+
"min" => hash["lwws"]["temperature"]["min"]["celsius"],
|
22
|
+
},
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
# set @pref_by_city and @id_by_city
|
27
|
+
def update_area_table
|
28
|
+
hash = get AREA_TABLE_URL
|
29
|
+
parse_area_table(hash)
|
30
|
+
end
|
31
|
+
|
32
|
+
# return city id via zipcode API
|
33
|
+
def city_id_by_zipcode(zipcode)
|
34
|
+
zipcode = zipcode.to_s.tr("0-9", "0-9").tr("-", "").tr("-", "")
|
35
|
+
return unless zipcode.match(/^\d{7}$/)
|
36
|
+
|
37
|
+
hash = info_by_zipcode(zipcode)
|
38
|
+
city = canonical_city(hash["city"])
|
39
|
+
pref = canonical_pref(hash["state"])
|
40
|
+
id_by_city[city] || id_by_city[pref] || id_by_pref[pref]
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
# use HTTParty.get
|
46
|
+
def get(*args)
|
47
|
+
self.class.get(*args)
|
48
|
+
end
|
49
|
+
|
50
|
+
# return like following Hash
|
51
|
+
# {
|
52
|
+
# "state_kana" => "トウキョウト",
|
53
|
+
# "city_kana" => "ミナトク",
|
54
|
+
# "address_kana" => "シロカネダイ",
|
55
|
+
# "company_kana" => "none",
|
56
|
+
# "state" => "東京都",
|
57
|
+
# "city" => "港区",
|
58
|
+
# "address" => "白金台",
|
59
|
+
# "company" => "none"
|
60
|
+
# }
|
61
|
+
def info_by_zipcode(zipcode)
|
62
|
+
response = get ZIPCODE_URL, :query => { :zn => zipcode }
|
63
|
+
values = response["ZIP_result"]["ADDRESS_value"]["value"]
|
64
|
+
Hash[values.map { |v| v.to_a.flatten }]
|
65
|
+
end
|
66
|
+
|
67
|
+
# update area table once
|
68
|
+
def pref_by_city
|
69
|
+
@pref_by_city ||= begin
|
70
|
+
update_area_table
|
71
|
+
@pref_by_city
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# update area table once
|
76
|
+
def id_by_city
|
77
|
+
@id_by_city ||= begin
|
78
|
+
update_area_table
|
79
|
+
@id_by_city
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# return typical city's id
|
84
|
+
def id_by_pref
|
85
|
+
@id_by_pref ||= pref_by_city.inject({}) { |hash, item|
|
86
|
+
k, v = item
|
87
|
+
hash[k] ||= v
|
88
|
+
hash
|
89
|
+
}
|
90
|
+
end
|
91
|
+
|
92
|
+
# parse area table hash of response from Weather API
|
93
|
+
def parse_area_table(hash)
|
94
|
+
@pref_by_city = {}
|
95
|
+
@id_by_city = {}
|
96
|
+
|
97
|
+
hash["rss"]["channel"]["source"]["area"].each do |area|
|
98
|
+
prefs = [area["pref"]].flatten
|
99
|
+
prefs.each do |pref|
|
100
|
+
pref_name = canonical_pref(pref["title"])
|
101
|
+
|
102
|
+
cities = [pref["city"]].flatten
|
103
|
+
cities.each do |city|
|
104
|
+
id = city["id"].to_i
|
105
|
+
title = city["title"]
|
106
|
+
@id_by_city[title] = id
|
107
|
+
@pref_by_city[title] = pref_name
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
rescue
|
112
|
+
raise ParseError, "Failed to parse area data from API"
|
113
|
+
end
|
114
|
+
|
115
|
+
# canonical prefecture name
|
116
|
+
# 道東 => 北海道
|
117
|
+
# 道央 => 北海道
|
118
|
+
# 道南 => 北海道
|
119
|
+
# 道北 => 北海道
|
120
|
+
def canonical_pref(name)
|
121
|
+
name = name.gsub(/^道.*/, "北海道")
|
122
|
+
name = name.gsub(/[都道府県]$/, "")
|
123
|
+
name
|
124
|
+
end
|
125
|
+
|
126
|
+
# canonical city name
|
127
|
+
def canonical_city(city)
|
128
|
+
city.gsub(/市$/, "")
|
129
|
+
end
|
130
|
+
|
131
|
+
# Custom Error class to raise in parse response from API
|
132
|
+
class ParseError < StandardError; end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
{
|
2
|
+
"稚内" => 1,
|
3
|
+
"旭川" => 2,
|
4
|
+
"留萌" => 3,
|
5
|
+
"札幌" => 4,
|
6
|
+
"岩見沢" => 5,
|
7
|
+
"倶知安" => 6,
|
8
|
+
"網走" => 7,
|
9
|
+
"北見" => 8,
|
10
|
+
"紋別" => 9,
|
11
|
+
"根室" => 10,
|
12
|
+
"釧路" => 11,
|
13
|
+
"帯広" => 12,
|
14
|
+
"室蘭" => 13,
|
15
|
+
"浦河" => 14,
|
16
|
+
"函館" => 15,
|
17
|
+
"江差" => 16,
|
18
|
+
"青森" => 17,
|
19
|
+
"むつ" => 18,
|
20
|
+
"八戸" => 19,
|
21
|
+
"秋田" => 20,
|
22
|
+
"横手" => 21,
|
23
|
+
"盛岡" => 22,
|
24
|
+
"宮古" => 23,
|
25
|
+
"大船渡" => 24,
|
26
|
+
"仙台" => 25,
|
27
|
+
"白石" => 26,
|
28
|
+
"山形" => 27,
|
29
|
+
"米沢" => 28,
|
30
|
+
"酒田" => 29,
|
31
|
+
"新庄" => 30,
|
32
|
+
"福島" => 31,
|
33
|
+
"小名浜" => 32,
|
34
|
+
"若松" => 33,
|
35
|
+
"水戸" => 54,
|
36
|
+
"土浦" => 55,
|
37
|
+
"宇都宮" => 56,
|
38
|
+
"大田原" => 57,
|
39
|
+
"前橋" => 58,
|
40
|
+
"みなかみ" => 59,
|
41
|
+
"さいたま" => 60,
|
42
|
+
"熊谷" => 61,
|
43
|
+
"秩父" => 62,
|
44
|
+
"東京" => 63,
|
45
|
+
"大島" => 64,
|
46
|
+
"八丈島" => 65,
|
47
|
+
"父島" => 66,
|
48
|
+
"千葉" => 67,
|
49
|
+
"銚子" => 68,
|
50
|
+
"館山" => 69,
|
51
|
+
"横浜" => 70,
|
52
|
+
"小田原" => 71,
|
53
|
+
"甲府" => 75,
|
54
|
+
"河口湖" => 76,
|
55
|
+
"富山" => 44,
|
56
|
+
"伏木" => 45,
|
57
|
+
"金沢" => 46,
|
58
|
+
"輪島" => 47,
|
59
|
+
"福井" => 48,
|
60
|
+
"敦賀" => 49,
|
61
|
+
"新潟" => 50,
|
62
|
+
"長岡" => 51,
|
63
|
+
"高田" => 52,
|
64
|
+
"相川" => 53,
|
65
|
+
"長野" => 72,
|
66
|
+
"松本" => 73,
|
67
|
+
"飯田" => 74,
|
68
|
+
"静岡" => 34,
|
69
|
+
"網代" => 35,
|
70
|
+
"三島" => 36,
|
71
|
+
"浜松" => 37,
|
72
|
+
"名古屋" => 38,
|
73
|
+
"豊橋" => 39,
|
74
|
+
"岐阜" => 40,
|
75
|
+
"高山" => 41,
|
76
|
+
"津" => 42,
|
77
|
+
"尾鷲" => 43,
|
78
|
+
"大津" => 77,
|
79
|
+
"彦根" => 78,
|
80
|
+
"京都" => 79,
|
81
|
+
"舞鶴" => 80,
|
82
|
+
"大阪" => 81,
|
83
|
+
"神戸" => 82,
|
84
|
+
"豊岡" => 83,
|
85
|
+
"奈良" => 84,
|
86
|
+
"風屋" => 85,
|
87
|
+
"和歌山" => 86,
|
88
|
+
"潮岬" => 87,
|
89
|
+
"岡山" => 88,
|
90
|
+
"津山" => 89,
|
91
|
+
"広島" => 90,
|
92
|
+
"庄原" => 91,
|
93
|
+
"松江" => 92,
|
94
|
+
"浜田" => 93,
|
95
|
+
"西郷" => 94,
|
96
|
+
"鳥取" => 95,
|
97
|
+
"米子" => 96,
|
98
|
+
"下関" => 97,
|
99
|
+
"山口" => 98,
|
100
|
+
"柳井" => 99,
|
101
|
+
"萩" => 100,
|
102
|
+
"徳島" => 101,
|
103
|
+
"日和佐" => 102,
|
104
|
+
"高松" => 103,
|
105
|
+
"松山" => 104,
|
106
|
+
"新居浜" => 105,
|
107
|
+
"宇和島" => 106,
|
108
|
+
"高知" => 107,
|
109
|
+
"室戸" => 108,
|
110
|
+
"清水" => 109,
|
111
|
+
"福岡" => 110,
|
112
|
+
"八幡" => 111,
|
113
|
+
"飯塚" => 112,
|
114
|
+
"久留米" => 113,
|
115
|
+
"大分" => 114,
|
116
|
+
"中津" => 115,
|
117
|
+
"日田" => 116,
|
118
|
+
"佐伯" => 117,
|
119
|
+
"長崎" => 118,
|
120
|
+
"佐世保" => 119,
|
121
|
+
"厳原" => 120,
|
122
|
+
"福江" => 121,
|
123
|
+
"佐賀" => 122,
|
124
|
+
"伊万里" => 123,
|
125
|
+
"熊本" => 124,
|
126
|
+
"阿蘇乙姫" => 125,
|
127
|
+
"牛深" => 126,
|
128
|
+
"人吉" => 127,
|
129
|
+
"宮崎" => 128,
|
130
|
+
"延岡" => 129,
|
131
|
+
"都城" => 130,
|
132
|
+
"高千穂" => 131,
|
133
|
+
"鹿児島" => 132,
|
134
|
+
"鹿屋" => 133,
|
135
|
+
"種子島" => 134,
|
136
|
+
"名瀬" => 135,
|
137
|
+
"那覇" => 136,
|
138
|
+
"名護" => 137,
|
139
|
+
"久米島" => 138,
|
140
|
+
"南大東島" => 139,
|
141
|
+
"宮古島" => 140,
|
142
|
+
"石垣島" => 141,
|
143
|
+
"与那国島" => 142
|
144
|
+
}
|
@@ -0,0 +1,144 @@
|
|
1
|
+
{
|
2
|
+
"稚内" => "北海",
|
3
|
+
"旭川" => "北海",
|
4
|
+
"留萌" => "北海",
|
5
|
+
"札幌" => "北海",
|
6
|
+
"岩見沢" => "北海",
|
7
|
+
"倶知安" => "北海",
|
8
|
+
"網走" => "北海",
|
9
|
+
"北見" => "北海",
|
10
|
+
"紋別" => "北海",
|
11
|
+
"根室" => "北海",
|
12
|
+
"釧路" => "北海",
|
13
|
+
"帯広" => "北海",
|
14
|
+
"室蘭" => "北海",
|
15
|
+
"浦河" => "北海",
|
16
|
+
"函館" => "北海",
|
17
|
+
"江差" => "北海",
|
18
|
+
"青森" => "青森",
|
19
|
+
"むつ" => "青森",
|
20
|
+
"八戸" => "青森",
|
21
|
+
"秋田" => "秋田",
|
22
|
+
"横手" => "秋田",
|
23
|
+
"盛岡" => "岩手",
|
24
|
+
"宮古" => "岩手",
|
25
|
+
"大船渡" => "岩手",
|
26
|
+
"仙台" => "宮城",
|
27
|
+
"白石" => "宮城",
|
28
|
+
"山形" => "山形",
|
29
|
+
"米沢" => "山形",
|
30
|
+
"酒田" => "山形",
|
31
|
+
"新庄" => "山形",
|
32
|
+
"福島" => "福島",
|
33
|
+
"小名浜" => "福島",
|
34
|
+
"若松" => "福島",
|
35
|
+
"水戸" => "茨城",
|
36
|
+
"土浦" => "茨城",
|
37
|
+
"宇都宮" => "栃木",
|
38
|
+
"大田原" => "栃木",
|
39
|
+
"前橋" => "群馬",
|
40
|
+
"みなかみ" => "群馬",
|
41
|
+
"さいたま" => "埼玉",
|
42
|
+
"熊谷" => "埼玉",
|
43
|
+
"秩父" => "埼玉",
|
44
|
+
"東京" => "東京",
|
45
|
+
"大島" => "東京",
|
46
|
+
"八丈島" => "東京",
|
47
|
+
"父島" => "東京",
|
48
|
+
"千葉" => "千葉",
|
49
|
+
"銚子" => "千葉",
|
50
|
+
"館山" => "千葉",
|
51
|
+
"横浜" => "神奈川",
|
52
|
+
"小田原" => "神奈川",
|
53
|
+
"甲府" => "山梨",
|
54
|
+
"河口湖" => "山梨",
|
55
|
+
"富山" => "富山",
|
56
|
+
"伏木" => "富山",
|
57
|
+
"金沢" => "石川",
|
58
|
+
"輪島" => "石川",
|
59
|
+
"福井" => "福井",
|
60
|
+
"敦賀" => "福井",
|
61
|
+
"新潟" => "新潟",
|
62
|
+
"長岡" => "新潟",
|
63
|
+
"高田" => "新潟",
|
64
|
+
"相川" => "新潟",
|
65
|
+
"長野" => "長野",
|
66
|
+
"松本" => "長野",
|
67
|
+
"飯田" => "長野",
|
68
|
+
"静岡" => "静岡",
|
69
|
+
"網代" => "静岡",
|
70
|
+
"三島" => "静岡",
|
71
|
+
"浜松" => "静岡",
|
72
|
+
"名古屋" => "愛知",
|
73
|
+
"豊橋" => "愛知",
|
74
|
+
"岐阜" => "岐阜",
|
75
|
+
"高山" => "岐阜",
|
76
|
+
"津" => "三重",
|
77
|
+
"尾鷲" => "三重",
|
78
|
+
"大津" => "滋賀",
|
79
|
+
"彦根" => "滋賀",
|
80
|
+
"京都" => "京都",
|
81
|
+
"舞鶴" => "京都",
|
82
|
+
"大阪" => "大阪",
|
83
|
+
"神戸" => "兵庫",
|
84
|
+
"豊岡" => "兵庫",
|
85
|
+
"奈良" => "奈良",
|
86
|
+
"風屋" => "奈良",
|
87
|
+
"和歌山" => "和歌山",
|
88
|
+
"潮岬" => "和歌山",
|
89
|
+
"岡山" => "岡山",
|
90
|
+
"津山" => "岡山",
|
91
|
+
"広島" => "広島",
|
92
|
+
"庄原" => "広島",
|
93
|
+
"松江" => "島根",
|
94
|
+
"浜田" => "島根",
|
95
|
+
"西郷" => "島根",
|
96
|
+
"鳥取" => "鳥取",
|
97
|
+
"米子" => "鳥取",
|
98
|
+
"下関" => "山口",
|
99
|
+
"山口" => "山口",
|
100
|
+
"柳井" => "山口",
|
101
|
+
"萩" => "山口",
|
102
|
+
"徳島" => "徳島",
|
103
|
+
"日和佐" => "徳島",
|
104
|
+
"高松" => "香川",
|
105
|
+
"松山" => "愛媛",
|
106
|
+
"新居浜" => "愛媛",
|
107
|
+
"宇和島" => "愛媛",
|
108
|
+
"高知" => "高知",
|
109
|
+
"室戸" => "高知",
|
110
|
+
"清水" => "高知",
|
111
|
+
"福岡" => "福岡",
|
112
|
+
"八幡" => "福岡",
|
113
|
+
"飯塚" => "福岡",
|
114
|
+
"久留米" => "福岡",
|
115
|
+
"大分" => "大分",
|
116
|
+
"中津" => "大分",
|
117
|
+
"日田" => "大分",
|
118
|
+
"佐伯" => "大分",
|
119
|
+
"長崎" => "長崎",
|
120
|
+
"佐世保" => "長崎",
|
121
|
+
"厳原" => "長崎",
|
122
|
+
"福江" => "長崎",
|
123
|
+
"佐賀" => "佐賀",
|
124
|
+
"伊万里" => "佐賀",
|
125
|
+
"熊本" => "熊本",
|
126
|
+
"阿蘇乙姫" => "熊本",
|
127
|
+
"牛深" => "熊本",
|
128
|
+
"人吉" => "熊本",
|
129
|
+
"宮崎" => "宮崎",
|
130
|
+
"延岡" => "宮崎",
|
131
|
+
"都城" => "宮崎",
|
132
|
+
"高千穂" => "宮崎",
|
133
|
+
"鹿児島" => "鹿児島",
|
134
|
+
"鹿屋" => "鹿児島",
|
135
|
+
"種子島" => "鹿児島",
|
136
|
+
"名瀬" => "鹿児島",
|
137
|
+
"那覇" => "沖縄",
|
138
|
+
"名護" => "沖縄",
|
139
|
+
"久米島" => "沖縄",
|
140
|
+
"南大東島" => "沖縄",
|
141
|
+
"宮古島" => "沖縄",
|
142
|
+
"石垣島" => "沖縄",
|
143
|
+
"与那国島" => "沖縄"
|
144
|
+
}
|
@@ -0,0 +1,327 @@
|
|
1
|
+
{
|
2
|
+
"lwws" => {
|
3
|
+
"author" => "livedoor Weather Team.",
|
4
|
+
"location" => {
|
5
|
+
"area" => "関東",
|
6
|
+
"pref" => "東京都",
|
7
|
+
"city" => "東京"
|
8
|
+
},
|
9
|
+
"title" => "東京都 東京 - 今日の天気",
|
10
|
+
"link" => "http://weather.livedoor.com/area/13/63.html?v=1",
|
11
|
+
"forecastday" => "today",
|
12
|
+
"day" => "Saturday",
|
13
|
+
"forecastdate" => "Sat, 07 Apr 2012 00:00:00 +0900",
|
14
|
+
"publictime" => "Sat, 07 Apr 2012 17:00:00 +0900",
|
15
|
+
"telop" => "晴時々曇",
|
16
|
+
"description" => "伊豆諸島南部では強風に、伊豆諸島北部、伊豆諸島南部では高波に、東京地方、伊豆諸島南部では空気の乾燥による火の取り扱いに、伊豆諸島北部では霜に対する農作...<br />[PR]<a href=\"http://weather.livedoor.com/indexes/cloth_wash/?r=rest_pr\">きょうは洗濯できるかな?</a>",
|
17
|
+
"image" => {
|
18
|
+
"title" => "晴時々曇",
|
19
|
+
"link" => "http://weather.livedoor.com/area/13/63.html?v=1",
|
20
|
+
"url" => "http://image.weather.livedoor.com/img/icon/2.gif",
|
21
|
+
"width" => "50",
|
22
|
+
"height" => "31"
|
23
|
+
},
|
24
|
+
"temperature" => {
|
25
|
+
"max" => {
|
26
|
+
"celsius" => nil,
|
27
|
+
"fahrenheit" => nil
|
28
|
+
},
|
29
|
+
"min" => {
|
30
|
+
"celsius" => nil,
|
31
|
+
"fahrenheit" => nil
|
32
|
+
}
|
33
|
+
},
|
34
|
+
"pinpoint" => {
|
35
|
+
"location" => [
|
36
|
+
{
|
37
|
+
"title" => "千代田区",
|
38
|
+
"link" => "http://weather.livedoor.com/p/13/63/13101.html",
|
39
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
40
|
+
},
|
41
|
+
{
|
42
|
+
"title" => "中央区",
|
43
|
+
"link" => "http://weather.livedoor.com/p/13/63/13102.html",
|
44
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
45
|
+
},
|
46
|
+
{
|
47
|
+
"title" => "港区",
|
48
|
+
"link" => "http://weather.livedoor.com/p/13/63/13103.html",
|
49
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
50
|
+
},
|
51
|
+
{
|
52
|
+
"title" => "新宿区",
|
53
|
+
"link" => "http://weather.livedoor.com/p/13/63/13104.html",
|
54
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
55
|
+
},
|
56
|
+
{
|
57
|
+
"title" => "文京区",
|
58
|
+
"link" => "http://weather.livedoor.com/p/13/63/13105.html",
|
59
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
60
|
+
},
|
61
|
+
{
|
62
|
+
"title" => "台東区",
|
63
|
+
"link" => "http://weather.livedoor.com/p/13/63/13106.html",
|
64
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
65
|
+
},
|
66
|
+
{
|
67
|
+
"title" => "墨田区",
|
68
|
+
"link" => "http://weather.livedoor.com/p/13/63/13107.html",
|
69
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
70
|
+
},
|
71
|
+
{
|
72
|
+
"title" => "江東区",
|
73
|
+
"link" => "http://weather.livedoor.com/p/13/63/13108.html",
|
74
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
75
|
+
},
|
76
|
+
{
|
77
|
+
"title" => "品川区",
|
78
|
+
"link" => "http://weather.livedoor.com/p/13/63/13109.html",
|
79
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
80
|
+
},
|
81
|
+
{
|
82
|
+
"title" => "目黒区",
|
83
|
+
"link" => "http://weather.livedoor.com/p/13/63/13110.html",
|
84
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
85
|
+
},
|
86
|
+
{
|
87
|
+
"title" => "大田区",
|
88
|
+
"link" => "http://weather.livedoor.com/p/13/63/13111.html",
|
89
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
90
|
+
},
|
91
|
+
{
|
92
|
+
"title" => "世田谷区",
|
93
|
+
"link" => "http://weather.livedoor.com/p/13/63/13112.html",
|
94
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
95
|
+
},
|
96
|
+
{
|
97
|
+
"title" => "渋谷区",
|
98
|
+
"link" => "http://weather.livedoor.com/p/13/63/13113.html",
|
99
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
100
|
+
},
|
101
|
+
{
|
102
|
+
"title" => "中野区",
|
103
|
+
"link" => "http://weather.livedoor.com/p/13/63/13114.html",
|
104
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
105
|
+
},
|
106
|
+
{
|
107
|
+
"title" => "杉並区",
|
108
|
+
"link" => "http://weather.livedoor.com/p/13/63/13115.html",
|
109
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
110
|
+
},
|
111
|
+
{
|
112
|
+
"title" => "豊島区",
|
113
|
+
"link" => "http://weather.livedoor.com/p/13/63/13116.html",
|
114
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
115
|
+
},
|
116
|
+
{
|
117
|
+
"title" => "北区",
|
118
|
+
"link" => "http://weather.livedoor.com/p/13/63/13117.html",
|
119
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
120
|
+
},
|
121
|
+
{
|
122
|
+
"title" => "荒川区",
|
123
|
+
"link" => "http://weather.livedoor.com/p/13/63/13118.html",
|
124
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
125
|
+
},
|
126
|
+
{
|
127
|
+
"title" => "板橋区",
|
128
|
+
"link" => "http://weather.livedoor.com/p/13/63/13119.html",
|
129
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
130
|
+
},
|
131
|
+
{
|
132
|
+
"title" => "練馬区",
|
133
|
+
"link" => "http://weather.livedoor.com/p/13/63/13120.html",
|
134
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
135
|
+
},
|
136
|
+
{
|
137
|
+
"title" => "足立区",
|
138
|
+
"link" => "http://weather.livedoor.com/p/13/63/13121.html",
|
139
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
140
|
+
},
|
141
|
+
{
|
142
|
+
"title" => "葛飾区",
|
143
|
+
"link" => "http://weather.livedoor.com/p/13/63/13122.html",
|
144
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
145
|
+
},
|
146
|
+
{
|
147
|
+
"title" => "江戸川区",
|
148
|
+
"link" => "http://weather.livedoor.com/p/13/63/13123.html",
|
149
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
150
|
+
},
|
151
|
+
{
|
152
|
+
"title" => "八王子市",
|
153
|
+
"link" => "http://weather.livedoor.com/p/13/63/13201.html",
|
154
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
155
|
+
},
|
156
|
+
{
|
157
|
+
"title" => "立川市",
|
158
|
+
"link" => "http://weather.livedoor.com/p/13/63/13202.html",
|
159
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
160
|
+
},
|
161
|
+
{
|
162
|
+
"title" => "武蔵野市",
|
163
|
+
"link" => "http://weather.livedoor.com/p/13/63/13203.html",
|
164
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
165
|
+
},
|
166
|
+
{
|
167
|
+
"title" => "三鷹市",
|
168
|
+
"link" => "http://weather.livedoor.com/p/13/63/13204.html",
|
169
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
170
|
+
},
|
171
|
+
{
|
172
|
+
"title" => "青梅市",
|
173
|
+
"link" => "http://weather.livedoor.com/p/13/63/13205.html",
|
174
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
175
|
+
},
|
176
|
+
{
|
177
|
+
"title" => "府中市",
|
178
|
+
"link" => "http://weather.livedoor.com/p/13/63/13206.html",
|
179
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
180
|
+
},
|
181
|
+
{
|
182
|
+
"title" => "昭島市",
|
183
|
+
"link" => "http://weather.livedoor.com/p/13/63/13207.html",
|
184
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
185
|
+
},
|
186
|
+
{
|
187
|
+
"title" => "調布市",
|
188
|
+
"link" => "http://weather.livedoor.com/p/13/63/13208.html",
|
189
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
190
|
+
},
|
191
|
+
{
|
192
|
+
"title" => "町田市",
|
193
|
+
"link" => "http://weather.livedoor.com/p/13/63/13209.html",
|
194
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
195
|
+
},
|
196
|
+
{
|
197
|
+
"title" => "小金井市",
|
198
|
+
"link" => "http://weather.livedoor.com/p/13/63/13210.html",
|
199
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
200
|
+
},
|
201
|
+
{
|
202
|
+
"title" => "小平市",
|
203
|
+
"link" => "http://weather.livedoor.com/p/13/63/13211.html",
|
204
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
205
|
+
},
|
206
|
+
{
|
207
|
+
"title" => "日野市",
|
208
|
+
"link" => "http://weather.livedoor.com/p/13/63/13212.html",
|
209
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
210
|
+
},
|
211
|
+
{
|
212
|
+
"title" => "東村山市",
|
213
|
+
"link" => "http://weather.livedoor.com/p/13/63/13213.html",
|
214
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
215
|
+
},
|
216
|
+
{
|
217
|
+
"title" => "国分寺市",
|
218
|
+
"link" => "http://weather.livedoor.com/p/13/63/13214.html",
|
219
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
220
|
+
},
|
221
|
+
{
|
222
|
+
"title" => "国立市",
|
223
|
+
"link" => "http://weather.livedoor.com/p/13/63/13215.html",
|
224
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
225
|
+
},
|
226
|
+
{
|
227
|
+
"title" => "福生市",
|
228
|
+
"link" => "http://weather.livedoor.com/p/13/63/13218.html",
|
229
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
230
|
+
},
|
231
|
+
{
|
232
|
+
"title" => "狛江市",
|
233
|
+
"link" => "http://weather.livedoor.com/p/13/63/13219.html",
|
234
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
235
|
+
},
|
236
|
+
{
|
237
|
+
"title" => "東大和市",
|
238
|
+
"link" => "http://weather.livedoor.com/p/13/63/13220.html",
|
239
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
240
|
+
},
|
241
|
+
{
|
242
|
+
"title" => "清瀬市",
|
243
|
+
"link" => "http://weather.livedoor.com/p/13/63/13221.html",
|
244
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
245
|
+
},
|
246
|
+
{
|
247
|
+
"title" => "東久留米市",
|
248
|
+
"link" => "http://weather.livedoor.com/p/13/63/13222.html",
|
249
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
250
|
+
},
|
251
|
+
{
|
252
|
+
"title" => "武蔵村山市",
|
253
|
+
"link" => "http://weather.livedoor.com/p/13/63/13223.html",
|
254
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
255
|
+
},
|
256
|
+
{
|
257
|
+
"title" => "多摩市",
|
258
|
+
"link" => "http://weather.livedoor.com/p/13/63/13224.html",
|
259
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
260
|
+
},
|
261
|
+
{
|
262
|
+
"title" => "稲城市",
|
263
|
+
"link" => "http://weather.livedoor.com/p/13/63/13225.html",
|
264
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
265
|
+
},
|
266
|
+
{
|
267
|
+
"title" => "羽村市",
|
268
|
+
"link" => "http://weather.livedoor.com/p/13/63/13227.html",
|
269
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
270
|
+
},
|
271
|
+
{
|
272
|
+
"title" => "あきる野市",
|
273
|
+
"link" => "http://weather.livedoor.com/p/13/63/13228.html",
|
274
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
275
|
+
},
|
276
|
+
{
|
277
|
+
"title" => "西東京市",
|
278
|
+
"link" => "http://weather.livedoor.com/p/13/63/13229.html",
|
279
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
280
|
+
},
|
281
|
+
{
|
282
|
+
"title" => "瑞穂町",
|
283
|
+
"link" => "http://weather.livedoor.com/p/13/63/13303.html",
|
284
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
285
|
+
},
|
286
|
+
{
|
287
|
+
"title" => "日の出町",
|
288
|
+
"link" => "http://weather.livedoor.com/p/13/63/13305.html",
|
289
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
290
|
+
},
|
291
|
+
{
|
292
|
+
"title" => "檜原村",
|
293
|
+
"link" => "http://weather.livedoor.com/p/13/63/13307.html",
|
294
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
295
|
+
},
|
296
|
+
{
|
297
|
+
"title" => "奥多摩町",
|
298
|
+
"link" => "http://weather.livedoor.com/p/13/63/13308.html",
|
299
|
+
"publictime" => "Sat, 07 Apr 2012 18:00:00 +0900"
|
300
|
+
}
|
301
|
+
]
|
302
|
+
},
|
303
|
+
"copyright" => {
|
304
|
+
"title" => "Copyright (C) 1996-2012 livedoor Co.,Ltd. All rights reserved.",
|
305
|
+
"link" => "http://weather.livedoor.com",
|
306
|
+
"image" => {
|
307
|
+
"title" => "livedoor 天気情報",
|
308
|
+
"link" => "http://weather.livedoor.com",
|
309
|
+
"url" => "http://image.weather.livedoor.com/img/cmn/livedoor.gif",
|
310
|
+
"width" => "118",
|
311
|
+
"height" => "26"
|
312
|
+
},
|
313
|
+
"provider" => [
|
314
|
+
{
|
315
|
+
"name" => "(株)ハレックス",
|
316
|
+
"link" => "http://www.halex.co.jp/halexbrain/weather/"
|
317
|
+
},
|
318
|
+
{
|
319
|
+
"name" => "日本気象協会",
|
320
|
+
"link" => "http://tenki.jp/"
|
321
|
+
}
|
322
|
+
]
|
323
|
+
},
|
324
|
+
"version" => "livedoor Weather Web Service 1.0"
|
325
|
+
}
|
326
|
+
}
|
327
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe "WeatherHacker::Client" do
|
6
|
+
before do
|
7
|
+
@client = WeatherHacker::Client.new
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "#get_weather" do
|
11
|
+
before do
|
12
|
+
zipcode = "690-0261"
|
13
|
+
@result = @client.get_weather(zipcode)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "get parsed weather data in Hash" do
|
17
|
+
[Hash, NilClass].should be_include @result.class
|
18
|
+
end
|
19
|
+
|
20
|
+
it "has weather" do
|
21
|
+
@result["weather"].should =~ /[晴曇雨]/
|
22
|
+
end
|
23
|
+
|
24
|
+
it "has max and min temperature" do
|
25
|
+
@result["temperature"].has_key?("max").should be_true
|
26
|
+
@result["temperature"].has_key?("min").should be_true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#update_area_table" do
|
31
|
+
it "has not table at first" do
|
32
|
+
@client.instance_variable_get(:@id_by_city).should be_nil
|
33
|
+
@client.instance_variable_get(:@pref_by_city).should be_nil
|
34
|
+
end
|
35
|
+
|
36
|
+
it "has area table after call" do
|
37
|
+
@client.update_area_table
|
38
|
+
@client.send(:id_by_city).keys.size.should_not == 0
|
39
|
+
@client.send(:pref_by_city).keys.size.should_not == 0
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "#city_id_by_zipcode" do
|
44
|
+
it "return city_id" do
|
45
|
+
city_id = @client.city_id_by_zipcode("108-0071")
|
46
|
+
city_id.should be_kind_of Integer
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/weather_hacker/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Ryo NAKAMURA"]
|
6
|
+
gem.email = ["r7kamura@gmail.com"]
|
7
|
+
gem.description = %q{Library for Livedoor Weather Web Service}
|
8
|
+
gem.summary = %q{Weather Forecaster via Livedoor Weather Web Service}
|
9
|
+
gem.homepage = "https://github.com/r7kamura/weather_hacker"
|
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_hacker"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = WeatherHacker::VERSION
|
17
|
+
|
18
|
+
gem.add_dependency "httparty"
|
19
|
+
gem.add_development_dependency "rspec"
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: weather_hacker
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Ryo NAKAMURA
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-04-07 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: httparty
|
16
|
+
requirement: &70112687112240 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70112687112240
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rspec
|
27
|
+
requirement: &70112687111760 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70112687111760
|
36
|
+
description: Library for Livedoor Weather Web Service
|
37
|
+
email:
|
38
|
+
- r7kamura@gmail.com
|
39
|
+
executables: []
|
40
|
+
extensions: []
|
41
|
+
extra_rdoc_files: []
|
42
|
+
files:
|
43
|
+
- .gitignore
|
44
|
+
- Gemfile
|
45
|
+
- LICENSE
|
46
|
+
- README.md
|
47
|
+
- Rakefile
|
48
|
+
- lib/weather_hacker.rb
|
49
|
+
- lib/weather_hacker/client.rb
|
50
|
+
- lib/weather_hacker/version.rb
|
51
|
+
- spec/fixtures/id_by_city.rb
|
52
|
+
- spec/fixtures/pref_by_city.rb
|
53
|
+
- spec/fixtures/response_from_weather_api.rb
|
54
|
+
- spec/spec_helper.rb
|
55
|
+
- spec/weather_hacker/client_spec.rb
|
56
|
+
- spec/weather_hacker_spec.rb
|
57
|
+
- weather_hacker.gemspec
|
58
|
+
homepage: https://github.com/r7kamura/weather_hacker
|
59
|
+
licenses: []
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options: []
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ! '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
requirements: []
|
77
|
+
rubyforge_project:
|
78
|
+
rubygems_version: 1.8.15
|
79
|
+
signing_key:
|
80
|
+
specification_version: 3
|
81
|
+
summary: Weather Forecaster via Livedoor Weather Web Service
|
82
|
+
test_files:
|
83
|
+
- spec/fixtures/id_by_city.rb
|
84
|
+
- spec/fixtures/pref_by_city.rb
|
85
|
+
- spec/fixtures/response_from_weather_api.rb
|
86
|
+
- spec/spec_helper.rb
|
87
|
+
- spec/weather_hacker/client_spec.rb
|
88
|
+
- spec/weather_hacker_spec.rb
|