summaryrefslogtreecommitdiff
path: root/app/note-store.js
diff options
context:
space:
mode:
Diffstat (limited to 'app/note-store.js')
-rw-r--r--app/note-store.js66
1 files changed, 66 insertions, 0 deletions
diff --git a/app/note-store.js b/app/note-store.js
new file mode 100644
index 0000000..c816efd
--- /dev/null
+++ b/app/note-store.js
@@ -0,0 +1,66 @@
+"use strict";
+
+const fs = require("fs");
+const util = require("util");
+const {sj, res204, err400, err500} = require("./utils");
+
+const rd = util.promisify(fs.readdir);
+const rf = util.promisify(fs.readFile);
+const wf = util.promisify(fs.writeFile);
+
+const {R_OK,W_OK} = fs.constants;
+const exists = s => new Promise(r => fs.access(s, R_OK|W_OK, e => r(!e)));
+
+const NOTE_DIR = "./users";
+
+function genNoteID() {
+ const now = new Date().toISOString();
+ return now.replace(/[^0-9]/g,"").slice(0,16);
+}
+
+async function newNote(req, res) {
+ let noteID, noteFile;
+
+ do {
+ noteID = genNoteID();
+ noteFile = `${NOTE_DIR}/${req.uid}/${noteID}.md`;
+ } while (await exists(noteFile)) // TODO increment
+
+ console.log(Date.now()+` Creating note ${req.uid}:${noteID}`);
+
+ await wf(noteFile, "");
+
+ sj(res, {id:noteID, content:""});
+}
+
+async function getNote(req, res, match) {
+ console.log(Date.now()+` Getting note ${req.uid}:${match.noteID}`);
+ const noteFile = `${NOTE_DIR}/${req.uid}/${match.noteID}.md`;
+ const content = await rf(noteFile, "UTF-8"); // TODO exists
+ sj(res, {id:match.noteID, content});
+}
+
+async function setNote(req, res, match, data) {
+ console.log(Date.now()+` Setting note ${req.uid}:${match.noteID}`);
+ if (match.noteID !== data.id) return err400(res);
+ const noteFile = `${NOTE_DIR}/${req.uid}/${match.noteID}.md`;
+ await wf(noteFile, data.content, "UTF-8");
+ sj(res, {});
+}
+
+async function listNotes(req, res) {
+ console.log(Date.now()+` Getting notes for ${req.uid}`);
+ const files = await rd(`${NOTE_DIR}/${req.uid}`);
+ const notes = files.map(fn => fn.slice(0,-3));
+ sj(res, notes);
+}
+
+// TODO list in order of recent updates w/ timestamps
+// TODO pagination?
+
+module.exports.attach = (app, {authed}) => {
+ app.get("/list", authed(listNotes));
+ app.post("/new", authed(newNote));
+ app.get("/(?<noteID>[0-9]{16})", authed(getNote));
+ app.jpost("/(?<noteID>[0-9]{16})", authed(setNote));
+};