diff options
| author | Florian Fischer <florian.fischer@muhq.space> | 2026-08-03 14:31:25 +0200 |
|---|---|---|
| committer | Florian Fischer <florian.fischer@muhq.space> | 2026-08-03 14:31:25 +0200 |
| commit | 6839831af54cd9302119bcc3bffafe10475958d4 (patch) | |
| tree | 12a1c1fbd864e9579cb9c3a09d4bf4686a280b73 /src/student-common.js | |
| parent | fccb70cbd876785f6833dfe6efc10ec9e445556d (diff) | |
| download | bycs-sol-6839831af54cd9302119bcc3bffafe10475958d4.tar.gz bycs-sol-6839831af54cd9302119bcc3bffafe10475958d4.zip | |
refactor project structure
* merge sites into single project root
* fix name of mass-graduation site
* enable typescript support
Diffstat (limited to 'src/student-common.js')
| -rw-r--r-- | src/student-common.js | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/src/student-common.js b/src/student-common.js new file mode 100644 index 0000000..2dfa35d --- /dev/null +++ b/src/student-common.js @@ -0,0 +1,115 @@ +import { getCourseId, getUserIconUrl, getCourseParticipantsUrl } from "./utils-ENV.js"; +import { fetchGraduation } from "./graduation-common.js"; +/** + * Class to represent Students. + */ +class Student { + graduation = null; + + constructor(id, name, group) { + this.id = id; + this.name = name; + this.group = group; + } + + async getIconUrl() { + return await getUserIconUrl(this.id); + } + + getGroup() { + return this.group; + } + + async getGraduation() { + if(!this.graduation) { + // fetchGraduation(this) sets this.graduation + await fetchGraduation(this); + } + return this.graduation; + } + + static async fetchById(id) { + let name = ""; + let group = ""; + + const res = await fetch(`/user/view.php?id=${id}&course=${getCourseId()}`); + const doc = new DOMParser().parseFromString(await res.text(), "text/html"); + + name = doc.querySelector("div.page-header-headings > h2").textContent; + + const cards = doc.querySelectorAll("div.card-body dl"); + for (const card of cards) { + if (card.querySelector("dt").textContent !== "Gruppe") + continue; + group = card.querySelector("dd > a").textContent; + break; + } + + return new Student(id, name, group); + } +} + +// Cache the fetched students. +let students = []; + +const idRegex = /id=(\d+)/; +async function _fetchStudents() { + const res = await fetch(getCourseParticipantsUrl()); + const doc = new DOMParser().parseFromString(await res.text(), "text/html"); + const table = doc.querySelector("tbody"); + let fetchedStudents = []; + table.querySelectorAll("tr").forEach(row => { + if (row.classList.contains("emptyrow")) + return; + + const roleCell = row.querySelector(".c4"); + // TODO(muhq): Is this locale dependent? + if (roleCell.innerHTML.includes("Lehrer")) { + return; + } + + const nameCell = row.querySelector(".c1"); + let name; + if (nameCell.firstChild.firstChild.tagName == "SPAN") + name = nameCell.firstChild.firstChild.title; + else + name = nameCell.innerText; + + const profileUrl = nameCell.querySelector("a.aabtn").href; + const match = idRegex.exec(profileUrl); + const id = match[1]; + + const groupCell = row.querySelector(".c5"); + const group = groupCell.querySelector("a.quickeditlink").textContent; + + fetchedStudents.push(new Student(id, name, group)); + }); + return fetchedStudents; +} + +async function fetchStudents(idFilter, nameFilter, groupFilter) { + if (!students.size) { + const studentsPromise = _fetchStudents() + const storedStudents = localStorage.getItem("students"); + if (storedStudents) { + studentsPromise.then((fetched) => localStorage.setItem("students", JSON.stringify(fetched))); + for (const o of JSON.parse(storedStudents)) { + students.push(new Student(o.id, o.name, o.group)); + } + } else { + students = await studentsPromise; + localStorage.setItem("students", JSON.stringify(students)); + } + } + + return students.filter((s) => (!idFilter || s.id === idFilter) && + (!nameFilter || s.name.includes(nameFilter)) && + (!groupFilter || s.group.includes(groupFilter))); +} + +async function fetchStudent(idFilter, nameFilter, groupFilter) { + const students = await fetchStudents(idFilter, nameFilter, groupFilter); + return students[0]; +} + +export { Student, fetchStudents, fetchStudent }; |
