tenkit 0.0.3 → 0.0.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3aa5020bbc4ca455845688d4fe94b4c5a272d288ef134a619750da149ceea012
4
- data.tar.gz: decd50d45c0edc8420f71de287ab08936cf9187b5735e757a2c52bc344d6eacb
3
+ metadata.gz: 2c9d994365e0a380527f2deb78aa646147d7dd1294f58cd00f69b514657c6f55
4
+ data.tar.gz: 4115b1cf791b2982af5dff5260c4a91c194f451bbf8d8ad7c6abe9d937874c76
5
5
  SHA512:
6
- metadata.gz: 61022b0c9a2424c4735a202bd3e6cd3f6248cc0e18ce1894309552d36ba79fcd305c012b595bb9b6b19090ca1f41ef9efc453e4daf9968645f73ef6ec1ddc7f2
7
- data.tar.gz: e2e8b6a45f0c29d9dd9a846305a21ae245c06578cd049173d757f6321479e36cfae12a9810c9a5a1b331b16a433ff6498fb87a8937b8198da153833d242b659f
6
+ metadata.gz: 61e011f43949099275b4cf99a62b3d9ce179dfab28b25c91cb72a1c99263dcc3250a250e6b1dcebfac5f70375b18592665d0e6e4827cd0503e18162f43ba5a75
7
+ data.tar.gz: f0d1e74ab7625818a17c3f76fbece22ab212968e0a5fc2c65096d4ee7e57ee009785244dd563c98e29ddc1d6362445f7a155570eeeab9228fd1d366c762b4b26
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jwt'
4
+ require 'openssl'
5
+ require 'httparty'
6
+ require_relative './weather_response'
7
+
8
+ module Tenkit
9
+ class Client
10
+ include HTTParty
11
+ base_uri 'https://weatherkit.apple.com/api/v1'
12
+
13
+ DATA_SETS = {
14
+ current_weather: 'currentWeather',
15
+ forecast_daily: 'forecastDaily',
16
+ forecast_hourly: 'forecastHourly',
17
+ trend_comparison: 'trendComparison',
18
+ weather_alerts: 'weatherAlerts',
19
+ forecast_next_hour: 'forecastNextHour'
20
+ }.freeze
21
+
22
+ def availability(lat, lon, country: 'US')
23
+ get("/availability/#{lat}/#{lon}?country=#{country}")
24
+ end
25
+
26
+ def weather(lat, lon, data_sets: [:current_weather], language: 'en')
27
+ path_root = "/weather/#{language}/#{lat}/#{lon}?dataSets="
28
+ path = path_root + data_sets.map { |ds| DATA_SETS[ds] }.compact.join(',')
29
+ response = get(path)
30
+ WeatherResponse.new(response)
31
+ end
32
+
33
+ def weather_alert(id, language: 'en')
34
+ puts 'TODO: implement weather alert endpoint'
35
+ puts language
36
+ puts id
37
+ end
38
+
39
+ private
40
+
41
+ def get(url)
42
+ headers = { Authorization: "Bearer #{token}" }
43
+ self.class.get(url, { headers: headers })
44
+ end
45
+
46
+ def header
47
+ {
48
+ alg: 'ES256',
49
+ kid: Tenkit.config.key_id,
50
+ id: "#{Tenkit.config.team_id}.#{Tenkit.config.service_id}"
51
+ }
52
+ end
53
+
54
+ def payload
55
+ {
56
+ iss: Tenkit.config.team_id,
57
+ iat: Time.new.to_i,
58
+ exp: Time.new.to_i + 600,
59
+ sub: Tenkit.config.service_id
60
+ }
61
+ end
62
+
63
+ def key
64
+ OpenSSL::PKey.read Tenkit.config.key
65
+ end
66
+
67
+ def token
68
+ JWT.encode payload, key, 'ES256', header
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tenkit
4
+ class Config
5
+ attr_accessor :team_id, :service_id, :key_id, :key
6
+ end
7
+ end
@@ -0,0 +1,45 @@
1
+ require_relative './metadata'
2
+
3
+ module Tenkit
4
+ class CurrentWeather
5
+ attr_reader :as_of,
6
+ :cloud_cover,
7
+ :condition_code,
8
+ :daylight,
9
+ :humidity,
10
+ :metadata,
11
+ :precipitation_intensity,
12
+ :pressure,
13
+ :pressure_trend,
14
+ :temperature,
15
+ :temperature_apparent,
16
+ :temperature_dew_point,
17
+ :uv_index,
18
+ :visibility,
19
+ :wind_direction,
20
+ :wind_gust,
21
+ :wind_speed
22
+
23
+ def initialize(current_weather)
24
+ return if current_weather.nil?
25
+
26
+ @as_of = current_weather['asOf']
27
+ @cloud_cover = current_weather['cloudCover']
28
+ @condition_code = current_weather['conditionCode']
29
+ @daylight = current_weather['daylight']
30
+ @humidity = current_weather['humidity']
31
+ @metadata = Metadata.new(current_weather['metadata'])
32
+ @precipitation_intensity = current_weather['precipitationIntensity']
33
+ @pressure = current_weather['pressure']
34
+ @pressure_trend = current_weather['pressureTrend']
35
+ @temperature = current_weather['temperature']
36
+ @temperature_apparent = current_weather['temperatureApparent']
37
+ @temperature_dew_point = current_weather['temperatureDewPoint']
38
+ @uv_index = current_weather['uvIndex']
39
+ @visibility = current_weather['visibility']
40
+ @wind_direction = current_weather['windDirection']
41
+ @wind_gust = current_weather['windGust']
42
+ @wind_speed = current_weather['windSpeed']
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,14 @@
1
+ require_relative './day_weather_conditions'
2
+
3
+ module Tenkit
4
+ class DailyForecast
5
+ attr_reader :days, :learn_more_url
6
+
7
+ def initialize(daily_forecast)
8
+ return if daily_forecast.nil?
9
+
10
+ @days = daily_forecast['days'].map { |day| DayWeatherConditions.new(day) }
11
+ @learn_more_url = daily_forecast['learnMoreURL']
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,57 @@
1
+ module Tenkit
2
+ class DayWeatherConditions
3
+ attr_reader :condition_code,
4
+ :daytime_forecast,
5
+ :forecast_end,
6
+ :forecast_start,
7
+ :max_uv_index,
8
+ :moon_phase,
9
+ :moonrise,
10
+ :moonset,
11
+ :overnight_forecast,
12
+ :precipitation_amount,
13
+ :precipitation_chance,
14
+ :precipitation_type,
15
+ :snowfall_amount,
16
+ :solar_midnight,
17
+ :solar_noon,
18
+ :sunrise,
19
+ :sunrise_astronomical,
20
+ :sunrise_civil,
21
+ :sunrise_nautical,
22
+ :sunset,
23
+ :sunset_astronomical,
24
+ :sunset_civil,
25
+ :sunset_nautical,
26
+ :temperature_max,
27
+ :temperature_min
28
+
29
+ def initialize(day_weather_conditions)
30
+ @condition_code = day_weather_conditions['condition_code']
31
+ @daytime_forecast = day_weather_conditions['daytime_forecast']
32
+ @forecast_end = day_weather_conditions['forecast_end']
33
+ @forecast_start = day_weather_conditions['forecast_start']
34
+ @max_uv_index = day_weather_conditions['max_uv_index']
35
+ @moon_phase = day_weather_conditions['moon_phase']
36
+ @moonrise = day_weather_conditions['moonrise']
37
+ @moonset = day_weather_conditions['moonset']
38
+ @overnight_forecast = day_weather_conditions['overnight_forecast']
39
+ @precipitation_amount = day_weather_conditions['precipitation_amount']
40
+ @precipitation_chance = day_weather_conditions['precipitation_chance']
41
+ @precipitation_type = day_weather_conditions['precipitation_type']
42
+ @snowfall_amount = day_weather_conditions['snowfall_amount']
43
+ @solar_midnight = day_weather_conditions['solar_midnight']
44
+ @solar_noon = day_weather_conditions['solar_noon']
45
+ @sunrise = day_weather_conditions['sunrise']
46
+ @sunrise_astronomical = day_weather_conditions['sunrise_astronomical']
47
+ @sunrise_civil = day_weather_conditions['sunrise_civil']
48
+ @sunrise_nautical = day_weather_conditions['sunrise_nautical']
49
+ @sunset = day_weather_conditions['sunset']
50
+ @sunset_astronomical = day_weather_conditions['sunset_astronomical']
51
+ @sunset_civil = day_weather_conditions['sunset_civil']
52
+ @sunset_nautical = day_weather_conditions['sunset_nautical']
53
+ @temperature_max = day_weather_conditions['temperature_max']
54
+ @temperature_min = day_weather_conditions['temperature_min']
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,11 @@
1
+ module Tenkit
2
+ class HourlyForecast
3
+ attr_reader :hours
4
+
5
+ def initialize(hourly_forecast)
6
+ return if hourly_forecast.nil?
7
+
8
+ @hours = hourly_forecast['hours']
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,25 @@
1
+ module Tenkit
2
+ class Metadata
3
+ attr_reader :attribution_url,
4
+ :expire_time,
5
+ :latitude,
6
+ :longitude,
7
+ :read_time,
8
+ :reported_time,
9
+ :units,
10
+ :version
11
+
12
+ def initialize(metadata)
13
+ return if metadata.nil?
14
+
15
+ @attribution_url = metadata['attributionURL']
16
+ @expire_time = metadata['expireTime']
17
+ @latitude = metadata['latitude']
18
+ @longitude = metadata['longitude']
19
+ @read_time = metadata['readTime']
20
+ @reported_time = metadata['reportedTime']
21
+ @units = metadata['units']
22
+ @version = metadata['version']
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,7 @@
1
+ module Tenkit
2
+ class NextHourForecast
3
+ def initialize(forecast_next_hour)
4
+ return if forecast_next_hour.nil?
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ module Tenkit
2
+ class Response
3
+ attr_reader :raw
4
+
5
+ def initialize(response)
6
+ @raw = response
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module Tenkit
2
+ class TrendComparison; end
3
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tenkit
4
+ VERSION = '0.0.5'
5
+ end
@@ -0,0 +1,31 @@
1
+ require_relative './current_weather'
2
+ require_relative './daily_forecast'
3
+ require_relative './hourly_forecast'
4
+ require_relative './next_hour_forecast'
5
+ require_relative './weather_alert_collection'
6
+
7
+ module Tenkit
8
+ class Weather
9
+ attr_reader :current_weather,
10
+ :forecast_daily,
11
+ :forecast_hourly,
12
+ :forecast_next_hour,
13
+ :weather_alerts
14
+
15
+ def initialize(response)
16
+ parsed_response = JSON.parse(response.body)
17
+
18
+ current_weather = parsed_response['currentWeather']
19
+ forecast_daily = parsed_response['forecastDaily']
20
+ forecast_hourly = parsed_response['forecastHourly']
21
+ forecast_next_hour = parsed_response['forecastNextHour']
22
+ weather_alerts = parsed_response['weatherAlerts']
23
+
24
+ @current_weather = CurrentWeather.new(current_weather)
25
+ @forecast_daily = DailyForecast.new(forecast_daily)
26
+ @forecast_hourly = HourlyForecast.new(forecast_hourly)
27
+ @forecast_next_hour = NextHourForecast.new(forecast_next_hour)
28
+ @weather_alerts = WeatherAlertCollection.new(weather_alerts)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,14 @@
1
+ require_relative './weather_alert_summary'
2
+
3
+ module Tenkit
4
+ class WeatherAlertCollection
5
+ attr_reader :alerts, :details_url
6
+
7
+ def initialize(weather_alerts)
8
+ return if weather_alerts.nil?
9
+
10
+ @alerts = weather_alerts['alerts'].map { |alert| WeatherAlertSummary.new(alert) }
11
+ @details_url = weather_alerts['detailsUrl']
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,39 @@
1
+ module Tenkit
2
+ class WeatherAlertSummary
3
+ attr_reader :area_id,
4
+ :area_name,
5
+ :certainty,
6
+ :country_code,
7
+ :description,
8
+ :details_url,
9
+ :effective_time,
10
+ :event_end_time,
11
+ :event_onset_time,
12
+ :expire_time,
13
+ :id,
14
+ :issued_time,
15
+ :responses,
16
+ :severity,
17
+ :source,
18
+ :urgency
19
+
20
+ def initialize(weather_alert)
21
+ @area_id = weather_alert['areaId']
22
+ @area_name = weather_alert['areaName']
23
+ @certainty = weather_alert['certainty']
24
+ @country_code = weather_alert['countryCode']
25
+ @description = weather_alert['description']
26
+ @details_url = weather_alert['detailsUrl']
27
+ @effective_time = weather_alert['effectiveTime']
28
+ @event_end_time = weather_alert['eventEndTime']
29
+ @event_onset_time = weather_alert['eventOnsetTime']
30
+ @expire_time = weather_alert['expireTime']
31
+ @id = weather_alert['id']
32
+ @issued_time = weather_alert['issued_time']
33
+ @responses = weather_alert['responses']
34
+ @severity = weather_alert['severity']
35
+ @source = weather_alert['source']
36
+ @urgency = weather_alert['urgency']
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,12 @@
1
+ require_relative './response'
2
+
3
+ module Tenkit
4
+ class WeatherResponse < Response
5
+ attr_reader :weather
6
+
7
+ def initialize(response)
8
+ super
9
+ @weather = Weather.new(response)
10
+ end
11
+ end
12
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tenkit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Pierce
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-01 00:00:00.000000000 Z
11
+ date: 2023-03-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '3.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: webmock
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '3.8'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '3.8'
97
111
  description: Wrapper for Weatherkit API
98
112
  email: james@superbasic.xyz
99
113
  executables: []
@@ -101,11 +115,26 @@ extensions: []
101
115
  extra_rdoc_files: []
102
116
  files:
103
117
  - lib/tenkit.rb
118
+ - lib/tenkit/client.rb
119
+ - lib/tenkit/config.rb
120
+ - lib/tenkit/current_weather.rb
121
+ - lib/tenkit/daily_forecast.rb
122
+ - lib/tenkit/day_weather_conditions.rb
123
+ - lib/tenkit/hourly_forecast.rb
124
+ - lib/tenkit/metadata.rb
125
+ - lib/tenkit/next_hour_forecast.rb
126
+ - lib/tenkit/response.rb
127
+ - lib/tenkit/trend_comparison.rb
128
+ - lib/tenkit/version.rb
129
+ - lib/tenkit/weather.rb
130
+ - lib/tenkit/weather_alert_collection.rb
131
+ - lib/tenkit/weather_alert_summary.rb
132
+ - lib/tenkit/weather_response.rb
104
133
  homepage: https://github.com/superbasicxyz/tenkit
105
134
  licenses:
106
135
  - MIT
107
136
  metadata: {}
108
- post_install_message:
137
+ post_install_message:
109
138
  rdoc_options: []
110
139
  require_paths:
111
140
  - lib
@@ -120,8 +149,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
120
149
  - !ruby/object:Gem::Version
121
150
  version: '0'
122
151
  requirements: []
123
- rubygems_version: 3.0.3.1
124
- signing_key:
152
+ rubygems_version: 3.4.6
153
+ signing_key:
125
154
  specification_version: 4
126
155
  summary: Wrapper for WeatherKit API
127
156
  test_files: []