aboutsummaryrefslogtreecommitdiff
path: root/js/database.js
blob: 73c2d176bd938769da2870df91c6f2c23f756ebe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import { getCourseId } from "./config.js";

const DB_TEMPLATE_LIST_HEADER = `
<table class="table table-striped">
  <thead>
    <tr>
      <th>Json</th>
    </tr>
  </thead>
  <tbody>
`;
const DB_TEMPLATE_LIST_ENTRY = `
<tr class="db-row">
  <td class="db-cell" data-key="date">##timeadded##</td>
  <td class="db-cell" data-key="coach">##user##</td>
  <td class="db-cell" data-key="json">[[Json]]</td>
</tr>
`;
const DB_TEMPLATE_LIST_FOOTER = `
 </tbody>
</table>
`;

let studentDbs = populateStudentDbs();

async function populateStudentDbs() {
	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');

	let dbs = new Map();
	for (const link of courseDoc.querySelectorAll("div.activityname a.aalink")) {
		const match = link.textContent.match(/(\d+)(Shadow|Public|Submit)/);
		if (!match) continue;
		const studentId = match[1];
		const dbType = match[2];
		const dbId = link.href.match(/[?&]id=(\d+)/)[1]

		if (!dbs.has(studentId)) {
			dbs.set(studentId, {});
		}

		dbs.get(studentId)[dbType.toLowerCase()] = new DB(dbId);
	}

	return dbs;
}

class DB {
	constructor(id) {
		this.id = id;
	}

	async fetchEntries(params) {
		return loadFromDatabaseActivity(this.id, params)
	}

	async saveEntry(json) {
		return addEntryToDatabaseActivity(this.id, json);
	}

	static async getStudentDbs(student) {
		const dbs = await studentDbs;
		return dbs.get(student.id);
	}
}

async function loadFromDatabaseActivity(id, params) {
	let dbUrl = `${window.location.origin}/mod/data/view.php?id=${id}&mode=list&perpage=1000`;
	// TODO(muhq): Why does this not include entries?
	if (params) {
		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 = [];
	dbDoc.querySelectorAll('.db-row').forEach(row => {
		let entry = {};
		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 loadFromStudentDatabase(student, type) {
	const dbs = await DB.getStudentDbs(student);
	const db = dbs[type];
	return await db.fetchEntries()
}

async function addEntryToDatabaseActivity(id, json) {
	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,
	});
}

async function addEntryToStudentDatabase(student, type, json) {
	const dbs = await DB.getStudentDbs(student);
	const db = dbs[type];
	await db.saveEntry(json);
}

export {
	DB,
	loadFromDatabaseActivity, loadFromStudentDatabase,
	addEntryToDatabaseActivity, addEntryToStudentDatabase,
};