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, };