42cal_bookmarklet/42cal_bookmarklet.min.js

2 lines
1.7 KiB
JavaScript

b="https://profile.intra.42.fr/",n=(t,r)=>fetch(t).then(t=>{if(!t.ok)throw Error(`HTTP Error! Status:${t.status}`);return t.text()}).then(t=>r(null,t)).catch(t=>r(t,"")),a=t=>new Date(t).toISOString().replace(/[-:]/g,"").split(".")[0]+"Z",n(b+`events.json?start=${d=(q=new Date).getFullYear()}-${u=String(q.getMonth()+1).padStart(2,"0")}-${v=String(q.getDate()).padStart(2,"0")}&end=${d+1}-${u}-${v}`,(t,r)=>{Promise.all(JSON.parse(r).map(t=>new Promise(r=>{t.id&&t.title&&t.end&&t.start?n(b+`${kind="exam"==t.kind?"exams":"events"}/${t.id}`,(o,l)=>{o?(alert("Error2:"+o),r()):(o=(h=(parser=new DOMParser).parseFromString(l,"text/html")).querySelector(".modal-body").textContent,e=h.querySelector(".icon-clock")?.parentElement.children[2].textContent,c=h.querySelector(".icon-location")?.parentElement.children[1].textContent,t.p=o||"Could not fetch p",e?t.e=e:t.e="Could not fetch duration",c?t.f=c:t.f="Could not fetch location",r(t))}):r()}))).then(t=>(t.filter(t=>t),x="<h1>Download iCals</h1><ol>",t.sort((t,r)=>new Date(t.start)-new Date(r.start)).forEach((t,r)=>{x+=`<li><a href="data:text/calendar;base64,${btoa(unescape(encodeURIComponent(`BEGIN:VCALENDAR\nVERSION:1.0\nPRODID:-//42Cal//\nBEGIN:VEVENT\nUID:${t.id}\nSUMMARY:${t.title}\nDESCRIPTION:${`DURATION:${t.e}\\n\\n`+t.p.trim()}\nLOCATION:${t.f}\nDTSTART:${a(t.start)}\nDTEND:${a(t.end)}\nEND:VEVENT\nEND:VCALENDAR`)))}" download="${t.title?t.title.replace(/\s+/g,"_"):`event_${r+1}`}.ics"><button ${t.is_subscribed&&"style=background:lightgreen"}>${new Date(t.start).toDateString()}:Download "<span style="color:#1443d3;font-weight:700;">${t.title||"Event"}.ics</span>"</button></a></li>`}),x+"</ol>")).then(t=>window.open("","_blank").document.write(t)).catch(t=>alert("Error1:"+t))});