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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b34798e9212d718e441ff0185598d028662b4e13994ebe7a7354cd0a22a7aef5
4
- data.tar.gz: 2e23bc917e77996ad1b848aed6340cdb25123ba5bfd976a8d5407c347f05ac25
3
+ metadata.gz: 6abc6282e6ec84a393eee2b5383d70f88643d7633f8bd7537c207dae341ead1b
4
+ data.tar.gz: a93e83c437e3b1f740fe7471cca72ad2e83c837d0a637c5fe8c71636bdd545dd
5
5
  SHA512:
6
- metadata.gz: 0c2ce46118ef92380c1c5bd1b4faba1b1e8893225161c7e3c2fe684298db3d830eda22f13854f8a69e8aef6d0ad581cca9b1ee40db8f3ab79bc410db1fce29f7
7
- data.tar.gz: 9099b7a5e109c567ab7a0b707d991ad53be609ff918b02b6d56bcc45516c1489a9785e931c2814036a415edab69c0f24826bdd9f18ec6ccc6a438dae85c89e86
6
+ metadata.gz: dbc95ba0e85745d9369e15b0e81b6f5d36a7199b1227aaaec56eb57b8aac067750e4e2c71f937a97b333fdf57693547d6f98a09e70d214a5300b5b09cd5eeb25
7
+ data.tar.gz: a2a458068aefa1f001ad85426ef5eba0317ba23a0320fab970eed818a9009186cc966f757c0a4f1b693a85cf668098ffa477acc3587849ed5864dcfc53a3b5fe
data/.rubocop.yml ADDED
@@ -0,0 +1,4 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
3
+ AllCops:
4
+ TargetRubyVersion: 2.6
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,59 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2020-04-07 20:38:28 -0300 using RuboCop version 0.67.2.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 2
10
+ Metrics/AbcSize:
11
+ Max: 54
12
+ Exclude:
13
+ - 'lib/kovid/historians.rb'
14
+
15
+ # Offense count: 2
16
+ Metrics/BlockLength:
17
+ Exclude:
18
+ - 'kovid.gemspec'
19
+ - 'spec/kovid_spec.rb'
20
+
21
+ # Offense count: 3
22
+ # Configuration parameters: CountComments.
23
+ Metrics/ClassLength:
24
+ Max: 220
25
+ Exclude:
26
+ - 'lib/kovid/cli.rb'
27
+ - 'lib/kovid/request.rb'
28
+ - 'lib/kovid/tablelize.rb'
29
+
30
+ # Offense count: 2
31
+ # Configuration parameters: CountComments, ExcludedMethods.
32
+ Metrics/MethodLength:
33
+ Max: 44
34
+ Exclude:
35
+ - 'lib/kovid/historians.rb'
36
+
37
+ # Offense count: 1
38
+ Metrics/PerceivedComplexity:
39
+ Max: 8
40
+ Exclude:
41
+ - 'lib/kovid/historians.rb'
42
+
43
+ # Offense count: 1
44
+ Style/CaseEquality:
45
+ Exclude:
46
+ - 'lib/kovid/request.rb'
47
+
48
+ Style/Documentation:
49
+ Exclude:
50
+ - 'spec/**/*'
51
+ - 'test/**/*'
52
+ - 'lib/kovid.rb'
53
+ - 'lib/kovid/helpers.rb'
54
+
55
+ # Offense count: 5
56
+ Style/MultilineBlockChain:
57
+ Exclude:
58
+ - 'lib/kovid/historians.rb'
59
+ - 'lib/kovid/request.rb'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- kovid (0.6.0)
4
+ kovid (0.6.5)
5
5
  ascii_charts (~> 0.9.1)
6
6
  rainbow (~> 3.0)
7
7
  terminal-table (~> 1.8)
data/README.md CHANGED
@@ -44,7 +44,7 @@ You can get continental information with the following commands:
44
44
 
45
45
  You can fetch US state-specific data:
46
46
  * `kovid state STATE` OR `kovid state "STATE NAME"`.
47
- * `kovid aus` for data on all US states.
47
+ * `kovid states --all` or `kovid states -a` for data on all US states.
48
48
 
49
49
  Provinces
50
50
 
data/Rakefile CHANGED
@@ -7,3 +7,4 @@ RSpec::Core::RakeTask.new(:spec)
7
7
 
8
8
  # rubocop:disable Style/HashSyntax
9
9
  task :default => :spec
10
+ # rubocop:enable Style/HashSyntax
data/kovid.gemspec CHANGED
@@ -8,8 +8,10 @@ Gem::Specification.new do |spec|
8
8
  spec.authors = ['Emmanuel Hayford']
9
9
  spec.email = ['siawmensah@gmail.com']
10
10
 
11
- spec.summary = 'A CLI to fetch and compare the 2019 coronavirus pandemic statistics.'
12
- spec.description = 'A CLI to fetch and compare the 2019 coronavirus pandemic statistics.'
11
+ summary = 'A CLI to fetch and compare the 2019 ' \
12
+ 'coronavirus pandemic statistics.'
13
+ spec.summary = summary
14
+ spec.description = summary
13
15
  spec.homepage = 'https://github.com/siaw23/kovid'
14
16
  spec.license = 'MIT'
15
17
  spec.required_ruby_version = Gem::Requirement.new('>= 2.4.0')
@@ -29,9 +31,12 @@ Gem::Specification.new do |spec|
29
31
  spec.add_development_dependency 'simplecov', '~> 0.18'
30
32
 
31
33
  # Specify which files should be added to the gem when it is released.
32
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
34
+ # The `git ls-files -z` loads the files in the RubyGem
35
+ # that have been added into git.
33
36
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
34
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
37
+ `git ls-files -z`.split("\x0").reject do |f|
38
+ f.match(%r{^(test|spec|features)/})
39
+ end
35
40
  end
36
41
  spec.bindir = 'exe'
37
42
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kovid
4
+ # Sends info about continents to Tablelize
5
+ module Aggregators
6
+ def eu_aggregate(eu_data)
7
+ aggregated_table(eu_data, 'The EU', Kovid::Request::EU_ISOS, '🇪🇺')
8
+ end
9
+
10
+ def europe_aggregate(europe_data)
11
+ aggregated_table(europe_data, 'Europe', Kovid::Request::EUROPE_ISOS, '🏰')
12
+ end
13
+
14
+ def africa_aggregate(africa_data)
15
+ aggregated_table(africa_data, 'Africa',
16
+ Kovid::Request::AFRICA_ISOS, '🌍')
17
+ end
18
+
19
+ def south_america_aggregate(south_america_data)
20
+ aggregated_table(south_america_data,
21
+ 'South America',
22
+ Kovid::Request::SOUTH_AMERICA_ISOS, '🌎')
23
+ end
24
+
25
+ def asia_aggregate(asia_data)
26
+ aggregated_table(asia_data, 'Asia', Kovid::Request::ASIA_ISOS, '🌏')
27
+ end
28
+ end
29
+ end
data/lib/kovid/cache.rb CHANGED
@@ -2,7 +2,10 @@
2
2
 
3
3
  require 'typhoeus'
4
4
 
5
+ # rubocop:disable Style/Documentation
5
6
  module Kovid
7
+ # rubocop:enable Style/Documentation
8
+ # Caches HTTP requests
6
9
  class Cache
7
10
  def initialize
8
11
  @memory = {}
data/lib/kovid/cli.rb CHANGED
@@ -4,38 +4,50 @@ require 'thor'
4
4
  require 'kovid'
5
5
 
6
6
  module Kovid
7
+ # Describes the commands that can be run by the user
8
+ # Descriptions are returned to STDOUT
7
9
  class CLI < Thor
8
- FULL_FLAG = %w[-f --full].freeze
9
-
10
10
  def self.exit_on_failure?
11
11
  true
12
12
  end
13
13
 
14
- desc 'province PROVINCE or province "PROVINCE NAME"', 'Returns reported data on provided province. eg "kovid check "new brunswick".'
14
+ desc 'province PROVINCE or province "PROVINCE NAME"',
15
+ 'Returns reported data on provided province. ' \
16
+ 'eg "kovid check "new brunswick".'
15
17
  method_option :full, aliases: '-p'
16
18
  def province(name)
17
19
  puts Kovid.province(name)
18
20
  data_source
19
21
  end
20
22
 
21
- desc 'provinces PROVINCE PROVINCE', 'Returns full comparison table for the given provinces. Accepts multiple provinces.'
23
+ desc 'provinces PROVINCE PROVINCE',
24
+ 'Returns full comparison table for the given provinces. ' \
25
+ 'Accepts multiple provinces.'
22
26
  def provinces(*names)
23
27
  puts Kovid.provinces(names)
24
28
  data_source
25
29
  end
26
30
 
27
- desc 'check COUNTRY or check "COUNTRY NAME"', 'Returns reported data on provided country. eg: "kovid check "hong kong".'
31
+ desc 'check COUNTRY or check "COUNTRY NAME"',
32
+ 'Returns reported data on provided country. ' \
33
+ 'eg: "kovid check "hong kong".'
28
34
  method_option :full, aliases: '-f'
29
- def check(name)
30
- fetch_country_stats(name)
35
+ def check(*name)
36
+ if name.size == 1
37
+ fetch_country_stats(name.pop)
38
+ elsif options[:full]
39
+ puts Kovid.country_comparison_full(name)
40
+ else
41
+ puts Kovid.country_comparison(name)
42
+ end
31
43
  data_source
32
44
  end
45
+ map country: :check
33
46
 
34
- desc 'country COUNTRY or country "COUNTRY NAME"', 'Returns reported data on provided country. eg: "kovid country "hong kong".'
35
- method_option :full, aliases: '-f'
36
- def country(name)
37
- fetch_country_stats(name)
38
- data_source
47
+ desc 'compare COUNTRY COUNTRY', 'Deprecated. Will be removed in v7.0.0'
48
+ def compare(*_name)
49
+ Kovid.info_table("#compare is deprecated and will be removed in v7.0.0. \
50
+ \nPlease do `kovid check COUNTRY COUNTRY ...` instead.")
39
51
  end
40
52
 
41
53
  desc 'state STATE', 'Return reported data on provided state.'
@@ -44,31 +56,20 @@ module Kovid
44
56
  data_source
45
57
  end
46
58
 
47
- desc 'compare COUNTRY COUNTRY', 'Returns full comparison table for given countries. Accepts multiple countries.'
48
- def compare(*name)
49
- if FULL_FLAG.include?(name.fetch(-1))
50
- puts Kovid.country_comparison_full(name[0..-2])
59
+ desc 'states STATE STATE or states --all',
60
+ 'Returns full comparison table for the given states. ' \
61
+ 'Accepts multiple states.'
62
+ method_option :all, aliases: '-a'
63
+ def states(*states)
64
+ if options[:all]
65
+ puts Kovid.all_us_states
51
66
  else
52
- puts Kovid.country_comparison(name)
67
+ downcased_states = states.map(&:downcase)
68
+ puts Kovid.states(downcased_states)
53
69
  end
54
- data_source
55
- end
56
-
57
- desc 'states STATE STATE', 'Returns full comparison table for the given states. Accepts multiple states.'
58
- def states(*states)
59
- # This ensures this command is case insensitive.
60
- downcased_states = states.map(&:downcase)
61
-
62
- puts Kovid.states(downcased_states)
63
- data_source
64
- end
65
70
 
66
- desc 'all_us_states', 'Returns full comparison table for all US states'
67
- def all_us_states
68
- puts Kovid.all_us_states
69
71
  data_source
70
72
  end
71
- map aus: :all_us_states
72
73
 
73
74
  desc 'world', 'Returns total number of cases, deaths and recoveries.'
74
75
  def world
@@ -76,7 +77,8 @@ module Kovid
76
77
  data_source
77
78
  end
78
79
 
79
- desc 'history COUNTRY or history COUNTRY N', 'Return history of incidents of COUNTRY (in the last N days)'
80
+ desc 'history COUNTRY or history COUNTRY N',
81
+ 'Return history of incidents of COUNTRY (in the last N days)'
80
82
  def history(*params)
81
83
  if params.size == 2
82
84
  puts Kovid.history(params.first, params.last)
@@ -0,0 +1,112 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kovid
4
+ module Constants
5
+ CASES_DEATHS_RECOVERED = [
6
+ 'Cases'.paint_white,
7
+ 'Deaths'.paint_red,
8
+ 'Recovered'.paint_green
9
+ ].freeze
10
+
11
+ CASES_DEATHS_RECOVERED_CTODAY_DTODAY = [
12
+ 'Cases'.paint_white,
13
+ 'Cases Today'.paint_white,
14
+ 'Deaths'.paint_red,
15
+ 'Deaths Today'.paint_red,
16
+ 'Recovered'.paint_green
17
+ ].freeze
18
+
19
+ DATE_CASES_DEATHS_RECOVERED = [
20
+ 'Date'.paint_white,
21
+ 'Cases'.paint_white,
22
+ 'Deaths'.paint_red,
23
+ 'Recovered'.paint_green
24
+ ].freeze
25
+
26
+ CONTINENTAL_AGGREGATE_HEADINGS = [
27
+ 'Cases'.paint_white,
28
+ 'Cases Today'.paint_white,
29
+ 'Deaths'.paint_red,
30
+ 'Deaths Today'.paint_red,
31
+ 'Recovered'.paint_green,
32
+ 'Active'.paint_yellow,
33
+ 'Critical'.paint_red
34
+ ].freeze
35
+
36
+ COMPARE_COUNTRY_TABLE_FULL = [
37
+ 'Country'.paint_white,
38
+ 'Cases'.paint_white,
39
+ 'Deaths'.paint_red,
40
+ 'Recovered'.paint_green,
41
+ 'Cases Today'.paint_white,
42
+ 'Deaths Today'.paint_red,
43
+ 'Critical'.paint_yellow,
44
+ 'Cases/Million'.paint_white
45
+ ].freeze
46
+
47
+ COMPARE_COUNTRIES_TABLE_HEADINGS = [
48
+ 'Country'.paint_white,
49
+ 'Cases'.paint_white,
50
+ 'Cases Today'.paint_white,
51
+ 'Deaths'.paint_red,
52
+ 'Deaths Today'.paint_red,
53
+ 'Recovered'.paint_green
54
+ ].freeze
55
+
56
+ FULL_COUNTRY_TABLE_HEADINGS = [
57
+ 'Cases'.paint_white,
58
+ 'Deaths'.paint_red,
59
+ 'Recovered'.paint_green,
60
+ 'Cases Today'.paint_white,
61
+ 'Deaths Today'.paint_red,
62
+ 'Critical'.paint_yellow,
63
+ 'Cases/Million'.paint_white
64
+ ].freeze
65
+
66
+ FULL_PROVINCE_TABLE_HEADINGS = [
67
+ 'Confirmed'.paint_white,
68
+ 'Deaths'.paint_red,
69
+ 'Recovered'.paint_green
70
+ ].freeze
71
+
72
+ FULL_STATE_TABLE_HEADINGS = [
73
+ 'Cases'.paint_white,
74
+ 'Cases Today'.paint_white,
75
+ 'Deaths'.paint_red,
76
+ 'Deaths Today'.paint_red,
77
+ 'Active'.paint_yellow
78
+ ].freeze
79
+
80
+ COMPARE_STATES_HEADINGS = [
81
+ 'State'.paint_white,
82
+ 'Cases'.paint_white,
83
+ 'Cases Today'.paint_white,
84
+ 'Deaths'.paint_red,
85
+ 'Deaths Today'.paint_red,
86
+ 'Active'.paint_yellow
87
+ ].freeze
88
+
89
+ COMPARE_PROVINCES_HEADINGS = [
90
+ 'Province'.paint_white,
91
+ 'Confirmed'.paint_white,
92
+ 'Deaths'.paint_red,
93
+ 'Recovered'.paint_green
94
+ ].freeze
95
+
96
+ FOOTER_LINE = [
97
+ '------------',
98
+ '------------',
99
+ '------------',
100
+ '------------'
101
+ ].freeze
102
+
103
+ COUNTRY_LETTERS = 'A'.upto('Z').with_index(127_462).to_h.freeze
104
+
105
+ RIGHT_ALIGN_COLUMNS = {
106
+ compare_country_table_full: [1, 2, 3, 4, 5, 6, 7],
107
+ compare_country_table: [1, 2, 3, 4, 5],
108
+ compare_us_states: [1, 2, 3, 4, 5],
109
+ compare_provinces: [1, 2, 3]
110
+ }.freeze
111
+ end
112
+ end
data/lib/kovid/helpers.rb CHANGED
@@ -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,19 @@ 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
17
33
  end
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kovid
4
+ # Constructs history data for specified country
5
+ module Historians
6
+ include Constants
7
+
8
+ def history(country, last)
9
+ # Write checks for when country is spelt wrong.
10
+ headings = DATE_CASES_DEATHS_RECOVERED
11
+ rows = []
12
+
13
+ stats = if last
14
+ Kovid.format_country_history_numbers(country).last(last.to_i)
15
+ else
16
+ Kovid.format_country_history_numbers(country)
17
+ end
18
+
19
+ dates = if last
20
+ country['timeline']['cases'].keys.last(last.to_i)
21
+ else
22
+ country['timeline']['cases'].keys
23
+ end
24
+
25
+ unless last
26
+ stats = stats.reject { |stat| stat[0].to_i.zero? && stat[1].to_i.zero? }
27
+ dates = dates.last(stats.count)
28
+ end
29
+
30
+ stats.each_with_index do |val, index|
31
+ val.unshift(Kovid.dateman(dates[index]))
32
+ end.each do |row|
33
+ rows << row
34
+ end
35
+
36
+ if stats.size > 10
37
+ rows << FOOTER_LINE
38
+ rows << DATE_CASES_DEATHS_RECOVERED
39
+ end
40
+
41
+ Terminal::Table.new(
42
+ title: country['country'].upcase,
43
+ headings: headings,
44
+ rows: rows
45
+ )
46
+ end
47
+
48
+ def histogram(country, date_string)
49
+ @date = date_string.split('.')
50
+
51
+ if @date.last.to_i != 20
52
+ Kovid.info_table('Only 2020 histgrams are available.')
53
+ return
54
+ end
55
+
56
+ # From dates where number of !cases.zero?
57
+ country_cases = country['timeline']['cases']
58
+ positive_cases_figures = country_cases.values.reject(&:zero?)
59
+ dates = country_cases.reject { |_k, v| v.zero? }.keys
60
+ data = []
61
+
62
+ # TODO: Refactor
63
+ # Returns array of days.to_i from the date param
64
+ dates = dates.map do |date|
65
+ date.split('/')
66
+ end.select do |date|
67
+ date.last == @date.last
68
+ end.select do |date|
69
+ date.first == @date.first
70
+ end.map do |array|
71
+ array[1]
72
+ end.map(&:to_i).last(positive_cases_figures.count)
73
+
74
+ # Arranges dates and figures in [x,y] for histogram
75
+ # With x being day, y being number of cases
76
+ if dates.empty?
77
+ if @date.first.to_i > Time.now.month
78
+ msgs = [
79
+ 'Seriously...??! 😏', 'Did you just check the future??',
80
+ 'You just checked the future Morgan.',
81
+ 'Knowing too much of your future is never a good thing.'
82
+ ]
83
+
84
+ Kovid.info_table(msgs.sample)
85
+ else
86
+ Kovid.info_table('Check your spelling/No infections for this month.')
87
+ end
88
+
89
+ else
90
+ dates.each_with_index do |val, index|
91
+ data << [val, positive_cases_figures[index]]
92
+ end
93
+ y_range = AsciiCharts::Cartesian.new(
94
+ data, bar: true, hide_zero: true
95
+ ).y_range
96
+
97
+ last_two_y = y_range.last 2
98
+ y_interval = last_two_y.last - last_two_y.first
99
+
100
+ scale("Scale on Y: #{y_interval}:#{(
101
+ y_interval / last_two_y.last.to_f * positive_cases_figures.last
102
+ ).round(2) / y_interval}")
103
+
104
+ puts 'Experimental feature, please report issues.'
105
+
106
+ AsciiCharts::Cartesian.new(data, bar: true, hide_zero: true).draw
107
+ end
108
+ end
109
+ end
110
+ end