aboutsummaryrefslogtreecommitdiff
path: root/src/admin-tools.js
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fischer@muhq.space>2026-10-17 10:23:22 +0200
committerFlorian Fischer <florian.fischer@muhq.space>2026-10-17 10:23:22 +0200
commit198bbebd89d212faae3e45a22830bab66dec49e0 (patch)
tree1b92b64f29e0bc50f5ff845b154450c926b82a69 /src/admin-tools.js
parent38477bab6c1c736a2d1e7dd79b75c6e122502622 (diff)
downloadbycs-sol-198bbebd89d212faae3e45a22830bab66dec49e0.tar.gz
bycs-sol-198bbebd89d212faae3e45a22830bab66dec49e0.zip
admin-tools: add export tools and improve duplicate finderHEADmain
Considered as duplicates are eequal qual changes submitted in the same hour. Bump dependencies.
Diffstat (limited to 'src/admin-tools.js')
-rw-r--r--src/admin-tools.js85
1 files changed, 42 insertions, 43 deletions
diff --git a/src/admin-tools.js b/src/admin-tools.js
index 116b5ee..b3135b1 100644
--- a/src/admin-tools.js
+++ b/src/admin-tools.js
@@ -1,9 +1,13 @@
import { GraduationChange, submitGraduationChange } from "./graduation-ENV.ts";
+import { findDuplicateChanges } from "./graduation-common.ts";
import { fetchStudent, fetchStudents } from "./student-ENV.ts";
import { fetchCourses } from "./moodle-ENV.ts";
import { DB } from "./database-ENV.ts";
import { DATETIME_FMT } from "./utils-common.ts";
+import JSZip from "jszip";
+import FileSaver from "file-saver";
+
let outputNode;
function output(msg) {
if (outputNode.style.display === "none") {
@@ -83,53 +87,19 @@ async function findDuplicates(course) {
const entries = await db.fetchEntries();
const changes = entries.map((e) => GraduationChange.fromDBEntry(e));
- const searched = new Set();
- const duplicates = [];
- for (const change of changes) {
- if (searched.has(change)) continue;
- searched.add(change);
-
- const curDuplicates = [change];
- for (const other of changes) {
- if (other === change) continue;
-
- let same = true;
- for (const key in change) {
- switch (key) {
- case "changeId":
- continue;
- case "date":
- same = same && change.date.getTime() === other.date.getTime();
- break;
- case "context":
- same = same && JSON.stringify(change.context) === JSON.stringify(other.context);
- break;
- default:
- same = same && change[key] === other[key];
- }
- if (!same) break;
- }
-
- if (same) {
- curDuplicates.push(other);
- searched.add(other);
- }
- }
+ const duplicates = findDuplicateChanges(changes);
- if (curDuplicates.length > 1) {
- duplicates.push(curDuplicates);
+ if (duplicates.length !== 0) {
+ let msg = `${course.title} Duplikate:<br>`;
+ for (const d of duplicates) {
+ const ids = d.map((e) => e.changeId);
+ const c = d[0];
+ msg += `- ${DATETIME_FMT.format(c.date)} ${c.coach} ${c.studentId} ${c.change} ${JSON.stringify(c.context)} ids: ${ids}<br>`;
}
+ output(msg + "\n");
}
- if (duplicates.length === 0) return;
-
- let msg = `${course.title} Duplikate:<br>`;
- for (const d of duplicates) {
- const ids = d.map((e) => e.changeId);
- const c = d[0];
- msg += `- ${DATETIME_FMT.format(c.date)} ${c.coach} ${c.studentId} ${c.change} ${JSON.stringify(c.context)} ids: ${ids}<br>`;
- }
- output(msg + "\n");
+ return [course, duplicates];
}
async function findAllDuplicates() {
@@ -141,6 +111,34 @@ async function findAllDuplicates() {
}
}
+async function exportGraduations(course) {
+ const dbActivity = await course.getActivity("Graduation");
+ const db = new DB(dbActivity.id);
+ const exportResponse = await db.exportEntries();
+ return [course, await exportResponse.text()];
+}
+
+async function exportAllGraduations() {
+ output("loading courses ...");
+ const courses = await fetchCourses("SOL Graduierung");
+ output(`exporting graduations of ${courses.length} courses ... `);
+ const promises = [];
+ for (const course of courses) {
+ promises.push(exportGraduations(course));
+ }
+ const results = await Promise.all(promises);
+
+ const zip = new JSZip();
+
+ for (const [course, entries] of results) {
+ zip.file(`${course.title}.csv`, entries);
+ }
+
+ zip.generateAsync({ type: "blob" }).then(function (content) {
+ FileSaver.saveAs(content, "graduation-db-exports.zip");
+ });
+}
+
async function init() {
outputNode = document.getElementById("admin-tools-output");
output("Admin tools ready.");
@@ -153,6 +151,7 @@ async function init() {
output(JSON.stringify(students.map((s) => s.id)));
});
document.getElementById("find-duplicates").addEventListener("click", findAllDuplicates);
+ document.getElementById("export-graduation-dbs").addEventListener("click", exportAllGraduations);
}
if (document.readyState === "loading") {