Skip to content

Instantly share code, notes, and snippets.

@CestDiego
Last active June 9, 2023 01:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CestDiego/91fdac8fcc42d27d2ca1fedec1c70507 to your computer and use it in GitHub Desktop.
Save CestDiego/91fdac8fcc42d27d2ca1fedec1c70507 to your computer and use it in GitHub Desktop.
ITP Camp Dashboard converter to ICS
// 🪄 Experimental: Use at your own risk ✨
// Paste this into the Chrome developer tools console while you are in your dashboard page in list view
// It will either open your calendar or download an ics file, it works on my computer :)
// Read the code, and suggest improvements thanks.
let sessionsLists = document.querySelectorAll('#currentSessionsList .sessionListItem')
//Does not support events that end in the morning
let getEventData = event =>{
let date = event.dataset.date
let time = event.querySelector('.sessionInfo b').textContent.replace('am','').replace('pm','').split('-')
let eventData;
eventData = {
eventName: event.querySelector('.sessionLeftColumn h3 a').textContent,
date,
time,
location: event.querySelector('.sessionLeftColumn h3 a').href
}
return eventData;
}
let getStartEndTime = (timeData) => {
const tzOffset = (new Date()).getTimezoneOffset() / 60
const [start, end] = timeData.map(time => time.split(':'))
// TODO: Assumes that no event starts and ends in the morning
if (Number(start[0]) < Number(end[0])) {
start[0] = String(Number(start[0]) + 12);
}
end[0] = String(Number(end[0]) + 12);
// offset
// start[0] = String(Number(start[0]) + tzOffset);
// end[0] = String(Number(end[0]) + tzOffset);
return {
start: "T" + start[0].padStart(2,'0') + (start.length > 1 ? start[1].padStart(2,'0') : '00')+ '00',
end: "T" + end[0].padStart(2,'0') + (end.length > 1 ? end[1].padStart(2,'0') : '00')+ '00',
}
}
let getVEvent = (eventData) =>{
if (eventData.time.length !== 2)
throw new Error('no time range in one of the events', eventData);
const yearMonthDay = eventData.date.replaceAll('-','')
const time = getStartEndTime(eventData.time)
return `
BEGIN:VEVENT
DTSTART:${yearMonthDay}${time.start}
DTEND:${yearMonthDay}${time.end}
DTSTAMP:20230608T225928Z
LOCATION:${eventData.location}
SUMMARY:${eventData.eventName}
END:VEVENT`
}
// Spread operator magic
const header = `BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//ical.marudot.com//iCal Event Maker
CALSCALE:GREGORIAN
BEGIN:VTIMEZONE
TZID:America/New_York
LAST-MODIFIED:20201011T015911Z
TZURL:http://tzurl.org/zoneinfo-outlook/America/New_York
X-LIC-LOCATION:America/New_York
BEGIN:DAYLIGHT
TZNAME:EDT
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
DTSTART:19700308T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
END:DAYLIGHT
BEGIN:STANDARD
TZNAME:EST
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
DTSTART:19701101T020000
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
END:STANDARD
END:VTIMEZONE`
const footer = `
END:VCALENDAR
`
const ics = header + [...sessionsLists].map(getEventData).map(getVEvent).join('') + footer
console.log(ics)
window.open("data:text/calendar;charset=utf8," + escape(ics));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment