Files
benchcoach-django/teamsnap/views.py
2022-06-28 12:44:02 -05:00

320 lines
9.8 KiB
Python

import datetime
import requests
from allauth.socialaccount.providers.oauth2.views import (
OAuth2Adapter,
OAuth2CallbackView,
OAuth2LoginView,
)
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 .forms import OpponentForm, PreferencesForm
from .models import Opponent, Preferences
from .provider import TeamsnapProvider
from .utils import get_teamsnap_client
class TeamsnapAdapter(OAuth2Adapter):
provider_id = TeamsnapProvider.id
# Fetched programmatically, must be reachable from container
access_token_url = "{}/oauth/token/".format("https://auth.teamsnap.com")
profile_url = "{}/me/".format("https://api.teamsnap.com/v3/")
# Accessed by the user browser, must be reachable by the host
authorize_url = "{}/oauth/authorize/".format("https://auth.teamsnap.com/")
# NOTE: trailing slashes in URLs are important, don't miss it
def complete_login(self, request, app, token, **kwargs):
headers = {"Authorization": f"Bearer {token.token}"}
resp = requests.get(self.profile_url, headers=headers)
j = resp.json()
if j.get("collection", {}).get("items"):
extra_data = {
i["name"]: i["value"] for i in j["collection"]["items"][0]["data"]
}
return self.get_provider().sociallogin_from_response(request, extra_data)
def populate_user(self, request, sociallogin, data):
user = super().populate_user(request, sociallogin, data)
user.username = user.email
return user
oauth2_login = OAuth2LoginView.adapter_view(TeamsnapAdapter)
oauth2_callback = OAuth2CallbackView.adapter_view(TeamsnapAdapter)
class PreferencesFormView(FormView):
template_name = "preferences.html"
form_class = PreferencesForm
success_url = "/"
def form_valid(self, form):
# This method is called when valid form data has been POSTed.
# It should return an HttpResponse.
if form.data["user"] == str(self.request.user.id):
form.save()
return super().form_valid(form)
else:
return super().form_invalid(form)
def get_initial(self):
"""
Returns the initial data to use for forms on this view.
"""
initial = super().get_initial()
initial["user"] = self.request.user
# initial['managed_team_id']
return initial
def get_form(self):
"""
Returns the initial data to use for forms on this view.
"""
import pyteamsnap.client
import pyteamsnap.objects
ts_account = self.request.user.socialaccount_set.first()
ts_token = ts_account.socialtoken_set.first()
# ts_token =
ts = pyteamsnap.client.TeamSnap(token=ts_token)
me = pyteamsnap.objects.Me(ts)
teams = [
(id, pyteamsnap.objects.Team.get(ts, id=id))
for id in me.data["managed_team_ids"]
]
try:
contact = Preferences.objects.get(user=self.request.user)
form = PreferencesForm(instance=contact, **self.get_form_kwargs())
except Preferences.DoesNotExist:
form = super().get_form(self.form_class)
choices = [
(id, f"{team.data['name']} ({team.data['season_name']})")
for id, team in teams
]
form.fields["managed_team_id"].widget.choices = choices
return form
def schedule_view(request, team_id=None):
if not team_id:
return redirect(
"teamsnap_schedule",
team_id=request.user.teamsnap_preferences.managed_team_id,
)
client = get_teamsnap_client(request)
no_past = bool(request.GET.get("no_past", 0))
games_only = bool(request.GET.get("games_only", 0))
from pyteamsnap.objects import Event
ts_events = Event.search(client, team_id=team_id)
if no_past:
ts_events = [
e
for e in ts_events
if e.data["start_date"] > datetime.datetime.now(datetime.timezone.utc)
]
if games_only:
ts_events = [e for e in ts_events if e.data["is_game"]]
ts_events = {e.data["id"]: e for e in ts_events}
pass
return render(
request,
"schedule.html",
context={"events": ts_events.values(), "team_id": team_id},
)
def view_event(request, event_id, team_id=None):
if not team_id:
return redirect(
"teamsnap_event", team_id=request.user.teamsnap_preferences.managed_team_id
)
from pyteamsnap.objects import (
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)][0]
ts_availability_summary = [
i
for i in ts_bulkload
if isinstance(i, AvailabilitySummary) and i.data["event_id"] == event_id
][0]
ts_lineup_entries = [
i
for i in ts_bulkload
if isinstance(i, EventLineupEntry) and i.data["event_id"] == event_id
]
return render(
request,
"event/view_event.html",
context={
"availability_summary": ts_availability_summary,
"event": ts_event,
"availablities": [],
"lineup_entries": ts_lineup_entries,
},
)
def multi_lineup_choose(request, team_id):
from django.forms import formset_factory
from pyteamsnap.objects import Event
from .forms import EventChooseForm
client = get_teamsnap_client(request)
if request.method == "POST":
ts_events = Event.search(client, team_id=team_id)
EventChooseFormset = formset_factory(EventChooseForm)
formset = EventChooseFormset(request.POST)
choices = [(e.data["id"], e.data["formatted_title"]) for e in ts_events]
for form in formset:
form.fields["event_id"].choices = choices
if formset.is_valid():
event_ids = [f.cleaned_data["event_id"] for f in formset]
else:
event_ids = request.GET.get("event_ids").split(",")
EventChooseFormset = formset_factory(EventChooseForm)
formset = EventChooseFormset(request.POST)
return redirect(
"teamsnap_edit_lineup",
team_id=team_id,
event_ids=",".join(event_ids),
)
elif not request.GET.get("num"):
return HttpResponse(500)
else:
num = int(request.GET.get("num"))
TEAM_ID = team_id
ts_events = Event.search(client, team_id=TEAM_ID)
ts_events = {e.data["id"]: e for e in ts_events}
EventChooseFormset = formset_factory(EventChooseForm, extra=num)
formset = EventChooseFormset()
choices = [(id, e.data["formatted_title"]) for id, e in ts_events.items()]
for form in formset:
form.fields["event_id"].choices = choices
pass
return render(
request,
"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.objects
ts_client = get_teamsnap_client(self.request)
user = pyteamsnap.objects.Me(ts_client)
team_id = int(self.kwargs.get("team_id"))
opponent_id = int(self.kwargs.get("opponent_id"))
opponent = pyteamsnap.objects.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.objects
ts_client = get_teamsnap_client(self.request)
context = super().get_context_data(**kwargs)
opponent = pyteamsnap.objects.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):
from pyteamsnap.objects import Opponent as TsOpponent
ts_client = get_teamsnap_client(self.request)
team_id = self.kwargs.get("team_id")
ts_opponents = TsOpponent.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