diff --git a/.github/charts.gif b/.github/charts.gif new file mode 100644 index 0000000..dde98b0 Binary files /dev/null and b/.github/charts.gif differ diff --git a/changelog.md b/changelog.md index cc81651..0f892e8 100644 --- a/changelog.md +++ b/changelog.md @@ -29,12 +29,88 @@ I have released a video course to help you become a better developer β€” +### RELEASE: [4.1.2](https://github.com/ahmadawais/corona-cli/compare/4.1.1...4.1.2) + +![πŸ› FIX:](https://img.shields.io/badge/-FIX-gray.svg?colorB=ff6347) + +> πŸ› Lingo [`d468c4a`](https://github.com/ahmadawais/corona-cli/commit/d468c4a9f5fe24e60f6d4d6ea549086085e94b67)
+ +
+ +[![hr](https://raw.githubusercontent.com/ahmadawais/stuff/master/images/git/hr.png)](/) + +
+ +### RELEASE: [4.1.1](https://github.com/ahmadawais/corona-cli/compare/4.1.0...4.1.1) + +![πŸ‘Œ IMPROVE:](https://img.shields.io/badge/-IMPROVEMENT-gray.svg?colorB=39AA54) + +> πŸ‘Œ Help [`dbe69e5`](https://github.com/ahmadawais/corona-cli/commit/dbe69e5a8025b307bd93b12f10588e3a8797effd)
+ +![πŸ“– DOC:](https://img.shields.io/badge/-DOCS-gray.svg?colorB=978CD4) + +> πŸ“– Changelog [`abc1e61`](https://github.com/ahmadawais/corona-cli/commit/abc1e61398b5d812b2a1efb28ebb8949bb6cd6fb)
+ +
+ +[![hr](https://raw.githubusercontent.com/ahmadawais/stuff/master/images/git/hr.png)](/) + +
+ +### RELEASE: [4.1.0](https://github.com/ahmadawais/corona-cli/compare/4.0.0...4.1.0) + +![πŸ› FIX:](https://img.shields.io/badge/-FIX-gray.svg?colorB=ff6347) + +> πŸ› Worldwide cases [`09e21ba`](https://github.com/ahmadawais/corona-cli/commit/09e21ba64bf37248be7bdb899fbf9fc4111cbada)
+ +![πŸ“– DOC:](https://img.shields.io/badge/-DOCS-gray.svg?colorB=978CD4) + +> πŸ“– Changelog [`6dd4396`](https://github.com/ahmadawais/corona-cli/commit/6dd439625d8a5f150d893e15f513a88ff8ae1062)
+ +
+ +[![hr](https://raw.githubusercontent.com/ahmadawais/stuff/master/images/git/hr.png)](/) + +
+ +### RELEASE: [4.0.0](https://github.com/ahmadawais/corona-cli/compare/3.8.6...4.0.0) + +![πŸ“¦ NEW:](https://img.shields.io/badge/-NEW-gray.svg?colorB=3778FF) + +> πŸ“¦ Chart for country queries (#66) thanks @ozanerturk [`9dff8fe`](https://github.com/ahmadawais/corona-cli/commit/9dff8fe28aa303bbdacccd510a23b6f44e688d33)
+> πŸ“¦ Charts [`6d5b21a`](https://github.com/ahmadawais/corona-cli/commit/6d5b21aba98cb35a143ebd33a1152a9bd232e606)
+> πŸ“¦ FOSS Funding [`7a5c07d`](https://github.com/ahmadawais/corona-cli/commit/7a5c07d29e48659335467f7270ea2e48ad77cc4f)
+ +![πŸ‘Œ IMPROVE:](https://img.shields.io/badge/-IMPROVEMENT-gray.svg?colorB=39AA54) + +> πŸ‘Œ Node check [`079da16`](https://github.com/ahmadawais/corona-cli/commit/079da16f8acb61a43e0ca64556e9c2a0bee9c876)
+> πŸ‘Œ Charts [`964b1c4`](https://github.com/ahmadawais/corona-cli/commit/964b1c42363d2807b5bee908dd88d2db9b9c2c66)
+> πŸ‘Œ Chart [`86b889a`](https://github.com/ahmadawais/corona-cli/commit/86b889a9210216f7074efe26b2c498b40d526461)
+ +![πŸ› FIX:](https://img.shields.io/badge/-FIX-gray.svg?colorB=ff6347) + +> πŸ› Sorting China [`e3c67e5`](https://github.com/ahmadawais/corona-cli/commit/e3c67e529f1ede28b0263e642af67a60a213182e)
+ +![πŸ“– DOC:](https://img.shields.io/badge/-DOCS-gray.svg?colorB=978CD4) + +> πŸ“– Changelog [`bd32c4e`](https://github.com/ahmadawais/corona-cli/commit/bd32c4e81fcf249f4ee222c2db869482b53b779e)
+ +
+ +[![hr](https://raw.githubusercontent.com/ahmadawais/stuff/master/images/git/hr.png)](/) + +
+ ### RELEASE: [3.8.6](https://github.com/ahmadawais/corona-cli/compare/3.8.5...3.8.6) ![πŸ“¦ NEW:](https://img.shields.io/badge/-NEW-gray.svg?colorB=3778FF) > πŸ“¦ Keywords [`02916cd`](https://github.com/ahmadawais/corona-cli/commit/02916cd10d2e93da0ce5e24c2e80a000b5251e6b)
+![πŸ“– DOC:](https://img.shields.io/badge/-DOCS-gray.svg?colorB=978CD4) + +> πŸ“– Changelog [`148004a`](https://github.com/ahmadawais/corona-cli/commit/148004a2dbca4b05579ea9d7eed6fe9cd277fe71)
+
[![hr](https://raw.githubusercontent.com/ahmadawais/stuff/master/images/git/hr.png)](/) diff --git a/package.json b/package.json index 698f077..ebb4224 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "corona-cli", - "version": "3.8.6", + "version": "4.1.2", "description": "Track the Coronavirus disease (COVID-19).", "license": "MIT", "repository": "ahmadawais/corona-cli", @@ -53,6 +53,7 @@ "cli-table3": "^0.5.1", "cli-welcome": "^1.4.0", "comma-number": "^2.0.1", + "is-online": "^8.2.1", "lodash.orderby": "^4.6.0", "log-symbols": "^3.0.0", "meow": "^6.1.0", diff --git a/readme.md b/readme.md index 7d8ba50..a9995c4 100644 --- a/readme.md +++ b/readme.md @@ -19,6 +19,7 @@ Track the Coronavirus disease (COVID-19) or the Novel Coronavirus Strain. - 🀯 Active daily reporting of your country's COVID-19 statistics - πŸ‡ΊπŸ‡Έ Get US States data for Coronavirus disease reports across the US - πŸ—ƒοΈ Data: Country, Cases, Deaths, Recovered, Active, Critical, Per Million +- πŸ“ˆ Charts: Plot statistics in the form of line charts both regular and logarithmic - πŸ“Ÿ Sort: `cases`, `cases-today`, `deaths`, `deaths-today`, `recovered`, `active`, `critical`, `per-million`
@@ -113,6 +114,20 @@ corona -s active -r [![πŸ“Ÿ](./.github/sort.gif)](./../../) +### Charts: Regular & Logarithmic + +```sh +# Print a country line chart. +corona usa --chart +corona usa --c + +# Print a country line chart with logarithmic data. +corona china --chart --log +corona china -c -g +``` + +[![πŸ“Ÿ](./.github/charts.gif)](./../../) + ### Limit the output ````sh diff --git a/utils/cli.js b/utils/cli.js index 0efdad0..93e1916 100644 --- a/utils/cli.js +++ b/utils/cli.js @@ -10,19 +10,23 @@ module.exports = meow( ${green(`corona`)} ${cyan(``)} ${yellow(`[--option]`)} Commands - ${cyan(`country-name`)} Get data for a given country - ${cyan(`states`)} Get data for all USA states + ${cyan(`country-name`)} Get data for a given country + ${cyan(`states`)} Get data for all USA states Options - ${yellow(`--xcolor`)}, ${yellow(`-x`)} Single colored output - ${yellow(`--sort`)}, ${yellow(`-s`)} Sort data by type - ${yellow(`--reverse`)}, ${yellow(`-r`)} Reverse print order - ${yellow(`--limit`)}, ${yellow(`-l`)} Print only N entries + ${yellow(`--sort`)}, ${yellow(`-s`)} Sort data by type + ${yellow(`--reverse`)}, ${yellow(`-r`)} Reverse print order + ${yellow(`--limit`)}, ${yellow(`-l`)} Print only N entries + ${yellow(`--chart`)}, ${yellow(`-c`)} Print chart for a country + ${yellow(`--log`)}, ${yellow(`-g`)} Print logarithmic chart + ${yellow(`--xcolor`)}, ${yellow(`-x`)} Single colored output + ${yellow(`--minimal`)}, ${yellow(`-m`)} Minimalistic CLI output Examples ${green(`corona`)} ${cyan(`china`)} ${green(`corona`)} ${cyan(`states`)} - ${green(`corona`)} ${yellow(`-x`)} + ${green(`corona`)} ${cyan(`china`)} ${yellow(`--chart`)} + ${green(`corona`)} ${cyan(`china`)} ${yellow(`--chart`)} ${yellow(`--log`)} ${green(`corona`)} ${yellow(`--sort`)} ${cyan(`cases-today`)} ${green(`corona`)} ${yellow(`-s`)} ${cyan(`critical`)} @@ -61,7 +65,8 @@ module.exports = meow( }, log: { type: 'boolean', - default: false + default: false, + alias: 'g' }, minimal: { type: 'boolean', diff --git a/utils/fetchAndHandleErrors.js b/utils/fetchAndHandleErrors.js new file mode 100644 index 0000000..3ff005a --- /dev/null +++ b/utils/fetchAndHandleErrors.js @@ -0,0 +1,31 @@ +const to = require('await-to-js').default; +const axios = require('axios'); +const isOnline = require('is-online'); +const handleError = require('cli-handle-error'); + +/** + * Handles errors and return Promise object with `error and `response` + * @param {string} url URL to fetch from + */ + +module.exports = async url => { + const [[error, response], online] = await Promise.all([ + to(axios.get(url)), + isOnline({ timeout: 3000 }) + ]); + + //Handle offline error + if (!online) + handleError( + ` Looks like you're offline.`, + new Error('offline'), + false, + true + ); + + //Handle every other error! + if (online && error) + handleError(`API is down, try again later.`, error, false, true); + + return { error, response }; +}; diff --git a/utils/getCountries.js b/utils/getCountries.js index 31cf9e5..fb477a0 100644 --- a/utils/getCountries.js +++ b/utils/getCountries.js @@ -1,12 +1,10 @@ -const axios = require('axios'); const chalk = require('chalk'); const cyan = chalk.cyan; const dim = chalk.dim; const comma = require('comma-number'); const { sortingKeys } = require('./table.js'); -const to = require('await-to-js').default; -const handleError = require('cli-handle-error'); const orderBy = require('lodash.orderby'); +const fetchAndHandleErrors = require('./fetchAndHandleErrors.js'); module.exports = async ( spinner, @@ -16,22 +14,15 @@ module.exports = async ( { sortBy, limit, reverse } ) => { if (!countryName && !states) { - const [err, response] = await to( - axios.get(`https://corona.lmao.ninja/countries`) + const { response } = await fetchAndHandleErrors( + `https://corona.lmao.ninja/countries` ); - handleError(`API is down, try again later.`, err, false); - let allCountries = response.data; - // Limit. - allCountries = allCountries.slice(0, limit); + let allCountries = response.data; // Sort & reverse. const direction = reverse ? 'asc' : 'desc'; - allCountries = orderBy( - allCountries, - [sortingKeys[sortBy]], - [direction] - ); + allCountries = orderBy(allCountries, [sortingKeys[sortBy]], [direction]); // Push selected data. allCountries.map((oneCountry, count) => { diff --git a/utils/getCountry.js b/utils/getCountry.js index 74aa818..29f108c 100644 --- a/utils/getCountry.js +++ b/utils/getCountry.js @@ -1,17 +1,14 @@ const chalk = require('chalk'); -const axios = require('axios'); const sym = require('log-symbols'); const comma = require('comma-number'); const red = chalk.red; -const to = require('await-to-js').default; -const handleError = require('cli-handle-error'); +const fetchAndHandleErrors = require('./fetchAndHandleErrors.js'); module.exports = async (spinner, table, states, countryName, options) => { if (countryName && !states && !options.chart) { - const [err, response] = await to( - axios.get(`https://corona.lmao.ninja/countries/${countryName}`) + const { response } = await fetchAndHandleErrors( + `https://corona.lmao.ninja/countries/${countryName}` ); - handleError(`API is down, try again later.`, err, false); const thisCountry = response.data; if (response.data === 'Country not found') { diff --git a/utils/getCountryChart.js b/utils/getCountryChart.js index 868000a..cd6b0d0 100644 --- a/utils/getCountryChart.js +++ b/utils/getCountryChart.js @@ -1,17 +1,14 @@ const comma = require('comma-number'); -const handleError = require('cli-handle-error'); -const axios = require('axios'); -const to = require('await-to-js').default; const moment = require('moment'); const blessed = require('blessed'); const contrib = require('blessed-contrib'); +const fetchAndHandleErrors = require('./fetchAndHandleErrors.js'); module.exports = async (spinner, countryName, { chart, log }) => { if (countryName && chart) { - const [err, response] = await to( - axios.get(`https://corona.lmao.ninja/v2/historical/${countryName}`) + const { response } = await fetchAndHandleErrors( + `https://corona.lmao.ninja/v2/historical/${countryName}` ); - handleError(`API is down, try again later.`, err, false); if (response.status === 404) { spinner.stopAndPersist(); console.log( @@ -21,7 +18,7 @@ module.exports = async (spinner, countryName, { chart, log }) => { ); process.exit(0); } - const logScale = x => x; + let logScale = x => x; if (log) { logScale = x => (x === 0 ? undefined : Math.log(x)); } diff --git a/utils/getStates.js b/utils/getStates.js index 4eaee68..af58d35 100644 --- a/utils/getStates.js +++ b/utils/getStates.js @@ -1,19 +1,16 @@ -const axios = require('axios'); const chalk = require('chalk'); const cyan = chalk.cyan; const dim = chalk.dim; const comma = require('comma-number'); const { sortingStateKeys } = require('./table.js'); -const to = require('await-to-js').default; -const handleError = require('cli-handle-error'); const orderBy = require('lodash.orderby'); +const fetchAndHandleErrors = require('./fetchAndHandleErrors.js'); module.exports = async (spinner, table, states, { sortBy, limit, reverse }) => { if (states) { - const [err, response] = await to( - axios.get(`https://corona.lmao.ninja/states`) + const { response } = await fetchAndHandleErrors( + `https://corona.lmao.ninja/states` ); - handleError(`API is down, try again later.`, err, false); let allStates = response.data; // Limit. diff --git a/utils/getWorldwide.js b/utils/getWorldwide.js index c37582c..76b44cc 100644 --- a/utils/getWorldwide.js +++ b/utils/getWorldwide.js @@ -1,29 +1,30 @@ -const axios = require('axios'); const comma = require('comma-number'); -const to = require('await-to-js').default; -const handleError = require('cli-handle-error'); +const fetchAndHandleErrors = require('./fetchAndHandleErrors.js'); module.exports = async (table, states) => { - const [err, all] = await to(axios.get(`https://corona.lmao.ninja/all`)); - handleError(`API is down, try again later.`, err, false); + const { response: all } = await fetchAndHandleErrors( + `https://corona.lmao.ninja/all` + ); + let data = Object.values(all.data); data = data.map(d => comma(d)); + // Don't print coz for states we still need that data of updated data. if (!states) { table.push([ - `β€”`, + `β†’`, `Worldwide`, - data[0], - `β€”`, - data[1], - `β€”`, - data[2], - `β€”`, - `β€”`, - `β€”` + comma(allData.cases), + comma(allData.todayCases), + comma(allData.deaths), + comma(allData.todayDeaths), + comma(allData.recovered), + comma(allData.active), + comma(allData.critical), + comma(allData.casesPerOneMillion) ]); } - const lastUpdated = Date(data[3]); + const lastUpdated = Date(allData.updated); return lastUpdated; };