accuweather 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +2 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/README.md +81 -0
- data/Rakefile +6 -0
- data/accuweather.gemspec +23 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/lib/accuweather.rb +37 -0
- data/lib/accuweather/conditions/current.rb +51 -0
- data/lib/accuweather/conditions/local.rb +37 -0
- data/lib/accuweather/conditions/parser.rb +53 -0
- data/lib/accuweather/conditions/units.rb +29 -0
- data/lib/accuweather/location.rb +27 -0
- data/lib/accuweather/version.rb +3 -0
- metadata +117 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 05d7bb60404314353deb76c8194a9d9c24d37d58
|
4
|
+
data.tar.gz: b366305e722e205d9689827d416bfa845f94ae06
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2a1d15961ac479a91be70ff7493e8d073b07d7f6033dbec4fad1b4a54b3ea79e117f725e63e69461dcb9c76e32dc250b7c3361c5d941d6c4b52c13926961422a
|
7
|
+
data.tar.gz: 991544a7b33bcef045cfc82f311a4e8d058700e889675311eba50cbd52e994a5fd07d164e970985a0c837c4c07687cda3c1a5481560b686fa5cb983546fc760d
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
accuweather
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.2.0
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
# Accuweather
|
2
|
+
|
3
|
+
Get weather information for cities around the world using the accuweather API. Includes
|
4
|
+
temperature, pressure, humidity, weather text and GPS coordinates.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'accuweather'
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install accuweather
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
Search for an accuweather location:
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
location_array = Accuweather.city_search('vancouver') # returns an array
|
28
|
+
vancouver = location_array.first
|
29
|
+
|
30
|
+
vancouver.id # => 'cityId:53286'
|
31
|
+
vancouver.city # => 'Vancouver'
|
32
|
+
vancouver.state # => 'Canada (British Columbia)'
|
33
|
+
vancouver.latitude # => '49.2448'
|
34
|
+
vancouver.longitude # => '123.1154'
|
35
|
+
```
|
36
|
+
|
37
|
+
Search for weather conditions for a given location id:
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
current_weather = Accuweather.get_conditions('cityId:53286').current
|
41
|
+
current_weather.temperature # => '41'
|
42
|
+
current_weather.weather_text # => 'Partly Sunny'
|
43
|
+
current_weather.pressure # => '30.35'
|
44
|
+
current_weather.humidity # => '43%'
|
45
|
+
current_weather.cloud_cover # => '40%'
|
46
|
+
```
|
47
|
+
|
48
|
+
Get the units for the conditions:
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
units = Accuweather.get_conditions('cityId:53286').units
|
52
|
+
units.temp # => 'F'
|
53
|
+
units.dist # => 'MI'
|
54
|
+
units.speed # => 'MPH'
|
55
|
+
```
|
56
|
+
|
57
|
+
Get more information on the location including time and time zone:
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
local = Accuweather.get_conditions('cityId:53286').local
|
61
|
+
local.time # => '13:41'
|
62
|
+
local.time_zone # => '-8'
|
63
|
+
local.time_zone_abbreviation # => 'PST'
|
64
|
+
```
|
65
|
+
|
66
|
+
Each `Accuweather::Conditions` object implements a `to_s` method that displays all attribute
|
67
|
+
name, value pairs. This makes it easy to explore the API. For example:
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
Accuweather.get_conditions('cityId:53286').local.to_s
|
71
|
+
# => "city: Vancouver, state: British Columbia, lat: 49.2448, lon: -123.1154, time: 13:41, time_zone: -8, obs_daylight: 0, current_gmt_offset: -8, time_zone_abbreviation: PST"
|
72
|
+
```
|
73
|
+
|
74
|
+
## Development
|
75
|
+
|
76
|
+
Run `rake` to run the tests
|
77
|
+
|
78
|
+
## Contributing
|
79
|
+
|
80
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/accuweather.
|
81
|
+
|
data/Rakefile
ADDED
data/accuweather.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'accuweather/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'accuweather'
|
8
|
+
spec.version = Accuweather::VERSION
|
9
|
+
spec.authors = ['Nick Aschenbach']
|
10
|
+
spec.email = ['nick.aschenbach@gmail.com']
|
11
|
+
|
12
|
+
spec.summary = 'Access current weather report and forecasts for cities around the world'
|
13
|
+
spec.homepage = 'https://github.com/nick-aschenbach/accuweather'
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
16
|
+
spec.require_paths = ['lib']
|
17
|
+
|
18
|
+
spec.add_development_dependency 'bundler', '~> 1.10'
|
19
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
20
|
+
spec.add_development_dependency 'rspec'
|
21
|
+
|
22
|
+
spec.add_runtime_dependency 'nokogiri'
|
23
|
+
end
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "accuweather"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/lib/accuweather.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'accuweather/version'
|
2
|
+
require 'accuweather/location'
|
3
|
+
require 'accuweather/conditions/parser'
|
4
|
+
require 'accuweather/conditions/units'
|
5
|
+
require 'accuweather/conditions/local'
|
6
|
+
require 'accuweather/conditions/current'
|
7
|
+
|
8
|
+
require 'net/http'
|
9
|
+
require 'nokogiri'
|
10
|
+
|
11
|
+
module Accuweather
|
12
|
+
def self.city_search(name)
|
13
|
+
response = Net::HTTP.get('samsungmobile.accu-weather.com',
|
14
|
+
"/widget/samsungmobile/city-find.asp?returnGeoPosition=1&location=#{name}")
|
15
|
+
|
16
|
+
|
17
|
+
xml = Nokogiri::XML.parse(response)
|
18
|
+
xml.css('location').map do |location|
|
19
|
+
Accuweather::Location.new(id: location.attr('location'),
|
20
|
+
city: location.attr('city'),
|
21
|
+
state: location.attr('state'),
|
22
|
+
latitude: location.attr('latitude'),
|
23
|
+
longitude: location.attr('longitude'))
|
24
|
+
end
|
25
|
+
rescue StandardError
|
26
|
+
[]
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.get_conditions(location_id)
|
30
|
+
response = Net::HTTP.get('samsungmobile.accu-weather.com',
|
31
|
+
"/widget/samsungmobile/weather-data.asp?metric=0&location=#{location_id}")
|
32
|
+
|
33
|
+
Accuweather::Conditions::Parser.new(response)
|
34
|
+
rescue StandardError
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Accuweather
|
2
|
+
module Conditions
|
3
|
+
class Current
|
4
|
+
attr_reader :url, :observation_time, :pressure, :temperature, :real_feel, :humidity, :weather_text, :weather_icon, :wind_gusts, :wind_speed, :wind_direction, :visibility, :precip, :uv_index, :dewpoint, :cloud_cover
|
5
|
+
|
6
|
+
def initialize(url:, observation_time:, pressure:, temperature:, real_feel:, humidity:, weather_text:, weather_icon:, wind_gusts:, wind_speed:, wind_direction:, visibility:, precip:, uv_index:, dewpoint:, cloud_cover:)
|
7
|
+
@url = url
|
8
|
+
@observation_time = observation_time
|
9
|
+
@pressure = pressure
|
10
|
+
@temperature = temperature
|
11
|
+
@real_feel = real_feel
|
12
|
+
@humidity = humidity
|
13
|
+
@weather_text = weather_text
|
14
|
+
@weather_icon = weather_icon
|
15
|
+
@wind_gusts = wind_gusts
|
16
|
+
@wind_speed = wind_speed
|
17
|
+
@wind_direction = wind_direction
|
18
|
+
@visibility = visibility
|
19
|
+
@precip = precip
|
20
|
+
@uv_index = uv_index
|
21
|
+
@dewpoint = dewpoint
|
22
|
+
@cloud_cover = cloud_cover
|
23
|
+
end
|
24
|
+
|
25
|
+
def ==(other)
|
26
|
+
url == other.url &&
|
27
|
+
observation_time == other.observation_time &&
|
28
|
+
pressure == other.pressure &&
|
29
|
+
temperature == other.temperature &&
|
30
|
+
real_feel == other.real_feel &&
|
31
|
+
humidity == other.humidity &&
|
32
|
+
weather_text == other.weather_text &&
|
33
|
+
weather_icon == other.weather_icon &&
|
34
|
+
wind_gusts == other.wind_gusts &&
|
35
|
+
wind_speed == other.wind_speed &&
|
36
|
+
wind_direction == other.wind_direction &&
|
37
|
+
visibility == other.visibility &&
|
38
|
+
precip == other.precip &&
|
39
|
+
uv_index == other.uv_index &&
|
40
|
+
dewpoint == other.dewpoint &&
|
41
|
+
cloud_cover == other.cloud_cover
|
42
|
+
rescue NoMethodError
|
43
|
+
false
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_s
|
47
|
+
"url: #{url}, observation_time: #{observation_time}, pressure: #{pressure}, temperature: #{temperature}, real_feel: #{real_feel}, humidity: #{humidity}, weather_text: #{weather_text}, weather_icon: #{weather_icon}, wind_gusts: #{wind_gusts}, wind_speed: #{wind_speed}, wind_direction: #{wind_direction}, visibility: #{visibility}, precip: #{precip}, uv_index: #{uv_index}, dewpoint: #{dewpoint}, cloud_cover: #{cloud_cover}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Accuweather
|
2
|
+
module Conditions
|
3
|
+
class Local
|
4
|
+
attr_reader :city, :state, :lat, :lon, :time, :time_zone, :obs_daylight, :current_gmt_offset, :time_zone_abbreviation
|
5
|
+
|
6
|
+
def initialize(city:, state:, lat:, lon:, time:, time_zone:, obs_daylight:, current_gmt_offset:, time_zone_abbreviation:)
|
7
|
+
@city = city
|
8
|
+
@state = state
|
9
|
+
@lat = lat
|
10
|
+
@lon = lon
|
11
|
+
@time = time
|
12
|
+
@time_zone = time_zone
|
13
|
+
@obs_daylight = obs_daylight
|
14
|
+
@current_gmt_offset = current_gmt_offset
|
15
|
+
@time_zone_abbreviation = time_zone_abbreviation
|
16
|
+
end
|
17
|
+
|
18
|
+
def ==(other)
|
19
|
+
city == other.city &&
|
20
|
+
state == other.state &&
|
21
|
+
lat == other.lat &&
|
22
|
+
lon == other.lon &&
|
23
|
+
time == other.time &&
|
24
|
+
time_zone == other.time_zone &&
|
25
|
+
obs_daylight == other.obs_daylight &&
|
26
|
+
current_gmt_offset == other.current_gmt_offset &&
|
27
|
+
time_zone_abbreviation == other.time_zone_abbreviation
|
28
|
+
rescue NoMethodError
|
29
|
+
false
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_s
|
33
|
+
"city: #{city}, state: #{state}, lat: #{lat}, lon: #{lon}, time: #{time}, time_zone: #{time_zone}, obs_daylight: #{obs_daylight}, current_gmt_offset: #{current_gmt_offset}, time_zone_abbreviation: #{time_zone_abbreviation}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Accuweather
|
2
|
+
module Conditions
|
3
|
+
class Parser
|
4
|
+
def initialize(response)
|
5
|
+
@doc = Nokogiri::XML.parse(response)
|
6
|
+
end
|
7
|
+
|
8
|
+
def units
|
9
|
+
units = @doc.css('units').first
|
10
|
+
Accuweather::Conditions::Units.new(temp: units.css('temp').text,
|
11
|
+
dist: units.css('dist').text,
|
12
|
+
speed: units.css('speed').text,
|
13
|
+
pres: units.css('pres').text,
|
14
|
+
prec: units.css('prec').text)
|
15
|
+
end
|
16
|
+
|
17
|
+
def local
|
18
|
+
local = @doc.css('local').first
|
19
|
+
Accuweather::Conditions::Local.new(city: local.css('city').text,
|
20
|
+
state: local.css('state').text,
|
21
|
+
lat: local.css('lat').text,
|
22
|
+
lon: local.css('lon').text,
|
23
|
+
time: local.css('time').text,
|
24
|
+
time_zone: local.css('timeZone').text,
|
25
|
+
obs_daylight: local.css('obsDaylight').text.strip,
|
26
|
+
current_gmt_offset: local.css('currentGmtOffset').text,
|
27
|
+
time_zone_abbreviation: local.css('timeZoneAbbreviation').text,
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
def current
|
32
|
+
current = @doc.css('currentconditions').first
|
33
|
+
Accuweather::Conditions::Current.new(url: current.css('url').text,
|
34
|
+
observation_time: current.css('observationtime').text,
|
35
|
+
pressure: current.css('pressure').text,
|
36
|
+
temperature: current.css('temperature').text,
|
37
|
+
real_feel: current.css('realfeel').text,
|
38
|
+
humidity: current.css('humidity').text,
|
39
|
+
weather_text: current.css('weathertext').text,
|
40
|
+
weather_icon: current.css('weathericon').text,
|
41
|
+
wind_gusts: current.css('windgusts').text,
|
42
|
+
wind_speed: current.css('windspeed').text,
|
43
|
+
wind_direction: current.css('winddirection').text,
|
44
|
+
visibility: current.css('visibility').text,
|
45
|
+
precip: current.css('precip').text,
|
46
|
+
uv_index: current.css('uvindex').text,
|
47
|
+
dewpoint: current.css('dewpoint').text,
|
48
|
+
cloud_cover: current.css('cloudcover').text,
|
49
|
+
)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Accuweather
|
2
|
+
module Conditions
|
3
|
+
class Units
|
4
|
+
attr_reader :temp, :dist, :speed, :pres, :prec
|
5
|
+
|
6
|
+
def initialize(temp:, dist:, speed:, pres:, prec:)
|
7
|
+
@temp = temp
|
8
|
+
@dist = dist
|
9
|
+
@speed = speed
|
10
|
+
@pres = pres
|
11
|
+
@prec = prec
|
12
|
+
end
|
13
|
+
|
14
|
+
def ==(other)
|
15
|
+
temp == other.temp &&
|
16
|
+
dist == other.dist &&
|
17
|
+
speed == other.speed &&
|
18
|
+
pres == other.pres &&
|
19
|
+
prec == other.prec
|
20
|
+
rescue NoMethodError
|
21
|
+
false
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_s
|
25
|
+
"temp: #{temp}, dist: #{dist}, speed: #{speed}, pres: #{pres}, prec: #{prec}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Accuweather
|
2
|
+
class Location
|
3
|
+
attr_reader :id, :city, :state, :latitude, :longitude
|
4
|
+
|
5
|
+
def initialize(id:, city:, state:, latitude:, longitude:)
|
6
|
+
@id = id
|
7
|
+
@city = city
|
8
|
+
@state = state
|
9
|
+
@latitude = latitude
|
10
|
+
@longitude = longitude
|
11
|
+
end
|
12
|
+
|
13
|
+
def ==(other)
|
14
|
+
id == other.id &&
|
15
|
+
city == other.city &&
|
16
|
+
state == other.state &&
|
17
|
+
latitude == other.latitude &&
|
18
|
+
longitude == other.longitude
|
19
|
+
rescue NoMethodError
|
20
|
+
false
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_s
|
24
|
+
"id: #{id}, city: #{city}, state: #{state}, latitude: #{latitude}, longitude: #{longitude}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: accuweather
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nick Aschenbach
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-11-25 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.10'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.10'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: nokogiri
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description:
|
70
|
+
email:
|
71
|
+
- nick.aschenbach@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- ".rspec"
|
78
|
+
- ".ruby-gemset"
|
79
|
+
- ".ruby-version"
|
80
|
+
- ".travis.yml"
|
81
|
+
- Gemfile
|
82
|
+
- README.md
|
83
|
+
- Rakefile
|
84
|
+
- accuweather.gemspec
|
85
|
+
- bin/console
|
86
|
+
- bin/setup
|
87
|
+
- lib/accuweather.rb
|
88
|
+
- lib/accuweather/conditions/current.rb
|
89
|
+
- lib/accuweather/conditions/local.rb
|
90
|
+
- lib/accuweather/conditions/parser.rb
|
91
|
+
- lib/accuweather/conditions/units.rb
|
92
|
+
- lib/accuweather/location.rb
|
93
|
+
- lib/accuweather/version.rb
|
94
|
+
homepage: https://github.com/nick-aschenbach/accuweather
|
95
|
+
licenses: []
|
96
|
+
metadata: {}
|
97
|
+
post_install_message:
|
98
|
+
rdoc_options: []
|
99
|
+
require_paths:
|
100
|
+
- lib
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
requirements: []
|
112
|
+
rubyforge_project:
|
113
|
+
rubygems_version: 2.4.6
|
114
|
+
signing_key:
|
115
|
+
specification_version: 4
|
116
|
+
summary: Access current weather report and forecasts for cities around the world
|
117
|
+
test_files: []
|