From e49f345f8f7bdc33f39208e8f91aca7a769e411a Mon Sep 17 00:00:00 2001 From: Exybore Date: Mon, 12 Aug 2019 11:52:19 +0200 Subject: [PATCH 1/8] docs: update readme --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index d1fe9c4..4018111 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,17 @@ License - RubyDoc +## Why would I use this library ? + +Before writing this OpenWeatherMap implementation, I checked for existing ones on rubygems.org. There's only small libraries, that has at least one or two good thing but that's all. Consequently, I decided to make my own one, combining all their advantages : + +- **Centralized :** all the options and fetch methods are stored in one class, that is initialized only once in all the program. Parameters are the same across all requests. +- **Fast :** the only thing that can slow the library is your Internet connection : indeed, no heavy operations are made in the background. As soon as it receives weather conditions, the only step for it is organizing them. +- **Simple :** the library only contains essential operations to keep the number of methods low. Moreover, all the information is perfectly human-readable. +- **Documented :** every method and class attribute is explained and every exception thrown is explicit, therefore learning or debugging the library remains easy. + +This work resulted in a powerful implementation that responds to primary needs while staying abordable. + - [📌 Requirements](#-requirements) - [🔧 Setup](#-setup) - [Quick installation](#quick-installation) From ed77300d0d3f5bf77c0e2861f8c2cb74da05af1e Mon Sep 17 00:00:00 2001 From: Exybore Date: Mon, 12 Aug 2019 11:52:43 +0200 Subject: [PATCH 2/8] chore(vcs): update gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 330b7d1..98b6810 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.gem -.vscode/ \ No newline at end of file +.vscode/ +.idea \ No newline at end of file From cff61ea2c099e32ebad55ee0002877924b0d7f79 Mon Sep 17 00:00:00 2001 From: Exybore Date: Mon, 12 Aug 2019 12:25:32 +0200 Subject: [PATCH 3/8] chore(vcs): add commit message template --- .github/.git_commit_msg.txt | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 .github/.git_commit_msg.txt diff --git a/.github/.git_commit_msg.txt b/.github/.git_commit_msg.txt new file mode 100644 index 0000000..4a6d579 --- /dev/null +++ b/.github/.git_commit_msg.txt @@ -0,0 +1,33 @@ +# : (If applied, this commit will...) (Max 50 char) +# |<---- Using a Maximum Of 50 Characters ---->| Hard limit to 72 -->| + + +# Explain why this change is being made +# |<---- Try To Limit Each Line to a Maximum Of 72 Characters ---->| + +# Provide links to any relevant issues, articles, commits, or other +# pull requests +# Example: See #23, fixes #58 + +# --- COMMIT END --- +# can be +# feat (new feature) +# fix (bug fix) +# refactor (refactoring production code) +# style (formatting, missing semi colons, etc; no code change) +# test (adding or refactoring tests; no production code change) +# chore (updating npm scripts etc; no production code change) +# -------------------- +# Remember to +# Capitalize the subject line +# Use the imperative mood in the subject line +# Do not end the subject line with a period +# Separate subject from body with a blank line (comments don't count) +# Use the body to explain what and why vs. how +# Can use multiple lines with "-" for bullet points in body +# +# If you can't summarize your changes in a single line, they should +# probably be split into multiple commits +# -------------------- +# For more information about this template, check out +# https://gist.github.com/adeekshith/cd4c95a064977cdc6c50 \ No newline at end of file From f539f178ee159f1d1bfe985f1098fa09d7fa6b26 Mon Sep 17 00:00:00 2001 From: Exybore Date: Mon, 12 Aug 2019 12:25:42 +0200 Subject: [PATCH 4/8] refactor: fix many details Fixed a lot of details, such as : - useless files in the data/ folder - exceptions that are no longer based on the StandardError but a proper exception so it's easier to debug - replacement of certain methods to others --- lib/openweathermap.rb | 57 ++++++++++++++++++++++++++- lib/openweathermap/api.rb | 22 +++++------ lib/openweathermap/classes.rb | 4 +- lib/openweathermap/current-weather.rb | 3 ++ lib/openweathermap/data/constants.rb | 31 --------------- lib/openweathermap/data/exceptions.rb | 19 --------- lib/openweathermap/forecast.rb | 2 + openweathermap.gemspec | 2 +- 8 files changed, 74 insertions(+), 66 deletions(-) delete mode 100644 lib/openweathermap/data/constants.rb delete mode 100644 lib/openweathermap/data/exceptions.rb diff --git a/lib/openweathermap.rb b/lib/openweathermap.rb index 5dc6a0f..35de0f6 100644 --- a/lib/openweathermap.rb +++ b/lib/openweathermap.rb @@ -1,9 +1,62 @@ +# frozen_string_literal: true + require 'net/http' require 'json' -require 'openweathermap/data/constants' -require 'openweathermap/data/exceptions' require 'openweathermap/classes' require 'openweathermap/current-weather' require 'openweathermap/forecast' require 'openweathermap/api' + +module OpenWeatherMap + module Constants + # URL of the OpenWeatherMap API + API_URL = 'https://api.openweathermap.org' + + # Accepted types of unit + UNITS = %w(default metric imperial) + + # Accepted locales + LANGS = %w(ar bg ca cz de el fa fi fr gl hr hu it ja kr la lt mk nl pl pt ro ru se sk sl es tr ua vi zh_cn zh_tw en) + + # The different URLs + URLS = { + current: '/data/2.5/weather', + forecast: '/data/2.5/forecast' + } + + # All condition codes associated with emojis + CONDITION_CODE = { + '01d' => '☀', + '02d' => '⛅', + '03d' => '☁', + '04d' => '☁☁', + '09d' => '🌧', + '10d' => '🌦', + '11d' => '🌩', + '13d' => '🌨', + '50d' => '🌫', + } + end + + class Exception < StandardError + end + + module Exceptions + # Exception to handle unknown lang + class UnknownLang < Exception + end + + # Exception to handle unknown units + class UnknownUnits < Exception + end + + # Exception to handle unknown location + class UnknownLocation < Exception + end + + # Exception to tell that the API key isn't authorized + class Unauthorized < Exception + end + end +end diff --git a/lib/openweathermap/api.rb b/lib/openweathermap/api.rb index 723011b..98f2751 100644 --- a/lib/openweathermap/api.rb +++ b/lib/openweathermap/api.rb @@ -1,11 +1,13 @@ +# frozen_string_literal: true + module OpenWeatherMap # The main API class. class API # @return [String] Default lang to use - attr_accessor :lang + attr_reader :lang # @return [String] Default units to use - attr_accessor :units + attr_reader :units # Initialize the API object # @@ -20,13 +22,13 @@ class API # - imperial (temperatures in Fahrenheit) # @raise [OpenWeatherMap::Exceptions::UnknownLang] if the selected lang is not unknown # @raise [OpenWeatherMap::Exceptions::UnknownUnits] if the selected units is not unknown - def initialize(api_key, lang = 'en', units = nil) + def initialize(api_key, lang = 'en', units = 'default') @api_key = api_key - raise OpenWeatherMap::Exceptions::UnknownLang, "[owm-ruby] error : unknown lang #{lang}" unless OpenWeatherMap::Constants::LANGS.include? lang + raise OpenWeatherMap::Exceptions::UnknownLang, "unknown lang #{lang}" unless OpenWeatherMap::Constants::LANGS.include? lang @lang = lang - raise OpenWeatherMap::Exceptions::UnknownUnits, "[owm-ruby] error : unknown units #{units}" unless OpenWeatherMap::Constants::UNITS.include? units + raise OpenWeatherMap::Exceptions::UnknownUnits, "unknown units #{units}" unless OpenWeatherMap::Constants::UNITS.include? units @units = units end @@ -79,16 +81,12 @@ def make_request(url, location) } params.merge! options - url = "#{OpenWeatherMap::Constants::API_URL}/#{url}?" - - params.each do |key, value| - url += "#{key}=#{value}&" - end + url = "#{OpenWeatherMap::Constants::API_URL}/#{url}?#{URI.encode_www_form(params)}" response = Net::HTTP.get_response(URI(url)) case response.code.to_i - when 401 then raise OpenWeatherMap::Exceptions::Unauthorized, "[openweathermap] error : unauthorized key. API message : #{response.message}" - when 404 then raise OpenWeatherMap::Exceptions::UnknownLocation, "[openweathermap] error : unknown location. API message : #{location}" + when 401 then raise OpenWeatherMap::Exceptions::Unauthorized, "unauthorized key. API message : #{response.message}" + when 404 then raise OpenWeatherMap::Exceptions::UnknownLocation, "unknown location. API message : #{location}" else response.body end end diff --git a/lib/openweathermap/classes.rb b/lib/openweathermap/classes.rb index cd55a01..3d3a0ba 100644 --- a/lib/openweathermap/classes.rb +++ b/lib/openweathermap/classes.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module OpenWeatherMap # Represents a city class City @@ -101,7 +103,7 @@ def initialize(data) @main = data['weather'][0]['main'] @description = data['weather'][0]['description'] @icon = "https://openweathermap.org/img/w/#{data['weather'][0]['icon']}.png" - @emoji = OpenWeatherMap::Constants::CONDITION_CODE[data['weather'][0]['icon'].sub('n', 'd')] + @emoji = OpenWeatherMap::Constants::CONDITION_CODE[data['weather'][0]['icon'].tr('n', 'd')] @temperature = data['main']['temp'] @temp_min = data['main']['temp_min'].to_f @temp_max = data['main']['temp_max'].to_f diff --git a/lib/openweathermap/current-weather.rb b/lib/openweathermap/current-weather.rb index 5c4c340..44657fa 100644 --- a/lib/openweathermap/current-weather.rb +++ b/lib/openweathermap/current-weather.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module OpenWeatherMap # Represents the current weather at a location class CurrentWeather @@ -12,6 +14,7 @@ class CurrentWeather # @param data [Hash] mixed data from the request def initialize(data) data = JSON.parse(data) + p data @city = OpenWeatherMap::City.new(data['name'], data['coord']['lon'], data['coord']['lat'], data['sys']['country']) @weather_conditions = OpenWeatherMap::WeatherConditions.new(data) end diff --git a/lib/openweathermap/data/constants.rb b/lib/openweathermap/data/constants.rb deleted file mode 100644 index 11df7d7..0000000 --- a/lib/openweathermap/data/constants.rb +++ /dev/null @@ -1,31 +0,0 @@ -module OpenWeatherMap - module Constants - # URL of the OpenWeatherMap API - API_URL = 'https://api.openweathermap.org' - - # Accepted types of unit - UNITS = [nil, 'metric', 'imperial'] - - # Accepted locales - LANGS = %w(ar bg ca cz de el fa fi fr gl hr hu it ja kr la lt mk nl pl pt ro ru se sk sl es tr ua vi zh_cn zh_tw en) - - # The different URLs - URLS = { - current: '/data/2.5/weather', - forecast: '/data/2.5/forecast' - } - - # All condition codes associated with emojis - CONDITION_CODE = { - '01d' => '☀', - '02d' => '⛅', - '03d' => '☁', - '04d' => '☁☁', - '09d' => '🌧', - '10d' => '🌦', - '11d' => '🌩', - '13d' => '🌨', - '50d' => '🌫', - } - end -end diff --git a/lib/openweathermap/data/exceptions.rb b/lib/openweathermap/data/exceptions.rb deleted file mode 100644 index 363e1f5..0000000 --- a/lib/openweathermap/data/exceptions.rb +++ /dev/null @@ -1,19 +0,0 @@ -module OpenWeatherMap - module Exceptions - # Exception to handle unknown lang - class UnknownLang < StandardError - end - - # Exception to handle unknown units - class UnknownUnits < StandardError - end - - # Exception to handle unknown location - class UnknownLocation < StandardError - end - - # Exception to tell that the API key isn't authorized - class Unauthorized < StandardError - end - end -end \ No newline at end of file diff --git a/lib/openweathermap/forecast.rb b/lib/openweathermap/forecast.rb index a9527f2..65a59da 100644 --- a/lib/openweathermap/forecast.rb +++ b/lib/openweathermap/forecast.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module OpenWeatherMap # Represents the forecast for a specific location class Forecast diff --git a/openweathermap.gemspec b/openweathermap.gemspec index cb2f7ba..baece86 100644 --- a/openweathermap.gemspec +++ b/openweathermap.gemspec @@ -6,7 +6,7 @@ Gem::Specification.new do |s| s.description = "An implementation to easily fetch the OpenWeatherMap API." s.authors = ["Exybore"] s.email = 'exybore@becauseofprog.fr' - s.files = ["lib/openweathermap.rb", "lib/openweathermap/current-weather.rb", "lib/openweathermap/forecast.rb", "lib/openweathermap/classes.rb", "lib/openweathermap/api.rb", "lib/openweathermap/data/constants.rb", "lib/openweathermap/data/exceptions.rb", ] + s.files = ["lib/openweathermap.rb", "lib/openweathermap/current-weather.rb", "lib/openweathermap/forecast.rb", "lib/openweathermap/classes.rb", "lib/openweathermap/api.rb"] s.homepage = 'https://github.com/becauseofprog/openweathermap-ruby' s.license = 'MIT' end From ff1a3643342ab0ca9cd661435243be784a0fb177 Mon Sep 17 00:00:00 2001 From: Exybore Date: Mon, 12 Aug 2019 12:27:49 +0200 Subject: [PATCH 5/8] docs: update readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4018111..a6121d4 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,7 @@ The constructor takes three parameters : - The first is an API key, that can be generated on the [OpenWeatherMap website](https://openweathermap.org/appid) - The second is the language of the data. It can be one of these : Arabic - ar, Bulgarian - bg, Catalan - ca, Czech - cz, German - de, Greek - el, English - en, Persian (Farsi) - fa, Finnish - fi, French - fr, Galician - gl, Croatian - hr, Hungarian - hu, Italian - it, Japanese - ja, Korean - kr, Latvian - la, Lithuanian - lt, Macedonian - mk, Dutch - nl, Polish - pl, Portuguese - pt, Romanian - ro, Russian - ru, Swedish - se, Slovak - sk, Slovenian - sl, Spanish - es, Turkish - tr, Ukrainian - ua, Vietnamese - vi, Chinese Simplified - zh_cn, Chinese Traditional - zh_tw. - The third is the unit system. It can be one of these : - - none (temperatures in Kelvin) + - default (temperatures in Kelvin) - metric (temperatures in Celsius) - imperial (temperatures in Fahrenheit) @@ -133,7 +133,7 @@ Its parameter is the same as the `current` method. It will return a `OpenWeather ### Possible exceptions -Your requests may return exceptions that are in the `OpenWeatherMap::Exceptions` module : +Your requests may return exceptions that are in the `OpenWeatherMap::Exceptions` module. All are based on the `OpenWeatherMap::Exception` class. - An `Unauthorized` exception, caused when your API key is wrong - An `UnknownLocation` exception, caused if the location you wrote is wrong From f9966d0fbdf69a42e2e70182372f6529d15cdadc Mon Sep 17 00:00:00 2001 From: Exybore Date: Mon, 12 Aug 2019 12:41:29 +0200 Subject: [PATCH 6/8] docs: update to rdoc Updated all the documentation inside the code so it's compatible with RDoc generation. --- lib/openweathermap.rb | 30 ++++++++++++++ lib/openweathermap/api.rb | 22 ++++++++-- lib/openweathermap/classes.rb | 60 +++++++++++++++++++++++++-- lib/openweathermap/current-weather.rb | 12 +++++- lib/openweathermap/forecast.rb | 10 +++++ 5 files changed, 127 insertions(+), 7 deletions(-) diff --git a/lib/openweathermap.rb b/lib/openweathermap.rb index 35de0f6..a54b064 100644 --- a/lib/openweathermap.rb +++ b/lib/openweathermap.rb @@ -9,23 +9,38 @@ require 'openweathermap/api' module OpenWeatherMap + + ## + # All the constants needed for the library + module Constants + + ## # URL of the OpenWeatherMap API + API_URL = 'https://api.openweathermap.org' + ## # Accepted types of unit + UNITS = %w(default metric imperial) + ## # Accepted locales + LANGS = %w(ar bg ca cz de el fa fi fr gl hr hu it ja kr la lt mk nl pl pt ro ru se sk sl es tr ua vi zh_cn zh_tw en) + ## # The different URLs + URLS = { current: '/data/2.5/weather', forecast: '/data/2.5/forecast' } + ## # All condition codes associated with emojis + CONDITION_CODE = { '01d' => '☀', '02d' => '⛅', @@ -39,23 +54,38 @@ module Constants } end + ## + # Base exception for the OpenWeatherMap library + class Exception < StandardError end + ## + # Exceptions that can be thrown by the library + module Exceptions + + ## # Exception to handle unknown lang + class UnknownLang < Exception end + ## # Exception to handle unknown units + class UnknownUnits < Exception end + ## # Exception to handle unknown location + class UnknownLocation < Exception end + ## # Exception to tell that the API key isn't authorized + class Unauthorized < Exception end end diff --git a/lib/openweathermap/api.rb b/lib/openweathermap/api.rb index 98f2751..2b5b082 100644 --- a/lib/openweathermap/api.rb +++ b/lib/openweathermap/api.rb @@ -1,14 +1,23 @@ # frozen_string_literal: true module OpenWeatherMap + ## # The main API class. + class API - # @return [String] Default lang to use + ## + # The default lang to use across the program + # @return [String] + attr_reader :lang - - # @return [String] Default units to use + + ## + # The default unit system to use across the program + # @return [String] + attr_reader :units + ## # Initialize the API object # # @param api_key [String] your OpenWeatherMap's API key @@ -22,6 +31,7 @@ class API # - imperial (temperatures in Fahrenheit) # @raise [OpenWeatherMap::Exceptions::UnknownLang] if the selected lang is not unknown # @raise [OpenWeatherMap::Exceptions::UnknownUnits] if the selected units is not unknown + def initialize(api_key, lang = 'en', units = 'default') @api_key = api_key @@ -32,6 +42,7 @@ def initialize(api_key, lang = 'en', units = 'default') @units = units end + ## # Get current weather at a specific location. # # @param location [String, Integer, Array] the location @@ -40,11 +51,13 @@ def initialize(api_key, lang = 'en', units = 'default') # - Integer : search by city ID (refer to http://bulk.openweathermap.org/sample/city.list.json.gz) # - Array : search by coordinates (format : [lon, lat]) # @return [OpenWeatherMap::CurrentWeather] requested data + def current(location) data = make_request(OpenWeatherMap::Constants::URLS[:current], location) OpenWeatherMap::CurrentWeather.new(data) end + ## # Get weather forecast for a specific location. # # @param location [String, Integer, Array] the location @@ -53,6 +66,7 @@ def current(location) # - Integer : search by city ID (refer to bulk.openweathermap.org/sample/city.list.json.gz) # - Array : search by coordinates (format : [lon, lat]) # @return [OpenWeatherMap::Forecast] requested data + def forecast(location) data = make_request(OpenWeatherMap::Constants::URLS[:forecast], location) OpenWeatherMap::Forecast.new(data) @@ -60,11 +74,13 @@ def forecast(location) private + ## # Make a request to the OpenWeatherMap API. # # @param url [String] The endpoint to reach # @param options [Hash] mixed options # @return [String] request's body + def make_request(url, location) options = {} options[:q] = location if location.is_a? String diff --git a/lib/openweathermap/classes.rb b/lib/openweathermap/classes.rb index 3d3a0ba..487143d 100644 --- a/lib/openweathermap/classes.rb +++ b/lib/openweathermap/classes.rb @@ -1,23 +1,35 @@ # frozen_string_literal: true module OpenWeatherMap - # Represents a city + + ## + # Class representing a city + class City + + ## # @return [String] City's name + attr_reader :name + ## # @return [Coordinates] City's coordinates + attr_reader :coordinates + ## # @return [String] Country in which the city is + attr_reader :country + ## # Create a new City object # # @param name [String] City's name # @param lon [Float] Longitude of the city # @param lat [Float] Latitude of the city # @param country [String] Country in which the city is + def initialize(name, lon, lat, country) @name = name @coordinates = OpenWeatherMap::Coordinates.new(lon, lat) @@ -25,79 +37,121 @@ def initialize(name, lon, lat, country) end end + ## # Represents a location's coordinates + class Coordinates + + ## # @return [Float] Longitude of the location + attr_reader :lon - + + ## # @return [Float] Latitude of the location + attr_reader :lat + ## # Create a new Coordinates object # # @param lon [Float] Longitude of the location # @param lat [Float] Latitude of the location + def initialize(lon, lat) @lon = lon @lat = lat end end + ## # Represents the weather conditions + class WeatherConditions + + ## # @return [Time] time of the condition + attr_reader :time - # @return [String] Main weather contitions at the moment + ## + # @return [String] Main weather conditions at the moment + attr_reader :main + ## # @return [String] Details of weather conditions + attr_reader :description + ## # @return [String] URL to conditions icon illustration + attr_reader :icon + ## # @return [String] Conditions illustrated by an emoji + attr_reader :emoji + ## # @return [Float] Temperature + attr_reader :temperature + ## # @return [Float] Minimum temperature at the moment (for large areas) + attr_reader :temp_min + ## # @return [Float] Maximum temperature at the moment (for large areas) + attr_reader :temp_max + ## # @return [Float] Atmospheric pressure in hPa + attr_reader :pressure + ## # @return [Float] Humidity percentage + attr_reader :humidity + ## # @return [Hash] Wind data. Keys : (symbols) # - speed : Wind speed (m/s or miles/hour) # - direction : Wind direction (meteorological degrees) + attr_reader :wind + ## # @return [Float] Clouds percentage + attr_reader :clouds + ## # @return [Hash, nil] Rain volume. Keys : (symbols) # - one_hour : Rain volume for the last 1 hour (mm) # - three_hours : Rain volume for the last 3 hours (mm) # Can be nil if there is no rain + attr_reader :rain + ## # @return [Hash, nil] Snow volume. Keys : (symbols) # - one_hour : Snow volume for the last 1 hour (mm) # - three_hours : Snow volume for the last 3 hours (mm) # Can be nil if there is no snow + attr_reader :snow + ## # Create a new WeatherConditions object. # # @param data [Hash] all the received data + def initialize(data) @time = Time.at(data['dt']) @main = data['weather'][0]['main'] diff --git a/lib/openweathermap/current-weather.rb b/lib/openweathermap/current-weather.rb index 44657fa..3824c19 100644 --- a/lib/openweathermap/current-weather.rb +++ b/lib/openweathermap/current-weather.rb @@ -1,17 +1,27 @@ # frozen_string_literal: true module OpenWeatherMap + + ## # Represents the current weather at a location + class CurrentWeather + + ## # @return [OpenWeatherMap::WeatherConditions] Conditions at the moment + attr_reader :weather_conditions + ## # @return [OpenWeatherMap::City] Requested city's data + attr_reader :city - + + ## # Create a new CurrentWeather object # # @param data [Hash] mixed data from the request + def initialize(data) data = JSON.parse(data) p data diff --git a/lib/openweathermap/forecast.rb b/lib/openweathermap/forecast.rb index 65a59da..78f3c1f 100644 --- a/lib/openweathermap/forecast.rb +++ b/lib/openweathermap/forecast.rb @@ -1,17 +1,27 @@ # frozen_string_literal: true module OpenWeatherMap + + ## # Represents the forecast for a specific location + class Forecast + + ## # @return [OpenWeatherMap::City] Requested city's data + attr_reader :city + ## # @return [Array] Forecast for many days and hours + attr_reader :forecast + ## # Create a new Forecast object # # @param data [Hash] mixed data from the request + def initialize(data) data = JSON.parse(data) @city = OpenWeatherMap::City.new(data['city']['name'], data['city']['coord']['lon'], data['city']['coord']['lat'], data['city']['country']) From 3c6e4c1cd2d9b476dec79a3d7b99f8cd453cc261 Mon Sep 17 00:00:00 2001 From: Exybore Date: Mon, 12 Aug 2019 12:56:44 +0200 Subject: [PATCH 7/8] feat: add json errors handling Added a new kind of exception when JSON throw one. --- lib/openweathermap.rb | 15 +++++++++++---- lib/openweathermap/current-weather.rb | 7 +++++-- lib/openweathermap/forecast.rb | 6 +++++- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/lib/openweathermap.rb b/lib/openweathermap.rb index a54b064..4001ef8 100644 --- a/lib/openweathermap.rb +++ b/lib/openweathermap.rb @@ -68,25 +68,32 @@ module Exceptions ## # Exception to handle unknown lang - class UnknownLang < Exception + class UnknownLang < OpenWeatherMap::Exception end ## # Exception to handle unknown units - class UnknownUnits < Exception + class UnknownUnits < OpenWeatherMap::Exception end ## # Exception to handle unknown location - class UnknownLocation < Exception + class UnknownLocation < OpenWeatherMap::Exception end ## # Exception to tell that the API key isn't authorized - class Unauthorized < Exception + class Unauthorized < OpenWeatherMap::Exception end + + ## + # Exception to handle data error + + class DataError < OpenWeatherMap::Exception + end + end end diff --git a/lib/openweathermap/current-weather.rb b/lib/openweathermap/current-weather.rb index 3824c19..968556d 100644 --- a/lib/openweathermap/current-weather.rb +++ b/lib/openweathermap/current-weather.rb @@ -23,8 +23,11 @@ class CurrentWeather # @param data [Hash] mixed data from the request def initialize(data) - data = JSON.parse(data) - p data + begin + data = JSON.parse(data) + rescue JSON::JSONError => e + raise OpenWeatherMap::Exceptions::DataError, "error while parsing data : #{e}" + end @city = OpenWeatherMap::City.new(data['name'], data['coord']['lon'], data['coord']['lat'], data['sys']['country']) @weather_conditions = OpenWeatherMap::WeatherConditions.new(data) end diff --git a/lib/openweathermap/forecast.rb b/lib/openweathermap/forecast.rb index 78f3c1f..d718b02 100644 --- a/lib/openweathermap/forecast.rb +++ b/lib/openweathermap/forecast.rb @@ -23,7 +23,11 @@ class Forecast # @param data [Hash] mixed data from the request def initialize(data) - data = JSON.parse(data) + begin + data = JSON.parse(data) + rescue JSON::JSONError => e + raise OpenWeatherMap::Exceptions::DataError, "error while parsing data : #{e}" + end @city = OpenWeatherMap::City.new(data['city']['name'], data['city']['coord']['lon'], data['city']['coord']['lat'], data['city']['country']) @forecast = [] data['list'].each do |element| From 4297ad52b9d74dc10ad6ba43f35b07be69fa28ab Mon Sep 17 00:00:00 2001 From: Exybore Date: Mon, 12 Aug 2019 12:58:15 +0200 Subject: [PATCH 8/8] chore(release): v0.2.3 --- openweathermap.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openweathermap.gemspec b/openweathermap.gemspec index baece86..a10ae1d 100644 --- a/openweathermap.gemspec +++ b/openweathermap.gemspec @@ -1,6 +1,6 @@ Gem::Specification.new do |s| s.name = 'openweathermap' - s.version = '0.2.2' + s.version = '0.2.3' s.date = '2019-03-16' s.summary = "🌐 Implementation of OpenWeatherMap API." s.description = "An implementation to easily fetch the OpenWeatherMap API."