split gamecard into its own app, add models to teamsnap for custom fields (images)

This commit is contained in:
2022-06-09 07:46:53 -05:00
parent aa897f6f49
commit abdab2d30b
56 changed files with 273 additions and 58 deletions

View File

@@ -272,5 +272,6 @@ SOCIALACCOUNT_FORMS = {"signup": "benchcoach.users.forms.UserSocialSignupForm"}
# Your stuff...
# ------------------------------------------------------------------------------
INSTALLED_APPS += ["teamsnap", "instagen"]
INSTALLED_APPS += ["teamsnap", "instagen", "gamecard"]
SOCIALACCOUNT_PROVIDERS = {"teamsnap": {"SCOPE": ["read", "write"]}}

View File

@@ -17,6 +17,7 @@ urlpatterns = [
path("accounts/", include("allauth.urls")),
path("", include("teamsnap.urls")),
path("", include("instagen.urls")),
path("", include("gamecard.urls")),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

0
gamecard/__init__.py Normal file
View File

6
gamecard/apps.py Normal file
View File

@@ -0,0 +1,6 @@
from django.apps import AppConfig
class GamecardConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "gamecard"

View File

View File

@@ -49,4 +49,4 @@ body.legal.landscape .sheet { width: 357mm; height: 215mm }
body.letter, body.legal { width: 216mm }
body.letter.landscape { width: 280mm }
body.legal.landscape { width: 357mm }
}
}

View File

@@ -169,7 +169,7 @@
</table>
<div>
<div class="" width="100%">
<img src="{% static 'teamsnap/ig/logos/hounds.png' %}"
<img src="{{ ts_team.logo.url }}"
height="120px"
>
</div>
@@ -177,7 +177,7 @@
VS.
</div>
<div class="" width="100%" style="text-align: right">
<img src="{% static 'teamsnap/ig/logos/hounds.png' %}"
<img src="{{ ts_opponent.logo.url }}"
width="120px"
>
</div>

3
gamecard/tests.py Normal file
View File

@@ -0,0 +1,3 @@
# from django.test import TestCase
# Create your tests here.

7
gamecard/urls.py Normal file
View File

@@ -0,0 +1,7 @@
from django.urls import path
from .views import gamecard
urlpatterns = [
path("<int:team_id>/event/<int:event_id>/gamecard/", gamecard, name="gamecard")
]

View File

109
gamecard/views.py Normal file
View File

@@ -0,0 +1,109 @@
from django.shortcuts import render
from teamsnap.models import Opponent, Team
from teamsnap.utils import get_teamsnap_client
def gamecard(request, team_id, event_id):
import re
from pyteamsnap.api import (
Availability,
AvailabilitySummary,
Event,
EventLineup,
EventLineupEntry,
Member,
)
client = get_teamsnap_client(request)
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_lineup_entries = EventLineupEntry.search(client, event_id=event_id)
if ts_lineup_entries:
# ts_lineup = EventLineup.get(
# client, id=ts_lineup_entries[0].data["event_lineup_id"]
# )
pass
else:
# ts_lineup = EventLineup.search(client, event_id=event_id)
pass
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_lineup_entries_lookup = {m.data["member_id"]: m for m in ts_lineup_entries}
members = []
for member in ts_members:
if not member.data["is_non_player"]:
members.append(
{
"member": getattr(member, "data"),
"availability": getattr(
ts_availability_lookup.get(member.data["id"], {}), "data", {}
),
"lineup_entry": getattr(
ts_lineup_entries_lookup.get(member.data["id"], {}), "data", {}
),
}
)
members = sorted(
members,
key=lambda d: (
{None: 3, 0: 2, 2: 1, 1: 0}.get( # No Response # No # Maybe # Yes
d["availability"].get("status_code")
),
d["member"].get("last_name"),
),
)
members_startinglineup = []
members_startingpositiononly = []
for member in members:
if re.search(
r"([A-Z0-9]+)(?:\s+\[(.*)\])?", member["lineup_entry"].get("label", "")
):
position, position_note = re.search(
r"([A-Z0-9]+)(?:\s+\[(.*)\])?", member["lineup_entry"].get("label", "")
).groups()
else:
position, position_note = ("", "")
position_only = position_note == "PO"
if position_only:
member["lineup_entry"]["label"] = position
if member["lineup_entry"].get("id") and not position_only:
members_startinglineup.append(member)
elif member["lineup_entry"].get("id") and position_only:
members_startingpositiononly.append(member)
members_startinglineup = sorted(
members_startinglineup,
key=lambda d: d.get("lineup_entry", {}).get("sequence", 100),
)
context = {
"event": ts_event,
"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"]),
}
return render(request, "gamecard/gamecard.html", context=context)

View File

@@ -1,6 +1,8 @@
from django.contrib import admin
from .models import Preferences
from .models import Opponent, Preferences, Team
# Register your models here.
admin.site.register(Preferences)
admin.site.register(Team)
admin.site.register(Opponent)

View File

@@ -1,4 +1,4 @@
# Generated by Django 3.2.13 on 2022-06-02 13:20
# Generated by Django 3.2.13 on 2022-06-09 12:09
from django.conf import settings
from django.db import migrations, models
@@ -14,6 +14,14 @@ class Migration(migrations.Migration):
]
operations = [
migrations.CreateModel(
name='Team',
fields=[
('id', models.IntegerField(primary_key=True, serialize=False)),
('logo', models.ImageField(upload_to='logos')),
('logo_mono', models.ImageField(upload_to='logos_mono')),
],
),
migrations.CreateModel(
name="Preferences",
fields=[

View File

@@ -0,0 +1,33 @@
# Generated by Django 3.2.13 on 2022-06-09 12:22
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('teamsnap', '0003_auto_20220609_0721'),
]
operations = [
migrations.AlterField(
model_name='opponent',
name='logo',
field=models.ImageField(blank=True, null=True, upload_to='logos'),
),
migrations.AlterField(
model_name='opponent',
name='logo_mono',
field=models.ImageField(blank=True, null=True, upload_to='logos_mono'),
),
migrations.AlterField(
model_name='team',
name='logo',
field=models.ImageField(blank=True, null=True, upload_to='logos'),
),
migrations.AlterField(
model_name='team',
name='logo_mono',
field=models.ImageField(blank=True, null=True, upload_to='logos_mono'),
),
]

View File

View File

@@ -7,3 +7,43 @@ from benchcoach.users.models import User
class Preferences(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
managed_team_id = models.IntegerField()
class Team(models.Model):
id = models.IntegerField(primary_key=True)
logo = models.ImageField(
upload_to="logos",
height_field=None,
width_field=None,
max_length=100,
null=True,
blank=True,
)
logo_mono = models.ImageField(
upload_to="logos_mono",
height_field=None,
width_field=None,
max_length=100,
null=True,
blank=True,
)
class Opponent(models.Model):
id = models.IntegerField(primary_key=True)
logo = models.ImageField(
upload_to="logos",
height_field=None,
width_field=None,
max_length=100,
null=True,
blank=True,
)
logo_mono = models.ImageField(
upload_to="logos_mono",
height_field=None,
width_field=None,
max_length=100,
null=True,
blank=True,
)

View File

@@ -34,7 +34,12 @@
<h6 class="text-muted mb-2">{{ event.data.location_name }}</h6>
</div>
<div class="d-flex">
<a class="btn btn-primary btn-sm mx-1" role="button" href="{% url 'teamsnap_edit_lineup' event_ids=event.data.id team_id=event.data.team_id %}">Go to Lineup</a>
<a class="btn btn-primary btn-sm mx-1" role="button" href="{% url 'teamsnap_edit_lineup' event_ids=event.data.id team_id=event.data.team_id %}">
Go to Lineup
</a>
<a class="btn btn-primary btn-sm mx-1" role="button" href="{% url 'gamecard' event_id=event.data.id team_id=event.data.team_id %}">
<i class="bi bi-book"></i>
</a>
<form method="get"
action="{% url 'instagen_generate' team_id=event.data.team_id event_id=event.data.id %}">
<select hidden class="form-select" name="game_id" id="game_id">
@@ -109,40 +114,40 @@
{% endblock %}
{% block inline_javascript %}
<script>
function donut(ctx, yes_count, maybe_count, no_count, unknown_count) {
var style = getComputedStyle(document.body);
const myChart = new Chart(ctx, {
type: 'doughnut',
responsive: 'true',
data: {
datasets: [{
label: 'Availability',
labels: [
'Yes',
'Maybe',
'No',
'Unknown'
],
data: [yes_count, maybe_count, no_count, unknown_count],
backgroundColor: [
style.getPropertyValue('--bs-success'),
style.getPropertyValue('--bs-info'),
style.getPropertyValue('--bs-danger'),
style.getPropertyValue('--bs-secondary')
],
hoverOffset: 4
}]
},
});
function donut(ctx, yes_count, maybe_count, no_count, unknown_count) {
var style = getComputedStyle(document.body);
const myChart = new Chart(ctx, {
type: 'doughnut',
responsive: 'true',
data: {
datasets: [{
label: 'Availability',
labels: [
'Yes',
'Maybe',
'No',
'Unknown'
],
data: [yes_count, maybe_count, no_count, unknown_count],
backgroundColor: [
style.getPropertyValue('--bs-success'),
style.getPropertyValue('--bs-info'),
style.getPropertyValue('--bs-danger'),
style.getPropertyValue('--bs-secondary')
],
hoverOffset: 4
}]
},
});
}
for (ctx of document.querySelectorAll('.availability-donut')){
donut(ctx,
ctx.dataset.availableYes,
ctx.dataset.availableMaybe,
ctx.dataset.availableNo,
ctx.dataset.availableUnknown,
)
}
</script>
}
for (ctx of document.querySelectorAll('.availability-donut')){
donut(ctx,
ctx.dataset.availableYes,
ctx.dataset.availableMaybe,
ctx.dataset.availableNo,
ctx.dataset.availableUnknown,
)
}
</script>
{% endblock %}

View File

@@ -0,0 +1,14 @@
import pyteamsnap
def get_teamsnap_client(request):
request.user.socialaccount_set.filter(provider="teamsnap").first()
current_teamsnap_user = request.user.socialaccount_set.filter(
provider="teamsnap"
).first()
ts_token = (
current_teamsnap_user.socialtoken_set.order_by("-expires_at").first().token
)
return pyteamsnap.api.TeamSnap(token=ts_token)

View File

@@ -1,6 +1,5 @@
import datetime
import pyteamsnap.api
import requests
from allauth.socialaccount.providers.oauth2.views import (
OAuth2Adapter,
@@ -19,6 +18,7 @@ from django.views.generic.edit import FormView
from .forms import PreferencesForm
from .models import Preferences
from .provider import TeamsnapProvider
from .utils import get_teamsnap_client
class TeamsnapAdapter(OAuth2Adapter):
@@ -53,19 +53,6 @@ oauth2_login = OAuth2LoginView.adapter_view(TeamsnapAdapter)
oauth2_callback = OAuth2CallbackView.adapter_view(TeamsnapAdapter)
def get_teamsnap_client(request):
request.user.socialaccount_set.filter(provider="teamsnap").first()
current_teamsnap_user = request.user.socialaccount_set.filter(
provider="teamsnap"
).first()
ts_token = (
current_teamsnap_user.socialtoken_set.order_by("-expires_at").first().token
)
return pyteamsnap.api.TeamSnap(token=ts_token)
class PreferencesFormView(FormView):
template_name = "preferences.html"
form_class = PreferencesForm
@@ -432,8 +419,7 @@ def submit_lineup(request, team_id, event_id):
try:
r.append(event_lineup_entry.put())
except Exception as e:
e
pass
raise e
pass
elif data.get("sequence") is not None and data.get("label"):
event_lineup_entry = EventLineupEntry.new(client)