kovid 0.6.1 → 0.6.6
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/.rubocop.yml +4 -0
- data/.rubocop_todo.yml +59 -0
- data/Gemfile.lock +1 -1
- data/README.md +1 -1
- data/Rakefile +1 -0
- data/kovid.gemspec +9 -4
- data/lib/kovid/aggregators.rb +29 -0
- data/lib/kovid/cache.rb +3 -0
- data/lib/kovid/cli.rb +35 -33
- data/lib/kovid/constants.rb +112 -0
- data/lib/kovid/helpers.rb +16 -0
- data/lib/kovid/historians.rb +110 -0
- data/lib/kovid/painter.rb +5 -0
- data/lib/kovid/request.rb +62 -25
- data/lib/kovid/tablelize.rb +123 -339
- data/lib/kovid/uri_builder.rb +1 -0
- data/lib/kovid/version.rb +1 -1
- metadata +7 -2
data/lib/kovid/painter.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'rainbow'
|
4
4
|
|
5
|
+
# Adds text color functionalities to String class
|
5
6
|
class String
|
6
7
|
def paint_white
|
7
8
|
Rainbow(self).white.bg(:black).bold
|
@@ -18,4 +19,8 @@ class String
|
|
18
19
|
def paint_yellow
|
19
20
|
Rainbow(self).yellow.bg(:black).bold
|
20
21
|
end
|
22
|
+
|
23
|
+
def paint_highlight
|
24
|
+
Rainbow(self).underline
|
25
|
+
end
|
21
26
|
end
|
data/lib/kovid/request.rb
CHANGED
@@ -6,6 +6,7 @@ require_relative 'cache'
|
|
6
6
|
require_relative 'uri_builder'
|
7
7
|
|
8
8
|
module Kovid
|
9
|
+
# Makes requests to external source to collect cases data
|
9
10
|
class Request
|
10
11
|
COUNTRIES_PATH = UriBuilder.new('/countries').url
|
11
12
|
STATES_URL = UriBuilder.new('/states').url
|
@@ -15,16 +16,18 @@ module Kovid
|
|
15
16
|
|
16
17
|
EU_ISOS = %w[AT BE BG CY CZ DE DK EE ES FI FR GR HR HU IE IT LT \
|
17
18
|
LU LV MT NL PL PT RO SE SI SK].freeze
|
18
|
-
EUROPE_ISOS = EU_ISOS + %w[GB IS NO CH MC AD SM VA BA RS ME MK AL\
|
19
|
-
BY UA RU MD]
|
19
|
+
EUROPE_ISOS = EU_ISOS + %w[GB IS NO CH MC AD SM VA BA RS ME MK AL \
|
20
|
+
BY UA RU MD].freeze
|
20
21
|
AFRICA_ISOS = %w[DZ AO BJ BW BF BI CM CV CF TD KM CD CG CI DJ EG \
|
21
|
-
GQ ER SZ ET GA GM GH GN GW KE LS LR LY MG MW ML
|
22
|
-
NG RW ST SN SC SL SO ZA SS SD
|
23
|
-
|
24
|
-
|
22
|
+
GQ ER SZ ET GA GM GH GN GW KE LS LR LY MG MW ML \
|
23
|
+
MR MU MA MZ NA NE NG RW ST SN SC SL SO ZA SS SD \
|
24
|
+
TZ TG TN UG ZM ZW EH].freeze
|
25
|
+
SOUTH_AMERICA_ISOS = %w[AR BO BV BR CL CO EC FK GF GY PY PE GS SR \
|
26
|
+
UY VE].freeze
|
25
27
|
ASIA_ISOS = %w[AE AF AM AZ BD BH BN BT CC CN CX GE HK ID IL IN \
|
26
|
-
IQ IR JO JP KG KH KP KR KW KZ LA LB LK MM MN MO
|
27
|
-
PS QA SA SG SY TH TJ TL TM TR TW
|
28
|
+
IQ IR JO JP KG KH KP KR KW KZ LA LB LK MM MN MO \
|
29
|
+
MY NP OM PH PK PS QA SA SG SY TH TJ TL TM TR TW \
|
30
|
+
UZ VN YE].freeze
|
28
31
|
|
29
32
|
class << self
|
30
33
|
def eu_aggregate
|
@@ -70,7 +73,7 @@ module Kovid
|
|
70
73
|
def by_country(country_name)
|
71
74
|
response = fetch_country(country_name)
|
72
75
|
|
73
|
-
if response.
|
76
|
+
if response.key?('message')
|
74
77
|
not_found(country_name)
|
75
78
|
else
|
76
79
|
Kovid::Tablelize.country_table(response)
|
@@ -82,7 +85,7 @@ module Kovid
|
|
82
85
|
def by_country_full(country_name)
|
83
86
|
response = fetch_country(country_name)
|
84
87
|
|
85
|
-
if response.
|
88
|
+
if response.key?('message')
|
86
89
|
not_found(country_name)
|
87
90
|
else
|
88
91
|
Kovid::Tablelize.full_country_table(response)
|
@@ -147,7 +150,9 @@ module Kovid
|
|
147
150
|
end
|
148
151
|
|
149
152
|
def cases
|
150
|
-
response = JSON.parse(
|
153
|
+
response = JSON.parse(
|
154
|
+
Typhoeus.get(UriBuilder.new('/all').url, cache_ttl: 900).response_body
|
155
|
+
)
|
151
156
|
|
152
157
|
Kovid::Tablelize.cases(response)
|
153
158
|
rescue JSON::ParserError
|
@@ -156,7 +161,11 @@ module Kovid
|
|
156
161
|
|
157
162
|
def history(country, last)
|
158
163
|
history_path = UriBuilder.new('/v2/historical').url
|
159
|
-
response = JSON.parse(
|
164
|
+
response = JSON.parse(
|
165
|
+
Typhoeus.get(
|
166
|
+
history_path + "/#{country}", cache_ttl: 900
|
167
|
+
).response_body
|
168
|
+
)
|
160
169
|
|
161
170
|
Kovid::Tablelize.history(response, last)
|
162
171
|
rescue JSON::ParserError
|
@@ -165,7 +174,11 @@ module Kovid
|
|
165
174
|
|
166
175
|
def histogram(country, date)
|
167
176
|
history_path = UriBuilder.new('/v2/historical').url
|
168
|
-
response = JSON.parse(
|
177
|
+
response = JSON.parse(
|
178
|
+
Typhoeus.get(
|
179
|
+
history_path + "/#{country}", cache_ttl: 900
|
180
|
+
).response_body
|
181
|
+
)
|
169
182
|
|
170
183
|
Kovid::Tablelize.histogram(response, date)
|
171
184
|
end
|
@@ -183,14 +196,20 @@ module Kovid
|
|
183
196
|
|
184
197
|
def fetch_countries(list)
|
185
198
|
list.map do |country|
|
186
|
-
JSON.parse(
|
199
|
+
JSON.parse(
|
200
|
+
Typhoeus.get(
|
201
|
+
COUNTRIES_PATH + "/#{country}", cache_ttl: 900
|
202
|
+
).response_body
|
203
|
+
)
|
187
204
|
end.sort_by { |json| -json['cases'] }
|
188
205
|
end
|
189
206
|
|
190
207
|
def fetch_compared_states(submitted_states)
|
191
208
|
state_data = fetch_state_data
|
192
209
|
|
193
|
-
state_data.select
|
210
|
+
state_data.select do |state|
|
211
|
+
submitted_states.include?(state['state'].downcase)
|
212
|
+
end
|
194
213
|
end
|
195
214
|
|
196
215
|
def fetch_state_data
|
@@ -198,6 +217,10 @@ module Kovid
|
|
198
217
|
end
|
199
218
|
|
200
219
|
def fetch_country(country_name)
|
220
|
+
# TODO: Match ISOs to full country names
|
221
|
+
if country_name == "netherlands"
|
222
|
+
country_name = "nl"
|
223
|
+
end
|
201
224
|
country_url = COUNTRIES_PATH + "/#{country_name}"
|
202
225
|
|
203
226
|
JSON.parse(Typhoeus.get(country_url, cache_ttl: 900).response_body)
|
@@ -209,7 +232,9 @@ module Kovid
|
|
209
232
|
|
210
233
|
def fetch_province(province)
|
211
234
|
response = fetch_jhucsse
|
212
|
-
response.select
|
235
|
+
response.select do |datum|
|
236
|
+
datum['province'] == capitalize_words(province)
|
237
|
+
end.first
|
213
238
|
end
|
214
239
|
|
215
240
|
def fetch_provinces(provinces)
|
@@ -219,19 +244,35 @@ module Kovid
|
|
219
244
|
end
|
220
245
|
|
221
246
|
def fetch_state(state)
|
222
|
-
states_array = JSON.parse(
|
247
|
+
states_array = JSON.parse(
|
248
|
+
Typhoeus.get(STATES_URL, cache_ttl: 900).response_body
|
249
|
+
)
|
223
250
|
|
224
|
-
states_array.select
|
251
|
+
states_array.select do |state_name|
|
252
|
+
state_name['state'] == capitalize_words(state)
|
253
|
+
end.first
|
225
254
|
end
|
226
255
|
|
227
256
|
def aggregator(isos, meth)
|
228
|
-
countries_array = JSON.parse(
|
229
|
-
|
257
|
+
countries_array = JSON.parse(countries_request)
|
230
258
|
country_array = countries_array.select do |hash|
|
231
259
|
isos.include?(hash['countryInfo']['iso2'])
|
232
260
|
end
|
261
|
+
data = countries_aggregator(country_array)
|
262
|
+
|
263
|
+
meth === data
|
264
|
+
rescue JSON::ParserError
|
265
|
+
puts SERVER_DOWN
|
266
|
+
end
|
267
|
+
|
268
|
+
def countries_request
|
269
|
+
Typhoeus.get(
|
270
|
+
UriBuilder.new('/countries').url, cache_ttl: 900
|
271
|
+
).response_body
|
272
|
+
end
|
233
273
|
|
234
|
-
|
274
|
+
def countries_aggregator(country_array)
|
275
|
+
country_array.inject do |base, other|
|
235
276
|
base.merge(other) do |key, left, right|
|
236
277
|
left ||= 0
|
237
278
|
right ||= 0
|
@@ -239,10 +280,6 @@ module Kovid
|
|
239
280
|
left + right unless %w[country countryInfo].include?(key)
|
240
281
|
end
|
241
282
|
end.compact
|
242
|
-
|
243
|
-
meth === data
|
244
|
-
rescue JSON::ParserError
|
245
|
-
puts SERVER_DOWN
|
246
283
|
end
|
247
284
|
end
|
248
285
|
end
|
data/lib/kovid/tablelize.rb
CHANGED
@@ -4,206 +4,63 @@ require 'terminal-table'
|
|
4
4
|
require 'date'
|
5
5
|
require 'ascii_charts'
|
6
6
|
require_relative 'painter'
|
7
|
+
require_relative 'constants'
|
8
|
+
require_relative 'aggregators'
|
9
|
+
require_relative 'historians'
|
7
10
|
|
8
11
|
module Kovid
|
12
|
+
# Constructs the tables according to specified input
|
9
13
|
class Tablelize
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
'Deaths'.paint_red,
|
14
|
-
'Recovered'.paint_green
|
15
|
-
].freeze
|
16
|
-
|
17
|
-
CASES_DEATHS_RECOVERED_CTODAY_DTODAY = [
|
18
|
-
'Cases'.paint_white,
|
19
|
-
'Cases Today'.paint_white,
|
20
|
-
'Deaths'.paint_red,
|
21
|
-
'Deaths Today'.paint_red,
|
22
|
-
'Recovered'.paint_green
|
23
|
-
].freeze
|
24
|
-
|
25
|
-
DATE_CASES_DEATHS_RECOVERED = [
|
26
|
-
'Date'.paint_white,
|
27
|
-
'Cases'.paint_white,
|
28
|
-
'Deaths'.paint_red,
|
29
|
-
'Recovered'.paint_green
|
30
|
-
].freeze
|
31
|
-
|
32
|
-
CONTINENTAL_AGGREGATE_HEADINGS = [
|
33
|
-
'Cases'.paint_white,
|
34
|
-
'Cases Today'.paint_white,
|
35
|
-
'Deaths'.paint_red,
|
36
|
-
'Deaths Today'.paint_red,
|
37
|
-
'Recovered'.paint_green,
|
38
|
-
'Active'.paint_yellow,
|
39
|
-
'Critical'.paint_red
|
40
|
-
].freeze
|
41
|
-
|
42
|
-
COMPARE_COUNTRY_TABLE_FULL = [
|
43
|
-
'Country'.paint_white,
|
44
|
-
'Cases'.paint_white,
|
45
|
-
'Deaths'.paint_red,
|
46
|
-
'Recovered'.paint_green,
|
47
|
-
'Cases Today'.paint_white,
|
48
|
-
'Deaths Today'.paint_red,
|
49
|
-
'Critical'.paint_yellow,
|
50
|
-
'Cases/Million'.paint_white
|
51
|
-
].freeze
|
52
|
-
|
53
|
-
COMPARE_COUNTRIES_TABLE_HEADINGS = [
|
54
|
-
'Country'.paint_white,
|
55
|
-
'Cases'.paint_white,
|
56
|
-
'Cases Today'.paint_white,
|
57
|
-
'Deaths'.paint_red,
|
58
|
-
'Deaths Today'.paint_red,
|
59
|
-
'Recovered'.paint_green
|
60
|
-
].freeze
|
61
|
-
|
62
|
-
FULL_COUNTRY_TABLE_HEADINGS = [
|
63
|
-
'Cases'.paint_white,
|
64
|
-
'Deaths'.paint_red,
|
65
|
-
'Recovered'.paint_green,
|
66
|
-
'Cases Today'.paint_white,
|
67
|
-
'Deaths Today'.paint_red,
|
68
|
-
'Critical'.paint_yellow,
|
69
|
-
'Cases/Million'.paint_white
|
70
|
-
].freeze
|
71
|
-
|
72
|
-
COMPARE_STATES_HEADINGS = [
|
73
|
-
'State'.paint_white,
|
74
|
-
'Cases'.paint_white,
|
75
|
-
'Cases Today'.paint_white,
|
76
|
-
'Deaths'.paint_red,
|
77
|
-
'Deaths Today'.paint_red,
|
78
|
-
'Active'.paint_yellow
|
79
|
-
].freeze
|
80
|
-
|
81
|
-
COMPARE_PROVINCES_HEADINGS = [
|
82
|
-
'Province'.paint_white,
|
83
|
-
'Confirmed'.paint_white,
|
84
|
-
'Deaths'.paint_red,
|
85
|
-
'Recovered'.paint_green
|
86
|
-
].freeze
|
87
|
-
|
88
|
-
FOOTER_LINE = ['------------', '------------', '------------', '------------'].freeze
|
89
|
-
COUNTRY_LETTERS = 'A'.upto('Z').with_index(127_462).to_h.freeze
|
90
|
-
|
91
|
-
RIGHT_ALIGN_COLUMNS = {
|
92
|
-
compare_country_table_full: [1, 2, 3, 4, 5, 6, 7],
|
93
|
-
compare_country_table: [1, 2, 3, 4, 5],
|
94
|
-
compare_us_states: [1, 2, 3, 4, 5],
|
95
|
-
compare_provinces: [1, 2, 3]
|
96
|
-
}.freeze
|
14
|
+
extend Kovid::Constants
|
15
|
+
extend Kovid::Aggregators
|
16
|
+
extend Kovid::Historians
|
97
17
|
|
18
|
+
class << self
|
98
19
|
def country_table(data)
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
check_if_positve(data['todayCases']),
|
103
|
-
comma_delimit(data['deaths']),
|
104
|
-
check_if_positve(data['todayDeaths']),
|
105
|
-
comma_delimit(data['recovered'])
|
106
|
-
]
|
107
|
-
]
|
108
|
-
|
109
|
-
if (iso = data['countryInfo']['iso2'])
|
110
|
-
Terminal::Table.new(title: "#{country_emoji(iso)} #{data['country'].upcase}",
|
111
|
-
headings: CASES_DEATHS_RECOVERED_CTODAY_DTODAY,
|
112
|
-
rows: rows)
|
113
|
-
else
|
114
|
-
Terminal::Table.new(title: data['country'].upcase,
|
115
|
-
headings: CASES_DEATHS_RECOVERED_CTODAY_DTODAY,
|
116
|
-
rows: rows)
|
117
|
-
end
|
20
|
+
Terminal::Table.new(title: country_title(data),
|
21
|
+
headings: CASES_DEATHS_RECOVERED_CTODAY_DTODAY,
|
22
|
+
rows: [country_row(data)])
|
118
23
|
end
|
119
24
|
|
120
25
|
def full_country_table(data)
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
comma_delimit(data['deaths']),
|
125
|
-
comma_delimit(data['recovered']),
|
126
|
-
check_if_positve(data['todayCases']),
|
127
|
-
check_if_positve(data['todayDeaths']),
|
128
|
-
comma_delimit(data['critical']),
|
129
|
-
comma_delimit(data['casesPerOneMillion'])
|
130
|
-
]
|
131
|
-
|
132
|
-
if iso = data['countryInfo']['iso2']
|
133
|
-
Terminal::Table.new(title: "#{country_emoji(iso)} #{data['country'].upcase}",
|
134
|
-
headings: FULL_COUNTRY_TABLE_HEADINGS,
|
135
|
-
rows: rows)
|
136
|
-
else
|
137
|
-
Terminal::Table.new(title: data['country'].upcase,
|
138
|
-
headings: FULL_COUNTRY_TABLE_HEADINGS,
|
139
|
-
rows: rows)
|
140
|
-
end
|
26
|
+
Terminal::Table.new(title: country_title(data),
|
27
|
+
headings: FULL_COUNTRY_TABLE_HEADINGS,
|
28
|
+
rows: [full_country_row(data)])
|
141
29
|
end
|
142
30
|
|
143
31
|
def full_province_table(province)
|
144
|
-
|
145
|
-
'
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
rows = []
|
150
|
-
rows << [province['stats']['confirmed'], province['stats']['deaths'], province['stats']['recovered']]
|
151
|
-
|
152
|
-
Terminal::Table.new(title: province['province'].upcase, headings: headings, rows: rows)
|
32
|
+
Terminal::Table.new(
|
33
|
+
title: province['province'].upcase,
|
34
|
+
headings: FULL_PROVINCE_TABLE_HEADINGS,
|
35
|
+
rows: [province_row(province)]
|
36
|
+
)
|
153
37
|
end
|
154
38
|
|
155
39
|
def full_state_table(state)
|
156
|
-
|
157
|
-
'
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
'Active'.paint_yellow
|
162
|
-
]
|
163
|
-
|
164
|
-
rows = []
|
165
|
-
rows << [state['cases'], check_if_positve(state['todayCases']), state['deaths'], check_if_positve(state['todayDeaths']), state['active']]
|
166
|
-
|
167
|
-
Terminal::Table.new(title: state['state'].upcase, headings: headings, rows: rows)
|
40
|
+
Terminal::Table.new(
|
41
|
+
title: state['state'].upcase,
|
42
|
+
headings: FULL_STATE_TABLE_HEADINGS,
|
43
|
+
rows: [country_row(state)]
|
44
|
+
)
|
168
45
|
end
|
169
46
|
|
170
47
|
def compare_countries_table(data)
|
171
48
|
rows = []
|
172
49
|
|
173
50
|
data.each do |country|
|
174
|
-
base_rows =
|
175
|
-
|
176
|
-
check_if_positve(country['todayCases']),
|
177
|
-
comma_delimit(country['deaths']),
|
178
|
-
check_if_positve(country['todayDeaths']),
|
179
|
-
comma_delimit(country['recovered'])
|
180
|
-
]
|
181
|
-
|
182
|
-
rows << if (iso = country['countryInfo']['iso2'])
|
183
|
-
base_rows.unshift("#{country_emoji(iso)} #{country['country'].upcase}")
|
184
|
-
else
|
185
|
-
base_rows.unshift(country['country'].upcase.to_s)
|
186
|
-
end
|
51
|
+
base_rows = country_row(country)
|
52
|
+
rows << base_rows.unshift(country_title(country))
|
187
53
|
end
|
188
54
|
|
189
55
|
align_columns(:compare_country_table,
|
190
|
-
Terminal::Table.new(
|
191
|
-
|
56
|
+
Terminal::Table.new(
|
57
|
+
headings: COMPARE_COUNTRIES_TABLE_HEADINGS,
|
58
|
+
rows: rows
|
59
|
+
))
|
192
60
|
end
|
193
61
|
|
194
62
|
def compare_countries_table_full(data)
|
195
|
-
rows = data.map
|
196
|
-
[
|
197
|
-
country.fetch('country'),
|
198
|
-
comma_delimit(country.fetch('cases')),
|
199
|
-
comma_delimit(country.fetch('deaths')),
|
200
|
-
comma_delimit(country.fetch('recovered')),
|
201
|
-
check_if_positve(country.fetch('todayCases')),
|
202
|
-
check_if_positve(country.fetch('todayDeaths')),
|
203
|
-
comma_delimit(country.fetch('critical')),
|
204
|
-
comma_delimit(country.fetch('casesPerOneMillion'))
|
205
|
-
]
|
206
|
-
end
|
63
|
+
rows = data.map { |country| compare_countries_full_row(country) }
|
207
64
|
|
208
65
|
align_columns(:compare_country_table_full,
|
209
66
|
Terminal::Table.new(headings: COMPARE_COUNTRY_TABLE_FULL,
|
@@ -211,15 +68,12 @@ module Kovid
|
|
211
68
|
end
|
212
69
|
|
213
70
|
def compare_us_states(data)
|
214
|
-
rows = data.map do |state|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
check_if_positve(state['todayDeaths']),
|
221
|
-
comma_delimit(state.fetch('active'))
|
222
|
-
]
|
71
|
+
rows = data.map.with_index do |state, index|
|
72
|
+
if index.odd?
|
73
|
+
us_state_row(state)
|
74
|
+
else
|
75
|
+
us_state_row(state).map(&:paint_highlight)
|
76
|
+
end
|
223
77
|
end
|
224
78
|
|
225
79
|
align_columns(:compare_us_states,
|
@@ -228,14 +82,7 @@ module Kovid
|
|
228
82
|
end
|
229
83
|
|
230
84
|
def compare_provinces(data)
|
231
|
-
rows = data.map
|
232
|
-
[
|
233
|
-
province['province'].upcase,
|
234
|
-
province['stats']['confirmed'],
|
235
|
-
province['stats']['deaths'],
|
236
|
-
province['stats']['recovered']
|
237
|
-
]
|
238
|
-
end
|
85
|
+
rows = data.map { |province| compare_provinces_row(province) }
|
239
86
|
|
240
87
|
align_columns(:compare_provinces,
|
241
88
|
Terminal::Table.new(headings: COMPARE_PROVINCES_HEADINGS,
|
@@ -243,160 +90,103 @@ module Kovid
|
|
243
90
|
end
|
244
91
|
|
245
92
|
def cases(cases)
|
246
|
-
headings = CASES_DEATHS_RECOVERED
|
247
|
-
rows = [
|
248
|
-
[
|
249
|
-
comma_delimit(cases['cases']),
|
250
|
-
comma_delimit(cases['deaths']),
|
251
|
-
comma_delimit(cases['recovered'])
|
252
|
-
]
|
253
|
-
]
|
254
|
-
|
255
|
-
Terminal::Table.new(title: '🌍 Total Number of Incidents Worldwide'.upcase, headings: headings, rows: rows)
|
256
|
-
end
|
257
|
-
|
258
|
-
def history(country, last)
|
259
|
-
# Write checks for when country is spelt wrong.
|
260
|
-
headings = DATE_CASES_DEATHS_RECOVERED
|
261
|
-
rows = []
|
262
|
-
|
263
|
-
stats = if last
|
264
|
-
transpose(country).last(last.to_i)
|
265
|
-
else
|
266
|
-
transpose(country)
|
267
|
-
end
|
268
|
-
|
269
|
-
dates = if last
|
270
|
-
country['timeline']['cases'].keys.last(last.to_i)
|
271
|
-
else
|
272
|
-
country['timeline']['cases'].keys
|
273
|
-
end
|
274
|
-
|
275
|
-
unless last
|
276
|
-
stats = stats.reject { |stat| stat[0].to_i.zero? && stat[1].to_i.zero? }
|
277
|
-
dates = dates.last(stats.count)
|
278
|
-
end
|
279
|
-
|
280
|
-
stats.each_with_index do |val, index|
|
281
|
-
val.unshift(Kovid.dateman(dates[index]))
|
282
|
-
end.each do |row|
|
283
|
-
rows << row
|
284
|
-
end
|
285
|
-
|
286
|
-
if stats.size > 10
|
287
|
-
rows << FOOTER_LINE
|
288
|
-
rows << DATE_CASES_DEATHS_RECOVERED
|
289
|
-
end
|
290
|
-
|
291
93
|
Terminal::Table.new(
|
292
|
-
title:
|
293
|
-
headings:
|
294
|
-
rows:
|
94
|
+
title: '🌍 Total Number of Incidents Worldwide'.upcase,
|
95
|
+
headings: CASES_DEATHS_RECOVERED,
|
96
|
+
rows: [cases_row(cases)]
|
295
97
|
)
|
296
98
|
end
|
297
99
|
|
298
|
-
|
299
|
-
@date = date_string.split('.')
|
300
|
-
|
301
|
-
if @date.last.to_i != 20
|
302
|
-
Kovid.info_table('Only 2020 histgrams are available.')
|
303
|
-
return
|
304
|
-
end
|
305
|
-
|
306
|
-
# From dates where number of !cases.zero?
|
307
|
-
positive_cases_figures = country['timeline']['cases'].values.reject(&:zero?)
|
308
|
-
dates = country['timeline']['cases'].reject { |_k, v| v.zero? }.keys
|
309
|
-
data = []
|
310
|
-
|
311
|
-
# Improve this later, like everything else.
|
312
|
-
# Returns array of days.to_i from the date param
|
313
|
-
dates = dates.map do |date|
|
314
|
-
date.split('/')
|
315
|
-
end.select do |date|
|
316
|
-
date.last == @date.last
|
317
|
-
end.select do |date|
|
318
|
-
date.first == @date.first
|
319
|
-
end.map do |array|
|
320
|
-
array[1]
|
321
|
-
end.map(&:to_i).last(positive_cases_figures.count)
|
322
|
-
|
323
|
-
# Arranges dates and figures in [x,y] for histogram
|
324
|
-
# With x being day, y being number of cases
|
325
|
-
if dates.empty?
|
326
|
-
if @date.first.to_i > Time.now.month
|
327
|
-
msgs = [
|
328
|
-
'Seriously...??! 😏', 'Did you just check the future??',
|
329
|
-
'You just checked the future Morgan.',
|
330
|
-
'Knowing too much of your future is never a good thing.'
|
331
|
-
]
|
332
|
-
|
333
|
-
Kovid.info_table(msgs.sample)
|
334
|
-
else
|
335
|
-
Kovid.info_table('Check your spelling/No infections for this month.')
|
336
|
-
end
|
100
|
+
private
|
337
101
|
|
102
|
+
def country_title(data)
|
103
|
+
iso = data['countryInfo']['iso2']
|
104
|
+
if iso.nil?
|
105
|
+
data['country'].upcase
|
338
106
|
else
|
339
|
-
|
340
|
-
data << [val, positive_cases_figures[index]]
|
341
|
-
end
|
342
|
-
y_range = AsciiCharts::Cartesian.new(data, bar: true, hide_zero: true).y_range
|
343
|
-
|
344
|
-
last_two_y = y_range.last 2
|
345
|
-
y_interval = last_two_y.last - last_two_y.first
|
346
|
-
|
347
|
-
scale("Scale on Y: #{y_interval}:#{(y_interval / last_two_y.last.to_f * positive_cases_figures.last).round(2) / y_interval}")
|
348
|
-
|
349
|
-
puts 'Experimental feature, please report issues.'
|
350
|
-
|
351
|
-
AsciiCharts::Cartesian.new(data, bar: true, hide_zero: true).draw
|
107
|
+
"#{country_emoji(iso)} #{data['country'].upcase}"
|
352
108
|
end
|
353
109
|
end
|
354
110
|
|
355
|
-
def
|
356
|
-
|
111
|
+
def country_emoji(iso)
|
112
|
+
COUNTRY_LETTERS.values_at(*iso.chars).pack('U*') + \
|
113
|
+
8203.chr(Encoding::UTF_8)
|
357
114
|
end
|
358
115
|
|
359
|
-
def
|
360
|
-
|
116
|
+
def cases_row(data)
|
117
|
+
[
|
118
|
+
Kovid.comma_delimit(data['cases']),
|
119
|
+
Kovid.comma_delimit(data['deaths']),
|
120
|
+
Kovid.comma_delimit(data['recovered'])
|
121
|
+
]
|
361
122
|
end
|
362
123
|
|
363
|
-
|
364
|
-
|
365
|
-
|
124
|
+
# Also works for state
|
125
|
+
def country_row(data)
|
126
|
+
[
|
127
|
+
Kovid.comma_delimit(data['cases']),
|
128
|
+
Kovid.add_plus_sign(data['todayCases']),
|
129
|
+
Kovid.comma_delimit(data['deaths']),
|
130
|
+
Kovid.add_plus_sign(data['todayDeaths']),
|
131
|
+
Kovid.comma_delimit(data['recovered'])
|
132
|
+
]
|
366
133
|
end
|
367
134
|
|
368
|
-
def
|
369
|
-
|
370
|
-
|
371
|
-
|
135
|
+
def full_country_row(data)
|
136
|
+
[
|
137
|
+
Kovid.comma_delimit(data['cases']),
|
138
|
+
Kovid.comma_delimit(data['deaths']),
|
139
|
+
Kovid.comma_delimit(data['recovered']),
|
140
|
+
Kovid.add_plus_sign(data['todayCases']),
|
141
|
+
Kovid.add_plus_sign(data['todayDeaths']),
|
142
|
+
Kovid.comma_delimit(data['critical']),
|
143
|
+
Kovid.comma_delimit(data['casesPerOneMillion'])
|
144
|
+
]
|
372
145
|
end
|
373
146
|
|
374
|
-
def
|
375
|
-
|
147
|
+
def province_row(data)
|
148
|
+
[
|
149
|
+
data['stats']['confirmed'],
|
150
|
+
data['stats']['deaths'],
|
151
|
+
data['stats']['recovered']
|
152
|
+
]
|
376
153
|
end
|
377
154
|
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
.join(',')
|
384
|
-
.reverse
|
155
|
+
def compare_provinces_row(data)
|
156
|
+
[
|
157
|
+
data['province'].upcase,
|
158
|
+
province_row(data)
|
159
|
+
].flatten
|
385
160
|
end
|
386
161
|
|
387
|
-
def
|
388
|
-
|
162
|
+
def compare_countries_full_row(data)
|
163
|
+
[
|
164
|
+
data.fetch('country'),
|
165
|
+
full_country_row(data)
|
166
|
+
].flatten
|
389
167
|
end
|
390
168
|
|
391
|
-
def
|
392
|
-
|
393
|
-
|
169
|
+
def us_state_row(data)
|
170
|
+
[
|
171
|
+
data.fetch('state').upcase,
|
172
|
+
Kovid.comma_delimit(data.fetch('cases')),
|
173
|
+
Kovid.add_plus_sign(data['todayCases']),
|
174
|
+
Kovid.comma_delimit(data['deaths']),
|
175
|
+
Kovid.add_plus_sign(data['todayDeaths']),
|
176
|
+
Kovid.comma_delimit(data.fetch('active'))
|
177
|
+
]
|
394
178
|
end
|
395
179
|
|
396
|
-
def
|
397
|
-
|
398
|
-
|
399
|
-
|
180
|
+
def aggregated_row(data)
|
181
|
+
[
|
182
|
+
Kovid.comma_delimit(data['cases']),
|
183
|
+
Kovid.add_plus_sign(data['todayCases']),
|
184
|
+
Kovid.comma_delimit(data['deaths']),
|
185
|
+
Kovid.add_plus_sign(data['todayDeaths']),
|
186
|
+
Kovid.comma_delimit(data['recovered']),
|
187
|
+
Kovid.comma_delimit(data['active']),
|
188
|
+
Kovid.comma_delimit(data['critical'])
|
189
|
+
]
|
400
190
|
end
|
401
191
|
|
402
192
|
def scale(msg)
|
@@ -405,32 +195,26 @@ module Kovid
|
|
405
195
|
end
|
406
196
|
|
407
197
|
def aggregated_table(collated_data, continent, iso, emoji)
|
408
|
-
title =
|
409
|
-
emoji + 8203.chr(Encoding::UTF_8) + \
|
410
|
-
" Aggregated Data on #{continent} (#{iso.size} States)".upcase
|
411
|
-
else
|
412
|
-
emoji + \
|
413
|
-
" Aggregated Data on #{continent} (#{iso.size} States)".upcase
|
414
|
-
end
|
415
|
-
|
416
|
-
rows = []
|
417
|
-
rows << [
|
418
|
-
comma_delimit(collated_data['cases']),
|
419
|
-
check_if_positve(collated_data['todayCases']),
|
420
|
-
comma_delimit(collated_data['deaths']),
|
421
|
-
check_if_positve(collated_data['todayDeaths']),
|
422
|
-
comma_delimit(collated_data['recovered']),
|
423
|
-
comma_delimit(collated_data['active']),
|
424
|
-
comma_delimit(collated_data['critical'])
|
425
|
-
]
|
198
|
+
title = aggregated_table_title(continent, iso, emoji)
|
426
199
|
|
427
200
|
Terminal::Table.new(
|
428
201
|
title: title,
|
429
202
|
headings: CONTINENTAL_AGGREGATE_HEADINGS,
|
430
|
-
rows:
|
203
|
+
rows: [aggregated_row(collated_data)]
|
431
204
|
)
|
432
205
|
end
|
433
206
|
|
207
|
+
def aggregated_table_title(continent, iso, emoji)
|
208
|
+
aggregated_data_continent = ' Aggregated Data on ' \
|
209
|
+
"#{continent} (#{iso.size} States)".upcase
|
210
|
+
|
211
|
+
if emoji.codepoints.size > 1
|
212
|
+
emoji + 8203.chr(Encoding::UTF_8) + aggregated_data_continent
|
213
|
+
else
|
214
|
+
emoji + aggregated_data_continent
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
434
218
|
def align_columns(table_type, table)
|
435
219
|
return table unless RIGHT_ALIGN_COLUMNS[table_type]
|
436
220
|
|