-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathupdate-data-de.js
178 lines (161 loc) · 5.59 KB
/
update-data-de.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
const fetch = require("node-fetch");
const fs = require("fs");
const CSVtoJSON = require("csvtojson");
// Do not remove this import! We want to load paramConfig.json at build time so that if somebody
// has accidentally broken the JSON by manual editing, build process is halted.
const paramConfig = require("./src/paramConfig.json");
const lastMidnight = new Date().setUTCHours(0, 0, 0, 0);
const cutoffDays = 3; // For example, 3 means "cut off today + 3 previous days".
function notTooRecent(dateTime) {
const daysFromLastMidnight = Math.round(
(new Date(dateTime).getTime() - new Date(lastMidnight).getTime()) / 86400000
);
return daysFromLastMidnight < -cutoffDays;
}
function verifyDataNotStale(lastSeenDay, days) {
// Verify that API is not serving stale data which is missing recent days completely.
if (lastSeenDay !== days - 1) {
process.exit(1);
}
}
function write(relativePath, content) {
fs.writeFile(relativePath, content, function (err) {
if (err) {
console.log(err);
process.exit(1); // Prevent build if disk write fails
}
});
}
async function callbackRtEstimate(response) {
response
.text()
.then((text) => {
const splitted = text.split(/\r?\n/);
const lastLine = splitted[splitted.length - 2];
const lastRtEstimateValue = Number.parseFloat(lastLine.split(",")[1]);
const lastRtEstimateDate = lastLine.split(",")[0];
console.log("Last Rt estimate:", lastRtEstimateValue, lastRtEstimateDate);
if (lastRtEstimateValue > 0 && lastRtEstimateValue < 10) {
write(
"data/latest_Rt.csv",
`date,Rt\n${lastRtEstimateDate},${lastRtEstimateValue}`
);
} else {
process.exit(1); // Prevent build if estimate out of bounds.
}
})
.catch((error) => {
console.log(error);
process.exit(1); // Prevent build if parse fails
});
}
async function callbackRtPNG(response) {
response
.buffer()
.then((blob) => {
write("public/latest_Rt.png", blob);
})
.catch((error) => {
console.log(error);
process.exit(1); // Prevent build if parse fails
});
}
function convertToJSON() {
return CSVtoJSON()
.fromFile("data/rki_raw_cases_and_deaths.csv")
.then((rkiData) => {
return rkiData;
})
.catch((err) => {
console.log(err);
});
}
function initializeParsedArray(epidemyStartDate, days) {
var parsed = {};
parsed["epidemyStartDate"] = epidemyStartDate;
parsed["days"] = days;
const thingsToCount = ["newConfirmedCases", "cumulativeConfirmedCases", "newConfirmedDeaths", "cumulativeConfirmedDeaths"];
for (var i = 0; i < thingsToCount.length; i++) {
const thing = thingsToCount[i];
parsed[thing] = {};
for (var day = 0; day < days; day++) {
parsed[thing][day] = 0;
}
}
return parsed
}
function countCases(parsed, json, oldColumnName, newColumnName, epidemyStartDate){
var lastSeenDay = 0
for (var i=0; i<json.length; i++) {
const c = json[i]
const dateTime = new Date(Date.parse(c["date"])).setUTCHours(0,0,0,0);
if (notTooRecent(dateTime)) {
// Exclude today's data by assumption that it is missing entries.
const day = daysFromZero(dateTime, epidemyStartDate)
parsed[newColumnName][day] = json[day][oldColumnName]
lastSeenDay = Math.max(day, lastSeenDay)
}
}
return parsed
}
function daysFromZero(dateTime, epidemyStartDate) {
return Math.round(
(new Date(dateTime).getTime() - new Date(epidemyStartDate).getTime()) / 86400000
);
}
async function callbackRKIConfirmedCasesAndDeaths(response) {
response
.text()
.then((text) => {
// Keep the original CSV for debugging purposes.
write("data/rki_raw_cases_and_deaths.csv", text);
return convertToJSON();
})
.then((json) => {
console.log(json);
const epidemyStartDate = new Date( Date.parse(json[0]["date"])).setUTCHours(0, 0, 0, 0);
const days = daysFromZero(lastMidnight, epidemyStartDate) - cutoffDays;
var parsed = initializeParsedArray(epidemyStartDate, days);
parsed = countCases(parsed, json, 'newinfections', 'newConfirmedCases',epidemyStartDate)
parsed = countCases(parsed, json, 'infections', 'cumulativeConfirmedCases', epidemyStartDate)
parsed = countCases(parsed, json, 'newdeaths', 'newConfirmedDeaths', epidemyStartDate)
parsed = countCases(parsed, json, 'deaths', 'cumulativeConfirmedDeaths',epidemyStartDate)
write("data/rki_parsed.json", JSON.stringify(parsed))
});
}
async function fetchOrExit(url, callback, additionalDataForCallback) {
return await fetch(url)
.then((response) => {
if (!response.ok) {
console.log(response);
process.exit(1); // Prevent build if fetch fails
}
return response;
})
.then(function (response) {
return callback(response, additionalDataForCallback);
})
.catch((error) => {
console.log(error);
process.exit(1); // Prevent build if parse fails
});
}
function fetchRtEstimateData() {
fetchOrExit(
"https://corosim-de-r-value.s3.eu-central-1.amazonaws.com/latest_Rt.csv",
callbackRtEstimate
);
fetchOrExit(
"https://corosim-de-r-value.s3.eu-central-1.amazonaws.com/latest_Rt.png",
callbackRtPNG
);
}
function fetchRKIData() {
fetchOrExit(
"https://corosim-de-r-value.s3.eu-central-1.amazonaws.com/confirmed_infections_and_deaths.csv",
callbackRKIConfirmedCasesAndDeaths
);
// Please see the callback function; it initiates a second fetch to a different file.
}
fetchRtEstimateData()
fetchRKIData()