您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Remove students that aren't students anymore
// ==UserScript== // @name Just Students // @namespace https://github.com/Marado-Programer/ // @match http*://oghma.epcc.pt/* // @grant none // @version 1.2 // @author [email protected] // @description Remove students that aren't students anymore // ==/UserScript== const url = window.location.href; document.body.innerHTML = document.body.innerHTML.replaceAll(/João Rodrigues/g, "Draikontuga"); document.body.innerHTML = document.body.innerHTML.replaceAll(/João Afonso Andrade Rodrigues/g, "Draikontuga"); document.querySelectorAll("li.student, tr.student").forEach((student) => { if (!student.classList.contains("active")) student.remove(); }); if (url.match(/units/)) { document.querySelectorAll("table.evaluations tr").forEach((student, i) => { if (i != 0 && !student.classList.contains("active")) student.remove(); }); const evaluationsTable = document.getElementsByClassName("evaluations")[1], evaluations = document.querySelectorAll("table.evaluations tr.active"); const orderedEvaluations = [].slice.call(evaluations).sort((x, y) => x.querySelector(".number") ? (x.querySelector(".number").childNodes[0].nodeValue - y.querySelector(".number").childNodes[0].nodeValue) : (x.querySelector("td:nth-child(4)").innerText - y.querySelector("td:nth-child(4)").innerText) ); evaluations.forEach((i) => i.remove()); orderedEvaluations.forEach((i) => evaluationsTable.append(i)); } else if (url.match(/users/)) { const evaluationsTable = document.getElementsByClassName("evaluations")[1], evaluations = document.querySelectorAll("table.evaluations tr.evaluation"); const date = /(\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2} UTC)/; const orderedEvaluations = [].slice.call(evaluations).sort((x, y) => { const xDate = new Date(date.exec(x.childNodes[15].title)[1]); const yDate = new Date(date.exec(y.childNodes[15].title)[1]); //return xDate - yDate; return x.childNodes[5].innerHTML - y.childNodes[5].innerHTML; }); const avg = orderedEvaluations.reduce((x, y) => parseInt( typeof x === "number" ? x : x.querySelector("td:nth-child(3)").innerText, 10, ) + parseInt( typeof y === "number" ? y : y.querySelector("td:nth-child(3)").innerText, 10, ) ); evaluations.forEach((i) => i.remove()); orderedEvaluations.forEach((i) => evaluationsTable.append(i)); const avgtr = document.createElement("tr"); avgtr.append(document.createElement("td")); avgtr.append(document.createElement("td")); const avgtd = document.createElement("td"); const b = document.createElement("b"); b.append( document.createTextNode(`Average: ${avg / orderedEvaluations.length}`), ); avgtd.append(b); avgtr.append(avgtd); avgtr.append(document.createElement("td")); avgtr.append(document.createElement("td")); avgtr.append(document.createElement("td")); avgtr.append(document.createElement("td")); avgtr.append(document.createElement("td")); avgtr.append(document.createElement("td")); evaluationsTable.append(avgtr); } else if (url.match(/\/courses\/?$/)) { Promise.all( [].slice.call( document.querySelectorAll( "#main > div > div.span10.main > table > tbody > tr a", ), ).map((i) => fetch(`${i.href}/evaluations`).then((res) => res.text()).then( (course) => { const you_start = course.indexOf('<tr class="active me">'); const you = course.substring( you_start, course.indexOf("</tr>", you_start), ).trim(); const rate_start = you.indexOf('<td class="number">'); const matches = you.substring( rate_start, you.indexOf("</td>", rate_start), ).match(/(\d+\.\d+).*\d+\/(\d+)/); if (matches == null) return; const [, rate, _modules] = matches; return rate; }, ) ), ).then((rates) => rates.filter((i) => typeof i === "string")).then((rates) => rates.reduce((x, y) => parseFloat(x, 10) + parseFloat(y, 10)) / rates.length ).then((avg) => console.log(avg)); } else if (url.match("/courses/")) { (async () => { const pages = [].slice.call( document.querySelectorAll( "#main > div > div.span10.main > ul > li > a:nth-child(1)", ), ).map(( i, ) => [i, fetch(`${i.href}/evaluations/`).then((res) => res.text())]); const unsorted = []; for (const [url, p] of pages) { const page = await p; const dummy = document.createElement("div"); const start = page.indexOf("<table"); dummy.innerHTML = page.substring( start, page.indexOf("</table>", start), ).trim(); const evaluationsTable = dummy.getElementsByClassName("evaluations")[0], evaluations = dummy.querySelectorAll( "table.evaluations tr.evaluation", ); const avg = [].slice.apply(evaluations).reduce((x, y) => parseInt( typeof x === "number" ? x : x.querySelector("td:nth-child(3)").innerText, 10, ) + parseInt( typeof y === "number" ? y : y.querySelector("td:nth-child(3)").innerText, 10, ), 0); unsorted.push([url, (avg / evaluations.length).toFixed(3)]); } const allavg = unsorted.reduce(([, x], [, y]) => [undefined, parseFloat(Number.isNaN(+x) ? 0 : x, 10) + parseFloat(Number.isNaN(+y) ? 0 : y, 10)])[1] / unsorted.filter(([, x]) => !Number.isNaN(+x)).length; const avgli = document.createElement("li"); avgli.classList.add("student"); avgli.classList.add("active"); //avgli.style.backgroundColor = "#FF1818"; avgli.innerHTML = '<a href="#AVG"><img src="" style="height: 79px; width: auto"></a><span class=""></span><br><a href="#AVG">AVERAGE USER</a>'; unsorted.push(["#AVG", allavg.toFixed(3)]); const lisorted = unsorted.sort(([, x], [, y]) => x - y).map( ([href, avg]) => { let student = null; if (href === "#AVG") { student = avgli; } else { const url = (new URL(href).pathname).replace(/\/?evaluations\/?/, ""); student = document.querySelector( `#main > div > div.span10.main > ul > li:has(a[href="${url}"])`, ); } const n = student.querySelector("span"); if (n != null) { n.innerText += ` (${avg})`; } return student; }, ); const list = document.querySelector("#main > div > div.span10.main > ul"); [].slice.apply(list.querySelectorAll("li")).forEach((i) => i.remove()); lisorted.forEach((i) => list.append(i)); })(); }