Last active
February 5, 2022 23:33
-
-
Save bakapear/547421f60fddb05c4b5b6b9d27fa89d5 to your computer and use it in GitHub Desktop.
EGN Abfallkalender to ICS format
This file contains 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
/* -*- js -*- */ | |
let URL = 'https://www.egn-abfallkalender.de/' | |
function makeForm (obj) { | |
let params = new URLSearchParams() | |
for (let o in obj) params.append(o, obj[o]) | |
return params | |
} | |
function formatDate (day, month, year) { | |
if (day.length < 2) day = '0' + day | |
if (month.length < 2) month = '0' + month | |
return year + month + day | |
} | |
async function getSessionHeaders () { | |
let res = await fetch(URL) | |
let data = await res.text() | |
let cookies = res.headers.get('set-cookie') | |
return { | |
cookie: cookies.split(' ').filter((x, i) => i % 7 === 0).slice(0, -1).join(' '), | |
'x-csrf-token': data.match(/csrf-token.*?content="(.*?)"/)[1] | |
} | |
} | |
async function makeRequest (path, params) { | |
let session = await getSessionHeaders() | |
params = makeForm(params) | |
let res = await fetch(URL + path, { | |
method: 'POST', | |
body: params, | |
headers: session | |
}) | |
let data = await res.json() | |
return data | |
} | |
function createICS (dates, name, text) { | |
let out = [] | |
for (let date of dates) { | |
out.push([ | |
'BEGIN:VEVENT', | |
'STATUS:CONFIRMED', | |
`DTSTART;TZID=Europe/Berlin:${date + OPTS.time[0]}`, | |
`DTEND;TZID=Europe/Berlin:${date + OPTS.time[1]}`, | |
`SUMMARY:${text}`, | |
'TRANSP:OPAQUE', | |
'BEGIN:VALARM', | |
'ACTION:DISPLAY', | |
'DESCRIPTION:This is an event reminder', | |
`TRIGGER:${OPTS.reminder}`, | |
'END:VALARM', | |
'END:VEVENT' | |
].join('\n')) | |
} | |
return [ | |
'BEGIN:VCALENDAR', | |
`PRODID:-//${name}`, | |
'VERSION:2.0', | |
'METHOD:PUBLISH', | |
'BEGIN:VTIMEZONE', | |
'TZID:Europe/Berlin', | |
'X-LIC-LOCATION:Europe/Berlin', | |
'BEGIN:DAYLIGHT', | |
'TZOFFSETFROM:+0100', | |
'TZOFFSETTO:+0200', | |
'TZNAME:CEST', | |
'DTSTART:19700329T020000', | |
'RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3', | |
'END:DAYLIGHT', | |
'BEGIN:STANDARD', | |
'TZOFFSETFROM:+0200', | |
'TZOFFSETTO:+0100', | |
'TZNAME:CET', | |
'DTSTART:19701025T030000', | |
'RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10', | |
'END:STANDARD', | |
'END:VTIMEZONE', | |
...out, | |
'END:VCALENDAR' | |
].join('\n') | |
} | |
let OPTS = { | |
time: ['T091500Z', 'T093000Z'], // 9:15 > 9:30 | |
reminder: '-P0DT13H0M0S' // remind 13 hours before | |
} | |
let PARAMS = { | |
city: await question('City: '), | |
district: await question('District: '), | |
street: await question('Street: '), | |
street_number: await question('Street Number: ') | |
} | |
let res = await makeRequest('kalender', PARAMS).catch(() => null) | |
if (!res) console.error('Invalid location!') | |
else { | |
let colors = res.trash_type_colors | |
let dates = res.waste_discharge | |
let out = {} | |
for (let year in dates) { | |
for (let month in dates[year]) { | |
for (let day in dates[year][month]) { | |
let type = colors[dates[year][month][day][0].toLowerCase()] | |
if (!out[type]) out[type] = [] | |
out[type].push(formatDate(day, month, year)) | |
} | |
} | |
} | |
let w = (x, y) => fs.writeFileSync(x, y) | |
w('grau.ics', createICS(out.grau, 'EGN//Abfallkalender Grau', 'Graue Mülltonne')) | |
w('blau.ics', createICS(out.blau, 'EGN//Abfallkalender Blau', 'Blaue Mülltonne')) | |
w('gelb.ics', createICS(out.gelb, 'EGN//Abfallkalender Gelb', 'Gelbe Mülltonne')) | |
w('braun.ics', createICS(out.braun, 'EGN//Abfallkalender Braun', 'Braune Mülltonne')) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment