import { getCourseId } from "./utils-ENV.js"; const DB_TEMPLATE_LIST_HEADER = ` `; const DB_TEMPLATE_LIST_ENTRY = ` `; const DB_TEMPLATE_LIST_FOOTER = `
Json
##timeadded## ##user## [[Json]]
`; let graduationDb = findGraduationDb(); const ID_QUERY_PARAM_REGEX = /[?&]id=(\d+)/; async function findGraduationDb() { let graduationDbId = localStorage.getItem("gruaduationDbId"); if (graduationDbId !== null) { return new DB(Number(graduationDbId)); } const courseUrl = `https://lernplattform.bycs.de/course/view.php?id=${getCourseId()}`; const courseRes = await fetch(courseUrl); const courseDoc = new DOMParser().parseFromString(await courseRes.text(), "text/html"); for (const a of courseDoc.querySelectorAll("div.activityname a.aalink")) { if (a.textContent.trim() === "Graduation Datenbank") { const anchor = a as HTMLAnchorElement; const match = anchor.href.match(ID_QUERY_PARAM_REGEX); if (match === null) continue; const dbId = match[1]; localStorage.setItem("graduationDbId", dbId); return new DB(Number(dbId)); } } console.assert(false, "Graduation DB not found"); } interface DatabaseParams { [key: string]: string; } interface DatabaseEntry { [key: string]: string; } class DB { id: number; constructor(id: number) { this.id = id; } async fetchEntries(params?: DatabaseParams) { return loadFromDatabaseActivity(this.id, params); } async saveEntry(json: string) { return addEntryToDatabaseActivity(this.id, json); } } async function loadFromDatabaseActivity(id: string | number, params?: DatabaseParams) { let dbUrl = `${window.location.origin}/mod/data/view.php?id=${id}&mode=list&perpage=1000`; // TODO(muhq): Why does this not include entries? if (typeof params !== "undefined") { dbUrl += "&filter=1&advanced=1"; for (const param in params) { dbUrl += `&${param}=${encodeURIComponent(params[param])}`; } } const dbRes = await fetch(encodeURI(dbUrl)); const dbDoc = new DOMParser().parseFromString(await dbRes.text(), "text/html"); let data: any[] = []; dbDoc.querySelectorAll(".db-row").forEach((row) => { let entry: DatabaseEntry = {}; row.querySelectorAll(".db-cell").forEach((field) => { const key = field.dataset.key!; let value; // Moodle includes the full date in the title attribute of the included span if (key === "date") { value = field.querySelector("span")?.title; } else { value = field.innerText.trim(); } entry[key] = value!; }); data.push(entry); }); return data; } async function getGraduationDb() { return (await graduationDb)!; } async function addEntryToDatabaseActivity(id: number, json: string) { // TODO(muhq): do not fetch the form const url = `/mod/data/edit.php?id=${id}`; const editRes = await fetch(url); const editDoc = new DOMParser().parseFromString(await editRes.text(), "text/html"); const form = editDoc.querySelector('div[role="main"] > form'); const formData = new FormData(form!); for (const key of formData.keys()) { if (key.startsWith("field_")) { formData.set(key, json); // We found our json key break; } } formData.set("saveandview", "Speichern"); return await fetch("/mod/data/edit.php", { method: "POST", // Set the FormData instance as the request body body: formData, }); } export { DB, DatabaseEntry, DatabaseParams, getGraduationDb };