diff options
author | RunasSudo <runassudo@yingtongli.me> | 2017-03-10 19:46:28 +1100 |
---|---|---|
committer | RunasSudo <runassudo@yingtongli.me> | 2017-03-10 19:46:28 +1100 |
commit | dbec55f3706665dc05ad4961b08c1d4d91e6ecf2 (patch) | |
tree | 66575a28423f42fe5897f52e69e0e3f9a563df80 | |
parent | 91e65afe8c46ff4917625e4d82994a0a5366ec72 (diff) |
Improve error messages
-rw-r--r-- | allocics.js | 170 | ||||
-rw-r--r-- | bootstrap.js | 14 | ||||
-rw-r--r-- | index.html | 2 |
3 files changed, 100 insertions, 86 deletions
diff --git a/allocics.js b/allocics.js index 584b8d3..a8c17f3 100644 --- a/allocics.js +++ b/allocics.js @@ -1,9 +1,3 @@ -/*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */ -!function(t){"use strict";if(t.URL=t.URL||t.webkitURL,t.Blob&&t.URL)try{return void new Blob}catch(e){}var n=t.BlobBuilder||t.WebKitBlobBuilder||t.MozBlobBuilder||function(t){var e=function(t){return Object.prototype.toString.call(t).match(/^\[object\s(.*)\]$/)[1]},n=function(){this.data=[]},o=function(t,e,n){this.data=t,this.size=t.length,this.type=e,this.encoding=n},i=n.prototype,a=o.prototype,r=t.FileReaderSync,c=function(t){this.code=this[this.name=t]},l="NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR".split(" "),s=l.length,u=t.URL||t.webkitURL||t,d=u.createObjectURL,f=u.revokeObjectURL,R=u,p=t.btoa,h=t.atob,b=t.ArrayBuffer,g=t.Uint8Array,w=/^[\w-]+:\/*\[?[\w\.:-]+\]?(?::[0-9]+)?/;for(o.fake=a.fake=!0;s--;)c.prototype[l[s]]=s+1;return u.createObjectURL||(R=t.URL=function(t){var e,n=document.createElementNS("http://www.w3.org/1999/xhtml","a");return n.href=t,"origin"in n||("data:"===n.protocol.toLowerCase()?n.origin=null:(e=t.match(w),n.origin=e&&e[1])),n}),R.createObjectURL=function(t){var e,n=t.type;return null===n&&(n="application/octet-stream"),t instanceof o?(e="data:"+n,"base64"===t.encoding?e+";base64,"+t.data:"URI"===t.encoding?e+","+decodeURIComponent(t.data):p?e+";base64,"+p(t.data):e+","+encodeURIComponent(t.data)):d?d.call(u,t):void 0},R.revokeObjectURL=function(t){"data:"!==t.substring(0,5)&&f&&f.call(u,t)},i.append=function(t){var n=this.data;if(g&&(t instanceof b||t instanceof g)){for(var i="",a=new g(t),l=0,s=a.length;s>l;l++)i+=String.fromCharCode(a[l]);n.push(i)}else if("Blob"===e(t)||"File"===e(t)){if(!r)throw new c("NOT_READABLE_ERR");var u=new r;n.push(u.readAsBinaryString(t))}else t instanceof o?"base64"===t.encoding&&h?n.push(h(t.data)):"URI"===t.encoding?n.push(decodeURIComponent(t.data)):"raw"===t.encoding&&n.push(t.data):("string"!=typeof t&&(t+=""),n.push(unescape(encodeURIComponent(t))))},i.getBlob=function(t){return arguments.length||(t=null),new o(this.data.join(""),t,"raw")},i.toString=function(){return"[object BlobBuilder]"},a.slice=function(t,e,n){var i=arguments.length;return 3>i&&(n=null),new o(this.data.slice(t,i>1?e:this.data.length),n,this.encoding)},a.toString=function(){return"[object Blob]"},a.close=function(){this.size=0,delete this.data},n}(t);t.Blob=function(t,e){var o=e?e.type||"":"",i=new n;if(t)for(var a=0,r=t.length;r>a;a++)Uint8Array&&t[a]instanceof Uint8Array?i.append(t[a].buffer):i.append(t[a]);var c=i.getBlob(o);return!c.slice&&c.webkitSlice&&(c.slice=c.webkitSlice),c};var o=Object.getPrototypeOf||function(t){return t.__proto__};t.Blob.prototype=o(new t.Blob)}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this.content||this); - -/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ -var saveAs=saveAs||function(e){"use strict";if(typeof e==="undefined"||typeof navigator!=="undefined"&&/MSIE [1-9]\./.test(navigator.userAgent)){return}var t=e.document,n=function(){return e.URL||e.webkitURL||e},r=t.createElementNS("http://www.w3.org/1999/xhtml","a"),o="download"in r,a=function(e){var t=new MouseEvent("click");e.dispatchEvent(t)},i=/constructor/i.test(e.HTMLElement)||e.safari,f=/CriOS\/[\d]+/.test(navigator.userAgent),u=function(t){(e.setImmediate||e.setTimeout)(function(){throw t},0)},s="application/octet-stream",d=1e3*40,c=function(e){var t=function(){if(typeof e==="string"){n().revokeObjectURL(e)}else{e.remove()}};setTimeout(t,d)},l=function(e,t,n){t=[].concat(t);var r=t.length;while(r--){var o=e["on"+t[r]];if(typeof o==="function"){try{o.call(e,n||e)}catch(a){u(a)}}}},p=function(e){if(/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)){return new Blob([String.fromCharCode(65279),e],{type:e.type})}return e},v=function(t,u,d){if(!d){t=p(t)}var v=this,w=t.type,m=w===s,y,h=function(){l(v,"writestart progress write writeend".split(" "))},S=function(){if((f||m&&i)&&e.FileReader){var r=new FileReader;r.onloadend=function(){var t=f?r.result:r.result.replace(/^data:[^;]*;/,"data:attachment/file;");var n=e.open(t,"_blank");if(!n)e.location.href=t;t=undefined;v.readyState=v.DONE;h()};r.readAsDataURL(t);v.readyState=v.INIT;return}if(!y){y=n().createObjectURL(t)}if(m){e.location.href=y}else{var o=e.open(y,"_blank");if(!o){e.location.href=y}}v.readyState=v.DONE;h();c(y)};v.readyState=v.INIT;if(o){y=n().createObjectURL(t);setTimeout(function(){r.href=y;r.download=u;a(r);h();c(y);v.readyState=v.DONE});return}S()},w=v.prototype,m=function(e,t,n){return new v(e,t||e.name||"download",n)};if(typeof navigator!=="undefined"&&navigator.msSaveOrOpenBlob){return function(e,t,n){t=t||e.name||"download";if(!n){e=p(e)}return navigator.msSaveOrOpenBlob(e,t)}}w.abort=function(){};w.readyState=w.INIT=0;w.WRITING=1;w.DONE=2;w.error=w.onwritestart=w.onprogress=w.onwrite=w.onabort=w.onerror=w.onwriteend=null;return m}(typeof self!=="undefined"&&self||typeof window!=="undefined"&&window||this.content);if(typeof module!=="undefined"&&module.exports){module.exports.saveAs=saveAs}else if(typeof define!=="undefined"&&define!==null&&define.amd!==null){define("FileSaver.js",function(){return saveAs})} - /* allocics.js - One-click export of Allocate+ timetables to ICS format Copyright © 2017 RunasSudo (Yingtong Li) @@ -22,84 +16,106 @@ var saveAs=saveAs||function(e){"use strict";if(typeof e==="undefined"||typeof na along with this program. If not, see <http://www.gnu.org/licenses/>. */ -// ALLOCATE+ STUFF +(function() { + // Sanity checks + if (typeof(timetableInit) === "undefined") { + alert('This doesn\'t seem to be an Allocate+ page. Please log in to Allocate+ before clicking the bookmark.'); + return; + } + + // Initialise the timetable if necessary + if (!timetableInit) { + initTimetable(); + } + + // Switch to the timetable page + activityDetailsGoBack("timetable-tpl"); + + // Load some dependencies + /*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */ + !function(t){"use strict";if(t.URL=t.URL||t.webkitURL,t.Blob&&t.URL)try{return void new Blob}catch(e){}var n=t.BlobBuilder||t.WebKitBlobBuilder||t.MozBlobBuilder||function(t){var e=function(t){return Object.prototype.toString.call(t).match(/^\[object\s(.*)\]$/)[1]},n=function(){this.data=[]},o=function(t,e,n){this.data=t,this.size=t.length,this.type=e,this.encoding=n},i=n.prototype,a=o.prototype,r=t.FileReaderSync,c=function(t){this.code=this[this.name=t]},l="NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR".split(" "),s=l.length,u=t.URL||t.webkitURL||t,d=u.createObjectURL,f=u.revokeObjectURL,R=u,p=t.btoa,h=t.atob,b=t.ArrayBuffer,g=t.Uint8Array,w=/^[\w-]+:\/*\[?[\w\.:-]+\]?(?::[0-9]+)?/;for(o.fake=a.fake=!0;s--;)c.prototype[l[s]]=s+1;return u.createObjectURL||(R=t.URL=function(t){var e,n=document.createElementNS("http://www.w3.org/1999/xhtml","a");return n.href=t,"origin"in n||("data:"===n.protocol.toLowerCase()?n.origin=null:(e=t.match(w),n.origin=e&&e[1])),n}),R.createObjectURL=function(t){var e,n=t.type;return null===n&&(n="application/octet-stream"),t instanceof o?(e="data:"+n,"base64"===t.encoding?e+";base64,"+t.data:"URI"===t.encoding?e+","+decodeURIComponent(t.data):p?e+";base64,"+p(t.data):e+","+encodeURIComponent(t.data)):d?d.call(u,t):void 0},R.revokeObjectURL=function(t){"data:"!==t.substring(0,5)&&f&&f.call(u,t)},i.append=function(t){var n=this.data;if(g&&(t instanceof b||t instanceof g)){for(var i="",a=new g(t),l=0,s=a.length;s>l;l++)i+=String.fromCharCode(a[l]);n.push(i)}else if("Blob"===e(t)||"File"===e(t)){if(!r)throw new c("NOT_READABLE_ERR");var u=new r;n.push(u.readAsBinaryString(t))}else t instanceof o?"base64"===t.encoding&&h?n.push(h(t.data)):"URI"===t.encoding?n.push(decodeURIComponent(t.data)):"raw"===t.encoding&&n.push(t.data):("string"!=typeof t&&(t+=""),n.push(unescape(encodeURIComponent(t))))},i.getBlob=function(t){return arguments.length||(t=null),new o(this.data.join(""),t,"raw")},i.toString=function(){return"[object BlobBuilder]"},a.slice=function(t,e,n){var i=arguments.length;return 3>i&&(n=null),new o(this.data.slice(t,i>1?e:this.data.length),n,this.encoding)},a.toString=function(){return"[object Blob]"},a.close=function(){this.size=0,delete this.data},n}(t);t.Blob=function(t,e){var o=e?e.type||"":"",i=new n;if(t)for(var a=0,r=t.length;r>a;a++)Uint8Array&&t[a]instanceof Uint8Array?i.append(t[a].buffer):i.append(t[a]);var c=i.getBlob(o);return!c.slice&&c.webkitSlice&&(c.slice=c.webkitSlice),c};var o=Object.getPrototypeOf||function(t){return t.__proto__};t.Blob.prototype=o(new t.Blob)}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this.content||this); + + /*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ + var saveAs=saveAs||function(e){"use strict";if(typeof e==="undefined"||typeof navigator!=="undefined"&&/MSIE [1-9]\./.test(navigator.userAgent)){return}var t=e.document,n=function(){return e.URL||e.webkitURL||e},r=t.createElementNS("http://www.w3.org/1999/xhtml","a"),o="download"in r,a=function(e){var t=new MouseEvent("click");e.dispatchEvent(t)},i=/constructor/i.test(e.HTMLElement)||e.safari,f=/CriOS\/[\d]+/.test(navigator.userAgent),u=function(t){(e.setImmediate||e.setTimeout)(function(){throw t},0)},s="application/octet-stream",d=1e3*40,c=function(e){var t=function(){if(typeof e==="string"){n().revokeObjectURL(e)}else{e.remove()}};setTimeout(t,d)},l=function(e,t,n){t=[].concat(t);var r=t.length;while(r--){var o=e["on"+t[r]];if(typeof o==="function"){try{o.call(e,n||e)}catch(a){u(a)}}}},p=function(e){if(/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)){return new Blob([String.fromCharCode(65279),e],{type:e.type})}return e},v=function(t,u,d){if(!d){t=p(t)}var v=this,w=t.type,m=w===s,y,h=function(){l(v,"writestart progress write writeend".split(" "))},S=function(){if((f||m&&i)&&e.FileReader){var r=new FileReader;r.onloadend=function(){var t=f?r.result:r.result.replace(/^data:[^;]*;/,"data:attachment/file;");var n=e.open(t,"_blank");if(!n)e.location.href=t;t=undefined;v.readyState=v.DONE;h()};r.readAsDataURL(t);v.readyState=v.INIT;return}if(!y){y=n().createObjectURL(t)}if(m){e.location.href=y}else{var o=e.open(y,"_blank");if(!o){e.location.href=y}}v.readyState=v.DONE;h();c(y)};v.readyState=v.INIT;if(o){y=n().createObjectURL(t);setTimeout(function(){r.href=y;r.download=u;a(r);h();c(y);v.readyState=v.DONE});return}S()},w=v.prototype,m=function(e,t,n){return new v(e,t||e.name||"download",n)};if(typeof navigator!=="undefined"&&navigator.msSaveOrOpenBlob){return function(e,t,n){t=t||e.name||"download";if(!n){e=p(e)}return navigator.msSaveOrOpenBlob(e,t)}}w.abort=function(){};w.readyState=w.INIT=0;w.WRITING=1;w.DONE=2;w.error=w.onwritestart=w.onprogress=w.onwrite=w.onabort=w.onerror=w.onwriteend=null;return m}(typeof self!=="undefined"&&self||typeof window!=="undefined"&&window||this.content);if(typeof module!=="undefined"&&module.exports){module.exports.saveAs=saveAs}else if(typeof define!=="undefined"&&define!==null&&define.amd!==null){define("FileSaver.js",function(){return saveAs})} -var YEAR = 2017; + // ALLOCATE+ STUFF -// Set to all weeks -//timetable.setCurrentView(new Date(2002, 6, 1)); -timetableAllWeeks(); + var YEAR = 2017; // TODO: Automatically detect this -var locationsEnglish = { - 'All': 'Alliance Lane', - 'Acc': 'Ancora Imparo Way', - 'Chn': 'Chancellors Walk', - 'Col': 'College Walk', - 'Exh': 'Exhibition Walk', - 'FGR': 'Ferntree Gully Road', - 'Inn': 'Innovation Walk', - 'Rnf': 'Rainforest Walk', - 'Res': 'Research Way', - 'Sce': 'Scenic Boulevard' -}; + // Set to all weeks + timetableAllWeeks(); -function parseLocation(loc) { - var match = loc.match(/^CL_([0-9]+)(All|Anc|Chn|Col|Exh|FGR|Inn|Rnf|Res|Sce)\/(.+)$/); - if (match === null) { - return null; - } - return match[1] + ' ' + locationsEnglish[match[2]] + ', ' + match[3]; -} + var locationsEnglish = { + 'All': 'Alliance Lane', + 'Acc': 'Ancora Imparo Way', + 'Chn': 'Chancellors Walk', + 'Col': 'College Walk', + 'Exh': 'Exhibition Walk', + 'FGR': 'Ferntree Gully Road', + 'Inn': 'Innovation Walk', + 'Rnf': 'Rainforest Walk', + 'Res': 'Research Way', + 'Sce': 'Scenic Boulevard' + }; -function pad2(num) { - if (num < 10) { - return '0' + num; + function parseLocation(loc) { + var match = loc.match(/^CL_([0-9]+)(All|Anc|Chn|Col|Exh|FGR|Inn|Rnf|Res|Sce)\/(.+)$/); + if (match === null) { + return null; + } + return match[1] + ' ' + locationsEnglish[match[2]] + ', ' + match[3]; } - return '' + num; -} -function dateToString(date) { - return date.getFullYear() + pad2(date.getMonth() + 1) + pad2(date.getDate()) + 'T' + pad2(date.getHours()) + pad2(date.getMinutes()) + pad2(date.getSeconds()); -} -var cal = [['BEGIN', 'VCALENDAR'], ['VERSION', '2.0'], ['PRODID', '-//RunasSudo//allocics.js//EN']]; -$.each(timetable.get_visible_events(), function(i, evt) { - var dates = weekpatternToDates(evt.node.day_of_week, evt.node.week_pattern, evt.node.start_date); - var startDateBits = evt.node.start_date.split('/'); - var startTimeBits = evt.node.start_time.split(':'); - - var dateString = dates; - var dateStringBits = dateString.split('/'); - var dateBegin = new Date(startDateBits[2], dateStringBits[1] - 1, dateStringBits[0], startTimeBits[0], startTimeBits[1]); - var dateEnd = new Date(dateBegin.getTime() + evt.node.duration * 60 * 1000); - - // Build ICS event - cal.push(['BEGIN', 'VEVENT']); - cal.push(['UID', window.location.hostname + '@' + evt.id]); - cal.push(['SUMMARY', evt.node.activityType + ' ' + evt.node.activity_code + ': ' + evt.node.description]); - cal.push(['DTSTAMP', dateToString(dateBegin)]); - cal.push(['DTSTART', dateToString(dateBegin)]); - cal.push(['DTEND', dateToString(dateEnd)]); - if (parseLocation(evt.node.location) != null) { - cal.push(['LOCATION', parseLocation(evt.node.location)]); + function pad2(num) { + if (num < 10) { + return '0' + num; + } + return '' + num; } - cal.push(['END', 'VEVENT']); -}); -cal.push(['END', 'VCALENDAR']); - -// ICS STUFF -var calStr = ''; -$.each(cal, function(i, evt) { - var entry = evt[0] + ':' + evt[1].replace(/\n/g, '\\n').replace(/,/g, '\\,').replace(/;/g, '\\;'); - // Process 75 characters at a time - while (entry.length > 75) { - calStr += entry.substring(0, 75); - calStr += '\r\n '; - entry = entry.substring(75); + function dateToString(date) { + return date.getFullYear() + pad2(date.getMonth() + 1) + pad2(date.getDate()) + 'T' + pad2(date.getHours()) + pad2(date.getMinutes()) + pad2(date.getSeconds()); } - calStr += entry; - calStr += '\r\n'; -}); -// Download it! -var blob = new Blob([calStr], {type: 'text/calendar;charset=utf-8'}); -saveAs(blob, 'allocateplus.ics'); + var cal = [['BEGIN', 'VCALENDAR'], ['VERSION', '2.0'], ['PRODID', '-//RunasSudo//allocics.js//EN']]; + $.each(timetable.get_visible_events(), function(i, evt) { + var dates = weekpatternToDates(evt.node.day_of_week, evt.node.week_pattern, evt.node.start_date); + var startDateBits = evt.node.start_date.split('/'); + var startTimeBits = evt.node.start_time.split(':'); + + var dateString = dates; + var dateStringBits = dateString.split('/'); + var dateBegin = new Date(startDateBits[2], dateStringBits[1] - 1, dateStringBits[0], startTimeBits[0], startTimeBits[1]); + var dateEnd = new Date(dateBegin.getTime() + evt.node.duration * 60 * 1000); + + // Build ICS event + cal.push(['BEGIN', 'VEVENT']); + cal.push(['UID', window.location.hostname + '@' + evt.id]); + cal.push(['SUMMARY', evt.node.activityType + ' ' + evt.node.activity_code + ': ' + evt.node.description]); + cal.push(['DTSTAMP', dateToString(dateBegin)]); + cal.push(['DTSTART', dateToString(dateBegin)]); + cal.push(['DTEND', dateToString(dateEnd)]); + if (parseLocation(evt.node.location) != null) { + cal.push(['LOCATION', parseLocation(evt.node.location)]); + } + cal.push(['END', 'VEVENT']); + }); + cal.push(['END', 'VCALENDAR']); + + // ICS STUFF + var calStr = ''; + $.each(cal, function(i, evt) { + var entry = evt[0] + ':' + evt[1].replace(/\n/g, '\\n').replace(/,/g, '\\,').replace(/;/g, '\\;'); + // Process 75 characters at a time + while (entry.length > 75) { + calStr += entry.substring(0, 75); + calStr += '\r\n '; + entry = entry.substring(75); + } + calStr += entry; + calStr += '\r\n'; + }); + + // Download it! + var blob = new Blob([calStr], {type: 'text/calendar;charset=utf-8'}); + saveAs(blob, 'allocateplus.ics'); +})(); diff --git a/bootstrap.js b/bootstrap.js index 102984d..0df71ee 100644 --- a/bootstrap.js +++ b/bootstrap.js @@ -16,11 +16,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ -if (window.location.hostname.indexOf('github.io') >= 0) { - window.alert('Drag the link to your bookmarks bar; don\'t click it.'); -} else { - // Load the main implementation - var impl = document.createElement('script'); - impl.src = 'https://runassudo.github.io/allocics.js/allocics.js'; - document.body.appendChild(impl); -} +// If integrity checking is ever implemented, this is where update notifications will be processed + +// Load the main implementation +var impl = document.createElement('script'); +impl.src = 'https://runassudo.github.io/allocics.js/allocics.js'; +document.body.appendChild(impl); @@ -27,7 +27,7 @@ <h2>Let's do it!</h2> <ol> - <li>Click <i>and drag</i> this link – <a href="javascript:var q=document.createElement('script');q.src='https://runassudo.github.io/allocics.js/bootstrap.js';document.body.appendChild(q);void 0;">Export Timetable</a> – to your bookmarks bar.</li> + <li>Click <i>and drag</i> this link – <a href="javascript:var q=document.createElement('script');q.src='https://runassudo.github.io/allocics.js/bootstrap.js';document.body.appendChild(q);void 0;" onclick="alert('Drag the link to your bookmarks bar; don\'t click it.');return false;">Export Timetable</a> – to your bookmarks bar.</li> <li>Log in to <a href="https://monash.edu/timetables/login.html">Allocate+</a>, and go to the ‘Timetable’ tab.</li> <li>Click the bookmark!</li> <li>That's it! Just download the ICS file and import it into your calendar.</li> |