add opponent views and forms

This commit is contained in:
2022-06-14 19:33:19 -05:00
parent 2129cfe3a1
commit 1f98127778
7 changed files with 173 additions and 246 deletions

View File

@@ -68,6 +68,9 @@
<li class="nav-item">
<a class="nav-link" href="{% url 'teamsnap_choose_multiple_lineups' team_id=request.user.teamsnap_preferences.managed_team_id%}?num=3">{% translate "Multi-Lineup" %}</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'teamsnap_opponents' team_id=request.user.teamsnap_preferences.managed_team_id%}">{% translate "Opponents" %}</a>
</li>
{% endif %}
<li class="nav-item dropdown">

View File

@@ -1,7 +1,7 @@
from django import forms
from django.forms import ModelForm, formset_factory
from .models import Preferences
from .models import Opponent, Preferences
class PreferencesForm(ModelForm):
@@ -58,10 +58,13 @@ LineupEntryFormset = formset_factory(
class EventChooseForm(forms.Form):
event_id = forms.ChoiceField()
# checked = forms.BooleanField(required=False)
# def __init__(self, events, *args, **kwargs):
# super(EventChooseForm, self).__init__(*args, **kwargs)
# self.fields['foo'].choices = [e.data['id'] for e in events]
class OpponentForm(forms.ModelForm):
class Meta:
model = Opponent
fields = "__all__"
# exclude = ["player"]
widgets = {"id": forms.HiddenInput()}
LineupEntryFormset = formset_factory(

View File

@@ -61,7 +61,7 @@
Opponent
</th>
<td>
<a href="">{{ event.data.opponent_name }}</a>
<a href="{% url 'teamsnap_opponent' opponent_id=event.data.opponent_id team_id=event.data.team_id%}">{{ event.data.opponent_name }}</a>
</td>
</tr>
<tr>

View File

@@ -0,0 +1,9 @@
{% extends "base.html" %}
{% block title %}{{ opponent.data.name }}{% endblock %}
{% block content %}
<h4>{{ opponent.data.name }}</h4>
<form method="post" enctype="multipart/form-data">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save">
</form>
{% endblock content %}

View File

@@ -0,0 +1,48 @@
{% extends "base.html" %}
{% block title %}Opponents{% endblock %}
{% block content %}
<h4 class="display-4">Opponents</h4>
<table class="table bg-white">
<thead>
<tr>
<th>
Team Name
</th>
<th>
Logo
</th>
<th>
Monocolor Logo
</th>
</tr>
</thead>
<tbody>
{% for ts_opponent, opponent in object_list %}
<tr>
<th>
<a class="text-decoration-none" href="{% url 'teamsnap_opponent' team_id=team_id opponent_id=opponent.id %}">
{{ ts_opponent.data.name }}
</a>
</th>
<td>
{% if opponent.logo %}
<div class="rounded-circle bg-light p-2" style="height:64px;width:64px;">
<img class="img-fluid" src="{{ opponent.logo.url }}">
</div>
{% endif %}
</td>
<td>
{% if opponent.logo_mono %}
<div class="rounded-circle bg-dark p-2" style="height:64px;width:64px;">
<img class="img-fluid" src="{{ opponent.logo_mono.url }}">
</img>
{% endif %}
</td>
</tr>
{% empty %}
<li>No opponents yet.</li>
{% endfor %}
</tbody>
</table>
{% endblock content %}

View File

@@ -2,7 +2,13 @@ from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns
from django.urls import include, path
from .provider import TeamsnapProvider
from .views import PreferencesFormView, schedule_view, view_event
from .views import (
OpponentFormView,
Opponents,
PreferencesFormView,
schedule_view,
view_event,
)
urlpatterns = default_urlpatterns(TeamsnapProvider)
@@ -17,4 +23,10 @@ urlpatterns += [
),
path("", include("teamsnap.lineup.urls")),
path("", include("teamsnap.dashboard.urls")),
path(
"<int:team_id>/opponent/<int:opponent_id>/",
OpponentFormView.as_view(),
name="teamsnap_opponent",
),
path("<int:team_id>/opponents", Opponents.as_view(), name="teamsnap_opponents"),
]

View File

@@ -6,14 +6,13 @@ from allauth.socialaccount.providers.oauth2.views import (
OAuth2CallbackView,
OAuth2LoginView,
)
from django.http import HttpResponse, HttpResponseNotAllowed, HttpResponseServerError
from django.shortcuts import redirect, render
from django.http import HttpResponse
from django.shortcuts import redirect, render, reverse
from django.views.generic import ListView
from django.views.generic.edit import FormView
from gamechanger.models import Player as GamechangerPlayer
from .forms import PreferencesForm
from .models import Preferences
from .forms import OpponentForm, PreferencesForm
from .models import Opponent, Preferences
from .provider import TeamsnapProvider
from .utils import get_teamsnap_client
@@ -60,7 +59,9 @@ class PreferencesFormView(FormView):
# It should return an HttpResponse.
if form.data["user"] == str(self.request.user.id):
form.save()
return super().form_valid(form)
return super().form_valid(form)
else:
return super().form_invalid(form)
def get_initial(self):
"""
@@ -180,238 +181,6 @@ def view_event(request, event_id, team_id=None):
)
def edit_lineup(request, event_ids, team_id):
import re
from pyteamsnap.api import (
Availability,
AvailabilitySummary,
Event,
EventLineup,
EventLineupEntry,
Member,
)
from teamsnap.forms import LineupEntryFormset
client = get_teamsnap_client(request)
event_ids = str(event_ids).split(",")
ts_bulkload = client.bulk_load(
team_id=team_id,
types=[Event, EventLineup, EventLineupEntry, AvailabilitySummary, Member],
event__id=",".join(event_ids),
)
event_ids = [int(i) for i in event_ids]
contexts = []
for event_id in event_ids:
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)
ts_members = [i for i in ts_bulkload if isinstance(i, Member)]
ts_member_lookup = {m.data["id"]: m for m in ts_members}
gc_player_lookup = {
m.data["id"]: getattr(
GamechangerPlayer.objects.filter(
teamsnap_member_id=m.data["id"]
).first(),
"id",
None,
)
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 lineup_entry in ts_lineup_entries:
members.append(
{
"member": getattr(
ts_member_lookup[lineup_entry.data["member_id"]], "data"
),
"availability": getattr(
ts_availability_lookup.get(lineup_entry.data["member_id"], {}),
"data",
{},
),
"lineup_entry": getattr(lineup_entry, "data", {}),
}
)
in_lineup_already = [m["member"] for m in members]
for member in ts_members:
if member.data not in in_lineup_already:
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"),
),
)
initial = []
for member in members:
if not member["member"]["is_non_player"]:
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"
initial.append(
{
"event_lineup_entry_id": member["lineup_entry"].get("id"),
"event_lineup_id": member["lineup_entry"].get(
"event_lineup_id"
),
"event_id": event_id,
"position_only": position_only,
"member_id": member["member"]["id"],
"sequence": member["lineup_entry"].get("sequence"),
"label": position,
"gamechanger_player_id": gc_player_lookup.get(
member["member"]["id"]
),
}
)
formset = LineupEntryFormset(initial=initial)
for form in formset:
form.member = ts_member_lookup.get(form["member_id"].initial)
form.availability = ts_availability_lookup.get(form["member_id"].initial)
formset_startinglineup = [
form
for form in formset
if form.initial.get("event_lineup_entry_id")
and not form.initial.get("position_only")
]
formset_startinglineup = sorted(
formset_startinglineup, key=lambda d: d.initial.get("sequence", 100)
)
formset_startingpositiononly = [
form
for form in formset
if form.initial.get("event_lineup_entry_id")
and form not in formset_startinglineup
]
formset_startingpositiononly = sorted(
formset_startingpositiononly, key=lambda d: d.initial.get("sequence", 100)
)
formset_bench = [
form
for form in formset
if form not in formset_startinglineup
and form not in formset_startingpositiononly
and form.availability.data["status_code"] in [2, 1]
]
formset_out = [
form
for form in formset
if form not in formset_startinglineup
and form not in formset_bench
and form not in formset_startingpositiononly
and not form.member.data["is_non_player"]
]
contexts.append(
{
"event": ts_event,
"formset": formset,
"formset_bench": formset_bench,
"formset_startinglineup": formset_startinglineup,
"formset_startingpositionalonly": formset_startingpositiononly,
"formset_out": formset_out,
}
)
return render(request, "lineup/edit.html", context={"contexts": contexts})
def submit_lineup(request, team_id, event_id):
from pyteamsnap.api import EventLineup, EventLineupEntry
from teamsnap.forms import LineupEntryFormset
client = get_teamsnap_client(request)
ts_lineup = EventLineup.search(client, event_id=event_id)
event_lineup_id = ts_lineup[0].data["id"]
if request.GET:
return HttpResponseNotAllowed()
if request.POST:
formset = LineupEntryFormset(request.POST)
if formset.is_valid():
r = []
for form in formset:
data = form.cleaned_data
if data.get("event_lineup_entry_id"):
event_lineup_entry = EventLineupEntry.get(
client, id=data.get("event_lineup_entry_id")
)
if data.get("position_only"):
data["label"] = data["label"] + " [PO]"
event_lineup_entry.data.update(data)
if not data.get("sequence") and not data.get("label"):
try:
r.append(event_lineup_entry.delete())
except Exception as e:
raise e
else:
try:
r.append(event_lineup_entry.put())
except Exception as e:
raise e
pass
elif data.get("sequence") is not None and data.get("label"):
event_lineup_entry = EventLineupEntry.new(client)
if data.get("position_only"):
data["label"] = data["label"] + " [PO]"
event_lineup_entry.data.update(data)
event_lineup_entry.data.update({"event_lineup_id": event_lineup_id})
try:
r.append(event_lineup_entry.post())
except Exception as e:
raise e
else:
pass
else:
pass
return HttpResponse(status=200)
return HttpResponseServerError()
def multi_lineup_choose(request, team_id):
from django.forms import formset_factory
from pyteamsnap.api import Event
@@ -464,3 +233,86 @@ def multi_lineup_choose(request, team_id):
"lineup/multiple_choose.html",
context={"formset": formset, "team_id": team_id},
)
class OpponentFormView(FormView):
pk_url_kwarg = "opponent_id"
template_name = "opponent.html"
form_class = OpponentForm
def get_success_url(self):
team_id = self.kwargs.get("team_id")
return reverse("teamsnap_opponents", kwargs={"team_id": team_id})
def form_valid(self, form):
# This method is called when valid form data has been POSTed.
# It should return an HttpResponse.
import pyteamsnap
ts_client = get_teamsnap_client(self.request)
user = pyteamsnap.api.Me(ts_client)
team_id = int(self.kwargs.get("team_id"))
opponent_id = int(self.kwargs.get("opponent_id"))
opponent = pyteamsnap.api.Opponent.get(ts_client, opponent_id)
if (
team_id in user.data["managed_team_ids"]
and opponent.data["team_id"] == team_id
):
form.save()
return super().form_valid(form)
else:
return super().form_invalid(form)
def get_form(self):
"""
Returns the initial data to use for forms on this view.
"""
try:
opponent, _ = Opponent.objects.get_or_create(
id=self.kwargs.get("opponent_id")
)
form = OpponentForm(instance=opponent, **self.get_form_kwargs())
except Opponent.DoesNotExist:
form = super().get_form(self.form_class)
# form.widgets['id'] = forms.HiddenInput()
return form
def get_context_data(self, **kwargs):
import pyteamsnap
ts_client = get_teamsnap_client(self.request)
context = super().get_context_data(**kwargs)
opponent = pyteamsnap.api.Opponent.get(
ts_client, self.kwargs.get("opponent_id")
)
context["opponent"] = opponent
return context
class Opponents(ListView):
model = Opponent
template_name = "opponents.html"
pass
def get_queryset(self):
import pyteamsnap
ts_client = get_teamsnap_client(self.request)
team_id = self.kwargs.get("team_id")
ts_opponents = pyteamsnap.api.Opponent.search(ts_client, team_id=team_id)
ts_opponents.sort(key=lambda t: t.data.get("name"))
opponents = []
for opponent in ts_opponents:
o, _ = Opponent.objects.get_or_create(id=opponent.data["id"])
opponents.append((opponent, o))
return opponents
def get_context_data(self, **kwargs):
team_id = self.kwargs.get("team_id")
context = super().get_context_data(**kwargs)
context["team_id"] = team_id
return context