Additional buttons and infos on episode page.
This commit is contained in:
32
app.py
32
app.py
@@ -8,6 +8,7 @@ from flask_bootstrap import Bootstrap
|
|||||||
import db
|
import db
|
||||||
import forms
|
import forms
|
||||||
import models
|
import models
|
||||||
|
import util
|
||||||
from config import Config
|
from config import Config
|
||||||
|
|
||||||
|
|
||||||
@@ -27,6 +28,22 @@ app = create_app()
|
|||||||
app.config.from_object(Config)
|
app.config.from_object(Config)
|
||||||
|
|
||||||
|
|
||||||
|
@app.template_filter("format_time")
|
||||||
|
def format_time(value):
|
||||||
|
"""Make the datetime to time string formatting available to jinja2"""
|
||||||
|
if value is None:
|
||||||
|
return ""
|
||||||
|
return util.datetime_time_str(value)
|
||||||
|
|
||||||
|
|
||||||
|
@app.template_filter("format_timedelta")
|
||||||
|
def format_timedelta(value):
|
||||||
|
"""Make formatting for timedeltas available to jinja2"""
|
||||||
|
if value is None:
|
||||||
|
return ""
|
||||||
|
return util.timedelta_to_str(value)
|
||||||
|
|
||||||
|
|
||||||
@app.cli.command("initdb")
|
@app.cli.command("initdb")
|
||||||
def init_db_command():
|
def init_db_command():
|
||||||
"""Initializes the database."""
|
"""Initializes the database."""
|
||||||
@@ -188,10 +205,15 @@ def episode_detail(season_id: int, episode_id: int):
|
|||||||
episode = db.query_db(sql, args, one=True, cls=models.Episode)
|
episode = db.query_db(sql, args, one=True, cls=models.Episode)
|
||||||
sql, args = db.load_episode_players(episode_id)
|
sql, args = db.load_episode_players(episode_id)
|
||||||
ep_players = db.query_db(sql, args, cls=models.Player)
|
ep_players = db.query_db(sql, args, cls=models.Player)
|
||||||
|
|
||||||
|
events = {"entries": [], "victory_count": 0, "defeat_count": 0}
|
||||||
|
|
||||||
model = {
|
model = {
|
||||||
"title": f"{season.code}{episode.code}",
|
"title": f"{season.code}{episode.code}",
|
||||||
"episode": episode,
|
"episode": episode,
|
||||||
"players": ep_players
|
"season": season,
|
||||||
|
"players": ep_players,
|
||||||
|
"events": events,
|
||||||
}
|
}
|
||||||
|
|
||||||
return render_template("episode_details.html", model=model)
|
return render_template("episode_details.html", model=model)
|
||||||
@@ -289,7 +311,13 @@ def episode_edit(season_id: int, episode_id: int):
|
|||||||
return redirect(url_for("season_overview", season_id=season_id))
|
return redirect(url_for("season_overview", season_id=season_id))
|
||||||
|
|
||||||
|
|
||||||
@app.route("/players/new")
|
@app.route("/seasons/<season_id>/episodes/<episode_id>/events/new", methods=["GET"])
|
||||||
|
@authorize
|
||||||
|
def event_new(season_id: int, episode_id: int):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/players/new", methods=["GET"])
|
||||||
@authorize
|
@authorize
|
||||||
def player_new():
|
def player_new():
|
||||||
form = forms.PlayerForm()
|
form = forms.PlayerForm()
|
||||||
|
|||||||
@@ -113,6 +113,10 @@ class Episode:
|
|||||||
end: Union[datetime.datetime, Rational]
|
end: Union[datetime.datetime, Rational]
|
||||||
code: str
|
code: str
|
||||||
|
|
||||||
|
@property
|
||||||
|
def playtime(self):
|
||||||
|
return self.end - self.start
|
||||||
|
|
||||||
def __post_init__(self):
|
def __post_init__(self):
|
||||||
if isinstance(self.date, str):
|
if isinstance(self.date, str):
|
||||||
self.date = datetime.datetime.strptime(self.date, util.DATE_FMT).date()
|
self.date = datetime.datetime.strptime(self.date, util.DATE_FMT).date()
|
||||||
|
|||||||
@@ -2,10 +2,22 @@
|
|||||||
{% set active_page = "seasons" %}
|
{% set active_page = "seasons" %}
|
||||||
{% block title %}{{ model.title }} {{ super() }}{% endblock %}
|
{% block title %}{{ model.title }} {{ super() }}{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block page %}
|
||||||
<div class="container">
|
{% if g.is_editor %}
|
||||||
|
<div class="btn-toolbar" role="toolbar">
|
||||||
|
<a class="btn btn-primary" role="button"
|
||||||
|
href="{{ url_for('episode_edit', season_id = model.season.id, episode_id = model.episode.id) }}">
|
||||||
|
<span class="fas fa-pencil-alt"></span> Edit Episode
|
||||||
|
</a>
|
||||||
|
<a class="btn btn-primary" role="button"
|
||||||
|
href="{{ url_for("event_new", episode_id = model.episode.id, season_id = model.season.id) }}" >
|
||||||
|
<span class="fas fa-plus"></span> Event
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-6">
|
<div class="col-sm-6">
|
||||||
|
|
||||||
<!--region Info Card-->
|
<!--region Info Card-->
|
||||||
|
|
||||||
@@ -14,6 +26,34 @@
|
|||||||
{{ model.episode.code }}: {{ model.episode.title }}
|
{{ model.episode.code }}: {{ model.episode.title }}
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
<div class="card-text">
|
||||||
|
<ul class="list-group list-group-flush">
|
||||||
|
<li class="list-group-item">
|
||||||
|
<span class="font-weight-bold">Date:</span>
|
||||||
|
{{ model.episode.date }}
|
||||||
|
</li>
|
||||||
|
<li class="list-group-item">
|
||||||
|
<span class="font-weight-bold">Start:</span>
|
||||||
|
{{ model.episode.start|format_time }}
|
||||||
|
</li>
|
||||||
|
<li class="list-group-item">
|
||||||
|
<span class="font-weight-bold">End:</span>
|
||||||
|
{{ model.episode.end|format_time }}
|
||||||
|
</li>
|
||||||
|
<li class="list-group-item">
|
||||||
|
<span class="font-weight-bold">Play Time:</span>
|
||||||
|
{{ model.episode.playtime }}
|
||||||
|
</li>
|
||||||
|
<li class="list-group-item">
|
||||||
|
<span class="font-weight-bold">Enemies Defeated:</span>
|
||||||
|
{{ model.events.victory_count }}
|
||||||
|
</li>
|
||||||
|
<li class="list-group-item">
|
||||||
|
<span class="font-weight-bold">Deaths:</span>
|
||||||
|
{{ model.events.defeat_count }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -49,15 +89,14 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-6">
|
<div class="col-sm-6">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header text-center">
|
<div class="card-header text-center">
|
||||||
Events
|
Event List
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
19
util.py
19
util.py
@@ -12,15 +12,26 @@ def str_to_datetime(data: str) -> datetime.datetime:
|
|||||||
return datetime.datetime.strptime(data, TIME_FMT)
|
return datetime.datetime.strptime(data, TIME_FMT)
|
||||||
|
|
||||||
|
|
||||||
def time_to_str(data: datetime.time) -> str:
|
def datetime_time_str(data: datetime) -> str:
|
||||||
"""
|
"""
|
||||||
Convert a datetime.time object into a formatted string for sqlite
|
Convert a datetime object into a formatted string for display
|
||||||
:param data: datetime.time
|
:param data: datetime
|
||||||
:return: str
|
:return: str
|
||||||
"""
|
"""
|
||||||
return data.strftime(TIME_FMT)
|
return data.strftime(TIME_FMT)
|
||||||
|
|
||||||
|
|
||||||
|
def timedelta_to_str(data: datetime.timedelta) -> str:
|
||||||
|
"""
|
||||||
|
Remove second and microsecond portion from timedeltas for display
|
||||||
|
:param data: datetime.timedelta
|
||||||
|
:return: str
|
||||||
|
"""
|
||||||
|
return str(
|
||||||
|
data - datetime.timedelta(seconds=data.seconds, microseconds=data.microseconds)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def combine_datetime(date: datetime.date, time: datetime.time):
|
def combine_datetime(date: datetime.date, time: datetime.time):
|
||||||
"""
|
"""
|
||||||
Combine a date and time object into a datetime object
|
Combine a date and time object into a datetime object
|
||||||
@@ -32,5 +43,5 @@ def combine_datetime(date: datetime.date, time: datetime.time):
|
|||||||
time.hour,
|
time.hour,
|
||||||
time.minute,
|
time.minute,
|
||||||
time.second,
|
time.second,
|
||||||
time.microsecond
|
time.microsecond,
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user