Skip to content

Instantly share code, notes, and snippets.

@darjanin
Created October 26, 2018 15:54
Show Gist options
  • Save darjanin/2e652e2b9601d184e7a79b32868cec0a to your computer and use it in GitHub Desktop.
Save darjanin/2e652e2b9601d184e7a79b32868cec0a to your computer and use it in GitHub Desktop.
// 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("&nbsp;", "")
.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