Skip to content

Instantly share code, notes, and snippets.

@bakapear
Last active February 5, 2022 23:33
Show Gist options
  • Save bakapear/547421f60fddb05c4b5b6b9d27fa89d5 to your computer and use it in GitHub Desktop.
Save bakapear/547421f60fddb05c4b5b6b9d27fa89d5 to your computer and use it in GitHub Desktop.
EGN Abfallkalender to ICS format
/* -*- 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