Version 1.0.1 of order script

Signed-off-by: Benny Samir Hierl <bennysamir@posteo.de>
This commit is contained in:
Benny Samir Hierl 2020-11-12 22:54:55 +01:00
parent c66ad6cbdc
commit 1e83dfd586
No known key found for this signature in database
GPG key ID: 69DE3C3C097DB7F7
2 changed files with 144 additions and 78 deletions

View file

@ -1,7 +1,7 @@
// Variables used by Scriptable. // Variables used by Scriptable.
// These must be at the very top of the file. Do not edit. // These must be at the very top of the file. Do not edit.
// icon-color: deep-blue; icon-glyph: shopping-cart; // icon-color: deep-blue; icon-glyph: shopping-cart;
// Version 1.0.0 // Version 1.0.1
const cacheMinutes = 60 * 2 const cacheMinutes = 60 * 2
const today = new Date() const today = new Date()
@ -36,29 +36,54 @@ const cacheExists = files.fileExists(path)
const cacheDate = cacheExists ? files.modificationDate(path) : 0 const cacheDate = cacheExists ? files.modificationDate(path) : 0
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
const parseDate = (stringDate) => { const localeText = {
default: ['Day', 'Days'],
en: ['Day', 'Days'],
de: ['Tag', 'Tage'],
fr: ['Jour', 'Jours'],
es: ['día', 'días'],
it: ['giorno', 'giorni']
}
////////////////////////////////////////////////////////////
const parseLongDate = (stringDate) => {
const months = { const months = {
'Januar': 0, 'January': 0,
'Februar': 1, 'February': 1,
'März': 2, 'March': 2,
'April': 3, 'April': 3,
'Mai': 4, 'May': 4,
'Juni': 5, 'June': 5,
'Juli': 6, 'July': 6,
'August': 7, 'August': 7,
'September': 8, 'September': 8,
'Oktober': 9, 'October': 9,
'November': 10, 'November': 10,
'Dezember': 11 'December': 11
} }
const m = stringDate.match(/([\d]{1,2})[.\s]+([\w]+)[\s]?([0-9]{4})?/) const m = stringDate.match(/([\w]+)[\s]([\d]{1,2}),[\s]([0-9]{4})/)
const monthKey = Object.keys(months).find((key) => { return new Date(m[3], months[m[1]], m[2])
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]) const parseShortDate = (stringDate, orderMonth) => {
const months = {
'Jan': 0,
'Feb': 1,
'Mar': 2,
'Apr': 3,
'May': 4,
'Jun': 5,
'Jul': 6,
'Aug': 7,
'Sep': 8,
'Oct': 9,
'Nov': 10,
'Dec': 11
}
const m = stringDate.match(/([\d]{1,2}) ([\w]{3})/)
let year = new Date().getFullYear()
if (months[m[2]] < orderMonth) {
year += 1
}
return new Date(year, months[m[2]], m[1])
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
function creatProgress(total, havegone) { function creatProgress(total, havegone) {
@ -97,7 +122,52 @@ const getTimeRemaining = function (endtime){
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
const getOrderdetails = async (ordernumber, email) => { const getOrderdetails = async (ordernumber, email) => {
const req = new Request(`https://store.apple.com/xc/de/vieworder/${ordernumber}/${email}`) const reqSession = new Request('https://secure.store.apple.com/shop/order/list')
resSession = await reqSession.loadString()
const CookieValues = reqSession.response.cookies.map((v) => {
return v.name + "=" + v.value
})
const xAosStkMatch = resSession.match(/"x-aos-stk":"([\w]+)"/)
if (!xAosStkMatch) {
throw new Error('Needed x-aos-stk token not found')
}
const postUrl = (reqSession.response.url.replace('/np/', '/npx/')) + '&_a=guestUserOrderLookUp&_m=loginHomeOLSS.orderLookUp'
const postReq = new Request(postUrl)
postReq.headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Referer': reqSession.response.url,
'x-aos-model-page': 'sentryLoginOlssNP',
'x-aos-stk': xAosStkMatch[1],
'X-Requested-With': 'XMLHttpRequest',
'Cookie': CookieValues.join('; ')
}
postReq.method = "POST";
postReq.addParameterToMultipart('loginHomeOLSS.orderLookUp.orderNumber', ordernumber)
postReq.addParameterToMultipart('loginHomeOLSS.orderLookUp.emailAddress', email)
const resPostReq = await postReq.loadString()
if (postReq.response.statusCode !== 200) {
throw new Error(`Got HTTP ${postReq.response.statusCode} from API.`)
}
let postResData
try {
postResData = JSON.parse(resPostReq)
} catch (e) {
throw new Error('Can\'t parse API response.')
}
if (postResData['head']['status'] !== 302) {
console.log(resPostReq)
throw new Error('Fetching the data failed. Got unexpected response. Please try it later.')
}
const req = new Request(postResData['head']['data']['url'])
const res = await req.loadString() const res = await req.loadString()
const rawJSON = res.match(/<script id="init_data" type="application\/json">(.*)<\/script>/) const rawJSON = res.match(/<script id="init_data" type="application\/json">(.*)<\/script>/)
if (!rawJSON) { if (!rawJSON) {
@ -124,11 +194,13 @@ if (cacheExists && (today.getTime() - cacheDate.getTime()) < (cacheMinutes * 60
files.writeString(path, JSON.stringify(orderDetails)) files.writeString(path, JSON.stringify(orderDetails))
} }
} catch (e) { } catch (e) {
console.error('Fetching data from website failed') console.error('Fetching data from website failed:')
console.error(e) console.error(e)
if (cacheExists) { if (cacheExists) {
console.warn('Fallback to Cache') console.warn('Fallback to Cache')
orderDetails = JSON.parse(files.readString(path)) orderDetails = JSON.parse(files.readString(path))
} else {
throw new Error('Fetching the data failed. Now data to show.')
} }
} }
} }
@ -147,8 +219,8 @@ if (!orderDetails) {
const itemPosition = orderDetails['orderDetail']['orderItems']['c'][(widgetInput[2] - 1) || 0] const itemPosition = orderDetails['orderDetail']['orderItems']['c'][(widgetInput[2] - 1) || 0]
const itemDetails = orderDetails['orderDetail']['orderItems'][itemPosition]['orderItemDetails'] const itemDetails = orderDetails['orderDetail']['orderItems'][itemPosition]['orderItemDetails']
const orderDate = parseDate(orderDetails['orderDetail']['orderHeader']['d']['orderPlacedDate']) const orderDate = parseLongDate(orderDetails['orderDetail']['orderHeader']['d']['orderPlacedDate'])
const deliveryDate = parseDate(itemDetails['d']['deliveryDate']) const deliveryDate = parseShortDate(itemDetails['d']['deliveryDate'], orderDate.getMonth())
const itemName = itemDetails['d']['productName'] const itemName = itemDetails['d']['productName']
const itemImageUrl = itemDetails['d']['imageData']['src'].replace(/wid=[\d]+/, 'wid=200').replace(/hei=[\d]+/, 'hei=200') const itemImageUrl = itemDetails['d']['imageData']['src'].replace(/wid=[\d]+/, 'wid=200').replace(/hei=[\d]+/, 'hei=200')
const itemImage = await(new Request(itemImageUrl)).loadImage() const itemImage = await(new Request(itemImageUrl)).loadImage()
@ -178,15 +250,11 @@ if (!orderDetails) {
itemNameText.minimumScaleFactor = 0.3 itemNameText.minimumScaleFactor = 0.3
itemNameText.lineLimit = 2 itemNameText.lineLimit = 2
widget.addSpacer() widget.addSpacer()
let postFix; const languageCode = Device.language().match(/^[\a-z]{2}/)
if(remainingDays === 1) { const t = (localeText[languageCode]) ? localeText[languageCode] : localeText.default
postFix = 'Day' let postFix = (remainingDays === 1) ? t[0] : t[1]
} else {
postFix = 'Days'
}
const remainingDayText = widget.addText(remainingDays + ' ' + postFix) const remainingDayText = widget.addText(remainingDays + ' ' + postFix)
remainingDayText.font = Font.regularSystemFont(28) remainingDayText.font = Font.regularSystemFont(28)

View file

@ -3,8 +3,6 @@
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. 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.
_Notice_: The script is only working with order on the german Apple Store. You can provide me your order number + email, so that I'm able to add the support for your language.
[[Download]](https://raw.githubusercontent.com/ThisIsBenny/iOS-Widgets/main/Apple-Order-Status/Apple-Store-Order-Status.js) [[Download]](https://raw.githubusercontent.com/ThisIsBenny/iOS-Widgets/main/Apple-Order-Status/Apple-Store-Order-Status.js)
## Setup ## Setup