gamechanger updates (added events, teams)
This commit is contained in:
16
gamechanger/templates/gamechanger/events.html
Normal file
16
gamechanger/templates/gamechanger/events.html
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{% extends "base.html" %}{% load tz %}
|
||||||
|
{% block title_header %}GameChanger Events{% endblock title_header %}
|
||||||
|
{% block content %}
|
||||||
|
<table class="table">
|
||||||
|
{% for event in events %}
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
{{ event.title }}
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
{{ event.start|localtime }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
{% endblock %}
|
||||||
@@ -1,48 +1,15 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{# {% for player in roster %}#}
|
<table class="table">
|
||||||
{# <li class="list-group-item">#}
|
{% for member in roster %}
|
||||||
{# {{ player.fname }} {{ player.lname }}#}
|
|
||||||
{# </li>#}
|
|
||||||
{# {% endfor %}#}
|
|
||||||
<form method="post" action='{% url 'gamechanger_import_roster' %}' >
|
|
||||||
{{ 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>
|
<tr>
|
||||||
|
<th>
|
||||||
|
{{ member.fname }} {{ member.lname }}
|
||||||
|
</th>
|
||||||
<td>
|
<td>
|
||||||
{{ form.gamechanger_name.value }}
|
{{ member }}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
|
||||||
{{ form.teamsnap_member_id }}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{ form.DELETE }}
|
|
||||||
</td>
|
|
||||||
{{ form.gamechanger_name.as_hidden }}
|
|
||||||
{{ form.teamsnap_name.as_hidden }}
|
|
||||||
{{ form.id.as_hidden }}
|
|
||||||
{{ form.teamsnap_member_id.as_hidden }}
|
|
||||||
{{ form.fname.as_hidden }}
|
|
||||||
{{ form.lname.as_hidden }}
|
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
<button class="btn btn-success" type="submit">
|
|
||||||
{# <i class="bi bi-arrow-right"></i>#}
|
|
||||||
Import
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
48
gamechanger/templates/gamechanger/roster_import.html
Normal file
48
gamechanger/templates/gamechanger/roster_import.html
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
{% 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_import_roster' %}' >
|
||||||
|
{{ formset.management_form }}
|
||||||
|
{% csrf_token %}
|
||||||
|
<table class="table">
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
{{ formset.0.gamechanger_name.label }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ formset.0.teamsnap_name.label }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ formset.0.DELETE.label }}
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
{% for form in formset %}
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
{{ form.gamechanger_name.value }}
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
{{ form.teamsnap_member_id }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ form.DELETE }}
|
||||||
|
</td>
|
||||||
|
{{ form.gamechanger_name.as_hidden }}
|
||||||
|
{{ form.teamsnap_name.as_hidden }}
|
||||||
|
{{ form.id.as_hidden }}
|
||||||
|
{{ form.teamsnap_member_id.as_hidden }}
|
||||||
|
{{ form.fname.as_hidden }}
|
||||||
|
{{ form.lname.as_hidden }}
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
<button class="btn btn-success" type="submit">
|
||||||
|
{# <i class="bi bi-arrow-right"></i>#}
|
||||||
|
Import
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
15
gamechanger/templates/gamechanger/teams.html
Normal file
15
gamechanger/templates/gamechanger/teams.html
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block content %}
|
||||||
|
<table class="table">
|
||||||
|
{% for team in teams %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{{ team.name }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ team }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
{% endblock %}
|
||||||
@@ -1,3 +1,86 @@
|
|||||||
from django.test import TestCase
|
import vcr
|
||||||
|
from django.conf import settings
|
||||||
|
from django.contrib.auth import (
|
||||||
|
BACKEND_SESSION_KEY,
|
||||||
|
HASH_SESSION_KEY,
|
||||||
|
SESSION_KEY,
|
||||||
|
get_user_model,
|
||||||
|
)
|
||||||
|
from django.contrib.sessions.backends.db import SessionStore
|
||||||
|
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
|
||||||
|
from selenium import webdriver
|
||||||
|
|
||||||
# Create your tests here.
|
|
||||||
|
def create_session_cookie():
|
||||||
|
|
||||||
|
# First, create a new test user
|
||||||
|
user = get_user_model()
|
||||||
|
# user.objects.create_user(username=username, password=password)
|
||||||
|
user = get_user_model().objects.get(pk=2)
|
||||||
|
|
||||||
|
# Then create the authenticated session using the new user credentials
|
||||||
|
session = SessionStore()
|
||||||
|
session[SESSION_KEY] = user.pk
|
||||||
|
session[BACKEND_SESSION_KEY] = settings.AUTHENTICATION_BACKENDS[0]
|
||||||
|
session[HASH_SESSION_KEY] = user.get_session_auth_hash()
|
||||||
|
session.save()
|
||||||
|
|
||||||
|
# Finally, create the cookie dictionary
|
||||||
|
cookie = {
|
||||||
|
"name": settings.SESSION_COOKIE_NAME,
|
||||||
|
"value": session.session_key,
|
||||||
|
"secure": False,
|
||||||
|
"path": "/",
|
||||||
|
}
|
||||||
|
return cookie
|
||||||
|
|
||||||
|
|
||||||
|
@vcr.use_cassette(
|
||||||
|
"gamechanger/fixtures/tests.yaml",
|
||||||
|
ignore_localhost=True,
|
||||||
|
# record_mode="new_episodes",
|
||||||
|
decode_compressed_response=True,
|
||||||
|
allow_playback_repeats=True,
|
||||||
|
)
|
||||||
|
class GameChangerTests(StaticLiveServerTestCase):
|
||||||
|
fixtures = ["benchcoach/fixtures/dump.json"]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
cls.port = 8000
|
||||||
|
super().setUpClass()
|
||||||
|
cls.selenium = webdriver.Chrome("/opt/homebrew/bin/chromedriver")
|
||||||
|
cls.selenium.implicitly_wait(10)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def tearDownClass(cls):
|
||||||
|
cls.selenium.quit()
|
||||||
|
super().tearDownClass()
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
session_cookie = create_session_cookie()
|
||||||
|
self.selenium.get("{}{}".format(self.live_server_url, "/"))
|
||||||
|
self.selenium.add_cookie(session_cookie)
|
||||||
|
self.selenium.refresh()
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_gamechanger_teams(self):
|
||||||
|
|
||||||
|
self.selenium.get(
|
||||||
|
"{url}/gc/{page}".format(url=self.live_server_url, page="teams")
|
||||||
|
)
|
||||||
|
breakpoint()
|
||||||
|
|
||||||
|
def test_gamechanger_events(self):
|
||||||
|
|
||||||
|
self.selenium.get(
|
||||||
|
"{url}/gc/{page}".format(url=self.live_server_url, page="events")
|
||||||
|
)
|
||||||
|
breakpoint()
|
||||||
|
|
||||||
|
def test_gamechanger_roster(self):
|
||||||
|
|
||||||
|
self.selenium.get(
|
||||||
|
"{url}/gc/{page}".format(url=self.live_server_url, page="roster")
|
||||||
|
)
|
||||||
|
breakpoint()
|
||||||
|
|||||||
@@ -3,15 +3,21 @@ from django.urls import path
|
|||||||
from .views import (
|
from .views import (
|
||||||
AccountFormView,
|
AccountFormView,
|
||||||
PreferencesFormView,
|
PreferencesFormView,
|
||||||
|
events,
|
||||||
lineup_submit,
|
lineup_submit,
|
||||||
|
roster,
|
||||||
roster_import,
|
roster_import,
|
||||||
stats,
|
stats,
|
||||||
|
teams,
|
||||||
)
|
)
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("account/", AccountFormView.as_view(), name="gamechanger_account"),
|
path("account/", AccountFormView.as_view(), name="gamechanger_account"),
|
||||||
path("preferences/", PreferencesFormView.as_view(), name="gamechanger_preferences"),
|
path("preferences/", PreferencesFormView.as_view(), name="gamechanger_preferences"),
|
||||||
path("roster/import", roster_import, name="gamechanger_import_roster"),
|
path("roster/import", roster_import, name="gamechanger_import_roster"),
|
||||||
|
path("roster", roster, name="gamechanger_roster"),
|
||||||
path("lineup/submit", lineup_submit, name="gamechanger_lineup_submit"),
|
path("lineup/submit", lineup_submit, name="gamechanger_lineup_submit"),
|
||||||
path("stats", stats, name="gamechanger_stats"),
|
path("stats", stats, name="gamechanger_stats"),
|
||||||
|
path("teams", teams, name="gamechanger_teams"),
|
||||||
|
path("events", events, name="gamechanger_events"),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
import csv
|
import csv
|
||||||
|
import datetime
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
import pytz
|
||||||
import requests
|
import requests
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
|
|
||||||
url = "https://gc.com/t/{season_id}/{team_id}/{page}"
|
url = "https://gc.com/t/{season_id}/{team_id}/{page}"
|
||||||
|
|
||||||
@@ -67,6 +70,94 @@ def scrape_page(season_id, team_id, page):
|
|||||||
return json.loads(m)
|
return json.loads(m)
|
||||||
|
|
||||||
|
|
||||||
|
def get_teams(session):
|
||||||
|
url = "https://gc.com/account/teams"
|
||||||
|
session.headers.update(
|
||||||
|
{
|
||||||
|
"referer": url.format("https://gc.com/account/profile"),
|
||||||
|
"x-csrftoken": session.cookies.get("csrftoken"),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
page = session.get(cookies=session.cookies, url=url)
|
||||||
|
soup = BeautifulSoup(page.content, "html.parser")
|
||||||
|
team_elements = [i for i in soup.find_all("li") if i.attrs.get("data-team-id")]
|
||||||
|
teams = []
|
||||||
|
for i, team_element in enumerate(team_elements):
|
||||||
|
league_type, number_of_games = [
|
||||||
|
c.text.strip() for c in team_element.findChildren("li")
|
||||||
|
][1:3]
|
||||||
|
season_slug, team_slug = (
|
||||||
|
team_element.find("a").attrs.get("href", "///").split("/")[2:]
|
||||||
|
)
|
||||||
|
teams.append(
|
||||||
|
{
|
||||||
|
"name": team_element.find("a").text,
|
||||||
|
"id": team_element.attrs.get("data-team-id"),
|
||||||
|
"season": team_element.findPrevious("header").text,
|
||||||
|
"league_type": league_type,
|
||||||
|
"number_of_games": number_of_games,
|
||||||
|
"season_slug": season_slug,
|
||||||
|
"team_slug": team_slug,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return teams
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def get_events(request):
|
||||||
|
authenticated_session = get_authenticated_session(request)
|
||||||
|
season_id = request.user.gamechanger_preferences.season_id
|
||||||
|
team_id = request.user.gamechanger_preferences.team_id
|
||||||
|
page = "stats/batting/Qualified/standard/csv"
|
||||||
|
authenticated_session.get(
|
||||||
|
url.format(season_id=season_id, team_id=team_id, page=page)
|
||||||
|
)
|
||||||
|
authenticated_session.headers.update(
|
||||||
|
{
|
||||||
|
"x-csrftoken": authenticated_session.cookies.get("csrftoken"),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
page = authenticated_session.get(
|
||||||
|
cookies=authenticated_session.cookies,
|
||||||
|
url=url.format(season_id=season_id, team_id=team_id, page="schedule/games"),
|
||||||
|
)
|
||||||
|
soup = BeautifulSoup(page.content, "html.parser")
|
||||||
|
game_elements = [r for r in soup.find_all("tr") if "game" in r.attrs.get("class")]
|
||||||
|
games = []
|
||||||
|
for i, game_element in enumerate(game_elements):
|
||||||
|
game_slug = game_element.find("a").attrs.get("href").split("/")[1]
|
||||||
|
title = game_element.find("a").text
|
||||||
|
jslocaldate, jslocaltime_start, jslocaltime_arrival = (
|
||||||
|
t.attrs.get("datetime") for t in game_element.findAll("time")
|
||||||
|
)
|
||||||
|
games.append(
|
||||||
|
{
|
||||||
|
"id": game_element.attrs.get("data-id"),
|
||||||
|
"title": title,
|
||||||
|
"game_slug": game_slug,
|
||||||
|
"start": pytz.timezone("utc").localize(
|
||||||
|
datetime.datetime.fromisoformat(jslocaltime_start)
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return games
|
||||||
|
|
||||||
|
|
||||||
|
def stream():
|
||||||
|
# game_page = authenticated_session.get(
|
||||||
|
# cookies=authenticated_session.cookies,
|
||||||
|
# url=f"https://gc.com/{game_slug}",
|
||||||
|
# )
|
||||||
|
# game_soup = BeautifulSoup(game_page.content, "html.parser")
|
||||||
|
# data_push_url_rel = game_soup.find("body").attrs.get("data-push-url")[2:]
|
||||||
|
# data_push_url = f"https://{data_push_url_rel}?sabertooth_aware=true"
|
||||||
|
# stream_page = authenticated_session.get(
|
||||||
|
# cookies=authenticated_session.cookies, url=data_push_url
|
||||||
|
# )
|
||||||
|
# game_stream = json.loads(stream_page.content)
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def stats(request):
|
def stats(request):
|
||||||
authenticated_session = get_authenticated_session(request)
|
authenticated_session = get_authenticated_session(request)
|
||||||
season_id = request.user.gamechanger_preferences.season_id
|
season_id = request.user.gamechanger_preferences.season_id
|
||||||
|
|||||||
@@ -9,6 +9,19 @@ from .models import Account, Player, Preferences
|
|||||||
from .utils import gamechanger
|
from .utils import gamechanger
|
||||||
|
|
||||||
|
|
||||||
|
def teams(request):
|
||||||
|
# season_id = request.user.gamechanger_preferences.season_id
|
||||||
|
# team_id = request.user.gamechanger_preferences.team_id
|
||||||
|
s = gamechanger.get_authenticated_session(request)
|
||||||
|
teams = gamechanger.get_teams(s)
|
||||||
|
return render(request, "gamechanger/teams.html", context={"teams": teams})
|
||||||
|
|
||||||
|
|
||||||
|
def events(request):
|
||||||
|
events = gamechanger.get_events(request)
|
||||||
|
return render(request, "gamechanger/events.html", context={"events": events})
|
||||||
|
|
||||||
|
|
||||||
class PreferencesFormView(FormView):
|
class PreferencesFormView(FormView):
|
||||||
template_name = "gamechanger/form.html"
|
template_name = "gamechanger/form.html"
|
||||||
form_class = PreferencesForm
|
form_class = PreferencesForm
|
||||||
@@ -83,6 +96,15 @@ class AccountFormView(FormView):
|
|||||||
return form
|
return form
|
||||||
|
|
||||||
|
|
||||||
|
def roster(request):
|
||||||
|
season_id = request.user.gamechanger_preferences.season_id
|
||||||
|
team_id = request.user.gamechanger_preferences.team_id
|
||||||
|
page = "roster"
|
||||||
|
d = gamechanger.scrape_page(season_id, team_id, page)
|
||||||
|
roster = d["roster"]
|
||||||
|
return render(request, "gamechanger/roster.html", context={"roster": roster})
|
||||||
|
|
||||||
|
|
||||||
def roster_import(request):
|
def roster_import(request):
|
||||||
if request.method == "GET":
|
if request.method == "GET":
|
||||||
from pyteamsnap.api import Member
|
from pyteamsnap.api import Member
|
||||||
@@ -128,7 +150,7 @@ def roster_import(request):
|
|||||||
pass
|
pass
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
"gamechanger/roster.html",
|
"gamechanger/roster_import.html",
|
||||||
context={"roster": roster, "formset": formset},
|
context={"roster": roster, "formset": formset},
|
||||||
)
|
)
|
||||||
elif request.POST:
|
elif request.POST:
|
||||||
|
|||||||
Reference in New Issue
Block a user