diff --git a/Apple-Order-Status/Apple-Store-Order-Status.js b/Apple-Order-Status/Apple-Store-Order-Status.js index 1bcea33..539892a 100644 --- a/Apple-Order-Status/Apple-Store-Order-Status.js +++ b/Apple-Order-Status/Apple-Store-Order-Status.js @@ -1,7 +1,7 @@ // 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; -// Version 1.0.0 +// Version 1.0.1 const cacheMinutes = 60 * 2 const today = new Date() @@ -20,7 +20,7 @@ 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') } @@ -36,34 +36,59 @@ 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]) +const localeText = { + default: ['Day', 'Days'], + en: ['Day', 'Days'], + de: ['Tag', 'Tage'], + fr: ['Jour', 'Jours'], + es: ['día', 'días'], + it: ['giorno', 'giorni'] } //////////////////////////////////////////////////////////// -function creatProgress(total,havegone){ +const parseLongDate = (stringDate) => { + const months = { + 'January': 0, + 'February': 1, + 'March': 2, + 'April': 3, + 'May': 4, + 'June': 5, + 'July': 6, + 'August': 7, + 'September': 8, + 'October': 9, + 'November': 10, + 'December': 11 + } + const m = stringDate.match(/([\w]+)[\s]([\d]{1,2}),[\s]([0-9]{4})/) + return new Date(m[3], months[m[1]], m[2]) +} +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) { const context = new DrawContext() - context.size= new Size(width, h) + context.size = new Size(width, h) context.opaque = false context.respectScreenScale = true context.setFillColor(new Color('#d2d2d7')) @@ -73,19 +98,19 @@ function creatProgress(total,havegone){ context.fillPath() context.setFillColor(new Color('#008009')) const path1 = new Path() - const path1width = (width*havegone/total > width) ? width : width*havegone/total + 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 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) ); + 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, @@ -97,16 +122,61 @@ const getTimeRemaining = function (endtime){ } //////////////////////////////////////////////////////////// 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 rawJSON = res.match(/