adding gamechanger, in progress

This commit is contained in:
2022-06-07 16:55:02 -05:00
parent 42d5c452e7
commit 82e77b9e6f
19 changed files with 337 additions and 28 deletions

View File

@@ -38,7 +38,7 @@
<body> <body>
<div class="mb-1"> <div class="mb-1 bg-light">
<nav class="navbar navbar-expand-md navbar-dark bg-navbar"> <nav class="navbar navbar-expand-md navbar-dark bg-navbar">
<div class="container-fluid"> <div class="container-fluid">
<button class="navbar-toggler navbar-toggler-right" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <button class="navbar-toggler navbar-toggler-right" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
@@ -72,10 +72,18 @@
</a> </a>
<ul class="dropdown-menu dropdown-menu-dark" aria-labelledby="navbarDropdown"> <ul class="dropdown-menu dropdown-menu-dark" aria-labelledby="navbarDropdown">
<li class="dropdown-item"> <li class="dropdown-item">
<a class="nav-link" href="{% url 'teamsnap_preferences' %}">{% translate "Preferences" %}</a> <a class="nav-link" href="{% url 'users:detail' request.user.username %}">{% translate "My Profile" %}</a>
</li>
<li><hr class="dropdown-divider"></li>
<li class="dropdown-item">
<a class="nav-link" href="{% url 'teamsnap_preferences' %}">{% translate "TeamSnap Preferences" %}</a>
</li>
<li><hr class="dropdown-divider"></li>
<li class="dropdown-item">
<a class="nav-link" href="{% url 'gamechanger_account' %}">{% translate "GameChanger Account" %}</a>
</li> </li>
<li class="dropdown-item"> <li class="dropdown-item">
<a class="nav-link" href="{% url 'users:detail' request.user.username %}">{% translate "My Profile" %}</a> <a class="nav-link" href="{% url 'gamechanger_preferences' %}">{% translate "GameChanger Preferences" %}</a>
</li> </li>
<li><hr class="dropdown-divider"></li> <li><hr class="dropdown-divider"></li>
<li class="dropdown-item"> <li class="dropdown-item">
@@ -107,7 +115,7 @@
</div> </div>
<div class="container bg-light"> <div class="container">
{% if messages %} {% if messages %}
{% for message in messages %} {% for message in messages %}

View File

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

View File

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

0
gamechanger/__init__.py Normal file
View File

6
gamechanger/admin.py Normal file
View File

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

6
gamechanger/apps.py Normal file
View File

@@ -0,0 +1,6 @@
from django.apps import AppConfig
class GamechangerConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'gamechanger'

35
gamechanger/forms.py Normal file
View File

@@ -0,0 +1,35 @@
from django import forms
from django.forms import ModelForm, formset_factory
from .models import Preferences, Account, Player
class PreferencesForm(ModelForm):
class Meta:
model = Preferences
fields = ["user", "season_id", "team_id"]
widgets = {
"user": forms.HiddenInput(),
"managed_team_id": forms.TextInput(),
}
labels = {"managed_team_id": "Selected Team"}
class AccountForm(ModelForm):
class Meta:
model = Account
fields = ["user", "email", "password"]
widgets = {
"user": forms.HiddenInput(),
"email": forms.EmailInput(),
"password": forms.PasswordInput()
}
class PlayerForm(ModelForm):
gamechanger_name = forms.Field()
teamsnap_name = forms.Field()
gamechanger_id = forms.Field()
class Meta:
model = Player
fields = ['id', 'teamsnap_member_id']
PlayerFormSet = formset_factory(PlayerForm, can_delete=True, extra=0)

View File

@@ -0,0 +1,34 @@
# Generated by Django 3.2.13 on 2022-06-07 16:50
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Preferences',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('managed_team_id', models.IntegerField()),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='gamechanger_preferences', to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='Account',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('email', models.EmailField(max_length=254)),
('password', models.CharField(max_length=255)),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='gamechanger_account', to=settings.AUTH_USER_MODEL)),
],
),
]

View File

@@ -0,0 +1,29 @@
# Generated by Django 3.2.13 on 2022-06-07 17:59
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('gamechanger', '0001_initial'),
]
operations = [
migrations.RemoveField(
model_name='preferences',
name='managed_team_id',
),
migrations.AddField(
model_name='preferences',
name='season_id',
field=models.CharField(default=1, max_length=255),
preserve_default=False,
),
migrations.AddField(
model_name='preferences',
name='team_id',
field=models.CharField(default=1, max_length=255),
preserve_default=False,
),
]

View File

20
gamechanger/models.py Normal file
View File

@@ -0,0 +1,20 @@
from django.db import models
from django.db.models import CharField, EmailField
from benchcoach.users.models import User
# Create your models here.
class Account(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="gamechanger_account")
email = EmailField()
password = CharField(max_length=255)
class Preferences(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="gamechanger_preferences")
season_id = CharField(max_length=255)
team_id = CharField(max_length=255)
class Player(models.Model):
id = models.AutoField(primary_key=True)
teamsnap_member_id = models.IntegerField()
fname = CharField(max_length=30)
lname = CharField(max_length=30)

View File

@@ -0,0 +1,7 @@
{% extends "base.html" %}
{% block content %}
<form method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save">
</form>
{% endblock content %}

View File

@@ -0,0 +1,44 @@
{% extends "base.html" %}
{% block content %}
{# {% for player in roster %}#}
{# <li class="list-group-item">#}
{# {{ player.fname }} {{ player.lname }}#}
{# </li>#}
{# {% endfor %}#}
<form method="post" action='{% url 'gamechanger_save' %}' >
{{ formset.management_form }}
{% csrf_token %}
<table>
<tr>
<td>
{{ formset.0.gamechanger_name.label }}
</td>
<td>
{{ formset.0.teamsnap_name.label }}
</td>
<td>
{{ formset.0.DELETE.label }}
</td>
</tr>
{% for form in formset %}
<tr>
<td>
{{ form.gamechanger_name }}
</td>
<td>
{{ form.teamsnap_name }}
</td>
<td>
{{ form.DELETE }}
</td>
{{ form.gamechanger_id.as_hidden }}
{{ form.teamsnap_member_id.as_hidden }}
</tr>
{% endfor %}
</table>
<button class="btn btn-success" type="submit">
{# <i class="bi bi-arrow-right"></i>#}
Import
</button>
</form>
{% endblock %}

3
gamechanger/tests.py Normal file
View File

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

16
gamechanger/urls.py Normal file
View File

@@ -0,0 +1,16 @@
from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns
from django.urls import path
from .views import (
PreferencesFormView,
AccountFormView,
roster_view,
roster_save
)
urlpatterns = [
path("account/", AccountFormView.as_view(), name="gamechanger_account"),
path("preferences/", PreferencesFormView.as_view(), name="gamechanger_preferences"),
path("roster/", roster_view, name="gamechanger_roster"),
path("roster/save", roster_save, name="gamechanger_save"),
]

View File

View File

@@ -0,0 +1,15 @@
import requests
import re
import json
url = "https://gc.com/t/{season_id}/{team_id}/{page}"
def scrape_page(season_id, team_id, page):
r=requests.get(url.format(season_id=season_id, team_id=team_id, page=page))
j=initialize_page_json = re.search(r'page.initialize\(\$.parseJSON\("(.*?)"\)', r.content.decode('unicode_escape'))
m=j.group(1)
return json.loads(m)
# d = scrape_page(season_id, team_id, page)
pass

81
gamechanger/views.py Normal file
View File

@@ -0,0 +1,81 @@
from django.shortcuts import render
from django.views.generic.edit import FormView
from django.views.generic.list import ListView
from .forms import PreferencesForm, AccountForm, PlayerFormSet
from .utils.gamechanger import scrape_page
from teamsnap.views import get_teamsnap_client
# Create your views here.
class PreferencesFormView(FormView):
template_name = "gamechanger/form.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)
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["email"] = self.request.user.username
# initial['managed_team_id']
return initial
class AccountFormView(FormView):
template_name = "gamechanger/form.html"
form_class = AccountForm
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)
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["email"] = self.request.user.username
# initial['managed_team_id']
return initial
def roster_view(request):
from pyteamsnap.api import Member
client = get_teamsnap_client(request)
season_id = request.user.gamechanger_preferences.season_id
team_id = request.user.gamechanger_preferences.team_id
teamsnap_team_id = request.user.preferences.managed_team_id
teamsnap_members = {
f"{member.data['first_name']} {member.data['last_name']}":member
for member in Member.search(client, team_id=teamsnap_team_id)
}
page = "roster"
d = scrape_page(season_id, team_id, page)
roster = d['roster']
initial = [{
'gamechanger_name':f"{player['fname']} {player['lname']}",
'teamsnap_name':"{first_name} {last_name}".format(**teamsnap_members[f"{player['fname']} {player['lname']}"].data),
'gamechanger_id':player.get('player_id'),
'teamsnap_member_id':teamsnap_members[f"{player['fname']} {player['lname']}"].data['id'],
} for player in roster]
formset = PlayerFormSet(initial=initial)
return render(request, "gamechanger/roster.html", context={'roster':roster, 'formset':formset})
pass
def roster_save(request):
pass

View File

@@ -12,13 +12,17 @@
<button class="btn btn-primary btn-sm py-0 m-1" onclick="importFromClipboard(this)" type="button"><i class="bi bi-arrow-90deg-down"></i></i><i class="bi bi-file-spreadsheet"></i> </button> <button class="btn btn-primary btn-sm py-0 m-1" onclick="importFromClipboard(this)" type="button"><i class="bi bi-arrow-90deg-down"></i></i><i class="bi bi-file-spreadsheet"></i> </button>
</div> </div>
<div class="col text-end d-inline"> <div class="col text-end d-inline">
<div class="btn-group">
<div class="dropdown"> <div class="dropdown">
<button class="btn btn-secondary dropdown-toggle btn-sm py-0 m-1" type="button" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false"> <button class="btn btn-secondary dropdown-toggle btn-sm py-0 m-1" type="button" id="dropdownMenuButton1"
data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-share"></i> Export <i class="bi bi-share"></i> Export
</button> </button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1"> <ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
<li> <li>
<a class="dropdown-item" href="javascript:;" onclick="copyEmailTable(this, '{{ event.data.start_date|date:"D, F j, Y g:i A" }}, {{ event.data.location_name }}, ({% if event.data.game_type == 'Away' %}@{% endif %}{{ event.data.opponent_name }})', '{% for form in formset %}{{ form.member.data.email_addresses.0 }},{% endfor %}')"> <a class="dropdown-item" href="javascript:;"
onclick="copyEmailTable(this, '{{ event.data.start_date|date:"D, F j, Y g:i A" }}, {{ event.data.location_name }}, ({% if event.data.game_type == 'Away' %}@{% endif %}{{ event.data.opponent_name }})', '
{% for form in formset %}{{ form.member.data.email_addresses.0 }},{% endfor %}')">
<i class="bi bi-envelope"></i> Generate Lineup Email <i class="bi bi-envelope"></i> Generate Lineup Email
</a> </a>
</li> </li>
@@ -38,7 +42,7 @@
</div> </div>
</div> </div>
</div> </div>
</div>
<div class="card-body p-0 m-0"> <div class="card-body p-0 m-0">
<div> <div>
<div class="row m-0"> <div class="row m-0">