add past and future availabilities to gamecard
This commit is contained in:
@@ -276,6 +276,7 @@ INSTALLED_APPS += [
|
||||
"teamsnap",
|
||||
"instagen",
|
||||
"gamecard",
|
||||
"gamechanger",
|
||||
"teamsnap.lineup",
|
||||
"teamsnap.dashboard",
|
||||
]
|
||||
|
||||
@@ -1,191 +1,240 @@
|
||||
{% load static %}
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.2/font/bootstrap-icons.css">
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" href="{% static 'css/gamecard.css' %}">
|
||||
<title>Title</title>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" href="{% static 'css/gamecard.css' %}">
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body class="b5">
|
||||
<section class="sheet">
|
||||
<div class="whole-card">
|
||||
<div class="half-card">
|
||||
<div class="content card-left">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="8" class="gametitle">
|
||||
{{ event.data.formatted_title }} {{ event.data.start_date|date:'m/d/Y g:i A' }}
|
||||
{# G#01 at Browns 05/01/2021 12:30 PM#}
|
||||
</th>
|
||||
<th class="homeaway" colspan="4">{{ event.data.game_type }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="numbercell">
|
||||
</th>
|
||||
<th class="customcol">
|
||||
</th>
|
||||
<th class="numbercell">
|
||||
</th>
|
||||
<th class="numbercell">
|
||||
</th>
|
||||
<th class="numbercell">1
|
||||
</th>
|
||||
<th class="numbercell">2
|
||||
</th>
|
||||
<th class="numbercell">3
|
||||
</th>
|
||||
<th class="numbercell">4
|
||||
</th>
|
||||
<th class="numbercell">5
|
||||
</th>
|
||||
<th class="numbercell">6
|
||||
</th>
|
||||
<th class="numbercell">7
|
||||
</th>
|
||||
<th class="numbercell">X
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for member in members_startinglineup %}
|
||||
<tr>
|
||||
<td class="numbercell">{{ member.lineup_entry.sequence | add:"1" }}</td>
|
||||
<td class="customcol">{{ member.member.last_name }}</td>
|
||||
<td class="numbercell">{{ member.member.jersey_number }}</td>
|
||||
<td class="numbercell">{{ member.lineup_entry.label }}</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<table>
|
||||
<tbody>
|
||||
{% for member in members_startingpositiononly %}
|
||||
<tr>
|
||||
<td class="numbercell"></td>
|
||||
<td class="customcol">{{ member.member.last_name }}</td>
|
||||
<td class="numbercell">{{ member.member.jersey_number }}</td>
|
||||
<td class="numbercell">{{ member.lineup_entry.label }}</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="half-card">
|
||||
<div class="content card-right">
|
||||
<table class="tg">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="numbercell"></th>
|
||||
<th class="numbercell"></th>
|
||||
<th class="condensedNameCell">Available</th>
|
||||
<th class="statscell">AVG/OBP/SLG:PA</th>
|
||||
<th class="numbercell"></th>
|
||||
<th class="numbercell"></th>
|
||||
<th class="numbercell"></th>
|
||||
<th class="numbercell"></th>
|
||||
<th class="numbercell"></th>
|
||||
<th class="numbercell"></th>
|
||||
<th class="numbercell"></th>
|
||||
<th class="numbercell"></th>
|
||||
<th class="numbercell"></th>
|
||||
<th class="numbercell"></th>
|
||||
<th class="numbercell"></th>
|
||||
<th class="numbercell"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for member in members %}
|
||||
<tr>
|
||||
<td class="numbercell"></td>
|
||||
<td class="numbercell available-status-code-{{ member.availability.status_code }}">{{ member.member.jersey_number }}</td>
|
||||
<td class="condensedNameCell available-status-code-{{ member.availability.status_code }}">{{ member.member.last_name }}</td>
|
||||
<td class="statscell"></td>
|
||||
<td class="numbercell"></td>
|
||||
<td class="numbercell"></td>
|
||||
<td class="numbercell"></td>
|
||||
<td class="numbercell"></td>
|
||||
<td class="numbercell"></td>
|
||||
<td class="numbercell"></td>
|
||||
<td class="numbercell"></td>
|
||||
<td class="numbercell"></td>
|
||||
<td class="numbercell"></td>
|
||||
<td class="numbercell"></td>
|
||||
<td class="numbercell"></td>
|
||||
<td class="numbercell"></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="whole-card">
|
||||
<div class="half-card">
|
||||
<div class="content card-left">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="8" class="gametitle">
|
||||
{{ event.data.formatted_title }} {{ event.data.start_date|date:'m/d/Y g:i A' }}
|
||||
{# G#01 at Browns 05/01/2021 12:30 PM#}
|
||||
</th>
|
||||
<th class="homeaway" colspan="4">{{ event.data.game_type }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="numbercell">
|
||||
</th>
|
||||
<th class="customcol">
|
||||
</th>
|
||||
<th class="numbercell">
|
||||
</th>
|
||||
<th class="numbercell">
|
||||
</th>
|
||||
<th class="numbercell">1
|
||||
</th>
|
||||
<th class="numbercell">2
|
||||
</th>
|
||||
<th class="numbercell">3
|
||||
</th>
|
||||
<th class="numbercell">4
|
||||
</th>
|
||||
<th class="numbercell">5
|
||||
</th>
|
||||
<th class="numbercell">6
|
||||
</th>
|
||||
<th class="numbercell">7
|
||||
</th>
|
||||
<th class="numbercell">X
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for member in members_startinglineup %}
|
||||
<tr>
|
||||
<td class="numbercell">{{ member.lineup_entry.sequence | add:"1" }}</td>
|
||||
<td class="customcol">{{ member.member.last_name }}</td>
|
||||
<td class="numbercell">{{ member.member.jersey_number }}</td>
|
||||
<td class="numbercell">{{ member.lineup_entry.label }}</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<table>
|
||||
<tbody>
|
||||
{% for member in members_startingpositiononly %}
|
||||
<tr>
|
||||
<td class="numbercell"></td>
|
||||
<td class="customcol">{{ member.member.last_name }}</td>
|
||||
<td class="numbercell">{{ member.member.jersey_number }}</td>
|
||||
<td class="numbercell">{{ member.lineup_entry.label }}</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="whole-card">
|
||||
<div class="half-card">
|
||||
<div class="content card-left"></div>
|
||||
</div>
|
||||
<div class="half-card">
|
||||
<div class="content card-right">
|
||||
<div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="numbercell" style="background-color: #323669">
|
||||
{{ event.data.start_date|date:"D, F j, Y g:i A" }}
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="numbercell" style="background-color: #323669">
|
||||
{{ event.data.location_name }}
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="numbercell" style="background-color: lightgray">
|
||||
<div class="half-card">
|
||||
<div class="content card-right">
|
||||
<table class="tg">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="numbercell"></th>
|
||||
<th class="numbercell"></th>
|
||||
<th class="condensedNameCell">Available</th>
|
||||
<th class="statscell">AVG/OBP/SLG:PA</th>
|
||||
<th class="numbercell">P</th>
|
||||
<th class="numbercell">C</th>
|
||||
<th class="numbercell">IF</th>
|
||||
<th class="numbercell">OF</th>
|
||||
{% for event in events_future %}
|
||||
<th class="numbercell">
|
||||
<span style="transform: rotate(-90deg);display: inline-block">
|
||||
{{ event.data.start_date|date:'D' }}
|
||||
</span>
|
||||
</th>
|
||||
{% endfor %}
|
||||
{% for event in events_past %}
|
||||
<th class="numbercell">
|
||||
<span style="transform: rotate(-90deg);display: inline-block">
|
||||
{{ event.data.start_date|date:'D' }}
|
||||
</span>
|
||||
</th>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for member in members %}
|
||||
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
<div>
|
||||
<div class="" width="100%">
|
||||
<img src="{{ ts_team.logo.url }}"
|
||||
height="120px"
|
||||
>
|
||||
</div>
|
||||
<div class="" width="100%" style="text-align: center;font-size: xxx-large; font-family: Pacifico">
|
||||
VS.
|
||||
</div>
|
||||
<div class="" width="100%" style="text-align: right">
|
||||
<img src="{{ ts_opponent.logo.url }}"
|
||||
width="120px"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<tr>
|
||||
<td class="numbercell"></td>
|
||||
<td class="numbercell available-status-code-{{ member.availability.status_code }}">{{ member.member.jersey_number }}</td>
|
||||
<td class="condensedNameCell available-status-code-{{ member.availability.status_code }}">{{ member.member.last_name }}</td>
|
||||
<td class="statscell"></td>
|
||||
<td class="numbercell">
|
||||
{% if "P" in member.member.position %}
|
||||
<i class="bi bi-check-square-fill"></i>
|
||||
{% else %}
|
||||
<i class="bi bi-square"></i>
|
||||
{% endif %}
|
||||
<td class="numbercell">
|
||||
{% if "C" in member.member.position %}
|
||||
<i class="bi bi-check-square-fill"></i>
|
||||
{% else %}
|
||||
<i class="bi bi-square"></i>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="numbercell">
|
||||
{% if "IF" in member.member.position or "1B" in member.member.position %}
|
||||
<i class="bi bi-check-square-fill"></i>
|
||||
{% else %}
|
||||
<i class="bi bi-square"></i>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="numbercell">
|
||||
{% if "OF" in member.member.position %}
|
||||
<i class="bi bi-check-square-fill"></i>
|
||||
{% else %}
|
||||
<i class="bi bi-square"></i>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="numbercell available-status-code-{{ member.availability_future.0.data.status_code }}">
|
||||
{{ member.availability_future.0.data.status.0 }}
|
||||
</td>
|
||||
<td class="numbercell available-status-code-{{ member.availability_future.1.data.status_code }}">
|
||||
{{ member.availability_future.1.data.status.0 }}
|
||||
</td>
|
||||
<td class="numbercell available-status-code-{{ member.availability_future.2.data.status_code }}">
|
||||
{{ member.availability_future.2.data.status.0 }}
|
||||
</td>
|
||||
<td class="numbercell available-status-code-{{ member.availability_future.3.data.status_code }}">
|
||||
{{ member.availability_future.3.data.status.0 }}
|
||||
</td>
|
||||
<td class="numbercell available-status-code-{{ member.availability_past.0.data.status_code }}">
|
||||
{{ member.availability_past.0.data.status.0 }}
|
||||
</td>
|
||||
<td class="numbercell available-status-code-{{ member.availability_past.1.data.status_code }}">
|
||||
{{ member.availability_past.1.data.status.0 }}
|
||||
</td>
|
||||
<td class="numbercell available-status-code-{{ member.availability_past.2.data.status_code }}">
|
||||
{{ member.availability_past.2.data.status.0 }}
|
||||
</td>
|
||||
<td class="numbercell available-status-code-{{ member.availability_past.3.data.status_code }}">
|
||||
{{ member.availability_past.3.data.status.0 }}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="whole-card">
|
||||
<div class="half-card">
|
||||
<div class="content card-left"></div>
|
||||
</div>
|
||||
<div class="half-card">
|
||||
<div class="content card-right">
|
||||
<div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="numbercell" style="background-color: #323669">
|
||||
{{ event.data.start_date|date:"D, F j, Y g:i A" }}
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="numbercell" style="background-color: #323669">
|
||||
{{ event.data.location_name }}
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="numbercell" style="background-color: lightgray">
|
||||
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
<div>
|
||||
<div class="" width="100%">
|
||||
<img src="{{ ts_team.logo.url }}"
|
||||
height="120px"
|
||||
>
|
||||
</div>
|
||||
<div class="" width="100%" style="text-align: center;font-size: xxx-large; font-family: Pacifico">
|
||||
VS.
|
||||
</div>
|
||||
<div class="" width="100%" style="text-align: right">
|
||||
{% if ts_opponent %}
|
||||
<img src="{{ ts_opponent.logo.url }}"
|
||||
width="120px"
|
||||
>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
# TODO Remove VCR
|
||||
import vcr
|
||||
from django.shortcuts import render
|
||||
|
||||
from teamsnap.models import Opponent, Team
|
||||
from teamsnap.utils import get_teamsnap_client
|
||||
|
||||
|
||||
@vcr.use_cassette("gamecard/fixtures/gamecard.yaml", record_mode="new_episodes")
|
||||
def gamecard(request, team_id, event_id):
|
||||
import re
|
||||
|
||||
@@ -20,13 +23,28 @@ def gamecard(request, team_id, event_id):
|
||||
ts_bulkload = client.bulk_load(
|
||||
team_id=team_id,
|
||||
types=[Event, EventLineup, EventLineupEntry, AvailabilitySummary, Member],
|
||||
event__id=event_id,
|
||||
)
|
||||
|
||||
ts_event = [
|
||||
i for i in ts_bulkload if isinstance(i, Event) and i.data["id"] == event_id
|
||||
][0]
|
||||
ts_availabilities = Availability.search(client, event_id=ts_event.data["id"])
|
||||
ts_events = [e for e in ts_bulkload if isinstance(e, Event)]
|
||||
ts_events.sort(key=lambda d: d.data.get("start_date"))
|
||||
ts_event = [e for e in ts_events if e.data["id"] == event_id][0]
|
||||
ts_events_future = ts_events[ts_events.index(ts_event) + 1 :]
|
||||
ts_events_past = ts_events[: ts_events.index(ts_event)]
|
||||
|
||||
ts_availabilities = Availability.search(client, team_id=team_id)
|
||||
|
||||
ts_availabilities_future = list(
|
||||
filter(
|
||||
lambda a: a.data["event_id"] in [e.data["id"] for e in ts_events_future],
|
||||
ts_availabilities,
|
||||
)
|
||||
)
|
||||
ts_availabilities_past = list(
|
||||
filter(
|
||||
lambda a: a.data["event_id"] in [e.data["id"] for e in ts_events_past],
|
||||
ts_availabilities,
|
||||
)
|
||||
)
|
||||
|
||||
ts_lineup_entries = EventLineupEntry.search(client, event_id=event_id)
|
||||
|
||||
@@ -41,7 +59,7 @@ def gamecard(request, team_id, event_id):
|
||||
|
||||
ts_members = [i for i in ts_bulkload if isinstance(i, Member)]
|
||||
# ts_member_lookup = {m.data["id"]: m for m in ts_members}
|
||||
ts_availability_lookup = {m.data["member_id"]: m for m in ts_availabilities}
|
||||
ts_availability_lookup = {m.data["id"]: m for m in ts_availabilities}
|
||||
ts_lineup_entries_lookup = {m.data["member_id"]: m for m in ts_lineup_entries}
|
||||
|
||||
members = []
|
||||
@@ -52,11 +70,27 @@ def gamecard(request, team_id, event_id):
|
||||
{
|
||||
"member": getattr(member, "data"),
|
||||
"availability": getattr(
|
||||
ts_availability_lookup.get(member.data["id"], {}), "data", {}
|
||||
ts_availability_lookup.get(
|
||||
f"{member.data['id']}-{event_id}", {}
|
||||
),
|
||||
"data",
|
||||
{},
|
||||
),
|
||||
"lineup_entry": getattr(
|
||||
ts_lineup_entries_lookup.get(member.data["id"], {}), "data", {}
|
||||
),
|
||||
"availability_future": list(
|
||||
filter(
|
||||
lambda a: a.data.get("member_id") == member.data["id"],
|
||||
ts_availabilities_future,
|
||||
)
|
||||
)[:4],
|
||||
"availability_past": list(
|
||||
filter(
|
||||
lambda a: a.data.get("member_id") == member.data["id"],
|
||||
ts_availabilities_past,
|
||||
)
|
||||
)[:4],
|
||||
}
|
||||
)
|
||||
|
||||
@@ -100,10 +134,12 @@ def gamecard(request, team_id, event_id):
|
||||
|
||||
context = {
|
||||
"event": ts_event,
|
||||
"events_future": ts_events_future[:4],
|
||||
"events_past": list(reversed(ts_events_past))[:4],
|
||||
"members": members,
|
||||
"members_startinglineup": members_startinglineup,
|
||||
"members_startingpositiononly": members_startingpositiononly,
|
||||
"ts_team": Team.objects.get(id=team_id),
|
||||
"ts_opponent": Opponent.objects.get(id=ts_event.data["opponent_id"]),
|
||||
"ts_opponent": Opponent.objects.filter(id=ts_event.data["opponent_id"]).first,
|
||||
}
|
||||
return render(request, "gamecard/gamecard.html", context=context)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[flake8]
|
||||
max-line-length = 120
|
||||
exclude = .tox,.git,*/migrations/*,*/static/CACHE/*,docs,node_modules,venv
|
||||
ignore = W503
|
||||
ignore = W503, E203
|
||||
|
||||
[pycodestyle]
|
||||
max-line-length = 120
|
||||
|
||||
@@ -8,7 +8,8 @@ from teamsnap.views import get_teamsnap_client
|
||||
def dashboard(request, team_id=None):
|
||||
if not team_id:
|
||||
return redirect(
|
||||
"teamsnap_dashboard", team_id=request.user.preferences.managed_team_id
|
||||
"teamsnap_dashboard",
|
||||
team_id=request.user.teamsnap_preferences.managed_team_id,
|
||||
)
|
||||
|
||||
from pyteamsnap.api import AvailabilitySummary, Event
|
||||
|
||||
Reference in New Issue
Block a user