Skip to content

Instantly share code, notes, and snippets.

@tomacco81
Forked from marco79cgn/dm-toilet-paper.js
Last active October 28, 2020 19:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tomacco81/8c240ed4d51d08ff57dbd173e0432432 to your computer and use it in GitHub Desktop.
Save tomacco81/8c240ed4d51d08ff57dbd173e0432432 to your computer and use it in GitHub Desktop.
Scriptable iOS widget that shows the amount of condoms which are available at your next dm drugstore
let country = 'de' // replace with 'at' for shops in Austria
let storeId = 251
let param = args.widgetParameter
if (param != null && param.length > 0) {
storeId = param
}
const widget = new ListWidget()
const storeInfo = await fetchStoreInformation()
const storeCapacity = await fetchAmountOfCondoms()
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('condom.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 condomText = column.addText("KONDOME")
condomText.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 condom packages
async function fetchAmountOfCondoms() {
let url
let counter = 0
if (country.toLowerCase() === 'at') {
// Austria
const array = ["173357", "172817", "175756", "62259", "197603", "297152", "175527", "178873", "204617", "173069", "259506", "159160", "193136", "191715", "262565", "264153", "227777", "259505", "204506", "150958", "150977", "115544", "64213", "97239", "97243", "154158", "154159", "193606", "191713", "159196", "179823", "191712", "204347", "36600", "99205", "99201", "267206"]
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=485644,490327,866352,485641,485642,849655,416293,711934,479111,564894,416289,609981,467930,685823,146559,297578,146560,564901,448725,478955,209733,478781,521332,893598,893597,893593,169572,169571,425076,209453,182939,169573,533062,786258,890438,523243&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=kondome&searchType=product'
} else {
url = 'https://store-data-service.services.dmtech.com/stores/item/de/' + storeId
widget.url = 'https://www.dm.de/search?query=kondome&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 'condom.png':
imageUrl = "https://i.imgur.com/q5lqXAa.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
// bitte bis zum Ende kopieren
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment