From 28589f8a7b50ec31faa058f0f481661a7ef0b4ab Mon Sep 17 00:00:00 2001 From: trinkey <97406176+trinkey@users.noreply.github.com> Date: Mon, 26 Feb 2024 17:33:35 -0500 Subject: [PATCH] add browse and home pages --- README.md | 2 + _server.py | 115 +++++++++++++++++++++++++++++++++++++----- public/browse.html | 53 +++++++++++++++++++ public/css/browse.css | 20 ++++++++ public/css/home.css | 17 +++++++ public/editor.html | 2 +- public/home.html | 63 +++++++++++++++++++++++ public/index.html | 2 +- public/js/editor.js | 9 ++-- public/js/user.js | 1 + public/login.html | 4 +- public/logout.html | 2 +- public/signup.html | 4 +- public/user.html | 2 +- 14 files changed, 273 insertions(+), 23 deletions(-) create mode 100644 public/browse.html create mode 100644 public/css/browse.css create mode 100644 public/css/home.css create mode 100644 public/home.html diff --git a/README.md b/README.md index 947b02a..dce6839 100644 --- a/README.md +++ b/README.md @@ -6,3 +6,5 @@ it's like pronouns.page but i made it ### todo * social links * sexuality/gender flags +* browse people and allow public pages +* home page diff --git a/_server.py b/_server.py index 674868b..e8fccc1 100644 --- a/_server.py +++ b/_server.py @@ -4,6 +4,7 @@ SAVING_DIRECTORY = "./save/" UPGRADE_TO_HTTPS = False import hashlib +import random import shutil import flask import json @@ -14,6 +15,7 @@ from flask import request, redirect from werkzeug.middleware.proxy_fix import ProxyFix app = flask.Flask(__name__) +app.url_map.strict_slashes = False def validate_color(color: str) -> bool: if len(color) != 7 or color[0] != "#": @@ -64,16 +66,55 @@ def ensure_file(path: str, *, default_value: str="", folder: bool=False) -> None f.close() def escape_html(string: str) -> str: - return string.replace("&", "&").replace("<", "<").replace("\"", "&quo;") - -def create_file_serve(file) -> Callable: - x = lambda: flask.send_file(f"{CONTENT_DIRECTORY}{file}") - x.__name__ = file - return x + return string.replace("&", "&").replace("<", "<").replace("\"", """) def generate_token(username: str, passhash: str) -> str: return sha(sha(f"{username}:{passhash}") + "among us in real life, sus, sus") +def list_public( + sort: str="alphabetical", + page: int=0, + limit: int=25 +) -> dict: + # Sort: "alphabetical", "random" + # Page: for "alphabetical", page for next. 0 is first page, 1 is second... + + x = json.loads(open(f"{SAVING_DIRECTORY}public/list.json", "r").read()) + output = { + "end": True, + "list": [] + } + + if sort == "alphabetical": + x = x[limit * page::] + output["end"] = len(x) <= limit + for i in x[:limit:]: + q = json.loads(open(f"{SAVING_DIRECTORY}{i}.json", "r").read()) + output["list"].append({ + "colors": q["colors"], + "display_name": q["display_name"], + "bio": q["description"], + "username": i + }) + + elif sort == "random": + random.shuffle(x) + for i in x[:limit:]: + q = json.loads(open(f"{SAVING_DIRECTORY}{i}.json", "r").read()) + output["list"].append({ + "colors": q["colors"], + "display_name": q["display_name"], + "bio": q["description"], + "username": i + }) + + return output + +def create_file_serve(file) -> Callable: + x = lambda property=None: flask.send_file(f"{CONTENT_DIRECTORY}{file}") + x.__name__ = file + return x + def create_folder_serve(directory) -> Callable: x = lambda file: flask.send_from_directory(f"{CONTENT_DIRECTORY}{directory}", file) x.__name__ = directory @@ -138,7 +179,7 @@ def api_account_signup(): except KeyError: flask.abort(400) - if len(x["username"]) > 24 or len(x["username"]) < 1: + if len(x["username"]) > 24 or len(username) < 1: flask.abort(400) if len(passhash) != 64: @@ -240,8 +281,6 @@ def api_account_self(): flask.abort(404) def api_save(): - # TODO - ADD SORTING - username = open(f'{SAVING_DIRECTORY}tokens/{request.cookies["token"]}.txt', 'r').read() x = json.loads(request.data) @@ -253,6 +292,19 @@ def api_save(): if "description" in x and len(x["description"]) < 512: user_data["description"] = x["description"] + if "public" in x: + user_data["public"] = bool(x["public"]) + public_list = json.loads(open(f"{SAVING_DIRECTORY}public/list.json", "r").read()) + + if user_data["public"] and username not in public_list: + public_list.append(username) + elif not user_data["public"] and username in public_list: + public_list.remove(username) + + f = open(f"{SAVING_DIRECTORY}public/list.json", "w") + f.write(json.dumps(sorted(public_list))) + f.close() + if "colors" in x: if "accent" in x["colors"] and validate_color(x["colors"]["accent"]): user_data["colors"]["accent"] = x["colors"]["accent"] @@ -304,18 +356,54 @@ def api_save(): return "200 OK" -def u_(username): - return flask.send_file(f"{CONTENT_DIRECTORY}user.html") +def api_browse(): + return return_dynamic_content_type( + json.dumps(list_public(request.args.get("sort"), int(request.args.get("page")) if "page" in request.args else 0)), + "application/json" + ) + +def home(): + if "token" not in request.cookies: + return flask.send_file(f"{CONTENT_DIRECTORY}home.html") + + token = request.cookies['token'] + + if len(token) != 64: + return flask.send_file(f"{CONTENT_DIRECTORY}home.html") + + for i in token: + if i not in "abcdef0123456789": + return flask.send_file(f"{CONTENT_DIRECTORY}home.html") + + try: + username = open(f"{SAVING_DIRECTORY}tokens/{token}.txt", "r").read() + user_info = json.loads(open(f"{SAVING_DIRECTORY}{username}.json", "r").read()) + except FileNotFoundError: + return flask.send_file(f"{CONTENT_DIRECTORY}home.html") + + x = open(f"{CONTENT_DIRECTORY}home.html", "r").read() + x = x.replace("{{USERNAME}}", username) + x = x.replace("{{DISPL_NAME}}", user_info["display_name"]) + x = x.replace("{{PUBLIC}}", "true" if "public" in user_info and user_info["public"] else "false") + x = x.replace("{{TOTAL}}", str(len(json.loads(open(f"{SAVING_DIRECTORY}public/list.json", "r").read())))) + + return return_dynamic_content_type(x, "text/html") ensure_file(SAVING_DIRECTORY, folder=True) ensure_file(f"{SAVING_DIRECTORY}tokens/", folder=True) +ensure_file(f"{SAVING_DIRECTORY}public", folder=True) +ensure_file(f"{SAVING_DIRECTORY}public/list.json", default_value="[]") app.route("/")(create_file_serve("index.html")) app.route("/login")(create_file_serve("login.html")) app.route("/signup")(create_file_serve("signup.html")) app.route("/logout")(create_file_serve("logout.html")) +app.route("/browse")(create_file_serve("browse.html")) + app.route("/editor")(create_file_serve("editor.html")) -app.route("/u/")(u_) +app.route("/u/")(create_file_serve("user.html")) +app.route("/home")(home) + app.route("/js/")(create_folder_serve("js")) app.route("/css/")(create_folder_serve("css")) @@ -324,6 +412,9 @@ app.route("/api/account/signup", methods=["POST"])(api_account_signup) app.route("/api/account/info/", methods=["GET"])(api_account_info_) app.route("/api/account/self", methods=["GET"])(api_account_self) app.route("/api/save", methods=["PATCH"])(api_save) +app.route("/api/browse", methods=["GET"])(api_browse) + +app.errorhandler(404)(create_file_serve("404.html")) if UPGRADE_TO_HTTPS: app.wsgi_app = ProxyFix(app.wsgi_app) diff --git a/public/browse.html b/public/browse.html new file mode 100644 index 0000000..ae5e2af --- /dev/null +++ b/public/browse.html @@ -0,0 +1,53 @@ + + + + + Browse - InfoPage + + + + + + + + +

Browse

+ Return home

+ +
+ + + + + diff --git a/public/css/browse.css b/public/css/browse.css new file mode 100644 index 0000000..2a1ebea --- /dev/null +++ b/public/css/browse.css @@ -0,0 +1,20 @@ +.user-entry { + width: 30em; + margin: 10px auto; + border: 2px var(--accent) solid; + padding: 6px; + border-radius: 4px; + background-color: var(--background); + color: var(--text); + cursor: pointer; +} + +p { + font-size: 1.2em; +} + +@media screen and (max-width: 40em) { + .user-entry { + width: 80vw; + } +} diff --git a/public/css/home.css b/public/css/home.css new file mode 100644 index 0000000..758307e --- /dev/null +++ b/public/css/home.css @@ -0,0 +1,17 @@ +.home-container { + width: 20em; + padding: 10px 0; + margin: 0 auto; + border: 2px var(--secondary) solid; + padding: 6px; + border-radius: 4px; + background-color: var(--accent); +} + +.home-container[onclick] { + cursor: pointer; +} + +p { + font-size: 1.2em; +} diff --git a/public/editor.html b/public/editor.html index cd01aa9..90a45be 100644 --- a/public/editor.html +++ b/public/editor.html @@ -2,7 +2,7 @@ - Editor + Editor - InfoPage diff --git a/public/home.html b/public/home.html new file mode 100644 index 0000000..27f9327 --- /dev/null +++ b/public/home.html @@ -0,0 +1,63 @@ + + + + + Home - InfoPage + + + + + + + + + + +

Welcome, {{DISPL_NAME}}!

+
+

Edit your profile

+ {{DISPL_NAME}} (@{{USERNAME}})
+
+
+
+

Toggle visibility

+ Visibility: Public +
+
+
+

Browse other profiles

+ Total public profiles: {{TOTAL}} +
+
+
+

Preview your profile

+ Shortened url:
+ https://infopg.web.app/u/{{USERNAME}} +
+ + + + \ No newline at end of file diff --git a/public/index.html b/public/index.html index c1ddef7..5277191 100644 --- a/public/index.html +++ b/public/index.html @@ -11,7 +11,7 @@ diff --git a/public/js/editor.js b/public/js/editor.js index a669f97..5a40456 100644 --- a/public/js/editor.js +++ b/public/js/editor.js @@ -55,7 +55,7 @@ function add_input(key) { } function updateColors() { - document.body.setAttribute("style", `--background: ${colors.background}; --background-low-opacity: ${colors.background}33; --accent: ${colors.accent}; --accent-low-opacity: ${colors.accent}66; --text: ${colors.text}; --text-low-opacity: ${colors.text}88;`); + document.body.setAttribute("style", `--primary: ${colors.text}; --secondary-low-opacity: ${colors.text}22; --background: ${colors.background}; --background-low-opacity: ${colors.background}33; --accent: ${colors.accent}; --accent-low-opacity: ${colors.accent}66; --text: ${colors.text}; --text-low-opacity: ${colors.text}88;`); } function get_list(key) { @@ -87,7 +87,9 @@ fetch("/api/account/self", {
Text color:
Background color:
-
Accent color:

+
Accent color:
+
Public:

+
@@ -126,7 +128,8 @@ fetch("/api/account/self", { pronouns: get_list("pronouns"), honorifics: get_list("honorifics"), compliments: get_list("compliments"), - relationship: get_list("relationship") + relationship: get_list("relationship"), + public: dom("public").checked }) }).then((response) => (response.text())) .then((text) => { diff --git a/public/js/user.js b/public/js/user.js index c336803..435c292 100644 --- a/public/js/user.js +++ b/public/js/user.js @@ -39,5 +39,6 @@ fetch("/api/account/info/" + x2[x2.length - 1].toLowerCase(), { document.body.append(x); }) .catch((err) => { + document.title = "User not found - InfoPage" document.body.innerHTML = "

User not found!

Sign up - Log in"; }); diff --git a/public/login.html b/public/login.html index 3fe27d3..f23444f 100644 --- a/public/login.html +++ b/public/login.html @@ -2,7 +2,7 @@ - Log In + Log In - InfoPage @@ -11,7 +11,7 @@ diff --git a/public/logout.html b/public/logout.html index 7b74f5f..8f0fa3f 100644 --- a/public/logout.html +++ b/public/logout.html @@ -2,7 +2,7 @@ - Log In + Log out - InfoPage diff --git a/public/signup.html b/public/signup.html index 1d3630a..0d8947b 100644 --- a/public/signup.html +++ b/public/signup.html @@ -2,7 +2,7 @@ - Sign Up + Sign Up - InfoPage @@ -11,7 +11,7 @@ diff --git a/public/user.html b/public/user.html index 7c58f5b..68275af 100644 --- a/public/user.html +++ b/public/user.html @@ -2,7 +2,7 @@ - User not found! + Loading user...