resolve merge conflicts
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
from django.contrib import admin
|
||||
|
||||
from .models import Preferences
|
||||
from .models import Opponent, Preferences, Team
|
||||
|
||||
# Register your models here.
|
||||
admin.site.register(Preferences)
|
||||
admin.site.register(Team)
|
||||
admin.site.register(Opponent)
|
||||
|
||||
0
teamsnap/dashboard/__init__.py
Normal file
0
teamsnap/dashboard/__init__.py
Normal file
6
teamsnap/dashboard/apps.py
Normal file
6
teamsnap/dashboard/apps.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class DashboardConfig(AppConfig):
|
||||
default_auto_field = "django.db.models.BigAutoField"
|
||||
name = "teamsnap.dashboard"
|
||||
0
teamsnap/dashboard/migrations/__init__.py
Normal file
0
teamsnap/dashboard/migrations/__init__.py
Normal file
@@ -34,7 +34,12 @@
|
||||
<h6 class="text-muted mb-2">{{ event.data.location_name }}</h6>
|
||||
</div>
|
||||
<div class="d-flex">
|
||||
<a class="btn btn-primary btn-sm mx-1" role="button" href="{% url 'teamsnap_edit_lineup' event_ids=event.data.id team_id=event.data.team_id %}">Go to Lineup</a>
|
||||
<a class="btn btn-primary btn-sm mx-1" role="button" href="{% url 'teamsnap_edit_lineup' event_ids=event.data.id team_id=event.data.team_id %}">
|
||||
Go to Lineup
|
||||
</a>
|
||||
<a class="btn btn-primary btn-sm mx-1" role="button" href="{% url 'gamecard' event_id=event.data.id team_id=event.data.team_id %}">
|
||||
<i class="bi bi-book"></i>
|
||||
</a>
|
||||
<form method="get"
|
||||
action="{% url 'instagen_generate' team_id=event.data.team_id event_id=event.data.id %}">
|
||||
<select hidden class="form-select" name="game_id" id="game_id">
|
||||
@@ -109,40 +114,40 @@
|
||||
{% endblock %}
|
||||
{% block inline_javascript %}
|
||||
<script>
|
||||
function donut(ctx, yes_count, maybe_count, no_count, unknown_count) {
|
||||
var style = getComputedStyle(document.body);
|
||||
const myChart = new Chart(ctx, {
|
||||
type: 'doughnut',
|
||||
responsive: 'true',
|
||||
data: {
|
||||
datasets: [{
|
||||
label: 'Availability',
|
||||
labels: [
|
||||
'Yes',
|
||||
'Maybe',
|
||||
'No',
|
||||
'Unknown'
|
||||
],
|
||||
data: [yes_count, maybe_count, no_count, unknown_count],
|
||||
backgroundColor: [
|
||||
style.getPropertyValue('--bs-success'),
|
||||
style.getPropertyValue('--bs-info'),
|
||||
style.getPropertyValue('--bs-danger'),
|
||||
style.getPropertyValue('--bs-secondary')
|
||||
],
|
||||
hoverOffset: 4
|
||||
}]
|
||||
},
|
||||
});
|
||||
function donut(ctx, yes_count, maybe_count, no_count, unknown_count) {
|
||||
var style = getComputedStyle(document.body);
|
||||
const myChart = new Chart(ctx, {
|
||||
type: 'doughnut',
|
||||
responsive: 'true',
|
||||
data: {
|
||||
datasets: [{
|
||||
label: 'Availability',
|
||||
labels: [
|
||||
'Yes',
|
||||
'Maybe',
|
||||
'No',
|
||||
'Unknown'
|
||||
],
|
||||
data: [yes_count, maybe_count, no_count, unknown_count],
|
||||
backgroundColor: [
|
||||
style.getPropertyValue('--bs-success'),
|
||||
style.getPropertyValue('--bs-info'),
|
||||
style.getPropertyValue('--bs-danger'),
|
||||
style.getPropertyValue('--bs-secondary')
|
||||
],
|
||||
hoverOffset: 4
|
||||
}]
|
||||
},
|
||||
});
|
||||
|
||||
}
|
||||
for (ctx of document.querySelectorAll('.availability-donut')){
|
||||
donut(ctx,
|
||||
ctx.dataset.availableYes,
|
||||
ctx.dataset.availableMaybe,
|
||||
ctx.dataset.availableNo,
|
||||
ctx.dataset.availableUnknown,
|
||||
)
|
||||
}
|
||||
</script>
|
||||
}
|
||||
for (ctx of document.querySelectorAll('.availability-donut')){
|
||||
donut(ctx,
|
||||
ctx.dataset.availableYes,
|
||||
ctx.dataset.availableMaybe,
|
||||
ctx.dataset.availableNo,
|
||||
ctx.dataset.availableUnknown,
|
||||
)
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
3
teamsnap/dashboard/tests.py
Normal file
3
teamsnap/dashboard/tests.py
Normal file
@@ -0,0 +1,3 @@
|
||||
# from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
8
teamsnap/dashboard/urls.py
Normal file
8
teamsnap/dashboard/urls.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from django.urls import path
|
||||
|
||||
from .views import dashboard
|
||||
|
||||
urlpatterns = [
|
||||
path("<int:team_id>/dashboard/", dashboard, name="teamsnap_dashboard"),
|
||||
path("dashboard/", dashboard, name="teamsnap_dashboard"),
|
||||
]
|
||||
42
teamsnap/dashboard/views.py
Normal file
42
teamsnap/dashboard/views.py
Normal file
@@ -0,0 +1,42 @@
|
||||
import datetime
|
||||
|
||||
from django.shortcuts import redirect, render
|
||||
|
||||
from teamsnap.views import get_teamsnap_client
|
||||
|
||||
|
||||
def dashboard(request, team_id=None):
|
||||
if not team_id:
|
||||
return redirect(
|
||||
"teamsnap_dashboard", team_id=request.user.preferences.managed_team_id
|
||||
)
|
||||
|
||||
from pyteamsnap.api import AvailabilitySummary, Event
|
||||
|
||||
client = get_teamsnap_client(request)
|
||||
ts_events = Event.search(client, team_id=team_id)
|
||||
ts_availability_summaries_d = {
|
||||
a.data["id"]: a for a in AvailabilitySummary.search(client, team_id=team_id)
|
||||
}
|
||||
ts_events_future = [
|
||||
e
|
||||
for e in ts_events
|
||||
if e.data["start_date"] > datetime.datetime.now(datetime.timezone.utc)
|
||||
]
|
||||
ts_events_past = [
|
||||
e
|
||||
for e in reversed(ts_events)
|
||||
if e.data["start_date"] < datetime.datetime.now(datetime.timezone.utc)
|
||||
]
|
||||
|
||||
return render(
|
||||
request,
|
||||
"dashboard.html",
|
||||
{
|
||||
"ts_events_future": ts_events_future,
|
||||
"ts_events_past": ts_events_past,
|
||||
"events_availabilities": [
|
||||
(e, ts_availability_summaries_d[e.data["id"]]) for e in ts_events_future
|
||||
],
|
||||
},
|
||||
)
|
||||
@@ -46,7 +46,7 @@ class LineupEntryForm(forms.Form):
|
||||
("DR", "DR"),
|
||||
("EH", "EH"),
|
||||
],
|
||||
widget=forms.Select(attrs={"onchange": "colorPositions();"}),
|
||||
widget=forms.Select(attrs={"onchange": "positionSelectChanged(this);"}),
|
||||
)
|
||||
|
||||
|
||||
|
||||
0
teamsnap/lineup/__init__.py
Normal file
0
teamsnap/lineup/__init__.py
Normal file
6
teamsnap/lineup/apps.py
Normal file
6
teamsnap/lineup/apps.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class LineupConfig(AppConfig):
|
||||
default_auto_field = "django.db.models.BigAutoField"
|
||||
name = "teamsnap.lineup"
|
||||
48
teamsnap/lineup/forms.py
Normal file
48
teamsnap/lineup/forms.py
Normal file
@@ -0,0 +1,48 @@
|
||||
from django import forms
|
||||
from django.forms import formset_factory
|
||||
|
||||
|
||||
class LineupEntryForm(forms.Form):
|
||||
member = None
|
||||
availability = None
|
||||
lineup_entry = None
|
||||
|
||||
event_lineup_entry_id = forms.Field(required=False)
|
||||
event_lineup_id = forms.Field(required=False)
|
||||
event_id = forms.Field()
|
||||
member_id = forms.Field()
|
||||
position_only = forms.BooleanField(initial=False, required=False)
|
||||
sequence = forms.IntegerField(required=False)
|
||||
label = forms.ChoiceField(
|
||||
required=False,
|
||||
choices=[
|
||||
("", "--"),
|
||||
("P", "P"),
|
||||
("C", "C"),
|
||||
("1B", "1B"),
|
||||
("2B", "2B"),
|
||||
("3B", "3B"),
|
||||
("SS", "SS"),
|
||||
("LF", "LF"),
|
||||
("CF", "CF"),
|
||||
("RF", "RF"),
|
||||
("DH", "DH"),
|
||||
("DR", "DR"),
|
||||
("EH", "EH"),
|
||||
],
|
||||
widget=forms.Select(attrs={"onchange": "positionSelectChanged(this);"}),
|
||||
)
|
||||
|
||||
|
||||
LineupEntryFormset = formset_factory(
|
||||
LineupEntryForm, can_delete=True, can_order=True, extra=0
|
||||
)
|
||||
|
||||
|
||||
class EventChooseForm(forms.Form):
|
||||
event_id = forms.ChoiceField()
|
||||
|
||||
|
||||
LineupEntryFormset = formset_factory(
|
||||
LineupEntryForm, can_delete=True, can_order=True, extra=0
|
||||
)
|
||||
0
teamsnap/lineup/migrations/__init__.py
Normal file
0
teamsnap/lineup/migrations/__init__.py
Normal file
399
teamsnap/lineup/static/lineup/js/lineup.js
Normal file
399
teamsnap/lineup/static/lineup/js/lineup.js
Normal file
@@ -0,0 +1,399 @@
|
||||
/* Project specific Javascript goes here. */
|
||||
function positionSelectChanged(elem) {
|
||||
let row = elem.closest("tr")
|
||||
row.dataset.position=elem.value
|
||||
colorPositions()
|
||||
}
|
||||
|
||||
function colorPositions() {
|
||||
for (bcLineup of document.getElementsByClassName("benchcoach-lineup")) {
|
||||
var player_rows = bcLineup.querySelectorAll('tr');
|
||||
var label_value_array = []
|
||||
player_rows.forEach(function (player_row, index) {
|
||||
if (player_row.querySelector('[name$="label"]')) {
|
||||
label_value_array.push(
|
||||
player_row.querySelector('select[name$="label"]').value)
|
||||
}
|
||||
}
|
||||
)
|
||||
bcLineup.querySelectorAll('[id^="position-status"]').forEach(function (position_status, index) {
|
||||
if (label_value_array.includes(position_status.innerHTML)) {
|
||||
if (position_status.classList.contains("text-danger")) {
|
||||
position_status.classList.remove('text-danger')
|
||||
}
|
||||
position_status.classList.add('text-success')
|
||||
} else {
|
||||
if (position_status.classList.contains("text-success")) {
|
||||
position_status.classList.remove('text-success')
|
||||
}
|
||||
position_status.classList.add('text-danger')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function refresh_lineup_order (itemEl){
|
||||
let bcLineup = itemEl.closest(".benchcoach-lineup")
|
||||
var player_rows = []
|
||||
for (tbody of bcLineup.querySelectorAll("[class*='tbody-benchcoach-starting']")){
|
||||
for (row of tbody.rows){
|
||||
player_rows.push(row)
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < player_rows.length; i++) {
|
||||
var player_order = player_rows[i].querySelector('[id^="sequence"]')
|
||||
var form_element_order = player_rows[i].querySelector('[id$="sequence"]')
|
||||
player_order.innerText = parseInt(player_rows[i].dataset.order)
|
||||
player_rows[i].dataset.order = i
|
||||
form_element_order.value = i
|
||||
player_order.innerHTML = i+1
|
||||
}
|
||||
var player_rows = bcLineup.getElementsByClassName("tbody-benchcoach-bench")[0].rows
|
||||
for (let i = 0; i < player_rows.length; i++) {
|
||||
var player_order = player_rows[i].querySelector('[id^="sequence"]')
|
||||
var form_element_order = player_rows[i].querySelector('[id$="sequence"]')
|
||||
player_rows[i].dataset.order = null
|
||||
form_element_order.value = null
|
||||
player_order.innerHTML = null
|
||||
}
|
||||
}
|
||||
|
||||
function sendToClipboard(itemEl){
|
||||
let bcLineup = itemEl.closest(".benchcoach-lineup")
|
||||
player_rows = bcLineup.querySelectorAll("[data-position=P]")
|
||||
lineup_export = []
|
||||
if (player_rows.length > 0){
|
||||
lineup_export.push(player_rows[0].dataset.playerName)
|
||||
lineup_export.push("","")
|
||||
} else {
|
||||
lineup_export.push("","","")
|
||||
}
|
||||
|
||||
lineup_export.push("")
|
||||
for (position of [
|
||||
'C',
|
||||
'1B',
|
||||
'2B',
|
||||
'3B',
|
||||
'SS',
|
||||
'LF',
|
||||
'CF',
|
||||
'RF',
|
||||
'DH',
|
||||
]
|
||||
) {
|
||||
var player_rows = bcLineup.querySelectorAll(`[data-position=${CSS.escape(position)}]`)
|
||||
if (player_rows.length > 0){
|
||||
lineup_export.push(player_rows[0].dataset.playerName)
|
||||
} else {
|
||||
lineup_export.push('')
|
||||
}
|
||||
}
|
||||
for (position of [
|
||||
'EH',
|
||||
]
|
||||
) {
|
||||
var player_rows = bcLineup.querySelectorAll(`[data-position=${CSS.escape(position)}]`)
|
||||
for (var i = 0; i < 2; i++) {
|
||||
if (i < player_rows.length){
|
||||
lineup_export.push(player_rows[i].dataset.playerName)
|
||||
} else {
|
||||
lineup_export.push("")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (position of [
|
||||
'DR',
|
||||
]
|
||||
) {
|
||||
let player_rows = bcLineup.querySelectorAll(`[data-position=${CSS.escape(position)}]`)
|
||||
if (player_rows.length > 0){
|
||||
lineup_export.push(player_rows[0].dataset.playerName)
|
||||
} else {
|
||||
lineup_export.push('')
|
||||
}
|
||||
}
|
||||
|
||||
lineup_export.push("")
|
||||
lineup_export.push("","")
|
||||
lineup_export.push("")
|
||||
|
||||
for (var i = 0; i < 11; i++) {
|
||||
let player_rows = bcLineup.querySelector('.table-benchcoach-startinglineup').querySelectorAll(`[data-order=${CSS.escape(i)}]`)
|
||||
if (player_rows.length > 0){
|
||||
lineup_export.push(player_rows[0].dataset.playerName)
|
||||
} else {
|
||||
lineup_export.push("")
|
||||
}
|
||||
}
|
||||
|
||||
console.dir(lineup_export)
|
||||
var textArea = document.createElement("textarea");
|
||||
textArea.value = lineup_export.join("\n");
|
||||
|
||||
// Avoid scrolling to bottom
|
||||
textArea.style.top = "0";
|
||||
textArea.style.left = "0";
|
||||
textArea.style.position = "fixed";
|
||||
|
||||
document.body.appendChild(textArea);
|
||||
textArea.focus();
|
||||
textArea.select();
|
||||
|
||||
try {
|
||||
var successful = document.execCommand('copy');
|
||||
var msg = successful ? 'successful' : 'unsuccessful';
|
||||
console.log('Copying text command was ' + msg);
|
||||
} catch (err) {
|
||||
console.error('Oops, unable to copy', err);
|
||||
}
|
||||
|
||||
document.body.removeChild(textArea);
|
||||
|
||||
}
|
||||
|
||||
benchcoach_lineups = document.getElementsByClassName("benchcoach-lineup")
|
||||
for (bcLineup of document.getElementsByClassName("benchcoach-lineup")) {
|
||||
var startinglineup = new Sortable.create(
|
||||
bcLineup.getElementsByClassName("tbody-benchcoach-startinglineup")[0], {
|
||||
animation: 150,
|
||||
handle: ".drag-handle",
|
||||
ghostClass:"ghost",
|
||||
group:{
|
||||
name:bcLineup.id,
|
||||
put:[bcLineup.id],
|
||||
pull:[bcLineup.id]
|
||||
},
|
||||
onAdd: function (/**Event*/evt) {
|
||||
// Add to Lineup
|
||||
var itemEl = evt.item; // dragged HTMLElement
|
||||
var player_order = itemEl.querySelector('[id^="sequence-member"]')
|
||||
var player_available =itemEl.querySelector('[class^="member-availability-status"]')
|
||||
refresh_lineup_order(itemEl)
|
||||
if (player_order.classList.contains('d-none')){
|
||||
player_order.classList.remove('d-none')
|
||||
}
|
||||
// player_available.classList.add('d-none')
|
||||
},
|
||||
onUpdate: function (/**Event*/evt) {
|
||||
console.log('update to lineup')
|
||||
var itemEl = evt.item; // dragged HTMLElement
|
||||
refresh_lineup_order(itemEl)
|
||||
},
|
||||
});
|
||||
|
||||
var bench = new Sortable.create(
|
||||
bcLineup.getElementsByClassName("tbody-benchcoach-bench")[0], {
|
||||
animation: 150,
|
||||
ghostClass:"ghost",
|
||||
sort: false,
|
||||
handle: ".drag-handle",
|
||||
// handle: ".bars-move",
|
||||
group:{
|
||||
name:bcLineup.id,
|
||||
put:[bcLineup.id],
|
||||
pull:[bcLineup.id]
|
||||
},
|
||||
onAdd: function (/**Event*/evt) {
|
||||
var itemEl = evt.item; // dragged HTMLElement
|
||||
var player_order = itemEl.querySelector('[id^="sequence-member"]')
|
||||
var player_available =itemEl.querySelector('[class^="member-availability-status"]')
|
||||
refresh_lineup_order(itemEl)
|
||||
// player_order.classList.add('d-none')
|
||||
if (player_order.classList.contains('d-none')){
|
||||
player_available.classList.remove('d-none')
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var positionalonlylineup = new Sortable.create(
|
||||
bcLineup.getElementsByClassName("tbody-benchcoach-startingpositionalonly")[0], {
|
||||
handle: ".drag-handle",
|
||||
group:{
|
||||
name:bcLineup.id,
|
||||
put:[bcLineup.id],
|
||||
pull:[bcLineup.id]
|
||||
},
|
||||
onAdd: function (/**Event*/evt) {
|
||||
var itemEl = evt.item; // dragged HTMLElement
|
||||
var player_order = itemEl.querySelector('[id^="sequence-member"]')
|
||||
var position_only = itemEl.querySelector('[id$="position_only"]')
|
||||
position_only.value = true
|
||||
var player_available =itemEl.querySelector('[class^="member-availability-status"]')
|
||||
refresh_lineup_order(itemEl)
|
||||
// player_order.classList.add('d-none')
|
||||
if (player_order.classList.contains('d-none')){
|
||||
player_available.classList.remove('d-none')
|
||||
}
|
||||
},
|
||||
onRemove: function (/**Event*/evt) {
|
||||
var itemEl = evt.item; // dragged HTMLElement
|
||||
var player_order = itemEl.querySelector('[id^="sequence-member"]')
|
||||
var player_available =itemEl.querySelector('[class^="member-availability-status"]')
|
||||
var position_only = itemEl.querySelector('[id$="position_only"]')
|
||||
position_only.value = false
|
||||
|
||||
if (player_order.classList.contains('d-none')){
|
||||
player_available.classList.remove('d-none')
|
||||
}
|
||||
},
|
||||
onUpdate: function (/**Event*/evt) {
|
||||
var itemEl = evt.item; // dragged HTMLElement
|
||||
refresh_lineup_order(itemEl)
|
||||
},
|
||||
}
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
function copyEmailTable(itemEl, subject, recipients){
|
||||
// Create container for the HTML
|
||||
// [1]
|
||||
let bcLineup = itemEl.closest(".benchcoach-lineup")
|
||||
var container = document.createElement('div')
|
||||
var tbl = document.createElement('table')
|
||||
|
||||
let thead = tbl.createTHead()
|
||||
let thead_row = thead.insertRow()
|
||||
let thead_row_cell = thead_row.insertCell()
|
||||
thead_row_cell.appendChild(document.createElement("h3").appendChild(document.createTextNode("STARTING LINEUP")))
|
||||
thead_row_cell.colSpan=3;
|
||||
thead_row_cell.classList.add('title-cell')
|
||||
var tbody = tbl.createTBody()
|
||||
for (row of bcLineup.querySelector(".table-benchcoach-startinglineup").rows) {
|
||||
let tr = tbody.insertRow()
|
||||
cell = tr.insertCell()
|
||||
cell.classList.add('sequence-cell')
|
||||
cell.appendChild(document.createTextNode((parseInt(row.dataset.order) + 1)))
|
||||
cell = tr.insertCell()
|
||||
cell.appendChild(document.createTextNode(row.dataset.playerName))
|
||||
cell.classList.add('name-cell')
|
||||
tr.insertCell().appendChild(document.createTextNode(row.dataset.position))
|
||||
}
|
||||
|
||||
if (bcLineup.querySelector('.table-benchcoach-startingpositionalonly').rows.length > 0) {
|
||||
var tr = tbody.insertRow()
|
||||
cell = tr.insertCell()
|
||||
cell.colSpan=3
|
||||
cell.appendChild(document.createTextNode("STARTING (POS. ONLY)"))
|
||||
cell.classList.add('title-cell')
|
||||
|
||||
for (row of bcLineup.querySelector('.table-benchcoach-startingpositionalonly').rows) {
|
||||
var tr = tbody.insertRow()
|
||||
cell = tr.insertCell()
|
||||
cell.classList.add('sequence-cell')
|
||||
cell.appendChild(document.createTextNode(""))
|
||||
cell=tr.insertCell()
|
||||
cell.appendChild(document.createTextNode(row.dataset.playerName))
|
||||
cell.classList.add('name-cell')
|
||||
tr.insertCell().appendChild(document.createTextNode(row.dataset.position))
|
||||
}
|
||||
}
|
||||
|
||||
if (bcLineup.querySelector('.table-benchcoach-bench').rows.length > 0) {
|
||||
var tr = tbody.insertRow()
|
||||
cell = tr.insertCell()
|
||||
cell.colSpan=3
|
||||
cell.appendChild(document.createTextNode("SUBS"))
|
||||
cell.classList.add('title-cell')
|
||||
|
||||
for (row of bcLineup.querySelector('.table-benchcoach-bench').rows) {
|
||||
var tr = tbody.insertRow()
|
||||
cell = tr.insertCell()
|
||||
cell.classList.add('sequence-cell')
|
||||
availability_status = {
|
||||
None: "UNK",
|
||||
"0": "NO",
|
||||
"2": "MAY",
|
||||
"1":"YES"
|
||||
}[row.dataset.availabilityStatuscode]
|
||||
cell.appendChild(document.createTextNode(availability_status))
|
||||
cell=tr.insertCell()
|
||||
cell.appendChild(document.createTextNode(row.dataset.playerName))
|
||||
cell.classList.add('name-cell')
|
||||
tr.insertCell().appendChild(document.createTextNode(""))
|
||||
}
|
||||
}
|
||||
|
||||
if (bcLineup.querySelector('.table-benchcoach-out').rows.length > 0) {
|
||||
var tr = tbody.insertRow()
|
||||
cell = tr.insertCell()
|
||||
cell.colSpan=3
|
||||
cell.appendChild(document.createTextNode("OUT"))
|
||||
cell.classList.add('title-cell')
|
||||
|
||||
for (row of bcLineup.querySelector('.table-benchcoach-out').rows) {
|
||||
var tr = tbody.insertRow()
|
||||
cell = tr.insertCell()
|
||||
cell.classList.add('sequence-cell')
|
||||
availability_status = {
|
||||
"None": "UNK",
|
||||
"0": "NO",
|
||||
"1": "MAY",
|
||||
"2":"YES"
|
||||
}[row.dataset.availabilityStatuscode]
|
||||
cell.appendChild(document.createTextNode(availability_status))
|
||||
tr.insertCell().appendChild(document.createTextNode(row.dataset.playerName))
|
||||
tr.insertCell().appendChild(document.createTextNode(""))
|
||||
}
|
||||
}
|
||||
|
||||
container.appendChild(tbl)
|
||||
for (cell of container.getElementsByClassName('title-cell')){
|
||||
cell.setAttribute (
|
||||
"style",
|
||||
"font-weight:bold;background-color:#323669;color:#fff;padding:2px 5px;"
|
||||
)}
|
||||
|
||||
for (cell of container.getElementsByClassName('sequence-cell')){
|
||||
cell.setAttribute (
|
||||
"style",
|
||||
"font-weight:bold;padding:2px 5px;"
|
||||
)}
|
||||
|
||||
for (cell of container.getElementsByClassName('name-cell')){
|
||||
cell.setAttribute (
|
||||
"style",
|
||||
"width:200px;"
|
||||
)}
|
||||
|
||||
// Detect all style sheets of the page
|
||||
var activeSheets = Array.prototype.slice.call(document.styleSheets)
|
||||
.filter(function (sheet) {
|
||||
return !sheet.disabled
|
||||
})
|
||||
|
||||
// Mount the container to the DOM to make `contentWindow` available
|
||||
// [3]
|
||||
document.body.appendChild(container)
|
||||
|
||||
// Copy to clipboard
|
||||
// [4]
|
||||
window.getSelection().removeAllRanges()
|
||||
|
||||
var range = document.createRange()
|
||||
range.selectNode(container)
|
||||
window.getSelection().addRange(range)
|
||||
|
||||
// [5.1]
|
||||
document.execCommand('copy')
|
||||
|
||||
// [5.2]
|
||||
for (var i = 0; i < activeSheets.length; i++) activeSheets[i].disabled = true
|
||||
|
||||
// [5.3]
|
||||
// document.execCommand('copy')
|
||||
|
||||
// [5.4]
|
||||
for (var i = 0; i < activeSheets.length; i++) activeSheets[i].disabled = false
|
||||
|
||||
// Remove the container
|
||||
// [6]
|
||||
document.body.removeChild(container)
|
||||
subject_encoded = encodeURIComponent(subject)
|
||||
window.open("readdle-spark://compose?recipient=manager@chihounds.com&subject="+subject+"&bcc="+recipients)
|
||||
}
|
||||
|
||||
colorPositions()
|
||||
1
teamsnap/lineup/static/lineup/teamsnap.svg
Normal file
1
teamsnap/lineup/static/lineup/teamsnap.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 5.8 KiB |
@@ -34,12 +34,12 @@
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block inline_javascript %}
|
||||
{{ block.super }}
|
||||
<script src="{% static 'js/Sortable.js' %}"></script>
|
||||
<script src="{% static 'lineup/js/lineup.js' %}"></script>
|
||||
<script>
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
/* Run whatever you want */
|
||||
3
teamsnap/lineup/tests.py
Normal file
3
teamsnap/lineup/tests.py
Normal file
@@ -0,0 +1,3 @@
|
||||
# from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
26
teamsnap/lineup/urls.py
Normal file
26
teamsnap/lineup/urls.py
Normal file
@@ -0,0 +1,26 @@
|
||||
from django.urls import path
|
||||
|
||||
from .views import edit_lineup, multi_lineup_choose, submit_lineup
|
||||
|
||||
urlpatterns = [
|
||||
path(
|
||||
"<int:team_id>/schedule/edit_lineup/<int:event_ids>",
|
||||
edit_lineup,
|
||||
name="teamsnap_edit_lineup",
|
||||
),
|
||||
path(
|
||||
"<int:team_id>/event/<int:event_id>/submit_lineup/",
|
||||
submit_lineup,
|
||||
name="teamsnap_submit_lineup",
|
||||
),
|
||||
path(
|
||||
"<int:team_id>/event/<str:event_ids>/edit_lineup/",
|
||||
edit_lineup,
|
||||
name="teamsnap_edit_lineup",
|
||||
),
|
||||
path(
|
||||
"<int:team_id>/multievent/choose",
|
||||
multi_lineup_choose,
|
||||
name="teamsnap_choose_multiple_lineups",
|
||||
),
|
||||
]
|
||||
288
teamsnap/lineup/views.py
Normal file
288
teamsnap/lineup/views.py
Normal file
@@ -0,0 +1,288 @@
|
||||
from django.http import (
|
||||
HttpResponse,
|
||||
HttpResponseNotAllowed,
|
||||
HttpResponseServerError,
|
||||
JsonResponse,
|
||||
)
|
||||
from django.shortcuts import redirect, render
|
||||
|
||||
from teamsnap.views import get_teamsnap_client
|
||||
|
||||
|
||||
def edit_lineup(request, event_ids, team_id):
|
||||
import re
|
||||
|
||||
from pyteamsnap.api import (
|
||||
Availability,
|
||||
AvailabilitySummary,
|
||||
Event,
|
||||
EventLineup,
|
||||
EventLineupEntry,
|
||||
Member,
|
||||
)
|
||||
|
||||
from teamsnap.forms import LineupEntryFormset
|
||||
|
||||
client = get_teamsnap_client(request)
|
||||
|
||||
event_ids = str(event_ids).split(",")
|
||||
|
||||
ts_bulkload = client.bulk_load(
|
||||
team_id=team_id,
|
||||
types=[Event, EventLineup, EventLineupEntry, AvailabilitySummary, Member],
|
||||
event__id=",".join(event_ids),
|
||||
)
|
||||
event_ids = [int(i) for i in event_ids]
|
||||
|
||||
contexts = []
|
||||
for event_id in event_ids:
|
||||
ts_event = [
|
||||
i for i in ts_bulkload if isinstance(i, Event) and i.data["id"] == event_id
|
||||
][0]
|
||||
ts_availabilities = Availability.search(client, event_id=ts_event.data["id"])
|
||||
ts_lineup_entries = EventLineupEntry.search(client, event_id=event_id)
|
||||
|
||||
ts_members = [i for i in ts_bulkload if isinstance(i, Member)]
|
||||
ts_member_lookup = {m.data["id"]: m for m in ts_members}
|
||||
ts_availability_lookup = {m.data["member_id"]: m for m in ts_availabilities}
|
||||
ts_lineup_entries_lookup = {m.data["member_id"]: m for m in ts_lineup_entries}
|
||||
|
||||
members = []
|
||||
|
||||
for lineup_entry in ts_lineup_entries:
|
||||
members.append(
|
||||
{
|
||||
"member": getattr(
|
||||
ts_member_lookup[lineup_entry.data["member_id"]], "data"
|
||||
),
|
||||
"availability": getattr(
|
||||
ts_availability_lookup.get(lineup_entry.data["member_id"], {}),
|
||||
"data",
|
||||
{},
|
||||
),
|
||||
"lineup_entry": getattr(lineup_entry, "data", {}),
|
||||
}
|
||||
)
|
||||
|
||||
in_lineup_already = [m["member"] for m in members]
|
||||
|
||||
for member in ts_members:
|
||||
if member.data not in in_lineup_already:
|
||||
members.append(
|
||||
{
|
||||
"member": getattr(member, "data"),
|
||||
"availability": getattr(
|
||||
ts_availability_lookup.get(member.data["id"], {}),
|
||||
"data",
|
||||
{},
|
||||
),
|
||||
"lineup_entry": getattr(
|
||||
ts_lineup_entries_lookup.get(member.data["id"], {}),
|
||||
"data",
|
||||
{},
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
members = sorted(
|
||||
members,
|
||||
key=lambda d: (
|
||||
{None: 3, 0: 2, 2: 1, 1: 0}.get( # No Response # No # Maybe # Yes
|
||||
d["availability"].get("status_code")
|
||||
),
|
||||
d["member"].get("last_name"),
|
||||
),
|
||||
)
|
||||
|
||||
initial = []
|
||||
for member in members:
|
||||
if not member["member"]["is_non_player"]:
|
||||
if re.search(
|
||||
r"([A-Z0-9]+)(?:\s+\[(.*)\])?",
|
||||
member["lineup_entry"].get("label", ""),
|
||||
):
|
||||
position, position_note = re.search(
|
||||
r"([A-Z0-9]+)(?:\s+\[(.*)\])?",
|
||||
member["lineup_entry"].get("label", ""),
|
||||
).groups()
|
||||
else:
|
||||
position, position_note = ("", "")
|
||||
position_only = position_note == "PO"
|
||||
initial.append(
|
||||
{
|
||||
"event_lineup_entry_id": member["lineup_entry"].get("id"),
|
||||
"event_lineup_id": member["lineup_entry"].get(
|
||||
"event_lineup_id"
|
||||
),
|
||||
"event_id": event_id,
|
||||
"position_only": position_only,
|
||||
"member_id": member["member"]["id"],
|
||||
"sequence": member["lineup_entry"].get("sequence"),
|
||||
"label": position,
|
||||
}
|
||||
)
|
||||
|
||||
formset = LineupEntryFormset(initial=initial)
|
||||
|
||||
for form in formset:
|
||||
form.member = ts_member_lookup.get(form["member_id"].initial)
|
||||
form.availability = ts_availability_lookup.get(form["member_id"].initial)
|
||||
|
||||
formset_startinglineup = [
|
||||
form
|
||||
for form in formset
|
||||
if form.initial.get("event_lineup_entry_id")
|
||||
and not form.initial.get("position_only")
|
||||
]
|
||||
formset_startinglineup = sorted(
|
||||
formset_startinglineup, key=lambda d: d.initial.get("sequence", 100)
|
||||
)
|
||||
formset_startingpositiononly = [
|
||||
form
|
||||
for form in formset
|
||||
if form.initial.get("event_lineup_entry_id")
|
||||
and form not in formset_startinglineup
|
||||
]
|
||||
formset_startingpositiononly = sorted(
|
||||
formset_startingpositiononly, key=lambda d: d.initial.get("sequence", 100)
|
||||
)
|
||||
formset_bench = [
|
||||
form
|
||||
for form in formset
|
||||
if form not in formset_startinglineup
|
||||
and form not in formset_startingpositiononly
|
||||
and form.availability.data["status_code"] in [2, 1]
|
||||
]
|
||||
formset_out = [
|
||||
form
|
||||
for form in formset
|
||||
if form not in formset_startinglineup
|
||||
and form not in formset_bench
|
||||
and form not in formset_startingpositiononly
|
||||
and not form.member.data["is_non_player"]
|
||||
]
|
||||
|
||||
contexts.append(
|
||||
{
|
||||
"event": ts_event,
|
||||
"formset": formset,
|
||||
"formset_bench": formset_bench,
|
||||
"formset_startinglineup": formset_startinglineup,
|
||||
"formset_startingpositionalonly": formset_startingpositiononly,
|
||||
"formset_out": formset_out,
|
||||
}
|
||||
)
|
||||
|
||||
return render(request, "lineup/edit.html", context={"contexts": contexts})
|
||||
|
||||
|
||||
def submit_lineup(request, team_id, event_id):
|
||||
from pyteamsnap.api import Event, EventLineup, EventLineupEntry
|
||||
|
||||
from teamsnap.forms import LineupEntryFormset
|
||||
|
||||
client = get_teamsnap_client(request)
|
||||
ts_event = Event.get(client, event_id)
|
||||
ts_lineup = EventLineup.search(client, event_id=event_id)
|
||||
event_lineup_id = ts_lineup[0].data["id"]
|
||||
if request.GET:
|
||||
return HttpResponseNotAllowed()
|
||||
if request.POST:
|
||||
formset = LineupEntryFormset(request.POST)
|
||||
if formset.is_valid():
|
||||
r = []
|
||||
for form in formset:
|
||||
data = form.cleaned_data
|
||||
if data.get("event_lineup_entry_id"):
|
||||
event_lineup_entry = EventLineupEntry.get(
|
||||
client, id=data.get("event_lineup_entry_id")
|
||||
)
|
||||
if data.get("position_only"):
|
||||
data["label"] = data["label"] + " [PO]"
|
||||
event_lineup_entry.data.update(data)
|
||||
if not data.get("sequence") and not data.get("label"):
|
||||
try:
|
||||
r.append(event_lineup_entry.delete())
|
||||
except Exception as e:
|
||||
raise e
|
||||
else:
|
||||
try:
|
||||
r.append(event_lineup_entry.put())
|
||||
except Exception as e:
|
||||
e
|
||||
pass
|
||||
pass
|
||||
elif data.get("sequence") is not None and data.get("label"):
|
||||
event_lineup_entry = EventLineupEntry.new(client)
|
||||
if data.get("position_only"):
|
||||
data["label"] = data["label"] + " [PO]"
|
||||
event_lineup_entry.data.update(data)
|
||||
event_lineup_entry.data.update({"event_lineup_id": event_lineup_id})
|
||||
try:
|
||||
r.append(event_lineup_entry.post())
|
||||
except Exception as e:
|
||||
raise e
|
||||
else:
|
||||
pass
|
||||
else:
|
||||
# breakpoint()
|
||||
pass
|
||||
# breakpoint()
|
||||
pass
|
||||
return JsonResponse(ts_event.data)
|
||||
pass
|
||||
return HttpResponseServerError
|
||||
|
||||
|
||||
def multi_lineup_choose(request, team_id):
|
||||
from django.forms import formset_factory
|
||||
from pyteamsnap.api import Event
|
||||
|
||||
from .forms import EventChooseForm
|
||||
|
||||
client = get_teamsnap_client(request)
|
||||
|
||||
if request.method == "POST":
|
||||
ts_events = Event.search(client, team_id=team_id)
|
||||
EventChooseFormset = formset_factory(EventChooseForm)
|
||||
formset = EventChooseFormset(request.POST)
|
||||
choices = [(e.data["id"], e.data["formatted_title"]) for e in ts_events]
|
||||
|
||||
for form in formset:
|
||||
form.fields["event_id"].choices = choices
|
||||
|
||||
if formset.is_valid():
|
||||
event_ids = [f.cleaned_data["event_id"] for f in formset]
|
||||
else:
|
||||
event_ids = request.GET.get("event_ids").split(",")
|
||||
EventChooseFormset = formset_factory(EventChooseForm)
|
||||
formset = EventChooseFormset(request.POST)
|
||||
|
||||
return redirect(
|
||||
"teamsnap_edit_lineup",
|
||||
team_id=team_id,
|
||||
event_ids=",".join(event_ids),
|
||||
)
|
||||
elif not request.GET.get("num"):
|
||||
return HttpResponse(500)
|
||||
else:
|
||||
num = int(request.GET.get("num"))
|
||||
TEAM_ID = team_id
|
||||
|
||||
ts_events = Event.search(client, team_id=TEAM_ID)
|
||||
ts_events = {e.data["id"]: e for e in ts_events}
|
||||
|
||||
EventChooseFormset = formset_factory(EventChooseForm, extra=num)
|
||||
formset = EventChooseFormset()
|
||||
|
||||
choices = [(id, e.data["formatted_title"]) for id, e in ts_events.items()]
|
||||
|
||||
for form in formset:
|
||||
form.fields["event_id"].choices = choices
|
||||
|
||||
pass
|
||||
return render(
|
||||
request,
|
||||
"lineup/multiple_choose.html",
|
||||
context={"formset": formset, "team_id": team_id},
|
||||
)
|
||||
@@ -1,4 +1,4 @@
|
||||
# Generated by Django 3.2.13 on 2022-06-02 13:20
|
||||
# Generated by Django 3.2.13 on 2022-06-09 12:09
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
@@ -14,6 +14,14 @@ class Migration(migrations.Migration):
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Team',
|
||||
fields=[
|
||||
('id', models.IntegerField(primary_key=True, serialize=False)),
|
||||
('logo', models.ImageField(upload_to='logos')),
|
||||
('logo_mono', models.ImageField(upload_to='logos_mono')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Preferences",
|
||||
fields=[
|
||||
|
||||
33
teamsnap/migrations/0004_auto_20220609_0722.py
Normal file
33
teamsnap/migrations/0004_auto_20220609_0722.py
Normal file
@@ -0,0 +1,33 @@
|
||||
# Generated by Django 3.2.13 on 2022-06-09 12:22
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('teamsnap', '0003_auto_20220609_0721'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='opponent',
|
||||
name='logo',
|
||||
field=models.ImageField(blank=True, null=True, upload_to='logos'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='opponent',
|
||||
name='logo_mono',
|
||||
field=models.ImageField(blank=True, null=True, upload_to='logos_mono'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='team',
|
||||
name='logo',
|
||||
field=models.ImageField(blank=True, null=True, upload_to='logos'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='team',
|
||||
name='logo_mono',
|
||||
field=models.ImageField(blank=True, null=True, upload_to='logos_mono'),
|
||||
),
|
||||
]
|
||||
@@ -12,3 +12,43 @@ class Preferences(models.Model):
|
||||
|
||||
class Meta:
|
||||
verbose_name_plural = "preferences"
|
||||
|
||||
|
||||
class Team(models.Model):
|
||||
id = models.IntegerField(primary_key=True)
|
||||
logo = models.ImageField(
|
||||
upload_to="logos",
|
||||
height_field=None,
|
||||
width_field=None,
|
||||
max_length=100,
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
logo_mono = models.ImageField(
|
||||
upload_to="logos_mono",
|
||||
height_field=None,
|
||||
width_field=None,
|
||||
max_length=100,
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
|
||||
|
||||
class Opponent(models.Model):
|
||||
id = models.IntegerField(primary_key=True)
|
||||
logo = models.ImageField(
|
||||
upload_to="logos",
|
||||
height_field=None,
|
||||
width_field=None,
|
||||
max_length=100,
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
logo_mono = models.ImageField(
|
||||
upload_to="logos_mono",
|
||||
height_field=None,
|
||||
width_field=None,
|
||||
max_length=100,
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
<html lang="en">
|
||||
{% extends "base.html" %}{% load static %}
|
||||
{% block title %} {{ event.data.formatted_title }} - Instagenerator{% endblock %}
|
||||
{% block page_heading %}
|
||||
<div class="row d-inline-flex">
|
||||
<div class="col">
|
||||
<img src="{% static 'teamsnap/ig/graphics/hounds-insta.jpg' %}" class="mx-auto d-block img-fluid shadow-sm" style="height:30px;border-radius: 8px;">
|
||||
</div>
|
||||
<div class="col text-nowrap px-0">Hounds Instagenerator</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block page_subheading %}{{ event.data.formatted_title }}, {{ event.data.start_date }}, {{ event.data.location_name }}{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
<form method="get" action="generate">
|
||||
|
||||
<div class="mb-3">
|
||||
<select hidden class="form-select" name="game_id" id="game_id">
|
||||
<optgroup label="Events">
|
||||
<option value="" disabled="disabled">Select an event...</option>
|
||||
<option selected value="{{event.data.id}}">{{event.data.formatted_title}}</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<legend class="">Background</legend>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="background" id="backgroundLocation" checked value="location">
|
||||
<label class="form-check-label" for="backgroundLocation">
|
||||
Location
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="background" id="backgroundTransparent" value="transparent">
|
||||
<label class="form-check-label" for="backgroundTransparent">
|
||||
Transparent
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="background" id="badge_only" value="badge">
|
||||
<label class="form-check-label" for="badge_only">
|
||||
Badge only
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<legend class="">Layout</legend>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="dimensions" id="square" checked value="1080x1080">
|
||||
<label class="form-check-label" for="square">
|
||||
Square
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="dimensions" id="portrait" value="1080x1920">
|
||||
<label class="form-check-label" for="portrait">
|
||||
Portrait
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="dimensions" id="portrait" value="1920x1080">
|
||||
<label class="form-check-label" for="portrait">
|
||||
Landscape
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-lg-flex justify-content-lg-end align-items-lg-center mb-3">
|
||||
<button type="submit" class="btn btn-primary btn-block">Get Image</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
||||
@@ -1,10 +0,0 @@
|
||||
{% extends "base.html" %}{% load static %}
|
||||
{#{% block title %} {{ event.data.formatted_title }}{% endblock %}#}
|
||||
{#{% block page_heading %}{{ event.data.formatted_title }}{% endblock %}#}
|
||||
{#{% block page_subheading %}{{ event.data.start_date }}, {{ event.data.location_name }}{% endblock %}#}
|
||||
|
||||
{% block content %}
|
||||
{% include 'teamsnap/lineup/widgets/lineup.html' with formset_lineup=formset_lineup formset_bench=formset_bench%}
|
||||
<script src="{% static 'js/Sortable.js' %}"></script>
|
||||
<script src="{% static 'teamsnap/js/lineup-table.js' %}"></script>
|
||||
{% endblock %}
|
||||
@@ -1,45 +0,0 @@
|
||||
{% extends "base.html" %}{% load static %}
|
||||
{% block title %} {{ title }}{% endblock %}
|
||||
|
||||
{% csrf_token %}
|
||||
|
||||
{% block page_heading %}
|
||||
<div class="row d-inline-flex">
|
||||
<div class="col">
|
||||
Schedule
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<form method="get" action="{% url 'teamsnap_edit_multiple_lineups' team_id=team_id%}">
|
||||
{{ formset.management_form }}
|
||||
<input class="btn btn-sm btn-outline-primary text-nowrap" type="submit" value="Submit">
|
||||
{% load tz %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-sm">
|
||||
{# <thead>#}
|
||||
{# </thead>#}
|
||||
<tbody>
|
||||
{% for form in formset %}
|
||||
{{ form.event_id.as_hidden }}
|
||||
<tr>
|
||||
<td>
|
||||
{{ form.checked }}
|
||||
</td>
|
||||
<td>
|
||||
<a href="{% url 'teamsnap_view_event' event_id=form.event.data.id team_id=request.user.teamsnapsettings.managed_team.id%}">{{ form.event.data.formatted_title }}</a>
|
||||
</td>
|
||||
<td>
|
||||
{{ form.event.data.start_date | localtime}}
|
||||
</td>
|
||||
<td>
|
||||
{{ form.event.data.location_name }}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -1,48 +1,20 @@
|
||||
from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns
|
||||
from django.urls import path
|
||||
from django.urls import include, path
|
||||
|
||||
from .provider import TeamsnapProvider
|
||||
from .views import (
|
||||
PreferencesFormView,
|
||||
dashboard,
|
||||
edit_lineup,
|
||||
multi_lineup_choose,
|
||||
schedule_view,
|
||||
submit_lineup,
|
||||
view_event,
|
||||
)
|
||||
from .views import PreferencesFormView, schedule_view, view_event
|
||||
|
||||
urlpatterns = default_urlpatterns(TeamsnapProvider)
|
||||
|
||||
urlpatterns += [
|
||||
path("preferences/", PreferencesFormView.as_view(), name="teamsnap_preferences"),
|
||||
path("<int:team_id>/schedule/", schedule_view, name="teamsnap_schedule"),
|
||||
path("<int:team_id>/dashboard/", dashboard, name="teamsnap_dashboard"),
|
||||
path("dashboard/", dashboard, name="teamsnap_dashboard"),
|
||||
path("schedule/", schedule_view, name="teamsnap_schedule"),
|
||||
path(
|
||||
"<int:team_id>/schedule/view_event/<int:event_id>",
|
||||
view_event,
|
||||
name="teamsnap_view_event",
|
||||
),
|
||||
path(
|
||||
"<int:team_id>/schedule/edit_lineup/<int:event_ids>",
|
||||
edit_lineup,
|
||||
name="teamsnap_edit_lineup",
|
||||
),
|
||||
path(
|
||||
"<int:team_id>/event/<int:event_id>/submit_lineup/",
|
||||
submit_lineup,
|
||||
name="teamsnap_submit_lineup",
|
||||
),
|
||||
path(
|
||||
"<int:team_id>/event/<str:event_ids>/edit_lineup/",
|
||||
edit_lineup,
|
||||
name="teamsnap_edit_multiple_lineups",
|
||||
),
|
||||
path(
|
||||
"<int:team_id>/multievent/choose",
|
||||
multi_lineup_choose,
|
||||
name="teamsnap_choose_multiple_lineups",
|
||||
),
|
||||
path("", include("teamsnap.lineup.urls")),
|
||||
path("", include("teamsnap.dashboard.urls")),
|
||||
]
|
||||
|
||||
14
teamsnap/utils/__init__.py
Normal file
14
teamsnap/utils/__init__.py
Normal file
@@ -0,0 +1,14 @@
|
||||
import pyteamsnap
|
||||
|
||||
|
||||
def get_teamsnap_client(request):
|
||||
request.user.socialaccount_set.filter(provider="teamsnap").first()
|
||||
current_teamsnap_user = request.user.socialaccount_set.filter(
|
||||
provider="teamsnap"
|
||||
).first()
|
||||
|
||||
ts_token = (
|
||||
current_teamsnap_user.socialtoken_set.order_by("-expires_at").first().token
|
||||
)
|
||||
|
||||
return pyteamsnap.api.TeamSnap(token=ts_token)
|
||||
@@ -1,6 +1,5 @@
|
||||
import datetime
|
||||
|
||||
import pyteamsnap.api
|
||||
import requests
|
||||
from allauth.socialaccount.providers.oauth2.views import (
|
||||
OAuth2Adapter,
|
||||
@@ -16,6 +15,7 @@ from gamechanger.models import Player as GamechangerPlayer
|
||||
from .forms import PreferencesForm
|
||||
from .models import Preferences
|
||||
from .provider import TeamsnapProvider
|
||||
from .utils import get_teamsnap_client
|
||||
|
||||
|
||||
class TeamsnapAdapter(OAuth2Adapter):
|
||||
@@ -50,19 +50,6 @@ oauth2_login = OAuth2LoginView.adapter_view(TeamsnapAdapter)
|
||||
oauth2_callback = OAuth2CallbackView.adapter_view(TeamsnapAdapter)
|
||||
|
||||
|
||||
def get_teamsnap_client(request):
|
||||
request.user.socialaccount_set.filter(provider="teamsnap").first()
|
||||
current_teamsnap_user = request.user.socialaccount_set.filter(
|
||||
provider="teamsnap"
|
||||
).first()
|
||||
|
||||
ts_token = (
|
||||
current_teamsnap_user.socialtoken_set.order_by("-expires_at").first().token
|
||||
)
|
||||
|
||||
return pyteamsnap.api.TeamSnap(token=ts_token)
|
||||
|
||||
|
||||
class PreferencesFormView(FormView):
|
||||
template_name = "preferences.html"
|
||||
form_class = PreferencesForm
|
||||
@@ -370,45 +357,7 @@ def edit_lineup(request, event_ids, team_id):
|
||||
}
|
||||
)
|
||||
|
||||
return render(request, "lineup/multiple_edit.html", context={"contexts": contexts})
|
||||
|
||||
|
||||
def dashboard(request, team_id=None):
|
||||
if not team_id:
|
||||
return redirect(
|
||||
"teamsnap_dashboard",
|
||||
team_id=request.user.teamsnap_preferences.managed_team_id,
|
||||
)
|
||||
|
||||
from pyteamsnap.api import AvailabilitySummary, Event
|
||||
|
||||
client = get_teamsnap_client(request)
|
||||
ts_events = Event.search(client, team_id=team_id)
|
||||
ts_availability_summaries_d = {
|
||||
a.data["id"]: a for a in AvailabilitySummary.search(client, team_id=team_id)
|
||||
}
|
||||
ts_events_future = [
|
||||
e
|
||||
for e in ts_events
|
||||
if e.data["start_date"] > datetime.datetime.now(datetime.timezone.utc)
|
||||
]
|
||||
ts_events_past = [
|
||||
e
|
||||
for e in reversed(ts_events)
|
||||
if e.data["start_date"] < datetime.datetime.now(datetime.timezone.utc)
|
||||
]
|
||||
|
||||
return render(
|
||||
request,
|
||||
"dashboard.html",
|
||||
{
|
||||
"ts_events_future": ts_events_future,
|
||||
"ts_events_past": ts_events_past,
|
||||
"events_availabilities": [
|
||||
(e, ts_availability_summaries_d[e.data["id"]]) for e in ts_events_future
|
||||
],
|
||||
},
|
||||
)
|
||||
return render(request, "lineup/edit.html", context={"contexts": contexts})
|
||||
|
||||
|
||||
def submit_lineup(request, team_id, event_id):
|
||||
@@ -443,8 +392,7 @@ def submit_lineup(request, team_id, event_id):
|
||||
try:
|
||||
r.append(event_lineup_entry.put())
|
||||
except Exception as e:
|
||||
e
|
||||
pass
|
||||
raise e
|
||||
pass
|
||||
elif data.get("sequence") is not None and data.get("label"):
|
||||
event_lineup_entry = EventLineupEntry.new(client)
|
||||
@@ -489,7 +437,7 @@ def multi_lineup_choose(request, team_id):
|
||||
formset = EventChooseFormset(request.POST)
|
||||
|
||||
return redirect(
|
||||
"teamsnap_edit_multiple_lineups",
|
||||
"teamsnap_edit_lineup",
|
||||
team_id=team_id,
|
||||
event_ids=",".join(event_ids),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user