weather-emoji 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/weather +29 -1
- data/lib/weather-emoji.rb +7 -5
- data/lib/weather-emoji/api.rb +50 -18
- data/lib/weather-emoji/emoji.rb +20 -8
- data/lib/weather-emoji/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 21cfddc805287e4a88f936350a8720c86a908e5b
|
4
|
+
data.tar.gz: a63f9861a3a0ae7975ba80ca06bd713ce41a24df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 811e86c10184927c43879e4e4bfe73386a8130b4b61fa5f70dd8d3abfe1a7b9ac3dbcd65dfce71a126899cea7d3673889a85b440cd5230073c066b2e84fbfaf2
|
7
|
+
data.tar.gz: 9284146f30c5553ce1d1f6e35723c2dd35fcb6431e85044605c6121d92a4893c55ff7c18c15a2e4a50c0cb08bc67a64218eac8f4dcc4ea9e4d6aa956d9453318
|
data/bin/weather
CHANGED
@@ -1,4 +1,32 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'weather-emoji'
|
4
|
-
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
options = {:host => nil}
|
7
|
+
|
8
|
+
# Rules to parse the command line arguments.
|
9
|
+
parser = OptionParser.new do |opts|
|
10
|
+
opts.banner = "Usage: weather [options]"
|
11
|
+
|
12
|
+
opts.on('-c', '--celsius', 'to use Metric (Celsius)') do
|
13
|
+
options[:unit] = "metric";
|
14
|
+
end
|
15
|
+
|
16
|
+
opts.on('-f', '--fahrenheit', 'to use Imperial (Fahrenheit)') do
|
17
|
+
options[:unit] = "imperial";
|
18
|
+
end
|
19
|
+
|
20
|
+
opts.on('-h', '--help', 'Display this help message') do
|
21
|
+
puts opts
|
22
|
+
exit
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Parse arguments according to above rules; leftovers are kept in ARGV
|
27
|
+
parser.parse!
|
28
|
+
|
29
|
+
# print the target hostname
|
30
|
+
options[:host] = ARGV[0]
|
31
|
+
|
32
|
+
puts WeatherEmoji::weather options
|
data/lib/weather-emoji.rb
CHANGED
@@ -5,10 +5,12 @@ require_relative 'weather-emoji/api'
|
|
5
5
|
require_relative 'weather-emoji/emoji'
|
6
6
|
|
7
7
|
module WeatherEmoji
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
# the "wrapper" for everything.
|
9
|
+
def self.weather options
|
10
|
+
coord = get_coordinates options[:host]
|
11
|
+
result = get_weather_for_coordinates coord, options
|
11
12
|
data = consume_weather_data result
|
12
|
-
WeatherEmoji::stringify data
|
13
|
+
puts WeatherEmoji::stringify data
|
14
|
+
exit
|
13
15
|
end
|
14
|
-
end
|
16
|
+
end
|
data/lib/weather-emoji/api.rb
CHANGED
@@ -2,60 +2,83 @@ module WeatherEmoji
|
|
2
2
|
GEOIP_URI = "http://freegeoip.net/json/"
|
3
3
|
API_KEY = "17928230b610439be8e3f005b7245c8a"
|
4
4
|
|
5
|
-
# get coordinates for given IP address
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
# get coordinates and corresponding country code for given IP address
|
6
|
+
# * +ip_addr+ - the IP address, or the hostname to get coordinates and country code of.
|
7
|
+
def self.get_coordinates ip_addr
|
9
8
|
uri = GEOIP_URI
|
10
9
|
uri += ip_addr if ip_addr
|
11
10
|
|
12
11
|
begin
|
13
12
|
response = JSON.parse(Net::HTTP.get(URI(uri)))
|
13
|
+
|
14
|
+
# latitude, longitude
|
14
15
|
lat = response["latitude"]
|
15
16
|
lon = response["longitude"]
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
|
18
|
+
# fetch country_code to determine which unit to default to
|
19
|
+
country_code = response["country_code"]
|
20
|
+
return [lat, lon, country_code]
|
21
|
+
rescue
|
22
|
+
puts "no internet connection or invalid hostname!"
|
23
|
+
exit
|
20
24
|
end
|
21
25
|
end
|
22
26
|
|
23
27
|
# get weather for given coordinates
|
24
|
-
def self.get_weather_for_coordinates coordinates,
|
28
|
+
def self.get_weather_for_coordinates coordinates, options
|
25
29
|
raise ArgumentError.new('latitude or longtitude not Numeric.') unless coordinates[0].is_a? Numeric or coordinates[1].is_a? Numeric
|
26
30
|
|
27
31
|
raw_weather_data = {}
|
28
32
|
|
29
|
-
|
33
|
+
# set up unit depending on the coordinate's country, if not given
|
34
|
+
raw_weather_data[:unit] = options[:unit]
|
35
|
+
if options[:unit].nil?
|
36
|
+
if coordinates[2] == "US"
|
37
|
+
raw_weather_data[:unit] = "imperial"
|
38
|
+
else
|
39
|
+
raw_weather_data[:unit] = "metric"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
current_weather_response = JSON.parse(Net::HTTP.get(URI(endpoint_for_current_weather(coordinates, raw_weather_data[:unit]))))
|
30
44
|
if current_weather_response["cod"] == 200
|
31
45
|
raw_weather_data[:current] = current_weather_response
|
32
46
|
else
|
33
|
-
|
47
|
+
puts "Error getting current weather information (#{current_weather_response["cod"]})"
|
34
48
|
exit
|
35
49
|
end
|
36
50
|
|
37
|
-
forecast_weather_response = JSON.parse(Net::HTTP.get(URI(endpoint_for_weather_forecast(coordinates))))
|
51
|
+
forecast_weather_response = JSON.parse(Net::HTTP.get(URI(endpoint_for_weather_forecast(coordinates, raw_weather_data[:unit]))))
|
38
52
|
if forecast_weather_response["cod"] == "200"
|
39
53
|
raw_weather_data[:today] = forecast_weather_response["list"][0]
|
40
54
|
raw_weather_data[:tomorrow] = forecast_weather_response["list"][1]
|
41
55
|
else
|
42
|
-
|
56
|
+
puts "error getting forecast information (#{forecast_weather_response["cod"]})"
|
43
57
|
exit
|
44
58
|
end
|
45
59
|
|
46
60
|
raw_weather_data
|
47
61
|
end
|
48
62
|
|
49
|
-
|
63
|
+
# Returns the API endpoint for current weather.
|
64
|
+
# * +coordinates+ - the coordinates to check weather of.
|
65
|
+
# * +unit+ - the unit to use. nil defaults to Kelvin; need to provide either "metric" or "imperial" for common uses.
|
66
|
+
def self.endpoint_for_current_weather coordinates, unit
|
50
67
|
"http://api.openweathermap.org/data/2.5/weather?units=#{unit}&lat=#{coordinates[0]}&lon=#{coordinates[1]}&APPID=#{API_KEY}"
|
51
68
|
end
|
52
69
|
|
53
|
-
|
70
|
+
# Returns the API endpoint for weather forecast.
|
71
|
+
# * +coordinates+ - the coordinates to check weather of.
|
72
|
+
# * +unit+ - the unit to use. nil defaults to Kelvin; need to provide either "metric" or "imperial" for common uses.
|
73
|
+
def self.endpoint_for_weather_forecast coordinates, unit
|
54
74
|
"http://api.openweathermap.org/data/2.5/forecast/daily?units=#{unit}&lat=#{coordinates[0]}&lon=#{coordinates[1]}&APPID=#{API_KEY}"
|
55
75
|
end
|
56
76
|
|
77
|
+
# Consumes given raw weather data from the API call.
|
78
|
+
# * +raw_weather_data+ - the raw data from the API call.
|
57
79
|
def self.consume_weather_data raw_weather_data
|
58
80
|
weather_data = {}
|
81
|
+
weather_data[:unit] = raw_weather_data[:unit]
|
59
82
|
|
60
83
|
weather_data[:current] = {
|
61
84
|
:code => raw_weather_data[:current]["weather"][0]["id"],
|
@@ -90,10 +113,19 @@ module WeatherEmoji
|
|
90
113
|
weather_data
|
91
114
|
end
|
92
115
|
|
116
|
+
def self.unit_code_for weather_data
|
117
|
+
if weather_data[:unit] == "metric"
|
118
|
+
"C"
|
119
|
+
elsif weather_data[:unit] == "imperial"
|
120
|
+
"F"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
93
124
|
def self.stringify weather_data
|
94
|
-
|
95
|
-
|
96
|
-
|
125
|
+
unit = unit_code_for weather_data
|
126
|
+
"Now: #{weather_data[:current][:code].to_emoji} (#{weather_data[:current][:temp].to_i}º#{unit}/#{weather_data[:current][:humidity]}%)
|
127
|
+
Today: #{weather_data[:today][:code].to_emoji} (#{weather_data[:today][:min].to_i}-#{weather_data[:today][:max].to_i}º#{unit})
|
128
|
+
Tomorrow: #{weather_data[:tomorrow][:code].to_emoji} (#{weather_data[:tomorrow][:min].to_i}-#{weather_data[:tomorrow][:max].to_i}º#{unit})"
|
97
129
|
end
|
98
130
|
|
99
131
|
end
|
data/lib/weather-emoji/emoji.rb
CHANGED
@@ -22,25 +22,37 @@ class Integer
|
|
22
22
|
end
|
23
23
|
|
24
24
|
# corresponding emoji for one single weather code.
|
25
|
-
# TODO verify each weather code to emoji conversion is accurate
|
26
25
|
def to_emoji
|
27
26
|
case self
|
28
|
-
when (200
|
29
|
-
"\u{26A1}"
|
30
|
-
when (300
|
27
|
+
when (200..299), 960, 961
|
28
|
+
"\u{26A1}" # thunderstorm
|
29
|
+
when (300..399)
|
31
30
|
"\u{1F326}" # light rain (drizzle)
|
32
|
-
when (500
|
33
|
-
"\u{2614}"
|
31
|
+
when (500..599)
|
32
|
+
"\u{2614}" # rain
|
33
|
+
when (600..699)
|
34
34
|
when 800
|
35
35
|
"\u{1F31E}" # clear sky
|
36
36
|
when 801
|
37
|
-
"\u{26C5}"
|
37
|
+
"\u{26C5}" # few clouds
|
38
38
|
when 802
|
39
39
|
"\u{1F324}" # scattered clouds
|
40
40
|
when 803
|
41
41
|
"\u{1F325}" # broken clouds
|
42
42
|
when 804
|
43
|
-
"\u{2601}"
|
43
|
+
"\u{2601}" # overcast clouds
|
44
|
+
when 900, 962
|
45
|
+
"\u{1F32A}" # tornado
|
46
|
+
when 903
|
47
|
+
"\u{2744}" # cold
|
48
|
+
when 904
|
49
|
+
"\u{1F525}" # hot
|
50
|
+
when 905, 957
|
51
|
+
"\u{1F32C}" # windy
|
52
|
+
when 906, 958, 959
|
53
|
+
"\u{1F30A}" # hail
|
54
|
+
else
|
55
|
+
"\u{1F30A}" # error
|
44
56
|
end
|
45
57
|
end
|
46
58
|
end
|