Skip to content

Instantly share code, notes, and snippets.

@mihaerzen
Last active November 28, 2021 15:22
Show Gist options
  • Save mihaerzen/47f732084ea95f2f40f250e9b60a6f5a to your computer and use it in GitHub Desktop.
Save mihaerzen/47f732084ea95f2f40f250e9b60a6f5a to your computer and use it in GitHub Desktop.
/*
* This script shows COVID-19 numbers using sledilnik.org API.
* No guarantee on correctness and completeness of the information provided.
*/
const BASE_API_URL = "https://api.sledilnik.org/api";
// URL to open when pressing on the widget.
const WIDGET_PRESS_URL = "https://covid-19.sledilnik.org";
/**
* @param widget {Widget}
* @param data {{ title: string; value: string; color: Color; footnote?: string }}
*/
function addDataBlock(widget, data) {
const viewStack = widget.addStack();
viewStack.layoutVertically();
const label = viewStack.addText(data.title);
label.font = Font.mediumSystemFont(12);
if (data.footnote !== "") {
let footnote = viewStack.addText(data.footnote);
footnote.font = Font.mediumSystemFont(6);
}
const value = viewStack.addText(data.value);
value.font = Font.mediumSystemFont(20);
value.textColor = data.color;
}
/**
* @param url {string}
* @return {*}
*/
function getJSONResponse(url) {
const req = new Request(url);
return req.loadJSON();
}
/**
* @param semaphoreValues {[number, number]}
* @param value {number}
* @param inverted {boolean}
* @return Color
*/
function getSemaphoreColor(semaphoreValues, value, inverted = false) {
if (value <= semaphoreValues[0]) {
return inverted ? Color.red() : Color.green();
}
if (value <= semaphoreValues[1]) {
return Color.yellow();
}
return inverted ? Color.green() : Color.red();
}
/**
* @param num {number}
* @return {string}
*/
function formatNumber(num) {
return (num).toLocaleString('sl');
}
const widget = new ListWidget();
widget.url = WIDGET_PRESS_URL;
const padding = 16;
widget.setPadding(padding, padding, padding, padding);
const header = widget.addText("🦠 COVID-19");
header.font = Font.mediumSystemFont(14);
const disclaimer = widget.addText("Podatki iz sledilnik.org");
disclaimer.font = Font.mediumSystemFont(6);
widget.addSpacer();
const wrapper = widget.addStack();
wrapper.layoutHorizontally();
const firstRow = wrapper.addStack();
firstRow.layoutVertically();
const apiResponseSummary = await getJSONResponse(`${BASE_API_URL}/summary`);
const casesAvg7Days = Math.round(apiResponseSummary.casesAvg7Days.value);
addDataBlock(firstRow, {
title: "Primeri",
value: formatNumber(casesAvg7Days),
footnote: "povp. 7 dni",
color: getSemaphoreColor([50, 100], casesAvg7Days),
});
firstRow.addSpacer();
const d = new Date();
d.setDate(d.getDate() - 4);
const from = encodeURIComponent(d.toISOString());
const apiResponseHospitals = await getJSONResponse(
`${BASE_API_URL}/hospitals?from=${from}`
);
const lastEntry = apiResponseHospitals.pop();
const icuBedsData = lastEntry.overall.icu;
const icuBedsOccupancy = Math.round(
(icuBedsData.occupied / icuBedsData.total) * 100
);
addDataBlock(firstRow, {
title: "Intenzivna",
value: `${icuBedsOccupancy}%`,
footnote: "Zasedenost",
color: getSemaphoreColor([20, 40], icuBedsOccupancy),
});
wrapper.addSpacer();
const secondRow = wrapper.addStack();
secondRow.layoutVertically();
const vaccinationSummary = apiResponseSummary.vaccinationSummary;
const vaccinationPercentage = vaccinationSummary.subValues.percent;
addDataBlock(secondRow, {
title: "Cepljeni",
value: `${Math.round(vaccinationPercentage)}%`,
footnote: `${formatNumber(vaccinationSummary.value)} 💉💉`,
color: getSemaphoreColor([50, 65], vaccinationPercentage, true),
});
secondRow.addSpacer();
const testsToday = apiResponseSummary.testsToday;
addDataBlock(secondRow, {
title: "PCR testi",
value: formatNumber(Math.round(testsToday.value)),
footnote: `${testsToday.subValues.percent}% pozitivnih`,
color: Color.red(),
});
Script.setWidget(widget);
Script.complete();
widget.presentSmall();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment