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.
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 MR MU MA MZ NA NE \
22
- NG RW ST SN SC SL SO ZA SS SD TZ TG TN UG ZM ZW EH].freeze
23
- SOUTH_AMERICA_ISOS = ['AR' 'BO', 'BV', 'BR', 'CL', 'CO', 'EC', \
24
- 'FK', 'GF', 'GY', 'PY', 'PE', 'GS', 'SR', 'UY', 'VE'].freeze
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 MY NP OM PH PK \
27
- PS QA SA SG SY TH TJ TL TM TR TW UZ VN YE].freeze
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.values.first.include?('not found')
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.values.first.include?('not found')
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(Typhoeus.get(UriBuilder.new('/all').url, cache_ttl: 900).response_body)
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(Typhoeus.get(history_path + "/#{country}", cache_ttl: 900).response_body)
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(Typhoeus.get(history_path + "/#{country}", cache_ttl: 900).response_body)
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(Typhoeus.get(COUNTRIES_PATH + "/#{country}", cache_ttl: 900).response_body)
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 { |state| submitted_states.include?(state['state'].downcase) }
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 { |datum| datum['province'] == capitalize_words(province) }.first
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(Typhoeus.get(STATES_URL, cache_ttl: 900).response_body)
247
+ states_array = JSON.parse(
248
+ Typhoeus.get(STATES_URL, cache_ttl: 900).response_body
249
+ )
223
250
 
224
- states_array.select { |state_name| state_name['state'] == capitalize_words(state) }.first
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(Typhoeus.get(UriBuilder.new('/countries').url, cache_ttl: 900).response_body)
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
- data = country_array.inject do |base, other|
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
@@ -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
- class << self
11
- CASES_DEATHS_RECOVERED = [
12
- 'Cases'.paint_white,
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
- rows = [
100
- [
101
- comma_delimit(data['cases']),
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
- rows = []
122
- rows << [
123
- comma_delimit(data['cases']),
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
- headings = [
145
- 'Confirmed'.paint_white,
146
- 'Deaths'.paint_red,
147
- 'Recovered'.paint_green
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
- headings = [
157
- 'Cases'.paint_white,
158
- 'Cases Today'.paint_white,
159
- 'Deaths'.paint_red,
160
- 'Deaths Today'.paint_red,
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
- comma_delimit(country['cases']),
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(headings: COMPARE_COUNTRIES_TABLE_HEADINGS,
191
- rows: rows))
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 do |country|
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
- state.fetch('state').upcase,
217
- comma_delimit(state.fetch('cases')),
218
- check_if_positve(state['todayCases']),
219
- comma_delimit(state['deaths']),
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 do |province|
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: country['country'].upcase,
293
- headings: headings,
294
- rows: 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
- def histogram(country, date_string)
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
- dates.each_with_index do |val, index|
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 eu_aggregate(eu_data)
356
- aggregated_table(eu_data, 'The EU', Kovid::Request::EU_ISOS, '🇪🇺')
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 europe_aggregate(europe_data)
360
- aggregated_table(europe_data, 'Europe', Kovid::Request::EUROPE_ISOS, '🏰')
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
- def africa_aggregate(africa_data)
364
- aggregated_table(africa_data, 'Africa',
365
- Kovid::Request::AFRICA_ISOS, '🌍')
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 south_america_aggregate(south_america_data)
369
- aggregated_table(south_america_data,
370
- 'South America',
371
- Kovid::Request::SOUTH_AMERICA_ISOS, '🌎')
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 asia_aggregate(asia_data)
375
- aggregated_table(asia_data, 'Asia', Kovid::Request::ASIA_ISOS, '🌏')
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
- private
379
-
380
- def comma_delimit(number)
381
- number.to_s.chars.to_a.reverse.each_slice(3)
382
- .map(&:join)
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 check_if_positve(num)
388
- num.to_i.positive? ? "+#{comma_delimit(num)}" : comma_delimit(num).to_s
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 country_emoji(iso)
392
- COUNTRY_LETTERS.values_at(*iso.chars).pack('U*') + \
393
- 8203.chr(Encoding::UTF_8)
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 transpose(load)
397
- load['timeline'].values.map(&:values).transpose.each do |data|
398
- data.map! { |number| comma_delimit(number) }
399
- end
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 = if emoji.codepoints.size > 1
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: 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