Skip to content
Permalink
Browse files

API for daily timeseries

  • Loading branch information
amodm committed Mar 16, 2020
1 parent ce0a13b commit 9ec472b9021fb1dea084c134f3ff9a1fb109b28a
Showing with 50 additions and 4 deletions.
  1. +2 −1 README.md
  2. +3 −1 index.js
  3. +43 −1 stats.js
  4. +2 −1 store.js
@@ -3,7 +3,8 @@
API for COVID-19 stats in India, sourced from [the official source](https://www.mohfw.gov.in/)

## API
* Stats: https://api.rootnet.in/covid19-in/stats
* Stats: https://api.rootnet.in/covid19-in/stats/latest
* Stats as a daily series: https://api.rootnet.in/covid19-in/stats/daily
* Contact & helpline: https://api.rootnet.in/covid19-in/contacts
* Refresh the data from source (maintainer only) https://api.rootnet.in/covid19-in/refresh

@@ -1,6 +1,6 @@
import { refreshFromSource } from "./refresh";
import { getContacts } from "./contacts";
import { getCaseCounts } from "./stats";
import { getCaseCounts, getCaseCountsTimeseries } from "./stats";

addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
@@ -20,5 +20,7 @@ const ROUTE_PREFIX = "/covid19-in";
const routeHandlers = {
'/contacts': getContacts,
'/stats': getCaseCounts,
'/stats/latest': getCaseCounts,
'/stats/daily': getCaseCountsTimeseries,
'/refresh': refreshFromSource
};
@@ -8,6 +8,44 @@ import { fetchTimestamps, successResponse } from "./api";
export async function getCaseCounts() {
const tsPromise = fetchTimestamps();
const regionalCaseCounts = await Store.get(STORE_KEYS.CASE_COUNTS, "json");

return successResponse(createCaseCountRecord(regionalCaseCounts), tsPromise);
}

/**
* Get case counts as a daily time series
*/
export async function getCaseCountsTimeseries() {
const tsPromise = fetchTimestamps();

const dayToKey = {};
let cursor = undefined;
while (true) {
const keysResponse = await Store.list(STORE_KEYS.CASE_COUNTS + "/", cursor);
for (let i=0; i<keysResponse.keys.length; i++) {
const key = keysResponse.keys[i].name;
const day = getDayFromRecordKey(key);
const existingKey = dayToKey[day];
if (!existingKey || existingKey.localeCompare(key) < 0) dayToKey[day] = key;
}
if (keysResponse.list_complete) break;
else cursor = keysResponse.cursor;
}

const recordKeys = Object.values(dayToKey);
const records = await Promise.all(recordKeys.map((k) => Store.get(k, "json")));

const timeseries = [];
for (let i=0; i<recordKeys.length; i++) {
const recordForDay = createCaseCountRecord(records[i]);
timeseries.push({day: getDayFromRecordKey(recordKeys[i]), ...recordForDay});
}
timeseries.sort((x,y) => x.day.localeCompare(y.day));

return successResponse(timeseries, tsPromise);
}

function createCaseCountRecord(regionalCaseCounts) {
const summaryCounts = {
"total": 0,
"confirmedCasesIndian": 0,
@@ -24,5 +62,9 @@ export async function getCaseCounts() {
}
summaryCounts["total"] = summaryCounts["confirmedCasesIndian"] + summaryCounts["confirmedCasesForeign"];

return successResponse({ "summary": summaryCounts, "regional": regionalCaseCounts }, tsPromise);
return { "summary": summaryCounts, "regional": regionalCaseCounts };
}

function getDayFromRecordKey(key) {
return key.split('/')[1].substr(0, 10);
}
@@ -1,4 +1,5 @@
export const Store = {
get: async (key, type='text') => COVID19.get(key, type),
put: async (key, value) => COVID19.put(key, value)
put: async (key, value) => COVID19.put(key, value),
list: async (prefix, cursor=undefined) => COVID19.list({ prefix, cursor })
};

0 comments on commit 9ec472b

Please sign in to comment.