owmo 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6ac6a3db29e87019c86229bcfe4d0e3b7a001080
4
- data.tar.gz: 067bec01b6055748a4844d8aa380fd06b0c37324
3
+ metadata.gz: e14ca9d0e7400dc1e9acd4d318c1f223837eae89
4
+ data.tar.gz: ab5302d6ef868d2723d10a8d24d4f9a1e0b4d8be
5
5
  SHA512:
6
- metadata.gz: 4f4d0980495978f29e7b4b93ffe6ea9904c82382b6e3325a88a7c401f7f971fed8148071029e1be68479515f273a5f12b6bd6b6ce514f679749dcfa9b7a825f4
7
- data.tar.gz: db1d47014dd4d26e646826a1b7708a0c62542fd71d480377eac568cc4992b2bb0f7c3ba02bf3d2203d96bf2d56470e560f2d050a57d4fc70f41a0b623a1348fc
6
+ metadata.gz: 2f82d1d1e265163514a0b24d0f1dd5e8e318b3905375d3eef8399df26eef91c1101b72f8836065b822d05360978414586d80e886f00cb510f5e60f54baef7b5b
7
+ data.tar.gz: a798ccfdc3f3482c244c5e8a474ba26d6a653831d85580d6ef652f7476c2a30353af2a6324b4594cbd3417c789fe55a444ff1bbbc308a0202828a4fade0651c2
data/.gitignore CHANGED
@@ -14,3 +14,4 @@
14
14
 
15
15
  *.gem
16
16
  test.rb
17
+ scratch.rb
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
- # Owmo
1
+ # OWMO - OpenWeatherMap.Org Client API
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/owmo`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ Ruby client for openweathermap.org client API. Currently only for current and forecast information.
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ [![Gem Version](https://badge.fury.io/rb/owmo.svg)](https://badge.fury.io/rb/owmo)
6
6
 
7
7
  ## Installation
8
8
 
@@ -24,25 +24,28 @@ Or install it yourself as:
24
24
 
25
25
  You'll need and API key from OpenWeatherMap.org (http://openweathermap.org/appid).
26
26
 
27
- Either instanciate the OWMO::Weather class:
27
+ Compelete examples can be found under owmo/examples.
28
+
29
+ ----
30
+ ### Quick Start
31
+
28
32
  ```ruby
29
33
  require 'owmo'
30
- api_key = ""
31
-
34
+ api_key = "<api key here>"
32
35
  weather = OWMO::Weather.new api_key: api_key
36
+ puts weather.get :current, zip: 52402
33
37
  ```
34
38
 
35
- or through the OWMO::weather method block:
36
39
  ```ruby
37
40
  require 'owmo'
38
- api_key = ""
39
-
41
+ api_key = "<api key here>"
40
42
  OWMO::weather api_key: api_key do |weather|
41
- puts weather.get :current, city_name: "London,uk"
43
+ puts weather.get :forecast, zip: 52402
42
44
  end
43
45
  ```
46
+ ----
44
47
 
45
- **Current weather data** (http://openweathermap.org/current)
48
+ ### Current weather data (http://openweathermap.org/current)
46
49
  ```ruby
47
50
  params = {
48
51
  city_name: "London,uk", # [city_name, city_id, zip, lat/lon]
@@ -54,7 +57,7 @@ end
54
57
  puts weather.get :current, params
55
58
 
56
59
  ```
57
- **5 day weather forecast** (http://openweathermap.org/forecast5)
60
+ ### 5 day weather forecast (http://openweathermap.org/forecast5)
58
61
  ```ruby
59
62
  params = {
60
63
  zip: "90210", # [city_name, city_id, zip, lat/lon]
@@ -66,7 +69,7 @@ end
66
69
  puts weather.get :forecast, params
67
70
  ```
68
71
 
69
- **16 day weather forecast** (http://openweathermap.org/forecast16)
72
+ ### 16 day weather forecast (http://openweathermap.org/forecast16)
70
73
  ```ruby
71
74
  params = {
72
75
  lat: "40.7128", lon: "74.0059", # [city_name, city_id, zip, lat/lon]
data/_config.yml ADDED
@@ -0,0 +1 @@
1
+ theme: jekyll-theme-hacker
@@ -1,18 +1,21 @@
1
1
  require 'owmo'
2
2
 
3
+ =begin rdoc
4
+ An example on how to get current conditions and use the different parameters.
5
+ =end
3
6
  api_key = ""
4
7
 
5
8
  OWMO::weather api_key: api_key do |weather|
6
9
 
7
10
  # http://openweathermap.org/current#data
8
- params = {
11
+ query = {
9
12
  city_name: "London,uk", # [city_name, city_id, zip, lat/lon]
10
13
  mode: 'json', # [json, xml, html] Not required, but an option
11
14
  units: 'imperial', # [imperial, metric] Not required, but an option
12
15
  lang: 'en_US' # Not required, but an option
13
16
  }
14
17
 
15
- current_condition = weather.get :current, params
18
+ current_condition = weather.get :current, query
16
19
 
17
20
  puts current_condition
18
21
  end
data/examples/extended.rb CHANGED
@@ -1,18 +1,22 @@
1
1
  require 'owmo'
2
2
 
3
+
4
+ =begin rdoc
5
+ An example on how to get the weather forcast and use the different parameters.
6
+ =end
3
7
  api_key = ""
4
8
 
5
9
  OWMO::weather api_key: api_key do |weather|
6
10
 
7
11
  # http://openweathermap.org/forecast16
8
- params = {
12
+ query = {
9
13
  lat: "40.7128", lon: "74.0059", # [city_name, city_id, zip, lat/lon]
10
14
  mode: 'json', # [json, xml, html] Not required, but an option
11
15
  units: 'imperial', # [imperial, metric] Not required, but an option
12
16
  lang: 'en_US' # Not required, but an option
13
17
  }
14
18
 
15
- extended = weather.get :extended, params
19
+ extended = weather.get :extended, query
16
20
 
17
21
  puts extended
18
22
  end
data/examples/forecast.rb CHANGED
@@ -1,18 +1,22 @@
1
1
  require 'owmo'
2
2
 
3
+
4
+ =begin rdoc
5
+ An example on how to get the extended forcast and use the different parameters.
6
+ =end
3
7
  api_key = ""
4
8
 
5
9
  OWMO::weather api_key: api_key do |weather|
6
10
 
7
11
  # http://openweathermap.org/forecast5
8
- params = {
12
+ query = {
9
13
  zip: "90210", # [city_name, city_id, zip, lat/lon]
10
14
  mode: 'json', # [json, xml, html] Not required, but an option
11
15
  units: 'imperial', # [imperial, metric] Not required, but an option
12
16
  lang: 'en_US' # Not required, but an option
13
17
  }
14
18
 
15
- forecast = weather.get :forecast, params
19
+ forecast = weather.get :forecast, query
16
20
 
17
21
  puts forecast
18
22
  end
@@ -0,0 +1,4 @@
1
+ require 'core_extensions/string/uri'
2
+
3
+ module CoreExtensions
4
+ end # CoreExtensions
@@ -0,0 +1,58 @@
1
+ require 'json'
2
+
3
+
4
+ module CoreExtensions
5
+ module Net
6
+ module HTTPResponse
7
+ module WeatherResponse
8
+ =begin rdoc
9
+ Contains the weather data. If it's JSON, then it'll be a hash, other forms (XML, HTML)
10
+ will be raw format. The raw JSON is also available using the self.body.
11
+ =end
12
+ attr_reader :weather
13
+
14
+ =begin rdoc
15
+ Returns the weather
16
+ =end
17
+ def weather
18
+ parse_weather
19
+ @weather
20
+ end # weather
21
+
22
+ =begin rdoc
23
+ Returns the response code
24
+ =end
25
+ public
26
+ def weather_code
27
+ parse_weather
28
+ return @weather['cod'].to_i if @weather.is_a? Hash
29
+ 200
30
+ end # weather_error
31
+
32
+ =begin rdoc
33
+ Returns the response message
34
+ =end
35
+ public
36
+ def weather_message
37
+ parse_weather
38
+ return @weather['message'] if @weather.is_a? Hash
39
+ ""
40
+ end # weather_message
41
+
42
+ =begin rdoc
43
+ Attempts to parse the body to JSON. This is so we don't have to continually
44
+ parse the raw JSON.
45
+ =end
46
+ private
47
+ def parse_weather
48
+ begin
49
+ @weather = JSON.parse(self.body)
50
+ rescue
51
+ @weather = self.body
52
+ end if @weather.nil?
53
+ end # parse_weather
54
+
55
+ end # WeatherResponse
56
+ end # HTTPResponse
57
+ end # Net
58
+ end # CoreExtensions
data/lib/owmo/api.rb ADDED
@@ -0,0 +1,49 @@
1
+ require 'core_extensions/net/http_response/weather_response'
2
+ require 'net/http'
3
+ require 'uri'
4
+
5
+
6
+ =begin rdoc
7
+ Include some weather response info into Net::HTTPResponse
8
+ =end
9
+ Net::HTTPResponse.include CoreExtensions::Net::HTTPResponse::WeatherResponse
10
+
11
+ module OWMO
12
+ =begin rdoc
13
+ Net module Mixins
14
+ =end
15
+ module API
16
+
17
+ =begin rdoc
18
+ Weather response error to handle errors received from OpenWeatherMap.orgs API
19
+ =end
20
+ class WeatherResponseError < StandardError
21
+ def initialize(response)
22
+ @response = response
23
+ super("ERROR #{@response.weather_code}: #{@response.weather_message}")
24
+ end # initialize
25
+ end # WeatherResponseError
26
+
27
+ =begin rdoc
28
+ Sends the GET request to OpenWeatherMap.org, and returns the response
29
+ =end
30
+ def self.get(uri)
31
+
32
+ raise "Invalid URI: Expected URI, got #{uri.class}" unless uri.is_a? URI
33
+
34
+ # Send the request
35
+ request = Net::HTTP::Get.new(uri)
36
+
37
+ response = Net::HTTP.start(uri.hostname, uri.port) do |http|
38
+ http.request(request)
39
+ end # response
40
+
41
+ # Check the response
42
+ raise OWMO::API::WeatherResponseError.new(response) unless response.weather_code == 200
43
+
44
+ return response.weather
45
+
46
+ end # get
47
+ end # Net
48
+
49
+ end # OWMO
data/lib/owmo/version.rb CHANGED
@@ -1,3 +1,8 @@
1
- module Owmo
2
- VERSION = "0.1.0"
3
- end
1
+ module OWMO
2
+
3
+ =begin rdoc
4
+ Gem Version
5
+ =end
6
+ VERSION = "0.2.0"
7
+
8
+ end # OWMO
@@ -0,0 +1,116 @@
1
+ require 'set'
2
+ require 'uri'
3
+
4
+
5
+ module OWMO
6
+
7
+ =begin rdoc
8
+ A weather class for retrieving current and forecasted weather conditions.
9
+ ==== Attributes
10
+ * +api_key+ - {OpenWeatherMap.org API key}[http://openweathermap.org/appid]
11
+ ==== Examples
12
+ api_key = "<My API Key>"
13
+ weather = OWMO::Weather.new api_key: api_key
14
+ puts weather.get :current, city_name: "London,uk"
15
+
16
+ =end
17
+ class Weather
18
+
19
+ =begin rdoc
20
+ Raised when missing OpenWeatherMap.org API key
21
+ =end
22
+ class MissingApiKey < StandardError
23
+ def initialize()
24
+ super("Missing OpenWeatherMap.org API key, please register for one here -> http://openweathermap.org/appid")
25
+ end # initialize
26
+ end # MissingApiKey
27
+
28
+ =begin rdoc
29
+ Invalid path specified
30
+ =end
31
+ class InvalidPathSpecified < StandardError
32
+ def initialize(path=nil)
33
+ @path = path
34
+ super("Invalid path specified: Got: '#{@path}', expected one of: #{OWMO::PATHS.keys}")
35
+ end # initialize
36
+ end # NoGeocodeSpecified
37
+
38
+ =begin rdoc
39
+ Missing Geocode from query
40
+ =end
41
+ class MissingGeocodes < StandardError
42
+ end # MissingGeocodes
43
+
44
+ =begin rdoc
45
+ {OpenWeatherMap.org API key}[http://openweathermap.org/appid]
46
+ =end
47
+ attr_reader :api_key
48
+
49
+ def initialize(**kwargs) #:notnew:
50
+ raise MissingApiKey if kwargs[:api_key].nil?
51
+ @api_key = kwargs[:api_key]
52
+ end # initialize
53
+
54
+ =begin rdoc
55
+ A weather class for retrieving current and forecasted weather conditions.
56
+ ==== Attributes
57
+ * +path+ - OWMO::PATH parameter
58
+ * +query+ - Hash of query options (Geocode, response format, units, etc.)
59
+ ==== Examples
60
+ api_key = "<My API Key>"
61
+ weather = OWMO::Weather.new api_key: api_key
62
+ puts weather.get :current, city_name: "London,uk"
63
+ =end
64
+ public
65
+ def get(path, **query)
66
+ # Format Geocode info
67
+ query = check_geocodes query
68
+
69
+ # Add the api key
70
+ query[:APPID] = @api_key if query[:APPID].nil?
71
+
72
+ # Create the uri
73
+ raise InvalidPathSpecified.new(path) if OWMO::PATHS[path].nil?
74
+ uri = URI "#{OWMO::URL}/#{OWMO::PATHS[path]}?#{URI.encode_www_form(query)}"
75
+
76
+ # Get the weather data
77
+ OWMO::API.get(uri)
78
+
79
+ end # get
80
+
81
+ =begin rdoc
82
+ Ensure appropriate query options are applied to the final URI
83
+ =end
84
+ def check_geocodes(**query)
85
+
86
+ # May never be called since query is required
87
+ raise MissingGeocodes if query.size == 0
88
+
89
+ GEOCODES.each do |name, geocodes|
90
+
91
+ # Get the common keys
92
+ intersect = geocodes[:options].flatten & query.keys
93
+
94
+ # If there are common keys
95
+ if intersect.size > 0 then
96
+
97
+ # Remap any keys if they are not the same as the query
98
+ case geocodes[:query]
99
+ when Array then
100
+ intersect.zip(geocodes[:query]).each do |old_key, new_key|
101
+ query[new_key] = query.delete(old_key) unless new_key == old_key
102
+ end # intersect
103
+ else
104
+ query[geocodes[:query]] = query.delete(intersect[0]) unless geocodes[:query] == intersect[0]
105
+ end # case
106
+
107
+ return query
108
+ end # if
109
+
110
+ end # GEOCODES
111
+
112
+ raise MissingGeocodes
113
+ end # check_geocodes
114
+
115
+ end # Weather
116
+ end # OWMO
data/lib/owmo.rb CHANGED
@@ -1,14 +1,78 @@
1
+ require "owmo/api"
1
2
  require "owmo/version"
2
- require "owmo/Weather"
3
+ require "owmo/weather"
3
4
 
4
5
 
6
+ =begin rdoc
7
+ OMWO = OpenWeatherMap.org client for current and forecasted weather conditions.
8
+ =end
5
9
  module OWMO
10
+
11
+ =begin rdoc
12
+ Openweathermap.org URL
13
+ =end
6
14
  URL = 'http://api.openweathermap.org/data/2.5'
7
15
 
16
+ =begin rdoc
17
+ Access current or forecasted conditions by (required):
18
+ * +:current+ - {Current weather data}[http://openweathermap.org/current]
19
+ * +:forecast+ - {5 day / 3 hour forecast}[http://openweathermap.org/forecast5]
20
+ * +:extended+ - {16 day / daily forecast}[http://openweathermap.org/forecast16]
21
+ =end
22
+ PATHS = {
23
+ current: 'weather', # Current weather data
24
+ forecast: 'forecast', # 5 day / 3 hour forecast
25
+ extended: 'forecast/daily' # 16 day / daily forecast
26
+ }
27
+
28
+ =begin rdoc
29
+ {Geocode options (required):}[http://openweathermap.org/current#one]
30
+ * +q:+ or +city_name:+ - By city name
31
+ * +id:+ or +city_id:+ - By city ID
32
+ * +zip:+ or +zip_code:+ - By zip code
33
+ * +lat:+, +lon:+ or +latitude:+, +longitude:+ - By geographic coordinates
34
+ =end
35
+ GEOCODES = {
36
+ "City Name" => {
37
+ query: :q,
38
+ options: [:q, :city_name]
39
+ },
40
+ "City ID" => {
41
+ query: :id,
42
+ options: [:id, :city_id]
43
+ },
44
+ "Zip Code" => {
45
+ query: :zip,
46
+ options: [:zip, :zip_code]
47
+ },
48
+ "Coordinance" => {
49
+ query: [:lat, :lon],
50
+ options: [[:lat, :lon], [:lattitude, :longitude]]
51
+ },
52
+ "Cities Within a Rectangle Zone" => {
53
+ query: :bbox,
54
+ options: [:bbox]
55
+ },
56
+ "Cities Within a Circle" => {
57
+ query: [:lat, :lon, :cnt],
58
+ options: [[:lat, :lon, :cnt],[:lattitude, :longitude, :cnt]]
59
+ }
60
+ }
61
+
62
+ =begin rdoc
63
+ Yield a weather object for querying weather data
64
+ ==== Attributes
65
+ * +api_key:+ - {OpenWeatherMap.org API key}[http://openweathermap.org/appid]
66
+ ==== Examples
67
+ api_key = "<My API Key>"
68
+ OWMO::weather api_key do |weather|
69
+ puts weather.get :current, city_name: "London,uk"
70
+ end
71
+ =end
8
72
  public
9
73
  def self.weather(**params)
10
74
  w = Weather.new params
11
75
  yield w
12
76
  end # weather
13
77
 
14
- end
78
+ end # OWMO
data/owmo.gemspec CHANGED
@@ -5,7 +5,7 @@ require 'owmo/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "owmo"
8
- spec.version = Owmo::VERSION
8
+ spec.version = OWMO::VERSION
9
9
  spec.authors = ["Robb"]
10
10
  spec.email = ["robb.randall@gmail.com"]
11
11
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: owmo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robb
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-06-05 00:00:00.000000000 Z
11
+ date: 2017-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,14 +66,18 @@ files:
66
66
  - LICENSE.txt
67
67
  - README.md
68
68
  - Rakefile
69
+ - _config.yml
69
70
  - bin/console
70
71
  - bin/setup
71
72
  - examples/current_conditions.rb
72
73
  - examples/extended.rb
73
74
  - examples/forecast.rb
75
+ - lib/core_extensions/core_extensions.rb
76
+ - lib/core_extensions/net/http_response/weather_response.rb
74
77
  - lib/owmo.rb
75
- - lib/owmo/Weather.rb
78
+ - lib/owmo/api.rb
76
79
  - lib/owmo/version.rb
80
+ - lib/owmo/weather.rb
77
81
  - owmo.gemspec
78
82
  homepage: https://github.com/robb-randall/owmo
79
83
  licenses:
data/lib/owmo/Weather.rb DELETED
@@ -1,96 +0,0 @@
1
- require 'net/http'
2
-
3
- module OWMO
4
- class Weather
5
-
6
- attr_reader :url, :api_key
7
-
8
- def initialize(**kwargs)
9
- raise "Missing required api_key" if kwargs[:api_key].nil?
10
- @url = kwargs[:url] || OWMO::URL
11
- @api_key = kwargs[:api_key]
12
- end # initialize
13
-
14
- public
15
- def get(path, **params)
16
- # Parse the path
17
- path = parse_path(path)
18
-
19
- # Parse the params
20
- params = parse_params(params)
21
-
22
- # Format the URI
23
- uri = build_uri(path, params)
24
-
25
- # Get the weather data
26
- get_weather(uri)
27
- end # get
28
-
29
- private
30
- def parse_path(path)
31
- case path
32
- # Current weather data
33
- when :current then 'weather'
34
-
35
- # 5 day / 3 hour forecast
36
- when :forecast then 'forecast'
37
-
38
- # 16 day / daily forecast
39
- when :extended then 'forecast/daily'
40
-
41
- # Raise an error
42
- else raise "Unknown path: '#{path}'"
43
-
44
- end # case
45
- end # path
46
-
47
- private
48
- def parse_params(**params)
49
- case
50
- # Search by city name
51
- when params.key?(:city_name) then
52
- params[:q] = params.delete :city_name
53
-
54
- # Search by city ID
55
- when params.key?(:city_id) then
56
- params[:id] = params.delete :city_id
57
-
58
- # Search by Zip
59
- when params.key?(:zip) then
60
-
61
- # Search by geo location
62
- when params.key?(:lat) && params.key?(:lon) then
63
-
64
- # Nothing is specified, raise an error
65
- else raise "Missing location parameter: #{params}"
66
- end # case
67
-
68
- params
69
- end # parse_params
70
-
71
- private
72
- def build_uri(path, **params)
73
- URI "#{@url}/#{path}?#{format_parameters(params)}"
74
- end # format_uri
75
-
76
- private
77
- def format_parameters(**params)
78
- params[:APPID] = @api_key if params[:APPID].nil?
79
- params.map {|k,v| "#{k}=#{v}"}.join('&')
80
- end # format_params
81
-
82
- private
83
- def get_weather(uri)
84
- Net::HTTP.start(uri.host, uri.port) do |http|
85
- req = Net::HTTP::Get.new uri
86
- resp = http.request req
87
-
88
- # Error if the request was unsuccessful
89
- raise "ERROR #{resp.code}: #{res.message} (#{res.class.name})" unless Net::HTTPSuccess
90
-
91
- resp.body
92
- end # http
93
- end # get_weather
94
-
95
- end # Weather
96
- end # OWMO