Skip to content

Commit 47fe6dd

Browse files
committed
Add forecaster
1 parent e43d9fe commit 47fe6dd

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

forecaster.rb

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#!/usr/bin/env ruby
2+
3+
require "#{ENV['HOME']}/programming/scripts/moon_info.rb"
4+
require 'json'
5+
require 'date'
6+
7+
class Forecaster
8+
URL = 'https://api.openweathermap.org/data/3.0/onecall'
9+
API_KEY = ENV['OPENWEATHER_API_KEY']
10+
11+
def self.call(latitude, longitude)
12+
new(latitude, longitude).call
13+
end
14+
15+
def initialize(latitude, longitude)
16+
@latitude = latitude
17+
@longitude = longitude
18+
end
19+
20+
def call
21+
build_structure(fetch_forecast)
22+
end
23+
24+
private
25+
attr_reader :latitude, :longitude
26+
27+
def build_structure(forecast)
28+
current = {
29+
temp: forecast['current']['temp'],
30+
desc: forecast['current']['weather'][0]['description'],
31+
icon_url: icon_url(forecast['current']['weather'][0]['icon'])
32+
}
33+
34+
daily = forecast['daily'].map do |day|
35+
{
36+
date: Time.at(day['dt']).to_date.to_s,
37+
sunrise: Time.at(day['sunrise']).strftime("%H:%M"),
38+
sunset: Time.at(day['sunset']).strftime("%H:%M"),
39+
moon_info: MoonInfo.new(day['moon_phase']),
40+
uvi: day['uvi'],
41+
uv_risk: risk_from_uv(day['uvi']),
42+
min_temp: day['temp']['min'],
43+
max_temp: day['temp']['max'],
44+
desc: day['weather'][0]['description'],
45+
icon_url: icon_url(day['weather'][0]['icon'])
46+
}
47+
end
48+
49+
OpenStruct.new(current: current, daily: daily)
50+
end
51+
52+
def risk_from_uv(uvi)
53+
case uvi
54+
when 0..2 then 'low'
55+
when 2..5 then 'moderate'
56+
when 5..7 then 'high'
57+
when 7..10 then 'very_high'
58+
else
59+
'extreme'
60+
end
61+
end
62+
63+
def fetch_forecast
64+
url = URL
65+
url += "?lat=#{latitude}"
66+
url += "&lon=#{longitude}"
67+
url += "&appid=#{API_KEY}"
68+
url += "&units=metric"
69+
url += "&exclude=minutely,hourly"
70+
71+
JSON.parse(`curl -s '#{url}'`)
72+
end
73+
74+
def icon_url(icon)
75+
"https://openweathermap.org/img/wn/#{icon}@2x.png"
76+
end
77+
end

0 commit comments

Comments
 (0)