A Scriptable widget that shows the amount of people who have received the corona vaccination in Germany
May 6, 2022 · View on GitHub
// Version 1.3.0 // 27.11.2021 // // Variables used by Scriptable. // These must be at the very top of the file. Do not edit. // icon-color: red; icon-glyph: notes-medical; // Mit Caching und Fallback const cacheMinutes = 60; // 60 min const today = new Date(); const neededTotalVaccinations = 83200000; let result; let resultDe; let width = 100; const h = 5;
const colorLightGreen = new Color("#47b881") const colorDarkGreen = new Color("#00783e")
let widget = new ListWidget(); widget.setPadding(6, 12, 8, 12); widget.url = "https://interaktiv.morgenpost.de/corona-impfungen-deutschland-bundeslaender-weltweit/";
await getNumbers(); await createWidget(); Script.setWidget(widget); Script.complete();
if (config.runsInApp) { widget.presentSmall(); }
async function createWidget() {
widget.addSpacer();
const amountFirstPerCent = resultDe.vaccinations1_quota;
const amountSecondPerCent = resultDe.vaccinations2_quota;
const amountBoosterPerCent = resultDe.vaccinations3_quota;
let firstDoseStack = widget.addStack()
firstDoseStack.layoutHorizontally()
let amountFirstText = firstDoseStack.addText("Erstimpfung");
amountFirstText.font = Font.boldSystemFont(12);
firstDoseStack.addSpacer()
let percentFirstText = firstDoseStack.addText(amountFirstPerCent.toLocaleString() + "%")
percentFirstText.font = Font.boldSystemFont(12);
widget.addSpacer(2);
let progressStack = widget.addStack();
progressStack.layoutVertically();
let progressNumberStack = widget.addStack();
progressNumberStack.layoutHorizontally();
const progressText = progressNumberStack.addText((resultDe.vaccinations1).toLocaleString());
progressText.font = Font.mediumSystemFont(10);
progressStack.addImage(createProgress((resultDe.vaccinations1), colorLightGreen));
widget.addSpacer(3)
let secondDoseStack = widget.addStack()
secondDoseStack.layoutHorizontally()
let amountSecondText = secondDoseStack.addText("Vollständig");
amountSecondText.font = Font.boldSystemFont(12);
secondDoseStack.addSpacer()
let percentSecondText = secondDoseStack.addText(amountSecondPerCent.toLocaleString() + "%")
percentSecondText.font = Font.boldSystemFont(12);
widget.addSpacer(2)
let progressStack2 = widget.addStack();
progressStack2.layoutVertically();
let progressNumberStack2 = widget.addStack();
progressNumberStack2.layoutHorizontally();
const progressText2 = progressNumberStack2.addText(resultDe.vaccinations2.toLocaleString());
progressText2.font = Font.mediumSystemFont(10);
progressStack2.addImage(createProgress(resultDe.vaccinations2, colorLightGreen));
widget.addSpacer(3);
let boosterStack = widget.addStack()
boosterStack.layoutHorizontally()
let amountBoosterText = boosterStack.addText("Booster");
amountBoosterText.font = Font.boldSystemFont(12);
boosterStack.addSpacer()
let percentBoosterText = boosterStack.addText(amountBoosterPerCent.toLocaleString() + "%")
percentBoosterText.font = Font.boldSystemFont(12);
widget.addSpacer(2)
let progressStack3 = widget.addStack();
progressStack3.layoutVertically();
let progressNumberStack3 = widget.addStack();
progressNumberStack3.layoutHorizontally();
const progressText3 = progressNumberStack3.addText(resultDe.vaccinations3.toLocaleString());
progressText3.font = Font.mediumSystemFont(10);
progressStack3.addImage(createProgress(resultDe.vaccinations3, colorLightGreen));
widget.addSpacer(6)
let calendarStack = widget.addStack();
const lastUpdateDate = new Date(resultDe.date);
let description = widget.addText("Stand: " + lastUpdateDate.toLocaleDateString());
description.centerAlignText();
description.font = Font.mediumSystemFont(9);
// widget.addSpacer(8)
}
// get images from local storage or download them once
async function getImage(image) {
let fm = FileManager.local();
let dir = fm.documentsDirectory();
let path = fm.joinPath(dir, image);
if (fm.fileExists(path)) {
return fm.readImage(path);
} else {
// download once
let imageUrl;
switch (image) {
case "vac-logo.png":
imageUrl = "https://i.imgur.com/ZsBNT8E.png";
break;
case "calendar-icon.png":
imageUrl = "https://i.imgur.com/Qp8CEFf.png";
break;
default:
console.log(Sorry, couldn't find ${image}.);
}
let req = new Request(imageUrl);
let loadedImage = await req.loadImage();
fm.writeImage(path, loadedImage);
return loadedImage;
}
}
async function getNumbers() { // Set up the file manager. const files = FileManager.local();
// Set up cache
const cachePath = files.joinPath(
files.cacheDirectory(),
"api-cache-covid-vaccination-numbers-mopo"
);
const cacheExists = files.fileExists(cachePath);
const cacheDate = cacheExists ? files.modificationDate(cachePath) : 0;
// Get Data
try {
// If cache exists and it's been less than 60 minutes since last request, use cached data.
if (
cacheExists &&
today.getTime() - cacheDate.getTime() < cacheMinutes * 60 * 1000
) {
console.log("Get from Cache");
result = JSON.parse(files.readString(cachePath));
} else {
console.log("Get from API");
const req2 = new Request(
"https://interaktiv.morgenpost.de/data/corona/rki-vaccination-latest.json"
);
result = await req2.loadJSON();
console.log("Write Data to Cache");
try {
files.writeString(cachePath, JSON.stringify(result));
} catch (e) {
console.log("Creating Cache failed!");
console.log(e);
}
}
} catch (e) {
console.error(e);
if (cacheExists) {
console.log("Get from Cache");
result = JSON.parse(files.readString(cachePath));
} else {
console.log("No fallback to cache possible. Due to missing cache.");
}
}
await setTotalVacNoForGermany(result);
}
async function setTotalVacNoForGermany(result) { for (var i = result.length - 1; i >= 0; i--) { let currentItem = result[i]; if (currentItem["id"] === "de") { resultDe = currentItem; } } }
function createProgress(vacNo, color) { const context = new DrawContext(); context.size = new Size(width, h); context.opaque = false; context.respectScreenScale = true; context.setFillColor(new Color("#d2d2d7")); const path = new Path(); path.addRoundedRect(new Rect(0, 0, width, h), 3, 2); context.addPath(path); context.fillPath(); context.setFillColor(color); const path1 = new Path(); const path1width = (width * vacNo) / neededTotalVaccinations > width ? width : (width * vacNo) / neededTotalVaccinations; path1.addRoundedRect(new Rect(0, 0, path1width, h), 3, 2); context.addPath(path1); context.fillPath();
return context.getImage();
}
// // Bitte bis zum Ende kopieren //