320 lines
9.8 KiB
Python
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
|