zetabot 1.0.7 → 1.1.0
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 +4 -4
- data/Gemfile.lock +36 -34
- data/bin/{console → zconsole} +1 -1
- data/bin/{setup → zeta_setup} +0 -0
- data/lib/Zeta/plugins/pdfinfo.rb +12 -14
- data/lib/Zeta/plugins/russian_roulette.rb +1 -1
- data/lib/Zeta/plugins/seen.rb +5 -1
- data/lib/Zeta/plugins/weather.rb +120 -151
- data/lib/Zeta/version.rb +1 -1
- metadata +5 -8
- data/lib/Zeta/gems.locked +0 -10
- data/lib/Zeta/plugins/weather_almanac.rb +0 -61
- data/lib/Zeta/plugins/weather_hurricane.rb +0 -44
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9a9cad4211323234ab96a59ba56d31982295e7592613da47f5859e89bb0d022a
|
|
4
|
+
data.tar.gz: ddf5ed10a9812098fa3af3113a81d6ba6eabbafca13b582dd0556ca04fb7ea36
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 26f5d9265910bdebf81fa1951555293eac0fb993a03578e1c8abf77e1c48ba716d4c5b47bbdd1f71b1646b2db7856f7b60acc78568c1ac016361c8b306f20b24
|
|
7
|
+
data.tar.gz: 91eb85dfdba2027300c335d7a8e718aaf4b44ee33d2bb63a9843fe0822c0abe4d601f1ec52e0b76c442289d250bebd69c77962cfc5fa6796756bffec90815032
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
zetabot (1.0.
|
|
4
|
+
zetabot (1.0.2)
|
|
5
5
|
actionview
|
|
6
6
|
chronic
|
|
7
7
|
chronic_duration
|
|
@@ -42,13 +42,13 @@ GEM
|
|
|
42
42
|
remote: https://rubygems.org/
|
|
43
43
|
specs:
|
|
44
44
|
Ascii85 (1.0.3)
|
|
45
|
-
actionview (5.2.
|
|
46
|
-
activesupport (= 5.2.
|
|
45
|
+
actionview (5.2.1)
|
|
46
|
+
activesupport (= 5.2.1)
|
|
47
47
|
builder (~> 3.1)
|
|
48
48
|
erubi (~> 1.4)
|
|
49
49
|
rails-dom-testing (~> 2.0)
|
|
50
50
|
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
|
51
|
-
activesupport (5.2.
|
|
51
|
+
activesupport (5.2.1)
|
|
52
52
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
53
53
|
i18n (>= 0.7, < 2)
|
|
54
54
|
minitest (~> 5.1)
|
|
@@ -72,12 +72,13 @@ GEM
|
|
|
72
72
|
cinch (~> 2.0)
|
|
73
73
|
cinch-toolbox (1.1.6)
|
|
74
74
|
nokogiri (~> 1.6)
|
|
75
|
-
clipboard (1.1.
|
|
75
|
+
clipboard (1.1.2)
|
|
76
76
|
code (0.9.2)
|
|
77
77
|
coderay (~> 1.1)
|
|
78
78
|
method_source (~> 0.9)
|
|
79
79
|
coderay (1.1.2)
|
|
80
80
|
concurrent-ruby (1.0.5)
|
|
81
|
+
connection_pool (2.2.2)
|
|
81
82
|
crack (0.4.3)
|
|
82
83
|
safe_yaml (~> 1.0.0)
|
|
83
84
|
crass (1.0.4)
|
|
@@ -89,7 +90,7 @@ GEM
|
|
|
89
90
|
thread_safe (~> 0.3, >= 0.3.1)
|
|
90
91
|
destructor (0.1.0)
|
|
91
92
|
diff-lcs (1.3)
|
|
92
|
-
discourse_api (0.
|
|
93
|
+
discourse_api (0.27.0)
|
|
93
94
|
faraday (~> 0.9)
|
|
94
95
|
faraday_middleware (~> 0.10)
|
|
95
96
|
rack (>= 1.6)
|
|
@@ -109,9 +110,9 @@ GEM
|
|
|
109
110
|
multipart-post (>= 1.2, < 3)
|
|
110
111
|
faraday_middleware (0.12.2)
|
|
111
112
|
faraday (>= 0.7.4, < 1.0)
|
|
112
|
-
ffi (1.9.
|
|
113
|
-
geocoder (1.
|
|
114
|
-
gist (
|
|
113
|
+
ffi (1.9.25)
|
|
114
|
+
geocoder (1.5.0)
|
|
115
|
+
gist (5.0.0)
|
|
115
116
|
github_api (0.18.2)
|
|
116
117
|
addressable (~> 2.4)
|
|
117
118
|
descendants_tracker (~> 0.0.4)
|
|
@@ -122,20 +123,20 @@ GEM
|
|
|
122
123
|
temple (>= 0.8.0)
|
|
123
124
|
tilt
|
|
124
125
|
hashery (2.1.2)
|
|
125
|
-
hashie (3.
|
|
126
|
+
hashie (3.6.0)
|
|
126
127
|
hirb (0.7.3)
|
|
127
128
|
http-cookie (1.0.3)
|
|
128
129
|
domain_name (~> 0.5)
|
|
129
130
|
httparty (0.16.2)
|
|
130
131
|
multi_xml (>= 0.5.2)
|
|
131
132
|
humanize-bytes (2.2.0)
|
|
132
|
-
i18n (1.0
|
|
133
|
+
i18n (1.1.0)
|
|
133
134
|
concurrent-ruby (~> 1.0)
|
|
134
135
|
instance (0.2.0)
|
|
135
136
|
interactive_editor (0.0.11)
|
|
136
137
|
spoon (>= 0.0.1)
|
|
137
138
|
ipaddress (0.8.3)
|
|
138
|
-
irbtools (2.2.
|
|
139
|
+
irbtools (2.2.1)
|
|
139
140
|
binding.repl (~> 3.0)
|
|
140
141
|
clipboard (~> 1.1)
|
|
141
142
|
code (~> 0.9)
|
|
@@ -149,7 +150,7 @@ GEM
|
|
|
149
150
|
method_locator (~> 0.0, >= 0.0.4)
|
|
150
151
|
methodfinder (~> 2.0)
|
|
151
152
|
ori (~> 0.1.0)
|
|
152
|
-
os
|
|
153
|
+
os
|
|
153
154
|
paint (>= 0.9, < 3.0)
|
|
154
155
|
ruby_engine (~> 1.0)
|
|
155
156
|
ruby_info (~> 1.0)
|
|
@@ -161,12 +162,12 @@ GEM
|
|
|
161
162
|
loofah (2.2.2)
|
|
162
163
|
crass (~> 1.0.2)
|
|
163
164
|
nokogiri (>= 1.5.9)
|
|
164
|
-
mechanize (2.7.
|
|
165
|
+
mechanize (2.7.6)
|
|
165
166
|
domain_name (~> 0.5, >= 0.5.1)
|
|
166
167
|
http-cookie (~> 1.0)
|
|
167
168
|
mime-types (>= 1.17.2)
|
|
168
169
|
net-http-digest_auth (~> 1.1, >= 1.1.1)
|
|
169
|
-
net-http-persistent (
|
|
170
|
+
net-http-persistent (>= 2.5.2)
|
|
170
171
|
nokogiri (~> 1.6)
|
|
171
172
|
ntlm-http (~> 0.1, >= 0.1.1)
|
|
172
173
|
webrobots (>= 0.0.9, < 0.2)
|
|
@@ -174,10 +175,10 @@ GEM
|
|
|
174
175
|
thread_safe (~> 0.3, >= 0.3.1)
|
|
175
176
|
method_locator (0.0.4)
|
|
176
177
|
method_source (0.9.0)
|
|
177
|
-
methodfinder (2.
|
|
178
|
-
mime-types (3.
|
|
178
|
+
methodfinder (2.2.1)
|
|
179
|
+
mime-types (3.2.2)
|
|
179
180
|
mime-types-data (~> 3.2015)
|
|
180
|
-
mime-types-data (3.
|
|
181
|
+
mime-types-data (3.2018.0812)
|
|
181
182
|
mini_portile2 (2.3.0)
|
|
182
183
|
minitest (5.11.3)
|
|
183
184
|
mkfifo (0.1.1)
|
|
@@ -185,10 +186,11 @@ GEM
|
|
|
185
186
|
multi_xml (0.6.0)
|
|
186
187
|
multipart-post (2.0.0)
|
|
187
188
|
net-http-digest_auth (1.4.1)
|
|
188
|
-
net-http-persistent (
|
|
189
|
-
|
|
189
|
+
net-http-persistent (3.0.0)
|
|
190
|
+
connection_pool (~> 2.2)
|
|
191
|
+
net_http_timeout_errors (0.3.3)
|
|
190
192
|
netrc (0.11.0)
|
|
191
|
-
nokogiri (1.8.
|
|
193
|
+
nokogiri (1.8.4)
|
|
192
194
|
mini_portile2 (~> 2.3.0)
|
|
193
195
|
ntlm-http (0.1.1)
|
|
194
196
|
numerizer (0.1.1)
|
|
@@ -212,7 +214,7 @@ GEM
|
|
|
212
214
|
ruby-rc4
|
|
213
215
|
ttfunk
|
|
214
216
|
persist (1.0.0)
|
|
215
|
-
public_suffix (3.0.
|
|
217
|
+
public_suffix (3.0.3)
|
|
216
218
|
rack (2.0.5)
|
|
217
219
|
rails-dom-testing (2.0.3)
|
|
218
220
|
activesupport (>= 4.2.0)
|
|
@@ -225,19 +227,19 @@ GEM
|
|
|
225
227
|
http-cookie (>= 1.0.2, < 2.0)
|
|
226
228
|
mime-types (>= 1.16, < 4.0)
|
|
227
229
|
netrc (~> 0.8)
|
|
228
|
-
rspec (3.
|
|
229
|
-
rspec-core (~> 3.
|
|
230
|
-
rspec-expectations (~> 3.
|
|
231
|
-
rspec-mocks (~> 3.
|
|
232
|
-
rspec-core (3.
|
|
233
|
-
rspec-support (~> 3.
|
|
234
|
-
rspec-expectations (3.
|
|
230
|
+
rspec (3.8.0)
|
|
231
|
+
rspec-core (~> 3.8.0)
|
|
232
|
+
rspec-expectations (~> 3.8.0)
|
|
233
|
+
rspec-mocks (~> 3.8.0)
|
|
234
|
+
rspec-core (3.8.0)
|
|
235
|
+
rspec-support (~> 3.8.0)
|
|
236
|
+
rspec-expectations (3.8.1)
|
|
235
237
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
236
|
-
rspec-support (~> 3.
|
|
237
|
-
rspec-mocks (3.
|
|
238
|
+
rspec-support (~> 3.8.0)
|
|
239
|
+
rspec-mocks (3.8.0)
|
|
238
240
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
239
|
-
rspec-support (~> 3.
|
|
240
|
-
rspec-support (3.
|
|
241
|
+
rspec-support (~> 3.8.0)
|
|
242
|
+
rspec-support (3.8.0)
|
|
241
243
|
ruby-ll (2.1.2)
|
|
242
244
|
ansi
|
|
243
245
|
ast
|
|
@@ -260,7 +262,7 @@ GEM
|
|
|
260
262
|
unf (0.1.4)
|
|
261
263
|
unf_ext
|
|
262
264
|
unf_ext (0.0.7.5)
|
|
263
|
-
unicode-display_width (1.
|
|
265
|
+
unicode-display_width (1.4.0)
|
|
264
266
|
unitwise (2.2.0)
|
|
265
267
|
liner (~> 0.2)
|
|
266
268
|
memoizable (~> 0.4)
|
data/bin/{console → zconsole}
RENAMED
|
@@ -4,7 +4,7 @@ require "bundler/setup"
|
|
|
4
4
|
require "zeta"
|
|
5
5
|
|
|
6
6
|
# You can add fixtures and/or initialization code here to make experimenting
|
|
7
|
-
# with your gem easier. You can also use a different
|
|
7
|
+
# with your gem easier. You can also use a different zconsole, if you like.
|
|
8
8
|
|
|
9
9
|
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
10
10
|
# require "pry"
|
data/bin/{setup → zeta_setup}
RENAMED
|
File without changes
|
data/lib/Zeta/plugins/pdfinfo.rb
CHANGED
|
@@ -42,20 +42,18 @@ module Plugins
|
|
|
42
42
|
return msg.reply("PDF → Unable to parse. file too big #{humanize_size}kb")
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
end
|
|
58
|
-
}
|
|
45
|
+
|
|
46
|
+
# Get file and parse metadata
|
|
47
|
+
open(url, "rb") do |io|
|
|
48
|
+
reader = PDF::Reader.new(io)
|
|
49
|
+
creator = reader.info[:Creator] || 'Anon'
|
|
50
|
+
producer = reader.info[:Producer] || 'Anon'
|
|
51
|
+
creation = reader.info[:CreationDate] || 'now'
|
|
52
|
+
modification = reader.info[:ModDate] || 'now'
|
|
53
|
+
title = reader.info[:Title] || nil
|
|
54
|
+
display = title ? title : "Title: None <> Creator: #{creator} <> Producer: #{producer} <> Creation: #{creation}"
|
|
55
|
+
msg.reply "PDF (#{humanize_size}kb) → #{display}"
|
|
56
|
+
end
|
|
59
57
|
|
|
60
58
|
|
|
61
59
|
rescue => e
|
|
@@ -37,7 +37,7 @@ module Plugins
|
|
|
37
37
|
return m.reply "I am sorry comrade, but I do not have pistol on me." unless m.channel.ops.include?(@bot)
|
|
38
38
|
return m.user.notice "Sorry comrade, but there is already game going on." if @games.include?(m.channel.name)
|
|
39
39
|
|
|
40
|
-
# player
|
|
40
|
+
# player zeta_setup
|
|
41
41
|
player = m.user
|
|
42
42
|
# player = m.user if player == @bot
|
|
43
43
|
# be nice, don't force the game on the starter unless the user actually exists in the channel.
|
data/lib/Zeta/plugins/seen.rb
CHANGED
|
@@ -6,7 +6,11 @@ module Plugins
|
|
|
6
6
|
def to_s
|
|
7
7
|
# "[#{time.asctime}] #{who} was seen in #{where} last saying #{what}"
|
|
8
8
|
time_ago = time_ago_in_words(Time.at(time))
|
|
9
|
-
"[ \x1F#{where.to_s.upcase}\x0F ] \x0304#{who}\x0F: \"\x0303#{what[0..300]}\x0F\" \x02#{time_ago}\x0F ago"
|
|
9
|
+
# "[ \x1F#{where.to_s.upcase}\x0F ] \x0304#{who}\x0F: \"\x0303#{what[0..300]}\x0F\" \x02#{time_ago}\x0F ago"
|
|
10
|
+
if where.to_s.upcase == 'STAFF' || where.to_s.upcase == 'SERVICES'
|
|
11
|
+
return ''
|
|
12
|
+
end
|
|
13
|
+
"Seen ∴ \x0304#{who}\x0F was last seen talking in \x1F#{where.to_s.upcase}\x0F \x02#{time_ago}\x0F ago."
|
|
10
14
|
end
|
|
11
15
|
end
|
|
12
16
|
|
data/lib/Zeta/plugins/weather.rb
CHANGED
|
@@ -21,107 +21,131 @@ module Plugins
|
|
|
21
21
|
match /w (.+)/, method: :weather
|
|
22
22
|
match 'w', method: :weather
|
|
23
23
|
match /setw (.+)/, method: :set_location
|
|
24
|
-
match /setws (.+)/, method: :set_source
|
|
25
24
|
match /wx (.+)/, method: :weather
|
|
26
25
|
match /weather (.+)/, method: :weather
|
|
26
|
+
match /almanac (.+)/, method: :almanac
|
|
27
|
+
match /hurricane/, method: :hurricane
|
|
27
28
|
|
|
28
29
|
#####
|
|
29
30
|
def initialize(*args)
|
|
30
|
-
@api_src = %w{wu noaa
|
|
31
|
-
@
|
|
32
|
-
@store = Persist.new(File.join(Dir.home, '.zeta', 'cache', 'weather.pstore'))
|
|
33
|
-
@source = Persist.new(File.join(Dir.home, '.zeta', 'cache', 'weather_source.pstore'))
|
|
31
|
+
@api_src = %w{wu noaa darksky owm}
|
|
32
|
+
@store = Persist.new(File.join(Dir.home, '.zeta', 'cache', 'weather.pstore'))
|
|
34
33
|
super
|
|
35
34
|
end
|
|
36
35
|
|
|
37
36
|
# ?w <location>
|
|
38
37
|
def weather(msg, query=nil)
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
else
|
|
42
|
-
stored_source = 'wu'
|
|
43
|
-
end
|
|
44
|
-
|
|
38
|
+
# Pull data source and scrub query
|
|
39
|
+
# Lookup user from pstore
|
|
45
40
|
if !@store[msg.user.to_s].nil? && query.nil?
|
|
46
|
-
|
|
41
|
+
stored_location, stored_source = @store[msg.user.to_s].split('::')
|
|
42
|
+
stored_source = @api_src.include?(stored_source) ? stored_source : 'wu'
|
|
43
|
+
data = send("#{stored_source}_src", stored_location)
|
|
44
|
+
# location = geolookup(@store[msg.user.to_s])
|
|
45
|
+
# data = wunderground_src(stored_location, false)
|
|
47
46
|
elsif query.nil?
|
|
48
|
-
return msg.reply 'No location set. ?setw <location>
|
|
47
|
+
return msg.reply 'No location set. ?setw <location> :(wu|darkscy|noaa|apixu|owm)'
|
|
49
48
|
else
|
|
50
49
|
# data = wu_src(query, true)
|
|
50
|
+
src = query[/:\w+/].gsub(/:/, '') if query[/:\w+/]
|
|
51
51
|
query = query.gsub(/:\w+/, '').strip if query
|
|
52
|
-
|
|
52
|
+
true_src = @api_src.include?(src) ? src : 'wu'
|
|
53
|
+
data = send("#{true_src}_src", query)
|
|
53
54
|
end
|
|
54
|
-
|
|
55
|
-
return msg.reply
|
|
55
|
+
return msg.reply "No results found for #{query} with #{true_src} source." if data.nil?
|
|
56
|
+
# return msg.reply 'Problem getting data. Try again later.' if data.nil?
|
|
56
57
|
msg.reply(data.reply)
|
|
57
58
|
end
|
|
58
59
|
|
|
59
60
|
# ?setw <location>
|
|
60
61
|
def set_location(msg, query)
|
|
61
62
|
# Establish source
|
|
63
|
+
src = query[/:\w+/].gsub(/:/, '') if query[/:\w+/]
|
|
62
64
|
query = query.gsub(/:\w+/, '').strip if query
|
|
63
65
|
|
|
64
66
|
# Sanity Check
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
else
|
|
68
|
-
stored_source = 'wu'
|
|
69
|
-
end
|
|
70
|
-
data = send("#{stored_source}_src", msg,query)
|
|
67
|
+
true_src = @api_src.include?(src) ? src : 'wu'
|
|
68
|
+
data = send("#{true_src}_src", query)
|
|
71
69
|
|
|
72
70
|
# Error
|
|
73
71
|
return msg.reply "No results found for #{query}." if data.nil?
|
|
74
72
|
|
|
75
73
|
# Store and display general location
|
|
76
|
-
|
|
77
|
-
serial_location = "#{data.lat},#{data.lon}"
|
|
74
|
+
serial_location = "#{query}::#{src}"
|
|
78
75
|
@store[msg.user.to_s] = serial_location unless data.nil?
|
|
79
|
-
msg.reply "Your location is now set to #{data.ac.
|
|
76
|
+
msg.reply "Your location is now set to #{data.ac.name}, #{data.ac.c}!"
|
|
80
77
|
end
|
|
81
78
|
|
|
82
|
-
# ?
|
|
83
|
-
def
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
79
|
+
# ?hurricane
|
|
80
|
+
def hurricane(msg)
|
|
81
|
+
url = URI.encode "http://api.wunderground.com/api/#{Zsec.wunderground}/currenthurricane/view.json"
|
|
82
|
+
location = JSON.parse(
|
|
83
|
+
# RestClient.get(url)
|
|
84
|
+
open(url).read
|
|
85
|
+
)
|
|
86
|
+
return msg.reply "No results found for #{query}." if location.nil?
|
|
87
|
+
reply_msg = "∴ #{location['currenthurricane'][0]['stormInfo']['stormName_Nice']} " \
|
|
88
|
+
"(#{location['currenthurricane'][0]['stormInfo']['stormNumber']}) "\
|
|
89
|
+
"≈ Category #{location['currenthurricane'][0]['Current']['SaffirSimpsonCategory']} " \
|
|
90
|
+
"≈ Wind #{location['currenthurricane'][0]['Current']['WindSpeed']['Mph']} mph " \
|
|
91
|
+
"(#{location['currenthurricane'][0]['Current']['WindSpeed']['Kph']} kph) " \
|
|
92
|
+
"≈ Wind Gust #{location['currenthurricane'][0]['Current']['WindGust']['Mph']} mph " \
|
|
93
|
+
"(#{location['currenthurricane'][0]['Current']['WindGust']['Kph']} kph) " \
|
|
94
|
+
"≈ #{location['currenthurricane'][0]['Current']['Time']['pretty']} ∴"
|
|
95
|
+
msg.reply(reply_msg)
|
|
88
96
|
end
|
|
89
97
|
|
|
98
|
+
# ?almanac <location>
|
|
99
|
+
def almanac(msg, locale)
|
|
100
|
+
autocomplete = JSON.parse(open(URI.encode("http://autocomplete.wunderground.com/aq?query=#{locale}")).read)
|
|
101
|
+
url = URI.encode("http://api.wunderground.com/api/#{Config.secrets[:wunderground]}/almanac/#{autocomplete['RESULTS'][0]['l']}.json")
|
|
102
|
+
location = JSON.parse(
|
|
103
|
+
# RestClient.get(url)
|
|
104
|
+
open(url).read
|
|
105
|
+
)
|
|
106
|
+
return msg.reply "No results found for #{query}." if location.nil?
|
|
107
|
+
|
|
108
|
+
time = Time.now()
|
|
109
|
+
|
|
110
|
+
data = OpenStruct.new(
|
|
111
|
+
date: time.strftime('%B, %d %Y (%A) '),
|
|
112
|
+
airport: location['almanac']['airport_code'],
|
|
113
|
+
high_norm_f: location['almanac']['temp_high']['normal']['F'],
|
|
114
|
+
high_norm_c: location['almanac']['temp_high']['normal']['C'],
|
|
115
|
+
high_record_y: location['almanac']['temp_high']['recordyear'],
|
|
116
|
+
high_record_f: location['almanac']['temp_high']['record']['F'],
|
|
117
|
+
high_record_c: location['almanac']['temp_high']['normal']['C'],
|
|
118
|
+
low_norm_f: location['almanac']['temp_low']['normal']['F'],
|
|
119
|
+
low_norm_c: location['almanac']['temp_low']['normal']['C'],
|
|
120
|
+
low_record_y: location['almanac']['temp_low']['recordyear'],
|
|
121
|
+
low_record_f: location['almanac']['temp_low']['record']['F'],
|
|
122
|
+
low_record_c: location['almanac']['temp_low']['normal']['C'],
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
reply_msg = "∴ Almanac #{data.date} ≈ Airport #{data.airport} " \
|
|
126
|
+
"≈ Normal #{data.high_norm_f} F (#{data.high_norm_c} C) | #{data.low_norm_f} F (#{data.low_norm_c} C) " \
|
|
127
|
+
"≈ High #{data.high_record_f} F (#{data.high_record_c} C) [#{data.high_record_y}] " \
|
|
128
|
+
"≈ Low #{data.low_record_f} F (#{data.low_record_c} C) [#{data.low_record_y}] ∴"
|
|
129
|
+
|
|
130
|
+
msg.reply(reply_msg)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
# -private
|
|
90
135
|
private
|
|
91
136
|
#### Weather Sources
|
|
92
137
|
# Weather Underground - https://wunderground.com
|
|
93
|
-
def wu_src(
|
|
138
|
+
def wu_src(location)
|
|
94
139
|
# Fuzzy location lookup
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
if stored
|
|
101
|
-
lat, lon = @store[msg.user.to_s].split(',')
|
|
102
|
-
else
|
|
140
|
+
ac = JSON.parse(
|
|
141
|
+
open(URI.encode("https://autocomplete.wunderground.com/aq?query=#{location}")).read,
|
|
142
|
+
object_class: OpenStruct
|
|
143
|
+
)
|
|
144
|
+
return nil if ac.RESULTS.empty?
|
|
103
145
|
|
|
104
|
-
|
|
105
|
-
open(URI.encode("https://maps.googleapis.com/maps/api/geocode/json?address=#{location}&key=#{Config.secrets[:google]}")).read,
|
|
106
|
-
object_class: OpenStruct
|
|
107
|
-
)
|
|
108
|
-
|
|
109
|
-
info(ac.status)
|
|
110
|
-
return nil if ac.results.nil?
|
|
111
|
-
if ac.status == "OVER_QUERY_LIMIT"
|
|
112
|
-
msg.reply("Google API - Over query Limit")
|
|
113
|
-
return nil
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
ac = ac.results[0]
|
|
117
|
-
lat = ac.geometry.location.lat
|
|
118
|
-
lon = ac.geometry.location.lng
|
|
119
|
-
localname = ac.formatted_address
|
|
120
|
-
end
|
|
121
|
-
# ac = ac.RESULTS[0]
|
|
146
|
+
ac = ac.RESULTS[0]
|
|
122
147
|
geolookup = JSON.parse(
|
|
123
|
-
|
|
124
|
-
open(URI.encode("https://api.wunderground.com/api/#{Config.secrets[:wunderground]}/geolookup/q/#{lat},#{lon}.json")).read,
|
|
148
|
+
open(URI.encode("https://api.wunderground.com/api/#{Config.secrets[:wunderground]}/geolookup/#{ac.l}.json")).read,
|
|
125
149
|
object_class: OpenStruct
|
|
126
150
|
).location.l rescue nil
|
|
127
151
|
|
|
@@ -131,19 +155,17 @@ module Plugins
|
|
|
131
155
|
object_class: OpenStruct
|
|
132
156
|
)
|
|
133
157
|
|
|
158
|
+
debug "DATA: #{data}"
|
|
134
159
|
data.ac = ac
|
|
135
|
-
data.lat = lat
|
|
136
|
-
data.lon = lon
|
|
137
|
-
localname = data.current_observation.display_location.full if localname.nil?
|
|
138
160
|
current = data.current_observation
|
|
139
161
|
alerts = data.alerts.empty? ? 'none' : data.alerts.map {|l| l['type']}.join(',')
|
|
140
|
-
pressure_si = Unitwise((current.pressure_in.to_f)+14.7, '[psi]').convert_to('kPa').to_f.round(2)
|
|
162
|
+
# pressure_si = Unitwise((current.pressure_in.to_f)+14.7, '[psi]').convert_to('kPa').to_f.round(2)
|
|
141
163
|
|
|
142
|
-
data.reply = "WU ∴ #{
|
|
164
|
+
data.reply = "WU ∴ #{ac.name}, #{ac.c} " \
|
|
143
165
|
"≈ #{current.weather} #{current.temperature_string} " \
|
|
144
166
|
"≈ Feels like #{current.feelslike_string} " \
|
|
145
167
|
"≈ Humidity: #{current.relative_humidity} " \
|
|
146
|
-
"≈ Pressure: #{current.pressure_in}
|
|
168
|
+
"≈ Pressure: #{current.pressure_in} in/Hg (#{current.pressure_mb} mbar) " \
|
|
147
169
|
"≈ Wind: #{current.wind_string} ≈ Alerts: #{alerts} ∴"
|
|
148
170
|
return data
|
|
149
171
|
# rescue
|
|
@@ -151,28 +173,17 @@ module Plugins
|
|
|
151
173
|
end
|
|
152
174
|
|
|
153
175
|
# Open Weather map - https://openweathermap.org/api
|
|
154
|
-
def owm_src(
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
176
|
+
def owm_src(location)
|
|
177
|
+
ac = JSON.parse(
|
|
178
|
+
open(URI.encode("http://maps.googleapis.com/maps/api/geocode/json?address=#{location}")).read,
|
|
179
|
+
object_class: OpenStruct
|
|
180
|
+
)
|
|
158
181
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
info(ac.status)
|
|
166
|
-
if ac.status == "OVER_QUERY_LIMIT"
|
|
167
|
-
msg.reply("Google API - Over query Limit")
|
|
168
|
-
return nil
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
ac = ac.results[0]
|
|
172
|
-
lat = ac.geometry.location.lat
|
|
173
|
-
lon = ac.geometry.location.lng
|
|
174
|
-
localname = ac.formatted_address
|
|
175
|
-
end
|
|
182
|
+
return nil if ac.results.nil? ## Unable to locate
|
|
183
|
+
|
|
184
|
+
ac = ac.results[0]
|
|
185
|
+
lat = ac.geometry.location.lat
|
|
186
|
+
lon = ac.geometry.location.lng
|
|
176
187
|
|
|
177
188
|
# Get Data
|
|
178
189
|
data = JSON.parse(
|
|
@@ -186,14 +197,10 @@ module Plugins
|
|
|
186
197
|
pressure = Unitwise((data.main.pressure.to_f/10)+101, 'kPa')
|
|
187
198
|
wind = Unitwise(data.wind.speed, 'kilometer')
|
|
188
199
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
data.lat = lat
|
|
192
|
-
data.lon = lon
|
|
193
|
-
data.reply = "OWM ∴ #{localname} " \
|
|
200
|
+
data.reply = "OWM ∴ #{ac.formatted_address} " \
|
|
194
201
|
"≈ #{data.weather[0].description}, #{temp.convert_to('[degF]').to_i.round(2)} F (#{temp.convert_to('Cel').to_i.round(2)} C) " \
|
|
195
202
|
"≈ Humidity: #{data.main.humidity}% " \
|
|
196
|
-
"≈ Pressure: #{pressure.convert_to('[psi]').to_f.round(2)}
|
|
203
|
+
"≈ Pressure: #{pressure.convert_to('[psi]').to_f.round(2)} in/Hg (#{data.main.pressure} mbar) " \
|
|
197
204
|
"≈ Wind: #{wind.convert_to('mile').to_i.round(2)} mph (#{wind.to_i.round(2)} km/h) ∴"
|
|
198
205
|
|
|
199
206
|
return data
|
|
@@ -201,29 +208,16 @@ module Plugins
|
|
|
201
208
|
end
|
|
202
209
|
|
|
203
210
|
# DarkSky - https://darksky.net/dev
|
|
204
|
-
def
|
|
205
|
-
|
|
211
|
+
def darksky_src(location)
|
|
206
212
|
ac = JSON.parse(
|
|
207
|
-
open(URI.encode("
|
|
213
|
+
open(URI.encode("http://maps.googleapis.com/maps/api/geocode/json?address=#{location}")).read,
|
|
208
214
|
object_class: OpenStruct
|
|
209
215
|
)
|
|
210
216
|
return nil if ac.results.nil? ## Unable to locate
|
|
211
217
|
|
|
212
|
-
info(ac.status)
|
|
213
|
-
if ac.status == "OVER_QUERY_LIMIT"
|
|
214
|
-
msg.reply("Google API - Over query Limit")
|
|
215
|
-
return nil
|
|
216
|
-
end
|
|
217
|
-
|
|
218
218
|
ac = ac.results[0]
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
else
|
|
222
|
-
lat = ac.geometry.location.lat
|
|
223
|
-
lon = ac.geometry.location.lng
|
|
224
|
-
end
|
|
225
|
-
|
|
226
|
-
localname = ac.formatted_address
|
|
219
|
+
lat = ac.geometry.location.lat
|
|
220
|
+
lon = ac.geometry.location.lng
|
|
227
221
|
|
|
228
222
|
data = JSON.parse(
|
|
229
223
|
open(
|
|
@@ -231,12 +225,7 @@ module Plugins
|
|
|
231
225
|
).read,
|
|
232
226
|
object_class: OpenStruct
|
|
233
227
|
)
|
|
234
|
-
|
|
235
228
|
data.ac = ac
|
|
236
|
-
data.lat = lat
|
|
237
|
-
data.lon = lon
|
|
238
|
-
|
|
239
|
-
|
|
240
229
|
current = data.currently
|
|
241
230
|
alerts = data.alerts.count rescue 0
|
|
242
231
|
c = Unitwise(current.temperature, '[degF]').convert_to('Cel').to_i
|
|
@@ -247,11 +236,11 @@ module Plugins
|
|
|
247
236
|
tempstring = "#{current.temperature.to_i} F (#{c} C)"
|
|
248
237
|
feelslike = "#{current.apparentTemperature.to_i} F (#{c_feels} C)"
|
|
249
238
|
|
|
250
|
-
data.reply = "DS ∴ #{
|
|
239
|
+
data.reply = "DS ∴ #{ac.formatted_address} " \
|
|
251
240
|
"≈ #{current.summary} #{tempstring} " \
|
|
252
241
|
"≈ Feels like #{feelslike} " \
|
|
253
242
|
"≈ Humidity: #{current.relative_humidity} " \
|
|
254
|
-
"≈ Pressure: #{p.convert_to('[psi]').to_f.round(2)}
|
|
243
|
+
"≈ Pressure: #{p.convert_to('[psi]').to_f.round(2)} in/Hg (#{current.pressure} mbar) " \
|
|
255
244
|
"≈ Wind: gusts upto #{current.windGust} mph (#{gusts} km/h) ≈ Alerts: #{alerts} ∴"
|
|
256
245
|
|
|
257
246
|
return data
|
|
@@ -260,62 +249,42 @@ module Plugins
|
|
|
260
249
|
end
|
|
261
250
|
|
|
262
251
|
# NOAA - https://graphical.weather.gov/xml/
|
|
263
|
-
def noaa_src(
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
252
|
+
def noaa_src(location)
|
|
253
|
+
ac = JSON.parse(
|
|
254
|
+
open(URI.encode("http://maps.googleapis.com/maps/api/geocode/json?address=#{location}")).read,
|
|
255
|
+
object_class: OpenStruct
|
|
256
|
+
)
|
|
257
|
+
return nil if ac.results.nil? ## Unable to locate
|
|
267
258
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
)
|
|
272
|
-
return nil if ac.results.nil? ## Unable to locate
|
|
273
|
-
|
|
274
|
-
info(ac.status)
|
|
275
|
-
if ac.status == "OVER_QUERY_LIMIT"
|
|
276
|
-
msg.reply("Google API - Over query Limit")
|
|
277
|
-
return nil
|
|
278
|
-
end
|
|
279
|
-
|
|
280
|
-
ac = ac.results[0]
|
|
281
|
-
lat = ac.geometry.location.lat
|
|
282
|
-
lon = ac.geometry.location.lng
|
|
283
|
-
localname = ac.formatted_address
|
|
284
|
-
end
|
|
259
|
+
ac = ac.results[0]
|
|
260
|
+
lat = ac.geometry.location.lat
|
|
261
|
+
lon = ac.geometry.location.lng
|
|
285
262
|
|
|
286
|
-
|
|
263
|
+
stations = JSON.parse(
|
|
287
264
|
open(URI.encode("https://api.weather.gov/points/#{lat},#{lon}/stations/")).read
|
|
288
265
|
) rescue nil
|
|
289
266
|
|
|
290
|
-
return nil if
|
|
291
|
-
|
|
292
|
-
station = JSON.parse(
|
|
293
|
-
open(URI.encode("#{station_list['observationStations'][0]}")).read,
|
|
294
|
-
object_class: OpenStruct
|
|
295
|
-
)
|
|
267
|
+
return nil if stations.nil? ## Unable to find station. probably not in the USA
|
|
296
268
|
|
|
297
269
|
parsed = JSON.parse(
|
|
298
|
-
open(URI.encode("#{
|
|
270
|
+
open(URI.encode("#{stations['observationStations'][0]}/observations/current")).read,
|
|
299
271
|
object_class: OpenStruct
|
|
300
272
|
)
|
|
301
273
|
|
|
302
|
-
localname = station.properties.name if localname.nil?
|
|
303
274
|
|
|
304
275
|
data = parsed.properties
|
|
305
276
|
data.ac = ac
|
|
306
|
-
data.lat = lat
|
|
307
|
-
data.lon = lon
|
|
308
277
|
f = data.temperature.value * 9/5
|
|
309
278
|
temp = "#{f.round(2)} F (#{data.temperature.value.to_i.round(2)} C) "
|
|
310
279
|
wind = "Gusts: #{data.windGust.value} avg: #{data.windSpeed.value.to_i.round(2)}"
|
|
311
280
|
feelslike = "#{data.windChill.value.to_i.round(2)} C"
|
|
312
281
|
pressure = Unitwise(data.barometricPressure.value.to_f+101325, 'Pa')
|
|
313
282
|
|
|
314
|
-
data.reply = "NOAA ∴ #{
|
|
283
|
+
data.reply = "NOAA ∴ #{ac.formatted_address} " \
|
|
315
284
|
"≈ #{data.textDescription} #{temp} " \
|
|
316
285
|
"≈ Feels like #{feelslike} " \
|
|
317
286
|
"≈ Humidity: #{data.relativeHumidity.value.round(2)} " \
|
|
318
|
-
"≈ Pressure: #{pressure.convert_to('[psi]').to_f.round(2)}
|
|
287
|
+
"≈ Pressure: #{pressure.convert_to('[psi]').to_f.round(2)} in/Hg (#{pressure.convert_to('kPa').to_f} mbar) " \
|
|
319
288
|
"≈ Wind: #{wind} ≈ Alerts: ∴"
|
|
320
289
|
return data
|
|
321
290
|
# rescue
|
data/lib/Zeta/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: zetabot
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Liothen
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2018-
|
|
11
|
+
date: 2018-10-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -571,8 +571,8 @@ files:
|
|
|
571
571
|
- README.md
|
|
572
572
|
- Rakefile
|
|
573
573
|
- Zeta.gemspec
|
|
574
|
-
- bin/
|
|
575
|
-
- bin/
|
|
574
|
+
- bin/zconsole
|
|
575
|
+
- bin/zeta_setup
|
|
576
576
|
- bin/zetabot
|
|
577
577
|
- lib/Zeta.rb
|
|
578
578
|
- lib/Zeta/access.rb
|
|
@@ -591,7 +591,6 @@ files:
|
|
|
591
591
|
- lib/Zeta/cache.rb
|
|
592
592
|
- lib/Zeta/cinch.rb
|
|
593
593
|
- lib/Zeta/config.rb
|
|
594
|
-
- lib/Zeta/gems.locked
|
|
595
594
|
- lib/Zeta/gems.rb
|
|
596
595
|
- lib/Zeta/locale.rb
|
|
597
596
|
- lib/Zeta/locale/en/8ball.yml
|
|
@@ -628,8 +627,6 @@ files:
|
|
|
628
627
|
- lib/Zeta/plugins/snooper.rb
|
|
629
628
|
- lib/Zeta/plugins/urban.rb
|
|
630
629
|
- lib/Zeta/plugins/weather.rb
|
|
631
|
-
- lib/Zeta/plugins/weather_almanac.rb
|
|
632
|
-
- lib/Zeta/plugins/weather_hurricane.rb
|
|
633
630
|
- lib/Zeta/plugins/whois.rb
|
|
634
631
|
- lib/Zeta/plugins/wiki.rb
|
|
635
632
|
- lib/Zeta/plugins/wolfram.rb
|
|
@@ -658,7 +655,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
658
655
|
version: '0'
|
|
659
656
|
requirements: []
|
|
660
657
|
rubyforge_project:
|
|
661
|
-
rubygems_version: 2.7.
|
|
658
|
+
rubygems_version: 2.7.6
|
|
662
659
|
signing_key:
|
|
663
660
|
specification_version: 4
|
|
664
661
|
summary: Zeta is a IRC bot written in ruby using the Cinch Framework
|
data/lib/Zeta/gems.locked
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
require 'ostruct'
|
|
3
|
-
require 'persist'
|
|
4
|
-
require 'open-uri'
|
|
5
|
-
require 'json'
|
|
6
|
-
require 'unitwise'
|
|
7
|
-
|
|
8
|
-
module Plugins
|
|
9
|
-
# Forecast is a Cinch plugin for getting the weather forecast.
|
|
10
|
-
# @original_author Jonah Ruiz <jonah@pixelhipsters.com>
|
|
11
|
-
# @author Liothen <liothen@flagrun.net>
|
|
12
|
-
class WeatherHurricane
|
|
13
|
-
include Cinch::Plugin
|
|
14
|
-
include Cinch::Helpers
|
|
15
|
-
enable_acl
|
|
16
|
-
|
|
17
|
-
set(
|
|
18
|
-
plugin_name: "Hurricane Info",
|
|
19
|
-
help: "Get the Weather?.\nUsage: `?hurricane`\n",
|
|
20
|
-
)
|
|
21
|
-
|
|
22
|
-
match /almanac (.+)/, method: :almanac
|
|
23
|
-
|
|
24
|
-
def almanac(msg, locale)
|
|
25
|
-
autocomplete = JSON.parse(open(URI.encode("http://autocomplete.wunderground.com/aq?query=#{locale}")).read)
|
|
26
|
-
url = URI.encode("http://api.wunderground.com/api/#{Config.secrets[:wunderground]}/almanac/#{autocomplete['RESULTS'][0]['l']}.json")
|
|
27
|
-
location = JSON.parse(
|
|
28
|
-
# RestClient.get(url)
|
|
29
|
-
open(url).read
|
|
30
|
-
)
|
|
31
|
-
return msg.reply "No results found for #{query}." if location.nil?
|
|
32
|
-
|
|
33
|
-
time = Time.now()
|
|
34
|
-
|
|
35
|
-
data = OpenStruct.new(
|
|
36
|
-
date: time.strftime('%B, %d %Y (%A) '),
|
|
37
|
-
airport: location['almanac']['airport_code'],
|
|
38
|
-
high_norm_f: location['almanac']['temp_high']['normal']['F'],
|
|
39
|
-
high_norm_c: location['almanac']['temp_high']['normal']['C'],
|
|
40
|
-
high_record_y: location['almanac']['temp_high']['recordyear'],
|
|
41
|
-
high_record_f: location['almanac']['temp_high']['record']['F'],
|
|
42
|
-
high_record_c: location['almanac']['temp_high']['normal']['C'],
|
|
43
|
-
low_norm_f: location['almanac']['temp_low']['normal']['F'],
|
|
44
|
-
low_norm_c: location['almanac']['temp_low']['normal']['C'],
|
|
45
|
-
low_record_y: location['almanac']['temp_low']['recordyear'],
|
|
46
|
-
low_record_f: location['almanac']['temp_low']['record']['F'],
|
|
47
|
-
low_record_c: location['almanac']['temp_low']['normal']['C'],
|
|
48
|
-
)
|
|
49
|
-
|
|
50
|
-
reply_msg = "∴ Almanac #{data.date} ≈ Airport #{data.airport} " \
|
|
51
|
-
"≈ Normal #{data.high_norm_f} F (#{data.high_norm_c} C) | #{data.low_norm_f} F (#{data.low_norm_c} C) " \
|
|
52
|
-
"≈ High #{data.high_record_f} F (#{data.high_record_c} C) [#{data.high_record_y}] " \
|
|
53
|
-
"≈ Low #{data.low_record_f} F (#{data.low_record_c} C) [#{data.low_record_y}] ∴"
|
|
54
|
-
|
|
55
|
-
msg.reply(reply_msg)
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
Bot.config.plugins.plugins.push Plugins::WeatherAlmanac
|
|
61
|
-
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
require 'ostruct'
|
|
2
|
-
require 'persist'
|
|
3
|
-
require 'open-uri'
|
|
4
|
-
require 'json'
|
|
5
|
-
require 'unitwise'
|
|
6
|
-
|
|
7
|
-
module Plugins
|
|
8
|
-
# Forecast is a Cinch plugin for getting the weather forecast.
|
|
9
|
-
# @original_author Jonah Ruiz <jonah@pixelhipsters.com>
|
|
10
|
-
# @author Liothen <liothen@flagrun.net>
|
|
11
|
-
class WeatherHurricane
|
|
12
|
-
include Cinch::Plugin
|
|
13
|
-
include Cinch::Helpers
|
|
14
|
-
enable_acl
|
|
15
|
-
|
|
16
|
-
set(
|
|
17
|
-
plugin_name: "Hurricane Info",
|
|
18
|
-
help: "Get the Weather?.\nUsage: `?hurricane`\n",
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
match /hurricane/, method: :hurricane
|
|
22
|
-
|
|
23
|
-
def hurricane(msg)
|
|
24
|
-
url = URI.encode "http://api.wunderground.com/api/#{Zsec.wunderground}/currenthurricane/view.json"
|
|
25
|
-
location = JSON.parse(
|
|
26
|
-
# RestClient.get(url)
|
|
27
|
-
open(url).read
|
|
28
|
-
)
|
|
29
|
-
return msg.reply "No results found for #{query}." if location.nil?
|
|
30
|
-
reply_msg = "∴ #{location['currenthurricane'][0]['stormInfo']['stormName_Nice']} " \
|
|
31
|
-
"(#{location['currenthurricane'][0]['stormInfo']['stormNumber']}) "\
|
|
32
|
-
"≈ Category #{location['currenthurricane'][0]['Current']['SaffirSimpsonCategory']} " \
|
|
33
|
-
"≈ Wind #{location['currenthurricane'][0]['Current']['WindSpeed']['Mph']} mph " \
|
|
34
|
-
"(#{location['currenthurricane'][0]['Current']['WindSpeed']['Kph']} kph) " \
|
|
35
|
-
"≈ Wind Gust #{location['currenthurricane'][0]['Current']['WindGust']['Mph']} mph " \
|
|
36
|
-
"(#{location['currenthurricane'][0]['Current']['WindGust']['Kph']} kph) " \
|
|
37
|
-
"≈ #{location['currenthurricane'][0]['Current']['Time']['pretty']} ∴"
|
|
38
|
-
msg.reply(reply_msg)
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
Bot.config.plugins.plugins.push Plugins::WeatherHurricane
|