Show episodes on season overview page.
This commit is contained in:
50
app.py
50
app.py
@@ -160,14 +160,22 @@ def season_edit(season_id: int):
|
|||||||
@authorize
|
@authorize
|
||||||
def season_overview(season_id: int):
|
def season_overview(season_id: int):
|
||||||
sql, args = db.load_season(season_id)
|
sql, args = db.load_season(season_id)
|
||||||
db_season = db.query_db(sql, args, one=True, cls=models.Season)
|
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)
|
||||||
|
|
||||||
infos = {
|
infos = {
|
||||||
"Number": db_season.code,
|
"Number": season.code,
|
||||||
"Game": db_season.game,
|
"Game": season.game,
|
||||||
"Start Date": db_season.start,
|
"Start Date": season.start,
|
||||||
"End Date": db_season.end if db_season.end else "Ongoing",
|
"End Date": season.end if season.end else "Ongoing",
|
||||||
|
}
|
||||||
|
model = {
|
||||||
|
"title": f"{season.code} {season.game}",
|
||||||
|
"season_info": infos,
|
||||||
|
"episodes": episodes
|
||||||
}
|
}
|
||||||
model = {"title": f"{db_season.code} {db_season.game}", "season_info": infos}
|
|
||||||
return render_template("season_overview.html", model=model)
|
return render_template("season_overview.html", model=model)
|
||||||
|
|
||||||
|
|
||||||
@@ -187,7 +195,7 @@ def episode_new(season_id: int):
|
|||||||
model = models.GenericFormModel(
|
model = models.GenericFormModel(
|
||||||
page_title="New Episode",
|
page_title="New Episode",
|
||||||
form_title="Create New Episode",
|
form_title="Create New Episode",
|
||||||
post_url="/episodes/save",
|
post_url=f"/seasons/{season_id}/episodes/edit/null",
|
||||||
)
|
)
|
||||||
|
|
||||||
form = forms.EpisodeForm(request.form)
|
form = forms.EpisodeForm(request.form)
|
||||||
@@ -198,10 +206,34 @@ def episode_new(season_id: int):
|
|||||||
@app.route("/seasons/<season_id>/episodes/edit/<episode_id>", methods=["GET", "POST"])
|
@app.route("/seasons/<season_id>/episodes/edit/<episode_id>", methods=["GET", "POST"])
|
||||||
@authorize
|
@authorize
|
||||||
def episode_edit(season_id: int, episode_id: int):
|
def episode_edit(season_id: int, episode_id: int):
|
||||||
|
model = models.GenericFormModel(
|
||||||
|
page_title="Edit Episode",
|
||||||
|
form_title="Edit Episode",
|
||||||
|
post_url=f"/seasons/{season_id}/episodes/edit/{episode_id}",
|
||||||
|
)
|
||||||
|
|
||||||
if request.method == "GET":
|
if request.method == "GET":
|
||||||
pass
|
sql, args = db.load_episode(episode_id)
|
||||||
|
episode: models.Episode = db.query_db(sql, args, one=True, cls=models.Episode)
|
||||||
|
|
||||||
|
form = forms.EpisodeForm()
|
||||||
|
|
||||||
|
model.form_title = f"Edit Episode '{episode.code}: {episode.title}'"
|
||||||
|
return render_template("generic_form.html", model=model, form=form)
|
||||||
else:
|
else:
|
||||||
pass
|
form = forms.EpisodeForm()
|
||||||
|
|
||||||
|
if not form.validate_on_submit():
|
||||||
|
model.errors = form.errors
|
||||||
|
return render_template("generic_form.html", model=model, form=form)
|
||||||
|
|
||||||
|
episode = models.Episode.from_form(form)
|
||||||
|
sql, args = db.save_episode(episode)
|
||||||
|
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))
|
||||||
|
|
||||||
|
|
||||||
@app.route("/players/new")
|
@app.route("/players/new")
|
||||||
|
|||||||
41
db.py
41
db.py
@@ -4,6 +4,7 @@ from flask import g
|
|||||||
|
|
||||||
import models
|
import models
|
||||||
from config import Config
|
from config import Config
|
||||||
|
from util import time_to_str
|
||||||
|
|
||||||
|
|
||||||
def connect_db():
|
def connect_db():
|
||||||
@@ -166,6 +167,16 @@ def load_season(id=None):
|
|||||||
return sql, args
|
return sql, args
|
||||||
|
|
||||||
|
|
||||||
|
def load_episode(episode_id: int = None):
|
||||||
|
sql = "select * from episode"
|
||||||
|
args = ()
|
||||||
|
if episode_id:
|
||||||
|
sql += " where episode.id = ?"
|
||||||
|
args = (episode_id,)
|
||||||
|
sql += " order by episode.code"
|
||||||
|
return sql, args
|
||||||
|
|
||||||
|
|
||||||
def load_episodes(season_id: int = None):
|
def load_episodes(season_id: int = None):
|
||||||
sql = "select * from episode"
|
sql = "select * from episode"
|
||||||
args = ()
|
args = ()
|
||||||
@@ -174,3 +185,33 @@ def load_episodes(season_id: int = None):
|
|||||||
args = (season_id,)
|
args = (season_id,)
|
||||||
sql += " order by episode.code"
|
sql += " order by episode.code"
|
||||||
return sql, args
|
return sql, args
|
||||||
|
|
||||||
|
|
||||||
|
def save_episode(episode: models.Episode):
|
||||||
|
if not episode.id:
|
||||||
|
sql = "insert into episode values (?, ?, ?, ?, ?, ?, ?)"
|
||||||
|
args = (
|
||||||
|
None,
|
||||||
|
episode.season_id,
|
||||||
|
episode.title,
|
||||||
|
episode.date,
|
||||||
|
time_to_str(episode.start),
|
||||||
|
time_to_str(episode.end),
|
||||||
|
episode.code
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
sql = (
|
||||||
|
"update episode "
|
||||||
|
"set season_id=?, title=?, date=?, start=?, end=?, code=?"
|
||||||
|
"where id==?"
|
||||||
|
)
|
||||||
|
args = (
|
||||||
|
episode.season_id,
|
||||||
|
episode.title,
|
||||||
|
episode.date,
|
||||||
|
time_to_str(episode.start),
|
||||||
|
time_to_str(episode.end),
|
||||||
|
episode.code,
|
||||||
|
episode.id,
|
||||||
|
)
|
||||||
|
return sql, args
|
||||||
|
|||||||
24
models.py
24
models.py
@@ -1,8 +1,10 @@
|
|||||||
import datetime
|
import datetime
|
||||||
|
import logging
|
||||||
from typing import Dict, List
|
from typing import Dict, List
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
|
||||||
import forms
|
import forms
|
||||||
|
from util import str_to_time
|
||||||
|
|
||||||
INVALID_STR = 'Form entry "{}" is invalid'
|
INVALID_STR = 'Form entry "{}" is invalid'
|
||||||
|
|
||||||
@@ -111,8 +113,24 @@ class Episode:
|
|||||||
date: datetime.date
|
date: datetime.date
|
||||||
start: datetime.time
|
start: datetime.time
|
||||||
end: datetime.time
|
end: datetime.time
|
||||||
|
code: str
|
||||||
|
|
||||||
def __post_init__(self):
|
def __post_init__(self):
|
||||||
self.date = datetime.datetime.strptime(self.date, "%Y-%m-%d").date()
|
try:
|
||||||
self.start = datetime.datetime.strptime(self.start, "%H:%M").time()
|
self.date = datetime.datetime.strptime(self.date, "%Y-%m-%d").date()
|
||||||
self.end = datetime.datetime.strptime(self.end, "%H:%M").time()
|
except TypeError as err:
|
||||||
|
logging.warning(err)
|
||||||
|
self.start = str_to_time(str(self.start))
|
||||||
|
self.end = str_to_time(str(self.end))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_form(cls, form: forms.EpisodeForm):
|
||||||
|
episode_id = int(form.episode_id.data) if form.episode_id.data else None
|
||||||
|
season_id = int(form.season_id.data)
|
||||||
|
title = str(form.title.data)
|
||||||
|
date = form.date.data
|
||||||
|
start = form.start.data
|
||||||
|
end = form.end.data
|
||||||
|
code = str(form.code.data)
|
||||||
|
|
||||||
|
return cls(episode_id, season_id, title, date, start, end, code)
|
||||||
|
|||||||
@@ -74,3 +74,7 @@ create table if not exists episode
|
|||||||
|
|
||||||
create unique index if not exists episode_id_uindex
|
create unique index if not exists episode_id_uindex
|
||||||
on episode (id);
|
on episode (id);
|
||||||
|
|
||||||
|
|
||||||
|
alter table episode
|
||||||
|
add code text not null default 'EXX';
|
||||||
|
|||||||
@@ -32,7 +32,47 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header text-center">Episodes</div>
|
<div class="card-header text-center">Episodes</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
Episode list here
|
{% if not model.episodes %}
|
||||||
|
<div class="alert alert-info">No Episodes in this Season</div>
|
||||||
|
{% else %}
|
||||||
|
|
||||||
|
<table class="table table-striped table-bordered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col" class="col-sm-auto text-center">#</th>
|
||||||
|
<th scope="col" class="col-sm-auto text-center">Date</th>
|
||||||
|
<th scope="col" class="col-sm-auto text-center">Title</th>
|
||||||
|
|
||||||
|
<th scope="col" class="col-sm-auto text-center">View</th>
|
||||||
|
{% if g.is_editor %}
|
||||||
|
<th scope="col" class="col-sm-auto text-center">Editor</th>
|
||||||
|
{% endif %}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for item in model.episodes %}
|
||||||
|
<tr>
|
||||||
|
<td class="col-sm-auto text-center">{{ item.code }}</td>
|
||||||
|
<td class="col-sm-auto text-center">{{ item.date }}</td>
|
||||||
|
<td class="col-sm-auto text-center">{{ item.title }}</td>
|
||||||
|
|
||||||
|
<td class="col-sm-auto text-center">
|
||||||
|
<a class="btn btn-default" href="#"><span class="fas fa-eye"></span></a>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
{% if g.is_editor %}
|
||||||
|
<td class="col-sm-auto text-center">
|
||||||
|
<a class="btn btn-default" href="{{ url_for('episode_edit', season_id = item.id, episode_id = item.id) }}">
|
||||||
|
<span class="fas fa-pencil-alt"></span>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
{% endif %}
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
18
util.py
Normal file
18
util.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import datetime
|
||||||
|
|
||||||
|
TIME_FMT = "%H:%M"
|
||||||
|
DATE_FMT = "%Y-%m-%d"
|
||||||
|
|
||||||
|
|
||||||
|
def str_to_time(data: str) -> datetime.time:
|
||||||
|
data = ":".join(data.split(":")[:2])
|
||||||
|
return datetime.datetime.strptime(data, TIME_FMT).time()
|
||||||
|
|
||||||
|
|
||||||
|
def time_to_str(data: datetime.time) -> str:
|
||||||
|
"""
|
||||||
|
Convert a datetime.time object into a formatted string for sqlite
|
||||||
|
:param data: datetime.time
|
||||||
|
:return: str
|
||||||
|
"""
|
||||||
|
return data.strftime(TIME_FMT)
|
||||||
Reference in New Issue
Block a user