KiitConnect Unlocker

Free as in beer.

当前为 2024-05-04 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name KiitConnect Unlocker
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.0
  5. // @license MIT
  6. // @description Free as in beer.
  7. // @author erucix
  8. // @match https://www.kiitconnect.com/*
  9. // @icon https://www.google.com/s2/favicons?sz=64&domain=kiitconnect.com
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14.  
  15. window.onload = function(){
  16.  
  17.  
  18. // Removes a node and replaces with its clone and helps in removing all event listeners.
  19. function remove(node) {
  20. node.classList.remove("text-yellow-500", "cursor-not-allowed");
  21. if (node.innerText == "Not Available") {
  22. node.classList.add("whitespace-nowrap", "font-bold", "text-gray-400");
  23. } else {
  24. node.classList.add("text-cyan-500");
  25. }
  26.  
  27. var clonedNode = node.cloneNode(true);
  28. node.parentNode.replaceChild(clonedNode, node);
  29. }
  30.  
  31. // Its a single paged application so continuously check for change in URL instead of onload.
  32. setInterval(function () {
  33.  
  34. // Check if the script has already been loaded for given semester.
  35. if (!document.head.classList.contains(location.pathname)) {
  36.  
  37. // Clear all the previous class list.
  38. document.head.classList = "";
  39.  
  40. // Add a class value indicating the script has been loaded for this semester.
  41. document.head.classList.add(location.pathname);
  42.  
  43.  
  44.  
  45. let docRequired; // Type of document required. Can be: notes, pyqs
  46. let branchName; // Name of choosen branch. Can be: cse, csse, csce, it
  47. let semesterId; // Semester representation in number. Can be any between 1 to 6
  48.  
  49. let finalPath = location.pathname;
  50.  
  51. // Assign values only if we have sufficient information in URL.
  52.  
  53. if (finalPath.includes("/academic/PYQS") && finalPath != "/academic/PYQS") {
  54. finalPath = finalPath.substring(finalPath.lastIndexOf("/") + 1);
  55. finalPath = finalPath.split("-");
  56.  
  57. docRequired = finalPath[0].toLowerCase();
  58. branchName = finalPath[1].toLowerCase();
  59. semesterId = Number(finalPath[2]);
  60.  
  61. // Fetching original source code so that we could get pdf links
  62. fetch(location.href)
  63. .then(data => data.text())
  64. .then(data => {
  65. if (docRequired == "pyqs") {
  66. // Making some adjustments to successfully parse it as JSON
  67.  
  68. let response = data.substring(data.lastIndexOf("1d:[\\") - 23);
  69. response = response.replace("self.__next_f.push(", "");
  70. response = response.substring(0, response.lastIndexOf(")</script>"));
  71.  
  72. let firstLevelRefined = JSON.parse(response);
  73. let secondLevelRefined = firstLevelRefined[1];
  74. secondLevelRefined = secondLevelRefined.substring(3);
  75.  
  76. let thirdLevelRefined = JSON.parse(secondLevelRefined);
  77.  
  78. let finalRefined = thirdLevelRefined[3].children[3].data.semesters[0].subjects;
  79.  
  80.  
  81. // Sort the list according to year
  82. finalRefined.forEach(element => {
  83. element.pyqs.sort((a, b) => {
  84. return Number(a.year) - Number(b.year);
  85. })
  86. });
  87.  
  88. console.log(finalRefined);
  89.  
  90. let containerTables = document.querySelectorAll("table");
  91.  
  92. // Used for storing loaded table indexes. SO don't touch the table
  93. // again later.
  94. let storedIndexArray = [];
  95.  
  96. containerTables.forEach((element) => {
  97. let tableRowItems = [...element.querySelectorAll("tr")];
  98.  
  99. // Since the first 'tr' is table header
  100.  
  101. tableRowItems.shift();
  102.  
  103. // Find a table such that the [numbers of paper we have] = [number of rows in table]
  104. // This reduces hassle of creating a new table
  105.  
  106. let index = 0;
  107.  
  108. for (let i = 0; i < finalRefined.length; i++) { // Here we dont touch the loaded table
  109. if (finalRefined[i].pyqs.length == tableRowItems.length && !storedIndexArray.includes(i)) {
  110. index = i;
  111. storedIndexArray.push(i);
  112. break;
  113. }
  114. }
  115.  
  116. let choosenSubject = finalRefined[index].pyqs;
  117.  
  118.  
  119. // Overwrite the 'td' values by our better sorted list
  120. tableRowItems.forEach((item, index1) => {
  121. let tdList = item.querySelectorAll("td");
  122.  
  123. tdList[0].innerText = choosenSubject[index1].year;
  124. tdList[1].innerText = choosenSubject[index1].type;
  125.  
  126. let anchor1 = tdList[2].querySelector("a");
  127. anchor1.innerText = choosenSubject[index1].name;
  128. anchor1.href = "https://drive.google.com/file/d/" + choosenSubject[index1].Question;
  129.  
  130. // Replace the anchor
  131. remove(anchor1);
  132.  
  133. let anchor2 = tdList[3].querySelector("a");
  134.  
  135. if (choosenSubject[index1].solution != null) {
  136. if (anchor2 == null) {
  137. anchor2 = document.createElement("a");
  138. anchor2.target = "_blank";
  139.  
  140. tdList[3].innerText = "";
  141. tdList[3].appendChild(anchor2);
  142. }
  143.  
  144. anchor2.innerText = "Solution";
  145. anchor2.href = "https://drive.google.com/file/d/" + choosenSubject[index1].solution;
  146. } else {
  147. if (anchor2 != null) {
  148. anchor2.innerHTML = "Not Available";
  149. }
  150. }
  151.  
  152. if (anchor2 != null) {
  153. remove(anchor2);
  154. }
  155.  
  156. });
  157. });
  158. }
  159. });
  160. }
  161.  
  162. // Remove all get premium buttons from site.
  163. setTimeout(function () {
  164. let premiumButtons = document.querySelectorAll("a[href='/premiuminfo']");
  165. premiumButtons.forEach(item => item.remove());
  166.  
  167. }, 1000);
  168. }
  169. }, 1000);
  170. }
  171. })();