Skip to content
Snippets Groups Projects
Commit a726814a authored by Raven Z.'s avatar Raven Z. :cat2:
Browse files

initial version ... still WIP

parents
No related branches found
No related tags found
No related merge requests found
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
main.js 0 → 100644
'use strict';
const JSDOM = require('jsdom').JSDOM
const AXIOS = require('axios').default
const MOMENT = require('moment')
const MENU_URL = 'https://www.studierendenwerk-aachen.de/speiseplaene/ahornstrasse-w-en.html'
AXIOS.get(MENU_URL)
.then(processResponse)
.catch(err => console.error('ERR: ', err));
function processResponse(response) {
const dom = new JSDOM(response.data)
const doc = dom.window.document
const daysDom = doc.querySelectorAll('.accordion > div')
const daysParsed = [...daysDom].map(parseDay)
console.log(JSON.stringify(daysParsed))
}
function parseDay(dayDom) {
const headline = dayDom.querySelector('h3')
const isActive = headline.classList.contains('active-headline')
const titleText = headline.querySelector('a').textContent
const date = MOMENT(titleText, 'dddd, DD.MM.YYYY')
const menuesDom = dayDom.querySelectorAll('table.menues tr')
const extrasDom = dayDom.querySelectorAll('table.extras tr')
const menues = [...menuesDom].map(parseMenuEntry)
return {
date: date.format('YYYY-MM-DD'),
label: titleText,
today: isActive,
menu: [...menues],
}
}
function parseMenuEntry(row) {
const classes = row.classList;
const labels = [...classes].map(cls => {switch (cls) {
case 'vegan': return cls
case 'OLV': return 'olv' // octo-lacto-vegetarian
case 'Schwein': return 'pork'
case 'Rind': return 'beef'
case 'Geflügel': return 'poultry'
case 'Fisch': return 'fish'
case 'odd': return null
case 'even': return null
case 'bg-color': return null
default: return '?:'+cls
}}).filter(e => !!e)
const categoryDom = row.querySelector('menue-category');
const priceDom = row.querySelector('menue-price');
const descDom = row.querySelector('.expand-nutr')
const nutrDom = row.querySelector('.nutr-info')
const category = categoryDom ? categoryDom.textContent : undefined
const price = priceDom ? priceDom.textContent : undefined
const description = parseDescription(descDom)
const nutrition = parseNutrition(nutrDom)
return {
labels,
category,
price,
description,
nutrition,
}
}
function parseDescription(descDom) {
const parts = []
descDom.childNodes.forEach(node => {
if (node.nodeName !== '#text') return;
let part = {
text: node.data.replace(/^\s*(\|\s*)|\s*$/g, '')
}
let nextNode = node.nextSibling
if (nextNode && nextNode.nodeName === 'SUP') {
part.notes = (nextNode.textContent || '?')
.split(',')
.map(s => s.trim())
}
parts.push(part)
})
return parts
}
function parseNutrition(nutrDom) {
const values = {}
nutrDom.querySelector('div').childNodes.forEach(node => {
if (node.nodeName !== '#text') return;
const match = node.data.match(/^\s*([^=]*?)\s*=\s*(.*?)\s*$/)
if (!match) { // should not happen ...
if (!values['?']) values['?'] = [];
values['?'].push(node.data)
}
const rawName = match[1];
const rawValue = match[2];
const name = (s => {switch(s) {
case 'Brennwert': return 'energy'
case 'Fett': return 'fat'
case 'Kohlenhydrate': return 'carbohydrate'
case 'Eiweiß': return 'protein'
default: return '?:' + s
}})(rawName)
values[name] = rawValue
})
return values
}
This diff is collapsed.
{
"name": "mampf-menu-fetcher",
"version": "0.0.0-dev",
"description": "",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"axios": "^0.19.2",
"jsdom": "^16.2.0",
"moment": "^2.24.0"
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment