Kepler Script

Kepler için notlar

当前为 2025-01-06 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Kepler Script
  3. // @author KazuroAkashi
  4. // @match https://obs.itu.edu.tr/ogrenci/
  5. // @license MIT
  6. // @version 0.0.1.20250106184221
  7. // @namespace https://greasyfork.org/users/1419483
  8. // @description Kepler için notlar
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. 'use strict';
  13.  
  14. async function getJWT() {
  15. return new Promise((resolve, reject) => {
  16. const xhr = new XMLHttpRequest();
  17. xhr.open("GET", "https://obs.itu.edu.tr/ogrenci/auth/jwt");
  18.  
  19. xhr.onload = () => {
  20. if (xhr.readyState == 4 && xhr.status == 200) {
  21. resolve(xhr.responseText);
  22. } else {
  23. reject(xhr.status);
  24. }
  25. };
  26. xhr.send();
  27. })
  28. }
  29.  
  30. async function getDonemListesi(jwt) {
  31. return new Promise((resolve, reject) => {
  32. const xhr = new XMLHttpRequest();
  33. xhr.open("GET", "https://obs.itu.edu.tr/api/ogrenci/DonemListesi");
  34. xhr.setRequestHeader("Authorization", "Bearer " + jwt);
  35.  
  36. xhr.onload = () => {
  37. if (xhr.readyState == 4 && xhr.status == 200) {
  38. resolve(JSON.parse(xhr.response));
  39. } else {
  40. reject(xhr.status);
  41. }
  42. };
  43. xhr.send();
  44. })
  45. }
  46.  
  47. async function getSinifListesi(jwt, donemId) {
  48. return new Promise((resolve, reject) => {
  49. const xhr = new XMLHttpRequest();
  50. xhr.open("GET", "https://obs.itu.edu.tr/api/ogrenci/sinif/KayitliSinifListesi/" + donemId);
  51. xhr.setRequestHeader("Authorization", "Bearer " + jwt);
  52.  
  53. xhr.onload = () => {
  54. if (xhr.readyState == 4 && xhr.status == 200) {
  55. resolve(JSON.parse(xhr.response));
  56. } else {
  57. reject(xhr.status);
  58. }
  59. };
  60. xhr.send();
  61. })
  62. }
  63.  
  64. async function getNotListesi(jwt, sinifId) {
  65. return new Promise((resolve, reject) => {
  66. const xhr = new XMLHttpRequest();
  67. xhr.open("GET", "https://obs.itu.edu.tr/api/ogrenci/Sinif/SinifDonemIciNotListesi/" + sinifId);
  68. xhr.setRequestHeader("Authorization", "Bearer " + jwt);
  69.  
  70. xhr.onload = () => {
  71. if (xhr.readyState == 4 && xhr.status == 200) {
  72. resolve(JSON.parse(xhr.response));
  73. } else {
  74. reject(xhr.status);
  75. }
  76. };
  77. xhr.send();
  78. })
  79. }
  80.  
  81. String.prototype.formatStr = String.prototype.formatStr ||
  82. function () {
  83. "use strict";
  84. var str = this.toString();
  85. if (arguments.length) {
  86. var t = typeof arguments[0];
  87. var key;
  88. var args = ("string" === t || "number" === t) ?
  89. Array.prototype.slice.call(arguments)
  90. : arguments[0];
  91.  
  92. for (key in args) {
  93. str = str.replace(new RegExp("\\{" + key + "\\}", "gi"), args[key]);
  94. }
  95. }
  96.  
  97. return str;
  98. };
  99.  
  100. const htmlParser = new DOMParser();
  101. function createHTMLElement(str) {
  102. const doc = htmlParser.parseFromString(str, "text/html");
  103. return doc.body.firstChild;
  104. }
  105.  
  106. function insertBeforeHTMLElement(str, el) {
  107. const insert = createHTMLElement(str);
  108. el.parentElement.insertBefore(insert, el);
  109. }
  110.  
  111. const newCardTemplate = `
  112. <div class="row">
  113. <div class="col-md-12 mb-5">
  114. <div class="card info-graphic info-graphic--service">
  115. <div class="card-body">
  116. <h2>Notlar</h2>
  117. {0}
  118. </div>
  119. </div>
  120. </div>
  121. </div>
  122. `;
  123.  
  124. const newClassTemplate = `
  125. <div class="col-lg-12 mb-3">
  126. <h4>{name}</h4>
  127. {notes}
  128. <div class="row ml-5">
  129. <h5>Ağırlıklı Ortalama</h5>
  130. <div class="ml-5">{average}</div>
  131. </div>
  132. </div>
  133. `;
  134.  
  135. const newNoteTemplate = `
  136. <div class="row ml-5">
  137. <h5>{name} (%{perc})</h5>
  138. <div class="ml-5">{note}</div>
  139. </div>
  140. `;
  141.  
  142. const newClassTemplateTable = `
  143. <div class="col-lg-12 mb-3">
  144. <h4>{name}</h4>
  145. <div class="table-vertical table-vertical--unheight">
  146. <table class="table table-striped table-bordered" style="table-layout: fixed">
  147. <tbody>
  148. {notes}
  149. <tr>
  150. <th class="title" style="width: 40%">Ağırlıklı Ortalama</th>
  151. <td>{average}</td>
  152. </tr>
  153. </tbody>
  154. </table>
  155. </div>
  156. </div>
  157. `;
  158.  
  159. const newNoteTemplateTable = `
  160. <tr>
  161. <th class="title" style="width: 40%">{name} (%{perc})</th>
  162. <td>{note}</td>
  163. </tr>
  164. `;
  165.  
  166. const classLineTemplate = `
  167. <div style="width: 100%; height: 1px; background: #358aed; margin-bottom: 15px; margin-top: 13px;"></div>
  168. `;
  169.  
  170. async function printNotlar() {
  171. const jwt = await getJWT();
  172. const donemListesi = (await getDonemListesi(jwt)).ogrenciDonemListesi;
  173. const sonDonem = donemListesi[donemListesi.length - 1];
  174. const sonDonemId = sonDonem.akademikDonemId;
  175. const sinifListesi = (await getSinifListesi(jwt, sonDonemId)).kayitSinifResultList;
  176.  
  177. const addBefore = document.querySelectorAll(".obs > .container-fluid > div > .row")[1];
  178.  
  179. let classesEl = "";
  180. for (const sinif of sinifListesi) {
  181. if (classesEl !== "") classesEl += classLineTemplate;
  182.  
  183. const sinifNameEn = sinif.bransKodu + sinif.dersKodu + " - " + sinif.dersAdiEN + " (CRN: " + sinif.crn + ")";
  184. const sinifNameTr = sinif.bransKodu + sinif.dersKodu + " - " + sinif.dersAdiTR + " (CRN: " + sinif.crn + ")";
  185. const sinifId = sinif.sinifId;
  186.  
  187. const notListesiObj = (await getNotListesi(jwt, sinifId));
  188. const notListesi = notListesiObj.sinifDonemIciNotListesi;
  189. const ortalama = notListesiObj.ortalama;
  190.  
  191. let notesEl = "";
  192. for (const not of notListesi) {
  193. const notName = not.degerlendirmeOlcutuAdi;
  194. const notPerc = not.degerlendirmeKatkisi;
  195. const notValue = not.not;
  196.  
  197. notesEl += newNoteTemplateTable.formatStr({ "name": notName, "perc": notPerc, "note": notValue });
  198. }
  199.  
  200. classesEl += newClassTemplateTable.formatStr({ "name": sinifNameTr, "notes": notesEl, "average": ortalama });
  201. }
  202.  
  203. const cardEl = newCardTemplate.formatStr(classesEl);
  204. insertBeforeHTMLElement(cardEl, addBefore);
  205. }
  206.  
  207. printNotlar();
  208.  
  209. })();