diff options
| author | Furkan Sahin <furkan-dev@proton.me> | 2021-09-05 22:56:45 -0500 |
|---|---|---|
| committer | Furkan Sahin <furkan-dev@proton.me> | 2021-09-05 22:56:45 -0500 |
| commit | fea56ae09cd612003e1bafd2459556b67a5950e9 (patch) | |
| tree | a195fab20351891e6a65f68d77b88bf8c9671e75 | |
| parent | d0975a6e7ee57de4debda94e823011d813fbf4a1 (diff) | |
Add import/export functionality
| -rw-r--r-- | src/components/EditorActions.svelte | 48 | ||||
| -rw-r--r-- | src/logic/EditorActions.ts | 13 | ||||
| -rw-r--r-- | src/models/EventInfo.ts | 10 | ||||
| -rw-r--r-- | src/models/Lab.ts | 18 | ||||
| -rw-r--r-- | src/models/PeerTeacher.ts | 21 | ||||
| -rw-r--r-- | src/util/parser.ts | 48 |
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 |
