Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
iOS Widget, das über Scriptable.app die Anzahl an dmBio-Mehl-Packungen in dm-Drogerien anzeigt
// dmBio Mehl-Widget
//
// Original work from:
// dm Klopapier Widget
// Copyright (C) 2020 by marco79 <marco79cgn@gmail.com>
//
// Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
// IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
// OF THIS SOFTWARE.
//
let storeId = 251
let param = args.widgetParameter
if (param != null && param.length > 0) {
storeId = param
}
const widget = new ListWidget()
const storeInfo = await fetchStoreInformation()
const storeCapacityW550 = await fetchAmountOfW550()
const storeCapacityW1050 = await fetchAmountOfW1050()
const storeCapacityWeizenVK = await fetchAmountOfWeizenVK()
const storeCapacityD630 = await fetchAmountOfD630()
const storeCapacityD1050 = await fetchAmountOfD1050()
const storeCapacityDinkelVK = await fetchAmountOfDinkelVK()
const storeCapacityRoggenVK = await fetchAmountOfRoggenVK()
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() {
const logoImg = await getImage('dm-logo.png')
widget.setPadding(8,8,8,8)
const titleFontSize = 12
const detailFontSize = 36
let titelzeile = widget.addStack()
titelzeile.layoutVertically()
const titel = titelzeile.addText("Mehl bei dm")
titel.font = Font.boldSystemFont(14)
widget.addSpacer(1)
// weizen 550
let row = widget.addStack()
row.layoutHorizontally()
let column = row.addStack()
column.layoutVertically()
const W550Text = column.addText("Weizenmehl 550: ")
W550Text.font = Font.mediumRoundedSystemFont(11)
const W550Count = row.addText(storeCapacityW550.toString())
W550Count.font = Font.mediumRoundedSystemFont(11)
if (storeCapacityW550 < 6) {
W550Count.textColor = new Color("#E50000")
} else {
W550Count.textColor = new Color("#00CD66")
}
// widget.addSpacer(4)
// weizen 1050
let row2 = widget.addStack()
row2.layoutHorizontally()
let column2 = row2.addStack()
column2.layoutVertically()
const W1050Text = column2.addText("Weizenmehl 1050: ")
W1050Text.font = Font.mediumRoundedSystemFont(11)
const W1050Count = row2.addText(storeCapacityW1050.toString())
W1050Count.font = Font.mediumRoundedSystemFont(11)
if (storeCapacityW1050 < 6) {
W1050Count.textColor = new Color("#E50000")
} else {
W1050Count.textColor = new Color("#00CD66")
}
// widget.addSpacer(4)
// weizen vk
let row3 = widget.addStack()
row3.layoutHorizontally()
let column3 = row3.addStack()
column3.layoutVertically()
const WeizenVKText = column3.addText("Weizen-Vollkorn: ")
WeizenVKText.font = Font.mediumRoundedSystemFont(11)
const WeizenVKCount = row3.addText(storeCapacityWeizenVK.toString())
WeizenVKCount.font = Font.mediumRoundedSystemFont(11)
if (storeCapacityWeizenVK < 6) {
WeizenVKCount.textColor = new Color("#E50000")
} else {
WeizenVKCount.textColor = new Color("#00CD66")
}
// widget.addSpacer(4)
// dinkel 630
let row4 = widget.addStack()
row4.layoutHorizontally()
let column4 = row4.addStack()
column4.layoutVertically()
const D630Text = column4.addText("Dinkelmehl 630: ")
D630Text.font = Font.mediumRoundedSystemFont(11)
const D630Count = row4.addText(storeCapacityD630.toString())
D630Count.font = Font.mediumRoundedSystemFont(11)
if (storeCapacityD630 < 6) {
D630Count.textColor = new Color("#E50000")
} else {
D630Count.textColor = new Color("#00CD66")
}
// widget.addSpacer(4)
// dinkel 1050
let row5 = widget.addStack()
row5.layoutHorizontally()
let column5 = row5.addStack()
column5.layoutVertically()
const D1050Text = column5.addText("Dinkelmehl 1050: ")
D1050Text.font = Font.mediumRoundedSystemFont(11)
const D1050Count = row5.addText(storeCapacityD1050.toString())
D1050Count.font = Font.mediumRoundedSystemFont(11)
if (storeCapacityD1050 < 6) {
D1050Count.textColor = new Color("#E50000")
} else {
D1050Count.textColor = new Color("#00CD66")
}
// widget.addSpacer(4)
// dinkel vk
let row6 = widget.addStack()
row6.layoutHorizontally()
let column6 = row6.addStack()
column6.layoutVertically()
const DinkelVKText = column6.addText("Dinkel-Vollkorn: ")
DinkelVKText.font = Font.mediumRoundedSystemFont(11)
const DinkelVKCount = row6.addText(storeCapacityDinkelVK.toString())
DinkelVKCount.font = Font.mediumRoundedSystemFont(11)
if (storeCapacityDinkelVK < 6) {
DinkelVKCount.textColor = new Color("#E50000")
} else {
DinkelVKCount.textColor = new Color("#00CD66")
}
// widget.addSpacer(4)
// roggen vk
let row7= widget.addStack()
row7.layoutHorizontally()
let column7 = row7.addStack()
column7.layoutVertically()
const RoggenVKText = column7.addText("Roggen-Vollkorn: ")
RoggenVKText.font = Font.mediumRoundedSystemFont(11)
const RoggenVKCount = row7.addText(storeCapacityRoggenVK.toString())
RoggenVKCount.font = Font.mediumRoundedSystemFont(11)
if (storeCapacityRoggenVK < 6) {
RoggenVKCount.textColor = new Color("#E50000")
} else {
RoggenVKCount.textColor = new Color("#00CD66")
}
widget.addSpacer(2)
// shop info & logo
let infologo = widget.addStack()
infologo.layoutHorizontally()
let infos = infologo.addStack()
infos.layoutVertically()
const street = infos.addText(storeInfo.address.street)
street.font = Font.regularSystemFont(8)
const zipCity = infos.addText(storeInfo.address.zip + " " + storeInfo.address.city)
zipCity.font = Font.regularSystemFont(8)
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 = infos.addText('Geöffnet')
shopStateText.textColor = new Color("#00CD66")
} else {
shopStateText = infos.addText('Geschlossen')
shopStateText.textColor = new Color("#E50000")
}
shopStateText.font = Font.mediumSystemFont(8)
infologo.addSpacer(20)
const logoImageStack = infologo.addStack()
logoImageStack.layoutVertically()
logoImageStack.addSpacer(0)
const logoImageStack2 = logoImageStack.addStack()
logoImageStack2.backgroundColor = new Color("#ffffff", 1.0)
logoImageStack2.cornerRadius = 6
const logo = logoImageStack2.addImage(logoImg)
logo.imageSize = new Size(25, 25)
logo.rightAlignImage()
}
// fetches the amount of weizen 550 packages
async function fetchAmountOfW550() {
let url
let counter = 0
url = 'https://products.dm.de/store-availability/DE/availability?dans=459912&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 the amount of weizen 1050 packages
async function fetchAmountOfW1050() {
let url
let counter = 0
url = 'https://products.dm.de/store-availability/DE/availability?dans=468120&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 the amount of weizen vollkorn packages
async function fetchAmountOfWeizenVK() {
let url
let counter = 0
url = 'https://products.dm.de/store-availability/DE/availability?dans=468178&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 the amount of dinkel 630 packages
async function fetchAmountOfD630() {
let url
let counter = 0
url = 'https://products.dm.de/store-availability/DE/availability?dans=461923&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 the amount of dinkel 1050 packages
async function fetchAmountOfD1050() {
let url
let counter = 0
url = 'https://products.dm.de/store-availability/DE/availability?dans=468119&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 the amount of dinkel vk packages
async function fetchAmountOfDinkelVK() {
let url
let counter = 0
url = 'https://products.dm.de/store-availability/DE/availability?dans=467198&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 the amount of roggen packages
async function fetchAmountOfRoggenVK() {
let url
let counter = 0
url = 'https://products.dm.de/store-availability/DE/availability?dans=468121&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
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
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
@veraverto

This comment has been minimized.

Copy link
Owner Author

@veraverto veraverto commented Oct 30, 2020

screenshit

Fork, der die Verfügbarkeit verschiedener dmBio-Mehlsorten anzeigt.

Leider wird das Logo nicht korrekt rechts am Rand ausgerichtet, das bekomme ich nicht richtig hin. Wenn der Straßenname zu lang ist, wird deshalb das Widget breiter wie es sein sollte. Wenn jemand Vorschläge zur Korrektur hat, würde ich mich darüber freuen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment