From c3a1ce74af2149c1aaf33cdca991514876517729 Mon Sep 17 00:00:00 2001 From: Glitchy Date: Fri, 6 Jun 2025 14:20:05 +0000 Subject: [PATCH] stuff --- .gitignore | 3 +++ app.py | 48 ++++++++++++++++++++++++++++++++++++++++++++- static/note.js | 42 ++++++++++++++++++++++++++++++++++----- templates/note.html | 1 + 4 files changed, 88 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index fcbd933..e424e5d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,10 @@ users.txt +access.log .venv venv env .env notes log.log +__pycache__ +error.log diff --git a/app.py b/app.py index ea64334..aaadef8 100644 --- a/app.py +++ b/app.py @@ -108,7 +108,53 @@ def api(note): def serve_note(note): if not get_user(): return redirect(url_for("login")) - return render_template("note.html", note=note) + return render_template("note.html", note=note, username=get_user()) + +@app.route("/public/") +@app.route("/board") +def serve_note_nologin(username: str = ""): + return render_template("note.html", note=username, username=get_user()) + +@app.route("/publicapi/", methods=["GET", "POST"]) +def public_board(username): + user = get_user() + path = os.path.join(DATA_DIR, username.replace("/", "_"), "__public.txt") + + if request.method == "GET": + if not os.path.exists(path): + return "", 200 + with open(path, "r", encoding="utf-8") as f: + return f.read(), 200 + + if request.method == "POST": + if user != username: + return "Forbidden", 403 + data = request.get_json() + if not data or "content" not in data: + return "Bad request", 400 + os.makedirs(os.path.dirname(path), exist_ok=True) + with open(path, "w", encoding="utf-8") as f: + f.write(data["content"]) + return jsonify({"status": "saved"}) + +@app.route("/boardapi", methods=["GET", "POST"]) +def shared_board(): + path = os.path.join(DATA_DIR, "__shared_board.txt") + + if request.method == "GET": + if not os.path.exists(path): + return "", 200 + with open(path, "r", encoding="utf-8") as f: + return f.read(), 200 + + if request.method == "POST": + data = request.get_json() + if not data or "content" not in data: + return "Bad request", 400 + with open(path, "w", encoding="utf-8") as f: + f.write(data["content"]) + return jsonify({"status": "saved"}) + @app.route("/") def serve_root(): diff --git a/static/note.js b/static/note.js index 4546358..f2aa128 100644 --- a/static/note.js +++ b/static/note.js @@ -1,31 +1,63 @@ const textarea = document.getElementById("editor"); const status = document.getElementById("status"); const error = document.getElementById("error"); +const currentUser = document.getElementById("username").innerHTML; +const path = window.location.pathname; -fetch("/api/" + noteName) +// === ROUTE PARSING === +let mode = "private"; +let fetchUrl = ""; +let editable = true; +let last = ""; + +if (path.startsWith("/public/")) { + const username = path.split("/")[2]; + fetchUrl = "/publicapi/" + username; + editable = (currentUser === username); + mode = "public"; +} else if (path === "/board") { + fetchUrl = "/boardapi"; + mode = "shared"; + editable = true; +} else if (path.startsWith("/n/") || path.startsWith("/notes/")) { + const note = path.split("/").pop(); + fetchUrl = "/api/" + note; + editable = true; +} else { + error.textContent = "Unsupported path: " + path; + textarea.disabled = true; + throw new Error("Unknown path: " + path); +} + +if (!editable) textarea.disabled = true; + +// === FETCH INITIAL CONTENT === +fetch(fetchUrl) .then(res => { - if (!res.ok) throw new Error("Failed to load note. Status: " + res.status); + if (!res.ok) throw new Error("Failed to load. Status: " + res.status); return res.text(); }) .then(text => { textarea.value = text; + last = text; status.textContent = "Loaded"; }) .catch(err => { - error.textContent = "Error loading note: " + err.message; + error.textContent = "Error loading content: " + err.message; status.textContent = "Load failed"; }); +// === AUTOSAVE LOGIC === let timeout; -let last = ""; textarea.addEventListener("input", () => { + if (!editable) return; status.textContent = "Typing..."; clearTimeout(timeout); timeout = setTimeout(() => { const text = textarea.value; if (text !== last) { - fetch("/api/" + noteName, { + fetch(fetchUrl, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ content: text }) diff --git a/templates/note.html b/templates/note.html index 1420f8c..281e5c9 100644 --- a/templates/note.html +++ b/templates/note.html @@ -2,6 +2,7 @@ + {{ note }}