diff --git a/main.js b/main.js index acbbeaf807c3d3560ecd347fcd5cd02ea5a037d6..85bd2b42d614c66c930baad5d08453a75fe60265 100644 --- a/main.js +++ b/main.js @@ -5,6 +5,7 @@ const MOMENT = require('moment') const MENU_URL = 'https://www.studierendenwerk-aachen.de/speiseplaene/ahornstrasse-w-en.html' +const fetchTime = MOMENT() AXIOS.get(MENU_URL) .then(processResponse) .catch(err => console.error('ERR: ', err)); @@ -13,9 +14,21 @@ function processResponse(response) { const dom = new JSDOM(response.data) const doc = dom.window.document const daysDom = doc.querySelectorAll('.accordion > div') + const additivesDom = doc.querySelector('#additives') const daysParsed = [...daysDom].map(parseDay) + const daysMap = {} + daysParsed.forEach(d => { daysMap[d.date] = d }) + const additives = parseAdditives(additivesDom) - console.log(JSON.stringify(daysParsed)) + + const result = { + days: daysMap, + additives, + url: MENU_URL, + fetchedAt: fetchTime.format() + } + + console.log(JSON.stringify(result)) } function parseDay(dayDom) { @@ -27,12 +40,14 @@ function parseDay(dayDom) { const extrasDom = dayDom.querySelectorAll('table.extras tr') const menues = [...menuesDom].map(parseMenuEntry) + const extras = [...extrasDom].map(parseExtrasEntry) return { date: date.format('YYYY-MM-DD'), label: titleText, today: isActive, menu: [...menues], + extras, } } @@ -50,8 +65,8 @@ function parseMenuEntry(row) { case 'bg-color': return null default: return '?:'+cls }}).filter(e => !!e) - const categoryDom = row.querySelector('menue-category'); - const priceDom = row.querySelector('menue-price'); + const categoryDom = row.querySelector('.menue-category'); + const priceDom = row.querySelector('.menue-price'); const descDom = row.querySelector('.expand-nutr') const nutrDom = row.querySelector('.nutr-info') @@ -69,6 +84,30 @@ function parseMenuEntry(row) { } } +function parseExtrasEntry(row) { + const categoryDom = row.querySelector('.menue-category'); + const descDom = row.querySelector('.menue-desc') + const nutrDom = row.querySelectorAll('.nutr-info') + + const category = categoryDom ? categoryDom.textContent : undefined + const description = parseDescription(descDom) + const nutrition = [...nutrDom].map(parseNutrition) + const count = Math.max(description.length, nutrition.length) + + let options = []; + for (let i = 0; i < count; i++) { + options.push({ + description: description[i] || null, + nutrition: nutrition[i] || null, + }) + } + + return { + category, + options, + } +} + function parseDescription(descDom) { const parts = [] descDom.childNodes.forEach(node => { @@ -89,8 +128,10 @@ function parseDescription(descDom) { } function parseNutrition(nutrDom) { + if (nutrDom.textContent === '-') return null const values = {} - nutrDom.querySelector('div').childNodes.forEach(node => { + const container = nutrDom.querySelector('div') || nutrDom + container.childNodes.forEach(node => { if (node.nodeName !== '#text') return; const match = node.data.match(/^\s*([^=]*?)\s*=\s*(.*?)\s*$/) if (!match) { // should not happen ... @@ -111,3 +152,25 @@ function parseNutrition(nutrDom) { }) return values } + +function parseAdditives(additivesDom) { + const rawText = additivesDom.textContent + const values = {} + rawText + .split(',') + .forEach(s => { + const matches = s + .trim() + .replace(/^\s*(with|contains)\s*/, '') + .match(/^\((.*?)\)\s*(.*?)$/) + if (!matches) { + if (!values['_?']) values['_?'] = [] + values['_?'].push(s) + return + } + const symbol = matches[1] + const text = matches[2] + values[symbol] = text + }) + return values +} diff --git a/package-lock.json b/package-lock.json index 8ab5eea0a2d755c4b5d6ced9e4ed50865cb4a0f5..b37d166ac93b54bb8ec6296d176023c2d9f99ad7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -440,6 +440,11 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "mustache": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.0.0.tgz", + "integrity": "sha512-FJgjyX/IVkbXBXYUwH+OYwQKqWpFPLaLVESd70yHjSDunwzV2hZOoTBvPf4KLoxesUzzyfTH6F784Uqd7Wm5yA==" + }, "nwsapi": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", diff --git a/package.json b/package.json index 6551ca8287994fd0b56121f1a97123bc07fd5008..7c0726b38d0ee9bb4298faaf6aa73f878a002195 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "dependencies": { "axios": "^0.19.2", "jsdom": "^16.2.0", - "moment": "^2.24.0" + "moment": "^2.24.0", + "mustache": "^4.0.0" } }