a lot of teamsnap sync work. not entirely happy with all of it
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
# Generated by Django 3.2.6 on 2021-11-20 23:53
|
# Generated by Django 3.2.6 on 2021-12-17 21:35
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
@@ -9,31 +9,47 @@ class Migration(migrations.Migration):
|
|||||||
initial = True
|
initial = True
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('teams', '0001_initial'),
|
('benchcoach', '0001_initial'),
|
||||||
('players', '0003_player_team'),
|
|
||||||
('venues', '0001_initial'),
|
|
||||||
('events', '0004_delete_availability'),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='User',
|
name='Team',
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.CharField(max_length=50, primary_key=True, serialize=False, unique=True)),
|
||||||
('teamsnap_id', models.CharField(max_length=10)),
|
('name', models.CharField(max_length=50, null=True)),
|
||||||
('access_token', models.CharField(max_length=50)),
|
('created_at', models.DateTimeField(null=True)),
|
||||||
|
('updated_at', models.DateTimeField(null=True)),
|
||||||
|
('benchcoach_object', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='teamsnapteam', to='benchcoach.team')),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'abstract': False,
|
'abstract': False,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Team',
|
name='User',
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.CharField(max_length=50, primary_key=True, serialize=False, unique=True)),
|
||||||
('teamsnap_id', models.CharField(max_length=10)),
|
('created_at', models.DateTimeField(null=True)),
|
||||||
|
('updated_at', models.DateTimeField(null=True)),
|
||||||
|
('first_name', models.CharField(max_length=50, null=True)),
|
||||||
|
('last_name', models.CharField(max_length=50, null=True)),
|
||||||
|
('email', models.EmailField(max_length=254, null=True)),
|
||||||
|
('managed_teams', models.ManyToManyField(to='teamsnap.Team')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Opponent',
|
||||||
|
fields=[
|
||||||
|
('id', models.CharField(max_length=50, primary_key=True, serialize=False, unique=True)),
|
||||||
('name', models.CharField(max_length=50, null=True)),
|
('name', models.CharField(max_length=50, null=True)),
|
||||||
('team', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='teams.team')),
|
('created_at', models.DateTimeField(null=True)),
|
||||||
|
('updated_at', models.DateTimeField(null=True)),
|
||||||
|
('benchcoach_object', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='benchcoach.team')),
|
||||||
|
('managed_by_team', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='teamsnap.team')),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'abstract': False,
|
'abstract': False,
|
||||||
@@ -42,10 +58,15 @@ class Migration(migrations.Migration):
|
|||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Member',
|
name='Member',
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.CharField(max_length=50, primary_key=True, serialize=False, unique=True)),
|
||||||
('teamsnap_id', models.CharField(max_length=10)),
|
('created_at', models.DateTimeField(null=True)),
|
||||||
('name', models.CharField(max_length=50, null=True)),
|
('updated_at', models.DateTimeField(null=True)),
|
||||||
('player', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='players.player')),
|
('first_name', models.CharField(max_length=50, null=True)),
|
||||||
|
('last_name', models.CharField(max_length=50, null=True)),
|
||||||
|
('jersey_number', models.IntegerField(null=True)),
|
||||||
|
('is_non_player', models.BooleanField()),
|
||||||
|
('benchcoach_object', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='benchcoach.player')),
|
||||||
|
('managed_by_team', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='teamsnap.team')),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'abstract': False,
|
'abstract': False,
|
||||||
@@ -54,10 +75,12 @@ class Migration(migrations.Migration):
|
|||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Location',
|
name='Location',
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.CharField(max_length=50, primary_key=True, serialize=False, unique=True)),
|
||||||
('teamsnap_id', models.CharField(max_length=10)),
|
|
||||||
('name', models.CharField(max_length=50, null=True)),
|
('name', models.CharField(max_length=50, null=True)),
|
||||||
('venue', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='venues.venue')),
|
('created_at', models.DateTimeField(null=True)),
|
||||||
|
('updated_at', models.DateTimeField(null=True)),
|
||||||
|
('benchcoach_object', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='benchcoach.venue')),
|
||||||
|
('managed_by_team', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='teamsnap.team')),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'abstract': False,
|
'abstract': False,
|
||||||
@@ -66,17 +89,54 @@ class Migration(migrations.Migration):
|
|||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Event',
|
name='Event',
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.CharField(max_length=50, primary_key=True, serialize=False, unique=True)),
|
||||||
('teamsnap_id', models.CharField(max_length=10)),
|
('created_at', models.DateTimeField(null=True)),
|
||||||
('name', models.CharField(max_length=50, null=True)),
|
('updated_at', models.DateTimeField(null=True)),
|
||||||
('label', models.CharField(max_length=50, null=True)),
|
('label', models.CharField(max_length=50, null=True)),
|
||||||
('start_date', models.DateTimeField(null=True)),
|
('start_date', models.DateTimeField(null=True)),
|
||||||
('event', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='events.event')),
|
('formatted_title', models.CharField(max_length=50, null=True)),
|
||||||
|
('points_for_opponent', models.PositiveSmallIntegerField(null=True)),
|
||||||
|
('points_for_team', models.PositiveSmallIntegerField(null=True)),
|
||||||
|
('is_game', models.BooleanField()),
|
||||||
|
('benchcoach_object', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='teamsnap_event', to='benchcoach.event')),
|
||||||
('location', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='teamsnap.location')),
|
('location', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='teamsnap.location')),
|
||||||
('opponent', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='teamsnap.team')),
|
('managed_by_team', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='teamsnap.team')),
|
||||||
|
('opponent', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='opponent', to='teamsnap.opponent')),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'abstract': False,
|
'abstract': False,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Availability',
|
||||||
|
fields=[
|
||||||
|
('id', models.CharField(max_length=50, primary_key=True, serialize=False, unique=True)),
|
||||||
|
('created_at', models.DateTimeField(null=True)),
|
||||||
|
('updated_at', models.DateTimeField(null=True)),
|
||||||
|
('status_code', models.SmallIntegerField(choices=[(1, 'Yes'), (0, 'No'), (2, 'Maybe'), (None, 'Unknown')], default=None, null=True)),
|
||||||
|
('benchcoach_object', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='benchcoach.availability')),
|
||||||
|
('event', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='teamsnap.event')),
|
||||||
|
('managed_by_team', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='teamsnap.team')),
|
||||||
|
('member', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='teamsnap.member')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name_plural': 'availabilities',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='LineupEntry',
|
||||||
|
fields=[
|
||||||
|
('id', models.CharField(max_length=50, primary_key=True, serialize=False, unique=True)),
|
||||||
|
('created_at', models.DateTimeField(null=True)),
|
||||||
|
('updated_at', models.DateTimeField(null=True)),
|
||||||
|
('label', models.PositiveSmallIntegerField(blank=True, choices=[(11, 'EH'), (1, 'P'), (2, 'C'), (3, '1B'), (4, '2B'), (5, '3B'), (6, 'SS'), (7, 'LF'), (8, 'CF'), (9, 'RF'), (10, 'DH')], default=None, null=True)),
|
||||||
|
('sequence', models.PositiveSmallIntegerField(blank=True, default=0, null=True)),
|
||||||
|
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='teamsnap.event')),
|
||||||
|
('managed_by_team', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='teamsnap.team')),
|
||||||
|
('member', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='teamsnap.member')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'unique_together': {('member', 'event')},
|
||||||
|
},
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
{% block title %} {{ title }}{% endblock %}
|
{% block title %} {{ title }}{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<h1>Currently Logged in as</h1>
|
<h1>Currently Logged in as</h1>
|
||||||
<p><b>BenchCoach: </b>{{ user }} ({{ user.email }})</p>
|
<p><b>BenchCoach: </b>{{ user }} ({{ user.email }})</p>
|
||||||
<p><b>TeamSnap: </b>{{ teamsnap_user.email }}</p>
|
<p><b>TeamSnap: </b>{{ teamsnap_user.email }}</p>
|
||||||
@@ -14,29 +13,48 @@
|
|||||||
<span class="visually-hidden">Loading...</span>
|
<span class="visually-hidden">Loading...</span>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
<button type="button" class="btn btn-primary m-1" onclick="sync_teamsnap_db()">
|
||||||
<textarea id="output_box" name="comment" disabled class="w-100 m" style="min-height: 400px"></textarea>
|
Sync TeamSnap DB
|
||||||
<button type="button" class="btn btn-outline-secondary m-1" onclick="clear_output_box()">Clear</button>
|
<div id="teamsnap-sync-spinner" class="spinner-border spinner-border-sm d-none" role="status">
|
||||||
|
<span class="visually-hidden">Loading...</span>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
{% include 'messages.html' %}
|
||||||
|
<div id="message-area"> </div>
|
||||||
<script>
|
<script>
|
||||||
const output_box = document.getElementById("output_box");
|
|
||||||
const progress_spinner = document.getElementById("teamsnap-sync-spinner")
|
const progress_spinner = document.getElementById("teamsnap-sync-spinner")
|
||||||
|
const message_area = document.getElementById("message-area")
|
||||||
function sync_teamsnap_db(){
|
function sync_teamsnap_db(){
|
||||||
const Http = new XMLHttpRequest();
|
const Http = new XMLHttpRequest();
|
||||||
const url='{% url 'sync teamsnap' %}';
|
const url='{% url 'sync teamsnap db' %}';
|
||||||
console.log(progress_spinner)
|
console.log(progress_spinner)
|
||||||
progress_spinner.classList.remove("d-none");
|
progress_spinner.classList.remove("d-none");
|
||||||
fetch(url)
|
fetch(url)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
progress_spinner.classList.add("d-none")
|
progress_spinner.classList.add("d-none")
|
||||||
|
message_area.innerText = "test"
|
||||||
return response.json();
|
return response.json();
|
||||||
})
|
})
|
||||||
.then((myJson) => {
|
.then((myJson) => {
|
||||||
var s = 'Number of objects updated: '
|
console.log(myJson)
|
||||||
for (i in myJson) {
|
message_area.innerHTML = myJson.msg
|
||||||
s += myJson[i]
|
});
|
||||||
{#s += myJson[i].name +" ("+ myJson[i].id+")" + "\r\n"#}
|
|
||||||
}
|
}
|
||||||
output_box.value = s;
|
|
||||||
|
function sync_teamsnap_db_2(){
|
||||||
|
const Http = new XMLHttpRequest();
|
||||||
|
const url='{% url 'sync teamsnap db' %}';
|
||||||
|
console.log(progress_spinner)
|
||||||
|
progress_spinner.classList.remove("d-none");
|
||||||
|
fetch(url)
|
||||||
|
.then((response) => {
|
||||||
|
progress_spinner.classList.add("d-none")
|
||||||
|
message_area.innerText = "test"
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then((myJson) => {
|
||||||
|
console.log(myJson)
|
||||||
|
message_area.innerHTML = myJson.msg
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{% extends 'base.html' %}{% block title %} {{ title }} {% endblock %}{% load crispy_forms_tags %}{% load static %}
|
{% extends 'base.html' %}{% block title %} {{ title }} {% endblock %}{% load static %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="w-100 text-center mx-auto text-center">
|
<div class="w-100 text-center mx-auto text-center">
|
||||||
|
|||||||
@@ -10,6 +10,6 @@ urlpatterns = [
|
|||||||
path('events', views.EventsListView.as_view(), name="teamsnap list events"),
|
path('events', views.EventsListView.as_view(), name="teamsnap list events"),
|
||||||
path('events-table', views.EventsTableView.as_view(), name="teamsnap table events"),
|
path('events-table', views.EventsTableView.as_view(), name="teamsnap table events"),
|
||||||
path('edit/event/<int:id>', views.edit_event, name='teamsnap edit event'),
|
path('edit/event/<int:id>', views.edit_event, name='teamsnap edit event'),
|
||||||
path('from_teamsnap', views.sync_teamsnap, name="sync teamsnap"),
|
path('sync_teamsnap_db', views.sync_teamsnap_db, name="sync teamsnap db"),
|
||||||
# path('import_teamsnap', views.import_teamsnap, name="import teamsnap"),
|
# path('import_teamsnap', views.import_teamsnap, name="import teamsnap"),
|
||||||
]
|
]
|
||||||
@@ -1,156 +1,185 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "benchcoach.settings")
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "benchcoachproject.settings")
|
||||||
os.environ["DJANGO_SETTINGS_MODULE"] = "benchcoach.settings"
|
os.environ["DJANGO_SETTINGS_MODULE"] = "benchcoachproject.settings"
|
||||||
import django
|
import django
|
||||||
django.setup()
|
django.setup()
|
||||||
|
|
||||||
from teamsnap.teamsnap.api import TeamSnap
|
from teamsnap.teamsnap.api import TeamSnap
|
||||||
import teamsnap.teamsnap.api
|
import teamsnap.teamsnap.api
|
||||||
from teamsnap.models import User, Member, Team, Event, Location, Availability, Opponent
|
from teamsnap.models import User, Member, Team, Event, Location, Availability, Opponent, TeamsnapBaseModel
|
||||||
from typing import List
|
from typing import List
|
||||||
from benchcoach.models import Profile as BenchcoachUser
|
from benchcoachproject.models import Profile as BenchcoachUser
|
||||||
from teams.models import Team as BenchcoachTeam
|
import benchcoach.models
|
||||||
from events.models import Event as BenchcoachEvent
|
from django.db import models
|
||||||
import pytz
|
import pytz
|
||||||
|
|
||||||
def update_object_from_teamsnap(
|
def update_teamsnap_object(d, teamsnap_object: TeamsnapBaseModel, benchcoach_model: models.Model ,create_benchcoach_object: bool = True, create_related: bool = False):
|
||||||
TeamsnapApiObject: teamsnap.teamsnap.api.ApiObject,
|
''' Function to update from a teamsnap object to Benchcoach object. This method is a simple method when there are no related objects
|
||||||
TeamsnapDbModelClass: teamsnap.models.TeamsnapBaseModel,
|
|
||||||
TeamsnapClient: teamsnap.teamsnap.api.TeamSnap,
|
|
||||||
teamsnap_search_kwargs: dict,
|
|
||||||
fetching_keys: List[tuple] = ['id'],
|
|
||||||
default_keys: List[tuple] = ['name']
|
|
||||||
):
|
|
||||||
|
|
||||||
"""
|
:param d: The information to update.
|
||||||
Import or Update database objects from TeamSnap API
|
:param teamsnap_object: The teamsnap object from which to update.
|
||||||
|
:param create_benchcoach_object: If true, will create the benchcoach object if it doesn't exist
|
||||||
additional_fetching_keys (key,) or (api_key, db_field_name) or (api_key, db_field_name, callable)
|
:param create_related: This is here for decoration only. It doesn't do anything.
|
||||||
Additional kwargs used to fetch an object from the database. ('id', 'teamsnap_id') are already included
|
:return: a list of tuples in the form (obj, did_create) for created or modified objects.
|
||||||
Callable will be run with the retrieved value as an argument. Example uses for this callable are to sanitize the value
|
'''
|
||||||
such as for a date, or to retrieve another database object
|
|
||||||
|
|
||||||
additional_default_keys
|
|
||||||
Additional Keys used to update the object (key,) or (api_key, db_field_name) or (api_key, db_field_name, callable)
|
|
||||||
('name',) is already included
|
|
||||||
Callable will be run with the retrieved value as an argument. Example uses for this callable are to sanitize the value
|
|
||||||
such as for a date, or to retrieve another database object
|
|
||||||
|
|
||||||
:rtype: object
|
|
||||||
"""
|
|
||||||
api_response = TeamsnapApiObject.search(client=TeamsnapClient, **teamsnap_search_kwargs)
|
|
||||||
|
|
||||||
# This routine allows, for convenience, simplers tuples in which the additional detail is not needed
|
|
||||||
# for example [('key', 'key', None)] can be passed as ['key'] if the TeamsnapApi key is the same as the TeamsnapDb field/key
|
|
||||||
# and doesn't need to be sanitized
|
|
||||||
for d in [fetching_keys, fetching_keys, default_keys]:
|
|
||||||
for i, key in enumerate(d):
|
|
||||||
if isinstance(key, tuple):
|
|
||||||
if len(key) == 1:
|
|
||||||
d[i] = (key[0], key[0], None)
|
|
||||||
if len(key) == 2:
|
|
||||||
d[i] = (key[0], key[1], None)
|
|
||||||
elif isinstance(key, str):
|
|
||||||
d[i] = (key, key, None)
|
|
||||||
|
|
||||||
r = []
|
r = []
|
||||||
for data in [items.data for items in api_response]:
|
|
||||||
kwargs, defaults = {}, {}
|
if teamsnap_object.benchcoach_object:
|
||||||
for api_key, db_field_name, callable_function in fetching_keys:
|
#TODO I'm not sure this does anything. need to make sure.
|
||||||
if api_key in data.keys():
|
benchcoach_object = benchcoach_model.objects.filter(id=teamsnap_object.benchcoach_object.id).first()
|
||||||
kwargs[db_field_name] = callable_function(data[api_key]) if callable_function else data[api_key]
|
created = False
|
||||||
for api_key, db_field_name, callable_function in default_keys:
|
r.append((benchcoach_object, created))
|
||||||
if api_key in data.keys():
|
elif not teamsnap_object.benchcoach_object and create_benchcoach_object:
|
||||||
defaults[db_field_name] = callable_function(data[api_key]) if callable_function else data[api_key]
|
benchcoach_object = benchcoach_model(**d) # create new benchcoach object
|
||||||
defaults ={k:v for k,v in defaults.items() if v is not None}
|
teamsnap_object.benchcoach_object = benchcoach_object
|
||||||
obj, created = TeamsnapDbModelClass.objects.update_or_create(**kwargs, defaults=defaults)
|
benchcoach_object.save()
|
||||||
r.append((obj,created))
|
teamsnap_object.save()
|
||||||
|
created = True
|
||||||
|
r.append((benchcoach_object, created))
|
||||||
|
elif not teamsnap_object.benchcoach_object:
|
||||||
|
raise benchcoach.models.Team.DoesNotExist
|
||||||
|
|
||||||
return r
|
return r
|
||||||
|
|
||||||
def update_locations (client, **kwargs):
|
def update_event(event: Event, create_benchcoach_object: bool = True, create_related=False):
|
||||||
return update_object_from_teamsnap(
|
benchcoach_model = benchcoach.models.Event
|
||||||
teamsnap.teamsnap.api.Location,
|
|
||||||
Location,
|
|
||||||
TeamsnapClient=client,
|
|
||||||
teamsnap_search_kwargs=kwargs,
|
|
||||||
default_keys=[
|
|
||||||
'name', 'created_at', 'updated_at',
|
|
||||||
('team_id', 'managed_by_team_id')
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
def update_teams (client, **kwargs):
|
d = {
|
||||||
teams = update_object_from_teamsnap(
|
'start': event.start_date,
|
||||||
teamsnap.teamsnap.api.Team,
|
}
|
||||||
Team,
|
|
||||||
TeamsnapClient=client,
|
|
||||||
teamsnap_search_kwargs=kwargs,
|
|
||||||
default_keys=[
|
|
||||||
'name', 'created_at', 'updated_at',
|
|
||||||
('team_id', 'managed_by_team_id')
|
|
||||||
]
|
|
||||||
)
|
|
||||||
opponents = update_object_from_teamsnap(
|
|
||||||
teamsnap.teamsnap.api.Opponent,
|
|
||||||
Opponent,
|
|
||||||
TeamsnapClient=client,
|
|
||||||
teamsnap_search_kwargs=kwargs,
|
|
||||||
default_keys= [
|
|
||||||
'name', 'created_at', 'updated_at',
|
|
||||||
('team_id', 'managed_by_team_id')
|
|
||||||
]
|
|
||||||
)
|
|
||||||
return teams + opponents
|
|
||||||
|
|
||||||
def update_members (client, **kwargs):
|
r = []
|
||||||
return update_object_from_teamsnap(
|
|
||||||
TeamsnapApiObject=teamsnap.teamsnap.api.Member,
|
if event.team:
|
||||||
TeamsnapDbModelClass=Member,
|
if event.team.benchcoach_object:
|
||||||
TeamsnapClient=client,
|
if event.game_type == "Home":
|
||||||
teamsnap_search_kwargs=kwargs,
|
d['home_team'] = event.team.benchcoach_object
|
||||||
default_keys=['first_name','last_name','jersey_number','is_non_player', 'created_at', 'updated_at',
|
elif event.game_type == "Away":
|
||||||
('team_id', 'managed_by_team_id'),
|
d['away_team'] = event.team.benchcoach_object
|
||||||
]
|
elif not event.team.benchcoach_object and create_related:
|
||||||
)
|
# create team object
|
||||||
|
# update_opponent
|
||||||
|
# r.append
|
||||||
pass
|
pass
|
||||||
|
elif not event.team.benchcoach_object:
|
||||||
|
raise benchcoach.models.Team.DoesNotExist
|
||||||
|
|
||||||
def update_availabilities(client, **kwargs):
|
if event.opponent:
|
||||||
return update_object_from_teamsnap(
|
if event.opponent.benchcoach_object:
|
||||||
TeamsnapApiObject=teamsnap.teamsnap.api.Availability,
|
if event.game_type == 'Home':
|
||||||
TeamsnapDbModelClass=Availability,
|
d['away_team'] = event.opponent.benchcoach_object
|
||||||
TeamsnapClient=client,
|
elif event.game_type == 'Away':
|
||||||
teamsnap_search_kwargs=kwargs,
|
d['home_team'] = event.opponent.benchcoach_object
|
||||||
default_keys=[ 'status_code',
|
elif not event.opponent.benchcoach_object and create_related:
|
||||||
'member_id',
|
# Create opponent object
|
||||||
'event_id',
|
# update_opponent()
|
||||||
'created_at',
|
# r.append
|
||||||
'updated_at',
|
pass
|
||||||
('team_id', 'managed_by_team_id')
|
elif not event.opponent.benchcoach_object:
|
||||||
]
|
raise benchcoach.models.Team.DoesNotExist
|
||||||
)
|
|
||||||
|
|
||||||
def update_events(client, **kwargs):
|
if event.location:
|
||||||
return update_object_from_teamsnap(
|
if event.location.benchcoach_object:
|
||||||
TeamsnapApiObject=teamsnap.teamsnap.api.Event,
|
if event.location:
|
||||||
TeamsnapDbModelClass=Event,
|
d['venue'] = event.location.benchcoach_object
|
||||||
TeamsnapClient=client,
|
elif not event.location.benchcoach_object and create_related:
|
||||||
teamsnap_search_kwargs=kwargs,
|
# Need to account for if no loacation assigned to teamsnap object.
|
||||||
default_keys=['formatted_title','label','points_for_opponent','points_for_team','is_game','opponent_id','location_id',
|
# create team object
|
||||||
'start_date', 'created_at', 'updated_at',
|
# update_opponent
|
||||||
('team_id', 'managed_by_team_id')
|
# r.append
|
||||||
]
|
pass
|
||||||
)
|
elif not event.location.benchcoach_object:
|
||||||
|
raise benchcoach.models.Venue.DoesNotExist
|
||||||
|
|
||||||
|
r += update_teamsnap_object(d, teamsnap_object=event, benchcoach_model=benchcoach_model, create_benchcoach_object=create_benchcoach_object)
|
||||||
|
|
||||||
|
return r
|
||||||
|
|
||||||
|
def update_opponent(opponent: Opponent, create_benchcoach_object: bool = True, create_related: bool = False):
|
||||||
|
benchcoach_model = benchcoach.models.Team
|
||||||
|
d = {
|
||||||
|
'name': opponent.name,
|
||||||
|
}
|
||||||
|
|
||||||
|
r = update_teamsnap_object(d, teamsnap_object=opponent, benchcoach_model=benchcoach_model, create_benchcoach_object= create_benchcoach_object, create_related = create_related)
|
||||||
|
|
||||||
|
return r
|
||||||
|
|
||||||
|
def update_team(teamsnap_object: Team, create_benchcoach_object: bool = True, create_related: bool = False):
|
||||||
|
benchcoach_model = benchcoach.models.Team
|
||||||
|
d = {
|
||||||
|
'name': teamsnap_object.name,
|
||||||
|
}
|
||||||
|
|
||||||
|
r = update_teamsnap_object(d, teamsnap_object=teamsnap_object, benchcoach_model=benchcoach_model, create_benchcoach_object=create_benchcoach_object,
|
||||||
|
create_related=create_related)
|
||||||
|
|
||||||
|
return r
|
||||||
|
|
||||||
|
def update_location(teamsnap_object: Location, create_benchcoach_object: bool = True, create_related: bool = False):
|
||||||
|
benchcoach_model = benchcoach.models.Venue
|
||||||
|
d = {
|
||||||
|
'name': teamsnap_object.name,
|
||||||
|
}
|
||||||
|
|
||||||
|
r = update_teamsnap_object(d, teamsnap_object=teamsnap_object, benchcoach_model=benchcoach_model, create_benchcoach_object=create_benchcoach_object,
|
||||||
|
create_related=create_related)
|
||||||
|
|
||||||
|
return r
|
||||||
|
|
||||||
|
def update_member(teamsnap_object: Member, create_benchcoach_object: bool = True, create_related: bool = False):
|
||||||
|
benchcoach_model = benchcoach.models.Player
|
||||||
|
d = {
|
||||||
|
'first_name': teamsnap_object.first_name,
|
||||||
|
'last_name': teamsnap_object.last_name,
|
||||||
|
'jersey_number': teamsnap_object.jersey_number,
|
||||||
|
}
|
||||||
|
|
||||||
|
r = update_teamsnap_object(d, teamsnap_object=teamsnap_object, benchcoach_model=benchcoach_model, create_benchcoach_object=create_benchcoach_object,
|
||||||
|
create_related=create_related)
|
||||||
|
|
||||||
|
return r
|
||||||
|
|
||||||
|
def update_availability(availability: Availability, create_benchcoach_object: bool = True, create_related: bool = False):
|
||||||
|
benchcoach_model = benchcoach.models.Availability
|
||||||
|
translation = {
|
||||||
|
Availability.YES: benchcoach.models.Availability.YES,
|
||||||
|
Availability.NO: benchcoach.models.Availability.NO,
|
||||||
|
Availability.MAYBE: benchcoach.models.Availability.MAYBE
|
||||||
|
}
|
||||||
|
|
||||||
|
d = {
|
||||||
|
'available': translation.get(availability.status_code, benchcoach.models.Availability.UNKNOWN),
|
||||||
|
'player': availability.member.benchcoach_object,
|
||||||
|
'event': availability.event.benchcoach_object
|
||||||
|
}
|
||||||
|
|
||||||
|
r = []
|
||||||
|
|
||||||
|
if availability.member.benchcoach_object:
|
||||||
|
d['player'] = availability.member.benchcoach_object
|
||||||
|
elif not availability.member.benchcoach_object and create_related:
|
||||||
|
r += update_member(availability.member, create_benchcoach_object = True)
|
||||||
|
d['player'] = availability.member.benchcoach_object
|
||||||
|
elif not availability.member.benchcoach_object and not create_related:
|
||||||
|
raise benchcoach.models.Availability.DoesNotExist
|
||||||
|
|
||||||
|
if availability.event.benchcoach_object:
|
||||||
|
d['event'] = availability.event.benchcoach_object
|
||||||
|
elif not availability.event.benchcoach_object and create_related:
|
||||||
|
r += update_event(availability.member, create_benchcoach_object = True)
|
||||||
|
d['event'] = availability.event.benchcoach_object
|
||||||
|
elif not availability.event.benchcoach_object and not create_related:
|
||||||
|
raise benchcoach.models.Event.DoesNotExist
|
||||||
|
|
||||||
|
r += update_teamsnap_object(d, teamsnap_object=availability, benchcoach_model=benchcoach_model, create_benchcoach_object=create_benchcoach_object,
|
||||||
|
create_related=create_related)
|
||||||
|
|
||||||
|
return r
|
||||||
|
|
||||||
def update_users(client, **kwargs):
|
|
||||||
return update_object_from_teamsnap(
|
|
||||||
TeamsnapApiObject=teamsnap.teamsnap.api.User,
|
|
||||||
TeamsnapDbModelClass=User,
|
|
||||||
TeamsnapClient=client,
|
|
||||||
teamsnap_search_kwargs=kwargs,
|
|
||||||
default_keys=['first_name', 'last_name', 'email', 'created_at', 'updated_at',]
|
|
||||||
)
|
|
||||||
|
|
||||||
def import_teamsnap():
|
def import_teamsnap():
|
||||||
user = BenchcoachUser.objects.get(id=1)
|
user = BenchcoachUser.objects.get(id=1)
|
||||||
@@ -158,33 +187,25 @@ def import_teamsnap():
|
|||||||
USER_ID = user.teamsnap_user.id
|
USER_ID = user.teamsnap_user.id
|
||||||
TEAM_ID = user.teamsnapsettings.managed_team.id
|
TEAM_ID = user.teamsnapsettings.managed_team.id
|
||||||
CLIENT = TeamSnap(token=TOKEN)
|
CLIENT = TeamSnap(token=TOKEN)
|
||||||
update_users(CLIENT, id=USER_ID)
|
|
||||||
|
|
||||||
l = []
|
l = []
|
||||||
for team in Opponent.objects.filter(managed_by_team_id=TEAM_ID):
|
for team in Opponent.objects.filter(team_id=TEAM_ID):
|
||||||
d = {
|
l += update_opponent(team, create_benchcoach_object=True, create_related=True)
|
||||||
'name': team.name,
|
|
||||||
}
|
|
||||||
obj, created = BenchcoachTeam.objects.update_or_create(opponent=team, defaults=d)
|
|
||||||
team.benchcoach_object = obj
|
|
||||||
team.save()
|
|
||||||
l.append((obj,created))
|
|
||||||
|
|
||||||
for team in Team.objects.filter(id=TEAM_ID):
|
for team in Team.objects.filter(id=TEAM_ID):
|
||||||
d = {
|
l += update_team(team, create_benchcoach_object=True, create_related=True)
|
||||||
'name': team.name,
|
|
||||||
}
|
|
||||||
obj_id = BenchcoachTeam.objects.filter(id=team.benchcoach_object.id).update(**d)
|
|
||||||
team.benchcoach_object = BenchcoachTeam.objects.get(id=obj_id)
|
|
||||||
team.save()
|
|
||||||
l.append((obj,created))
|
|
||||||
|
|
||||||
for event in Event.objects.filter(managed_by_team_id=TEAM_ID):
|
for location in Location.objects.filter(team_id=TEAM_ID):
|
||||||
d = {
|
l += update_location(location, create_benchcoach_object=True, create_related=True)
|
||||||
'start':event.start_date,
|
|
||||||
}
|
for member in Member.objects.filter(team_id=TEAM_ID, is_non_player=False):
|
||||||
obj, created = BenchcoachEvent.objects.update_or_create(teamsnap_event=event, defaults=d)
|
l += update_member(member, create_benchcoach_object= True, create_related=True)
|
||||||
# event.benchcoach_object = obj
|
|
||||||
|
for event in Event.objects.filter(team_id=TEAM_ID):
|
||||||
|
l += update_event(event, create_benchcoach_object=True, create_related=True)
|
||||||
|
|
||||||
|
for availability in Availability.objects.filter(team_id=TEAM_ID):
|
||||||
|
l += update_availability(availability, create_benchcoach_object=True, create_related=True)
|
||||||
|
|
||||||
pass
|
pass
|
||||||
# l += update_teams(CLIENT, team_id=TEAM_ID)
|
# l += update_teams(CLIENT, team_id=TEAM_ID)
|
||||||
|
|||||||
198
teamsnap/utils/import_teamsnap_2.py
Normal file
198
teamsnap/utils/import_teamsnap_2.py
Normal file
@@ -0,0 +1,198 @@
|
|||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "benchcoachproject.settings")
|
||||||
|
os.environ["DJANGO_SETTINGS_MODULE"] = "benchcoachproject.settings"
|
||||||
|
import django
|
||||||
|
django.setup()
|
||||||
|
|
||||||
|
from teamsnap.teamsnap.api import TeamSnap
|
||||||
|
import teamsnap.teamsnap.api
|
||||||
|
from teamsnap.models import User, Member, Team, Event, Location, Availability, Opponent, TeamsnapBaseModel
|
||||||
|
from typing import List, Type, Tuple
|
||||||
|
from benchcoachproject.models import Profile as BenchcoachUser
|
||||||
|
import benchcoach.models
|
||||||
|
from django.db import models
|
||||||
|
import pytz
|
||||||
|
|
||||||
|
def update_teamsnapbasemodel_from_teamsnap(
|
||||||
|
TeamsnapModel: Type[TeamsnapBaseModel],
|
||||||
|
teamsnap_client: teamsnap.teamsnap.api.TeamSnap,
|
||||||
|
fields: List[str]= ['created_at', 'updated_at'],
|
||||||
|
additional_fields: List[str] = [],
|
||||||
|
related_fields: List[Tuple[str, Type[TeamsnapBaseModel]]] = [],
|
||||||
|
create = True,
|
||||||
|
create_related = True,
|
||||||
|
**teamsnap_search_kwargs
|
||||||
|
):
|
||||||
|
api_response_objects = TeamsnapModel.ApiObject.search(
|
||||||
|
client=teamsnap_client, **teamsnap_search_kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
r = []
|
||||||
|
|
||||||
|
for response_object in api_response_objects:
|
||||||
|
d = {k:response_object.data[k] for k in fields}
|
||||||
|
d.update({k:response_object.data[k] for k in additional_fields})
|
||||||
|
|
||||||
|
for related_field_name, RelatedTeamSnapModel in related_fields:
|
||||||
|
related_field_name = f"{related_field_name}_id"
|
||||||
|
filter_criteria = {related_field_name:response_object.data[related_field_name]}
|
||||||
|
if related_field_name == "team_id" and RelatedTeamSnapModel.__name__ == "Team":
|
||||||
|
filter_criteria = {'id':response_object.data[related_field_name]}
|
||||||
|
related_teamsnap_object = RelatedTeamSnapModel.objects.filter(**filter_criteria).first()
|
||||||
|
if related_teamsnap_object:
|
||||||
|
d[related_field_name] = related_teamsnap_object
|
||||||
|
elif not related_teamsnap_object and create_related:
|
||||||
|
related_teamsnap_object = RelatedTeamSnapModel(**{related_field_name:response_object.data[related_field_name]})
|
||||||
|
related_teamsnap_object.save()
|
||||||
|
elif not related_teamsnap_object and not create_related:
|
||||||
|
raise RelatedTeamSnapModel.DoesNotExist
|
||||||
|
|
||||||
|
teamsnap_object = TeamsnapModel.objects.filter(id=response_object.data['id'])
|
||||||
|
if teamsnap_object:
|
||||||
|
teamsnap_object.update(**d)
|
||||||
|
created = False
|
||||||
|
r.append((teamsnap_object.first(), created))
|
||||||
|
elif not teamsnap_object and create:
|
||||||
|
new_teamsnap_object = TeamsnapModel(**d) # create new benchcoach object
|
||||||
|
new_teamsnap_object.save()
|
||||||
|
created = True
|
||||||
|
r.append((new_teamsnap_object, created))
|
||||||
|
elif not teamsnap_object and not create:
|
||||||
|
raise TeamsnapModel.DoesNotExist
|
||||||
|
|
||||||
|
return r
|
||||||
|
|
||||||
|
def update_events(
|
||||||
|
teamsnap_client: teamsnap.teamsnap.api.TeamSnap,
|
||||||
|
create: bool = True,
|
||||||
|
create_related: bool = False,
|
||||||
|
**teamsnap_search_kwargs
|
||||||
|
):
|
||||||
|
r = update_teamsnapbasemodel_from_teamsnap(
|
||||||
|
TeamsnapModel= Event,
|
||||||
|
teamsnap_client= teamsnap_client,
|
||||||
|
additional_fields=['label', 'start_date', 'formatted_title', 'points_for_opponent', 'points_for_team', 'is_game', 'game_type'],
|
||||||
|
related_fields=[('location', Location), ('opponent', Opponent), ('team', Team)],
|
||||||
|
create=create,
|
||||||
|
create_related=create_related,
|
||||||
|
**teamsnap_search_kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
return r
|
||||||
|
|
||||||
|
def update_opponents(
|
||||||
|
teamsnap_client: teamsnap.teamsnap.api.TeamSnap,
|
||||||
|
create: bool = True,
|
||||||
|
create_related: bool = False,
|
||||||
|
**teamsnap_search_kwargs
|
||||||
|
):
|
||||||
|
r = update_teamsnapbasemodel_from_teamsnap(
|
||||||
|
TeamsnapModel= Opponent,
|
||||||
|
teamsnap_client= teamsnap_client,
|
||||||
|
additional_fields=['name'],
|
||||||
|
related_fields=[('team', Team)],
|
||||||
|
create=create,
|
||||||
|
create_related=create_related,
|
||||||
|
**teamsnap_search_kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
return r
|
||||||
|
|
||||||
|
def update_teams(
|
||||||
|
teamsnap_client: teamsnap.teamsnap.api.TeamSnap,
|
||||||
|
create: bool = True,
|
||||||
|
create_related: bool = False,
|
||||||
|
**teamsnap_search_kwargs
|
||||||
|
):
|
||||||
|
r = update_teamsnapbasemodel_from_teamsnap(
|
||||||
|
TeamsnapModel=Team,
|
||||||
|
teamsnap_client=teamsnap_client,
|
||||||
|
additional_fields=['name'],
|
||||||
|
create=create,
|
||||||
|
create_related=create_related,
|
||||||
|
**teamsnap_search_kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def update_locations(
|
||||||
|
teamsnap_client: teamsnap.teamsnap.api.TeamSnap,
|
||||||
|
create: bool = True,
|
||||||
|
create_related: bool = False,
|
||||||
|
**teamsnap_search_kwargs
|
||||||
|
):
|
||||||
|
r = update_teamsnapbasemodel_from_teamsnap(
|
||||||
|
TeamsnapModel=Location,
|
||||||
|
teamsnap_client=teamsnap_client,
|
||||||
|
additional_fields=['name'],
|
||||||
|
related_fields=[('team', Team)],
|
||||||
|
create=create,
|
||||||
|
create_related=create_related,
|
||||||
|
**teamsnap_search_kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
def update_availabilities(teamsnap_client: teamsnap.teamsnap.api.TeamSnap,
|
||||||
|
create: bool = True,
|
||||||
|
create_related: bool = False,
|
||||||
|
**teamsnap_search_kwargs
|
||||||
|
):
|
||||||
|
r = update_teamsnapbasemodel_from_teamsnap(
|
||||||
|
TeamsnapModel= Availability,
|
||||||
|
teamsnap_client= teamsnap_client,
|
||||||
|
related_fields=[('event', Event), ('member', Member), ('team', Team)],
|
||||||
|
create=create,
|
||||||
|
create_related=create_related,
|
||||||
|
**teamsnap_search_kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
def import_teamsnap():
|
||||||
|
user = BenchcoachUser.objects.get(id=1)
|
||||||
|
TOKEN = user.teamsnap_access_token
|
||||||
|
USER_ID = user.teamsnap_user.id
|
||||||
|
TEAM_ID = user.teamsnapsettings.managed_team.id
|
||||||
|
CLIENT = TeamSnap(token=TOKEN)
|
||||||
|
|
||||||
|
l = []
|
||||||
|
for team in Opponent.objects.filter(managed_by_team_id=TEAM_ID):
|
||||||
|
l += update_opponent(team, create_benchcoach_object=True, create_related=True)
|
||||||
|
|
||||||
|
for team in Team.objects.filter(id=TEAM_ID):
|
||||||
|
l += update_team(team, create_benchcoach_object=True, create_related=True)
|
||||||
|
|
||||||
|
for location in Location.objects.filter(managed_by_team_id=TEAM_ID):
|
||||||
|
l += update_location(location, create_benchcoach_object=True, create_related=True)
|
||||||
|
|
||||||
|
for member in Member.objects.filter(managed_by_team_id=TEAM_ID, is_non_player=False):
|
||||||
|
l += update_member(member, create_benchcoach_object= True, create_related=True)
|
||||||
|
|
||||||
|
for event in Event.objects.filter(managed_by_team_id=TEAM_ID):
|
||||||
|
l += update_event(event, create_benchcoach_object=True, create_related=True)
|
||||||
|
|
||||||
|
for availability in Availability.objects.filter(managed_by_team_id=TEAM_ID):
|
||||||
|
l += update_availability(availability, create_benchcoach_object=True, create_related=True)
|
||||||
|
|
||||||
|
pass
|
||||||
|
# l += update_teams(CLIENT, team_id=TEAM_ID)
|
||||||
|
# l += update_members(CLIENT, team_id=TEAM_ID)
|
||||||
|
# l += update_locations(CLIENT, team_id=TEAM_ID)
|
||||||
|
# l += update_events(CLIENT, team_id=TEAM_ID)
|
||||||
|
# l += update_availabilities(CLIENT, team_id=TEAM_ID)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
|
||||||
|
TOKEN = BenchcoachUser.objects.get(id=1).teamsnap_access_token
|
||||||
|
USER_ID = BenchcoachUser.objects.get(id=1).teamsnap_user_id
|
||||||
|
TEAM_ID = BenchcoachUser.objects.get(id=1).teamsnapsettings.managed_team_id
|
||||||
|
CLIENT = TeamSnap(token=TOKEN)
|
||||||
|
for Obj in [User]:
|
||||||
|
a = Obj.ApiObject.search(CLIENT, id=USER_ID)
|
||||||
|
for _a in a:
|
||||||
|
obj, created = Obj.update_or_create_from_teamsnap_api(_a.data)
|
||||||
|
|
||||||
|
for Obj in [Event, Availability, Location, Member, Opponent, Team]:
|
||||||
|
a = Obj.ApiObject.search(CLIENT, team_id=TEAM_ID)
|
||||||
|
for _a in a:
|
||||||
|
obj, created = Obj.update_or_create_from_teamsnap_api(_a.data)
|
||||||
|
# update_opponents(CLIENT, team_id=TEAM_ID)
|
||||||
|
# update_events(CLIENT, team_id=TEAM_ID)
|
||||||
165
teamsnap/utils/teamsnap_object_utils.py
Normal file
165
teamsnap/utils/teamsnap_object_utils.py
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "benchcoachproject.settings")
|
||||||
|
os.environ["DJANGO_SETTINGS_MODULE"] = "benchcoachproject.settings"
|
||||||
|
import django
|
||||||
|
django.setup()
|
||||||
|
|
||||||
|
from teamsnap.teamsnap.api import TeamSnap
|
||||||
|
import teamsnap.teamsnap.api
|
||||||
|
from teamsnap.models import User, Member, Team, Event, Location, Availability, Opponent, TeamsnapBaseModel
|
||||||
|
from typing import List
|
||||||
|
from benchcoachproject.models import Profile as BenchcoachUser
|
||||||
|
|
||||||
|
|
||||||
|
def update_object_from_teamsnap(
|
||||||
|
TeamsnapApiObject: teamsnap.teamsnap.api.ApiObject,
|
||||||
|
TeamsnapDbModelClass: teamsnap.models.TeamsnapBaseModel,
|
||||||
|
TeamsnapClient: teamsnap.teamsnap.api.TeamSnap,
|
||||||
|
teamsnap_search_kwargs: dict,
|
||||||
|
fetching_keys: List[tuple] = ['id'],
|
||||||
|
default_keys: List[tuple] = ['name'],
|
||||||
|
related_objects: List[tuple] = []
|
||||||
|
):
|
||||||
|
|
||||||
|
"""
|
||||||
|
Import or Update database objects from TeamSnap API. Currently this depends on being run in a particular order when the database is empty.
|
||||||
|
|
||||||
|
additional_fetching_keys (key,) or (api_key, db_field_name) or (api_key, db_field_name, callable)
|
||||||
|
Additional kwargs used to fetch an object from the database. ('id', 'teamsnap_id') are already included
|
||||||
|
Callable will be run with the retrieved value as an argument. Example uses for this callable are to sanitize the value
|
||||||
|
such as for a date, or to retrieve another database object
|
||||||
|
|
||||||
|
additional_default_keys
|
||||||
|
Additional Keys used to update the object (key,) or (api_key, db_field_name) or (api_key, db_field_name, callable)
|
||||||
|
('name',) is already included
|
||||||
|
Callable will be run with the retrieved value as an argument. Example uses for this callable are to sanitize the value
|
||||||
|
such as for a date, or to retrieve another database object
|
||||||
|
|
||||||
|
:rtype: object
|
||||||
|
"""
|
||||||
|
api_response = TeamsnapApiObject.search(client=TeamsnapClient, **teamsnap_search_kwargs)
|
||||||
|
|
||||||
|
# This routine allows, for convenience, simplers tuples in which the additional detail is not needed
|
||||||
|
# for example [('key', 'key', None)] can be passed as ['key'] if the TeamsnapApi key is the same as the TeamsnapDb field/key
|
||||||
|
# and doesn't need to be sanitized
|
||||||
|
for d in [fetching_keys, fetching_keys, default_keys]:
|
||||||
|
for i, key in enumerate(d):
|
||||||
|
if isinstance(key, tuple):
|
||||||
|
if len(key) == 1:
|
||||||
|
d[i] = (key[0], key[0], None)
|
||||||
|
if len(key) == 2:
|
||||||
|
d[i] = (key[0], key[1], None)
|
||||||
|
elif isinstance(key, str):
|
||||||
|
d[i] = (key, key, None)
|
||||||
|
|
||||||
|
r = []
|
||||||
|
for related_object in related_objects:
|
||||||
|
pass
|
||||||
|
|
||||||
|
for data in [items.data for items in api_response]:
|
||||||
|
kwargs, defaults = {}, {}
|
||||||
|
for api_key, db_field_name, callable_function in fetching_keys:
|
||||||
|
if api_key in data.keys():
|
||||||
|
kwargs[db_field_name] = callable_function(data[api_key]) if callable_function else data[api_key]
|
||||||
|
for api_key, db_field_name, callable_function in default_keys:
|
||||||
|
if api_key in data.keys():
|
||||||
|
defaults[db_field_name] = callable_function(data[api_key]) if callable_function else data[api_key]
|
||||||
|
defaults ={k:v for k,v in defaults.items() if v is not None}
|
||||||
|
obj, created = TeamsnapDbModelClass.objects.update_or_create(**kwargs, defaults=defaults)
|
||||||
|
r.append((obj,created))
|
||||||
|
return r
|
||||||
|
|
||||||
|
def update_locations (client, **kwargs):
|
||||||
|
return update_object_from_teamsnap(
|
||||||
|
teamsnap.teamsnap.api.Location,
|
||||||
|
Location,
|
||||||
|
TeamsnapClient=client,
|
||||||
|
teamsnap_search_kwargs=kwargs,
|
||||||
|
default_keys=[
|
||||||
|
'name', 'created_at', 'updated_at',
|
||||||
|
('team_id', 'managed_by_team_id')
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
def update_teams (client, **kwargs):
|
||||||
|
teams = update_object_from_teamsnap(
|
||||||
|
teamsnap.teamsnap.api.Team,
|
||||||
|
Team,
|
||||||
|
TeamsnapClient=client,
|
||||||
|
teamsnap_search_kwargs=kwargs,
|
||||||
|
default_keys=[
|
||||||
|
'name', 'created_at', 'updated_at'
|
||||||
|
],
|
||||||
|
related_objects = [
|
||||||
|
('team_id', 'managed_by_team_id')
|
||||||
|
]
|
||||||
|
)
|
||||||
|
opponents = update_object_from_teamsnap(
|
||||||
|
teamsnap.teamsnap.api.Opponent,
|
||||||
|
Opponent,
|
||||||
|
TeamsnapClient=client,
|
||||||
|
teamsnap_search_kwargs=kwargs,
|
||||||
|
default_keys= [
|
||||||
|
'name', 'created_at', 'updated_at',
|
||||||
|
('team_id', 'managed_by_team_id')
|
||||||
|
]
|
||||||
|
)
|
||||||
|
return teams + opponents
|
||||||
|
|
||||||
|
def update_members (client, **kwargs):
|
||||||
|
return update_object_from_teamsnap(
|
||||||
|
TeamsnapApiObject=teamsnap.teamsnap.api.Member,
|
||||||
|
TeamsnapDbModelClass=Member,
|
||||||
|
TeamsnapClient=client,
|
||||||
|
teamsnap_search_kwargs=kwargs,
|
||||||
|
default_keys=['first_name','last_name','jersey_number','is_non_player', 'created_at', 'updated_at',
|
||||||
|
('team_id', 'managed_by_team_id'),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
pass
|
||||||
|
|
||||||
|
def update_availabilities(client, **kwargs):
|
||||||
|
return update_object_from_teamsnap(
|
||||||
|
TeamsnapApiObject=teamsnap.teamsnap.api.Availability,
|
||||||
|
TeamsnapDbModelClass=Availability,
|
||||||
|
TeamsnapClient=client,
|
||||||
|
teamsnap_search_kwargs=kwargs,
|
||||||
|
default_keys=[ 'status_code',
|
||||||
|
'member_id',
|
||||||
|
'event_id',
|
||||||
|
'created_at',
|
||||||
|
'updated_at',
|
||||||
|
('team_id', 'managed_by_team_id')
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
def update_events(client, **kwargs):
|
||||||
|
return update_object_from_teamsnap(
|
||||||
|
TeamsnapApiObject=teamsnap.teamsnap.api.Event,
|
||||||
|
TeamsnapDbModelClass=Event,
|
||||||
|
TeamsnapClient=client,
|
||||||
|
teamsnap_search_kwargs=kwargs,
|
||||||
|
default_keys=['formatted_title','label','points_for_opponent','points_for_team','is_game','opponent_id','location_id',
|
||||||
|
'start_date', 'created_at', 'updated_at', 'game_type',
|
||||||
|
('team_id', 'managed_by_team_id')
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
def update_users(client, **kwargs):
|
||||||
|
return update_object_from_teamsnap(
|
||||||
|
TeamsnapApiObject=teamsnap.teamsnap.api.User,
|
||||||
|
TeamsnapDbModelClass=User,
|
||||||
|
TeamsnapClient=client,
|
||||||
|
teamsnap_search_kwargs=kwargs,
|
||||||
|
default_keys=['first_name', 'last_name', 'email', 'created_at', 'updated_at',]
|
||||||
|
)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
TOKEN = BenchcoachUser.objects.get(id=1).teamsnap_access_token
|
||||||
|
USER_ID = BenchcoachUser.objects.get(id=1).teamsnap_user_id
|
||||||
|
TEAM_ID = BenchcoachUser.objects.get(id=1).teamsnapsettings.managed_team_id
|
||||||
|
CLIENT = TeamSnap(token=TOKEN)
|
||||||
|
# update_users(CLIENT, id=USER_ID)
|
||||||
|
update_teams(CLIENT, team_id=TEAM_ID)
|
||||||
@@ -2,21 +2,22 @@ from django.shortcuts import render, redirect
|
|||||||
|
|
||||||
from .teamsnap.api import Event as TsApiEvent
|
from .teamsnap.api import Event as TsApiEvent
|
||||||
from .teamsnap.api import TeamSnap
|
from .teamsnap.api import TeamSnap
|
||||||
from .models import User, Member, Team, Event, Location, LineupEntry
|
from .models import User, Member, Team, Event, Location, LineupEntry, Opponent, Availability
|
||||||
from django.views.generic.list import ListView
|
|
||||||
from lib.views import BenchcoachListView
|
from lib.views import BenchcoachListView
|
||||||
from .forms import LineupEntryForm, LineupEntryFormSet, EventForm, EventFormSet
|
from .forms import LineupEntryForm, LineupEntryFormSet, EventForm, EventFormSet
|
||||||
from django.forms.models import model_to_dict
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.db.models import Case, When
|
from django.db.models import Case, When
|
||||||
from django.views import View
|
from django.views import View
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from benchcoach.models import Profile as BenchcoachUser
|
import benchcoachproject.models
|
||||||
from events.models import Event as BenchcoachEvent
|
import benchcoach.models
|
||||||
import teamsnap.teamsnap.api
|
import teamsnap.teamsnap.api
|
||||||
import json
|
import json
|
||||||
from django.http import JsonResponse
|
from django.http import JsonResponse
|
||||||
from .utils.import_teamsnap import update_users, update_teams, update_events, update_members, update_locations, update_availabilities
|
from .utils.teamsnap_object_utils import update_users, update_teams, update_events, update_members, update_locations, update_availabilities
|
||||||
|
from django.contrib import messages
|
||||||
|
from django.template.loader import render_to_string
|
||||||
|
from .utils.import_teamsnap import update_team, update_event, update_member, update_location, update_opponent, update_availability, update_teamsnap_object
|
||||||
|
|
||||||
def queryset_from_ids(Model, id_list):
|
def queryset_from_ids(Model, id_list):
|
||||||
#https://stackoverflow.com/questions/4916851/django-get-a-queryset-from-array-of-ids-in-specific-order
|
#https://stackoverflow.com/questions/4916851/django-get-a-queryset-from-array-of-ids-in-specific-order
|
||||||
@@ -77,13 +78,13 @@ class LocationListView(BenchcoachListView):
|
|||||||
page_title = "TeamSnap Locations"
|
page_title = "TeamSnap Locations"
|
||||||
|
|
||||||
def update_from_teamsnap_event(request):
|
def update_from_teamsnap_event(request):
|
||||||
TOKEN = BenchcoachUser.objects.get(id=1).teamsnap_access_token
|
TOKEN = benchcoachproject.models.User.objects.get(id=1).teamsnap_access_token
|
||||||
CLIENT = TeamSnap(token=TOKEN)
|
CLIENT = TeamSnap(token=TOKEN)
|
||||||
teamsnap_event_id=request.POST.get('teamsnap event')
|
teamsnap_event_id=request.POST.get('teamsnap event')
|
||||||
benchcoach_event_id=request.POST.get('teamsnap event')
|
benchcoach_event_id=request.POST.get('teamsnap event')
|
||||||
if teamsnap_event_id:
|
if teamsnap_event_id:
|
||||||
benchcoach_event = BenchcoachEvent.objects.get(id=benchcoach_event_id)
|
benchcoach_event = benchcoach.models.Event.objects.get(id=benchcoach_event_id)
|
||||||
teamsnap_object = Event.objects.get(id=teamsnap_event_id)
|
teamsnap_object = benchcoach.models.Event.objects.get(id=teamsnap_event_id)
|
||||||
teamsnap_id = teamsnap_object.teamsnap_id
|
teamsnap_id = teamsnap_object.teamsnap_id
|
||||||
teamsnap_response = TsApiEvent.search(client=CLIENT, id=teamsnap_id)
|
teamsnap_response = TsApiEvent.search(client=CLIENT, id=teamsnap_id)
|
||||||
if teamsnap_response[0]:
|
if teamsnap_response[0]:
|
||||||
@@ -93,20 +94,85 @@ def update_from_teamsnap_event(request):
|
|||||||
|
|
||||||
return HttpResponse(f'Success, {data}')
|
return HttpResponse(f'Success, {data}')
|
||||||
|
|
||||||
def sync_teamsnap(request):
|
def sync_with_teamsnap_api(request):
|
||||||
|
'''
|
||||||
|
This sync the internal TeamSnap Database with the TeamSnap API
|
||||||
|
'''
|
||||||
TOKEN = request.user.profile.teamsnap_access_token
|
TOKEN = request.user.profile.teamsnap_access_token
|
||||||
USER_ID = request.user.profile.teamsnap_user.id
|
USER_ID = request.user.profile.teamsnap_user.id
|
||||||
TEAM_ID = request.user.profile.teamsnapsettings.managed_team.id
|
TEAM_ID = request.user.profile.teamsnapsettings.managed_team.id
|
||||||
CLIENT = TeamSnap(token=TOKEN)
|
CLIENT = TeamSnap(token=TOKEN)
|
||||||
l = []
|
|
||||||
l += update_users(CLIENT, id=USER_ID)
|
|
||||||
l += update_teams(CLIENT, team_id=TEAM_ID)
|
|
||||||
l += update_members(CLIENT, team_id=TEAM_ID)
|
|
||||||
l += update_locations(CLIENT, team_id=TEAM_ID)
|
|
||||||
l += update_events(CLIENT, team_id=TEAM_ID)
|
|
||||||
l += update_availabilities(CLIENT, team_id=TEAM_ID)
|
|
||||||
|
|
||||||
return JsonResponse({'number of objects updated':len(l)})
|
r = {}
|
||||||
|
|
||||||
|
for Obj in [User]:
|
||||||
|
r[Obj.__name__] = []
|
||||||
|
a = Obj.ApiObject.search(CLIENT, id=USER_ID)
|
||||||
|
for _a in a:
|
||||||
|
obj, created = Obj.update_or_create_from_teamsnap_api(_a.data)
|
||||||
|
r[Obj.__name__].append((obj, created))
|
||||||
|
|
||||||
|
for Obj in [Event, Availability, Location, Member, Opponent, Team]:
|
||||||
|
r[Obj.__name__] = []
|
||||||
|
a = Obj.ApiObject.search(CLIENT, team_id=TEAM_ID)
|
||||||
|
for _a in a:
|
||||||
|
obj, created = Obj.update_or_create_from_teamsnap_api(_a.data)
|
||||||
|
r[Obj.__name__].append((obj, created))
|
||||||
|
|
||||||
|
for object_name, results in r.items():
|
||||||
|
if len(r) == 0:
|
||||||
|
messages.error(request, f"Error! No {object_name} objects created or updated")
|
||||||
|
else:
|
||||||
|
result = [created for obj, created in results]
|
||||||
|
messages.success(request, f"Success! {sum(result)} {object_name} objects created, {len(result)-sum(result)} {object_name} objects updated.")
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'msg': render_to_string('messages.html', {}, request),
|
||||||
|
}
|
||||||
|
|
||||||
|
return JsonResponse(data)
|
||||||
|
|
||||||
|
def sync_teamsnap_db(request):
|
||||||
|
'''
|
||||||
|
This syncs the internal BenchCoach Database and the TeamSnap Database
|
||||||
|
'''
|
||||||
|
TEAM_ID = request.user.profile.teamsnapsettings.managed_team.id
|
||||||
|
r={}
|
||||||
|
|
||||||
|
r['team/opponent'] = []
|
||||||
|
for team in Opponent.objects.filter(team_id=TEAM_ID):
|
||||||
|
r['team/opponent'] += update_opponent(team, create_benchcoach_object=True, create_related=True)
|
||||||
|
|
||||||
|
for team in Team.objects.filter(id=TEAM_ID):
|
||||||
|
r['team/opponent'] += update_team(team, create_benchcoach_object=True, create_related=True)
|
||||||
|
|
||||||
|
r['location'] = []
|
||||||
|
for location in Location.objects.filter(team_id=TEAM_ID):
|
||||||
|
r['team/location'] += update_location(location, create_benchcoach_object=True, create_related=True)
|
||||||
|
|
||||||
|
r['member'] = []
|
||||||
|
for member in Member.objects.filter(team_id=TEAM_ID, is_non_player=False):
|
||||||
|
r['member'] += update_member(member, create_benchcoach_object=True, create_related=True)
|
||||||
|
|
||||||
|
r['event'] = []
|
||||||
|
for event in Event.objects.filter(team_id=TEAM_ID):
|
||||||
|
r['event'] += update_event(event, create_benchcoach_object=True, create_related=True)
|
||||||
|
|
||||||
|
r['availability'] = []
|
||||||
|
for availability in Availability.objects.filter(team_id=TEAM_ID):
|
||||||
|
r['availability'] += update_availability(availability, create_benchcoach_object=True, create_related=True)
|
||||||
|
|
||||||
|
for object_name, results in r.items():
|
||||||
|
if len(r) == 0:
|
||||||
|
messages.error(request, f"Error! No {object_name} objects created or updated")
|
||||||
|
else:
|
||||||
|
result = [created for obj, created in results]
|
||||||
|
messages.success(request, f"Success! {sum(result)} {object_name} objects created, {len(result)-sum(result)} {object_name} objects updated.")
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'msg': render_to_string('messages.html', {}, request),
|
||||||
|
}
|
||||||
|
return JsonResponse(data)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user