feat: tsaplus.user.js
This commit is contained in:
parent
b3cf9776f2
commit
807dece8b3
188
userscripts/tsaplus.user.js
Normal file
188
userscripts/tsaplus.user.js
Normal file
@ -0,0 +1,188 @@
|
||||
// ==UserScript==
|
||||
// @name TSA+
|
||||
// @namespace Violentmonkey Scripts
|
||||
// @match https://tsa.hust.edu.vn/dang-ky-thi*
|
||||
// @namespace tretrauit-dev
|
||||
// @grant none
|
||||
// @version 1.0
|
||||
// @author tretrauit
|
||||
// @description 18:56:28 16/5/2024
|
||||
// @require https://raw.githubusercontent.com/naugtur/insertionQuery/master/insQ.min.js
|
||||
// ==/UserScript==
|
||||
|
||||
const sleep = ms => new Promise(r => setTimeout(r, ms));
|
||||
|
||||
function getElementByInnerText(element, text) {
|
||||
return Array.from(element.querySelectorAll("*")).find((e) => e.innerText === text);
|
||||
}
|
||||
|
||||
// Replace console functions with our own.
|
||||
// biome-ignore lint/complexity/noStaticOnlyClass: console replacement (in SessionStorage) since TSA disabled it fuck.
|
||||
class console {
|
||||
static log(...args) {
|
||||
const log = sessionStorage.getItem("tsaplus.console.log");
|
||||
if (log) {
|
||||
sessionStorage.setItem("tsaplus.console.log", `${log}\n${args.toString()}`);
|
||||
} else {
|
||||
sessionStorage.setItem("tsaplus.console.log", args.toString());
|
||||
}
|
||||
}
|
||||
static info(...args) {
|
||||
const log = sessionStorage.getItem("tsaplus.console.info");
|
||||
if (log) {
|
||||
sessionStorage.setItem("tsaplus.console.info", `${log}\n${args.toString()}`);
|
||||
} else {
|
||||
sessionStorage.setItem("tsaplus.console.info", args.toString());
|
||||
}
|
||||
}
|
||||
static warn(...args) {
|
||||
const log = sessionStorage.getItem("tsaplus.console.warn");
|
||||
if (log) {
|
||||
sessionStorage.setItem("tsaplus.console.warn", `${log}\n${args.toString()}`);
|
||||
} else {
|
||||
sessionStorage.setItem("tsaplus.console.warn", args.toString());
|
||||
}
|
||||
}
|
||||
static error(...args) {
|
||||
const log = sessionStorage.getItem("tsaplus.console.error");
|
||||
if (log) {
|
||||
sessionStorage.setItem("tsaplus.console.error", `${log}\n${args.toString()}`);
|
||||
} else {
|
||||
sessionStorage.setItem("tsaplus.console.error", args.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
unsafeWindow.console = console;
|
||||
|
||||
|
||||
// Hijack XHR with ours.
|
||||
let lastExamDetail = null;
|
||||
const OrigXHR = unsafeWindow.XMLHttpRequest;
|
||||
function xhrResponseCallback(xhr) {
|
||||
if (xhr.responseURL.includes("https://api-hust.khaothi.online/my/apiv1/exams/get-exam-plan-detail")) {
|
||||
console.log(`Set lastExamDetail to ${xhr.responseURL}`);
|
||||
lastExamDetail = xhr.response;
|
||||
}
|
||||
}
|
||||
class XMLHttpRequest extends OrigXHR {
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
// alert("XHR created");
|
||||
this.onload = () => {
|
||||
xhrResponseCallback(this);
|
||||
// alert("XHR loaded");
|
||||
};
|
||||
}
|
||||
send(...args) {
|
||||
super.send(...args);
|
||||
}
|
||||
}
|
||||
unsafeWindow.XMLHttpRequest = XMLHttpRequest;
|
||||
|
||||
insertionQ(".ant-modal-root").every(async (_) => {
|
||||
let retry = 0;
|
||||
while (retry < 50 && lastExamDetail === null) {
|
||||
retry += 1;
|
||||
await sleep(100);
|
||||
if (retry >= 50) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
console.log("Found lastExamDetail");
|
||||
const examDetail = JSON.parse(lastExamDetail);
|
||||
lastExamDetail = null;
|
||||
const examId = examDetail.data.exam.id;
|
||||
const rsp = await fetch(`https://api-hust.khaothi.online/my/apiv1/exam-plan/get-test-sites?exam_id=${examId}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${localStorage.getItem("authen_access_token")}`
|
||||
}
|
||||
})
|
||||
const data = await rsp.json();
|
||||
const [element, elementType] = await Promise.any([(async () => {
|
||||
let element;
|
||||
do {
|
||||
await sleep(10);
|
||||
element = getElementByInnerText(document, "Thông tin đăng ký");
|
||||
retry += 1;
|
||||
if (retry >= 100) {
|
||||
return [null, null];
|
||||
}
|
||||
}
|
||||
while (element === undefined || element.parentElement === undefined);
|
||||
return [element, "register"];
|
||||
})(), (async () => {
|
||||
let element;
|
||||
do {
|
||||
await sleep(10);
|
||||
element = getElementByInnerText(document, "Điểm TSA");
|
||||
retry += 1;
|
||||
if (retry >= 100) {
|
||||
return [null, null];
|
||||
}
|
||||
}
|
||||
while (element === undefined || element.parentElement === undefined);
|
||||
return [element, "score"];
|
||||
})()])
|
||||
const waveInfo = {};
|
||||
const genericInfo = {
|
||||
totalContestants: 0,
|
||||
totalCapacity: 0
|
||||
};
|
||||
switch (elementType) {
|
||||
case "register":
|
||||
firstCol = element.parentElement.parentElement.children[0];
|
||||
break;
|
||||
case "score":
|
||||
firstCol = element.parentElement.parentElement.parentElement.parentElement;
|
||||
break;
|
||||
case null:
|
||||
return;
|
||||
}
|
||||
for (const testSite of data.data.test_sites) {
|
||||
if (testSite.name.startsWith("Đợt")) {
|
||||
const wave = testSite.name.split(" ")[1];
|
||||
if (!waveInfo[wave]) {
|
||||
waveInfo[wave] = {
|
||||
totalContestants: 0,
|
||||
totalCapacity: 0
|
||||
}
|
||||
}
|
||||
waveInfo[wave].totalContestants += testSite.count_test_taker;
|
||||
if (testSite.max_test_taker === 0) {
|
||||
waveInfo[wave].totalCapacity += testSite.count_test_taker;
|
||||
} else {
|
||||
waveInfo[wave].totalCapacity += testSite.max_test_taker;
|
||||
}
|
||||
} else {
|
||||
genericInfo.totalContestants += testSite.count_test_taker;
|
||||
if (testSite.max_test_taker === 0) {
|
||||
genericInfo.totalCapacity += testSite.count_test_taker;
|
||||
} else {
|
||||
genericInfo.totalCapacity += testSite.max_test_taker;
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(`Wave info: ${JSON.stringify(waveInfo)}`);
|
||||
console.log(`Generic info: ${JSON.stringify(genericInfo)}`);
|
||||
if (Object.keys(waveInfo).length > 0) {
|
||||
for (const [waveName, wave] of Object.entries(waveInfo)) {
|
||||
console.log("Adding wave info");
|
||||
const pElement = document.createElement("p");
|
||||
pElement.innerHTML = `Số thí sinh đăng ký đợt ${waveName}: ${wave.totalContestants}/${wave.totalCapacity}`;
|
||||
if (elementType === "register") {
|
||||
firstCol.insertBefore(pElement, firstCol.children[1]);
|
||||
} else {
|
||||
firstCol.insertBefore(pElement, firstCol.children[0]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log("Adding generic info");
|
||||
const pElement = document.createElement("p");
|
||||
pElement.innerHTML = `Số thí sinh đăng ký: ${genericInfo.totalContestants}/${genericInfo.totalCapacity}`;
|
||||
if (elementType === "register") {
|
||||
firstCol.insertBefore(pElement, firstCol.children[1]);
|
||||
} else {
|
||||
firstCol.insertBefore(pElement, firstCol.children[0]);
|
||||
}
|
||||
}
|
||||
});
|
Loading…
Reference in New Issue
Block a user