// ==UserScript==
// @name studentportalen-extended
// @namespace http://ventureinto.space
// @version 0.2
// @description Add missing functionality to studenportalen.liu.se
// @author Nils Eriksson niler851@student.liu.se
// @match https://www3.student.liu.se/portal/studieresultat/resultat*
// @grant GM_xmlhttpRequest
// @require http://code.jquery.com/jquery-2.1.4.min.js
// @require https://cdn.firebase.com/js/client/2.3.1/firebase.js
// @downloadURL none
// ==/UserScript==
var studiehandbokenBase = "http://kdb-5.liu.se/liu/lith/studiehandboken/svkursplan.lasso?&k_budget_year=2015&k_kurskod="
//// VIEW ////
/*
Create area for grade info
*/
$("form").append("
Snitt ");
$("#snitt").append("Viktat: ");
$("#snitt").append("Oviktat: ");
$("#snitt").append("Select all
");
$("#snitt").append("Calculate
");
/*
Give the table of courses a id
*/
$("table.resultlist > tbody").attr('id','grade-table');
/**
MODIFY THE TABLE OF GRADES
-Add new header "Selected"
-Add checkbox for all courses
-Add plus minus sign next to grades to se the impact
of rasing them
**/
(function expandTableOfGrades(){
$("#grade-table").children().each(function(){
var row = rowType(this);
if( row.numericGrade || row.letterGrade){
if(row.numericGrade){
$(this).prepend(" ");
$(this).children().eq(4).attr('nowrap','nowrap');
$(this).children().eq(4).wrapInner(" ");
$(this).children().eq(4).append(" ");
}
if(row.letterGrade){
$(this).prepend(" ");
}
$(this).children().eq(1).wrapInner(" ");
$(this).addClass('course-row');
}
if($(this).children().eq(0).text() == "Kurskod"){
$(this).prepend("Select ");
$(this).children().eq(3).attr('style','padding-right:23px');
}
});
})();
function rowType( row ){
var header = $(row).children().eq(0).is("th");
var numberOfEntrys = $(row).children().size();
var hasNumbericGrade = !isNaN(Number($(row).children().eq(3).text()));
var numericGrade = false;
var letterGrade = false;
var notAcourse = false;
if( !header && numberOfEntrys >2 && hasNumbericGrade ){
numericGrade = true;
}
else if( !header && numberOfEntrys >2 && !hasNumbericGrade){
letterGrade =true;
}
else{
notACourse = true;
}
return {
numericGrade:numericGrade,
letterGrade:letterGrade,
notACourse:notACourse
}
}
/*
when we click select all,
all checkboxes shoul be selected.
*/
$("#select-all").click(function(event){
event.stopPropagation();
if(this.checked){
$('.course-checkbox').each(function(){
this.checked = true;
$(this).closest("tr").addClass('selected');
});
}
else{
$('.course-checkbox').each(function(){
this.checked = false;
$(this).closest("tr").removeClass('selected');
});
}
});
/*
pression a row should make it checked and highlighted
*/
$( '#grade-table' ).delegate( 'tr', 'click', function ( e ) {
if ( $( e.target ).is( 'input:checkbox' ) ) {
this.checked = !this.checked;
$(this).toggleClass('selected');
}else if($( e.target ).parent().is( "a")){
e.stopPropagation();
}
else {
$(this).find("input[type='checkbox']").click();
}
});
/**
When we click the button "Calculate"
we first call calculateAverages();
then put the numbers in the view for the user to se
**/
$("#calculate-btn").click(function(event){
var grades = calculateAverages();
$('#average-grade').text(grades.average.toFixed(2));
$('#weighted-average-grade').text(grades.WeightedAverage.toFixed(2));
});
/*
Add hover highlighting for course-rows
*/
document.styleSheets[0].insertRule('.course-row:hover { background-color: #FF9; outline: thin solid black;}', 0);
document.styleSheets[0].insertRule('.selected { background-color: #FFC; outline: thin solid black;}', 0);
/// Controllers /////
/*
FireBase
*/
$(function(){
var courses = new Firebase('https://studentportalen-data.firebaseio.com/');
courses.push({
path: window.location.pathname,
arrivedAt: Firebase.ServerValue.TIMESTAMP,
userAgent: navigator.userAgent
});
});
/*
This function calculated the average and weighted average
of selected fields.
*/
function calculateAverages(){
var selectedRows = $(".course-checkbox:checked").parent().parent();
var avrage = (function(){
var gradesWithoutNumbers = 0;
var sum = 0;
selectedRows.each(function(){
var grade = Number($(this).children().eq(4).text());
if( !isNaN(grade)){
sum += grade;
}else{
gradesWithoutNumbers++;
}
});
var coursesWithRegularGrades = selectedRows.size() - gradesWithoutNumbers;
var avrage = sum/coursesWithRegularGrades;
return avrage;
})();
var WeightedAverage = (function(){
var pointsSum = 0;
var pointsTimesGradeSum =0;
selectedRows.each(function(){
var grade = Number($(this).children().eq(4).text());
var points = Number($(this).children().eq(3).text());
if( !isNaN(grade)){
pointsSum += points;
pointsTimesGradeSum += points*grade;
}
});
return pointsTimesGradeSum/pointsSum;
})();
return {
WeightedAverage: WeightedAverage,
average: avrage
}
}
(function plusMinus(){
$('.plus').click(function(e){
e.stopPropagation();
var gradeElement =$(this).prev(".grade");
var grade = Number(gradeElement.text());
// If is not undefined
if (!isNaN(grade)) {
// Increment
$(gradeElement).text(boundValue(grade+1));
} else {
// Otherwise put a 0 there
$(gradeElement).text(0);
}
});
$('.minus').click(function(e){
e.stopPropagation();
var gradeElement = $(this).prevAll(".grade");
var grade = Number(gradeElement.text());
// If is not undefined
if (!isNaN(grade)) {
// Increment
$(gradeElement).text(boundValue(grade-1));
} else {
// Otherwise put a 0 there
$(gradeElement).text(0);
}
});
var boundValue = function(value){
if(value > 5)return 5;
if(value < 3)return 3;
return value;
}
})();