show last updated time
This commit is contained in:
parent
b656adc23d
commit
9c8877397a
35
generate.js
35
generate.js
@ -4,11 +4,13 @@ const path = require('path');
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const parseCsv = require('csv-parse/lib/sync');
|
const parseCsv = require('csv-parse/lib/sync');
|
||||||
const pug = require('pug');
|
const pug = require('pug');
|
||||||
|
const {execSync} = require('child_process');
|
||||||
|
|
||||||
const publicDir = path.join(__dirname, 'public');
|
const publicDir = path.join(__dirname, 'public');
|
||||||
const templatesDir = path.join(__dirname, 'tmpl');
|
const templatesDir = path.join(__dirname, 'tmpl');
|
||||||
const dataDir = path.join(__dirname, 'data');
|
const dataDir = path.join(__dirname, 'data');
|
||||||
const covidDataDir = path.resolve(path.join(__dirname, 'COVID-19', 'csse_covid_19_data'));
|
const covidGitDir = path.join(__dirname, 'COVID-19');
|
||||||
|
const covidDataDir = path.join(covidGitDir, 'csse_covid_19_data');
|
||||||
const timeSeriesDir = path.join(covidDataDir, 'csse_covid_19_time_series');
|
const timeSeriesDir = path.join(covidDataDir, 'csse_covid_19_time_series');
|
||||||
|
|
||||||
const promiseMe = (fn) => {
|
const promiseMe = (fn) => {
|
||||||
@ -45,6 +47,18 @@ const confirmedUSCsv = path.join(timeSeriesDir, 'time_series_covid19_confirmed_U
|
|||||||
const populationStatesCsv = path.join(dataDir, 'SCPRC-EST2019-18+POP-RES.csv');
|
const populationStatesCsv = path.join(dataDir, 'SCPRC-EST2019-18+POP-RES.csv');
|
||||||
const populationCountriesCsv = path.join(dataDir, 'population-world-wikipedia.tsv');
|
const populationCountriesCsv = path.join(dataDir, 'population-world-wikipedia.tsv');
|
||||||
|
|
||||||
|
const lastGlobalDeathsUpdate = execSync(`git -C "${covidGitDir}" log -n 1 --pretty=format:'%ci' "${deathsGlobalCsv}"`, {
|
||||||
|
encoding: 'utf8',
|
||||||
|
});
|
||||||
|
const lastUSDeathsUpdate = execSync(`git -C "${covidGitDir}" log -n 1 --pretty=format:'%ci' "${deathsUSCsv}"`, {
|
||||||
|
encoding: 'utf8',
|
||||||
|
});
|
||||||
|
|
||||||
|
const lastUpdate = new Date(lastGlobalDeathsUpdate > lastUSDeathsUpdate ?
|
||||||
|
lastGlobalDeathsUpdate :
|
||||||
|
lastUSDeathsUpdate
|
||||||
|
);
|
||||||
|
|
||||||
const zeroPad = value => value < 10 ? `0${value}` : value.toString();
|
const zeroPad = value => value < 10 ? `0${value}` : value.toString();
|
||||||
const toSafeName = x => x.replace(/[^A-Za-z]/g, '-').toLowerCase();
|
const toSafeName = x => x.replace(/[^A-Za-z]/g, '-').toLowerCase();
|
||||||
|
|
||||||
@ -519,7 +533,8 @@ const processGlobalDeaths = async () => {
|
|||||||
const worldTmpl = path.join(templatesDir, 'world.pug');
|
const worldTmpl = path.join(templatesDir, 'world.pug');
|
||||||
const worldHtml = pug.renderFile(worldTmpl, {
|
const worldHtml = pug.renderFile(worldTmpl, {
|
||||||
data: worldData,
|
data: worldData,
|
||||||
$title: 'The World'
|
$title: 'The World',
|
||||||
|
lastUpdate,
|
||||||
});
|
});
|
||||||
|
|
||||||
const targetFile = path.join(publicDir, 'index.html');
|
const targetFile = path.join(publicDir, 'index.html');
|
||||||
@ -529,31 +544,37 @@ const processGlobalDeaths = async () => {
|
|||||||
|
|
||||||
const singleCountryTmpl = path.join(templatesDir, 'country.pug');
|
const singleCountryTmpl = path.join(templatesDir, 'country.pug');
|
||||||
const singleStateTmpl = path.join(templatesDir, 'state.pug');
|
const singleStateTmpl = path.join(templatesDir, 'state.pug');
|
||||||
|
|
||||||
|
const countryFn = pug.compileFile(singleCountryTmpl);
|
||||||
|
const stateFn = pug.compileFile(singleStateTmpl);
|
||||||
|
|
||||||
await Promise.all(countryArr.map(async (countryData) => {
|
await Promise.all(countryArr.map(async (countryData) => {
|
||||||
const start = Date.now();
|
const start = Date.now();
|
||||||
const targetFile = path.join(publicDir, 'countries', countryData.safeName + '.html');
|
const targetFile = path.join(publicDir, 'countries', countryData.safeName + '.html');
|
||||||
const countryHtml = pug.renderFile(singleCountryTmpl, {
|
const countryHtml = countryFn({
|
||||||
data: countryData,
|
data: countryData,
|
||||||
$title: countryData.name,
|
$title: countryData.name,
|
||||||
|
lastUpdate,
|
||||||
});
|
});
|
||||||
console.log(`writing to ${targetFile}`);
|
console.log(`writing to ${targetFile}`);
|
||||||
await promiseMe(callback => fs.writeFile(targetFile, countryHtml, callback));
|
await promiseMe(callback => fs.writeFile(targetFile, countryHtml, callback));
|
||||||
console.log(`wrote to ${targetFile} in ${Date.now() - start}ms`);
|
console.log(`wrote to ${targetFile} in ${Date.now() - start}ms`);
|
||||||
|
|
||||||
if (countryData.states.length) {
|
if (countryData.states.length) {
|
||||||
for (const stateData of countryData.states) {
|
await Promise.all(countryData.states.map(async (stateData) => {
|
||||||
if (!stateData.name || !stateData.counties || !stateData.counties.length) {
|
if (!stateData.name || !stateData.counties || !stateData.counties.length) {
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
const start = Date.now();
|
const start = Date.now();
|
||||||
const targetFile = path.join(publicDir, 'countries', countryData.safeName + '-' + stateData.safeName + '.html');
|
const targetFile = path.join(publicDir, 'countries', countryData.safeName + '-' + stateData.safeName + '.html');
|
||||||
const stateHtml = pug.renderFile(singleStateTmpl, {
|
const stateHtml = stateFn({
|
||||||
data: stateData,
|
data: stateData,
|
||||||
$title: stateData.name + ' - ' + countryData.name,
|
$title: stateData.name + ' - ' + countryData.name,
|
||||||
|
lastUpdate,
|
||||||
});
|
});
|
||||||
await promiseMe(callback => fs.writeFile(targetFile, stateHtml, callback));
|
await promiseMe(callback => fs.writeFile(targetFile, stateHtml, callback));
|
||||||
console.log(`wrote to ${targetFile} in ${Date.now() - start}ms`);
|
console.log(`wrote to ${targetFile} in ${Date.now() - start}ms`);
|
||||||
}
|
}));
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -11,5 +11,8 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"serve": "11.3.0"
|
"serve": "11.3.0"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"start": "node_modules/.bin/serve -n -d -l 9999 public"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -146,13 +146,21 @@ html
|
|||||||
!{JSON.stringify(data.timeSeriesDaily.map(x => x.delta))},
|
!{JSON.stringify(data.timeSeriesDaily.map(x => x.delta))},
|
||||||
);
|
);
|
||||||
|
|
||||||
div.container
|
div.container.mt-2
|
||||||
h1 Covid-19 Data
|
h1.text-center Covid-19 Death Data
|
||||||
p.text-muted: em.
|
div.d-flex.justify-content-around.font-italic.small
|
||||||
Data from #[a(href="https://github.com/CSSEGISandData/COVID-19") Johns Hopkins CSSE].
|
div
|
||||||
This page generated from latest data as of #{new Date().toISOString()}.
|
- const generationDate = new Date().toISOString();
|
||||||
|
| Data from #[a(href="https://github.com/CSSEGISandData/COVID-19") Johns Hopkins CSSE]
|
||||||
|
div
|
||||||
|
| Generated: #[time.generation-date(datetime=generationDate title=generationDate)= generationDate]
|
||||||
|
div
|
||||||
|
- const lastUpdateISO = lastUpdate.toISOString();
|
||||||
|
| Data updated: #[time.update-date(datetime=lastUpdateISO title=lastUpdateISO)= lastUpdateISO]
|
||||||
|
|
||||||
div.main-content
|
hr
|
||||||
|
|
||||||
|
div.main-content.mt-4
|
||||||
block main
|
block main
|
||||||
|
|
||||||
script.
|
script.
|
||||||
@ -255,4 +263,12 @@ html
|
|||||||
});
|
});
|
||||||
|
|
||||||
handleHash(window.location.hash);
|
handleHash(window.location.hash);
|
||||||
|
|
||||||
|
const setDate = (selector) => {
|
||||||
|
const node = document.querySelector(selector);
|
||||||
|
node.textContent = new Date(node.getAttribute('datetime')).toLocaleString();
|
||||||
|
};
|
||||||
|
|
||||||
|
setDate('.generation-date');
|
||||||
|
setDate('.update-date');
|
||||||
}());
|
}());
|
||||||
|
Loading…
Reference in New Issue
Block a user