diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/admin-tools.js | 31 | ||||
| -rw-r--r-- | src/moodle-prod.ts | 120 |
2 files changed, 151 insertions, 0 deletions
diff --git a/src/admin-tools.js b/src/admin-tools.js index f598c35..9da744b 100644 --- a/src/admin-tools.js +++ b/src/admin-tools.js @@ -1,5 +1,6 @@ import { GraduationChange, submitGraduationChange } from "./graduation-ENV.ts"; import { fetchStudent, fetchStudents } from "./student-ENV.ts"; +import { fetchCourses } from "./moodle-ENV.ts"; let outputNode; function output(msg) { @@ -38,11 +39,41 @@ async function coachAssignmentImport() { output("Coach Zuweisung importiert"); } +async function updateActivities(course) { + const promises = []; + for (const activityName of ["Cockpit", "Klassenliste", "Coaching", "Admin-Tools"]) { + const activity = course.getActivity(activityName); + const input = document.getElementById(`${activityName.toLowerCase()}-file-input`); + if (input.value === "") continue; + const text = input.files[0].text(); + promises.push((await activity).update(await text)); + } + return Promise.all(promises); +} + +export async function updateCourses() { + output("loading courses ..."); + const courses = await fetchCourses("SOL Graduierung"); + output(`updating ${courses.length} courses ... `); + const promises = []; + for (const course of courses) { + promises.push(updateActivities(course)); + } + + Promise.all(promises) + .then(() => { + output("Updating activities done."); + }) + .catch((_error) => {}); +} + async function init() { outputNode = document.getElementById("admin-tools-output"); + output("Admin tools ready."); document .getElementById("admin-tools-coach-import-submit") .addEventListener("click", coachAssignmentImport); + document.getElementById("activity-update-submit").addEventListener("click", updateCourses); } if (document.readyState === "loading") { 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; +} |
