Merge branch 'main' of ssh://hectabit.org/HectaBit/PageBurger

This commit is contained in:
Tracker-Friendly 2024-02-25 17:06:09 +00:00
commit 7f665f57a9
8 changed files with 86 additions and 59 deletions

View File

@ -1,9 +1,11 @@
## PageBurger ## PageBurger
PageBurger is a simple note-taking app with end-to-end encryption. 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) [Go to the PageBurger website](https://notes.hectabit.org)
[API documentation](APIDOCS.md) [API documentation](APIDOCS.md)
[Roadmap](ROADMAP.md)

6
ROADMAP.md Normal file
View File

@ -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)

95
main
View File

@ -4,9 +4,11 @@ import sqlite3
import time import time
import secrets import secrets
import configparser 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 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 # Parse configuration file, and check if anything is wrong with it
config = configparser.ConfigParser() config = configparser.ConfigParser()
@ -20,8 +22,8 @@ MAX_STORAGE = config["config"]["MAX_STORAGE"]
if SECRET_KEY == "placeholder": if SECRET_KEY == "placeholder":
print("[WARNING] Secret key not set") print("[WARNING] Secret key not set")
# Define Flask # Define Quart
app = Flask(__name__) app = Quart(__name__)
app.config["SECRET_KEY"] = SECRET_KEY app.config["SECRET_KEY"] = SECRET_KEY
# Database functions # Database functions
@ -96,37 +98,37 @@ def check_username_taken(username):
# Main page # Main page
@app.route("/") @app.route("/")
def main(): async def main():
return render_template("main.html") return await render_template("main.html")
# Web app # Web app
@app.route("/app") @app.route("/app")
def webapp(): async def webapp():
return render_template("app.html") return await render_template("app.html")
# Login and signup # Login and signup
@app.route("/signup") @app.route("/signup")
def signup(): async def signup():
return render_template("signup.html") return await render_template("signup.html")
@app.route("/login") @app.route("/login")
def login(): async def login():
return render_template("login.html") return await render_template("login.html")
# Privacy policy # Privacy policy
@app.route("/privacy") @app.route("/privacy")
def privacy(): async def privacy():
return render_template("privacy.html") return await render_template("privacy.html")
# API # API
@app.route("/api/version", methods=("GET", "POST")) @app.route("/api/version", methods=("GET", "POST"))
def apiversion(): async def apiversion():
return "PageBurger Version 1.1" return "PageBurger Version 1.1"
@app.route("/api/signup", methods=("GET", "POST")) @app.route("/api/signup", methods=("GET", "POST"))
def apisignup(): async def apisignup():
if request.method == "POST": if request.method == "POST":
data = request.get_json() data = await request.get_json()
username = data["username"] username = data["username"]
password = data["password"] password = data["password"]
@ -172,9 +174,9 @@ def apisignup():
}, 200 }, 200
@app.route("/api/login", methods=("GET", "POST")) @app.route("/api/login", methods=("GET", "POST"))
def apilogin(): async def apilogin():
if request.method == "POST": if request.method == "POST":
data = request.get_json() data = await request.get_json()
username = data["username"] username = data["username"]
password = data["password"] password = data["password"]
@ -227,9 +229,9 @@ def apilogin():
conn.close() conn.close()
@app.route("/api/userinfo", methods=("GET", "POST")) @app.route("/api/userinfo", methods=("GET", "POST"))
def apiuserinfo(): async def apiuserinfo():
if request.method == "POST": if request.method == "POST":
data = request.get_json() data = await request.get_json()
secretKey = data["secretKey"] secretKey = data["secretKey"]
userCookie = get_session(secretKey) userCookie = get_session(secretKey)
@ -245,9 +247,9 @@ def apiuserinfo():
return datatemplate return datatemplate
@app.route("/api/listnotes", methods=("GET", "POST")) @app.route("/api/listnotes", methods=("GET", "POST"))
def apilistnotes(): async def apilistnotes():
if request.method == "POST": if request.method == "POST":
data = request.get_json() data = await request.get_json()
secretKey = data["secretKey"] secretKey = data["secretKey"]
userCookie = get_session(secretKey) userCookie = get_session(secretKey)
@ -269,9 +271,9 @@ def apilistnotes():
return datatemplate, 200 return datatemplate, 200
@app.route("/api/exportnotes", methods=("GET", "POST")) @app.route("/api/exportnotes", methods=("GET", "POST"))
def apiexportnotes(): async def apiexportnotes():
if request.method == "POST": if request.method == "POST":
data = request.get_json() data = await request.get_json()
secretKey = data["secretKey"] secretKey = data["secretKey"]
userCookie = get_session(secretKey) userCookie = get_session(secretKey)
@ -296,9 +298,9 @@ def apiexportnotes():
return datatemplate, 200 return datatemplate, 200
@app.route("/api/newnote", methods=("GET", "POST")) @app.route("/api/newnote", methods=("GET", "POST"))
def apinewnote(): async def apinewnote():
if request.method == "POST": if request.method == "POST":
data = request.get_json() data = await request.get_json()
secretKey = data["secretKey"] secretKey = data["secretKey"]
noteName = data["noteName"] noteName = data["noteName"]
@ -314,9 +316,9 @@ def apinewnote():
return {}, 200 return {}, 200
@app.route("/api/readnote", methods=("GET", "POST")) @app.route("/api/readnote", methods=("GET", "POST"))
def apireadnote(): async def apireadnote():
if request.method == "POST": if request.method == "POST":
data = request.get_json() data = await request.get_json()
secretKey = data["secretKey"] secretKey = data["secretKey"]
noteId = data["noteId"] noteId = data["noteId"]
@ -338,9 +340,9 @@ def apireadnote():
return {}, 422 return {}, 422
@app.route("/api/editnote", methods=("GET", "POST")) @app.route("/api/editnote", methods=("GET", "POST"))
def apieditnote(): async def apieditnote():
if request.method == "POST": if request.method == "POST":
data = request.get_json() data = await request.get_json()
secretKey = data["secretKey"] secretKey = data["secretKey"]
noteId = data["noteId"] noteId = data["noteId"]
content = data["content"] content = data["content"]
@ -367,9 +369,9 @@ def apieditnote():
return {}, 422 return {}, 422
@app.route("/api/removenote", methods=("GET", "POST")) @app.route("/api/removenote", methods=("GET", "POST"))
def apiremovenote(): async def apiremovenote():
if request.method == "POST": if request.method == "POST":
data = request.get_json() data = await request.get_json()
secretKey = data["secretKey"] secretKey = data["secretKey"]
noteId = data["noteId"] noteId = data["noteId"]
@ -393,9 +395,9 @@ def apiremovenote():
@app.route("/api/deleteaccount", methods=("GET", "POST")) @app.route("/api/deleteaccount", methods=("GET", "POST"))
def apideleteaccount(): async def apideleteaccount():
if request.method == "POST": if request.method == "POST":
data = request.get_json() data = await request.get_json()
secretKey = data["secretKey"] secretKey = data["secretKey"]
userCookie = get_session(secretKey) userCookie = get_session(secretKey)
@ -414,9 +416,9 @@ def apideleteaccount():
return {}, 200 return {}, 200
@app.route("/api/sessions/list", methods=("GET", "POST")) @app.route("/api/sessions/list", methods=("GET", "POST"))
def apisessionslist(): async def apisessionslist():
if request.method == "POST": if request.method == "POST":
data = request.get_json() data = await request.get_json()
secretKey = data["secretKey"] secretKey = data["secretKey"]
userCookie = get_session(secretKey) userCookie = get_session(secretKey)
@ -443,9 +445,9 @@ def apisessionslist():
return datatemplate, 200 return datatemplate, 200
@app.route("/api/sessions/remove", methods=("GET", "POST")) @app.route("/api/sessions/remove", methods=("GET", "POST"))
def apisessionsremove(): async def apisessionsremove():
if request.method == "POST": if request.method == "POST":
data = request.get_json() data = await request.get_json()
secretKey = data["secretKey"] secretKey = data["secretKey"]
sessionId = data["sessionId"] sessionId = data["sessionId"]
@ -483,19 +485,22 @@ def listusers(secretkey):
return redirect("/") return redirect("/")
@app.route("/api/logout") @app.route("/api/logout")
def apilogout(): async def apilogout():
return render_template("logout.html") return await render_template("logout.html")
@app.errorhandler(500) @app.errorhandler(500)
def burger(e): async def burger(e):
return {}, 500 return {}, 500
@app.errorhandler(404) @app.errorhandler(404)
def burger(e): async def burger(e):
return render_template("error.html", errorCode=404, errorMessage="Page not found"), 404 return await render_template("error.html", errorCode=404, errorMessage="Page not found"), 404
# Start server # Start server
hypercornconfig = Config()
hypercornconfig.bind = (HOST + ":" + PORT)
if __name__ == "__main__": if __name__ == "__main__":
print("[INFO] Server started") print("[INFO] Server started")
serve(app, host=HOST, port=PORT) asyncio.run(serve(app, hypercornconfig))
print("[INFO] Server stopped") print("[INFO] Server stopped")

View File

@ -1,3 +1,3 @@
flask quart
waitress hypercorn
werkzeug werkzeug

View File

@ -83,6 +83,21 @@
color: white; color: white;
background-color: #202124; 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, p,
@ -638,13 +653,6 @@ body {
background-color: #ffffeb; background-color: #ffffeb;
} }
.mainDiv img {
position: fixed;
right: 7vh;
top: 8vh;
border-radius: 8px;
}
.links { .links {
text-align: center; text-align: center;
padding: 10px; padding: 10px;

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.1 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@ -15,13 +15,17 @@
<div class="mainDiv"> <div class="mainDiv">
<div class="startDiv"> <div class="startDiv">
<h1 class="w300">PageBurger</h1> <h1 class="w300">PageBurger</h1>
<p>A simple note-taking app!</p> <p>A simple note-taking service!</p>
<br> <br>
<a href="/app">Open in your browser</a> <a href="/app">Open in your browser</a>
<br>
<a href="/static/pageburger.mobileconfig" style="margin-top: 5px;">Download for iOS</a> <a href="/static/pageburger.mobileconfig" style="margin-top: 5px;">Download for iOS</a>
<a style="padding: 0; padding-bottom: 0; margin-top: 5px; background-color: rgba(0, 0, 0, 0);" href="https://flathub.org/apps/org.hectabit.PageBurger">
<img class="flathubLogo" style="height: 55px;"src="/static/svg/flathublight.svg">
</a>
</div> </div>
<br><br><br> <br>
<div class="feature green"> <div class="feature green">
<h7 class="w300">Secure</h7> <h7 class="w300">Secure</h7>
<p2>All your notes are fully end-to-end encrypted. Only you can read your notes, not anyone else.</p2> <p2>All your notes are fully end-to-end encrypted. Only you can read your notes, not anyone else.</p2>