Last active
May 1, 2026 17:35
-
-
Save Pinjasaur/4b612b9ddda2e25c7cd2b5cd0017469e to your computer and use it in GitHub Desktop.
Minnebar Session Schedule .ics Bookmarklet https://sessions.minnestar.org/schedule
This file contains hidden or 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
| javascript:(function(){const r={},s=(document.querySelectorAll(".nav-top .timeslot[startsAt]").forEach(e=>{var t=e.getAttribute("href").replace("#","");r[t]={start:parseInt(e.getAttribute("startsAt"),10),end:parseInt(e.getAttribute("endsAt"),10)}}),[]);if(document.querySelectorAll(".timeslot[id]").forEach(e=>{var t=e.id;const o=r[t];o&&e.querySelectorAll(".session").forEach(t=>{var r=t.querySelector("button.toggle-attendance");if(r&&"true"===r.getAttribute("data-session-attending")){var r=t.querySelector("h3.title"),n=t.querySelector(".room"),t=t.querySelector(".description"),r=r?r.textContent.trim():"Untitled Session",n=n?n.textContent.trim():"";let e="";t&&((t=t.cloneNode(!0)).querySelectorAll("a[href]").forEach(e=>{var t=e.getAttribute("href"),r=e.textContent.trim();e.replaceWith(r===t?r:r+" ("+t+")")}),e=t.textContent.trim()),s.push({title:r,location:n,description:e,start:o.start,end:o.end})}})}),0===s.length)alert("No attended sessions found. Make sure you are marked as attending sessions.");else{const i=["BEGIN:VCALENDAR","VERSION:2.0","PRODID:-//Minnebar Schedule Bookmarklet//EN","CALSCALE:GREGORIAN","METHOD:PUBLISH"];s.forEach((e,t)=>{var t="minnebar-"+e.start+"-"+t+"@minnestar.org",r=n(Math.floor(Date.now()/1e3));i.push("BEGIN:VEVENT"),i.push(a("UID:"+t)),i.push("DTSTAMP:"+r),i.push("DTSTART:"+n(e.start)),i.push("DTEND:"+n(e.end)),i.push(a("SUMMARY:"+o(e.title))),e.location&&i.push(a("LOCATION:"+o(e.location))),e.description&&i.push(a("DESCRIPTION:"+o(e.description))),i.push("END:VEVENT")}),i.push("END:VCALENDAR");var e=i.join("\r\n"),e=new Blob([e],{type:"text/calendar;charset=utf-8"}),e=URL.createObjectURL(e),t=document.createElement("a");function n(e){return new Date(1e3*e).toISOString().replace(/[-:]/g,"").replace(/\.\d{3}/,"")}function o(e){return e.replace(/\\/g,"\\\\").replace(/;/g,"\\;").replace(/,/g,"\\,").replace(/\n/g,"\\n")}function a(e){for(var t=[];75<e.length;)t.push(e.substring(0,75)),e=" "+e.substring(75);return t.push(e),t.join("\r\n")}t.href=e,t.download="minnebar-schedule.ics",document.body.appendChild(t),t.click(),document.body.removeChild(t),URL.revokeObjectURL(e),alert("Downloaded "+s.length+" session(s) to minnebar-schedule.ics")}})(); |
This file contains hidden or 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
| javascript:(function(){ | |
| const timeMap = {}; | |
| document.querySelectorAll('.nav-top .timeslot[startsAt]').forEach(a => { | |
| const href = a.getAttribute('href'); | |
| const id = href.replace('#', ''); | |
| timeMap[id] = { | |
| start: parseInt(a.getAttribute('startsAt'), 10), | |
| end: parseInt(a.getAttribute('endsAt'), 10) | |
| }; | |
| }); | |
| const events = []; | |
| document.querySelectorAll('.timeslot[id]').forEach(block => { | |
| const id = block.id; | |
| const times = timeMap[id]; | |
| if (!times) return; | |
| block.querySelectorAll('.session').forEach(session => { | |
| const btn = session.querySelector('button.toggle-attendance'); | |
| if (!btn || btn.getAttribute('data-session-attending') !== 'true') return; | |
| const titleEl = session.querySelector('h3.title'); | |
| const roomEl = session.querySelector('.room'); | |
| const descEl = session.querySelector('.description'); | |
| const title = titleEl ? titleEl.textContent.trim() : 'Untitled Session'; | |
| const location = roomEl ? roomEl.textContent.trim() : ''; | |
| let description = ''; | |
| if (descEl) { | |
| const clone = descEl.cloneNode(true); | |
| clone.querySelectorAll('a[href]').forEach(a => { | |
| const href = a.getAttribute('href'); | |
| const text = a.textContent.trim(); | |
| a.replaceWith(text === href ? text : text + ' (' + href + ')'); | |
| }); | |
| description = clone.textContent.trim(); | |
| } | |
| events.push({ title, location, description, start: times.start, end: times.end }); | |
| }); | |
| }); | |
| if (events.length === 0) { | |
| alert('No attended sessions found. Make sure you are marked as attending sessions.'); | |
| return; | |
| } | |
| function toICSDate(unixSec) { | |
| const d = new Date(unixSec * 1000); | |
| return d.toISOString().replace(/[-:]/g, '').replace(/\.\d{3}/, ''); | |
| } | |
| function escapeICS(str) { | |
| return str.replace(/\\/g, '\\\\').replace(/;/g, '\\;').replace(/,/g, '\\,').replace(/\n/g, '\\n'); | |
| } | |
| function foldLine(line) { | |
| const out = []; | |
| while (line.length > 75) { | |
| out.push(line.substring(0, 75)); | |
| line = ' ' + line.substring(75); | |
| } | |
| out.push(line); | |
| return out.join('\r\n'); | |
| } | |
| const lines = [ | |
| 'BEGIN:VCALENDAR', | |
| 'VERSION:2.0', | |
| 'PRODID:-//Minnebar Schedule Bookmarklet//EN', | |
| 'CALSCALE:GREGORIAN', | |
| 'METHOD:PUBLISH' | |
| ]; | |
| events.forEach((ev, i) => { | |
| const uid = 'minnebar-' + ev.start + '-' + i + '@minnestar.org'; | |
| const now = toICSDate(Math.floor(Date.now() / 1000)); | |
| lines.push('BEGIN:VEVENT'); | |
| lines.push(foldLine('UID:' + uid)); | |
| lines.push('DTSTAMP:' + now); | |
| lines.push('DTSTART:' + toICSDate(ev.start)); | |
| lines.push('DTEND:' + toICSDate(ev.end)); | |
| lines.push(foldLine('SUMMARY:' + escapeICS(ev.title))); | |
| if (ev.location) lines.push(foldLine('LOCATION:' + escapeICS(ev.location))); | |
| if (ev.description) lines.push(foldLine('DESCRIPTION:' + escapeICS(ev.description))); | |
| lines.push('END:VEVENT'); | |
| }); | |
| lines.push('END:VCALENDAR'); | |
| const icsContent = lines.join('\r\n'); | |
| const blob = new Blob([icsContent], { type: 'text/calendar;charset=utf-8' }); | |
| const url = URL.createObjectURL(blob); | |
| const a = document.createElement('a'); | |
| a.href = url; | |
| a.download = 'minnebar-schedule.ics'; | |
| document.body.appendChild(a); | |
| a.click(); | |
| document.body.removeChild(a); | |
| URL.revokeObjectURL(url); | |
| alert('Downloaded ' + events.length + ' session(s) to minnebar-schedule.ics'); | |
| })(); |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://kagi.com/assistant/d4a8f045-46aa-4dcd-9ee9-c0d681f62ff2