first version of apple store order status widget

Signed-off-by: Benny Samir Hierl <bennysamir@posteo.de>
This commit is contained in:
Benny Samir Hierl 2020-11-12 18:09:17 +01:00
parent 8021750a6a
commit 6fec12f26d
No known key found for this signature in database
GPG key ID: 69DE3C3C097DB7F7
2 changed files with 239 additions and 0 deletions

View file

@ -0,0 +1,224 @@
// Variables used by Scriptable.
// These must be at the very top of the file. Do not edit.
// icon-color: deep-blue; icon-glyph: shopping-cart;
const cacheMinutes = 60 * 2
const today = new Date()
let width
const h = 5
const debug = false
if (config.widgetFamily === 'small') {
width = 100
} else {
width = 200
}
////////////////////////////////////////////////////////////
let widgetInputRAW = args.widgetParameter;
let widgetInput;
if (widgetInputRAW !== null) {
widgetInput = widgetInputRAW.toString().trim().split(';')
if (widgetInput[2] && !/^[\d]+$/.test(widgetInput[2])) {
throw new Error('Third parameter has to be a number')
}
} else {
throw new Error('No Ordernumber and E-Mail address set')
}
////////////////////////////////////////////////////////////
const files = FileManager.local()
const path = files.joinPath(files.cacheDirectory(), "widget-apple-store-order")
const cacheExists = files.fileExists(path)
const cacheDate = cacheExists ? files.modificationDate(path) : 0
////////////////////////////////////////////////////////////
const parseDate = (stringDate) => {
const months = {
'Januar': 0,
'Februar': 1,
'März': 2,
'April': 3,
'Mai': 4,
'Juni': 5,
'Juli': 6,
'August': 7,
'September': 8,
'Oktober': 9,
'November': 10,
'Dezember': 11
}
const m = stringDate.match(/([\d]{1,2})[.\s]+([\w]+)[\s]?([0-9]{4})?/)
const monthKey = Object.keys(months).find((key) => {
return key === m[2] || key.substring(0,3) == m[2]
})
if (!m[3]) {
m[3] = new Date().getFullYear()
}
return new Date(m[3], months[monthKey], m[1])
}
////////////////////////////////////////////////////////////
function creatProgress(total,havegone){
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(new Color('#008009'))
const path1 = new Path()
const path1width = (width*havegone/total > width) ? width : width*havegone/total
path1.addRoundedRect(new Rect(0, 0, path1width, h), 3, 2)
context.addPath(path1)
context.fillPath()
return context.getImage()
}
////////////////////////////////////////////////////////////
const getTimeRemaining = function (endtime){
const total = Date.parse(endtime) - Date.parse(new Date());
const seconds = Math.floor( (total/1000) % 60 );
const minutes = Math.floor( (total/1000/60) % 60 );
const hours = Math.floor( (total/(1000*60*60)) % 24 );
const days = Math.floor( total/(1000*60*60*24) );
return {
total,
days,
hours,
minutes,
seconds
};
}
////////////////////////////////////////////////////////////
const getOrderdetails = async (ordernumber, email) => {
const req = new Request(`https://store.apple.com/xc/de/vieworder/${ordernumber}/${email}`)
const res = await req.loadString()
const rawJSON = res.match(/<script id="init_data" type="application\/json">(.*)<\/script>/)
if(!rawJSON) {
return null
}
const data = JSON.parse(rawJSON[1])
if (!data['orderDetail']) {
console.log(data)
throw new Error('no orderDetail attribute')
}
return data
}
////////////////////////////////////////////////////////////
let orderDetails
if (cacheExists && (today.getTime() - cacheDate.getTime()) < (cacheMinutes * 60 * 1000)) {
console.log("Get from Cache")
orderDetails = JSON.parse(files.readString(path))
} else {
console.log("Get from Website")
try {
orderDetails = await getOrderdetails(widgetInput[0], widgetInput[1])
if(orderDetails !== null) {
console.log("Write to Cache")
files.writeString(path, JSON.stringify(orderDetails))
}
} catch (e) {
console.error('Fetching data from website failed')
console.error(e)
if (cacheExists) {
console.warn('Fallback to Cache')
orderDetails = JSON.parse(files.readString(path))
}
}
}
if (debug) {
console.log(JSON.stringify(orderDetails, null, 2))
}
let widget = new ListWidget();
if (!orderDetails) {
widget.addText('No order found')
} else {
if (widgetInput[2] && !orderDetails['orderDetail']['orderItems']['c'][widgetInput[2] - 1]) {
throw new Error(`No Item on position ${widgetInput[2]}`)
}
const itemPosition = orderDetails['orderDetail']['orderItems']['c'][(widgetInput[2] -1) || 0]
const itemDetails = orderDetails['orderDetail']['orderItems'][itemPosition]['orderItemDetails']
const orderDate = parseDate(orderDetails['orderDetail']['orderHeader']['d']['orderPlacedDate'])
const deliveryDate = parseDate(itemDetails['d']['deliveryDate'])
const itemName = itemDetails['d']['productName']
const itemImageUrl = itemDetails['d']['imageData']['src'].replace(/wid=[\d]+/, 'wid=200').replace(/hei=[\d]+/, 'hei=200')
const itemImage = await (new Request(itemImageUrl)).loadImage()
const remainingDays = getTimeRemaining(deliveryDate).days + 1;
widget.setPadding(10, 10, 10, 10)
widget.backgroundColor = Color.white()
widget.url = `https://store.apple.com/xc/de/vieworder/${widgetInput[0]}/${widgetInput[1]}`
const headlineText = widget.addText(' Order Status')
headlineText.font = Font.regularSystemFont(14)
headlineText.textColor = Color.black()
widget.addSpacer()
const productStack = widget.addStack()
productStack.layoutHorizontally()
itemImageElement = productStack.addImage(itemImage)
itemImageElement.imageSize = new Size(30, 30)
productStack.addSpacer(10)
const itemNameText = productStack.addText(itemName)
itemNameText.font = Font.regularSystemFont(16)
itemNameText.textColor = Color.black()
itemNameText.minimumScaleFactor = 0.3
itemNameText.lineLimit = 2
widget.addSpacer()
let postFix;
if(remainingDays === 1) {
postFix = 'Day'
} else {
postFix = 'Days'
}
const remainingDayText = widget.addText(remainingDays + ' ' + postFix)
remainingDayText.font = Font.regularSystemFont(28)
remainingDayText.textColor = Color.black()
remainingDayText.centerAlignText()
widget.addSpacer()
const total = (deliveryDate - orderDate) / (1000*60*60*24)
const daysGone = total - remainingDays
widget.addImage(creatProgress(total, daysGone))
widget.addSpacer(5)
const footerStack = widget.addStack()
footerStack.layoutHorizontally()
const orderDateText = footerStack.addDate(orderDate)
orderDateText.textColor = Color.black()
orderDateText.font = Font.regularSystemFont(8)
footerStack.addSpacer()
const deliveryDateText = footerStack.addDate(deliveryDate)
deliveryDateText.textColor = Color.black()
deliveryDateText.font = Font.regularSystemFont(8)
}
if(!config.runsInWidget) {
await widget.presentSmall()
} else {
// Tell the system to show the widget.
Script.setWidget(widget)
Script.complete()
}

View file

@ -0,0 +1,15 @@
# Apple Store Order Status
This widget shows you the status of your Apple Store order. It shows the remaining days until delivery, the product name, product image, order date and delivery date.
[[Download]](https://raw.githubusercontent.com/ThisIsBenny/iOS-Widgets/main/Apple-Order-Status/Apple-Store-Order-Status.js)
## Setup
Set the Order-Number and your E-Mail Adress, separated by `;` to the Widget Parameter.
Example: `W1234567;jon@snow.com`
### Optional
if you have more than one item in your order, you can use the third parameter to specify which item should be displayed (default: 1).
Example: Example: `W1234567;jon@snow.com;2`