Replace season editor with the generic editor.
This commit is contained in:
60
app.py
60
app.py
@@ -2,7 +2,7 @@ import functools
|
||||
import logging
|
||||
import os
|
||||
|
||||
from flask import Flask, g, render_template, request, redirect, session
|
||||
from flask import Flask, g, render_template, request, redirect, session, url_for
|
||||
from flask_bootstrap import Bootstrap
|
||||
|
||||
import db
|
||||
@@ -104,34 +104,55 @@ def season_list():
|
||||
("end", "Ended At"),
|
||||
],
|
||||
}
|
||||
return render_template("seasons.html", model=model)
|
||||
return render_template("season_list.html", model=model)
|
||||
|
||||
|
||||
@app.route("/seasons/new", methods=["GET"])
|
||||
@authorize
|
||||
def season_new():
|
||||
return render_template("editseason.html", model={})
|
||||
form = forms.SeasonForm()
|
||||
model = models.GenericFormModel(
|
||||
page_title="New Season",
|
||||
form_title="Create New Season",
|
||||
post_url="/seasons/edit/null",
|
||||
)
|
||||
return render_template("generic_form.html", model=model, form=form)
|
||||
|
||||
|
||||
@app.route("/seasons/<id>/edit")
|
||||
@app.route("/seasons/edit/<season_id>", methods=["GET", "POST"])
|
||||
@authorize
|
||||
def season_edit(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)
|
||||
def season_edit(season_id: int):
|
||||
model = models.GenericFormModel(
|
||||
page_title="Seasons",
|
||||
form_title="Edit Season",
|
||||
post_url=f"/seasons/edit/{season_id}",
|
||||
)
|
||||
|
||||
if request.method == "GET":
|
||||
sql, args = db.load_season(season_id)
|
||||
season: models.Season = db.query_db(sql, args, one=True, cls=models.Season)
|
||||
|
||||
@app.route("/seasons/save", methods=["POST"])
|
||||
@authorize
|
||||
def season_save():
|
||||
try:
|
||||
season = models.Season.from_form(request.form)
|
||||
except AttributeError as err:
|
||||
print(err)
|
||||
return render_template("editseason.html", model={})
|
||||
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)
|
||||
|
||||
season = models.Season.from_form(form)
|
||||
sql, args = db.save_season_query(season)
|
||||
res = db.update_db(sql, args)
|
||||
return redirect("/seasons")
|
||||
errors = db.update_db(sql, args)
|
||||
return redirect(url_for("season_list"))
|
||||
|
||||
|
||||
@app.route("/seasons/<season_id>", methods=["GET"])
|
||||
@@ -341,9 +362,6 @@ def enemy_edit(enemy_id: int):
|
||||
)
|
||||
|
||||
if request.method == "GET":
|
||||
sql, args = db.load_season()
|
||||
seasons = db.query_db(sql, args, cls=models.Season)
|
||||
|
||||
sql, args = db.load_enemies(enemy_id)
|
||||
enemy = db.query_db(sql, args, one=True, cls=models.Enemy)
|
||||
|
||||
|
||||
12
forms.py
12
forms.py
@@ -8,11 +8,21 @@ from wtforms import (
|
||||
DecimalField,
|
||||
SelectField,
|
||||
)
|
||||
from wtforms.validators import DataRequired
|
||||
from wtforms.validators import DataRequired, Optional
|
||||
|
||||
import choices
|
||||
|
||||
|
||||
class SeasonForm(FlaskForm):
|
||||
season_id = StringField("Season ID", render_kw={"readonly": True})
|
||||
code = StringField("Season Code", validators=[DataRequired()])
|
||||
game_name = StringField("Game Name", validators=[DataRequired()])
|
||||
description = StringField("Season Description")
|
||||
start = DateField("Season Start", format="%Y-%m-%d", validators=[DataRequired()])
|
||||
end = DateField("Season End", format="%Y-%m-%d", validators=[Optional()])
|
||||
submit_button = SubmitField("Submit")
|
||||
|
||||
|
||||
class EpisodeForm(FlaskForm):
|
||||
season_id = StringField("Season ID", render_kw={"readonly": True})
|
||||
episode_id = StringField("Episode ID", render_kw={"readonly": True})
|
||||
|
||||
48
models.py
48
models.py
@@ -1,4 +1,5 @@
|
||||
import datetime
|
||||
from typing import Dict, List
|
||||
from dataclasses import dataclass
|
||||
|
||||
import forms
|
||||
@@ -11,6 +12,7 @@ class GenericFormModel:
|
||||
page_title: str
|
||||
form_title: str
|
||||
post_url: str
|
||||
errors: Dict[str, List[str]] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -78,34 +80,24 @@ class Season:
|
||||
end: datetime.date
|
||||
code: str
|
||||
|
||||
def __post_init__(self):
|
||||
try:
|
||||
self.start = datetime.datetime.strptime(self.start, "%Y-%m-%d").date()
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
self.end = datetime.datetime.strptime(self.end, "%Y-%m-%d").date()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def from_form(cls, form):
|
||||
id = form.get("id", None)
|
||||
id = int(id) if id else None
|
||||
def from_form(cls, form: forms.SeasonForm):
|
||||
season_id = int(form.season_id.data) if form.season_id.data else None
|
||||
code = str(form.code.data)
|
||||
game = str(form.game_name.data)
|
||||
description = str(form.description.data) if form.description.data else None
|
||||
start = form.start.data
|
||||
end = form.end.data
|
||||
|
||||
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 AttributeError(INVALID_STR.format("end"))
|
||||
|
||||
code = form.get("code", None)
|
||||
if not code:
|
||||
raise AttributeError(INVALID_STR.format("code"))
|
||||
|
||||
self = cls(id, game, description, start, end, code)
|
||||
self = cls(season_id, game, description, start, end, code)
|
||||
return self
|
||||
|
||||
@@ -6,6 +6,18 @@
|
||||
{% block page %}
|
||||
<div class="text-center">
|
||||
<h1>{{ model.form_title }}</h1>
|
||||
|
||||
{% if model.errors %}
|
||||
<div class="alert alert-danger">
|
||||
{% for field, errors in model.errors.items() %}
|
||||
<div>
|
||||
<strong class="text-capitalize">{{ field }}</strong>:
|
||||
{{ errors|join(', ') }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<form action="{{ model.post_url }}" method="post">
|
||||
{{ wtf.quick_form(form, button_map={'submit_button': 'primary'}, form_type='horizontal', horizontal_columns=('lg', 2, 10)) }}
|
||||
</form>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
{% block page %}
|
||||
{% if g.is_editor %}
|
||||
<div class="btn-toolbar" role="toolbar">
|
||||
<a class="btn btn-primary" href="/seasons/new" role="button"><span class="fas fa-plus"></span> Season</a>
|
||||
<a class="btn btn-primary" href="{{ url_for("season_new") }}" role="button"><span class="fas fa-plus"></span> Season</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if not model.seasons %}
|
||||
@@ -40,9 +40,11 @@
|
||||
|
||||
{% if g.is_editor %}
|
||||
<td class="col-sm-auto text-center">
|
||||
<a class="btn btn-dark" href="/seasons/{{ item.id }}/edit"><span class="fas fa-pencil-alt"></span></a>
|
||||
<a class="btn btn-dark" href="{{ url_for('season_edit', season_id = item.id) }}">
|
||||
<span class="fas fa-pencil-alt"></span>
|
||||
</a>
|
||||
|
||||
<a class="btn btn-dark" href="/seasons/{{ item.id }}/new">
|
||||
<a class="btn btn-dark" href="#">
|
||||
<span class="fas fa-plus"></span> Episode
|
||||
</a>
|
||||
</td>
|
||||
Reference in New Issue
Block a user