openweathermap 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/openweathermap.rb +9 -0
- data/lib/openweathermap/api.rb +96 -0
- data/lib/openweathermap/classes.rb +125 -0
- data/lib/openweathermap/current-weather.rb +19 -0
- data/lib/openweathermap/data/constants.rb +32 -0
- data/lib/openweathermap/data/exceptions.rb +19 -0
- data/lib/openweathermap/forecast.rb +22 -0
- metadata +50 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a01ee11d2636128cb6c2cced0e2ac2f3e6fa3261
|
4
|
+
data.tar.gz: f3112253de1b74d72f9a6a38351d8939f0ae8970
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 67dc078f85400f220e81f79f3a1908d4a60e780970efee7044c1d72b968dd28c888e51c40f6e65841a1546f4beb7f984d43d7fb67b10c579cf76f2c8f5321022
|
7
|
+
data.tar.gz: 053f6ff4af3da00089d1c3fc600c84fecffe991b5fff7cf9b5a013f92c52e6c75c1c9a8c6835c19e9084f6732c10f2787578bf1b267303e22f78fbcb9b641b85
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
require 'openweathermap/data/constants'
|
5
|
+
require 'openweathermap/data/exceptions'
|
6
|
+
require 'openweathermap/classes'
|
7
|
+
require 'openweathermap/current-weather'
|
8
|
+
require 'openweathermap/forecast'
|
9
|
+
require 'openweathermap/api'
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module OpenWeatherMap
|
2
|
+
# The main API class.
|
3
|
+
class API
|
4
|
+
# @return [String] Default lang to use
|
5
|
+
attr_accessor :lang
|
6
|
+
|
7
|
+
# @return [String] Default units to use
|
8
|
+
attr_accessor :units
|
9
|
+
|
10
|
+
# Initialize the API object
|
11
|
+
#
|
12
|
+
# @param api_key [String] your OpenWeatherMap's API key
|
13
|
+
# For further information, go to https://openweathermap.org/price
|
14
|
+
# @param lang [String] the default lang
|
15
|
+
# Refer to OpenWeatherMap::Constants::LANGS for accepted values
|
16
|
+
# @param units [String] the units system to use
|
17
|
+
# Accepted values :
|
18
|
+
# - none (temperatures in Kelvin)
|
19
|
+
# - metric (temperatures in Celsius)
|
20
|
+
# - imperial (temperatures in Fahrenheit)
|
21
|
+
# @raise [OpenWeatherMap::Exceptions::UnknownLang] if the selected lang is not unknown
|
22
|
+
# @raise [OpenWeatherMap::Exceptions::UnknownUnits] if the selected units is not unknown
|
23
|
+
def initialize(api_key, lang = 'en', units = nil)
|
24
|
+
@api_key = api_key
|
25
|
+
|
26
|
+
raise OpenWeatherMap::Exceptions::UnknownLang, "[owm-ruby] error : unknown lang #{lang}" unless OpenWeatherMap::Constants::LANGS.include? lang
|
27
|
+
@lang = lang
|
28
|
+
|
29
|
+
raise OpenWeatherMap::Exceptions::UnknownUnits, "[owm-ruby] error : unknown units #{units}" unless OpenWeatherMap::Constants::UNITS.include? units
|
30
|
+
@units = units
|
31
|
+
end
|
32
|
+
|
33
|
+
# Get current weather at a specific location.
|
34
|
+
#
|
35
|
+
# @param location [String, Integer, Array] the location
|
36
|
+
# Can be one of this type :
|
37
|
+
# - String : search by city name
|
38
|
+
# - Integer : search by city ID (refer to bulk.openweathermap.org/sample/city.list.json.gz)
|
39
|
+
# - Array : search by coordinates (format : [lon, lat])
|
40
|
+
# @return [OpenWeatherMap::CurrentWeather] requested data
|
41
|
+
def current(location)
|
42
|
+
data = make_request(OpenWeatherMap::Constants::URLS[:current], location)
|
43
|
+
OpenWeatherMap::CurrentWeather.new(data)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Get weather forecast for a specific location.
|
47
|
+
#
|
48
|
+
# @param location [String, Integer, Array] the location
|
49
|
+
# Can be one of this type :
|
50
|
+
# - String : search by city name
|
51
|
+
# - Integer : search by city ID (refer to bulk.openweathermap.org/sample/city.list.json.gz)
|
52
|
+
# - Array : search by coordinates (format : [lon, lat])
|
53
|
+
# @return [OpenWeatherMap::Forecast] requested data
|
54
|
+
def forecast(location)
|
55
|
+
data = make_request(OpenWeatherMap::Constants::URLS[:forecast], location)
|
56
|
+
OpenWeatherMap::Forecast.new(data)
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
# Make a request to the OpenWeatherMap API.
|
62
|
+
#
|
63
|
+
# @param url [String] The endpoint to reach
|
64
|
+
# @param options [Hash] mixed options
|
65
|
+
# @return [String] request's body
|
66
|
+
def make_request(url, location)
|
67
|
+
options = {}
|
68
|
+
options[:q] = location if location.is_a? String
|
69
|
+
options[:id] = location if location.is_a? Integer
|
70
|
+
if location.is_a? Array
|
71
|
+
options[:lon] = location[0]
|
72
|
+
options[:lat] = location[1]
|
73
|
+
end
|
74
|
+
|
75
|
+
params = {
|
76
|
+
apikey: @api_key,
|
77
|
+
lang: @lang,
|
78
|
+
units: @units
|
79
|
+
}
|
80
|
+
params.merge! options
|
81
|
+
|
82
|
+
url = "#{OpenWeatherMap::Constants::API_URL}/#{url}?"
|
83
|
+
|
84
|
+
params.each do |key, value|
|
85
|
+
url += "#{key}=#{value}&"
|
86
|
+
end
|
87
|
+
|
88
|
+
response = Net::HTTP.get_response(URI(url))
|
89
|
+
case response.code.to_i
|
90
|
+
when 401 then raise OpenWeatherMap::Exceptions::Unauthorized, "[openweathermap] error : unauthorized key. API message : #{response.message}"
|
91
|
+
when 404 then raise OpenWeatherMap::Exceptions::UnknownLocation, "[openweathermap] error : unknown location. API message : #{location}"
|
92
|
+
else response.body
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
module OpenWeatherMap
|
2
|
+
# Represents a city
|
3
|
+
class City
|
4
|
+
# @return [String] City's name
|
5
|
+
attr_reader :name
|
6
|
+
|
7
|
+
# @return [Coordinates] City's coordinates
|
8
|
+
attr_reader :coordinates
|
9
|
+
|
10
|
+
# @return [String] Country in which the city is
|
11
|
+
attr_reader :country
|
12
|
+
|
13
|
+
# Create a new City object
|
14
|
+
#
|
15
|
+
# @param name [String] City's name
|
16
|
+
# @param lon [Float] Longitude of the city
|
17
|
+
# @param lat [Float] Latitude of the city
|
18
|
+
# @param country [String] Country in which the city is
|
19
|
+
def initialize(name, lon, lat, country)
|
20
|
+
@name = name
|
21
|
+
@coordinates = OpenWeatherMap::Coordinates.new(lon, lat)
|
22
|
+
@country = country
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Represents a location's coordinates
|
27
|
+
class Coordinates
|
28
|
+
# @return [Float] Longitude of the location
|
29
|
+
attr_reader :lon
|
30
|
+
|
31
|
+
# @return [Float] Latitude of the location
|
32
|
+
attr_reader :lat
|
33
|
+
|
34
|
+
# Create a new Coordinates object
|
35
|
+
#
|
36
|
+
# @param lon [Float] Longitude of the location
|
37
|
+
# @param lat [Float] Latitude of the location
|
38
|
+
def initialize(lon, lat)
|
39
|
+
@lon = lon
|
40
|
+
@lat = lat
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Represents the weather conditions
|
45
|
+
class WeatherConditions
|
46
|
+
# @return [Time] time of the condition
|
47
|
+
attr_reader :time
|
48
|
+
|
49
|
+
# @return [String] Main weather contitions at the moment
|
50
|
+
attr_reader :main
|
51
|
+
|
52
|
+
# @return [String] Details of weather conditions
|
53
|
+
attr_reader :description
|
54
|
+
|
55
|
+
# @return [String] URL to conditions icon illustration
|
56
|
+
attr_reader :icon
|
57
|
+
|
58
|
+
# @return [String] Conditions illustrated by an emoji
|
59
|
+
attr_reader :emoji
|
60
|
+
|
61
|
+
# @return [Float] Temperature
|
62
|
+
attr_reader :temperature
|
63
|
+
|
64
|
+
# @return [Float] Minimum temperature at the moment (for large areas)
|
65
|
+
attr_reader :temp_min
|
66
|
+
|
67
|
+
# @return [Float] Maximum temperature at the moment (for large areas)
|
68
|
+
attr_reader :temp_max
|
69
|
+
|
70
|
+
# @return [Float] Atmospheric pressure in hPa
|
71
|
+
attr_reader :pressure
|
72
|
+
|
73
|
+
# @return [Float] Humidity percentage
|
74
|
+
attr_reader :humidity
|
75
|
+
|
76
|
+
# @return [Hash] Wind data. Keys : (symbols)
|
77
|
+
# - speed : Wind speed (m/s or miles/hour)
|
78
|
+
# - direction : Wind direction (meteorological degrees)
|
79
|
+
attr_reader :wind
|
80
|
+
|
81
|
+
# @return [Float] Clouds percentage
|
82
|
+
attr_reader :clouds
|
83
|
+
|
84
|
+
# @return [Hash, nil] Rain volume. Keys : (symbols)
|
85
|
+
# - one_hour : Rain volume for the last 1 hour (mm)
|
86
|
+
# - three_hours : Rain volume for the last 3 hours (mm)
|
87
|
+
# Can be nil if there is no rain
|
88
|
+
attr_reader :rain
|
89
|
+
|
90
|
+
# @return [Hash, nil] Snow volume. Keys : (symbols)
|
91
|
+
# - one_hour : Snow volume for the last 1 hour (mm)
|
92
|
+
# - three_hours : Snow volume for the last 3 hours (mm)
|
93
|
+
# Can be nil if there is no snow
|
94
|
+
attr_reader :snow
|
95
|
+
|
96
|
+
# Create a new WeatherConditions object.
|
97
|
+
#
|
98
|
+
# @param data [Hash] all the received data
|
99
|
+
def initialize(data)
|
100
|
+
@time = Time.at(data['dt'])
|
101
|
+
@main = data['weather'][0]['main']
|
102
|
+
@description = data['weather'][0]['description']
|
103
|
+
@icon = "https://openweathermap.org/img/w/#{data['weather'][0]['icon']}.png"
|
104
|
+
@emoji = OpenWeatherMap::Constants::CONDITION_CODE[data['weather'][0]['icon'].sub('n', 'd')]
|
105
|
+
@temperature = data['main']['temp']
|
106
|
+
@temp_min = data['main']['temp_min'].to_f
|
107
|
+
@temp_max = data['main']['temp_max'].to_f
|
108
|
+
@pressure = data['main']['pressure'].to_f
|
109
|
+
@humidity = data['main']['humidity'].to_f
|
110
|
+
@wind = {
|
111
|
+
speed: data['wind']['speed'],
|
112
|
+
direction: data['wind']['deg']
|
113
|
+
}
|
114
|
+
@clouds = data['clouds']['all'].to_f
|
115
|
+
@rain = data['rain'].nil? ? nil : {
|
116
|
+
one_hour: data['rain']['1h'],
|
117
|
+
three_hours: data['rain']['3h']
|
118
|
+
}
|
119
|
+
@snow = data['snow'].nil? ? nil : {
|
120
|
+
one_hour: data['snow']['1h'],
|
121
|
+
three_hours: data['snow']['3h']
|
122
|
+
}
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module OpenWeatherMap
|
2
|
+
# Represents the current weather at a location
|
3
|
+
class CurrentWeather
|
4
|
+
# @return [OpenWeatherMap::WeatherConditions] Conditions at the moment
|
5
|
+
attr_reader :weather_conditions
|
6
|
+
|
7
|
+
# @return [OpenWeatherMap::City] Requested city's data
|
8
|
+
attr_reader :city
|
9
|
+
|
10
|
+
# Create a new CurrentWeather object
|
11
|
+
#
|
12
|
+
# @param data [Hash] mixed data from the request
|
13
|
+
def initialize(data)
|
14
|
+
data = JSON.parse(data)
|
15
|
+
@city = OpenWeatherMap::City.new(data['name'], data['coord']['lon'], data['coord']['lat'], data['sys']['country'])
|
16
|
+
@weather_conditions = OpenWeatherMap::WeatherConditions.new(data)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module OpenWeatherMap
|
2
|
+
module Constants
|
3
|
+
# URL of the OpenWeatherMap API
|
4
|
+
API_URL = 'https://api.openweathermap.org'
|
5
|
+
|
6
|
+
# Accepted types of unit
|
7
|
+
UNITS = [nil, 'metric', 'imperial']
|
8
|
+
|
9
|
+
# Accepted locales
|
10
|
+
LANGS = ['ar', 'bg', 'ca', 'cz', 'de', 'el', 'fa', 'fi', 'fr', 'gl', 'hr', 'hu', 'it', 'ja', 'kr', 'la',
|
11
|
+
'lt', 'mk', 'nl', 'pl', 'pt', 'ro', 'ru', 'se', 'sk', 'sl', 'es', 'tr', 'ua', 'vi', 'zh_cn', 'zh_tw' 'en']
|
12
|
+
|
13
|
+
# The different URLs
|
14
|
+
URLS = {
|
15
|
+
current: '/data/2.5/weather',
|
16
|
+
forecast: '/data/2.5/forecast'
|
17
|
+
}
|
18
|
+
|
19
|
+
# All condition codes associated with emojis
|
20
|
+
CONDITION_CODE = {
|
21
|
+
'01d' => '☀',
|
22
|
+
'02d' => '⛅',
|
23
|
+
'03d' => '☁',
|
24
|
+
'04d' => '☁☁',
|
25
|
+
'09d' => '🌧',
|
26
|
+
'10d' => '🌦',
|
27
|
+
'11d' => '🌩',
|
28
|
+
'13d' => '🌨',
|
29
|
+
'50d' => '🌫',
|
30
|
+
}
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module OpenWeatherMap
|
2
|
+
module Exceptions
|
3
|
+
# Exception to handle unknown lang
|
4
|
+
class UnknownLang < StandardError
|
5
|
+
end
|
6
|
+
|
7
|
+
# Exception to handle unknown units
|
8
|
+
class UnknownUnits < StandardError
|
9
|
+
end
|
10
|
+
|
11
|
+
# Exception to handle unknown location
|
12
|
+
class UnknownLocation < StandardError
|
13
|
+
end
|
14
|
+
|
15
|
+
# Exception to tell that the API key isn't authorized
|
16
|
+
class Unauthorized < StandardError
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module OpenWeatherMap
|
2
|
+
# Represents the forecast for a specific location
|
3
|
+
class Forecast
|
4
|
+
# @return [OpenWeatherMap::City] Requested city's data
|
5
|
+
attr_reader :city
|
6
|
+
|
7
|
+
# @return [Array<OpenWeatherMap::WeatherConditions>] Forecast for many days and hours
|
8
|
+
attr_reader :forecast
|
9
|
+
|
10
|
+
# Create a new Forecast object
|
11
|
+
#
|
12
|
+
# @param data [Hash] mixed data from the request
|
13
|
+
def initialize(data)
|
14
|
+
data = JSON.parse(data)
|
15
|
+
@city = OpenWeatherMap::City.new(data['city']['name'], data['city']['coord']['lon'], data['city']['coord']['lat'], data['city']['country'])
|
16
|
+
@forecast = []
|
17
|
+
data['list'].each do |element|
|
18
|
+
forecast << OpenWeatherMap::WeatherConditions.new(element)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: openweathermap
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Exybore
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-03-16 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: An implementation to easily fetch the OpenWeatherMap API.
|
14
|
+
email: exybore@becauseofprog.fr
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- lib/openweathermap.rb
|
20
|
+
- lib/openweathermap/api.rb
|
21
|
+
- lib/openweathermap/classes.rb
|
22
|
+
- lib/openweathermap/current-weather.rb
|
23
|
+
- lib/openweathermap/data/constants.rb
|
24
|
+
- lib/openweathermap/data/exceptions.rb
|
25
|
+
- lib/openweathermap/forecast.rb
|
26
|
+
homepage: https://github.com/becauseofprog/openweathermap-ruby
|
27
|
+
licenses:
|
28
|
+
- MIT
|
29
|
+
metadata: {}
|
30
|
+
post_install_message:
|
31
|
+
rdoc_options: []
|
32
|
+
require_paths:
|
33
|
+
- lib
|
34
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - ">="
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
requirements: []
|
45
|
+
rubyforge_project:
|
46
|
+
rubygems_version: 2.2.2
|
47
|
+
signing_key:
|
48
|
+
specification_version: 4
|
49
|
+
summary: "\U0001F310 Implementation of OpenWeatherMap API."
|
50
|
+
test_files: []
|