From d58e38185e356909e5fc47cf3309d2922279742f Mon Sep 17 00:00:00 2001 From: Alexandra Parker Date: Tue, 17 Mar 2020 15:54:33 -0700 Subject: [PATCH 1/4] add basic CLI support, --emojis flag, [country] positional argument --- app.js | 17 ++-- bin/index.js | 51 ++++++++++- lib/byCountry.js | 17 ++-- lib/corona.js | 14 +-- lib/helpers.js | 21 ++++- package-lock.json | 229 +++++++++++++++++++++++++++++++++++++++++++++- package.json | 3 +- 7 files changed, 320 insertions(+), 32 deletions(-) diff --git a/app.js b/app.js index 9184990..a804a4b 100644 --- a/app.js +++ b/app.js @@ -7,7 +7,7 @@ const port = process.env.PORT || 3001; const { getCountryTable, getJSONData, getJSONDataForCountry } = require('./lib/byCountry'); const { getCompleteTable } = require('./lib/corona'); -const { countryUpperCase } = require('./lib/helpers'); +const { countryUpperCase, lookupCountry } = require('./lib/helpers'); function errorHandler(error, res) { @@ -34,11 +34,10 @@ app.get('/', (req, res) => { }); app.get('/:country', (req, res) => { - const { country } = countryUpperCase(req.params); - let lookupObj = null; + const { country } = req.params; const format = req.query.format ? req.query.format : ''; - if (!country || country === 'All') { + if (!country || 'ALL' === country.toUpperCase()) { if (format.toLowerCase() === 'json') { return getJSONData().then(result => { res.setHeader('Cache-Control', 's-maxage=900'); @@ -53,13 +52,8 @@ app.get('/:country', (req, res) => { }).catch(error => errorHandler(error, res)); } - try { - lookupObj = lookup.byIso(country) - || lookup.byFips(country) - || lookup.byCountry(country); - } catch (error) { - lookupObj = lookup.byFips(country) || lookup.byCountry(country); - } + let lookupObj = lookupCountry(country); + if (!lookupObj) { return res.send(` Country not found. @@ -70,6 +64,7 @@ app.get('/:country', (req, res) => { - /India: for India. `); } + const { iso2 } = lookupObj; if (format.toLowerCase() === 'json') { diff --git a/bin/index.js b/bin/index.js index a5ce8bc..d0403bb 100755 --- a/bin/index.js +++ b/bin/index.js @@ -1,7 +1,56 @@ #!/usr/bin/env node const { getCompleteTable } = require('../lib/corona'); +const { getCountryTable } = require('../lib/byCountry'); +const { lookupCountry } = require('../lib/helpers'); -getCompleteTable() +const {argv} = require('yargs') + .command('$0 [country]', 'show COVID-19 statistics for the world or the given country', yargs => + yargs.positional('country', { + coerce(arg) { + console.log(arg); + if('ALL' === arg.toUpperCase()) { + return 'ALL'; + } + + const country = lookupCountry(arg); + + if(!country) { + throw new Error(`Country '${arg}' not found. + Try full country name or country code. + Ex: + - UK: for United Kingdom + - US: for United States of America. + - India: for India.`); + } + + return country.iso2; + }, + describe: 'which country to show statistics for', + default: 'all', + type: 'string' + }) + ) + .options({ + e: { + alias: 'emojis', + describe: 'enable the use of emojis in the table (may break alignment in some terminals)', + default: false, + type: 'boolean' + }, + c: { + alias: 'color', + describe: 'enable the use of color in the table.', + type: 'boolean' + } + }) + .strict() + .help('help'); + +console.log(argv); + +const {emojis, country} = argv; + +(country === 'all' ? getCompleteTable(argv) : getCountryTable(country, argv)) .then(console.log) .catch(console.error); \ No newline at end of file diff --git a/lib/byCountry.js b/lib/byCountry.js index 9b61952..ecd7fcf 100644 --- a/lib/byCountry.js +++ b/lib/byCountry.js @@ -79,20 +79,20 @@ exports.getJSONDataForCountry = async (countryCode) => { return countryData; } -exports.getCountryTable = async (countryCode) => { +exports.getCountryTable = async (countryCode, {emojis=false}={}) => { const head = [ '', 'State', 'Confirmed', - 'Recovered', - 'Deaths', - 'Active', + `Recovered${emojis ? ' 😀' : ''}`, + `Deaths${emojis ? ' 😞' : ''}`, + `Active${emojis ? ' 😷' : ''}`, 'Mortality %', 'Recovered %', '1 Day ▲', '1 Week ▲', // 'RoG', - // '🏳', + ...( emojis ? ['🏳'] : [] ), ]; const table = new Table({ head, @@ -105,6 +105,11 @@ exports.getCountryTable = async (countryCode) => { const { latest, confirmed, deaths, recovered } = data; const countryData = getDataByState(confirmed, deaths, recovered) .filter(obj => obj.countryCode === countryCode); + + if(countryData.length === 0) { + throw new Error(`Country code ${countryCode} does not match anything in the database.`); + } + const totalStats = getTotalStats(countryData); table.push({ [countryData[0].country]: [ @@ -136,7 +141,7 @@ exports.getCountryTable = async (countryCode) => { getOneDayChange(cd), getOneWeekChange(cd), // getRateOfGrowth(cd), - // getEmoji(cd.countryCode), + ... (emojis ? [countryEmoji] : []) ] table.push({ [rank++]: values }) }); diff --git a/lib/corona.js b/lib/corona.js index 4a84976..f0591b5 100644 --- a/lib/corona.js +++ b/lib/corona.js @@ -79,20 +79,20 @@ function extraStats(dataArr) { ); } -exports.getCompleteTable = async () => { +exports.getCompleteTable = async ({emojis=false}={}) => { const head = [ '', 'Country', 'Confirmed', - 'Recovered', - 'Deaths', - 'Active', + `Recovered${emojis ? ' 😀' : ''}`, + `Deaths${emojis ? ' 😞' : ''}`, + `Active${emojis ? ' 😷' : ''}`, 'Mortality %', 'Recovered %', '1 Day ▲', '1 Week ▲', // 'RoG', - // '🏳', + ...( emojis ? ['🏳'] : [] ), ]; const table = new Table({ head, @@ -117,7 +117,7 @@ exports.getCompleteTable = async () => { getOneDayChange(worldStats), getOneWeekChange(worldStats), // '', - // '🌎' + ... ( emojis ? ['🌎'] : [] ) ] }) let rank = 1; @@ -134,7 +134,7 @@ exports.getCompleteTable = async () => { getOneDayChange(cd), getOneWeekChange(cd), // getRateOfGrowth(cd), - // getEmoji(cd.countryCode), + ... (emojis ? [countryEmoji] : []) ] table.push({ [rank++]: values }) }); diff --git a/lib/helpers.js b/lib/helpers.js index 207bd6f..5730b34 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -3,6 +3,7 @@ const h = require('humanize-number'); const emojiFlags = require('emoji-flags'); const _ = require('lodash'); const moment = require('moment'); +const lookup = require('country-code-lookup'); const e = exports; e.getCountry = (country) => { @@ -145,14 +146,24 @@ e.getTotalStats = (countryData) => { return worldStats; }; -e.countryUpperCase = (countryParams) => { - if(countryParams.country.length > 2 ){ - const country = countryParams.country.toLowerCase().split(' ').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' '); - return { country }; +e.countryUpperCase = country => { + if(country.length > 2){ + return country.toLowerCase().split(/\s+/).map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' '); } - return countryParams; + return country; }; +e.lookupCountry = country => { + country = e.countryUpperCase(country); + try { + return lookup.byIso(country) + || lookup.byFips(country) + || lookup.byCountry(country); + } catch (error) { + return lookup.byFips(country) || lookup.byCountry(country); + } +} + e.footer = (lastUpdated) => ` Stay safe. Stay inside. diff --git a/package-lock.json b/package-lock.json index d85ea6e..86bd30b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "coronavirus-tracker-cli", - "version": "0.2.0", + "version": "0.3.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -305,6 +305,46 @@ } } }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, "clone": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", @@ -435,6 +475,11 @@ "ms": "2.0.0" } }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", @@ -488,6 +533,11 @@ "lodash.find": "3.2.1" } }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -609,6 +659,15 @@ } } }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, "follow-redirects": { "version": "1.5.10", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", @@ -634,6 +693,11 @@ "dev": true, "optional": true }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, "get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", @@ -856,6 +920,14 @@ "package-json": "^4.0.0" } }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, "lodash": { "version": "4.17.15", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", @@ -1179,6 +1251,27 @@ "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", "dev": true }, + "p-limit": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", + "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, "package-json": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", @@ -1196,6 +1289,11 @@ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, "path-is-inside": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", @@ -1313,6 +1411,16 @@ "rc": "^1.0.1" } }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -1391,6 +1499,11 @@ "send": "0.17.1" } }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, "setprototypeof": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", @@ -1654,6 +1767,11 @@ "isexe": "^2.0.0" } }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, "widest-line": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", @@ -1663,6 +1781,46 @@ "string-width": "^2.1.1" } }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, "write-file-atomic": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", @@ -1680,11 +1838,80 @@ "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", "dev": true }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true + }, + "yargs": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", + "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "yargs-parser": { + "version": "18.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.1.tgz", + "integrity": "sha512-KRHEsOM16IX7XuLnMOqImcPNbLVXMNHYAoFc3BKR8Ortl5gzDbtXvvEoGx9imk5E+X1VeNKNlcHr8B8vi+7ipA==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + } + } } } } diff --git a/package.json b/package.json index 89476c8..ae8e90a 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,8 @@ "lodash": "^4.17.15", "moment": "^2.24.0", "morgan": "^1.9.1", - "node-cache": "^5.1.0" + "node-cache": "^5.1.0", + "yargs": "15.3.1" }, "devDependencies": { "nodemon": "^2.0.2" From c94932fab5bd9336e00ddae741198d1ceab23ad2 Mon Sep 17 00:00:00 2001 From: Alexandra Parker Date: Tue, 17 Mar 2020 17:43:03 -0700 Subject: [PATCH 2/4] oops, remove some debugging code --- bin/index.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/bin/index.js b/bin/index.js index d0403bb..dc06c16 100755 --- a/bin/index.js +++ b/bin/index.js @@ -47,10 +47,6 @@ const {argv} = require('yargs') .strict() .help('help'); -console.log(argv); - -const {emojis, country} = argv; - (country === 'all' ? getCompleteTable(argv) : getCountryTable(country, argv)) .then(console.log) .catch(console.error); \ No newline at end of file From c0af963668f009665d5fcd22c02db87bdd099299 Mon Sep 17 00:00:00 2001 From: sagark Date: Thu, 19 Mar 2020 00:12:55 +0530 Subject: [PATCH 3/4] fix changes to country filter on cli, changes to readme --- bin/index.js | 43 +++++++++++++++------------ lib/byCountry.js | 2 +- lib/corona.js | 8 ++--- lib/helpers.js | 2 +- package-lock.json | 75 +++++++++++++++++++++++++++++++++++++++++++++-- package.json | 3 +- readme.md | 46 +++++++++++++++++++---------- 7 files changed, 136 insertions(+), 43 deletions(-) diff --git a/bin/index.js b/bin/index.js index dc06c16..110de9e 100755 --- a/bin/index.js +++ b/bin/index.js @@ -1,32 +1,32 @@ #!/usr/bin/env node - +const yargonaut = require('yargonaut') + .style('green'); +const yargs = require('yargs'); +const chalk = require('chalk'); const { getCompleteTable } = require('../lib/corona'); const { getCountryTable } = require('../lib/byCountry'); const { lookupCountry } = require('../lib/helpers'); -const {argv} = require('yargs') - .command('$0 [country]', 'show COVID-19 statistics for the world or the given country', yargs => +const { argv } = yargs + .command('$0 [country]','Tool to COVID-19 statistics for the world or the given country', yargs => yargs.positional('country', { coerce(arg) { - console.log(arg); - if('ALL' === arg.toUpperCase()) { + if ('ALL' === arg.toUpperCase()) { return 'ALL'; } - const country = lookupCountry(arg); - - if(!country) { - throw new Error(`Country '${arg}' not found. - Try full country name or country code. - Ex: - - UK: for United Kingdom - - US: for United States of America. - - India: for India.`); + if (!country) { + let error = `Country '${arg}' not found.\n`; + error += 'Try full country name or country code.\n'; + error += 'Ex:\n'; + error += '- UK: for United Kingdom \n'; + error += '- US: for United States of America.\n'; + error += '- Italy: for Italy.\n'; + throw new Error(chalk.red.bold(error)); } - return country.iso2; }, - describe: 'which country to show statistics for', + describe: 'Filter table by country', default: 'all', type: 'string' }) @@ -34,19 +34,24 @@ const {argv} = require('yargs') .options({ e: { alias: 'emojis', - describe: 'enable the use of emojis in the table (may break alignment in some terminals)', + describe: 'Show emojis in table', default: false, type: 'boolean' }, c: { alias: 'color', - describe: 'enable the use of color in the table.', + describe: 'Show colors formatted output', type: 'boolean' } }) .strict() .help('help'); -(country === 'all' ? getCompleteTable(argv) : getCountryTable(country, argv)) +const { emojis, country } = argv; +( + country === 'ALL' + ? getCompleteTable(emojis) + : getCountryTable(country, emojis) +) .then(console.log) .catch(console.error); \ No newline at end of file diff --git a/lib/byCountry.js b/lib/byCountry.js index ecd7fcf..197dd0c 100644 --- a/lib/byCountry.js +++ b/lib/byCountry.js @@ -79,7 +79,7 @@ exports.getJSONDataForCountry = async (countryCode) => { return countryData; } -exports.getCountryTable = async (countryCode, {emojis=false}={}) => { +exports.getCountryTable = async (countryCode, emojis = false) => { const head = [ '', 'State', diff --git a/lib/corona.js b/lib/corona.js index f0591b5..917215f 100644 --- a/lib/corona.js +++ b/lib/corona.js @@ -79,11 +79,11 @@ function extraStats(dataArr) { ); } -exports.getCompleteTable = async ({emojis=false}={}) => { +exports.getCompleteTable = async (emojis = false) => { const head = [ '', 'Country', - 'Confirmed', + `Confirmed ${emojis ? ' ✅': ''}`, `Recovered${emojis ? ' 😀' : ''}`, `Deaths${emojis ? ' 😞' : ''}`, `Active${emojis ? ' 😷' : ''}`, @@ -117,7 +117,7 @@ exports.getCompleteTable = async ({emojis=false}={}) => { getOneDayChange(worldStats), getOneWeekChange(worldStats), // '', - ... ( emojis ? ['🌎'] : [] ) + ...( emojis ? ['🌎'] : [] ) ] }) let rank = 1; @@ -134,7 +134,7 @@ exports.getCompleteTable = async ({emojis=false}={}) => { getOneDayChange(cd), getOneWeekChange(cd), // getRateOfGrowth(cd), - ... (emojis ? [countryEmoji] : []) + ...(emojis ? [countryEmoji] : []) ] table.push({ [rank++]: values }) }); diff --git a/lib/helpers.js b/lib/helpers.js index 5730b34..e3d1c07 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -162,7 +162,7 @@ e.lookupCountry = country => { } catch (error) { return lookup.byFips(country) || lookup.byCountry(country); } -} +}; e.footer = (lastUpdated) => ` diff --git a/package-lock.json b/package-lock.json index 86bd30b..933035a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -556,8 +556,7 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "etag": { "version": "1.8.1", @@ -626,6 +625,11 @@ } } }, + "figlet": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.3.0.tgz", + "integrity": "sha512-f7A8aOJAfyehLJ7lQ6rEA8WJw7kOk3lfWRi5piSjkzbK5YkI5sqO8eiLHz1ehO+DM0QYB85i8VfA6XIGUbU1dg==" + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -747,6 +751,21 @@ "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", "dev": true }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + } + } + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -1284,6 +1303,11 @@ "semver": "^5.1.0" } }, + "parent-require": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parent-require/-/parent-require-1.0.0.tgz", + "integrity": "sha1-dGoWdjgIOoYLDu9nMssn7UbDKXc=" + }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -1849,6 +1873,53 @@ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true }, + "yargonaut": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/yargonaut/-/yargonaut-1.1.4.tgz", + "integrity": "sha512-rHgFmbgXAAzl+1nngqOcwEljqHGG9uUZoPjsdZEs1w5JW9RXYzrSvH/u70C1JE5qFi0qjsdhnUX/dJRpWqitSA==", + "requires": { + "chalk": "^1.1.1", + "figlet": "^1.1.1", + "parent-require": "^1.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, "yargs": { "version": "15.3.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", diff --git a/package.json b/package.json index ae8e90a..6926344 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "coronavirus-tracker-cli", - "version": "0.3.0", + "version": "0.4.0", "description": "track conronavirus cases from cli", "main": "./lib/corona.js", "bin": { @@ -29,6 +29,7 @@ "moment": "^2.24.0", "morgan": "^1.9.1", "node-cache": "^5.1.0", + "yargonaut": "^1.1.4", "yargs": "15.3.1" }, "devDependencies": { diff --git a/readme.md b/readme.md index 460e16b..a2b0cbf 100644 --- a/readme.md +++ b/readme.md @@ -51,31 +51,31 @@ npm install coronavirus-tracker-cli -g corona ```` -**Top 10** - -Note: This command will cause colored output to be discarded. +**With emojis** ````sh -# Grep the rank of 10 and the 23 lines preceding it -corona | grep -B 23 ' 10 ' +corona -e ```` -**Your country** +**Filter by country** + +````sh +corona italy +```` -Note: These commands will cause colored output to be discarded. +**Disable colors** -- Replace the `US` part of the command with your country code. -- If you want to also see the `World` stats, replace the `3` with a `5` ````sh -# sed the first 3 (or 5) lines; your country; bottom table border -corona | sed -n '1,3p;/\(US\)/p;/╚═/p' +corona --colors=false ```` -Or, get your country within context of your rank +**Top 10** (Working on native command) + +Note: This command will cause colored output to be discarded. + ````sh -# grep with 2 lines of context for each result -# output the 'World' stats and headers; the country stats; the bottom table border -corona | grep --color=none -C 2 -e 'World' -e '\(US\)' -e 'Stay' +# Grep the rank of 10 and the 23 lines preceding it +corona | grep -B 23 ' 10 ' ```` ### ToDos @@ -86,6 +86,22 @@ corona | grep --color=none -C 2 -e 'World' -e '\(US\)' -e 'Stay' * Add growth rate. (linear regression) * Add latest updates from reddit / twitter. +### Contributors + +``` + project : curl-corona + lines : 2821 + authors : + 2343 sagark 83.1% + 293 Alexandra Parker 10.4% + 120 Not Committed Yet 4.3% + 30 Lucas Fernandez Nicolau 1.1% + 25 Shelton Koskie 0.9% + 6 Mo'men Tawfik 0.2% + 3 XhmikosR 0.1% + 1 CyberDracula 0.0% +``` + ### Other Regional Trackers. * [Italy](http://opendatadpc.maps.arcgis.com/apps/opsdashboard/index.html#/b0c68bce2cce478eaac82fe38d4138b1) From e1c1404dcc56079b8f66aeba19c9376c3e31608d Mon Sep 17 00:00:00 2001 From: sagark Date: Thu, 19 Mar 2020 00:16:08 +0530 Subject: [PATCH 4/4] added contributors to readme --- now.json | 2 +- readme.md | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/now.json b/now.json index 3cdd750..0571a9d 100644 --- a/now.json +++ b/now.json @@ -3,7 +3,7 @@ "builds": [ { "src": "*.js", - "use": "@now/node-server" + "use": "@now/node" } ], "routes": [ diff --git a/readme.md b/readme.md index a2b0cbf..889f342 100644 --- a/readme.md +++ b/readme.md @@ -54,7 +54,7 @@ corona **With emojis** ````sh -corona -e +corona --emojis ```` **Filter by country** @@ -90,11 +90,10 @@ corona | grep -B 23 ' 10 ' ``` project : curl-corona - lines : 2821 + lines : 2837 authors : - 2343 sagark 83.1% - 293 Alexandra Parker 10.4% - 120 Not Committed Yet 4.3% + 2479 Sagar Karira 87.4% + 293 Alexandra Parker 10.3% 30 Lucas Fernandez Nicolau 1.1% 25 Shelton Koskie 0.9% 6 Mo'men Tawfik 0.2%