aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2016-05-27 07:01:48 -0700
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2016-05-27 07:01:48 -0700
commit6b673bcb11c01dec2406080d8fe2cba2f3a4ff5f (patch)
treea215564393aaebdfbd0b0b0afc57650a011c45fb
downloadcalendar-6b673bcb11c01dec2406080d8fe2cba2f3a4ff5f.zip
calendar-6b673bcb11c01dec2406080d8fe2cba2f3a4ff5f.tar.bz2
Adds website side stuff.
-rw-r--r--calendar.css62
-rw-r--r--calendar.js226
-rw-r--r--get.php74
-rw-r--r--index.ssi134
4 files changed, 496 insertions, 0 deletions
diff --git a/calendar.css b/calendar.css
new file mode 100644
index 0000000..9d21d49
--- /dev/null
+++ b/calendar.css
@@ -0,0 +1,62 @@
+#classes td
+{
+ padding-right: 1.5em;
+/* text-align:center; */
+}
+
+#classes .class_id
+{
+ font-weight:bold;
+}
+.message a,
+.message a:visited
+.message a:hover
+{
+ color: #066;
+}
+
+.message table
+{
+ margin-bottom: 1em;
+}
+
+.message hr
+{
+ margin-top: 1.2em;
+ margin-top: 1.2em;
+}
+
+.message h3
+{
+ margin-top: 1em;
+}
+
+.message h2
+{
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+ font-size: 1.3em;
+ margin-left: -1.3em;
+}
+
+span.positive
+{
+ color: #070;
+}
+
+span.negative
+{
+ color: #700;
+}
+
+.message h1.important
+{
+ color: #B72929;
+ margin-bottom: 1em;
+}
+
+#url_sources
+{
+ margin-top: 1em;
+ margin-bottom: 1EM;
+}
diff --git a/calendar.js b/calendar.js
new file mode 100644
index 0000000..7945900
--- /dev/null
+++ b/calendar.js
@@ -0,0 +1,226 @@
+var mas = mas || new Object();
+mas.calendar = new Object();
+mas.calendar.private = new Object();
+mas.calendar.private.curriculum_groups_file = new Array();
+mas.calendar.private.curriculum_classes_file = new Array();
+mas.calendar.private.groups_url_sources = null;
+
+mas.calendar.curriculums = null;
+mas.calendar.groups = null;
+mas.calendar.classes = null;
+mas.calendar.output_url = null;
+mas.calendar.qrcode = null;
+mas.calendar.url_sources = null;
+
+mas.calendar.private.add_curriculum =
+function (id, fullname, groups, classes)
+{
+ var entry;
+
+ if (fullname == "")
+ {
+ return;
+ }
+
+ entry = "<option value=" + id + ">" + fullname + "</option>";
+
+ mas.calendar.curriculums.innerHTML = entry + mas.calendar.curriculums.innerHTML;
+
+ mas.calendar.private.curriculum_groups_file[id] = groups;
+ mas.calendar.private.curriculum_classes_file[id] = classes;
+};
+
+mas.calendar.private.add_group =
+function (data)
+{
+ var entry, i, url_sources;
+
+ if (data[0] == "")
+ {
+ return;
+ }
+
+ url_sources = new Array();
+
+ for (i = 3; i < data.length; i += 2)
+ {
+ url_sources.push(data[i]);
+ }
+
+ mas.calendar.private.groups_url_sources[data[1]] = url_sources;
+
+ entry = "<option value=" + data[1] + ">" + data[0] + "</option>";
+
+ mas.calendar.groups.innerHTML = entry + mas.calendar.groups.innerHTML;
+};
+
+mas.calendar.private.add_class =
+function (fullname, id)
+{
+ var entry;
+
+ if (fullname == "")
+ {
+ return;
+ }
+
+ entry =
+ (
+ "<tr><td class=\"class_checkbox\"><input type=\"checkbox\" "
+ + "onclick=\"mas.calendar.generate_url();\" name=\"classes\" value=\""
+ + id
+ + "\" /></td><td class=\"class_id\">"
+ + id
+ + "</td><td class=\"class_fullname\">"
+ + fullname
+ + "</td></tr>"
+ );
+
+ mas.calendar.classes.innerHTML = entry + mas.calendar.classes.innerHTML;
+};
+
+mas.calendar.private.load_curriculums =
+function ()
+{
+ var lines, i, val;
+
+ lines = this.responseText.split('\n');
+
+ for (i = lines.length; i --> 0;)
+ {
+ val = lines[i].split("::");
+ mas.calendar.private.add_curriculum(i, val[0], val[1], val[2]);
+ }
+
+ mas.calendar.select_curriculum();
+};
+
+mas.calendar.private.load_groups =
+function ()
+{
+ var lines, i, j, val;
+
+ mas.calendar.groups.innerHTML = "";
+ mas.calendar.private.groups_url_sources = new Array();
+
+ lines = this.responseText.split('\n');
+
+ for (i = lines.length; i --> 0;)
+ {
+ val = lines[i].split("::");
+ mas.calendar.private.add_group(val);
+ }
+
+ mas.calendar.select_group();
+};
+
+mas.calendar.private.load_classes =
+function ()
+{
+ var lines, i, val;
+
+ mas.calendar.classes.innerHTML = "";
+
+ lines = this.responseText.split('\n');
+
+ for (i = lines.length; i --> 0;)
+ {
+ val = lines[i].split("::");
+ mas.calendar.private.add_class(val[0], val[2]);
+ }
+
+ mas.calendar.generate_url();
+};
+
+mas.calendar.private.get_file =
+function (file, fun)
+{
+ var req
+ req = new XMLHttpRequest();
+
+ req.onload = fun;
+
+ req.open("get", file, true);
+ req.send();
+};
+
+mas.calendar.select_curriculum =
+function ()
+{
+ var fullname;
+
+ fullname = mas.calendar.curriculums.value;
+
+ mas.calendar.private.get_file
+ (
+ ("data/" + mas.calendar.private.curriculum_groups_file[fullname]),
+ mas.calendar.private.load_groups
+ );
+
+ mas.calendar.private.get_file
+ (
+ ("data/" + mas.calendar.private.curriculum_classes_file[fullname]),
+ mas.calendar.private.load_classes
+ );
+};
+
+mas.calendar.select_group =
+function ()
+{
+ var data, i, result;
+
+ mas.calendar.url_sources.innerHTML = "";
+
+ data = mas.calendar.private.groups_url_sources[mas.calendar.groups.value];
+ result = "";
+
+ for (i = 0; i < data.length; ++i)
+ {
+ result += "<li>" + data[i] + "</li>";
+ }
+
+ mas.calendar.url_sources.innerHTML = result;
+};
+
+mas.calendar.populate =
+function ()
+{
+ mas.calendar.curriculums = document.getElementById("curriculums");
+ mas.calendar.groups = document.getElementById("groups");
+ mas.calendar.classes = document.getElementById("classes");
+ mas.calendar.output_url = document.getElementById("output_url");
+ mas.calendar.qrcode = document.getElementById("qrcode");
+ mas.calendar.url_sources = document.getElementById("url_sources");
+
+ mas.calendar.private.get_file
+ (
+ "data/CURRICULUMS",
+ mas.calendar.private.load_curriculums
+ );
+};
+
+mas.calendar.generate_url =
+function ()
+{
+ var url, loc, i, classes;
+
+ url = document.location.href.toString();
+ loc = url.substring(0, (url.lastIndexOf("/") + 1));
+ loc = loc + "get.php?g=" + mas.calendar.groups.value + "&m=unknown,";
+
+ classes = document.getElementsByName("classes");
+
+ for (i = classes.length; i --> 0;)
+ {
+ if (classes[i].checked)
+ {
+ loc = loc + classes[i].value + ",";
+ }
+ }
+
+ loc = loc.substring(0, (loc.length - 1));
+
+ mas.calendar.qrcode.innerHTML= "";
+ mas.calendar.output_url.setAttribute("value", loc);
+ jQuery('#qrcode').qrcode(loc);
+};
diff --git a/get.php b/get.php
new file mode 100644
index 0000000..d816573
--- /dev/null
+++ b/get.php
@@ -0,0 +1,74 @@
+<?php
+ header('Content-Type: text/calendar; charset=UTF-8');
+
+ $group = $_GET["g"];
+ $modules = explode(",", $_GET["m"]);
+
+ if (!preg_match("/^[0-9A-Za-z_-]+$/", $group))
+ {
+ echo "[E] Invalid group ID: " . $group;
+
+ exit -1;
+ }
+
+ $vcalendar = "BEGIN:VCALENDAR\r\n";
+ $vcalendar .= "VERSION:2.0\r\n";
+ $vcalendar .= "PRODID:-//MultiAgentSystems.org//University Calendar//EN\r\n";
+ $vcalendar .= "CALSCALE:GREGORIAN\r\n";
+ $vcalendar .= "METHOD:PUBLISH\r\n";
+ $vcalendar .= "X-WR-CALNAME:";
+ $vcalendar .= str_replace("_", " ", $group);
+ $vcalendar .= "\r\n";
+ $vcalendar .= "X-WR-TIMEZONE:Europe/Paris\r\n";
+ $vcalendar .= "BEGIN:VTIMEZONE\r\n";
+ $vcalendar .= "TZID:Europe/Paris\r\n";
+ $vcalendar .= "X-LIC-LOCATION:Europe/Paris\r\n";
+ $vcalendar .= "BEGIN:DAYLIGHT\r\n";
+ $vcalendar .= "TZOFFSETFROM:+0100\r\n";
+
+ $vcalendar .= "TZOFFSETTO:+0200\r\n";
+ $vcalendar .= "TZNAME:CEST\r\n";
+ $vcalendar .= "DTSTART:19810329T020000\r\n";
+ $vcalendar .= "RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU\r\n";
+ $vcalendar .= "END:DAYLIGHT\r\n";
+ $vcalendar .= "BEGIN:STANDARD\r\n";
+ $vcalendar .= "TZOFFSETFROM:+0200\r\n";
+ $vcalendar .= "TZOFFSETTO:+0100\r\n";
+ $vcalendar .= "TZNAME:CET\r\n";
+ $vcalendar .= "DTSTART:19961027T030000\r\n";
+ $vcalendar .= "RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU\r\n";
+ $vcalendar .= "END:STANDARD\r\n";
+ $vcalendar .= "END:VTIMEZONE\r\n";
+
+ echo $vcalendar;
+
+ foreach ($modules as $module)
+ {
+ $ics_fragment = "output/" . $group . "_" . $module . ".ics";
+ if (!preg_match("/^[0-9A-Za-z_-]+$/", $module))
+ {
+ echo "[E] Invalid module ID: " . $module;
+
+ exit -1;
+ }
+
+ if (file_exists($ics_fragment))
+ {
+ readfile($ics_fragment);
+ }
+ }
+
+ $group_ics_file = $group . ".ics";
+
+ if (file_exists($group_ics_file))
+ {
+ readfile($group_ics_file);
+ }
+
+ if (file_exists("warnings.ics"))
+ {
+ readfile("warnings.ics");
+ }
+
+ echo "END:VCALENDAR";
+?>
diff --git a/index.ssi b/index.ssi
new file mode 100644
index 0000000..2435328
--- /dev/null
+++ b/index.ssi
@@ -0,0 +1,134 @@
+<!--#include virtual="../ssi/shared_head.ssi" -->
+ <title>Calendar @ Multi-Agent Systems (.org)</title>
+ <link rel="stylesheet" type="text/css" href="calendar.css">
+ <script src="./qrcode/jquery.min.js"></script>
+ <script src="./qrcode/jquery.qrcode.min.js"></script>
+ <script src="./calendar.js"></script>
+ </head>
+ <body>
+ <!--#include virtual="../ssi/header.ssi" -->
+ <div class="message">
+ <center>
+ <h1 class="important">Warning</h1>
+ </center>
+ This service is no longer available.<br \>
+ Feel free to download its
+ <a href="/repositories_old/calendar/">source code</a> (available under the
+ <a href="/calendar/LICENSE">"New BSD License"</a>)
+ and setup your own.
+ </div>
+ <br />
+ <div class="message">
+ <center>
+ <h1>Personalized ICS Calendar</h1>
+ Version 1.7 (Last build on 2015/11/06):
+ </center>
+ <h3>Step 1: Select a Curriculum</h3>
+ <select onchange="mas.calendar.select_curriculum()" id="curriculums">
+ </select>
+ <h3>Step 2: Select a Group</h3>
+ <select onchange="mas.calendar.select_group()" id="groups">
+ </select>
+ <h3>Step 3: Select Class(es)</h3>
+ <table id="classes">
+ </table>
+ <h3>Result:</h3>
+ <input
+ id="output_url"
+ readonly="readonly"
+ style="width: 100%;"
+ type="text" />
+ <center>
+ <div id="qrcode"></div>
+ </center>
+ </div>
+ <div class="message">
+ <center>
+ <h1 class="important">Important</h1>
+ </center>
+ Here is the list of URLs that are currently used to get information
+ for this group, please make sure it is complete:
+ <ul id="url_sources">
+ </ul>
+ If you think an URL is missing, please
+ <a href="/contact/">contact me</a>.
+ <br />
+ Also note that it might be because
+ an class you take belongs to another curriculum (i.e. this is not the
+ main curriculum for this class) that is also handled by this program,
+ you will have to get its events from the main curriculum
+ (e.g. those from <i>M2RIT RIBDM</i> who want the <i>FAI</i> class need
+ to also generate an URL for the <i>M2IM</i> curriculum, because
+ <i>FAI</i> events officially belong to the <i>M2IM</i> calendar).
+ </div>
+ <script>mas.calendar.populate();</script>
+ <div class="message">
+ <center>
+ <h2>Additional Information</h2>
+ </center>
+ <ul>
+ <li>
+ If you want a curriculum to be added, just ask.
+ </li>
+ <li>
+ Calendars are refreshed every two hours.
+ </li>
+ <li>
+ Computations are done on the <i>Antares</i> server, you can check
+ if the server is running by going to <a href="/servers/">the servers
+ page</a>. Note that you never directly communicate with
+ <i>Antares</i>: <i>Antares</i> sends its data to this webserver
+ and you ask the webserver for them. Therefore, if <i>Antares</i> is
+ down, it will only result in the data not being updated and you will
+ not be made aware of it.
+ </li>
+ <li>
+ Bug reports and feature requests can be done through
+ <a href="/repositories_old/calendar/">the project's repository</a>,
+ by <a href="/contact/">contacting me</a> or alternatively by using
+ <a href="/bugzilla/">the bug report system</a>. Feedback and feature
+ request are welcome, so do not hesitate.
+ </li>
+ <li>
+ If "unknown" is part of the "m" parameter of the URL, unrecognized
+ events are not filtered out. This is why you might sometimes see
+ events that are not meant for you (as soon as I figure out where
+ they belong, they get properly filtered).
+ <br />
+ Removing this tag is not recommended.
+ </li>
+ <li>
+ Source code is available
+ <a href="/repositories_old/calendar/">here</a>
+ under the <a href="/calendar/LICENSE">"New BSD License"</a>.
+ </li>
+ <li>
+ The <a href="https://en.wikipedia.org/wiki/QR_code">QRCode</a> is
+ generated using
+ <a href="https://github.com/jeromeetienne/jquery-qrcode/">
+ jquery-qrcode
+ </a>.
+ </li>
+ <li>
+ The generated ICS documents were validated using
+ <a href="http://icalvalid.cloudapp.net/">iCalendar Validator</a>.
+ </li>
+ <li>
+ <b>M2RIT RIBDM</b>'s Google Calendar source will not be handled by
+ this tool as long as it stays the gaping security hole it currently
+ is (its admin login credentials are public). Users are encouraged to
+ ask the curriculum's manager for a better system.
+ </li>
+ </ul>
+ </div>
+
+ <div class="message">
+ <center>
+ <h2>Last log(s)</h2>
+ </center>
+<pre>
+<!--#include file="last_log.log" -->
+</pre>
+ </div>
+ </body>
+</html>