GPA meter

A user script to show GPA on aims page

Você precisará instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Você precisará instalar uma extensão como o Tampermonkey para instalar este script.

Você precisará instalar um gerenciador de scripts de usuário para instalar este script.

(Eu já tenho um gerenciador de scripts de usuário, me deixe instalá-lo!)

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

(Eu já possuo um gerenciador de estilos de usuário, me deixar fazer a instalação!)

// ==UserScript==
// @name         GPA meter
// @namespace    https://greatest.deepsurf.us/en/users/674736-jatin-sharma
// @description  A user script to show GPA on aims page
// @include      https://aims.iith.ac.in/aims/courseReg/myCrsHistoryPage*
// @author       Jatin Sharma ([email protected])
// @version      0.4
// @grant        none
// ==/UserScript==

/* jshint esversion: 6 */
/* global $ */

(function () {
    'use strict';

    let exclude_list = [
        'Minor Core',
        'Honors Core',
        'Honours project',
        'Honours coursework',
        'FCC',
        'Additional',
        'Audit',
    ];

    const grade_values = {
        'A+': 10,
        'A' : 10,
        'A-': 9,
        'B' : 8,
        'B-': 7,
        'C' : 6,
        'C-': 5,
        'D' : 4,
        'FR': 0,
        'FS': 0
    };
    // console.log('Student ID: ', studentId);

    let append_checkbox = (parent, is_checked) => {
        parent.append('<input style="float:right" class="cgpa-cal-check" type="checkbox" ' + (is_checked ? 'checked' : '') + ' />');
    };

    let add_checkboxes = () => {
        let courses_checked = new Set();
        $(".cgpa-cal-check").remove();
        let elems = $(".hierarchyLi.dataLi").not(".hierarchyHdr, .hierarchySubHdr");
        elems.each((i, el) => {
            let course_id = el.children[0].textContent.trim();
            let type = el.children[4].textContent.trim();
            let grade = el.children[7].textContent.trim();
            let is_checked = !(courses_checked.has(course_id) || exclude_list.includes(type) || grade == "" || grade == "I");
            if (is_checked) courses_checked.add(course_id);
            append_checkbox($(el.children[0]), is_checked);
        });
    }

    let add_courseCategoryDropdown = () => {
        let courseCategoryDropDown = `
        <select class="catSel" style="width: auto; background: aliceblue; border-radius: 5px">
            <option value="Additional">Additional</option>
            <option value="Audit">Audit</option>
            <option value="Liberal Arts Elective">Liberal Arts Elective</option>
            <option value="Departmental Core Laboratory">Departmental Core Laboratory</option>
            <option value="Departmental Elective">Departmental Elective</option>
            <option value="Departmental Core Theory">Departmental Core Theory</option>
            <option value="Basic Sciences">Basic Sciences</option>
            <option value="Professional Ethics">Professional Ethics</option>
            <option value="Seminar">Seminar</option>
            <option value="Thesis">Thesis</option>
            <option value="Basic Engineering Skills">Basic Engineering Skills</option>
            <option value="Free Elective">Free Elective</option>
            <option value="FCC">FCC</option>
            <option value="Creative Arts">Creative Arts</option>
        </select>`;

        let elems = $(".hierarchyLi.dataLi").not(".hierarchyHdr, .hierarchySubHdr").children('.col5');
        $('.col5').css({ "width": "220px" });
        $('.col1').css({ "width": "75px" });
        $('.col4').css({ "width": "80px" });
        elems.each((i, el) => {
            let origCategory = el.innerText.trim();
            el.dataset.origCategory = origCategory;
            el.innerHTML = '';
            el.insertAdjacentHTML('afterbegin', courseCategoryDropDown);
            $(el.children[0]).val(origCategory).change();
        });
        $('.catSel').on('change', (e) => {
            let origCategory = e.target.parentElement.dataset.origCategory;
            if (e.target.value === origCategory) {
                e.target.style.backgroundColor = "aliceblue";
                e.target.removeAttribute('title');
            } else {
                e.target.style.backgroundColor = "mistyrose";
                e.target.title = `Orig: ${origCategory}`;
            }

        });
        $('.catSel').tooltip();
        $('.catSel').tooltip('option', 'track', true);
        $('#courseHistoryUI .col8').attr('contenteditable','true');
    };


    let show_total_gpa = () => {
        $('#gpa_button').val('Calculating');
        $('#gpa_bar').remove();
        let cg_total_grades = 0;
        let cg_total_credits = 0;
        let total_credits = 0;

        if ($(".cgpa-cal-check").length == 0) {
            add_checkboxes();
            add_courseCategoryDropdown();
        }
        let elems = $('.cgpa-cal-check:checked').parent().parent()

        let categoryMap = {
            'Departmental Core Theory': 0,
            'Departmental Elective': 0,
            'Free Elective': 0,
            'Liberal Arts Elective': 0,
            'Creative Arts': 0,
            'Basic Sciences': 0,
            'Basic Engineering Skills': 0,
            'Additional': 0
        };


        let deptMap = {};

        elems.each((i, el) => {
            let type = el.children[4].children[0].value;

            let course_id = el.children[0].textContent.trim();
            let grade = el.children[7].textContent.trim();
            let credits = Number(el.children[2].textContent.trim());
            total_credits += credits;
            categoryMap[type] = credits + (categoryMap[type] || 0);

            let deptId = course_id.slice(0, 2);
            deptMap[deptId] = credits + (deptMap[deptId] || 0);

            if (grade in grade_values) {
                grade = grade_values[grade];
                cg_total_grades += credits * grade;
                cg_total_credits += credits;
            }
        });
        let gpa = (cg_total_grades / cg_total_credits).toFixed(2);

        console.log(categoryMap);
        console.log(deptMap);

        let generateRow = (title, val) => `<li class="hierarchyLi">
            <span class="" style="margin-left: 100px; width:300px">${title}</span>
            <span class="" style="margin-left: 400px;">${val}</span>
        </li>`;

        $('#gpa_button').val('Show Gpa');
        $('#courseHistoryUI').before(
            `<ul id="gpa_bar" class="subCnt">
                <li class="hierarchyLi hierarchyHdr changeHdrCls">TOTAL GPA</li>
                ${generateRow('Total GPA of graded courses', gpa)}
                ${Object.entries(categoryMap).map((entry) => generateRow(entry[0], entry[1])).join('\n')}
                ${generateRow('Total credits', total_credits)}
            </ul>`);
    }

    let get_course_changes_csv = () => `Course Code,Course Name,Credits,From Course Type,To Course Type,Semester\n`+
                $('.catSel')
                .filter( (i, el) => el.value !== el.parentElement.dataset.origCategory )
                .map((i, el) => ``+
                    `${el.parentElement.parentElement.children[0].textContent.trim()},`+
                    `${el.parentElement.parentElement.children[1].textContent.trim()},`+
                    `${Number(el.parentElement.parentElement.children[2].textContent.trim())},`+
                    `${el.parentElement.dataset.origCategory},`+
                    `${el.value},`+
                    `${el.parentElement.parentElement.parentElement.children[0].children[0].textContent.trim()}`)
                .get().reverse().join('\n');

    $("#studentCourseSearch").before(
        `<input id="getcoursechanges_button" class="btn" title="Copy CSV of Course Type Changes to clipboard"`+
        `value="Copy Changes" style="padding: 5px 7px; margin-right:10px;" type="button"></input>`
    );
    $('#getcoursechanges_button').click(() => {
        let text = get_course_changes_csv();
        console.log(text);
        navigator.clipboard.writeText(text).then(function() {
            console.log('CSV Copied to clipboard');
        }, function(err) {
            console.error('Async: Could not copy text: ', err);
            alert('Could not copy to clipboard. Please find the CSV in your browser console');
        });
    });


    $("#studentCourseSearch").before(
        '<input id="gpa_button" class="btn" value="Show Gpa" style="padding: 5px 7px; margin-right:10px;" type="button"></input>'
    );
    $('#gpa_button').click(show_total_gpa);
//    console.log('All assets are loaded')
})();