Last active
January 11, 2018 07:23
-
-
Save nijssen/72c67403365d48a6255be17c10b46a81 to your computer and use it in GitHub Desktop.
Generates a vCalendar file from PeopleSoft Campus Solutions "my class schedule".
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
// ==UserScript== | |
// @name Portal Events finder | |
// @namespace http://www.bevroren.com/ | |
// @version 0.1 | |
// @description Transfers events from the portal page to google calendar | |
// @author Thomas Nijssen | |
// @match https://ais-cs.ucsc.edu/psc/csprd/EMPLOYEE/PSFT_CSPRD/c/SA_LEARNER_SERVICES.SSR_SSENRL_LIST.GBL* | |
// @match https://ais-cs.ucsc.edu/psc/csprd/EMPLOYEE/HRMS/c/SA_LEARNER_SERVICES.SSR_SSENRL_LIST.GBL* | |
// @match https://my.ucsc.edu/psc/csprd/EMPLOYEE/PSFT_CSPRD/c/SA_LEARNER_SERVICES.SSR_SSENRL_LIST.GBL* | |
// @match https://my.ucsc.edu/psc/csprd/EMPLOYEE/HRMS/c/SA_LEARNER_SERVICES.SSR_SSENRL_LIST.GBL* | |
// @grant none | |
// @require http://code.jquery.com/jquery.js | |
// ==/UserScript== | |
//(function() { | |
var events = []; | |
jQuery("tr[id^='trCLASS_MTG_VW']").each(function(i, el) { | |
var cname = jQuery(jQuery(el.closest("table.PSGROUPBOXWBO")).find("td")[0]).text().trim().split(" - "); | |
var times = parsetimes(jQuery(el.cells[3]).text().trim()); | |
var daterange = jQuery(el.cells[6]).text().trim().split(" - "); | |
var sectionid = jQuery(el.cells[1]).text().trim(); | |
var sectiontype = jQuery(el.cells[2]).text().trim(); //lecture, discussion, etc | |
var room = jQuery(el.cells[4]).text().trim(); | |
if(!times.start) return null; //like an online class | |
events.push({ | |
classid: cname[0], | |
classname: cname[1], | |
sectionid: sectionid, | |
sectiontype: sectiontype, | |
endday: new Date(daterange[1]), | |
start: datetimeconv(daterange[0], times.start, times.days[0]), | |
end: datetimeconv(daterange[0], times.end, times.days[0]), | |
days: times.days, | |
room: room | |
}); | |
}); | |
//window.prompt("Send this to Thomas:", JSON.stringify(events)); | |
//sendevents(events); | |
window.myevents = events; | |
makeical(events); | |
function titlefmt(e, formatstring) { | |
return formatstring.replace(/\*([a-z]+)/g, function() { | |
return e[arguments[1]]; | |
}); | |
} | |
function icaldatefmt(dobj) { | |
var thingy = function(want, i, arr) { | |
var f = this["get" + want]; | |
//console.log(arguments); | |
//console.dir(this); | |
try { | |
var s = f.call(this); | |
s += arr[i] == "Month" ? 1 : 0; | |
if(("" + s).length == 1) s = "0" + s; | |
return s; | |
} catch(e) { | |
return "OOPS"; | |
} | |
}; | |
return ["FullYear", "Month", "Date"].map(thingy, dobj).join("") + "T" + ["Hours", "Minutes", "Seconds"].map(thingy, dobj).join(""); | |
} | |
function makeical(eventslist) { | |
var myname = jQuery("*[id*='PERSON_NAME']")[0].textContent.trim(); | |
var icaltext = ["BEGIN:VCALENDAR", "VERSION:2.0", "CALSCALE:GREGORIAN", "X-NAME:" + myname]; | |
for(var eventindex in eventslist) { | |
var event = eventslist[eventindex]; | |
if(!event || !event.start) continue; | |
icaltext.push("BEGIN:VEVENT"); | |
icaltext.push("DTSTART:" + icaldatefmt(event.start)); | |
icaltext.push("DTEND:" + icaldatefmt(event.end)); | |
icaltext.push("UID:" + ("" + Math.random()).replace("0.", "") + "@" + location.hostname); | |
icaltext.push("SUMMARY:" + titlefmt(event, "*classid *sectionid - *sectiontype")); | |
event.endday.setHours(23, 59, 59); | |
icaltext.push("RRULE:FREQ=WEEKLY;UNTIL=" + icaldatefmt(event.endday) + ";WKST=" + event.days[0] + ";BYDAY=" + event.days.join(",")); | |
icaltext.push("LOCATION:" + event.room); | |
icaltext.push("END:VEVENT"); | |
} | |
icaltext.push("END:VCALENDAR"); | |
//var icalfile = btoa(icaltext.join("\r\n")); | |
var icalfile = encodeURIComponent(icaltext.join("\r\n")); | |
//jQuery("#ACE_width > tbody > tr:nth-child(9)").html('<td colspan=3></td><td colspan=3><a href="data:text/calendar;base64,' + icalfile + '">Download</a>'); | |
jQuery("#ACE_width > tbody > tr:nth-child(9)").html('<td colspan=3></td><td colspan=3><a href="data:text/calendar,' + icalfile + '">Download</a>'); | |
} | |
function __thing(x, i) { | |
if(!x.start) return []; | |
var ret = [ jQuery("<input />", { type: "hidden", name: "havethis", value: i }) ]; | |
for(var prop in x) { | |
ret.push(jQuery("<input />", { type: "hidden", name: i + prop, value: x[prop] })); | |
} | |
return ret; | |
} | |
function datetimeconv(day, time, firstday) { | |
if(!time) return null; //online classes have no time | |
var timeparts = time.match(/(\d+):(\d+)(P|A)/); | |
var d = new Date(day); | |
var h = parseInt(timeparts[1]); | |
d.setHours(parseInt(h) + ((timeparts[3] == "P" && h < 12)? 12 : 0)); | |
d.setMinutes(parseInt(timeparts[2])); | |
//set first day to be the right day of the week | |
var weekdays = ["SU", "MO", "TU", "WE", "TH", "FR", "SA"]; | |
var oldday = d.getDay(); | |
var actualday = weekdays.indexOf(firstday); | |
d.setHours(d.getHours() + (24 * (actualday - oldday))); | |
return d; | |
} | |
function parsetimes(text) { | |
var parts = text.split(/\s/); | |
var dayparts = parts[0].split(""); | |
var days = []; | |
for(var i = 0; i < dayparts.length; i += 2) { | |
days.push(("" + dayparts[i] + dayparts[i + 1]).toUpperCase()); | |
} | |
return { | |
days: days, | |
start: parts[1], | |
end: parts[3] | |
}; | |
} | |
//})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment