Created
October 26, 2018 15:54
-
-
Save darjanin/2e652e2b9601d184e7a79b32868cec0a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Variables used by Scriptable. | |
// These must be at the very top of the file. Do not edit. | |
// icon-color: teal; icon-glyph: utensils; | |
const click = "http://m.clickfood.sk/sk/menu/"; | |
async function getMenu(link, parseMenu) { | |
try { | |
if (link.endsWith("date=")) { | |
const date = getMomentForMenu().format("DD.MM.YYYY"); | |
link = `${link}${date}`; | |
} | |
const request = new Request(link); | |
const body = await request.loadString(); | |
return parseMenu(body); | |
} catch (e) { | |
console.log(e); | |
return `Chyba počas načítavania menu 😥`; | |
} | |
} | |
const capitalize = str => str[0].toUpperCase() + str.slice(1); | |
function getIndicesOf(menuStrFrom, menuStrTo, str) { | |
const menuStrFromLen = menuStrFrom.length; | |
const menuStrToLen = menuStrTo.length; | |
if (menuStrFromLen === 0 || menuStrToLen === 0) { | |
return []; | |
} | |
let startIndex = 0; | |
let index; | |
const indices = []; | |
while ((index = str.indexOf(menuStrFrom, startIndex)) > -1) { | |
const from = index; | |
const to = str.indexOf(menuStrTo, from + menuStrFromLen); | |
startIndex = to + menuStrToLen; | |
indices.push({ from, to }); | |
} | |
return indices; | |
} | |
function getPriceOfItem(item) { | |
const priceMatch = item.match(/\b(\d+[,.]\d+)\s*€/); | |
return priceMatch && parseFloat(priceMatch[1].replace(",", ".")); | |
} | |
function parseTodaysClickMenu(rawMenu) { | |
const menuStart = rawMenu.indexOf('<div id="kategoria-menu-'); | |
if (menuStart === -1) { | |
throw new Error('Parsing Click menu: "<div id="kategoria-menu-" not found'); | |
} | |
const menuEnd = rawMenu.indexOf('<div id="kategoria-salaty"', menuStart); | |
if (menuEnd === -1) { | |
throw new Error( | |
'Parsing Click menu: "<div id="kategoria-salaty"" not found' | |
); | |
} | |
const menu = rawMenu.substring(menuStart, menuEnd); | |
const dayMatch = menu.match(/kategoria-menu-(\w+)/); | |
const day = dayMatch ? capitalize(dayMatch[1]) : "?"; | |
const indices = getIndicesOf("<li", "</li>", menu); | |
const soupsIndex = menu.indexOf('<div id="kategoria-polievky"'); | |
const soup = [], | |
main = []; | |
indices.forEach(index => { | |
let item = menu | |
.substring(index.from, index.to) | |
// delete all HTML tags | |
.replace(/<[^>]*>/g, ""); | |
item = item | |
// remove item comments | |
.replace(/\([^)]*\)/g, "") | |
// remove multiple spaces | |
.replace(/\s+/g, " ") | |
// remove add to cart symbol | |
.replace(/\s\+\s/g, " ") | |
.trim(); | |
if (index.from < soupsIndex) { | |
const price = getPriceOfItem(item); | |
if (price == null || price > 3.5) { | |
// filter dessert | |
main.push(`${main.length + 1}. ${item}`); | |
} | |
} else { | |
soup.push(`${soup.length + 1}. ${item}`); | |
} | |
}); | |
return { | |
soup, | |
main | |
}; | |
} | |
const menu = await getMenu(click, parseTodaysClickMenu); | |
const nums = ["1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣"]; | |
const splitValue = (value, words = 5) => { | |
value = value | |
.replace(" ", "") | |
.replace(/\(.*/, "") | |
.split(" "); | |
const subtitle = value.slice(words).join(" "); | |
const title = value.slice(0, words).join(" "); | |
return { title, subtitle }; | |
}; | |
const cleanupData = data => { | |
let cleaned = {}; | |
for (let category in data) { | |
cleaned[category] = data[category].map(item => splitValue(item)); | |
} | |
return cleaned; | |
}; | |
const createRow = (value, subtitle, isHeader = false) => { | |
let row = new UITableRow(); | |
row.isHeader = isHeader; | |
row.height = isHeader ? 40 : 40 + (Math.floor(subtitle.length / 50) + 1) * 14; | |
row.cellSpacing = 0; | |
let columnOptions = [ | |
{ value: value, subtitle: subtitle, align: "left", weight: 1 } | |
]; | |
for (options of columnOptions) { | |
let cell = createCell(options); | |
row.addCell(cell); | |
} | |
return row; | |
}; | |
function createCell({ value, format, subtitle, weight, align }) { | |
const text = format ? value.toLocaleDateString("en-US", format) : value; | |
const cell = UITableCell.text(text, subtitle); | |
cell.widthWeight = weight; | |
cell[`${align}Aligned`](); | |
return cell; | |
} | |
function handleEvents(meals) { | |
const { main, soup } = meals; | |
let table = new UITable(); | |
table.showSeparators = true; | |
table.addRow(createRow("Hlavne jedlo", "", true)); | |
for (let index in main) { | |
const { title, subtitle } = main[index]; | |
table.addRow(createRow(title, subtitle)); | |
} | |
table.addRow(createRow("Polievky", "", true)); | |
for (let index in soup) { | |
const { title, subtitle } = soup[index]; | |
table.addRow(createRow(title, subtitle)); | |
} | |
QuickLook.present(table); | |
} | |
const meals = await getMenu(click, parseTodaysClickMenu); | |
let table = handleEvents(cleanupData(meals)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment