// 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.5 const cacheMinutes = 60 * 2 const today = new Date() let width; const h = 5 const debug = false if (config.widgetFamily === 'small') { width = 100 } else { width = 300 } //////////////////////////////////////////////////////////// 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-" + widgetInput[0]) const cacheExists = files.fileExists(path) const cacheDate = cacheExists ? files.modificationDate(path) : 0 //////////////////////////////////////////////////////////// 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 = { '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 } let m m = stringDate.match(/([\d]{1,2}) ([\w]{3})/) if (!m) { m = stringDate.match(/([\w]{3}) ([\d]{1,2})/) if (m) { const t = m[1] m[1] = m[2] m[2] = t } else { throw new Error('Failed to extract the delivery date from string: ' + stringDate) } } 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.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 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(/