From 30bab3e651c3b8e7e3a46a5a4d6ba7ecbad211da Mon Sep 17 00:00:00 2001 From: luxick Date: Sat, 12 Jan 2019 14:49:39 +0100 Subject: [PATCH] Add Seasons. --- app.py | 48 +++++++++++++++++++++--- db.py | 36 +++++++++++++++--- model.py => models.py | 46 ++++++++++++++++++++--- templates/editseason.html | 79 +++++++++++++++++++++++++++++++++++++++ templates/seasons.html | 45 +++++++++++++++++++++- 5 files changed, 237 insertions(+), 17 deletions(-) rename model.py => models.py (52%) create mode 100644 templates/editseason.html diff --git a/app.py b/app.py index 11e8111..c250e5d 100644 --- a/app.py +++ b/app.py @@ -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/') +@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') diff --git a/db.py b/db.py index d8c043b..4ac5ab0 100644 --- a/db.py +++ b/db.py @@ -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 diff --git a/model.py b/models.py similarity index 52% rename from model.py rename to models.py index b013d5c..4698563 100644 --- a/model.py +++ b/models.py @@ -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 diff --git a/templates/editseason.html b/templates/editseason.html new file mode 100644 index 0000000..270fe70 --- /dev/null +++ b/templates/editseason.html @@ -0,0 +1,79 @@ +{% extends "base.html" %} +{% set active_page = "seasons" %} +{% block title %}Seasons{% endblock %} + + +{% block content %} +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+ + +{% endblock %} \ No newline at end of file diff --git a/templates/seasons.html b/templates/seasons.html index d732eaf..ee09bb7 100644 --- a/templates/seasons.html +++ b/templates/seasons.html @@ -3,5 +3,48 @@ {% block title %}Seasons{% endblock %} {% block content %} -There are no seasons. + {% if g.is_editor %} + + {% endif %} +{% if not model.seasons %} + There are no seasons. + {% else %} + + + + {% for prop, caption in model.columns %} + + {% endfor %} + + + + {% if g.is_editor %} + + {% endif %} + + + + {% for item in model.seasons %} + + {% for prop, caption in model.columns %} + + {% endfor %} + + + + {% if g.is_editor %} + + {% endif %} + + {% endfor %} + +
{{ caption }}Editor
{{ item[prop] }} + Show + + Edit +
+ + {% endif %} {% endblock %} \ No newline at end of file