Yeet useless tables

Yeet useless data paths in dockerfile
Add order into templates file
This commit is contained in:
Michał Gdula 2023-06-22 13:19:00 +00:00
parent b19dedc568
commit 300c80fcd5
17 changed files with 86 additions and 106 deletions

View file

@ -2,7 +2,6 @@
FROM alpine:latest FROM alpine:latest
EXPOSE 8000 EXPOSE 8000
# RUN apt update && apt install -y python3 python3-pip postgresql-client
RUN apk update && apk add python3 py3-pip postgresql-client RUN apk update && apk add python3 py3-pip postgresql-client
WORKDIR /data WORKDIR /data

View file

@ -4,17 +4,16 @@ from flask import Flask, render_template, abort
from flask_assets import Bundle from flask_assets import Bundle
from werkzeug.exceptions import HTTPException from werkzeug.exceptions import HTTPException
from .config import MIGRATION_DIR, INSTANCE_DIR
from .extensions import db, migrate, cache, assets, login_manager from .extensions import db, migrate, cache, assets, login_manager
from .models import Users from .models import Users
from . import views, auth, api, filters from . import views, auth, api, filters
app = Flask(__name__, instance_path=INSTANCE_DIR) app = Flask(__name__)
app.config.from_pyfile("config.py") app.config.from_pyfile("config.py")
db.init_app(app) db.init_app(app)
migrate.init_app(app, db, directory=MIGRATION_DIR) migrate.init_app(app, db)
with app.app_context(): with app.app_context():
db.create_all() db.create_all()

View file

@ -59,7 +59,6 @@ def post():
if int(difficulty) not in GAME_DIFFICULTIES: if int(difficulty) not in GAME_DIFFICULTIES:
return "Invalid difficulty!" return "Invalid difficulty!"
session_data = Sessions.query.filter_by(auth_key=session_key).first() session_data = Sessions.query.filter_by(auth_key=session_key).first()
if not session_data: if not session_data:
return "Authentication failed!" return "Authentication failed!"

View file

@ -15,7 +15,7 @@ blueprint = Blueprint("auth", __name__)
@blueprint.route("/auth", methods=["GET"]) @blueprint.route("/auth", methods=["GET"])
def auth(): def auth():
return render_template("auth.html") return render_template("views/auth.html")
@blueprint.route("/register", methods=["POST"]) @blueprint.route("/register", methods=["POST"])
@ -59,10 +59,9 @@ def register():
@blueprint.route("/login", methods=["POST"]) @blueprint.route("/login", methods=["POST"])
def login(): def login():
# Get the form data # Get the form data
username = request.form["username"].strip() username = request.form.get("username", None).strip()
password = request.form["password"].strip() password = request.form.get("password", None).strip()
username_regex = re.compile(USER_REGEX) username_regex = re.compile(USER_REGEX)
error = [] error = []
# Validate the form # Validate the form

View file

@ -23,9 +23,6 @@ SQLALCHEMY_DATABASE_URI = f"postgresql+psycopg2://{user}:{password}@{host}:5432/
SQLALCHEMY_TRACK_MODIFICATIONS = False SQLALCHEMY_TRACK_MODIFICATIONS = False
SQLALCHEMY_POOL_RECYCLE = 621 SQLALCHEMY_POOL_RECYCLE = 621
MIGRATION_DIR = "/data/storage/migrations"
INSTANCE_DIR = "/data/storage/instance"
""" """
# SQLite # SQLite
SECRET_KEY = "dev" SECRET_KEY = "dev"

View file

@ -2,12 +2,12 @@ import datetime
from flask import Blueprint from flask import Blueprint
blueprint = Blueprint('filters', __name__, template_folder='templates') blueprint = Blueprint("filters", __name__, template_folder="templates")
@blueprint.app_template_filter() @blueprint.app_template_filter()
def format_result(dttm): def format_result(dttm):
dttm = str(dttm).split('.') dttm = str(dttm).split(".")
time = datetime.timedelta(seconds=int(dttm[0])) time = datetime.timedelta(seconds=int(dttm[0]))
microtime = dttm[1][:3] microtime = dttm[1][:3]
return f'{time}:{microtime}' return f"{time}:{microtime}"

View file

@ -9,9 +9,6 @@ from .config import GAME_VERSION
class Scores(db.Model): class Scores(db.Model):
""" """
Post table Post table
Scores supports anonymous posting, and instead just wants to post a score,
then the username must be provided. Otherwise, it's grabbed from the user
table
""" """
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
@ -75,25 +72,6 @@ class PasswordReset(db.Model):
) )
class Permissions(db.Model):
"""
Permissions table
"""
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey("users.id", use_alter=True))
user_ban = db.Column(db.Boolean, default=False)
user_warn = db.Column(db.Boolean, default=False)
score_removal = db.Column(db.Boolean, default=False)
score_edit = db.Column(db.Boolean, default=False)
admin_panel = db.Column(db.Boolean, default=False)
admin_promote = db.Column(db.Boolean, default=False)
admin_demote = db.Column(db.Boolean, default=False)
class ProfileTags(db.Model): class ProfileTags(db.Model):
""" """
Profile Tags table Profile Tags table
@ -112,6 +90,9 @@ class Users(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
alt_id = db.Column(db.String, nullable=False, unique=True) alt_id = db.Column(db.String, nullable=False, unique=True)
superuser = db.Column(db.Boolean, default=False)
picture = db.Column(db.String)
username = db.Column(db.String(32), unique=True, nullable=False) username = db.Column(db.String(32), unique=True, nullable=False)
email = db.Column(db.String) email = db.Column(db.String)

View file

@ -1,43 +0,0 @@
{% extends "base.html" %}
{% block content %}
<div class="block">
<h2>Login</h2>
<p>Welcome back!</p>
<form action="{{ url_for('auth.login') }}" method="POST">
<span class="text-input">
<label for="login-username">Username</label>
<input type="text" name="username" id="login-username" required>
</span>
<span class="text-input">
<label for="login-password">Password</label>
<input type="password" name="password" id="login-password" required>
</span>
<button type="submit" class="button primary">Login</button>
</form>
</div>
<div class="block">
<h2>Register</h2>
<p>Don't have an account?</p>
<form action="{{ url_for('auth.register') }}" method="POST">
<span class="text-input">
<label for="register-username">Username</label>
<input type="text" name="username" id="register-username" required>
</span>
<span class="text-input">
<label for="register-password">Password</label>
<input type="password" name="password" id="register-password" minlength="8" required>
</span>
<span class="text-input">
<label for="register-confirm">Confirm</label>
<input type="password" name="confirm" id="register-confirm" minlength="8" required>
</span>
<button type="submit" class="button primary">Register</button>
</form>
</div>
{% endblock %}

View file

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<title>Front Rooms Highscores</title> <title>{% block title %}Front Rooms Highscores{% endblock %}</title>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
@ -16,10 +16,9 @@
{% assets "scripts" %}<script src="{{ ASSET_URL }}"></script>{% endassets %} {% assets "scripts" %}<script src="{{ ASSET_URL }}"></script>{% endassets %}
</head> </head>
<body> <body>
<div class="search-hint"> <div class="search-hint"><p>Start typing to see results...</p></div>
<p>Start typing to see results...</p>
</div>
<!-- Hopefully I can make this change seasonally/weekly/something-ly -->
<picture class="background"> <picture class="background">
<source srcset="{{ url_for('static', filename='images/background.webp') }}"> <source srcset="{{ url_for('static', filename='images/background.webp') }}">
<img src="{{ url_for('static', filename='images/background.png') }}" alt="The Front Rooms Level select render"> <img src="{{ url_for('static', filename='images/background.png') }}" alt="The Front Rooms Level select render">
@ -28,38 +27,30 @@
<div class="app"> <div class="app">
<!-- Get flashed lol --> <!-- Get flashed lol -->
<div class="flash"> <div class="flash">
<!-- My bad -->
{% with messages = get_flashed_messages(with_categories=true) %} {% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %} {% if messages %}
{% for category, message in messages %} {% for category, message in messages %}
<p class="{{ category }}" onclick="this.remove()"><span><i class="ph-bold ph-x"></i></span>{{ message }}</p> <p class="{{ category }}" onclick="this.remove()">
<span><i class="ph-bold ph-x"></i></span>
{{ message }}
</p>
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% endwith %} {% endwith %}
</div> </div>
<header> <header>
<!-- Overcomplicated header, probably should just use CSS for some of this stuff -->
<picture class="title"> <picture class="title">
<source srcset="{{ url_for('static', filename='images/title.webp') }}"> <source srcset="{{ url_for('static', filename='images/title.webp') }}">
<img src="{{ url_for('static', filename='images/title.png') }}" alt="The Front Rooms logo"> <img src="{{ url_for('static', filename='images/title.png') }}" alt="The Front Rooms logo">
</picture> </picture>
<nav> <!-- Import navigation bar -->
<a href="{{ url_for('views.index') }}" class="button">Scores</a> {% include 'navigation.html' %}
<a href="{{ url_for('views.about') }}" class="button">About</a>
<span class="spacer"></span> <!-- Second nav for page specific tools -->
{% if current_user.is_authenticated %}
<a href="{{ url_for('views.settings') }}" class="button primary">
{{ current_user.username }}
{% if not current_user.email %}<i class="ph ph-warning"></i>{% endif %}
</a>
{% else %}
<a href="{{ url_for('auth.auth') }}" class="button primary"><i class="ph ph-user-circle"></i></a>
{% endif %}
</nav>
<!-- Secondary nav bar for page specific content -->
{% block nav %}{% endblock %} {% block nav %}{% endblock %}
</header> </header>

View file

@ -0,0 +1,15 @@
{% macro text(id, name, type="text", required=False, minlength=0) %}
<span class="text-input">
<label for="{{ id }}">
{{ name|title }}
</label>
<input
type="{{ type }}"
name="{{ name }}"
id="{{ id }}"
{% if required %}required{% endif %}
minlength="{{ minlength }}"
>
</span>
{% endmacro %}

View file

@ -0,0 +1,15 @@
<nav>
<a href="{{ url_for('views.index') }}" class="button">Scores</a>
<a href="{{ url_for('views.about') }}" class="button">About</a>
<span class="spacer"></span>
{% if current_user.is_authenticated %}
<a href="{{ url_for('views.settings') }}" class="button primary">
{{ current_user.username }}
{% if not current_user.email %}<i class="ph ph-warning"></i>{% endif %}
</a>
{% else %}
<a href="{{ url_for('auth.auth') }}" class="button primary"><i class="ph ph-user-circle"></i></a>
{% endif %}
</nav>

View file

@ -0,0 +1,25 @@
{% extends "base.html" %}
{% from "macros/input.html" import text %}
{% block content %}
<div class="block">
<h2>Login</h2>
<p>Welcome back!</p>
<form action="{{ url_for('auth.login') }}" method="POST">
{{ text(id="login-username", name="username", required=True) }}
{{ text(id="login-password", name="password", type="password", required=True) }}
<button type="submit" class="button primary">Login</button>
</form>
</div>
<div class="block">
<h2>Register</h2>
<p>Don't have an account?</p>
<form action="{{ url_for('auth.register') }}" method="POST">
{{ text(id="register-username", name="username", required=True) }}
{{ text(id="register-password", name="password", type="password", required=True, minlength=8) }}
{{ text(id="register-confirm", name="confirm", type="password", required=True, minlength=8) }}
<button type="submit" class="button primary">Register</button>
</form>
</div>
{% endblock %}

View file

@ -27,13 +27,17 @@ def index():
scores = scores.order_by(Scores.score.asc()).limit(MAX_TOP_SCORES).all() scores = scores.order_by(Scores.score.asc()).limit(MAX_TOP_SCORES).all()
return render_template( return render_template(
"scores.html", scores=scores, diff=int(diff_arg), ver=ver_arg, user=user_arg "views/scores.html",
scores=scores,
diff=int(diff_arg),
ver=ver_arg,
user=user_arg
) )
@blueprint.route("/about") @blueprint.route("/about")
def about(): def about():
return render_template("about.html") return render_template("views/about.html")
@blueprint.route("/settings", methods=["GET"]) @blueprint.route("/settings", methods=["GET"])
@ -51,4 +55,4 @@ def settings():
flash("Insert password change function", "error") flash("Insert password change function", "error")
sessions = Sessions.query.filter_by(user_id=current_user.id).all() sessions = Sessions.query.filter_by(user_id=current_user.id).all()
return render_template("settings.html", sessions=sessions) return render_template("views/settings.html", sessions=sessions)

View file

@ -36,8 +36,7 @@ services:
build: TFR build: TFR
restart: unless-stopped restart: unless-stopped
volumes: volumes:
- ./TFR/storage:/data/storage - ./TFR/storage/migrations:/data/migrations
- ./TFR/logs:/data/logs
environment: environment:
FLASK_KEY: ${THE_FRONT_ROOMS_SECRETE_KEY} FLASK_KEY: ${THE_FRONT_ROOMS_SECRETE_KEY}
DB_USER: ${POSTGRES_USER} DB_USER: ${POSTGRES_USER}