PageBurger
-A simple note-taking app!
+A simple note-taking service!
Open in your browser -
+ Download for iOS + + + +
+
diff --git a/README.md b/README.md index 3232683..ed84e69 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,11 @@ ## PageBurger PageBurger is a simple note-taking app with end-to-end encryption. -PageBurger is a community fork of the discontinued [BurgerNotes](https://codeberg.org/burger-software/burgernotes). Most of the credits go to BurgerSoftware. +PageBurger is a community fork of the discontinued [burgernotes](https://codeberg.org/burger-software/burgernotes). Most of the credits go to burger software. -### links +### Links [Go to the PageBurger website](https://notes.hectabit.org) [API documentation](APIDOCS.md) + +[Roadmap](ROADMAP.md) \ No newline at end of file diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 0000000..b5808e9 --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,6 @@ +# Pageburger Roadmap + +- Switch to WebSockets for updating notes + live updating of note list and more, this involves redoing some APIs +- Compress notes to reduce bandwidth and storage +- Dedicated domain (not just a subdomain, if anyone can donate a domain let Arzumify know!) +- Native Apps (native iOS and Linux apps are in development) \ No newline at end of file diff --git a/main b/main index adcd807..dd04035 100644 --- a/main +++ b/main @@ -4,9 +4,11 @@ import sqlite3 import time import secrets import configparser -from waitress import serve +import asyncio +from hypercorn.config import Config +from hypercorn.asyncio import serve from werkzeug.security import generate_password_hash, check_password_hash -from flask import Flask, render_template, request, url_for, flash, redirect, session, make_response, send_from_directory, stream_with_context, Response, request +from quart import Quart, render_template, request, url_for, flash, redirect, session, make_response, send_from_directory, stream_with_context, Response, request # Parse configuration file, and check if anything is wrong with it config = configparser.ConfigParser() @@ -20,8 +22,8 @@ MAX_STORAGE = config["config"]["MAX_STORAGE"] if SECRET_KEY == "placeholder": print("[WARNING] Secret key not set") -# Define Flask -app = Flask(__name__) +# Define Quart +app = Quart(__name__) app.config["SECRET_KEY"] = SECRET_KEY # Database functions @@ -96,37 +98,37 @@ def check_username_taken(username): # Main page @app.route("/") -def main(): - return render_template("main.html") +async def main(): + return await render_template("main.html") # Web app @app.route("/app") -def webapp(): - return render_template("app.html") +async def webapp(): + return await render_template("app.html") # Login and signup @app.route("/signup") -def signup(): - return render_template("signup.html") +async def signup(): + return await render_template("signup.html") @app.route("/login") -def login(): - return render_template("login.html") +async def login(): + return await render_template("login.html") # Privacy policy @app.route("/privacy") -def privacy(): - return render_template("privacy.html") +async def privacy(): + return await render_template("privacy.html") # API @app.route("/api/version", methods=("GET", "POST")) -def apiversion(): +async def apiversion(): return "PageBurger Version 1.1" @app.route("/api/signup", methods=("GET", "POST")) -def apisignup(): +async def apisignup(): if request.method == "POST": - data = request.get_json() + data = await request.get_json() username = data["username"] password = data["password"] @@ -172,9 +174,9 @@ def apisignup(): }, 200 @app.route("/api/login", methods=("GET", "POST")) -def apilogin(): +async def apilogin(): if request.method == "POST": - data = request.get_json() + data = await request.get_json() username = data["username"] password = data["password"] @@ -227,9 +229,9 @@ def apilogin(): conn.close() @app.route("/api/userinfo", methods=("GET", "POST")) -def apiuserinfo(): +async def apiuserinfo(): if request.method == "POST": - data = request.get_json() + data = await request.get_json() secretKey = data["secretKey"] userCookie = get_session(secretKey) @@ -245,9 +247,9 @@ def apiuserinfo(): return datatemplate @app.route("/api/listnotes", methods=("GET", "POST")) -def apilistnotes(): +async def apilistnotes(): if request.method == "POST": - data = request.get_json() + data = await request.get_json() secretKey = data["secretKey"] userCookie = get_session(secretKey) @@ -269,9 +271,9 @@ def apilistnotes(): return datatemplate, 200 @app.route("/api/exportnotes", methods=("GET", "POST")) -def apiexportnotes(): +async def apiexportnotes(): if request.method == "POST": - data = request.get_json() + data = await request.get_json() secretKey = data["secretKey"] userCookie = get_session(secretKey) @@ -296,9 +298,9 @@ def apiexportnotes(): return datatemplate, 200 @app.route("/api/newnote", methods=("GET", "POST")) -def apinewnote(): +async def apinewnote(): if request.method == "POST": - data = request.get_json() + data = await request.get_json() secretKey = data["secretKey"] noteName = data["noteName"] @@ -314,9 +316,9 @@ def apinewnote(): return {}, 200 @app.route("/api/readnote", methods=("GET", "POST")) -def apireadnote(): +async def apireadnote(): if request.method == "POST": - data = request.get_json() + data = await request.get_json() secretKey = data["secretKey"] noteId = data["noteId"] @@ -338,9 +340,9 @@ def apireadnote(): return {}, 422 @app.route("/api/editnote", methods=("GET", "POST")) -def apieditnote(): +async def apieditnote(): if request.method == "POST": - data = request.get_json() + data = await request.get_json() secretKey = data["secretKey"] noteId = data["noteId"] content = data["content"] @@ -367,9 +369,9 @@ def apieditnote(): return {}, 422 @app.route("/api/removenote", methods=("GET", "POST")) -def apiremovenote(): +async def apiremovenote(): if request.method == "POST": - data = request.get_json() + data = await request.get_json() secretKey = data["secretKey"] noteId = data["noteId"] @@ -393,9 +395,9 @@ def apiremovenote(): @app.route("/api/deleteaccount", methods=("GET", "POST")) -def apideleteaccount(): +async def apideleteaccount(): if request.method == "POST": - data = request.get_json() + data = await request.get_json() secretKey = data["secretKey"] userCookie = get_session(secretKey) @@ -414,9 +416,9 @@ def apideleteaccount(): return {}, 200 @app.route("/api/sessions/list", methods=("GET", "POST")) -def apisessionslist(): +async def apisessionslist(): if request.method == "POST": - data = request.get_json() + data = await request.get_json() secretKey = data["secretKey"] userCookie = get_session(secretKey) @@ -443,9 +445,9 @@ def apisessionslist(): return datatemplate, 200 @app.route("/api/sessions/remove", methods=("GET", "POST")) -def apisessionsremove(): +async def apisessionsremove(): if request.method == "POST": - data = request.get_json() + data = await request.get_json() secretKey = data["secretKey"] sessionId = data["sessionId"] @@ -483,19 +485,22 @@ def listusers(secretkey): return redirect("/") @app.route("/api/logout") -def apilogout(): - return render_template("logout.html") +async def apilogout(): + return await render_template("logout.html") @app.errorhandler(500) -def burger(e): +async def burger(e): return {}, 500 @app.errorhandler(404) -def burger(e): - return render_template("error.html", errorCode=404, errorMessage="Page not found"), 404 +async def burger(e): + return await render_template("error.html", errorCode=404, errorMessage="Page not found"), 404 # Start server +hypercornconfig = Config() +hypercornconfig.bind = (HOST + ":" + PORT) + if __name__ == "__main__": print("[INFO] Server started") - serve(app, host=HOST, port=PORT) + asyncio.run(serve(app, hypercornconfig)) print("[INFO] Server stopped") diff --git a/requirements.txt b/requirements.txt index 2194384..afcaa89 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -flask -waitress +quart +hypercorn werkzeug \ No newline at end of file diff --git a/static/css/style.css b/static/css/style.css index 53be75f..e591e68 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -83,6 +83,21 @@ color: white; background-color: #202124; } + + .flathubLogo { + filter: invert(100%) + } + + .feature { + background-color: rgba(0, 0, 0, 0) !important; + color: var(--text-color) + } + .mainDiv .yellow { + border-color: #e9e98d !important; + } + .mainDiv .green { + border-color: #a9f9a9 !important; + } } p, @@ -638,13 +653,6 @@ body { background-color: #ffffeb; } -.mainDiv img { - position: fixed; - right: 7vh; - top: 8vh; - border-radius: 8px; -} - .links { text-align: center; padding: 10px; diff --git a/static/svg/flathubdark.svg b/static/svg/flathubdark.svg new file mode 100644 index 0000000..1db1173 --- /dev/null +++ b/static/svg/flathubdark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/svg/flathublight.svg b/static/svg/flathublight.svg new file mode 100644 index 0000000..060a2db --- /dev/null +++ b/static/svg/flathublight.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/main.html b/templates/main.html index d4b5417..f410802 100644 --- a/templates/main.html +++ b/templates/main.html @@ -15,13 +15,17 @@
A simple note-taking app!
+A simple note-taking service!