Skip to content

Instantly share code, notes, and snippets.

@nijssen
Last active January 11, 2018 07:23
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 nijssen/72c67403365d48a6255be17c10b46a81 to your computer and use it in GitHub Desktop.
Save nijssen/72c67403365d48a6255be17c10b46a81 to your computer and use it in GitHub Desktop.
Generates a vCalendar file from PeopleSoft Campus Solutions "my class schedule".
// ==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