aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFurkan Sahin <furkan-dev@proton.me>2021-09-05 22:56:45 -0500
committerFurkan Sahin <furkan-dev@proton.me>2021-09-05 22:56:45 -0500
commitfea56ae09cd612003e1bafd2459556b67a5950e9 (patch)
treea195fab20351891e6a65f68d77b88bf8c9671e75 /src
parentd0975a6e7ee57de4debda94e823011d813fbf4a1 (diff)
Add import/export functionality
Diffstat (limited to 'src')
-rw-r--r--src/components/EditorActions.svelte48
-rw-r--r--src/logic/EditorActions.ts13
-rw-r--r--src/models/EventInfo.ts10
-rw-r--r--src/models/Lab.ts18
-rw-r--r--src/models/PeerTeacher.ts21
-rw-r--r--src/util/parser.ts48
6 files changed, 152 insertions, 6 deletions
diff --git a/src/components/EditorActions.svelte b/src/components/EditorActions.svelte
index a0372ed..fa2a041 100644
--- a/src/components/EditorActions.svelte
+++ b/src/components/EditorActions.svelte
@@ -3,7 +3,11 @@
import IconButton from "@smui/icon-button";
import Snackbar, { Actions } from "@smui/snackbar";
import FileUpload from "./FileUpload.svelte";
- import { parseLabScheduleFile, parsePTFile } from "../logic/EditorActions";
+ import {
+ parseDatabaseFile,
+ parseLabScheduleFile,
+ parsePTFile,
+ } from "../logic/EditorActions";
import { labStore, ptStore } from "../stores";
let ptSchedules: FileList | null;
@@ -50,10 +54,48 @@
}
$: {
- if (dbFile?.length) console.log(dbFile);
+ if (dbFile?.length) {
+ parseDatabaseFile(dbFile[0])
+ .then((database) => {
+ labStore.set(database.labs);
+ ptStore.set(database.peerTeachers);
+ })
+ .catch(() => {
+ snackbarText = "Failed to import database. See console for details.";
+ snackbar.open();
+ });
+ }
}
- function exportDB() {}
+ function exportDB() {
+ const peerTeachers = [...$ptStore.values()];
+ const labs = [...$labStore.values()];
+ const database = {
+ labs: labs,
+ peerTeachers: peerTeachers,
+ };
+
+ const dbObj = JSON.stringify(database, (_, value) => {
+ // Need to manually convert the PeerTeacher objects'
+ // `labs` set to an array because `JSON.stringify` doesn't
+ // support "stringing" it out of the box
+ if (typeof value === "object" && value instanceof Set) {
+ return [...value];
+ }
+ return value;
+ });
+
+ const blob = new Blob([dbObj], { type: "text/json" });
+ const anchor = document.createElement("a");
+ const url = window.URL.createObjectURL(blob);
+ anchor.href = url;
+ anchor.download = "pt-db.json";
+ anchor.style.display = "none";
+ document.body.appendChild(anchor);
+ anchor.click();
+ document.body.removeChild(anchor);
+ window.URL.revokeObjectURL(url);
+ }
</script>
<div id="action-bar">
diff --git a/src/logic/EditorActions.ts b/src/logic/EditorActions.ts
index 875fdc4..4a83fbc 100644
--- a/src/logic/EditorActions.ts
+++ b/src/logic/EditorActions.ts
@@ -1,4 +1,4 @@
-import { parseLabSchedule, parsePTSchedule } from "../util/parser";
+import { parseDatabase, parseLabSchedule, parsePTSchedule } from "../util/parser";
export async function parsePTFile(file: File) {
try {
@@ -20,3 +20,14 @@ export async function parseLabScheduleFile(file: File) {
throw error;
}
}
+
+export async function parseDatabaseFile(file: File) {
+ const text = await file.text();
+ try {
+ const database = JSON.parse(text);
+ return parseDatabase(database);
+ } catch (error) {
+ console.error(file.name, error);
+ throw error;
+ }
+}
diff --git a/src/models/EventInfo.ts b/src/models/EventInfo.ts
index d20682c..6fce60b 100644
--- a/src/models/EventInfo.ts
+++ b/src/models/EventInfo.ts
@@ -1,3 +1,9 @@
+interface EventInfoSerializeInfo {
+ days: string,
+ start: number,
+ end: number
+}
+
export default class EventInfo {
days: string;
start: number;
@@ -16,6 +22,10 @@ export default class EventInfo {
this.end = end;
}
+ static fromJSON({days, start, end}: EventInfoSerializeInfo) {
+ return new EventInfo(days, start, end);
+ }
+
static timeToStr(time: number) {
let hour = Math.floor(time / 100);
const minute = time % 100;
diff --git a/src/models/Lab.ts b/src/models/Lab.ts
index 8636f74..d23cffb 100644
--- a/src/models/Lab.ts
+++ b/src/models/Lab.ts
@@ -1,4 +1,16 @@
-import type EventInfo from "./EventInfo";
+import EventInfo from "./EventInfo";
+
+interface LabSerializeInfo {
+ course: number,
+ section: number,
+ event: {
+ days: string,
+ start: number,
+ end: number
+ },
+ building: string,
+ room: string
+}
export default class Lab {
id: number;
@@ -24,6 +36,10 @@ export default class Lab {
this.room = room;
}
+ static fromJSON({course, section, event, building, room}: LabSerializeInfo) {
+ return new Lab(course, section, EventInfo.fromJSON(event), building, room);
+ }
+
get time() {
return this.event.info;
}
diff --git a/src/models/PeerTeacher.ts b/src/models/PeerTeacher.ts
index 6518a80..f1a8739 100644
--- a/src/models/PeerTeacher.ts
+++ b/src/models/PeerTeacher.ts
@@ -1,4 +1,16 @@
-import type EventInfo from "./EventInfo";
+import EventInfo from "./EventInfo";
+
+interface PeerTeacherSerializeInfo {
+ id: number,
+ firstname: string,
+ lastname: string,
+ events: {
+ days: string,
+ start: number,
+ end: number
+ }[],
+ labs: number[]
+}
export default class PeerTeacher {
id: number;
@@ -18,4 +30,11 @@ export default class PeerTeacher {
this.events = [];
this.labs = new Set();
}
+
+ static fromJSON({id, firstname, lastname, events, labs}: PeerTeacherSerializeInfo) {
+ const pt = new PeerTeacher(id, firstname, lastname);
+ pt.events = events.map(e => EventInfo.fromJSON(e));
+ pt.labs = new Set(labs);
+ return pt;
+ }
} \ No newline at end of file
diff --git a/src/util/parser.ts b/src/util/parser.ts
index 6d706d7..2f1bdd4 100644
--- a/src/util/parser.ts
+++ b/src/util/parser.ts
@@ -24,6 +24,32 @@ interface LabSchedule {
}[]
};
+interface DatabaseFile {
+ labs: {
+ id: number,
+ course: number,
+ section: number,
+ event: {
+ days: string,
+ start: number,
+ end: number
+ },
+ building: string,
+ room: string
+ }[],
+ peerTeachers: {
+ id: number,
+ firstname: string,
+ lastname: string,
+ events: {
+ days: string,
+ start: number,
+ end: number
+ }[],
+ labs: number[]
+ }[]
+}
+
/**
* Parses a peer teacher schedule
* @param schedule The schedule to parse
@@ -104,4 +130,26 @@ export function parseLabSchedule(schedule: LabSchedule) {
}
return results;
+}
+
+/**
+ * Parses a database file into maps of Lab and PeerTeacher objects
+ * @param database The database object from a database file
+ * @returns And object with lab and peer teacher maps
+ */
+export function parseDatabase(database: DatabaseFile) {
+ const result = {
+ labs: new Map<number, Lab>(),
+ peerTeachers: new Map<number, PeerTeacher>()
+ }
+
+ database.labs.forEach(lab => {
+ result.labs.set(lab.id, Lab.fromJSON(lab));
+ });
+
+ database.peerTeachers.forEach(pt => {
+ result.peerTeachers.set(pt.id, PeerTeacher.fromJSON(pt));
+ });
+
+ return result;
} \ No newline at end of file