Add Seasons.

This commit is contained in:
2019-01-12 14:49:39 +01:00
parent c090d65038
commit 30bab3e651
5 changed files with 237 additions and 17 deletions

48
app.py
View File

@@ -2,7 +2,7 @@ import functools
from flask import Flask, g, render_template, request, redirect, session
import db
import model
import models
app = Flask(__name__)
@@ -76,7 +76,45 @@ def landing():
@app.route('/seasons')
@authorize
def seasons():
return render_template('seasons.html')
sql, args = db.load_season()
results = db. query_db(sql, args, cls=models.Season)
model = {
'seasons': results,
'columns': [
('game', 'Game'),
('description', 'Season Description'),
('start', 'Started At'),
('end', 'Ended At')
]
}
return render_template('seasons.html', model=model)
@app.route('/newseason', methods=['GET'])
@authorize
def new_season():
return render_template('editseason.html', model={})
@app.route('/seasons/edit/<id>')
@authorize
def edit_season(id: int):
sql, args = db.load_season(id)
loaded = db.query_db(sql, args, one=True, cls=models.Season)
return render_template('editseason.html', model=loaded)
@app.route('/saveseason', methods=['POST'])
@authorize
def save_season():
try:
season = models.Season.from_form(request.form)
except AttributeError as err:
print(err)
return render_template('editseason.html', model={})
sql, args = db.save_season_query(season)
res = db.update_db(sql, args)
return redirect('/seasons')
@app.route('/newplayer', methods=['GET'])
@@ -87,9 +125,9 @@ def new_player():
@app.route('/saveplayer', methods=['POST'])
@authorize
def update_player():
def save_player():
data = request.form
player = model.Player(
player = models.Player(
id=data.get('id', None),
real_name=data['real_name'],
alias=data['alias'],
@@ -153,7 +191,7 @@ def new_drink():
@app.route('/savedrink', methods=['POST'])
@authorize
def save_drink():
drink = model.Drink.from_form(request.form)
drink = models.Drink.from_form(request.form)
res = db.save_drink(drink)
return redirect('/drinks')

36
db.py
View File

@@ -2,7 +2,7 @@ import sqlite3
import logging as log
from flask import g
import model
import models
DATABASE = 'es_debug.db'
@@ -18,12 +18,14 @@ def connect_db():
return db
def query_db(query, args=(), one=False):
"""Runs an SQL query on an new database connection, returning the fetched rows"""
def query_db(query, args=(), one=False, cls=None):
"""Runs an SQL query on an new database connection, returning the fetched rv"""
log.info(f'Running query ({query})\nwith arguments ({args})')
cur = connect_db().execute(query, args)
rv = cur.fetchall()
cur.close()
if cls:
rv = [cls(**row) for row in rv]
return (rv[0] if rv else None) if one else rv
@@ -79,7 +81,7 @@ def load_players(id=None):
args = (id, )
sql += ' order by player.id'
rows = query_db(sql, args)
players = [model.Player(**row) for row in rows]
players = [models.Player(**row) for row in rows]
return players
@@ -91,7 +93,7 @@ def load_drinks(id=None):
args = (id, )
sql += ' order by drink.id'
rows = query_db(sql, args)
drinks = [model.Drink(**row) for row in rows]
drinks = [models.Drink(**row) for row in rows]
return drinks
@@ -120,5 +122,27 @@ def load_enemies(id=None):
args = (id, )
sql += ' order by enemy.id'
rows = query_db(sql, args)
enemies = [model.Enemy(**row) for row in rows]
enemies = [models.Enemy(**row) for row in rows]
return enemies
def save_season_query(season):
if not season.id:
sql = 'insert into season values (?, ?, ?, ?, ?)'
args = (None, season.game, season.description, season.start, season.end)
else:
sql = 'update season ' \
'set game=?, description=?, start=?, end=? ' \
'where id==?'
args = (season.game, season.description, season.start, season.end, season.id)
return sql, args
def load_season(id=None):
sql = 'select * from season'
args = ()
if id:
sql += ' where season.id = ?'
args = (id, )
sql += ' order by season.start'
return sql, args

View File

@@ -1,4 +1,4 @@
from _ctypes import ArgumentError
import datetime
from dataclasses import dataclass
INVALID_STR = 'Form entry "{}" is invalid'
@@ -35,12 +35,12 @@ class Drink:
name = form.get('name', None)
if not name:
raise ArgumentError('Form data contains no field "name"')
raise AttributeError('Form data contains no field "name"')
name = str(name)
vol = form.get('vol', None)
if not vol:
raise ArgumentError('Form data contains no field "vol"')
raise AttributeError('Form data contains no field "vol"')
vol = float(vol)
self = cls(id=id, name=name, vol=vol)
@@ -60,13 +60,49 @@ class Enemy:
name = form.get('name', None)
if not name:
raise ArgumentError(INVALID_STR.format('name'))
raise AttributeError(INVALID_STR.format('name'))
name = str(name)
boss = form.get('boss', '')
if boss not in [True, False, 'True', 'False']:
raise ArgumentError(INVALID_STR.format('boss'))
raise AttributeError(INVALID_STR.format('boss'))
self = cls(id=id, name=name, boss=boss)
return self
@dataclass
class Season:
id: int
game: str
description: str
start: datetime.date
end: datetime.date
@classmethod
def from_form(cls, form):
id = form.get('id', None)
id = int(id) if id else None
game = form.get('game', None)
if not game:
raise AttributeError(INVALID_STR.format('game'))
game = str(game)
description = form.get('description', None)
start = form.get('start', None)
try:
start = datetime.date.fromisoformat(start)
except Exception:
raise AttributeError(INVALID_STR.format('start'))
end = form.get('end', None)
if end:
try:
end = datetime.date.fromisoformat(end)
except Exception:
raise INVALID_STR.format('end')
self = cls(id, game, description, start, end)
return self

79
templates/editseason.html Normal file
View File

@@ -0,0 +1,79 @@
{% extends "base.html" %}
{% set active_page = "seasons" %}
{% block title %}Seasons{% endblock %}
{% block content %}
<form class="needs-validation" novalidate action="/saveseason" method="post">
<div class="form-group">
<label for="id">ID</label>
<input name="id"
type="text"
class="form-control"
id="id"
value="{{ model['id'] }}"
readonly>
</div>
<div class="form-group">
<label for="game">Game Name</label>
<input name="game"
type="text"
class="form-control"
id="game"
placeholder="The game name..."
value="{{ model['game'] }}"
required>
</div>
<div class="form-group">
<label for="description">Season Description</label>
<input name="description"
type="text"
class="form-control"
id="description"
placeholder="The season description..."
value="{{ model['description'] }}"
required>
</div>
<div class="form-group">
<label for="start">Season Start</label>
<input name="start"
type="date"
class="form-control"
id="start"
placeholder="YYYY-MM-DD"
value="{{ model['start'] }}"
required>
</div>
<div class="form-group">
<label for="end">Season End</label>
<input name="end"
type="date"
class="form-control"
id="start"
placeholder="Season end date..."
value="{{ model['end'] }}">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<script>
// Example starter JavaScript for disabling form submissions if there are invalid fields
(function() {
'use strict';
window.addEventListener('load', function() {
// Fetch all the forms we want to apply custom Bootstrap validation styles to
let forms = document.getElementsByClassName('needs-validation');
// Loop over them and prevent submission
let validation = Array.prototype.filter.call(forms, function (form) {
form.addEventListener('submit', function (event) {
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
}, false);
});
}, false);
})();
</script>
{% endblock %}

View File

@@ -3,5 +3,48 @@
{% block title %}Seasons{% endblock %}
{% block content %}
There are no seasons.
{% if g.is_editor %}
<div class="btn-toolbar" role="toolbar">
<a class="btn btn-primary" href="/newseason" role="button">New Season</a>
</div>
{% endif %}
{% if not model.seasons %}
There are no seasons.
{% else %}
<table class="table table-hover table-striped table-bordered">
<thead>
<tr>
{% for prop, caption in model.columns %}
<th scope="col" class="col-sm-auto text-center">{{ caption }}</th>
{% endfor %}
<th scope="col" class="col-sm-auto text-center"></th>
{% if g.is_editor %}
<th scope="col" class="col-sm-auto text-center">Editor</th>
{% endif %}
</tr>
</thead>
<tbody>
{% for item in model.seasons %}
<tr>
{% for prop, caption in model.columns %}
<td class="col-sm-auto text-center">{{ item[prop] }}</td>
{% endfor %}
<td class="col-sm-auto text-center">
<a class="btn btn-dark" href="/seasons/{{ item.id }}">Show</a>
</td>
{% if g.is_editor %}
<td class="col-sm-auto text-center">
<a class="btn btn-dark" href="/seasons/edit/{{ item.id }}">Edit</a>
</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
{% endblock %}