您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Kepler için notlar
当前为
- // ==UserScript==
- // @name Kepler Script
- // @author KazuroAkashi
- // @match https://obs.itu.edu.tr/ogrenci/
- // @license MIT
- // @version 0.0.1.20250107090026
- // @namespace https://greasyfork.org/users/1419483
- // @description Kepler için notlar
- // ==/UserScript==
- (function() {
- 'use strict';
- async function getJWT() {
- return new Promise((resolve, reject) => {
- const xhr = new XMLHttpRequest();
- xhr.open("GET", "https://obs.itu.edu.tr/ogrenci/auth/jwt");
- xhr.onload = () => {
- if (xhr.readyState == 4 && xhr.status == 200) {
- resolve(xhr.responseText);
- } else {
- reject(xhr.status);
- }
- };
- xhr.send();
- })
- }
- async function getDonemListesi(jwt) {
- return new Promise((resolve, reject) => {
- const xhr = new XMLHttpRequest();
- xhr.open("GET", "https://obs.itu.edu.tr/api/ogrenci/DonemListesi");
- xhr.setRequestHeader("Authorization", "Bearer " + jwt);
- xhr.onload = () => {
- if (xhr.readyState == 4 && xhr.status == 200) {
- resolve(JSON.parse(xhr.response));
- } else {
- reject(xhr.status);
- }
- };
- xhr.send();
- })
- }
- async function getSinifListesi(jwt, donemId) {
- return new Promise((resolve, reject) => {
- const xhr = new XMLHttpRequest();
- xhr.open("GET", "https://obs.itu.edu.tr/api/ogrenci/sinif/KayitliSinifListesi/" + donemId);
- xhr.setRequestHeader("Authorization", "Bearer " + jwt);
- xhr.onload = () => {
- if (xhr.readyState == 4 && xhr.status == 200) {
- resolve(JSON.parse(xhr.response));
- } else {
- reject(xhr.status);
- }
- };
- xhr.send();
- })
- }
- async function getHarfNotuListesi(jwt, donemId) {
- return new Promise((resolve, reject) => {
- const xhr = new XMLHttpRequest();
- xhr.open("GET", "https://obs.itu.edu.tr/api/ogrenci/Sinif/SinifHarfNotuListesi/" + donemId);
- xhr.setRequestHeader("Authorization", "Bearer " + jwt);
- xhr.onload = () => {
- if (xhr.readyState == 4 && xhr.status == 200) {
- const arr = JSON.parse(xhr.response).sinifHarfNotuResultList;
- const obj = {};
- for (const not of arr) {
- obj[not.crn] = not.harfNotu;
- }
- resolve(obj);
- } else {
- reject(xhr.status);
- }
- };
- xhr.send();
- })
- }
- async function getNotListesi(jwt, sinifId) {
- return new Promise((resolve, reject) => {
- const xhr = new XMLHttpRequest();
- xhr.open("GET", "https://obs.itu.edu.tr/api/ogrenci/Sinif/SinifDonemIciNotListesi/" + sinifId);
- xhr.setRequestHeader("Authorization", "Bearer " + jwt);
- xhr.onload = () => {
- if (xhr.readyState == 4 && xhr.status == 200) {
- resolve(JSON.parse(xhr.response));
- } else {
- reject(xhr.status);
- }
- };
- xhr.send();
- })
- }
- String.prototype.formatStr = String.prototype.formatStr ||
- function () {
- "use strict";
- var str = this.toString();
- if (arguments.length) {
- var t = typeof arguments[0];
- var key;
- var args = ("string" === t || "number" === t) ?
- Array.prototype.slice.call(arguments)
- : arguments[0];
- for (key in args) {
- str = str.replace(new RegExp("\\{" + key + "\\}", "gi"), args[key]);
- }
- }
- return str;
- };
- const htmlParser = new DOMParser();
- function createHTMLElement(str) {
- const doc = htmlParser.parseFromString(str, "text/html");
- return doc.body.firstChild;
- }
- function insertBeforeHTMLElement(str, el) {
- const insert = createHTMLElement(str);
- el.parentElement.insertBefore(insert, el);
- }
- const newOptionTemplate = `
- <option value="{id}">{name}</option>
- `;
- const newCardTemplate = `
- <div class="row">
- <div class="col-md-12 mb-5">
- <div class="card info-graphic info-graphic--service">
- <div class="card-body">
- <h2>Notlar</h2>
- <select id="notscript-donemlist" class="form-control" style="margin: 10px">
- {1}
- </select>
- <div class="row" style="justify-content: center; align-items: center;">
- <input id="notscript-hidetrivial" type="checkbox">
- <label for="notscript-hidetrivial" style="padding-left: 10px; margin: 0; user-select: none;">Hiç not girilmemiş dersleri gizle</label>
- </div>
- {0}
- </div>
- </div>
- </div>
- </div>
- `;
- const newDonemTemplate = `
- <div style="display: none" class="notscript-donem" data-id={id}>{classes}</div>
- `;
- const newClassTemplateTable = `
- <div class="col-lg-12 mb-3 notscript-class" data-crn="{crn}">
- <h4 style="font-weight: 600">{name}</h4>
- <div class="table-vertical table-vertical--unheight">
- <table class="table table-striped table-bordered" style="table-layout: fixed">
- <tbody>
- {notes}
- <tr>
- <th class="title" style="width: 40%">Ağırlıklı Ortalama</th>
- <td>{average}</td>
- </tr>
- <tr style="display: {harfnotudisp}">
- <th class="title" style="width: 40%">Harf Notu</th>
- <td style="font-weight: 600; font-size: 1.8rem; color: {harfnotucolor}">{harfnotu}</td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- `;
- const newNoteTemplateTable = `
- <tr>
- <th class="title" style="width: 40%">{name} - %{perc} - Sıra: {pos}/{enrolled} - Ort. {avg} - S.Sap {devi}</th>
- <td>{note}</td>
- </tr>
- `;
- const classLineTemplate = `
- <div id="notscript-line-{crn}" style="width: 100%; height: 1px; background: #358aed; margin-bottom: 15px; margin-top: 13px;"></div>
- `;
- // TODO: Option to hide ignorable classes
- // TODO: Term Selection
- async function printNotlar() {
- const jwt = await getJWT();
- const donemListesi = (await getDonemListesi(jwt)).ogrenciDonemListesi;
- const sonDonem = donemListesi[donemListesi.length - 1];
- const sonDonemId = sonDonem.akademikDonemId;
- const addBefore = document.querySelectorAll(".obs > .container-fluid > div > .row")[1];
- const hidecrns = [];
- let donemOptList = "";
- let donems = "";
- for (let i = donemListesi.length - 1; i >= 0; i--) {
- const donem = donemListesi[i];
- donemOptList += newOptionTemplate.formatStr({ id: donem.akademikDonemId, name: donem.akademikDonemAdi });
- const sinifListesi = (await getSinifListesi(jwt, donem.akademikDonemId)).kayitSinifResultList;
- const harfNotuListesi = (await getHarfNotuListesi(jwt, donem.akademikDonemId));
- let classesEl = "";
- for (const sinif of sinifListesi) {
- if (classesEl !== "") classesEl += classLineTemplate.formatStr({ crn: sinif.crn });
- const sinifNameEn = sinif.bransKodu + sinif.dersKodu + " - " + sinif.dersAdiEN + " (CRN: " + sinif.crn + ")";
- const sinifNameTr = sinif.bransKodu + sinif.dersKodu + " - " + sinif.dersAdiTR + " (CRN: " + sinif.crn + ")";
- const sinifId = sinif.sinifId;
- const notListesiObj = (await getNotListesi(jwt, sinifId));
- const notListesi = notListesiObj.sinifDonemIciNotListesi;
- const ortalama = notListesiObj.ortalama;
- let notesEl = "";
- for (const not of notListesi) {
- const name = not.degerlendirmeOlcutuAdi;
- const perc = not.degerlendirmeKatkisi;
- const note = not.not;
- const pos = not.sinifSirasi;
- const enrolled = not.ogrenciSayisi;
- const avg = not.ortalama;
- const devi = not.standartSapma;
- notesEl += newNoteTemplateTable.formatStr({ name, perc, note, pos, enrolled, avg, devi });
- }
- if (notListesi.length === 0 && !harfNotuListesi[sinif.crn]) {
- hidecrns.push(sinif.crn);
- }
- let harfnotudisp = "none";
- let harfnotu = "";
- let harfnotucolor = "red"
- if (harfNotuListesi[sinif.crn]) {
- harfnotudisp = "";
- harfnotu = harfNotuListesi[sinif.crn];
- if (harfnotu === "AA" || harfnotu === "BL") {
- harfnotucolor = "#22dd22";
- } else if (harfnotu === "BA+" || harfnotu === "BA" || harfnotu === "BB+" || harfnotu === "BB") {
- harfnotucolor = "#aadd22"
- } else if (harfnotu === "CB+" || harfnotu === "CB" || harfnotu === "CC+" || harfnotu === "CC") {
- harfnotucolor = "#dddd22"
- } else if (harfnotu === "DC+" || harfnotu === "DC" || harfnotu === "DD+" || harfnotu === "DD") {
- harfnotucolor = "#dd9922"
- } else if (harfnotu === "VF" || harfnotu === "FF" || harfnotu === "BZ") {
- harfnotucolor = "#dd2222"
- }
- }
- classesEl += newClassTemplateTable.formatStr({ crn: sinif.crn, name: sinifNameTr, notes: notesEl, average: ortalama, harfnotudisp, harfnotu, harfnotucolor });
- }
- donems += newDonemTemplate.formatStr({ id: donem.akademikDonemId, classes: classesEl });
- }
- const cardEl = newCardTemplate.formatStr(donems, donemOptList);
- const cardEll = createHTMLElement(cardEl);
- addBefore.parentElement.insertBefore(cardEll, addBefore);
- const donemlistEl = cardEll.querySelector("#notscript-donemlist");
- const donemElList = cardEll.querySelectorAll(".notscript-donem");
- donemlistEl.onchange = (e) => {
- for (const donem of donemElList) {
- if (donem.dataset.id === donemlistEl.value) donem.style.display = "";
- else donem.style.display = "none";
- }
- }
- donemlistEl.onchange();
- const hidetrivialEl = cardEll.querySelector("#notscript-hidetrivial");
- hidetrivialEl.checked = window.localStorage.getItem("hide_trivial_classes");
- const classes = cardEll.querySelectorAll(".notscript-class");
- const trivialClasses = classes.values().filter(cl => hidecrns.includes(cl.dataset.crn)).toArray();
- hidetrivialEl.onchange = (e) => {
- const disp = hidetrivialEl.checked ? "none" : "";
- window.localStorage.setItem("hide_trivial_classes", hidetrivialEl.checked);
- for (const cl of trivialClasses) {
- cl.style.display = disp;
- const line = cardEll.querySelector("#notscript-line-" + cl.dataset.crn);
- line.style.display = disp;
- }
- }
- hidetrivialEl.onchange();
- }
- printNotlar();
- })();