adding gamechanger, in progress
This commit is contained in:
@@ -38,7 +38,7 @@
|
||||
|
||||
<body>
|
||||
|
||||
<div class="mb-1">
|
||||
<div class="mb-1 bg-light">
|
||||
<nav class="navbar navbar-expand-md navbar-dark bg-navbar">
|
||||
<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">
|
||||
@@ -72,10 +72,18 @@
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-dark" aria-labelledby="navbarDropdown">
|
||||
<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 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><hr class="dropdown-divider"></li>
|
||||
<li class="dropdown-item">
|
||||
@@ -107,7 +115,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
<div class="container bg-light">
|
||||
<div class="container">
|
||||
|
||||
{% if messages %}
|
||||
{% for message in messages %}
|
||||
|
||||
@@ -272,7 +272,7 @@ SOCIALACCOUNT_FORMS = {"signup": "benchcoach.users.forms.UserSocialSignupForm"}
|
||||
|
||||
# Your stuff...
|
||||
# ------------------------------------------------------------------------------
|
||||
INSTALLED_APPS += ["teamsnap", "instagen"]
|
||||
INSTALLED_APPS += ["teamsnap", "instagen","gamechanger"]
|
||||
SOCIALACCOUNT_PROVIDERS = {
|
||||
'teamsnap': {
|
||||
'SCOPE': ["read", "write"]
|
||||
|
||||
@@ -17,6 +17,7 @@ urlpatterns = [
|
||||
path("accounts/", include("allauth.urls")),
|
||||
path("", include("teamsnap.urls")),
|
||||
path("", include("instagen.urls")),
|
||||
path("gc/", include("gamechanger.urls"))
|
||||
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
|
||||
|
||||
|
||||
0
gamechanger/__init__.py
Normal file
0
gamechanger/__init__.py
Normal file
6
gamechanger/admin.py
Normal file
6
gamechanger/admin.py
Normal 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
6
gamechanger/apps.py
Normal 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
35
gamechanger/forms.py
Normal 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)
|
||||
34
gamechanger/migrations/0001_initial.py
Normal file
34
gamechanger/migrations/0001_initial.py
Normal 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)),
|
||||
],
|
||||
),
|
||||
]
|
||||
29
gamechanger/migrations/0002_auto_20220607_1259.py
Normal file
29
gamechanger/migrations/0002_auto_20220607_1259.py
Normal 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,
|
||||
),
|
||||
]
|
||||
0
gamechanger/migrations/__init__.py
Normal file
0
gamechanger/migrations/__init__.py
Normal file
20
gamechanger/models.py
Normal file
20
gamechanger/models.py
Normal 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)
|
||||
7
gamechanger/templates/gamechanger/form.html
Normal file
7
gamechanger/templates/gamechanger/form.html
Normal 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 %}
|
||||
44
gamechanger/templates/gamechanger/roster.html
Normal file
44
gamechanger/templates/gamechanger/roster.html
Normal 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
3
gamechanger/tests.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
16
gamechanger/urls.py
Normal file
16
gamechanger/urls.py
Normal 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"),
|
||||
]
|
||||
0
gamechanger/utils/__init__.py
Normal file
0
gamechanger/utils/__init__.py
Normal file
15
gamechanger/utils/gamechanger.py
Normal file
15
gamechanger/utils/gamechanger.py
Normal 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
81
gamechanger/views.py
Normal 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
|
||||
@@ -12,33 +12,37 @@
|
||||
<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 class="col text-end d-inline">
|
||||
<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">
|
||||
<i class="bi bi-share"></i> Export
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
|
||||
<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 %}')">
|
||||
<i class="bi bi-envelope"></i> Generate Lineup Email
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" onclick="sendToClipboard(this)">
|
||||
<i class="bi bi-file-spreadsheet"></i> Sheet format to Clipboard
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<button class="btn btn-teamsnap btn-sm py-0 m-1" type="submit">
|
||||
<i class="bi bi-arrow-right"></i>
|
||||
TeamSnap
|
||||
</button>
|
||||
<div class="btn-group">
|
||||
<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">
|
||||
<i class="bi bi-share"></i> Export
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
|
||||
<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 %}')">
|
||||
<i class="bi bi-envelope"></i> Generate Lineup Email
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" onclick="sendToClipboard(this)">
|
||||
<i class="bi bi-file-spreadsheet"></i> Sheet format to Clipboard
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<button class="btn btn-teamsnap btn-sm py-0 m-1" type="submit">
|
||||
<i class="bi bi-arrow-right"></i>
|
||||
TeamSnap
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-body p-0 m-0">
|
||||
<div>
|
||||
<div class="row m-0">
|
||||
|
||||
Reference in New Issue
Block a user