aboutsummaryrefslogtreecommitdiff
path: root/src/student-prod.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/student-prod.ts')
-rw-r--r--src/student-prod.ts90
1 files changed, 90 insertions, 0 deletions
diff --git a/src/student-prod.ts b/src/student-prod.ts
new file mode 100644
index 0000000..24ac869
--- /dev/null
+++ b/src/student-prod.ts
@@ -0,0 +1,90 @@
+import type { Graduation } from "./graduation-common.ts";
+import { Student } from "./student-common.ts";
+import { getUserIconUrl, getCourseParticipantsUrl } from "./utils-prod.js"
+import { fetchGraduation } from "./graduation-prod.ts";
+
+declare module "./student-common.ts" {
+ interface Student {
+ getGraduation(): Promise<Graduation>;
+ getIconUrl(): Promise<string>;
+ }
+}
+Student.prototype.getGraduation = function () {
+ return fetchGraduation(this);
+};
+
+Student.prototype.getIconUrl = function () {
+ return getUserIconUrl(this.id);
+};
+
+// Cache the fetched students.
+let students: Array<Student> | null = null;
+
+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")!;
+ const fetchedStudents: Array<Student> = [];
+ 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<HTMLElement>(".c1")!;
+ let name;
+ const c = nameCell.firstChild!.firstChild! as HTMLElement;
+ if (c.tagName == "SPAN")
+ name = c.title;
+ else
+ name = nameCell.innerText;
+
+ const profileUrl = nameCell.querySelector<HTMLAnchorElement>("a.aabtn")!.href;
+ const match = idRegex.exec(profileUrl);
+ if (match === null) {
+ console.error("Profile Regex did not match");
+ return;
+ }
+ const id = match[1];
+
+ const groupCell = row.querySelector(".c5")!;
+ const group = groupCell.querySelector<HTMLElement>("a.quickeditlink")!.textContent;
+
+ fetchedStudents.push(new Student(Number(id), name, group));
+ });
+ return fetchedStudents;
+}
+
+async function fetchStudents(idFilter?: number, nameFilter?: string, groupFilter?: string) {
+ if (students === null) {
+ const studentsPromise = _fetchStudents();
+ const storedStudents = localStorage.getItem("students");
+ if (storedStudents) {
+ studentsPromise.then((fetched) => localStorage.setItem("students", JSON.stringify(fetched)));
+ students = [];
+ 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) =>
+ (typeof idFilter === "undefined" || s.id === idFilter) &&
+ (typeof nameFilter === "undefined" || s.name.includes(nameFilter)) &&
+ (typeof groupFilter === "undefined" || s.group.includes(groupFilter)));
+}
+
+async function fetchStudent(idFilter: number, nameFilter: string, groupFilter: string) {
+ const students = await fetchStudents(idFilter, nameFilter, groupFilter);
+ return students[0];
+}
+
+export { Student, fetchStudents, fetchStudent };