-
-
Save achisto/ebccd305226218f1cbd01540213403c3 to your computer and use it in GitHub Desktop.
// Forked from https://gist.github.com/marco79cgn/23ce08fd8711ee893a3be12d4543f2d2 | |
// Based on the code at 24 Oct 2020 00:24 | |
// | |
// Displays the amount of flour that is still available. | |
// Product numbers taken from a search for "Weizenmehl": https://www.dm.de/search?query=weizenmehl&searchType=product | |
// | |
// Icon made by Freepik from www.flaticon.com and modified by achisto | |
// | |
let country = 'de' | |
let storeId = 251 | |
let grain = 'Weizen' | |
let type = '1050' | |
if (!config.runsInWidget) { | |
} else { | |
const params = args.widgetParameter ? args.widgetParameter.split(",") : undefined | |
country = params[0] | |
storeId = params[1] | |
grain = params[2] | |
type = params[3] | |
} | |
let typeName; | |
let typeId; | |
// // // Mehl-Sorten dan DE // // // | |
// | |
// Weizen | |
// 550 459912,488334 | |
// 1050 468120 | |
// Vollkorn 468178,706590 | |
// | |
// Dinkel | |
// 1050 468119 | |
// 630 461923 | |
// Vollkorn 467198 | |
// | |
// Roggen | |
// Vollkorn 468121,704854 | |
// | |
// Hafer | |
// glutenfrei 721676 | |
// | |
// Buchweizen | |
// vollkorn 468168 | |
// | |
// | |
// // // Mehl-Sorten dan AT // // // | |
// | |
// Weizen | |
// 550 | |
// 1050 | |
// Vollkorn | |
// | |
// Dinkel | |
// 1050 | |
// 630 | |
// Vollkorn | |
// | |
// Roggen | |
// Vollkorn | |
// | |
// Hafer | |
// glutenfrei | |
// | |
// Buchweizen | |
// vollkorn | |
// | |
// | |
if (grain === "Weizen") { | |
if (type === "550") { | |
typeId = '459912,488334' | |
typeName = 'Weizen 550' | |
} | |
if (type === "1050") { | |
typeId = '468120' | |
typeName = 'Weizen 1050' | |
} | |
if (type === "Vollkorn") { | |
typeId = '468178,706590' | |
typeName = 'Weizen Voll' | |
} | |
} | |
if (grain === "Dinkel") { | |
if (type === "1050") { | |
typeId = '468119' | |
typeName = 'Dinkel 1050' | |
} | |
if (type === "630") { | |
typeId = '461923' | |
typeName = 'Dinkel 630' | |
} | |
if (type === "Vollkorn") { | |
typeId = '467198' | |
typeName = 'Dinkel Voll' | |
} | |
} | |
if (grain === "Roggen") { | |
typeId = '468121,704854' | |
typeName = 'Roggen Voll' | |
} | |
if (grain === "Hafer") { | |
typeId = '468121,704854' | |
typeName = 'Hafer gluten' | |
} | |
const widget = new ListWidget() | |
const storeInfo = await fetchStoreInformation() | |
const storeCapacity = await fetchAmountOfPaper() | |
await createWidget() | |
// used for debugging if script runs inside the app | |
if (!config.runsInWidget) { | |
await widget.presentSmall() | |
} | |
Script.setWidget(widget) | |
Script.complete() | |
// build the content of the widget | |
async function createWidget() { | |
widget.addSpacer(4) | |
const logoImg = await getImage('dm-logo.png') | |
widget.setPadding(10, 10, 10, 10) | |
const titleFontSize = 12 | |
const detailFontSize = 36 | |
const logoStack = widget.addStack() | |
logoStack.addSpacer(86) | |
const logoImageStack = logoStack.addStack() | |
logoStack.layoutHorizontally() | |
logoImageStack.backgroundColor = new Color("#ffffff", 1.0) | |
logoImageStack.cornerRadius = 8 | |
const wimg = logoImageStack.addImage(logoImg) | |
wimg.imageSize = new Size(40, 40) | |
wimg.rightAlignImage() | |
widget.addSpacer() | |
const icon = await getImage('flour.png') | |
let row = widget.addStack() | |
row.layoutHorizontally() | |
row.addSpacer(2) | |
const iconImg = row.addImage(icon) | |
iconImg.imageSize = new Size(40, 40) | |
row.addSpacer(13) | |
let column = row.addStack() | |
column.layoutVertically() | |
const paperText = column.addText(typeName) | |
paperText.font = Font.mediumRoundedSystemFont(13) | |
const packageCount = column.addText(storeCapacity.toString()) | |
packageCount.font = Font.mediumRoundedSystemFont(22) | |
if (storeCapacity < 30) { | |
packageCount.textColor = new Color("#E50000") | |
} else { | |
packageCount.textColor = new Color("#00CD66") | |
} | |
widget.addSpacer(4) | |
const row2 = widget.addStack() | |
row2.layoutVertically() | |
const street = row2.addText(storeInfo.address.street) | |
street.font = Font.regularSystemFont(11) | |
const zipCity = row2.addText(storeInfo.address.zip + " " + storeInfo.address.city) | |
zipCity.font = Font.regularSystemFont(11) | |
let currentTime = new Date().toLocaleTimeString('de-DE', { hour: "numeric", minute: "numeric" }) | |
let currentDay = new Date().getDay() | |
let isOpen | |
if (currentDay > 0) { | |
const todaysOpeningHour = storeInfo.openingHours[currentDay-1].timeRanges[0].opening | |
const todaysClosingHour = storeInfo.openingHours[currentDay-1].timeRanges[0].closing | |
const range = [todaysOpeningHour, todaysClosingHour]; | |
isOpen = isInRange(currentTime, range) | |
} else { | |
isOpen = false | |
} | |
let shopStateText | |
if (isOpen) { | |
shopStateText = row2.addText('Geöffnet') | |
shopStateText.textColor = new Color("#00CD66") | |
} else { | |
shopStateText = row2.addText('Geschlossen') | |
shopStateText.textColor = new Color("#E50000") | |
} | |
shopStateText.font = Font.mediumSystemFont(11) | |
} | |
// fetches the amount of toilet paper packages | |
async function fetchAmountOfPaper() { | |
let url | |
let counter = 0 | |
if (country.toLowerCase() === 'at') { | |
// Austria | |
const array = ["178498", "178489", "223485", "253667", "63675", "178516"] | |
for (var i = 0; i < array.length; i++) { | |
let currentItem = array[i] | |
url = 'https://products.dm.de/store-availability/AT/products/dans/' + currentItem + '/stocklevel?storeNumbers=' + storeId | |
let req = new Request(url) | |
let apiResult = await req.loadJSON() | |
if (req.response.statusCode == 200) { | |
counter += apiResult.storeAvailability[0].stockLevel | |
} | |
} | |
} else { | |
// Germany | |
url = 'https://products.dm.de/store-availability/DE/availability?dans=' + typeId + '&storeNumbers=' + storeId | |
const req = new Request(url) | |
const apiResult = await req.loadJSON() | |
for (var i in apiResult.storeAvailabilities) { | |
counter += apiResult.storeAvailabilities[i][0].stockLevel | |
} | |
} | |
return counter | |
} | |
// fetches information of the configured store, e.g. opening hours, address etc. | |
async function fetchStoreInformation() { | |
let url | |
if (country.toLowerCase() === 'at') { | |
url = 'https://store-data-service.services.dmtech.com/stores/item/at/' + storeId | |
widget.url = 'https://www.dm.at/search?query=mehl&searchType=product' | |
} else { | |
url = 'https://store-data-service.services.dmtech.com/stores/item/de/' + storeId | |
widget.url = 'https://www.dm.de/search?query=mehl&searchType=product' | |
} | |
let req = new Request(url) | |
let apiResult = await req.loadJSON() | |
return apiResult | |
} | |
// checks whether the store is currently open or closed | |
function isInRange(value, range) { | |
return value >= range[0] && value <= range[1]; | |
} | |
// get images from local filestore 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 'dm-logo.png': | |
imageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/5/50/Dm_Logo.svg/300px-Dm_Logo.svg.png" | |
break | |
case 'flour.png': | |
imageUrl = "https://i.imgur.com/gwWtMWn.png" | |
break | |
default: | |
console.log(`Sorry, couldn't find ${image}.`); | |
} | |
let iconImage = await loadImage(imageUrl) | |
fm.writeImage(path, iconImage) | |
return iconImage | |
} | |
} | |
// helper function to download an image from a given url | |
async function loadImage(imgUrl) { | |
const req = new Request(imgUrl) | |
return await req.loadImage() | |
} | |
// end of script |
Tolles Widget! Könntest du es noch so anpassen, dass die genaue Anzahl für die jeweiligen Mehlsorten und -typen angezeigt wird? Vielleicht auch so, dass man im Skript die gewünschten Sorten auswählen kann. Beispielsweise Weizen 550, Weizen 1050, Weizen Vollkorn und Roggen Vollkorn.
Tolles Widget! Könntest du es noch so anpassen, dass die genaue Anzahl für die jeweiligen Mehlsorten und -typen angezeigt wird? Vielleicht auch so, dass man im Skript die gewünschten Sorten auswählen kann. Beispielsweise Weizen 550, Weizen 1050, Weizen Vollkorn und Roggen Vollkorn.
Das ist theoretisch möglich, mir fehlen aber vermutlich die Coding-Skills - schaue später mal, ob ich mir das herleiten kann!
Schöner Fork. Wurde auch oft nachgefragt.
Darf ich mir dein Mehl-Icon für das Klopapier widget „ausleihen“? Natürlich mit Verweis auf Freepik und dich.
Schöner Fork. Wurde auch oft nachgefragt.
Darf ich mir dein Mehl-Icon für das Klopapier widget „ausleihen“? Natürlich mit Verweis auf Freepik und dich.
Hey! Klar, ist ja nicht meins und bewusst alles öffentlich hier, bedien‘ dich gerne :)
Habe das Script eben mit den aktuellen Änderungen von @marco79cgn geupdated. Bitte für ein komplettes Changelog bei seinem Script vorbei schauen.
Tolles Widget! Könntest du es noch so anpassen, dass die genaue Anzahl für die jeweiligen Mehlsorten und -typen angezeigt wird? Vielleicht auch so, dass man im Skript die gewünschten Sorten auswählen kann. Beispielsweise Weizen 550, Weizen 1050, Weizen Vollkorn und Roggen Vollkorn.
Das Widget unterstützt jetzt die Auswahl einer Mehlsorte:
Modified to display the remaining amount of flour and similiar products. Based on the original script by @marco79cgn.
Please note: I am not the original widget-creator neither do I know much about JavaScript. I just modified the original code to fit my needs of showing the amount of flour instead of toilet paper. I'm able to help setting yourself up with the widget but unfortunately can't provide tech support or add more functionality, the later just exceeds my skills.
Mehl-Sorten DE
These are all the types of flour supported by the widget (all types I could find in the web store):
Weizen
-- 550
-- 1050
-- Vollkorn
Dinkel
-- 1050
-- 630
-- Vollkorn
Roggen
-- Vollkorn
Hafer
-- glutenfrei
Buchweizen
-- Vollkorn
Select the type of flour by entering widget parameters, all separated by ",". You need to enter 4 parameters (see GIF at the end of this comment on how to enter parameters):
The structure is
country,store,grain,type
. Example:de,251,Weizen,1050
Entering these parameters results in a widget looking likes this:
Updates
24.10.2020, 15:38
You're now able to select the type of flour by entering four parameters. Currently only works for german stores!
24.10.2020, 13:07
Updated the complete code to represent the current version by @marco79cgn from 24.10.2020, 00:24. Please refer to his changelog for information about changes he made to the code. Some of the major things:
Please copy & paste the complete code into Scriptable for the changes to be effective