kovid 0.6.2 → 0.6.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -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