kovid 0.6.2 → 0.6.7

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.
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'terminal-table'
4
+
4
5
  module Kovid
5
6
  module_function
6
7
 
@@ -14,4 +15,25 @@ module Kovid
14
15
  date_to_parse = Date.strptime(date, '%m/%d/%y').to_s
15
16
  Date.parse(date_to_parse).strftime('%d %b, %y')
16
17
  end
18
+
19
+ def comma_delimit(number)
20
+ number.to_s.chars.to_a.reverse.each_slice(3).map(&:join).join(',').reverse
21
+ end
22
+
23
+ # Insert + sign to format positive numbers
24
+ def add_plus_sign(num)
25
+ num.to_i.positive? ? "+#{comma_delimit(num)}" : comma_delimit(num).to_s
26
+ end
27
+
28
+ def format_country_history_numbers(load)
29
+ load['timeline'].values.map(&:values).transpose.each do |data|
30
+ data.map! { |number| Kovid.comma_delimit(number) }
31
+ end
32
+ end
33
+
34
+ def lookup_us_state(state)
35
+ us = Carmen::Country.coded('USA')
36
+ lookup = us.subregions.coded(state) || us.subregions.named(state)
37
+ lookup ? lookup.name : state
38
+ end
17
39
  end
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kovid
4
+ module Historians
5
+ include Constants
6
+
7
+ def history(country, last)
8
+ # TODO: Write checks for when country is spelt wrong.
9
+ rows = []
10
+
11
+ stats = if last
12
+ Kovid.format_country_history_numbers(country).last(last.to_i)
13
+ else
14
+ Kovid.format_country_history_numbers(country)
15
+ end
16
+
17
+ dates = if last
18
+ country['timeline']['cases'].keys.last(last.to_i)
19
+ else
20
+ country['timeline']['cases'].keys
21
+ end
22
+
23
+ unless last
24
+ stats = stats.reject { |stat| stat[0].to_i.zero? && stat[1].to_i.zero? }
25
+ dates = dates.last(stats.count)
26
+ end
27
+
28
+ stats.each_with_index do |val, index|
29
+ val.unshift(Kovid.dateman(dates[index]))
30
+ end.each do |row|
31
+ rows << row
32
+ end
33
+
34
+ if stats.size > 10
35
+ rows << FOOTER_LINE
36
+ rows << DATE_CASES_DEATHS_RECOVERED
37
+ end
38
+
39
+ Terminal::Table.new(
40
+ title: country['country'].upcase,
41
+ headings: DATE_CASES_DEATHS_RECOVERED,
42
+ rows: rows
43
+ )
44
+ end
45
+
46
+ def histogram(country, date_string)
47
+ @date = date_string.split('.')
48
+
49
+ if @date.last.to_i != 20
50
+ Kovid.info_table('Only 2020 histgrams are available.')
51
+ return
52
+ end
53
+
54
+ # From dates where number of !cases.zero?
55
+ country_cases = country['timeline']['cases']
56
+ positive_cases_figures = country_cases.values.reject(&:zero?)
57
+ dates = country_cases.reject { |_k, v| v.zero? }.keys
58
+ data = []
59
+
60
+ # TODO: Refactor
61
+ # Returns array of days.to_i from the date param
62
+ dates = dates.map do |date|
63
+ date.split('/')
64
+ end.select do |date|
65
+ date.last == @date.last
66
+ end.select do |date|
67
+ date.first == @date.first
68
+ end.map do |array|
69
+ array[1]
70
+ end.map(&:to_i).last(positive_cases_figures.count)
71
+
72
+ # Arranges dates and figures in [x,y] for histogram
73
+ # With x being day, y being number of cases
74
+ if dates.empty?
75
+ if @date.first.to_i > Time.now.month
76
+ msgs = [
77
+ 'Seriously...??! 😏', 'Did you just check the future??',
78
+ 'You just checked the future Morgan.',
79
+ 'Knowing too much of your future is never a good thing.'
80
+ ]
81
+
82
+ Kovid.info_table(msgs.sample)
83
+ else
84
+ Kovid.info_table('Check your spelling/No infections for this month.')
85
+ end
86
+
87
+ else
88
+ dates.each_with_index do |val, index|
89
+ data << [val, positive_cases_figures[index]]
90
+ end
91
+ y_range = AsciiCharts::Cartesian.new(
92
+ data, bar: true, hide_zero: true
93
+ ).y_range
94
+
95
+ last_two_y = y_range.last 2
96
+ y_interval = last_two_y.last - last_two_y.first
97
+
98
+ scale("Scale on Y: #{y_interval}:#{(
99
+ y_interval / last_two_y.last.to_f * positive_cases_figures.last
100
+ ).round(2) / y_interval}")
101
+
102
+ puts 'Experimental feature, please report issues.'
103
+
104
+ AsciiCharts::Cartesian.new(data, bar: true, hide_zero: true).draw
105
+ end
106
+ end
107
+ end
108
+ end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'rainbow'
4
-
5
4
  class String
6
5
  def paint_white
7
6
  Rainbow(self).white.bg(:black).bold
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'json'
4
+ require 'carmen'
4
5
  require_relative 'tablelize'
5
6
  require_relative 'cache'
6
7
  require_relative 'uri_builder'
@@ -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)
@@ -107,7 +110,7 @@ module Kovid
107
110
  end
108
111
 
109
112
  def state(state)
110
- response = fetch_state(state)
113
+ response = fetch_state(Kovid.lookup_us_state(state))
111
114
  if response.nil?
112
115
  not_found(state)
113
116
  else
@@ -119,7 +122,6 @@ module Kovid
119
122
 
120
123
  def states(states)
121
124
  compared_states = fetch_compared_states(states)
122
-
123
125
  Kovid::Tablelize.compare_us_states(compared_states)
124
126
  rescue JSON::ParserError
125
127
  puts SERVER_DOWN
@@ -147,7 +149,9 @@ module Kovid
147
149
  end
148
150
 
149
151
  def cases
150
- response = JSON.parse(Typhoeus.get(UriBuilder.new('/all').url, cache_ttl: 900).response_body)
152
+ response = JSON.parse(
153
+ Typhoeus.get(UriBuilder.new('/all').url, cache_ttl: 900).response_body
154
+ )
151
155
 
152
156
  Kovid::Tablelize.cases(response)
153
157
  rescue JSON::ParserError
@@ -156,7 +160,11 @@ module Kovid
156
160
 
157
161
  def history(country, last)
158
162
  history_path = UriBuilder.new('/v2/historical').url
159
- response = JSON.parse(Typhoeus.get(history_path + "/#{country}", cache_ttl: 900).response_body)
163
+ response = JSON.parse(
164
+ Typhoeus.get(
165
+ history_path + "/#{country}", cache_ttl: 900
166
+ ).response_body
167
+ )
160
168
 
161
169
  Kovid::Tablelize.history(response, last)
162
170
  rescue JSON::ParserError
@@ -165,7 +173,11 @@ module Kovid
165
173
 
166
174
  def histogram(country, date)
167
175
  history_path = UriBuilder.new('/v2/historical').url
168
- response = JSON.parse(Typhoeus.get(history_path + "/#{country}", cache_ttl: 900).response_body)
176
+ response = JSON.parse(
177
+ Typhoeus.get(
178
+ history_path + "/#{country}", cache_ttl: 900
179
+ ).response_body
180
+ )
169
181
 
170
182
  Kovid::Tablelize.histogram(response, date)
171
183
  end
@@ -183,14 +195,20 @@ module Kovid
183
195
 
184
196
  def fetch_countries(list)
185
197
  list.map do |country|
186
- JSON.parse(Typhoeus.get(COUNTRIES_PATH + "/#{country}", cache_ttl: 900).response_body)
198
+ JSON.parse(
199
+ Typhoeus.get(
200
+ COUNTRIES_PATH + "/#{country}", cache_ttl: 900
201
+ ).response_body
202
+ )
187
203
  end.sort_by { |json| -json['cases'] }
188
204
  end
189
205
 
190
206
  def fetch_compared_states(submitted_states)
191
- state_data = fetch_state_data
207
+ submitted_states.map! { |s| Kovid.lookup_us_state(s) }
192
208
 
193
- state_data.select { |state| submitted_states.include?(state['state'].downcase) }
209
+ fetch_state_data.select do |state|
210
+ submitted_states.include?(state['state'])
211
+ end
194
212
  end
195
213
 
196
214
  def fetch_state_data
@@ -198,6 +216,8 @@ module Kovid
198
216
  end
199
217
 
200
218
  def fetch_country(country_name)
219
+ # TODO: Match ISOs to full country names
220
+ country_name = 'nl' if country_name == 'netherlands'
201
221
  country_url = COUNTRIES_PATH + "/#{country_name}"
202
222
 
203
223
  JSON.parse(Typhoeus.get(country_url, cache_ttl: 900).response_body)
@@ -209,7 +229,9 @@ module Kovid
209
229
 
210
230
  def fetch_province(province)
211
231
  response = fetch_jhucsse
212
- response.select { |datum| datum['province'] == capitalize_words(province) }.first
232
+ response.select do |datum|
233
+ datum['province'] == capitalize_words(province)
234
+ end.first
213
235
  end
214
236
 
215
237
  def fetch_provinces(provinces)
@@ -219,19 +241,35 @@ module Kovid
219
241
  end
220
242
 
221
243
  def fetch_state(state)
222
- states_array = JSON.parse(Typhoeus.get(STATES_URL, cache_ttl: 900).response_body)
244
+ states_array = JSON.parse(
245
+ Typhoeus.get(STATES_URL, cache_ttl: 900).response_body
246
+ )
223
247
 
224
- states_array.select { |state_name| state_name['state'] == capitalize_words(state) }.first
248
+ states_array.select do |state_name|
249
+ state_name['state'] == capitalize_words(state)
250
+ end.first
225
251
  end
226
252
 
227
253
  def aggregator(isos, meth)
228
- countries_array = JSON.parse(Typhoeus.get(UriBuilder.new('/countries').url, cache_ttl: 900).response_body)
229
-
254
+ countries_array = JSON.parse(countries_request)
230
255
  country_array = countries_array.select do |hash|
231
256
  isos.include?(hash['countryInfo']['iso2'])
232
257
  end
258
+ data = countries_aggregator(country_array)
233
259
 
234
- data = country_array.inject do |base, other|
260
+ meth === data
261
+ rescue JSON::ParserError
262
+ puts SERVER_DOWN
263
+ end
264
+
265
+ def countries_request
266
+ Typhoeus.get(
267
+ UriBuilder.new('/countries').url, cache_ttl: 900
268
+ ).response_body
269
+ end
270
+
271
+ def countries_aggregator(country_array)
272
+ country_array.inject do |base, other|
235
273
  base.merge(other) do |key, left, right|
236
274
  left ||= 0
237
275
  right ||= 0
@@ -239,10 +277,6 @@ module Kovid
239
277
  left + right unless %w[country countryInfo].include?(key)
240
278
  end
241
279
  end.compact
242
-
243
- meth === data
244
- rescue JSON::ParserError
245
- puts SERVER_DOWN
246
280
  end
247
281
  end
248
282
  end
@@ -4,206 +4,62 @@ 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
9
12
  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
13
+ extend Kovid::Constants
14
+ extend Kovid::Aggregators
15
+ extend Kovid::Historians
97
16
 
17
+ class << self
98
18
  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
19
+ Terminal::Table.new(title: country_title(data),
20
+ headings: CASES_DEATHS_RECOVERED_CTODAY_DTODAY,
21
+ rows: [country_row(data)])
118
22
  end
119
23
 
120
24
  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
25
+ Terminal::Table.new(title: country_title(data),
26
+ headings: FULL_COUNTRY_TABLE_HEADINGS,
27
+ rows: [full_country_row(data)])
141
28
  end
142
29
 
143
30
  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)
31
+ Terminal::Table.new(
32
+ title: province['province'].upcase,
33
+ headings: FULL_PROVINCE_TABLE_HEADINGS,
34
+ rows: [province_row(province)]
35
+ )
153
36
  end
154
37
 
155
38
  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)
39
+ Terminal::Table.new(
40
+ title: state['state'].upcase,
41
+ headings: FULL_STATE_TABLE_HEADINGS,
42
+ rows: [country_row(state)]
43
+ )
168
44
  end
169
45
 
170
46
  def compare_countries_table(data)
171
47
  rows = []
172
48
 
173
49
  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
50
+ base_rows = country_row(country)
51
+ rows << base_rows.unshift(country_title(country))
187
52
  end
188
53
 
189
54
  align_columns(:compare_country_table,
190
- Terminal::Table.new(headings: COMPARE_COUNTRIES_TABLE_HEADINGS,
191
- rows: rows))
55
+ Terminal::Table.new(
56
+ headings: COMPARE_COUNTRIES_TABLE_HEADINGS,
57
+ rows: rows
58
+ ))
192
59
  end
193
60
 
194
61
  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
62
+ rows = data.map { |country| compare_countries_full_row(country) }
207
63
 
208
64
  align_columns(:compare_country_table_full,
209
65
  Terminal::Table.new(headings: COMPARE_COUNTRY_TABLE_FULL,
@@ -213,23 +69,9 @@ module Kovid
213
69
  def compare_us_states(data)
214
70
  rows = data.map.with_index do |state, index|
215
71
  if index.odd?
216
- [
217
- state.fetch('state').upcase,
218
- comma_delimit(state.fetch('cases')),
219
- check_if_positve(state['todayCases']),
220
- comma_delimit(state['deaths']),
221
- check_if_positve(state['todayDeaths']),
222
- comma_delimit(state.fetch('active'))
223
- ]
72
+ us_state_row(state)
224
73
  else
225
- [
226
- state.fetch('state').upcase.paint_highlight,
227
- comma_delimit(state.fetch('cases')).paint_highlight,
228
- check_if_positve(state['todayCases']).paint_highlight,
229
- comma_delimit(state['deaths']).paint_highlight,
230
- check_if_positve(state['todayDeaths']).paint_highlight,
231
- comma_delimit(state.fetch('active')).paint_highlight
232
- ]
74
+ us_state_row(state).map(&:paint_highlight)
233
75
  end
234
76
  end
235
77
 
@@ -239,14 +81,7 @@ module Kovid
239
81
  end
240
82
 
241
83
  def compare_provinces(data)
242
- rows = data.map do |province|
243
- [
244
- province['province'].upcase,
245
- province['stats']['confirmed'],
246
- province['stats']['deaths'],
247
- province['stats']['recovered']
248
- ]
249
- end
84
+ rows = data.map { |province| compare_provinces_row(province) }
250
85
 
251
86
  align_columns(:compare_provinces,
252
87
  Terminal::Table.new(headings: COMPARE_PROVINCES_HEADINGS,
@@ -254,160 +89,103 @@ module Kovid
254
89
  end
255
90
 
256
91
  def cases(cases)
257
- headings = CASES_DEATHS_RECOVERED
258
- rows = [
259
- [
260
- comma_delimit(cases['cases']),
261
- comma_delimit(cases['deaths']),
262
- comma_delimit(cases['recovered'])
263
- ]
264
- ]
265
-
266
- Terminal::Table.new(title: '🌍 Total Number of Incidents Worldwide'.upcase, headings: headings, rows: rows)
267
- end
268
-
269
- def history(country, last)
270
- # Write checks for when country is spelt wrong.
271
- headings = DATE_CASES_DEATHS_RECOVERED
272
- rows = []
273
-
274
- stats = if last
275
- transpose(country).last(last.to_i)
276
- else
277
- transpose(country)
278
- end
279
-
280
- dates = if last
281
- country['timeline']['cases'].keys.last(last.to_i)
282
- else
283
- country['timeline']['cases'].keys
284
- end
285
-
286
- unless last
287
- stats = stats.reject { |stat| stat[0].to_i.zero? && stat[1].to_i.zero? }
288
- dates = dates.last(stats.count)
289
- end
290
-
291
- stats.each_with_index do |val, index|
292
- val.unshift(Kovid.dateman(dates[index]))
293
- end.each do |row|
294
- rows << row
295
- end
296
-
297
- if stats.size > 10
298
- rows << FOOTER_LINE
299
- rows << DATE_CASES_DEATHS_RECOVERED
300
- end
301
-
302
92
  Terminal::Table.new(
303
- title: country['country'].upcase,
304
- headings: headings,
305
- rows: rows
93
+ title: '🌍 Total Number of Incidents Worldwide'.upcase,
94
+ headings: CASES_DEATHS_RECOVERED,
95
+ rows: [cases_row(cases)]
306
96
  )
307
97
  end
308
98
 
309
- def histogram(country, date_string)
310
- @date = date_string.split('.')
311
-
312
- if @date.last.to_i != 20
313
- Kovid.info_table('Only 2020 histgrams are available.')
314
- return
315
- end
316
-
317
- # From dates where number of !cases.zero?
318
- positive_cases_figures = country['timeline']['cases'].values.reject(&:zero?)
319
- dates = country['timeline']['cases'].reject { |_k, v| v.zero? }.keys
320
- data = []
321
-
322
- # Improve this later, like everything else.
323
- # Returns array of days.to_i from the date param
324
- dates = dates.map do |date|
325
- date.split('/')
326
- end.select do |date|
327
- date.last == @date.last
328
- end.select do |date|
329
- date.first == @date.first
330
- end.map do |array|
331
- array[1]
332
- end.map(&:to_i).last(positive_cases_figures.count)
333
-
334
- # Arranges dates and figures in [x,y] for histogram
335
- # With x being day, y being number of cases
336
- if dates.empty?
337
- if @date.first.to_i > Time.now.month
338
- msgs = [
339
- 'Seriously...??! 😏', 'Did you just check the future??',
340
- 'You just checked the future Morgan.',
341
- 'Knowing too much of your future is never a good thing.'
342
- ]
343
-
344
- Kovid.info_table(msgs.sample)
345
- else
346
- Kovid.info_table('Check your spelling/No infections for this month.')
347
- end
99
+ private
348
100
 
101
+ def country_title(data)
102
+ iso = data['countryInfo']['iso2']
103
+ if iso.nil?
104
+ data['country'].upcase
349
105
  else
350
- dates.each_with_index do |val, index|
351
- data << [val, positive_cases_figures[index]]
352
- end
353
- y_range = AsciiCharts::Cartesian.new(data, bar: true, hide_zero: true).y_range
354
-
355
- last_two_y = y_range.last 2
356
- y_interval = last_two_y.last - last_two_y.first
357
-
358
- scale("Scale on Y: #{y_interval}:#{(y_interval / last_two_y.last.to_f * positive_cases_figures.last).round(2) / y_interval}")
359
-
360
- puts 'Experimental feature, please report issues.'
361
-
362
- AsciiCharts::Cartesian.new(data, bar: true, hide_zero: true).draw
106
+ "#{country_emoji(iso)} #{data['country'].upcase}"
363
107
  end
364
108
  end
365
109
 
366
- def eu_aggregate(eu_data)
367
- aggregated_table(eu_data, 'The EU', Kovid::Request::EU_ISOS, '🇪🇺')
110
+ def country_emoji(iso)
111
+ COUNTRY_LETTERS.values_at(*iso.chars).pack('U*') + \
112
+ 8203.chr(Encoding::UTF_8)
368
113
  end
369
114
 
370
- def europe_aggregate(europe_data)
371
- aggregated_table(europe_data, 'Europe', Kovid::Request::EUROPE_ISOS, '🏰')
115
+ def cases_row(data)
116
+ [
117
+ Kovid.comma_delimit(data['cases']),
118
+ Kovid.comma_delimit(data['deaths']),
119
+ Kovid.comma_delimit(data['recovered'])
120
+ ]
372
121
  end
373
122
 
374
- def africa_aggregate(africa_data)
375
- aggregated_table(africa_data, 'Africa',
376
- Kovid::Request::AFRICA_ISOS, '🌍')
123
+ # Also works for state
124
+ def country_row(data)
125
+ [
126
+ Kovid.comma_delimit(data['cases']),
127
+ Kovid.add_plus_sign(data['todayCases']),
128
+ Kovid.comma_delimit(data['deaths']),
129
+ Kovid.add_plus_sign(data['todayDeaths']),
130
+ Kovid.comma_delimit(data['recovered'])
131
+ ]
377
132
  end
378
133
 
379
- def south_america_aggregate(south_america_data)
380
- aggregated_table(south_america_data,
381
- 'South America',
382
- Kovid::Request::SOUTH_AMERICA_ISOS, '🌎')
134
+ def full_country_row(data)
135
+ [
136
+ Kovid.comma_delimit(data['cases']),
137
+ Kovid.comma_delimit(data['deaths']),
138
+ Kovid.comma_delimit(data['recovered']),
139
+ Kovid.add_plus_sign(data['todayCases']),
140
+ Kovid.add_plus_sign(data['todayDeaths']),
141
+ Kovid.comma_delimit(data['critical']),
142
+ Kovid.comma_delimit(data['casesPerOneMillion'])
143
+ ]
383
144
  end
384
145
 
385
- def asia_aggregate(asia_data)
386
- aggregated_table(asia_data, 'Asia', Kovid::Request::ASIA_ISOS, '🌏')
146
+ def province_row(data)
147
+ [
148
+ data['stats']['confirmed'],
149
+ data['stats']['deaths'],
150
+ data['stats']['recovered']
151
+ ]
387
152
  end
388
153
 
389
- private
390
-
391
- def comma_delimit(number)
392
- number.to_s.chars.to_a.reverse.each_slice(3)
393
- .map(&:join)
394
- .join(',')
395
- .reverse
154
+ def compare_provinces_row(data)
155
+ [
156
+ data['province'].upcase,
157
+ province_row(data)
158
+ ].flatten
396
159
  end
397
160
 
398
- def check_if_positve(num)
399
- num.to_i.positive? ? "+#{comma_delimit(num)}" : comma_delimit(num).to_s
161
+ def compare_countries_full_row(data)
162
+ [
163
+ data.fetch('country'),
164
+ full_country_row(data)
165
+ ].flatten
400
166
  end
401
167
 
402
- def country_emoji(iso)
403
- COUNTRY_LETTERS.values_at(*iso.chars).pack('U*') + \
404
- 8203.chr(Encoding::UTF_8)
168
+ def us_state_row(data)
169
+ [
170
+ data.fetch('state').upcase,
171
+ Kovid.comma_delimit(data.fetch('cases')),
172
+ Kovid.add_plus_sign(data['todayCases']),
173
+ Kovid.comma_delimit(data['deaths']),
174
+ Kovid.add_plus_sign(data['todayDeaths']),
175
+ Kovid.comma_delimit(data.fetch('active'))
176
+ ]
405
177
  end
406
178
 
407
- def transpose(load)
408
- load['timeline'].values.map(&:values).transpose.each do |data|
409
- data.map! { |number| comma_delimit(number) }
410
- end
179
+ def aggregated_row(data)
180
+ [
181
+ Kovid.comma_delimit(data['cases']),
182
+ Kovid.add_plus_sign(data['todayCases']),
183
+ Kovid.comma_delimit(data['deaths']),
184
+ Kovid.add_plus_sign(data['todayDeaths']),
185
+ Kovid.comma_delimit(data['recovered']),
186
+ Kovid.comma_delimit(data['active']),
187
+ Kovid.comma_delimit(data['critical'])
188
+ ]
411
189
  end
412
190
 
413
191
  def scale(msg)
@@ -416,32 +194,26 @@ module Kovid
416
194
  end
417
195
 
418
196
  def aggregated_table(collated_data, continent, iso, emoji)
419
- title = if emoji.codepoints.size > 1
420
- emoji + 8203.chr(Encoding::UTF_8) + \
421
- " Aggregated Data on #{continent} (#{iso.size} States)".upcase
422
- else
423
- emoji + \
424
- " Aggregated Data on #{continent} (#{iso.size} States)".upcase
425
- end
426
-
427
- rows = []
428
- rows << [
429
- comma_delimit(collated_data['cases']),
430
- check_if_positve(collated_data['todayCases']),
431
- comma_delimit(collated_data['deaths']),
432
- check_if_positve(collated_data['todayDeaths']),
433
- comma_delimit(collated_data['recovered']),
434
- comma_delimit(collated_data['active']),
435
- comma_delimit(collated_data['critical'])
436
- ]
197
+ title = aggregated_table_title(continent, iso, emoji)
437
198
 
438
199
  Terminal::Table.new(
439
200
  title: title,
440
201
  headings: CONTINENTAL_AGGREGATE_HEADINGS,
441
- rows: rows
202
+ rows: [aggregated_row(collated_data)]
442
203
  )
443
204
  end
444
205
 
206
+ def aggregated_table_title(continent, iso, emoji)
207
+ aggregated_data_continent = ' Aggregated Data on ' \
208
+ "#{continent} (#{iso.size} States)".upcase
209
+
210
+ if emoji.codepoints.size > 1
211
+ emoji + 8203.chr(Encoding::UTF_8) + aggregated_data_continent
212
+ else
213
+ emoji + aggregated_data_continent
214
+ end
215
+ end
216
+
445
217
  def align_columns(table_type, table)
446
218
  return table unless RIGHT_ALIGN_COLUMNS[table_type]
447
219