Rewrite data layer using SqlAlchemy Part 1

This commit is contained in:
2019-10-14 19:02:25 +02:00
parent f6a38cc2db
commit fccd75d6c5
51 changed files with 1297 additions and 658 deletions

View File

@@ -0,0 +1,72 @@
from flask import render_template, redirect
from estusshots import app
from estusshots import forms, models, orm
from estusshots.util import authorize
from estusshots.orm import Drink
@app.route("/drink")
@authorize
def drink_list():
db = orm.new_session()
drinks = db.query(Drink).order_by(Drink.name).all()
model = {
"drinks": drinks,
"columns": [("name", "Drink Name"), ("vol", "Alcohol %")],
"controls": [("edit", "Edit")],
}
return render_template("drink_list.html", model=model)
@app.route("/drink/<drink_id>/edit", methods=["GET"])
@authorize
def drink_edit(drink_id: int):
db = orm.new_session()
drink = db.query(Drink).filter(Drink.id == drink_id).first()
form = forms.DrinkForm()
form.drink_id.data = drink.id
form.name.data = drink.name
form.vol.data = drink.vol
model = models.GenericFormModel(
page_title="Edit Drink",
form_title=f'Edit Drink "{drink.name}"',
post_url="/drink/save",
)
return render_template("generic_form.html", model=model, form=form)
@app.route("/drink/new", methods=["GET"])
@authorize
def new_drink():
form = forms.DrinkForm()
model = models.GenericFormModel(
page_title="New Drink",
form_title=f"Create a new Drink",
post_url="/drink/save",
)
return render_template("generic_form.html", model=model, form=form)
@app.route("/drink/save", methods=["POST"])
@authorize
def drink_save():
form = forms.DrinkForm()
if form.validate_on_submit():
drink_id = int(form.drink_id.data) if form.drink_id.data else None
db = orm.new_session()
if drink_id:
drink = db.query(Drink).filter(Drink.id == drink_id).first()
else:
drink = Drink()
db.add(drink)
drink.populate_from_form(form)
err = db.commit()
return redirect("/drink")
model = models.GenericFormModel(
page_title="Drinks", form_title="Edit Drink", post_url="/drink/save"
)
return render_template("generic_form.html", model=model, form=form)

View File

@@ -0,0 +1,72 @@
from flask import render_template, request, redirect
from estusshots import app
from estusshots import forms, models, orm
from estusshots.util import authorize
from estusshots.orm import Enemy
from sqlalchemy.orm import subqueryload
@app.route("/enemy")
@authorize
def enemy_list():
db = orm.new_session()
enemies = db.query(Enemy).options(subqueryload(Enemy.season)).order_by(Enemy.name).all()
model = {"enemies": enemies}
return render_template("enemies.html", model=model)
@app.route("/enemy/new", methods=["GET"])
@authorize
def enemy_new(preselect_season=None):
form = forms.EnemyForm()
if preselect_season:
form.season_id.default = preselect_season
model = models.GenericFormModel(
page_title="Enemies",
form_title="Create a new Enemy",
post_url=f"/enemy/null/edit",
)
return render_template("generic_form.html", model=model, form=form)
@app.route("/enemy/<enemy_id>/edit", methods=["GET", "POST"])
@authorize
def enemy_edit(enemy_id: int):
model = models.GenericFormModel(
page_title="Enemies",
form_title="Edit Enemy",
post_url=f"/enemy/{enemy_id}/edit",
)
if request.method == "GET":
db = orm.new_session()
enemy = db.query(Enemy).filter(Enemy.id == enemy_id).first()
form = forms.EnemyForm()
form.season_id.data = enemy.season_id if enemy.season_id else -1
form.name.data = enemy.name
form.is_boss.data = enemy.boss
form.enemy_id.data = enemy_id
model.form_title = f'Edit Enemy "{enemy.name}"'
return render_template("generic_form.html", model=model, form=form)
else:
form = forms.EnemyForm()
if form.validate_on_submit():
db = orm.new_session()
enemy = db.query(Enemy).filter(Enemy.id == enemy_id).first()
if not enemy:
enemy = Enemy()
db.add(enemy)
enemy.populate_from_form(form)
db.commit()
if form.submit_continue_button.data:
form.name.data = None
return enemy_new(preselect_season=enemy.season_id)
return redirect("/enemy")
model.form_title = "Incorrect Data"
return render_template("generic_form.html", model=model, form=form)

View File

@@ -0,0 +1,137 @@
from typing import List
from flask import render_template, request, redirect
from estusshots import app
from estusshots import forms, models, db
from estusshots.util import authorize
@app.route("/season/<season_id>/episode/<episode_id>")
@authorize
def episode_detail(season_id: int, episode_id: int):
sql, args = db.load_season(season_id)
season = db.query_db(sql, args, one=True, cls=models.Season)
sql, args = db.load_episode(episode_id)
episode = db.query_db(sql, args, one=True, cls=models.Episode)
sql, args = db.load_episode_players(episode_id)
ep_players = db.query_db(sql, args, cls=models.Player)
sql, args = db.load_events(episode_id)
ep_events: List[models.Event] = db.query_db(sql, args, cls=models.Event)
sql, args = db.load_enemies(season_id)
enemies = db.query_db(sql, args, cls=models.Enemy)
deaths = [ev for ev in ep_events if ev.type == models.EventType.Death]
entries = []
for death in deaths:
entries.append({
"time": death.time.time(),
"type": death.type,
"player_name": [p.name for p in ep_players if p.id == death.player_id],
"enemy_name": [e.name for e in enemies if e.id == death.enemy_id]
})
events = None
if ep_events:
events = {"entries": death, "victory_count": 0, "defeat_count": 0}
model = {
"title": f"{season.code}{episode.code}",
"episode": episode,
"season": season,
"players": ep_players,
"events": events,
}
return render_template("episode_details.html", model=model)
@app.route("/season/<season_id>/episode", methods=["GET"])
@authorize
def episode_list(season_id: int):
sql, args = db.load_season(season_id)
season = db.query_db(sql, args, one=True, cls=models.Season)
sql, args = db.load_episodes(season_id)
episodes = db.query_db(sql, args, cls=models.Episode)
model = {"season_id": season_id, "season_code": season.code}
return render_template("episode_list.html", model=model)
@app.route("/season/<season_id>/episode/new", methods=["GET"])
@authorize
def episode_new(season_id: int):
model = models.GenericFormModel(
page_title="New Episode",
form_title="Create New Episode",
post_url=f"/season/{season_id}/episode/null/edit",
)
form = forms.EpisodeForm(request.form)
form.season_id.data = season_id
return render_template("generic_form.html", model=model, form=form)
@app.route("/season/<season_id>/episode/<episode_id>/edit", methods=["GET", "POST"])
@authorize
def episode_edit(season_id: int, episode_id: int):
model = models.GenericFormModel(
page_title="Edit Episode",
form_title="Edit Episode",
post_url=f"/season/{season_id}/episode/{episode_id}/edit",
)
if request.method == "GET":
sql, args = db.load_episode(episode_id)
episode: models.Episode = db.query_db(sql, args, one=True, cls=models.Episode)
sql, args = db.load_episode_players(episode_id)
ep_players = db.query_db(sql, args, cls=models.Player)
form = forms.EpisodeForm()
form.season_id.data = episode.season_id
form.episode_id.data = episode.id
form.code.data = episode.code
form.date.data = episode.date
form.start.data = episode.start
form.end.data = episode.end
form.title.data = episode.title
form.players.data = [p.id for p in ep_players]
model.form_title = f"Edit Episode '{episode.code}: {episode.title}'"
return render_template("generic_form.html", model=model, form=form)
else:
form = forms.EpisodeForm()
if not form.validate_on_submit():
model.errors = form.errors
return render_template("generic_form.html", model=model, form=form)
errors = False
episode = models.Episode.from_form(form)
sql, args = db.save_episode(episode)
last_key = db.update_db(sql, args, return_key=True)
episode_id = episode.id if episode.id else last_key
form_ids = form.players.data
sql, args = db.load_episode_players(episode_id)
ep_players = db.query_db(sql, args, cls=models.Player)
pids = [p.id for p in ep_players]
new_ids = [pid for pid in form_ids if pid not in pids]
removed_ids = [pid for pid in pids if pid not in form_ids]
if removed_ids:
sql, args = db.remove_episode_player(episode_id, removed_ids)
errors = db.update_db(sql, args)
if new_ids:
sql, args = db.save_episode_players(episode_id, new_ids)
errors = db.update_db(sql, args)
if errors:
model.errors = {"Error saving episode": [errors]}
return render_template("generic_form.html", model=model, form=form)
return redirect(url_for("season_overview", season_id=season_id))

View File

@@ -0,0 +1,56 @@
from collections import namedtuple
from flask import render_template, request, redirect
from estusshots import app
from estusshots import forms, models, db, choices
from estusshots.util import authorize
@app.route("/season/<s_id>/episode/<ep_id>/event/new", methods=["GET"])
@authorize
def event_new(s_id: int, ep_id: int):
model = {
"page_title": "New Event",
"form_title": "Create New Event",
"post_url": f"/season/{s_id}/episode/{ep_id}/event/null/edit",
}
sql, args = db.load_episode(ep_id)
episode: models.Episode = db.query_db(sql, args, one=True, cls=models.Episode)
sql, args = db.load_episode_players(ep_id)
ep_players = db.query_db(sql, args, cls=models.Player)
form = forms.EventForm()
form.episode_id.data = ep_id
form.enemy.choices = choices.enemy_choice_for_season(s_id)
form.event_type.data = 1
Penalty = namedtuple("Penalty", ["penalty_id", "player_id", "player", "drink"])
for player in ep_players:
form.penalties.append_entry(Penalty(None, player.id, player.name, 1))
return render_template("event_editor.html", model=model, form=form)
@app.route("/season/<s_id>/episode/<ep_id>/event/<ev_id>/edit", methods=["GET", "POST"])
@authorize
def event_edit(s_id: int, ep_id: int, ev_id: int):
model = {
"page_title": "Edit Event",
"form_title": "Edit Event",
"post_url": f"/season/{s_id}/episode/{ep_id}/event/{ev_id}/edit",
}
if request.method == "GET":
return render_template("event_editor.html", model=model)
else:
form = forms.EventForm()
form.enemy.choices = choices.enemy_choice_for_season(s_id)
if not form.validate_on_submit():
model["errors"] = form.errors
return render_template("event_editor.html", model=model, form=form)
event = models.Event.from_form(form)
sql, args = db.save_event(event)
errors = db.update_db(sql, args)
return redirect(f"/season/{s_id}/episode/{ep_id}")

28
estusshots/views/login.py Normal file
View File

@@ -0,0 +1,28 @@
from flask import render_template, request, redirect, session
from estusshots import app
from estusshots.util import authorize, get_user_type
@app.route("/login", methods=["GET", "POST"])
def login():
if request.method == "GET":
return render_template("login.html")
else:
user_type = get_user_type(request.form.get("password"))
if not user_type:
return redirect("/login")
session["user_type"] = user_type
return redirect("/")
@app.route("/logout")
def logout():
session.pop("role", None)
return redirect("login")
@app.route("/")
@authorize
def landing():
return redirect("/season")

View File

@@ -0,0 +1,71 @@
from flask import render_template, request, redirect
from estusshots import app
from estusshots import forms, models, orm
from estusshots.util import authorize
from estusshots.orm import Player
@app.route("/player/new", methods=["GET"])
@authorize
def player_new():
form = forms.PlayerForm()
model = models.GenericFormModel(
page_title="Players",
form_title="Create a new Player",
post_url="/player/null/edit",
)
return render_template("generic_form.html", model=model, form=form)
@app.route("/player/<player_id>/edit", methods=["GET", "POST"])
@authorize
def player_edit(player_id: int):
model = models.GenericFormModel(
page_title="Players",
form_title=f"Edit Player",
post_url=f"/player/{player_id}/edit",
)
# Edit Existing Player
if request.method == "GET":
db = orm.new_session()
player = db.query(Player).filter(Player.id == player_id).first()
form = forms.PlayerForm()
form.player_id.data = player.id
form.anonymize.data = player.anon
form.real_name.data = player.real_name
form.alias.data = player.alias
form.hex_id.data = player.hex_id
model.form_title = f'Edit Player "{player.name}"'
return render_template("generic_form.html", model=model, form=form)
# Save POSTed data
else:
form = forms.PlayerForm()
if form.validate_on_submit():
db = orm.new_session()
player = db.query(Player).filter(Player.id == player_id).first()
player.populate_from_form(form)
db.commit()
return redirect("/player")
model.form_title = "Incorrect Data"
return render_template("generic_form.html", model=model, form=form)
@app.route("/player")
@authorize
def player_list():
db = orm.new_session()
players = db.query(Player)
model = {
"player_list": players,
"columns": [
("name", "Player Name"),
("alias", "Alias"),
("hex_id", "Hex ID"),
],
}
return render_template("player_list.html", model=model)

View File

@@ -0,0 +1,94 @@
from flask import render_template, request, redirect, url_for
from estusshots import app
from estusshots import forms, models, orm
from estusshots.util import authorize
from estusshots.orm import Season
@app.route("/season")
@authorize
def season_list():
db = orm.new_session()
seasons = db.query(Season).order_by(Season.code).all()
model = {
"seasons": seasons,
"columns": [
("code", "#"),
("game", "Game"),
("description", "Season Description"),
("start", "Started At"),
("end", "Ended At"),
],
}
return render_template("season_list.html", model=model)
@app.route("/season/new", methods=["GET"])
@authorize
def season_new():
form = forms.SeasonForm()
model = models.GenericFormModel(
page_title="New Season",
form_title="Create New Season",
post_url="/season/edit/null",
)
return render_template("generic_form.html", model=model, form=form)
@app.route("/season/edit/<season_id>", methods=["GET", "POST"])
@authorize
def season_edit(season_id: int):
model = models.GenericFormModel(
page_title="Seasons",
form_title="Edit Season",
post_url=f"/season/edit/{season_id}",
)
db = orm.new_session()
season = db.query(Season).filter(Season.id == season_id).first()
if request.method == "GET":
form = forms.SeasonForm()
form.season_id.data = season.id
form.code.data = season.code
form.game_name.data = season.game
form.description.data = season.description
form.start.data = season.start
form.end.data = season.end
model.form_title = f"Edit Season '{season.code}: {season.game}'"
return render_template("generic_form.html", model=model, form=form)
else:
form = forms.SeasonForm()
if not form.validate_on_submit():
model.errors = form.errors
return render_template("generic_form.html", model=model, form=form)
if not season:
season = Season()
db.add(season)
season.populate_from_form(form)
db.commit()
return redirect(url_for("season_list"))
@app.route("/season/<season_id>", methods=["GET"])
@authorize
def season_overview(season_id: int):
db = orm.new_session()
season = db.query(Season).filter(Season.id == season_id).first()
infos = {
"Number": season.code,
"Game": season.game,
"Start Date": season.start,
"End Date": season.end if season.end else "Ongoing",
}
model = {
"title": f"{season.code} {season.game}",
"season_info": infos,
"episodes": season.episodes,
}
return render_template("season_overview.html", model=model)