aboutsummaryrefslogtreecommitdiff
path: root/src/moodle-prod.ts
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fischer@muhq.space>2026-09-27 18:48:50 +0200
committerFlorian Fischer <florian.fischer@muhq.space>2026-09-27 18:48:50 +0200
commit16668963d4dcc95ad281608dc3064677d8643404 (patch)
treed102b4b8af4b91f58e914a04975f5a75d6610f30 /src/moodle-prod.ts
parent20c1c0782bae0a10d1774f919e6381b5df44d207 (diff)
downloadbycs-sol-16668963d4dcc95ad281608dc3064677d8643404.tar.gz
bycs-sol-16668963d4dcc95ad281608dc3064677d8643404.zip
admin-tools: implement mass course update
Diffstat (limited to 'src/moodle-prod.ts')
-rw-r--r--src/moodle-prod.ts120
1 files changed, 120 insertions, 0 deletions
diff --git a/src/moodle-prod.ts b/src/moodle-prod.ts
new file mode 100644
index 0000000..39bb190
--- /dev/null
+++ b/src/moodle-prod.ts
@@ -0,0 +1,120 @@
+import { getCourseId, getSesskey } from "./utils-ENV.js";
+
+export class Activity {
+ id: number;
+ title: string;
+
+ constructor(id: number, title: string) {
+ this.id = id;
+ this.title = title;
+ }
+
+ async update(text: string) {
+ const url = `https://lernplattform.bycs.de/course/modedit.php?update=${this.id}`;
+ const editRes = await fetch(url);
+ const editDoc = new DOMParser().parseFromString(await editRes.text(), "text/html");
+ const form = editDoc.querySelector<HTMLFormElement>('div[role="main"] > form');
+ const formData = new FormData(form!);
+
+ formData.set("page[text]", text);
+ formData.set("submitbutton", "Speichern und anzeigen");
+ return await fetch("/course/modedit.php", {
+ method: "POST",
+ body: formData,
+ });
+ }
+}
+
+export class Course {
+ id: Number;
+ title: string;
+ activities: Promise<Array<Activity>>;
+
+ constructor(id: number, title: string, courseDoc?: Document) {
+ this.id = id;
+ this.title = title;
+ this.activities = this.fetchActivities(courseDoc);
+ }
+
+ async fetchActivities(courseDoc?: Document) {
+ if (typeof courseDoc === "undefined") {
+ const courseUrl = `https://lernplattform.bycs.de/course/view.php?id=${this.id}`;
+ const courseRes = await fetch(courseUrl);
+ courseDoc = new DOMParser().parseFromString(await courseRes.text(), "text/html");
+ }
+
+ const activities = [];
+ for (const n of courseDoc.querySelectorAll(".activity-name-area")) {
+ const url = n.querySelector<HTMLAnchorElement>(".aalink")?.href!;
+ const match = /id=(\d+)/.exec(url);
+ const a = new Activity(Number(match![1]), n.textContent.trim());
+ activities.push(a);
+ }
+
+ return activities;
+ }
+
+ async getActivity(name: string) {
+ const activities = await this.activities;
+ for (const a of activities) {
+ if (a.title.includes(name)) {
+ return a;
+ }
+ }
+ return null;
+ }
+}
+
+export async function fetchCourse(courseId?: number) {
+ if (typeof courseId === "undefined") {
+ courseId = Number(getCourseId());
+ }
+
+ const courseUrl = `https://lernplattform.bycs.de/course/view.php?id=${courseId}`;
+ const courseRes = await fetch(courseUrl);
+ const courseDoc = new DOMParser().parseFromString(await courseRes.text(), "text/html");
+
+ return new Course(courseId, courseDoc.querySelector("h1")?.innerText!, courseDoc);
+}
+
+export async function fetchCourses(pattern: string) {
+ const params = {
+ index: 0,
+ methodname: "core_course_get_enrolled_courses_by_timeline_classification",
+ args: {
+ offset: 0,
+ limit: 0,
+ classification: "search",
+ sort: "fullname",
+ customfieldname: "schule",
+ customfieldvalue: "Gymnasium Messestadt Riem",
+ searchvalue: pattern,
+ requiredfields: [
+ "id",
+ "fullname",
+ "shortname",
+ "showcoursecategory",
+ "showshortname",
+ "visible",
+ "enddate",
+ ],
+ },
+ };
+
+ const coursesRes = await fetch(
+ `/lib/ajax/service.php?sesskey=${getSesskey()}&info=core_course_get_enrolled_courses_by_timeline_classification`,
+ {
+ method: "POST",
+ body: JSON.stringify([params]),
+ },
+ );
+
+ const coursesJSON = JSON.parse(await coursesRes.text());
+ const courses = [];
+ for (const o of coursesJSON[0].data.courses) {
+ const c = new Course(o.id, o.fullname);
+ courses.push(c);
+ }
+
+ return courses;
+}