Kepler Script

Kepler için notlar

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

// ==UserScript==
// @name         Kepler Script
// @author       KazuroAkashi
// @match        https://obs.itu.edu.tr/ogrenci/
// @license MIT
// @version 0.0.1.20250106095007
// @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 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 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>
        {0}
      </div>
    </div>
  </div>
</div>
`;

const newClassTemplate = `
<div class="col-lg-12 mb-3">
  <h4>{name}</h4>
  {notes}
  <div class="row ml-5">
    <h5>Ağırlıklı Ortalama</h5>
    <div class="ml-5">{average}</div>
  </div>
</div>
`;

const newNoteTemplate = `
<div class="row ml-5">
  <h5>{name} (%{perc})</h5>
  <div class="ml-5">{note}</div>
</div>
`;

const newClassTemplateTable = `
<div class="col-lg-12 mb-3">
  <h4>{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>
      </tbody>
    </table>
  </div>
</div>
`;

const newNoteTemplateTable = `
<tr>
  <th class="title" style="width: 40%">{name} (%{perc})</th>
  <td>{note}</td>
</tr>
`;

async function printNotlar() {
  const jwt = await getJWT();
  const donemListesi = (await getDonemListesi(jwt)).ogrenciDonemListesi;
  const sonDonem = donemListesi[donemListesi.length - 1];
  const sonDonemId = sonDonem.akademikDonemId;
  const sinifListesi = (await getSinifListesi(jwt, sonDonemId)).kayitSinifResultList;

  const addBefore = document.querySelectorAll(".obs > .container-fluid > div > .row")[1];

  let classesEl = "";
  for (const sinif of sinifListesi) {
    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 notName = not.degerlendirmeOlcutuAdi;
      const notPerc = not.degerlendirmeKatkisi;
      const notValue = not.not;

      notesEl += newNoteTemplateTable.formatStr({ "name": notName, "perc": notPerc, "note": notValue });
    }

    classesEl += newClassTemplateTable.formatStr({ "name": sinifNameTr, "notes": notesEl, "average": ortalama });
  }

  const cardEl = newCardTemplate.formatStr(classesEl);
  insertBeforeHTMLElement(cardEl, addBefore);
}

printNotlar();

})();