NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name TISS Registration Madness // @namespace JuHwon // @version 1.0 // @description Just Madness // @match https://tiss.tuwien.ac.at/* // @copyright 2016+, JuHwon // @require http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js // ==/UserScript== (function TissRegistrationMadnessClass() { var options = { // option do enable autoregistration autoRegistration: true, // option to enable autoreload if the reigster button is not available autoReload: false, // interval to refresh the page if register button not available refreshInterval: 1000, // course number courseNumber: '188.916', // type of registration, available options: lva, group, exam registrationType: 'lva', // section of registration button, e.g. group name like "Gruppe 3", or name of exam // this option is not available with the registration type 'lva' registerSection: '', // semester of the desired course semester: '2016W', // if you got multiple study codes, configure the desired one without the dot (e.g. 033526) studyCode: '', // option to enable/disable logs on page enableLog: true, // option to specify a time to start the script, it will reload the page at the specified time // [year, month, day, hours, minutes, seconds, milliseconds] // leave array empty to disable the specific startTime startTime: [2016, 9 -1, 15, 6, 59] }; var state = { NONE: 0, SUCCESS: 1, REGISTER: 2, STUDY_SELECTION: 3, ACKNOWLEDGE: 5, // errors WRONG_COURSE: 10, WRONG_SEMESTER: 11, WRONG_TAB: 12, // not found SECTION_NOTFOUND: 20, BUTTON_NOTFOUND: 21 }; var tabs = { lva: 'LVA-Anmeldung', group: 'Gruppen', exam: 'Prüfungen' }; var LOG_AREA_SYLE = 'color: black; background-color: #FFFCD9; font-size: 10pt; padding-top: 1px;'; var LOG_AREA_ID = 'trmLog'; var ERROR_AREA_STYLE = 'color: red; font-weight: bold; font-size: 14pt; padding: 8px 0px;'; var ERROR_AREA_ID = 'trmError'; var SUCCESS_AREA_STYLE = 'color: green; font-weight: bold; font-size: 14pt; padding: 8px 0px;'; var SUCCESS_AREA_ID = 'trmSuccess'; this.init = function() { this.state = state.NONE; this.extendJQuery(); // delay start if specified var timeToStart; if (options.startTime.length > 0 && (timeToStart = new (Date.bind.apply(Date, [null].concat(options.startTime)))() - new Date()) > 0) { setTimeout(this.reloadPage, timeToStart); this.setCountDown(timeToStart); } else { this.injectArea(LOG_AREA_ID, LOG_AREA_SYLE, 'Information Log'); this.injectArea(ERROR_AREA_ID, ERROR_AREA_STYLE); this.injectArea(SUCCESS_AREA_ID, SUCCESS_AREA_STYLE); if (options.registrationType == 'lva') { options.registerSection = 'LVA-Anmeldung'; } this.start(); } }; this.start = function() { this.pageLog('TISS Registration Madness started'); this.pageLog('LVA Number: ' + this.getLvaNumber()); this.pageLog('LVA Name: ' + this.getLvaName()); this.pageLog('SelectedTab: ' + this.getSelectedTab()); var foundStudySelection = !!this.getStudySelection(); var foundConfirmButton = !!this.getConfirmButton(); var foundAcknowledgeButton = !!this.getAcknowledgeButton(); // identify registration step & process if(this.properSemesterSelected() && !this.isRegistered()) { if (this.properTabSelected()){ this.register(); } else if (foundStudySelection) { this.studySelection(); } else if (foundConfirmButton) { this.confirm(); } else if (foundAcknowledgeButton) { this.acknowledge(); } else { this.state = state.NONE; } } switch(this.state) { case state.SUCCESS: this.pageSuccess('You are successfully registered.'); break; case state.WRONG_COURSE: this.pageError('Wrong course selected. Expected: ' + options.courseNumber); break; case state.WRONG_SEMESTER: this.pageError('Wrong semester selected. Expected: ' + options.semester); break; case state.WRONG_TAB: this.pageError('Wrong Tab selected. Tab did not match ' + tabs[options.registrationType]); break; case state.SECTION_NOTFOUND: this.pageError('Could not find section with title "' + options.registerSection + '"'); break; case state.BUTTON_NOTFOUND: this.pageError('Could not find register button.'); break; case state.NONE: this.pageError('Could not determine registration step.'); break; } }; this.register = function() { this.state = state.REGISTER; if(!this.properCourseSelected()) { return; } var section = this.getSection(); if (!section) { this.state = state.SECTION_NOTFOUND; return; } this.highlightElement(this.getSectionLabel()); var registerButton = this.getRegisterButton(section); if (!registerButton) { this.state = state.BUTTON_NOTFOUND; if (options.autoReload) { setTimeout(this.reloadPage, options.refreshInterval); } return; } this.highlightElement(registerButton); if (options.autoRegistration) { registerButton.click(); } }; this.studySelection = function() { this.state = state.STUDY_SELECTION; var selection = this.getStudySelection(); this.pageError(''); if (options.studyCode) { this.setSelectedValue(selection, options.studyCode); } this.confirm(); }; this.confirm = function() { var confirmButton = this.getConfirmButton(); this.highlightElement(confirmButton); if (options.autoRegistration) { confirmButton.click(); } }; this.acknowledge = function() { this.state = state.ACKNOWLEDGE; var button = this.getAcknowledgeButton(); this.highlightElement(button); if (options.autoRegistration) { button.click(); } }; this.isRegistered = function() { var section = this.getSection(); if(!section || !this.getDeregisterButton(section)) { return false; } this.highlightElement(this.getSectionLabel()); this.state = state.SUCCESS; return true; }; ///////////////////////// Props var _lvaNumber; this.getLvaNumber = function() { return _lvaNumber || (_lvaNumber = $('#contentInner h1 span:first').text().trim()); }; var _lvaName; this.getLvaName = function() { return _lvaName || (_lvaName = $('#contentInner h1').textNodes().text().trim()); }; var _selectedTab; this.getSelectedTab = function() { return _selectedTab || (_selectedTab = $('li.ui-tabs-selected').text().trim()); }; var _sectionLabel; this.getSectionLabel = function() { if (!_sectionLabel) { _sectionLabel = $(".groupWrapper .header_element span").filter(function () { return $(this).text().trim() === options.registerSection; }); _sectionLabel = _sectionLabel.length > 1 ? _sectionLabel.first() : _sectionLabel; } return _sectionLabel; }; var _section; this.getSection = function() { return _section || (_section = this.getSectionLabel().closest('.groupWrapper')); }; var _acknowledgeButton; // returns null if button is not found this.getAcknowledgeButton = function() { var button = _acknowledgeButton || (_acknowledgeButton = $("form#confirmForm input:submit[value='Ok']")); return button.length === 0 ? null : button; }; var _registerButton; // returns null if button is not found this.getRegisterButton = function(section) { if (!_registerButton) { _registerButton = $(section).find('input:submit[value="Anmelden"]'); // fallback solutions, since it seems the value is not always the same if (_registerButton.length === 0) { _registerButton = $(section).find('input:submit[value="Voranmelden"]'); } if (_registerButton.length === 0) { _registerButton = $(section).find('input:submit[value="Voranmeldung"]'); } _registerButton = _registerButton.length === 0 ? null : _registerButton; } return _registerButton; }; var _confirmButton; // returns null if button is not found this.getConfirmButton = function() { return _confirmButton || (_confirmButton = this.getRegisterButton($('form#regForm'))); }; var _studySelection; // returns null if button is not found this.getStudySelection = function() { var selection = _studySelection || (_studySelection = $("#regForm").find('select[name="regForm:studyCode"]')); return selection.length === 0 ? null : selection; }; var _deregisterButton; // returns null if button is not found this.getDeregisterButton = function(section) { var button = _deregisterButton || (_deregisterButton || $(section).find('input:submit[value="Abmelden"]')); return button.length === 0 ? null : button; }; //////////////////////// Util this.highlightElement = function(element) { if (options.enableLog) { element.css('background-color', 'lightgreen'); } }; this.setSelectedValue = function (element, value) { element.find('option').removeAttr('selected'); element.find('option[value="' + value + '"]').attr('selected', 'selected'); }; this.pageError = function(msg) { if (options.enableLog) { var errorLog = $('#' + ERROR_AREA_ID); errorLog.html(msg); } }; this.pageSuccess = function(msg) { if (options.enableLog) { var successLog = $('#' + SUCCESS_AREA_ID); successLog.html(msg); } }; this.pageLog = function(msg) { if (options.enableLog) { var log = $('#' + LOG_AREA_ID); log.html(log.html() + '<br />' + msg); } }; this.injectArea = function(id, style, title, force) { if (options.enableLog || force) { $('#contentInner').before( '<div id="' + id + '" style="' + style + '">' + (title ? '<h2>' + title + '</h2>' : '') + '</div>' ); } }; this.reloadPage = function() { location.reload(); }; this.setCountDown = function(milliseconds) { this.injectArea('trmCountdown', LOG_AREA_SYLE, '', true); var ms = milliseconds; var logCountdown = function() { $('#trmCountdown').html('Script will start in ' + Math.round(ms/1000) + ' seconds.'); }; setInterval(function() { ms -= 1000; logCountdown(); }, 1000); }; this.extendJQuery = function() { jQuery.fn.textNodes = function() { return $(this) .contents() .filter(function() { return this.nodeType === Node.TEXT_NODE; }); }; }; //////////////////////// Validation this.properCourseSelected = function() { var lvaNumber = this.getLvaNumber().replace(/[^\d]/, ''); if (lvaNumber !== options.courseNumber.replace(/[^\d]/, '')) { this.state = state.WRONG_COURSE; return false; } return true; }; this.properSemesterSelected = function() { var subheader = $('#contentInner #subHeader').text().trim(); if (subheader.indexOf(options.semester) === -1) { this.state = state.WRONG_SEMESTER; return false; } return true; }; this.properTabSelected = function() { if (this.getSelectedTab() !== tabs[options.registrationType]) { this.state = state.WRONG_TAB; return false; } return true; }; this.init(); })();