mirror of
https://github.com/Fluffy-Bean/GameExpo23.git
synced 2025-05-28 13:53:12 +00:00
Add base template and unuasble style
This commit is contained in:
parent
8bf194f936
commit
0af071992b
10 changed files with 94 additions and 53 deletions
20
Highscore-Server/server/config.py
Normal file
20
Highscore-Server/server/config.py
Normal file
|
@ -0,0 +1,20 @@
|
|||
import os
|
||||
|
||||
# Purely to make the code a bit more readable
|
||||
def env(key):
|
||||
return os.getenv(key)
|
||||
|
||||
SECRET_KEY = env('FLASK_KEY')
|
||||
BEARER_TOKEN = env('BEARER_TOKEN')
|
||||
|
||||
user = env('DB_USER')
|
||||
password = env('DB_PASSWORD')
|
||||
host = env('DB_HOST')
|
||||
database = env('DB_NAME')
|
||||
|
||||
SQLALCHEMY_DATABASE_URI = f"postgresql+psycopg2://{user}:{password}@{host}:5432/{database}"
|
||||
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
||||
SQLALCHEMY_POOL_RECYCLE = 621
|
||||
|
||||
MIGRATION_DIR = '/data/storage/migrations'
|
||||
INSTANCE_DIR = '/data/storage/instance'
|
7
Highscore-Server/server/extensions.py
Normal file
7
Highscore-Server/server/extensions.py
Normal file
|
@ -0,0 +1,7 @@
|
|||
from flask_sqlalchemy import SQLAlchemy
|
||||
from flask_migrate import Migrate
|
||||
from flask_caching import Cache
|
||||
|
||||
db = SQLAlchemy()
|
||||
migrate = Migrate()
|
||||
cache = Cache(config={'CACHE_TYPE': 'simple'})
|
43
Highscore-Server/server/models.py
Normal file
43
Highscore-Server/server/models.py
Normal file
|
@ -0,0 +1,43 @@
|
|||
"""
|
||||
Database models for the server
|
||||
"""
|
||||
from extensions import db
|
||||
|
||||
|
||||
class Scores(db.Model):
|
||||
"""
|
||||
Post table
|
||||
"""
|
||||
__tablename__ = "scores"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
|
||||
score = db.Column(db.Integer, nullable=False)
|
||||
difficulty = db.Column(db.String, nullable=False)
|
||||
achievements = db.Column(db.String, nullable=False)
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
|
||||
|
||||
scored_at = db.Column(
|
||||
db.DateTime,
|
||||
nullable=False,
|
||||
server_default=db.func.now(),
|
||||
)
|
||||
|
||||
|
||||
class Users(db.Model):
|
||||
"""
|
||||
User table
|
||||
"""
|
||||
__tablename__ = "users"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
steam_uuid = db.Column(db.String, unique=True, nullable=False)
|
||||
steam_name = db.Column(db.String, nullable=False)
|
||||
|
||||
scores = db.relationship('Scores', backref='user', lazy=True)
|
||||
|
||||
creation_data = db.Column(
|
||||
db.DateTime,
|
||||
nullable=False,
|
||||
server_default=db.func.now(),
|
||||
)
|
29
Highscore-Server/server/run.sh
Normal file
29
Highscore-Server/server/run.sh
Normal file
|
@ -0,0 +1,29 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Wait for database to start
|
||||
until pg_isready -d $DB_NAME -h $DB_HOST -U $DB_USER
|
||||
do
|
||||
echo "Waiting for database to start... (5s)"
|
||||
sleep 5
|
||||
done
|
||||
|
||||
echo "Database is ready!"
|
||||
|
||||
# Check if migrastions folder exists
|
||||
if [ ! -d "/data/storage/migrations" ];
|
||||
then
|
||||
echo "Creating tables..."
|
||||
flask --app server db init
|
||||
fi
|
||||
|
||||
# Check if there are any changes to the database
|
||||
if $(flask --app server db check);
|
||||
then
|
||||
echo "Database changes detected! Migrating..."
|
||||
flask --app server db migrate
|
||||
flask --app server db upgrade
|
||||
fi
|
||||
|
||||
# Start server!!!!
|
||||
echo "Starting server..."
|
||||
gunicorn --bind highscore:8080 server:app
|
17
Highscore-Server/server/server.py
Normal file
17
Highscore-Server/server/server.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
import os
|
||||
from flask import Flask
|
||||
from extensions import db, migrate, cache
|
||||
from config import MIGRATION_DIR, INSTANCE_DIR
|
||||
from views import blueprint
|
||||
|
||||
app = Flask(__name__, instance_path=INSTANCE_DIR)
|
||||
app.config.from_pyfile('config.py')
|
||||
|
||||
db.init_app(app)
|
||||
migrate.init_app(app, db, directory=MIGRATION_DIR)
|
||||
cache.init_app(app)
|
||||
|
||||
with app.app_context():
|
||||
db.create_all()
|
||||
|
||||
app.register_blueprint(blueprint)
|
53
Highscore-Server/server/templates/base.html
Normal file
53
Highscore-Server/server/templates/base.html
Normal file
|
@ -0,0 +1,53 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Front Rooms Highscores</title>
|
||||
<style>
|
||||
@import url('https://fonts.cdnfonts.com/css/cmu-serif');
|
||||
|
||||
* {
|
||||
font-family: 'CMU Serif', serif;
|
||||
}
|
||||
|
||||
body, html {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.app {
|
||||
margin: auto;
|
||||
padding: 1rem;
|
||||
text-align: center;
|
||||
|
||||
min-width: 621px;
|
||||
|
||||
border: 3px solid yellow;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app">
|
||||
<h1>Front Rooms Highscores</h1>
|
||||
<p>Created by Bradley, Mia, Bartek & Michał</p>
|
||||
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="Easy">Easy</a></li>
|
||||
<li><a href="Normal">Normal</a></li>
|
||||
<li><a href="Hard">Hard</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
29
Highscore-Server/server/templates/scores.html
Normal file
29
Highscore-Server/server/templates/scores.html
Normal file
|
@ -0,0 +1,29 @@
|
|||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
{% if show_sub %}
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="Level1">Level 1</a></li>
|
||||
<li><a href="Level2">Level 2</a></li>
|
||||
<li><a href="Level3">Level 3</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
{% endif %}
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Score</th>
|
||||
<th>Difficulty</th>
|
||||
<th>Achievements</th>
|
||||
<th>Player</th>
|
||||
</tr>
|
||||
{% for score in top_scores %}
|
||||
<tr>
|
||||
<td>{{ score.score }}</td>
|
||||
<td>{{ score.difficulty }}</td>
|
||||
<td>{{ score.achievements }}</td>
|
||||
<td>{{ score.user.steam_name }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endblock %}
|
62
Highscore-Server/server/views.py
Normal file
62
Highscore-Server/server/views.py
Normal file
|
@ -0,0 +1,62 @@
|
|||
from flask import Blueprint, jsonify, request, render_template
|
||||
from flask_wtf import FlaskForm
|
||||
from wtforms import StringField, IntegerField
|
||||
from wtforms.validators import DataRequired
|
||||
|
||||
from models import Scores, Users
|
||||
from extensions import db, cache
|
||||
from config import BEARER_TOKEN
|
||||
|
||||
|
||||
blueprint = Blueprint('views', __name__)
|
||||
|
||||
|
||||
class ScoreForm(FlaskForm):
|
||||
playerName = StringField('Player Name', validators=[DataRequired()])
|
||||
playerId = StringField('Player ID', validators=[DataRequired()])
|
||||
score = IntegerField('Score', validators=[DataRequired()])
|
||||
difficulty = StringField('Difficulty', validators=[DataRequired()])
|
||||
achievements = StringField('Achievements', validators=[DataRequired()])
|
||||
|
||||
|
||||
@blueprint.route('/', methods=['GET'])
|
||||
@cache.cached(timeout=60)
|
||||
def index():
|
||||
top_scores = Scores.query.order_by(Scores.score.desc()).limit(10).all()
|
||||
return render_template('scores.html', top_scores=top_scores, show_sub=True)
|
||||
|
||||
|
||||
@blueprint.route('/post', methods=['POST'])
|
||||
def post():
|
||||
form = ScoreForm()
|
||||
|
||||
if not form:
|
||||
return "Invalid form", 400
|
||||
if request.headers.get('Authentication') != 'Bearer ' + BEARER_TOKEN:
|
||||
return "Invalid authentication", 401
|
||||
|
||||
if not isinstance(form.score.data, int):
|
||||
return "Score must be an integer", 400
|
||||
if form.score.data < 0:
|
||||
return "Score must be greater than 0", 400
|
||||
if form.difficulty.data not in ['easy', 'medium', 'hard']:
|
||||
return "Invalid difficulty", 400
|
||||
|
||||
user = Users.query.filter_by(steam_uuid=form.playerId.data).first()
|
||||
if not user:
|
||||
user = Users(
|
||||
steam_uuid=form.playerId.data,
|
||||
steam_name=form.playerName.data,
|
||||
)
|
||||
db.session.add(user)
|
||||
db.session.commit()
|
||||
|
||||
score = Scores(
|
||||
score=form.score.data,
|
||||
difficulty=form.difficulty.data,
|
||||
achievements=form.achievements.data,
|
||||
user_id=user.id,
|
||||
)
|
||||
db.session.add(score)
|
||||
db.session.commit()
|
||||
return jsonify({'message': 'Success!'})
|
Loading…
Add table
Add a link
Reference in a new issue