Finalize migration to SQLAlchemy.
This commit is contained in:
@@ -1,16 +1,16 @@
|
|||||||
from estusshots import orm, models, db
|
from estusshots.orm import new_session, EventType, Season, Player, Drink, Enemy
|
||||||
from estusshots.orm import Season
|
|
||||||
|
|
||||||
|
|
||||||
def event_choices():
|
def event_choices():
|
||||||
return [(member.value, member.name) for member in models.EventType]
|
return [(member.value, member.name) for member in EventType]
|
||||||
|
|
||||||
|
|
||||||
def season_choices():
|
def season_choices():
|
||||||
""" Query the database for available seasons.
|
"""
|
||||||
|
Query the database for available seasons.
|
||||||
This returns a list of tuples with the season ID and a display string.
|
This returns a list of tuples with the season ID and a display string.
|
||||||
"""
|
"""
|
||||||
db = orm.new_session()
|
db = new_session()
|
||||||
seasons = db.query(Season).order_by(Season.code).all()
|
seasons = db.query(Season).order_by(Season.code).all()
|
||||||
choices = [(s.id, f"{s.code}: {s.game}") for s in seasons]
|
choices = [(s.id, f"{s.code}: {s.game}") for s in seasons]
|
||||||
choices.insert(0, (-1, "No Season"))
|
choices.insert(0, (-1, "No Season"))
|
||||||
@@ -21,8 +21,8 @@ def player_choice():
|
|||||||
"""
|
"""
|
||||||
Query database for a list of available players to bind them to a select box
|
Query database for a list of available players to bind them to a select box
|
||||||
"""
|
"""
|
||||||
sql, args = db.load_players()
|
db = new_session()
|
||||||
players = db.query_db(sql, args, cls=models.Player)
|
players = sorted(db.query(Player).all(), key=lambda x: x.name)
|
||||||
return [(p.id, p.name) for p in players]
|
return [(p.id, p.name) for p in players]
|
||||||
|
|
||||||
|
|
||||||
@@ -30,8 +30,8 @@ def drink_choice():
|
|||||||
"""
|
"""
|
||||||
Query database for a list of all available drinks to select from
|
Query database for a list of all available drinks to select from
|
||||||
"""
|
"""
|
||||||
sql, args = db.load_drinks()
|
db = new_session()
|
||||||
drinks = db.query_db(sql, args, cls=models.Drink)
|
drinks = db.query(Drink).order_by(Drink.name).all()
|
||||||
choices = [(d.id, d.name) for d in drinks]
|
choices = [(d.id, d.name) for d in drinks]
|
||||||
choices.insert(0, (-1, "None"))
|
choices.insert(0, (-1, "None"))
|
||||||
return choices
|
return choices
|
||||||
@@ -41,9 +41,13 @@ def enemy_choice_for_season(season_id: int):
|
|||||||
"""
|
"""
|
||||||
Query database for all available enemies in this season
|
Query database for all available enemies in this season
|
||||||
"""
|
"""
|
||||||
sql, args = db.load_enemies_for_season(season_id)
|
db = new_session()
|
||||||
enemies = db.query_db(sql, args, cls=models.Enemy)
|
season: Season = db.query(Season).get(season_id)
|
||||||
return [(e.id, e.name) for e in enemies]
|
global_enemies = db.query(Enemy).filter(Enemy.season_id == -1).all()
|
||||||
|
if not season and not global_enemies:
|
||||||
|
return []
|
||||||
|
combined = global_enemies + season.enemies
|
||||||
|
return [(e.id, e.name) for e in combined]
|
||||||
|
|
||||||
|
|
||||||
class IterableBase:
|
class IterableBase:
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import enum
|
import enum
|
||||||
|
from typing import Iterable, List
|
||||||
|
|
||||||
import sqlalchemy
|
import sqlalchemy
|
||||||
from sqlalchemy import create_engine, ForeignKey, Table
|
from sqlalchemy import create_engine, ForeignKey, Table
|
||||||
from sqlalchemy.ext.declarative import declarative_base
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
@@ -10,6 +12,13 @@ from estusshots import util, forms
|
|||||||
engine = create_engine('sqlite:///../databases/test.db')
|
engine = create_engine('sqlite:///../databases/test.db')
|
||||||
Base = declarative_base()
|
Base = declarative_base()
|
||||||
|
|
||||||
|
player_episode = Table(
|
||||||
|
'player_episode',
|
||||||
|
Base.metadata,
|
||||||
|
Column('player_id', ForeignKey('players.id'), primary_key=True),
|
||||||
|
Column('episode_id', ForeignKey('episodes.id'), primary_key=True)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class EventType(enum.Enum):
|
class EventType(enum.Enum):
|
||||||
Pause = 0
|
Pause = 0
|
||||||
@@ -27,6 +36,7 @@ class Player(Base):
|
|||||||
anon = Column(Boolean, default=False)
|
anon = Column(Boolean, default=False)
|
||||||
|
|
||||||
events = relationship("Event", back_populates="player")
|
events = relationship("Event", back_populates="player")
|
||||||
|
episodes = relationship("Episode", secondary=player_episode, back_populates="players")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
@@ -61,8 +71,8 @@ class Season(Base):
|
|||||||
start = Column(Date)
|
start = Column(Date)
|
||||||
end = Column(Date)
|
end = Column(Date)
|
||||||
|
|
||||||
episodes = relationship("Episode", back_populates="season")
|
episodes: Iterable["Episode"] = relationship("Episode", back_populates="season")
|
||||||
enemies = relationship("Enemy", back_populates="season")
|
enemies: Iterable["Enemy"] = relationship("Enemy", back_populates="season")
|
||||||
|
|
||||||
def populate_from_form(self, form: "forms.SeasonForm"):
|
def populate_from_form(self, form: "forms.SeasonForm"):
|
||||||
self.code = str(form.code.data)
|
self.code = str(form.code.data)
|
||||||
@@ -82,7 +92,7 @@ class Enemy(Base):
|
|||||||
season_id = Column(Integer, ForeignKey('seasons.id'))
|
season_id = Column(Integer, ForeignKey('seasons.id'))
|
||||||
season = relationship("Season", back_populates="enemies")
|
season = relationship("Season", back_populates="enemies")
|
||||||
|
|
||||||
events = relationship('Event', back_populates="enemy")
|
events: Iterable["Event"] = relationship('Event', back_populates="enemy")
|
||||||
|
|
||||||
def populate_from_form(self, form: "forms.EnemyForm"):
|
def populate_from_form(self, form: "forms.EnemyForm"):
|
||||||
self.name = str(form.name.data)
|
self.name = str(form.name.data)
|
||||||
@@ -103,18 +113,26 @@ class Episode(Base):
|
|||||||
season_id = Column(Integer, ForeignKey('seasons.id'))
|
season_id = Column(Integer, ForeignKey('seasons.id'))
|
||||||
season = relationship("Season", back_populates="episodes")
|
season = relationship("Season", back_populates="episodes")
|
||||||
|
|
||||||
events = relationship('Event', back_populates='episode')
|
events: List["Event"] = relationship('Event', back_populates='episode')
|
||||||
|
players = relationship("Player", secondary=player_episode, back_populates="episodes")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def playtime(self):
|
def playtime(self):
|
||||||
return util.timedelta(self.start, self.end)
|
return util.compute_timedelta(self.start, self.end)
|
||||||
|
|
||||||
|
def populate_from_form(self, form: "forms.EpisodeForm"):
|
||||||
|
self.code = str(form.code.data)
|
||||||
|
self.title = str(form.title.data)
|
||||||
|
self.date = form.date.data
|
||||||
|
self.start = form.start.data
|
||||||
|
self.end = form.end.data
|
||||||
|
|
||||||
|
|
||||||
class Event(Base):
|
class Event(Base):
|
||||||
__tablename__ = 'events'
|
__tablename__ = 'events'
|
||||||
|
|
||||||
id = Column(Integer, primary_key=True)
|
id = Column(Integer, primary_key=True)
|
||||||
type = Column(Enum(EventType))
|
type: EventType = Column(Enum(EventType))
|
||||||
time = Column(Time)
|
time = Column(Time)
|
||||||
comment = Column(String)
|
comment = Column(String)
|
||||||
|
|
||||||
@@ -127,7 +145,15 @@ class Event(Base):
|
|||||||
enemy_id = Column(Integer, ForeignKey('enemies.id'))
|
enemy_id = Column(Integer, ForeignKey('enemies.id'))
|
||||||
enemy = relationship('Enemy', back_populates='events')
|
enemy = relationship('Enemy', back_populates='events')
|
||||||
|
|
||||||
penalties = relationship('Penalty', back_populates='event')
|
penalties: List["Penalty"] = relationship('Penalty', back_populates='event')
|
||||||
|
|
||||||
|
def populate_from_form(self, form: "forms.EventForm"):
|
||||||
|
self.episode_id = int(form.episode_id.data)
|
||||||
|
self.type = EventType(form.event_type.data)
|
||||||
|
self.time = form.time.data
|
||||||
|
self.comment = str(form.comment.data) if form.comment.data else None
|
||||||
|
self.player_id = int(form.player.data) if form.player.data else None
|
||||||
|
self.enemy_id = int(form.enemy.data) if form.enemy.data else None
|
||||||
|
|
||||||
|
|
||||||
class Penalty(Base):
|
class Penalty(Base):
|
||||||
|
|||||||
@@ -34,23 +34,23 @@
|
|||||||
</li>
|
</li>
|
||||||
<li class="list-group-item">
|
<li class="list-group-item">
|
||||||
<span class="font-weight-bold">Start:</span>
|
<span class="font-weight-bold">Start:</span>
|
||||||
{{ model.episode.start|format_time }}
|
{{ model.episode.start|format_time or "Not started yet" }}
|
||||||
</li>
|
</li>
|
||||||
<li class="list-group-item">
|
<li class="list-group-item">
|
||||||
<span class="font-weight-bold">End:</span>
|
<span class="font-weight-bold">End:</span>
|
||||||
{{ model.episode.end|format_time }}
|
{{ model.episode.end|format_time or "Not ended yet"}}
|
||||||
</li>
|
</li>
|
||||||
<li class="list-group-item">
|
<li class="list-group-item">
|
||||||
<span class="font-weight-bold">Play Time:</span>
|
<span class="font-weight-bold">Play Time:</span>
|
||||||
{{ model.episode.playtime }}
|
{{ model.episode.playtime or 0 }} Hours
|
||||||
</li>
|
</li>
|
||||||
<li class="list-group-item">
|
<li class="list-group-item">
|
||||||
<span class="font-weight-bold">Enemies Defeated:</span>
|
<span class="font-weight-bold">Enemies Defeated:</span>
|
||||||
{{ model.events.victory_count }}
|
{{ 0 }}
|
||||||
</li>
|
</li>
|
||||||
<li class="list-group-item">
|
<li class="list-group-item">
|
||||||
<span class="font-weight-bold">Deaths:</span>
|
<span class="font-weight-bold">Deaths:</span>
|
||||||
{{ model.events.defeat_count }}
|
{{ model.deaths|length or 0}}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -88,46 +88,48 @@
|
|||||||
<!--endregion-->
|
<!--endregion-->
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
|
|
||||||
{% if model.events %}
|
<!--region Deaths Card-->
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header text-center">
|
<div class="card-header text-center">
|
||||||
Event List
|
Deaths
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
|
||||||
|
{% if model.deaths %}
|
||||||
|
|
||||||
<table class="table table-striped table-bordered">
|
<table class="table table-striped table-bordered">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col" class="col-sm-auto text-center">Time</th>
|
<th scope="col" class="col-xs-auto text-center">Time</th>
|
||||||
<th scope="col" class="col-sm-auto text-center">Type</th>
|
<th scope="col" class="col-xs text-center">Enemy</th>
|
||||||
<th scope="col" class="col-sm-auto text-center">Player</th>
|
<th scope="col" class="col-xs text-center">Player</th>
|
||||||
<th scope="col" class="col-sm-auto text-center">Enemy</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for entry in model.events.entries %}
|
{% for entry in model.deaths %}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="col-sm-auto text-center">{{ entry.time }}</td>
|
<td class="col-xs-auto text-center">{{ entry.time|format_time }}</td>
|
||||||
<td class="col-sm-auto text-center">{{ entry.type.name }}</td>
|
<td class="col-xs text-center">{{ entry.enemy.name }}</td>
|
||||||
<td class="col-sm-auto text-center">{{ entry.type.player_name }}</td>
|
<td class="col-xs text-center">{{ entry.player.name }}</td>
|
||||||
<td class="col-sm-auto text-center">{{ entry.type.enemy_name }}</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
|
||||||
|
<div class="alert alert-info">Nothing did happen yet</div>
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
|
||||||
<div class="card">
|
<!--endregion-->
|
||||||
<div class="card-header text-center">
|
|
||||||
Event List
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="alert alert-info">Nothing did happen yet</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -37,17 +37,19 @@ def timedelta_to_str(data: timedelta) -> str:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def timedelta(start: time, end: time) -> float:
|
def compute_timedelta(start: time, end: time) -> float:
|
||||||
startDateTime = datetime.combine(date.today(), start)
|
if not start or not end:
|
||||||
|
return 0
|
||||||
|
s = datetime.combine(date.today(), start)
|
||||||
# Check if the the end is still on the same day
|
# Check if the the end is still on the same day
|
||||||
if start.hour > end.hour:
|
if start.hour > end.hour:
|
||||||
base = date.today() + timedelta(days=1)
|
base = date.today() + timedelta(days=1)
|
||||||
else:
|
else:
|
||||||
base = date.today()
|
base = date.today()
|
||||||
endDateTime = datetime.combine(base, end)
|
e = datetime.combine(base, end)
|
||||||
difference = startDateTime - endDateTime
|
difference = s - e
|
||||||
difference_hours = difference.total_seconds() / 3600
|
difference_hours = difference.total_seconds() / 3600
|
||||||
return difference_hours
|
return abs(difference_hours)
|
||||||
|
|
||||||
|
|
||||||
def combine_datetime(date: datetime.date, time: datetime.time):
|
def combine_datetime(date: datetime.date, time: datetime.time):
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from flask import render_template, request, redirect
|
from flask import render_template, request, redirect, url_for
|
||||||
|
|
||||||
from estusshots import app
|
from estusshots import app
|
||||||
from estusshots import forms, models, orm
|
from estusshots import forms, models, orm
|
||||||
@@ -18,11 +18,12 @@ def enemy_list():
|
|||||||
|
|
||||||
@app.route("/enemy/new", methods=["GET"])
|
@app.route("/enemy/new", methods=["GET"])
|
||||||
@authorize
|
@authorize
|
||||||
def enemy_new(preselect_season=None):
|
def enemy_new():
|
||||||
form = forms.EnemyForm()
|
form = forms.EnemyForm()
|
||||||
|
|
||||||
if preselect_season:
|
if "preselect" in request.args:
|
||||||
form.season_id.default = preselect_season
|
form.season_id.process_data(request.args['preselect'])
|
||||||
|
form.is_boss.data = True
|
||||||
|
|
||||||
model = models.GenericFormModel(
|
model = models.GenericFormModel(
|
||||||
page_title="Enemies",
|
page_title="Enemies",
|
||||||
@@ -64,9 +65,8 @@ def enemy_edit(enemy_id: int):
|
|||||||
enemy.populate_from_form(form)
|
enemy.populate_from_form(form)
|
||||||
db.commit()
|
db.commit()
|
||||||
if form.submit_continue_button.data:
|
if form.submit_continue_button.data:
|
||||||
form.name.data = None
|
return redirect(url_for("enemy_new", preselect=form.season_id.data))
|
||||||
return enemy_new(preselect_season=enemy.season_id)
|
return redirect(url_for("enemy_list"))
|
||||||
return redirect("/enemy")
|
|
||||||
|
|
||||||
model.form_title = "Incorrect Data"
|
model.form_title = "Incorrect Data"
|
||||||
return render_template("generic_form.html", model=model, form=form)
|
return render_template("generic_form.html", model=model, form=form)
|
||||||
|
|||||||
@@ -1,45 +1,24 @@
|
|||||||
from typing import List
|
from flask import render_template, request, redirect, url_for
|
||||||
|
|
||||||
from flask import render_template, request, redirect
|
|
||||||
|
|
||||||
from estusshots import app
|
from estusshots import app
|
||||||
from estusshots import forms, models, db
|
from estusshots import forms, models, orm
|
||||||
from estusshots.util import authorize
|
from estusshots.util import authorize
|
||||||
|
from estusshots.orm import Season, Episode, Player, Event
|
||||||
|
|
||||||
|
|
||||||
@app.route("/season/<season_id>/episode/<episode_id>")
|
@app.route("/season/<season_id>/episode/<episode_id>")
|
||||||
@authorize
|
@authorize
|
||||||
def episode_detail(season_id: int, episode_id: int):
|
def episode_detail(season_id: int, episode_id: int):
|
||||||
sql, args = db.load_season(season_id)
|
db = orm.new_session()
|
||||||
season = db.query_db(sql, args, one=True, cls=models.Season)
|
episode: Episode = db.query(Episode).get(episode_id)
|
||||||
sql, args = db.load_episode(episode_id)
|
deaths = [event for event in episode.events if event.type == orm.EventType.Death]
|
||||||
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 = {
|
model = {
|
||||||
"title": f"{season.code}{episode.code}",
|
"title": f"{episode.season.code}{episode.code}",
|
||||||
"episode": episode,
|
"episode": episode,
|
||||||
"season": season,
|
"season": episode.season,
|
||||||
"players": ep_players,
|
"players": episode.players,
|
||||||
"events": events,
|
"deaths": sorted(deaths, key=lambda x: x.time),
|
||||||
}
|
}
|
||||||
|
|
||||||
return render_template("episode_details.html", model=model)
|
return render_template("episode_details.html", model=model)
|
||||||
@@ -48,12 +27,9 @@ def episode_detail(season_id: int, episode_id: int):
|
|||||||
@app.route("/season/<season_id>/episode", methods=["GET"])
|
@app.route("/season/<season_id>/episode", methods=["GET"])
|
||||||
@authorize
|
@authorize
|
||||||
def episode_list(season_id: int):
|
def episode_list(season_id: int):
|
||||||
sql, args = db.load_season(season_id)
|
db = orm.new_session()
|
||||||
season = db.query_db(sql, args, one=True, cls=models.Season)
|
season = db.query(Season).filter(Season.id == season_id).first()
|
||||||
sql, args = db.load_episodes(season_id)
|
model = {"season_id": season.id, "season_code": season.code}
|
||||||
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)
|
return render_template("episode_list.html", model=model)
|
||||||
|
|
||||||
|
|
||||||
@@ -65,7 +41,6 @@ def episode_new(season_id: int):
|
|||||||
form_title="Create New Episode",
|
form_title="Create New Episode",
|
||||||
post_url=f"/season/{season_id}/episode/null/edit",
|
post_url=f"/season/{season_id}/episode/null/edit",
|
||||||
)
|
)
|
||||||
|
|
||||||
form = forms.EpisodeForm(request.form)
|
form = forms.EpisodeForm(request.form)
|
||||||
form.season_id.data = season_id
|
form.season_id.data = season_id
|
||||||
return render_template("generic_form.html", model=model, form=form)
|
return render_template("generic_form.html", model=model, form=form)
|
||||||
@@ -79,15 +54,10 @@ def episode_edit(season_id: int, episode_id: int):
|
|||||||
form_title="Edit Episode",
|
form_title="Edit Episode",
|
||||||
post_url=f"/season/{season_id}/episode/{episode_id}/edit",
|
post_url=f"/season/{season_id}/episode/{episode_id}/edit",
|
||||||
)
|
)
|
||||||
|
form = forms.EpisodeForm()
|
||||||
|
db = orm.new_session()
|
||||||
|
episode: Episode = db.query(Episode).get(episode_id)
|
||||||
if request.method == "GET":
|
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.season_id.data = episode.season_id
|
||||||
form.episode_id.data = episode.id
|
form.episode_id.data = episode.id
|
||||||
form.code.data = episode.code
|
form.code.data = episode.code
|
||||||
@@ -95,43 +65,24 @@ def episode_edit(season_id: int, episode_id: int):
|
|||||||
form.start.data = episode.start
|
form.start.data = episode.start
|
||||||
form.end.data = episode.end
|
form.end.data = episode.end
|
||||||
form.title.data = episode.title
|
form.title.data = episode.title
|
||||||
form.players.data = [p.id for p in ep_players]
|
form.players.data = [p.id for p in episode.players]
|
||||||
|
|
||||||
model.form_title = f"Edit Episode '{episode.code}: {episode.title}'"
|
model.form_title = f"Edit Episode '{episode.code}: {episode.title}'"
|
||||||
return render_template("generic_form.html", model=model, form=form)
|
return render_template("generic_form.html", model=model, form=form)
|
||||||
else:
|
else:
|
||||||
form = forms.EpisodeForm()
|
|
||||||
|
|
||||||
if not form.validate_on_submit():
|
if not form.validate_on_submit():
|
||||||
model.errors = form.errors
|
model.errors = form.errors
|
||||||
return render_template("generic_form.html", model=model, form=form)
|
return render_template("generic_form.html", model=model, form=form)
|
||||||
|
if not episode:
|
||||||
errors = False
|
episode = Episode()
|
||||||
episode = models.Episode.from_form(form)
|
db.add(episode)
|
||||||
sql, args = db.save_episode(episode)
|
season: Season = db.query(Season).get(season_id)
|
||||||
|
episode.populate_from_form(form)
|
||||||
last_key = db.update_db(sql, args, return_key=True)
|
episode.season = season
|
||||||
|
player_ids = list(form.players.data)
|
||||||
episode_id = episode.id if episode.id else last_key
|
players = db.query(Player).filter(Player.id.in_(player_ids)).all()
|
||||||
|
episode.players = players
|
||||||
form_ids = form.players.data
|
errors = db.commit()
|
||||||
|
|
||||||
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:
|
if errors:
|
||||||
model.errors = {"Error saving episode": [errors]}
|
model.errors = {"Error saving episode": [errors]}
|
||||||
return render_template("generic_form.html", model=model, form=form)
|
return render_template("generic_form.html", model=model, form=form)
|
||||||
return redirect(url_for("season_overview", season_id=season_id))
|
return redirect(url_for("episode_detail", season_id=season_id, episode_id=episode_id))
|
||||||
|
|||||||
@@ -2,9 +2,10 @@ from collections import namedtuple
|
|||||||
|
|
||||||
from flask import render_template, request, redirect
|
from flask import render_template, request, redirect
|
||||||
|
|
||||||
from estusshots import app
|
from estusshots import app, orm
|
||||||
from estusshots import forms, models, db, choices
|
from estusshots import forms, models, choices
|
||||||
from estusshots.util import authorize
|
from estusshots.util import authorize
|
||||||
|
from estusshots.orm import new_session, EventType, Event, Episode, Enemy, Penalty
|
||||||
|
|
||||||
|
|
||||||
@app.route("/season/<s_id>/episode/<ep_id>/event/new", methods=["GET"])
|
@app.route("/season/<s_id>/episode/<ep_id>/event/new", methods=["GET"])
|
||||||
@@ -15,19 +16,16 @@ def event_new(s_id: int, ep_id: int):
|
|||||||
"form_title": "Create New Event",
|
"form_title": "Create New Event",
|
||||||
"post_url": f"/season/{s_id}/episode/{ep_id}/event/null/edit",
|
"post_url": f"/season/{s_id}/episode/{ep_id}/event/null/edit",
|
||||||
}
|
}
|
||||||
sql, args = db.load_episode(ep_id)
|
db = new_session()
|
||||||
episode: models.Episode = db.query_db(sql, args, one=True, cls=models.Episode)
|
episode: Episode = db.query(Episode).get(ep_id)
|
||||||
|
|
||||||
sql, args = db.load_episode_players(ep_id)
|
|
||||||
ep_players = db.query_db(sql, args, cls=models.Player)
|
|
||||||
|
|
||||||
form = forms.EventForm()
|
form = forms.EventForm()
|
||||||
form.episode_id.data = ep_id
|
form.episode_id.data = ep_id
|
||||||
form.enemy.choices = choices.enemy_choice_for_season(s_id)
|
form.enemy.choices = choices.enemy_choice_for_season(s_id)
|
||||||
form.event_type.data = 1
|
form.event_type.data = EventType.Death.value
|
||||||
|
|
||||||
Penalty = namedtuple("Penalty", ["penalty_id", "player_id", "player", "drink"])
|
Penalty = namedtuple("Penalty", ["penalty_id", "player_id", "player", "drink"])
|
||||||
for player in ep_players:
|
for player in episode.players:
|
||||||
form.penalties.append_entry(Penalty(None, player.id, player.name, 1))
|
form.penalties.append_entry(Penalty(None, player.id, player.name, 1))
|
||||||
|
|
||||||
return render_template("event_editor.html", model=model, form=form)
|
return render_template("event_editor.html", model=model, form=form)
|
||||||
@@ -41,16 +39,43 @@ def event_edit(s_id: int, ep_id: int, ev_id: int):
|
|||||||
"form_title": "Edit Event",
|
"form_title": "Edit Event",
|
||||||
"post_url": f"/season/{s_id}/episode/{ep_id}/event/{ev_id}/edit",
|
"post_url": f"/season/{s_id}/episode/{ep_id}/event/{ev_id}/edit",
|
||||||
}
|
}
|
||||||
|
db = new_session()
|
||||||
|
event: Event = db.query(Event).get(ev_id)
|
||||||
|
form = forms.EventForm()
|
||||||
|
form.enemy.choices = choices.enemy_choice_for_season(s_id)
|
||||||
|
|
||||||
if request.method == "GET":
|
if request.method == "GET":
|
||||||
|
form.episode_id.process_data(event.episode_id)
|
||||||
|
form.event_type.process_data(event.type.value)
|
||||||
|
form.enemy.process_data(event.enemy_id)
|
||||||
|
form.player.process_data(event.player_id)
|
||||||
|
form.time.process_data(event.time)
|
||||||
|
form.comment.process_data(event.comment)
|
||||||
|
Penalty = namedtuple("Penalty", ["penalty_id", "player_id", "player", "drink"])
|
||||||
|
for penalty in event.penalties:
|
||||||
|
form.penalties.append_entry(Penalty(penalty.id, penalty.player_id, penalty.player.name, penalty.drink_id))
|
||||||
return render_template("event_editor.html", model=model)
|
return render_template("event_editor.html", model=model)
|
||||||
else:
|
else:
|
||||||
form = forms.EventForm()
|
|
||||||
form.enemy.choices = choices.enemy_choice_for_season(s_id)
|
|
||||||
if not form.validate_on_submit():
|
if not form.validate_on_submit():
|
||||||
model["errors"] = form.errors
|
model["errors"] = form.errors
|
||||||
return render_template("event_editor.html", model=model, form=form)
|
return render_template("event_editor.html", model=model, form=form)
|
||||||
|
if not event:
|
||||||
|
event = Event()
|
||||||
|
for entry in form.penalties:
|
||||||
|
penalty = orm.Penalty()
|
||||||
|
penalty.player_id = entry.player_id.data
|
||||||
|
penalty.drink_id = entry.drink.data
|
||||||
|
db.add(penalty)
|
||||||
|
event.penalties.append(penalty)
|
||||||
|
db.add(event)
|
||||||
|
else:
|
||||||
|
for event in event.penalties:
|
||||||
|
penalty = next((p for p in form.penalties.data if p["penalty_id"] == event.id), None)
|
||||||
|
if not penalty:
|
||||||
|
continue
|
||||||
|
penalty.player_id = form.player_id.data
|
||||||
|
penalty.drink_id = form.drink.data
|
||||||
|
|
||||||
event = models.Event.from_form(form)
|
event.populate_from_form(form)
|
||||||
sql, args = db.save_event(event)
|
db.commit()
|
||||||
errors = db.update_db(sql, args)
|
|
||||||
return redirect(f"/season/{s_id}/episode/{ep_id}")
|
return redirect(f"/season/{s_id}/episode/{ep_id}")
|
||||||
|
|||||||
Reference in New Issue
Block a user