mirror of
https://github.com/Fluffy-Bean/GameExpo23.git
synced 2025-05-18 09:24:52 +00:00
Yeet useless tables
Yeet useless data paths in dockerfile Add order into templates file
This commit is contained in:
parent
b19dedc568
commit
300c80fcd5
17 changed files with 86 additions and 106 deletions
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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!"
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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}"
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 %}
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
15
TFR/server/templates/macros/input.html
Normal file
15
TFR/server/templates/macros/input.html
Normal 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 %}
|
15
TFR/server/templates/navigation.html
Normal file
15
TFR/server/templates/navigation.html
Normal 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>
|
25
TFR/server/templates/views/auth.html
Normal file
25
TFR/server/templates/views/auth.html
Normal 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 %}
|
|
@ -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)
|
||||||
|
|
|
@ -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}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue