KiitConnect Unlocker

Free as in beer.

目前為 2024-05-04 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         KiitConnect Unlocker
// @namespace    http://tampermonkey.net/
// @version      1.0
// @license      MIT
// @description  Free as in beer.
// @author       erucix
// @match        https://www.kiitconnect.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=kiitconnect.com
// ==/UserScript==

(function() {
    'use strict';

    window.onload = function(){


        // Removes a node and replaces with its clone and helps in removing all event listeners.
        function remove(node) {
            node.classList.remove("text-yellow-500", "cursor-not-allowed");
            if (node.innerText == "Not Available") {
                node.classList.add("whitespace-nowrap", "font-bold", "text-gray-400");
            } else {
                node.classList.add("text-cyan-500");
            }

            var clonedNode = node.cloneNode(true);
            node.parentNode.replaceChild(clonedNode, node);
        }

        // Its a single paged application so continuously check for change in URL instead of onload.
        setInterval(function () {

            // Check if the script has already been loaded for given semester.
            if (!document.head.classList.contains(location.pathname)) {

                // Clear all the previous class list.
                document.head.classList = "";

                // Add a class value indicating the script has been loaded for this semester.
                document.head.classList.add(location.pathname);



                let docRequired; // Type of document required. Can be: notes, pyqs
                let branchName;  // Name of choosen branch. Can be: cse, csse, csce, it
                let semesterId;  // Semester representation in number. Can be any between 1 to 6

                let finalPath = location.pathname;

                // Assign values only if we have sufficient information in URL.

                if (finalPath.includes("/academic/PYQS") && finalPath != "/academic/PYQS") {
                    finalPath = finalPath.substring(finalPath.lastIndexOf("/") + 1);
                    finalPath = finalPath.split("-");

                    docRequired = finalPath[0].toLowerCase();
                    branchName = finalPath[1].toLowerCase();
                    semesterId = Number(finalPath[2]);

                    // Fetching original source code so that we could get pdf links
                    fetch(location.href)
                        .then(data => data.text())
                        .then(data => {
                        if (docRequired == "pyqs") {
                            // Making some adjustments to successfully parse it as JSON

                            let response = data.substring(data.lastIndexOf("1d:[\\") - 23);
                            response = response.replace("self.__next_f.push(", "");
                            response = response.substring(0, response.lastIndexOf(")</script>"));

                            let firstLevelRefined = JSON.parse(response);
                            let secondLevelRefined = firstLevelRefined[1];
                            secondLevelRefined = secondLevelRefined.substring(3);

                            let thirdLevelRefined = JSON.parse(secondLevelRefined);

                            let finalRefined = thirdLevelRefined[3].children[3].data.semesters[0].subjects;


                            // Sort the list according to year
                            finalRefined.forEach(element => {
                                element.pyqs.sort((a, b) => {
                                    return Number(a.year) - Number(b.year);
                                })
                            });

                            console.log(finalRefined);

                            let containerTables = document.querySelectorAll("table");

                            // Used for storing loaded table indexes. SO don't touch the table
                            // again later.
                            let storedIndexArray = [];

                            containerTables.forEach((element) => {
                                let tableRowItems = [...element.querySelectorAll("tr")];

                                // Since the first 'tr' is table header

                                tableRowItems.shift();

                                // Find a table such that the [numbers of paper we have] = [number of rows in table]
                                // This reduces hassle of creating a new table

                                let index = 0;

                                for (let i = 0; i < finalRefined.length; i++) { //           Here we dont touch the loaded table
                                    if (finalRefined[i].pyqs.length == tableRowItems.length && !storedIndexArray.includes(i)) {
                                        index = i;
                                        storedIndexArray.push(i);
                                        break;
                                    }
                                }

                                let choosenSubject = finalRefined[index].pyqs;


                                // Overwrite the 'td' values by our better sorted list
                                tableRowItems.forEach((item, index1) => {
                                    let tdList = item.querySelectorAll("td");

                                    tdList[0].innerText = choosenSubject[index1].year;
                                    tdList[1].innerText = choosenSubject[index1].type;

                                    let anchor1 = tdList[2].querySelector("a");
                                    anchor1.innerText = choosenSubject[index1].name;
                                    anchor1.href = "https://drive.google.com/file/d/" + choosenSubject[index1].Question;

                                    // Replace the anchor
                                    remove(anchor1);

                                    let anchor2 = tdList[3].querySelector("a");

                                    if (choosenSubject[index1].solution != null) {
                                        if (anchor2 == null) {
                                            anchor2 = document.createElement("a");
                                            anchor2.target = "_blank";

                                            tdList[3].innerText = "";
                                            tdList[3].appendChild(anchor2);
                                        }

                                        anchor2.innerText = "Solution";
                                        anchor2.href = "https://drive.google.com/file/d/" + choosenSubject[index1].solution;
                                    } else {
                                        if (anchor2 != null) {
                                            anchor2.innerHTML = "Not Available";
                                        }
                                    }

                                    if (anchor2 != null) {
                                        remove(anchor2);
                                    }

                                });
                            });
                        }
                    });
                }

                // Remove all get premium buttons from site.
                setTimeout(function () {
                    let premiumButtons = document.querySelectorAll("a[href='/premiuminfo']");
                    premiumButtons.forEach(item => item.remove());

                }, 1000);
            }
        }, 1000);
    }
})();