Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 57 additions & 46 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const {
getJSONDataForCountry,
} = require('./lib/byCountry');
const { getCompleteTable, getGraph } = require('./lib/corona');
const { lookupCountry, htmlTemplate } = require('./lib/helpers');
const { lookupCountry, htmlTemplate, footer } = require('./lib/helpers');
const { getLiveUpdates } = require('./lib/reddit.js');
const { getWorldoMetersTable } = require('./lib/worldoMeters.js');
const { helpContent, countryNotFound } = require('./lib/constants');
Expand All @@ -18,12 +18,17 @@ const app = express();
const port = process.env.PORT || 3001;
const IS_CURL_RE = /\bcurl\b/im;

function errorHandler(error, res) {
function errorHandler(error, req, res) {
console.error(error);
return res.status(500).send(htmlTemplate(`
const body = `
I am sorry. Something went wrong. Please report it\n
${error.message}
`));
${footer(new Date)}
`;
if (req.isCurl) {
return body;
}
return res.status(500).send(htmlTemplate(body));
}

app.set('json escape', true);
Expand All @@ -47,58 +52,60 @@ app.use(helmet.referrerPolicy({ policy: 'strict-origin-when-cross-origin' }));
app.use(morgan(':remote-addr :remote-user :method :url :status :res[content-length] - :response-time ms'));
app.use((req, res, next) => {
res.setHeader('Cache-Control', 'no-cache');
req.isCurl = IS_CURL_RE.test(req.headers['user-agent']);
next();
});

app.get('/', (req, res) => {
const isCurl = IS_CURL_RE.test(req.headers['user-agent']);
const isCurl = req.isCurl;
const format = req.query.format ? req.query.format : '';
const minimal = req.query.minimal === 'true';
const emojis = req.query.emojis === 'true';
const top = req.query.top ? Number(req.query.top) : 1000;
const source = req.query.source ? Number(req.query.source) : 1;
const source = req.query.source ? Number(req.query.source) : 2;

if (source === 1) {
if (format.toLowerCase() === 'json') {
return getJSONData().then(result => {
return res.json(result);
}).catch(error => errorHandler(error, req, res));
}

if (source === 2) {
return getWorldoMetersTable({ isCurl, emojis, minimal, top, format})
return getCompleteTable({ isCurl, emojis, minimal, top })
.then(result => {
return res.send(result);
}).catch(error => errorHandler(error, res));
}).catch(error => errorHandler(error, req, res));
}

if (format.toLowerCase() === 'json') {
return getJSONData().then(result => {
return res.json(result);
}).catch(error => errorHandler(error, res));
}

return getCompleteTable({ isCurl, emojis, minimal, top })
return getWorldoMetersTable({ isCurl, emojis, minimal, top, format})
.then(result => {
return res.send(result);
}).catch(error => errorHandler(error, res));
}).catch(error => errorHandler(error, req, res));

});

app.get('/updates', (req, res) => {
const isCurl = IS_CURL_RE.test(req.headers['user-agent']);
const isCurl = req.isCurl;
const format = req.query.format ? req.query.format : '';

if (format.toLowerCase() === 'json') {
return getLiveUpdates({ json: true, isCurl }).then(result => {
return res.json(result);
}).catch(error => errorHandler(error, res));
}).catch(error => errorHandler(error, req, res));
}

return getLiveUpdates({ json: false, isCurl }).then(result => {
return res.send(result);
}).catch(error => errorHandler(error, res));
}).catch(error => errorHandler(error, req, res));
});

app.get(['/:country/graph', '/graph'], (req, res) => {
const { country } = req.params;
const isCurl = IS_CURL_RE.test(req.headers['user-agent']);
const isCurl = req.isCurl;
if (!country) {
return getGraph({ isCurl })
.then(result => res.send(result))
.catch(error => errorHandler(error, res));
.catch(error => errorHandler(error, req, res));
}
const lookupObj = lookupCountry(country);

Expand All @@ -107,11 +114,11 @@ app.get(['/:country/graph', '/graph'], (req, res) => {
}
return getGraph({countryCode: lookupObj.iso2, isCurl })
.then(result => res.send(result))
.catch(error => errorHandler(error, res));
.catch(error => errorHandler(error, req, res));
});

app.get('/help', (req, res) => {
const isCurl = IS_CURL_RE.test(req.headers['user-agent']);
const isCurl = req.isCurl;
if (!isCurl) {
return res.send(htmlTemplate(helpContent));
}
Expand All @@ -121,23 +128,41 @@ app.get('/help', (req, res) => {

app.get('/:country', (req, res) => {
const { country } = req.params;
const isCurl = IS_CURL_RE.test(req.headers['user-agent']);
const isCurl = req.isCurl;
const format = req.query.format ? req.query.format : '';
const minimal = req.query.minimal === 'true';
const emojis = req.query.emojis === 'true';
const source = req.query.source ? Number(req.query.source) : 1;
const source = req.query.source ? Number(req.query.source) : 2;

if (!country || country.toUpperCase() === 'ALL') {
if (format.toLowerCase() === 'json') {
return getJSONData().then(result => {
return getWorldoMetersTable({ isCurl, emojis, minimal, format }).then(result => {
return res.json(result);
}).catch(error => errorHandler(error, res));
}).catch(error => errorHandler(error, req, res));
}

return getWorldoMetersTable({ isCurl, emojis, minimal })
.then(result => {
return res.send(result);
}).catch(error => errorHandler(error, req, res));
}
if (source === 1) {
const lookupObj = lookupCountry(country);

if (!lookupObj) {
return res.status(404).send(countryNotFound(isCurl));
}
const { iso2 } = lookupObj;

return getCompleteTable({ isCurl, emojis, minimal })
if (format.toLowerCase() === 'json') {
return getJSONDataForCountry(iso2).then(result => {
return res.json(result);
}).catch(error => errorHandler(error, req, res));
}
return getCountryTable({ countryCode: iso2, isCurl, emojis, minimal })
.then(result => {
return res.send(result);
}).catch(error => errorHandler(error, res));
}).catch(error => errorHandler(error, req, res));
}

const lookupObj = lookupCountry(country);
Expand All @@ -146,26 +171,12 @@ app.get('/:country', (req, res) => {
return res.status(404).send(countryNotFound(isCurl));
}


const { iso2 } = lookupObj;

if (source === 2) {
return getWorldoMetersTable({ countryCode: iso2, isCurl, emojis, minimal, format })
.then(result => {
return res.send(result);
}).catch(error => errorHandler(error, res));
}

if (format.toLowerCase() === 'json') {
return getJSONDataForCountry(iso2).then(result => {
return res.json(result);
}).catch(error => errorHandler(error, res));
}

return getCountryTable({ countryCode: iso2, isCurl, emojis, minimal })
return getWorldoMetersTable({ countryCode: iso2, isCurl, emojis, minimal, format })
.then(result => {
return res.send(result);
}).catch(error => errorHandler(error, res));
}).catch(error => errorHandler(error, req, res));
});

app.listen(port, () => console.log(`Running on ${port}`));
14 changes: 7 additions & 7 deletions bin/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const { argv } = yargs
s: {
alias: 'source',
describe: 'fetch data from other source',
default: 1,
default: 2,
type: 'int'
},
e: {
Expand Down Expand Up @@ -74,15 +74,15 @@ const { argv } = yargs
.help('help');

argv.countryCode = argv.country;
if (argv.source === 2) {
getWorldoMetersTable(argv).then(console.log).catch(console.error);
}
else if (argv.graph === true) {
getGraph(argv.countryCode).then(console.log).catch(console.error);
} else {
if (argv.source === 1) {
(
argv.country === 'ALL'
? getCompleteTable(argv)
: getCountryTable(argv)
).then(console.log).catch(console.error);
}
else if (argv.graph === true) {
getGraph(argv.countryCode).then(console.log).catch(console.error);
} else {
getWorldoMetersTable(argv).then(console.log).catch(console.error);
}
4 changes: 4 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## Version 0.9.0

* Changed default source to worldoMeters. i.e source 2 is now default

## Version 0.8.0

* Added confirmed cases graphs `corona -g` or `corona italy -g`
Expand Down
6 changes: 5 additions & 1 deletion lib/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,12 @@ exports.getWorldoMetersData = async (countryCode = 'ALL') => {
critical: 0,
});

result.data.forEach(obj => obj.countryCode = countryNameMap[obj.country]);
result.data.forEach(obj => {
obj.countryCode = countryNameMap[obj.country];
obj.confirmed = obj.cases;
});
worldStats.casesPerOneMillion = (worldStats.cases / 7794).toFixed(2);
worldStats.confirmed = worldStats.cases;
let finalData = result.data;
if (countryCode && countryCode !== 'ALL') {
finalData = finalData.filter(obj => obj.countryCode === countryCode);
Expand Down
31 changes: 25 additions & 6 deletions lib/constants.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { htmlTemplate } = require('./helpers');
const { htmlTemplate, footer } = require('./helpers');
exports.countryNameMap = {
China: 'CN',
UK: 'GB',
Expand Down Expand Up @@ -181,6 +181,20 @@ exports.countryNameMap = {
'Dominican Republic': 'DO',
'Burkina Faso': 'BF',
Uzbekistan: 'UZ',
'Madagascar': 'MG',
'Uganda': 'UG',
'Zimbabwe': 'ZW',
'Dominica': 'DM',
'Laos': 'LA',
'Myanmar': 'MM',
'Belize': 'BZ',
'Eritrea': 'ER',
'Grenada': 'GD',
'Mozambique': 'MZ',
'Papua New Guinea': 'PG',
'Syria': 'SY',
'Timor-Leste': 'TL',
'Turks and Caicos': 'TC'
};

exports.helpContent = `
Expand All @@ -201,6 +215,7 @@ https://corona-stats.online

---------------------------------------------------------------------------------

(DEFAULT SOURCE)
# Source 2 stats - updated every 15 minutes from worldometers.info
https://corona-stats.online?source=2

Expand All @@ -213,12 +228,14 @@ https://corona-stats.online/[countryCode]
https://corona-stats.online/[countryName]

## Example: From source 1
https://corona-stats.online/Italy
https://corona-stats.online/UK
https://corona-stats.online/Italy?source=1
https://corona-stats.online/UK?source=1

## Example: From source 2
## Example: From source 2 (DEFAULT)
https://corona-stats.online/italy
https://corona-stats.online/italy?source=2
https://corona-stats.online/UK?source=2
https://corona-stats.online/UK

---------------------------------------------------------------------------------

Expand All @@ -227,7 +244,7 @@ https://corona-stats.online/UK?source=2
## Example:
https://corona-stats.online?minimal=true
https://corona-stats.online/Italy?minimal=true (with country filter)
https://corona-stats.online?minimal=true&source=2 (with source)
https://corona-stats.online?minimal=true&source=1 (with source)
https://corona-stats.online/uk?source=2&minimal=true (with source and country)

---------------------------------------------------------------------------------
Expand All @@ -246,7 +263,7 @@ https://corona-stats.online/uk?source=2&json=true (with source and countr

## Example:
https://corona-stats.online?top=25
https://corona-stats.online?source=2&top=10 (with source)
https://corona-stats.online?source=1&top=10 (with source)
https://corona-stats.online/uk?minimal=true&top=20 (with minimal)


Expand Down Expand Up @@ -275,6 +292,8 @@ exports.countryNotFound = (isCurl) => {
- /UK: for United Kingdom
- /US: for United States of America.
- /Italy: for Italy.

${footer(new Date)}
`;
return isCurl ? body : htmlTemplate(body);
};
27 changes: 22 additions & 5 deletions lib/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,9 @@ ${chalk.greenBright('Twitter')}: ${chalk.blueBright('https://twitter.com/ekrysis

${chalk.magentaBright('Last Updated on:')} ${moment(lastUpdated).utc().format('DD-MMM-YYYY HH:MM')} UTC

${chalk.red.bold('NEW REALTIME UPDATES')}: ${chalk.blueBright('https://corona-stats.online?source=2')}
${chalk.red.bold('UPDATE')}: ${chalk.blueBright('Source 2 is now default source')}
${chalk.red.bold('JHU Source 1 table')}: ${chalk.blueBright('https://corona-stats.online?source=1')}
${chalk.red.bold('HELP')}: ${chalk.blueBright('https://corona-stats.online/help')}
${chalk.bgBlueBright.bold('API was down because JHU has removed recovered from their data :( ')}: ${chalk.blueBright('https://github.com/CSSEGISandData/COVID-19/issues/1250')}
`;

e.getTableBorders = minimal => {
Expand Down Expand Up @@ -235,9 +235,7 @@ e.extraStats = (dataArr) => {
return dataArr.map(obj => {
return {
...obj,
active: e.calActive(obj),
mortalityPer: e.calMortalityPer(obj),
recoveredPer: e.calRecoveredPer(obj)
};
});
};
Expand All @@ -250,18 +248,37 @@ e.htmlTemplate = (body) => {
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Coronavirus Tracker</title>
<style>
*, ::after, ::before {
box-sizing: border-box;
}
body {
background-color: #0d0208;
color: #00ff41;
font-size: 1rem;
font-weight: 400;
line-height: normal;
margin: 0;
text-align: left;
}
.container {
margin-right: auto;
margin-left: auto;
padding-right: 10px;
padding-left: 10px;
width: 100%;
}
pre {
display: block;
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
overflow: auto;
white-space: pre;
}
</style>
</head>
<body>
<pre>${body}</pre>
<div class="container">
<pre>${body}</pre>
</div>
</body>
</html>
`;
Expand Down
Loading