add teams, teams view, autoscrolling and better index tracking

main
Razmig Sarkissian 2 years ago
parent 5691fc0e60
commit dcb728ba88
  1. 1
      padel/urls.py
  2. 2
      scores/admin.py
  3. 37
      scores/migrations/0011_match_match_index_tournament_auto_scrolling_team.py
  4. 22
      scores/migrations/0012_rename_playerone_team_name_remove_team_playertwo.py
  5. 18
      scores/migrations/0013_team_backgroundcolor.py
  6. 18
      scores/migrations/0014_team_shortname.py
  7. 22
      scores/migrations/0015_remove_team_shortname_tournament_shortname.py
  8. 18
      scores/migrations/0016_team_datelabel.py
  9. 23
      scores/migrations/0017_match_refreshrate_tournament_tournament_index.py
  10. 20
      scores/models.py
  11. 12
      scores/serializers.py
  12. 8
      scores/static/scores/style.css
  13. 39
      scores/templates/scores/index.html
  14. 103
      scores/templates/scores/match.html
  15. 39
      scores/templates/scores/tournament.html
  16. 28
      scores/urls.py
  17. 120
      scores/views.py

@ -23,6 +23,7 @@ router.register(r'users', views.UserViewSet)
router.register(r'clubs', views.ClubViewSet)
router.register(r'matches', views.MatchViewSet)
router.register(r'tournaments', views.TournamentViewSet)
router.register(r'teams', views.TeamViewSet)
urlpatterns = [
path('api/', include(router.urls)),

@ -4,7 +4,9 @@ from django.contrib import admin
from .models import Club
from .models import Match
from .models import Tournament
from .models import Team
admin.site.register(Club)
admin.site.register(Tournament)
admin.site.register(Match)
admin.site.register(Team)

@ -0,0 +1,37 @@
# Generated by Django 4.2 on 2023-07-28 11:28
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('scores', '0010_alter_tournament_club'),
]
operations = [
migrations.AddField(
model_name='match',
name='match_index',
field=models.IntegerField(default=0),
),
migrations.AddField(
model_name='tournament',
name='auto_scrolling',
field=models.BooleanField(default=False),
),
migrations.CreateModel(
name='Team',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('playerOne', models.CharField(blank=True, max_length=200)),
('playerTwo', models.CharField(blank=True, max_length=200)),
('rank', models.IntegerField(default=0)),
('position', models.IntegerField(default=0)),
('bracket', models.BooleanField(default=False)),
('positionLabel', models.CharField(blank=True, max_length=200)),
('match', models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, to='scores.match')),
],
),
]

@ -0,0 +1,22 @@
# Generated by Django 4.2 on 2023-07-28 12:16
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('scores', '0011_match_match_index_tournament_auto_scrolling_team'),
]
operations = [
migrations.RenameField(
model_name='team',
old_name='playerOne',
new_name='name',
),
migrations.RemoveField(
model_name='team',
name='playerTwo',
),
]

@ -0,0 +1,18 @@
# Generated by Django 4.2 on 2023-07-28 12:46
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('scores', '0012_rename_playerone_team_name_remove_team_playertwo'),
]
operations = [
migrations.AddField(
model_name='team',
name='backgroundColor',
field=models.CharField(blank=True, max_length=200),
),
]

@ -0,0 +1,18 @@
# Generated by Django 4.2 on 2023-07-28 13:25
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('scores', '0013_team_backgroundcolor'),
]
operations = [
migrations.AddField(
model_name='team',
name='shortname',
field=models.CharField(blank=True, max_length=200),
),
]

@ -0,0 +1,22 @@
# Generated by Django 4.2 on 2023-07-28 13:56
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('scores', '0014_team_shortname'),
]
operations = [
migrations.RemoveField(
model_name='team',
name='shortname',
),
migrations.AddField(
model_name='tournament',
name='shortname',
field=models.CharField(blank=True, max_length=200),
),
]

@ -0,0 +1,18 @@
# Generated by Django 4.2 on 2023-07-28 15:52
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('scores', '0015_remove_team_shortname_tournament_shortname'),
]
operations = [
migrations.AddField(
model_name='team',
name='dateLabel',
field=models.CharField(blank=True, max_length=200),
),
]

@ -0,0 +1,23 @@
# Generated by Django 4.2 on 2023-07-28 16:13
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('scores', '0016_team_datelabel'),
]
operations = [
migrations.AddField(
model_name='match',
name='refreshrate',
field=models.IntegerField(default=10),
),
migrations.AddField(
model_name='tournament',
name='tournament_index',
field=models.IntegerField(default=0),
),
]

@ -12,6 +12,9 @@ class Club(models.Model):
class Tournament(models.Model):
club = models.ForeignKey(Club, on_delete=models.CASCADE, default=None)
name = models.CharField(max_length=200)
auto_scrolling = models.BooleanField(default=False)
shortname = models.CharField(max_length=200, blank=True)
tournament_index = models.IntegerField(default=0)
def __str__(self):
return self.name
@ -27,6 +30,8 @@ class Match(models.Model):
date = models.DateTimeField('start date')
enddate = models.DateTimeField('end date', null=True, blank=True)
court = models.IntegerField(default=0)
match_index = models.IntegerField(default=0)
refreshrate = models.IntegerField(default=10)
title = models.CharField(max_length=200, blank=True)
team1 = models.CharField(max_length=200, blank=True)
@ -46,6 +51,9 @@ class Match(models.Model):
team2scorecolumn4 = models.CharField(max_length=200, blank=True)
team2scorecolumn5 = models.CharField(max_length=200, blank=True)
def teams(self):
return self.team_set.order_by('position')
def poule(self):
return self.court / 100
@ -100,3 +108,15 @@ class Match(models.Model):
def seconds(self):
return (timezone.now() - self.date).total_seconds()
class Team(models.Model):
name = models.CharField(max_length=200, blank=True)
rank = models.IntegerField(default=0)
position = models.IntegerField(default=0)
bracket = models.BooleanField(default=False)
positionLabel = models.CharField(max_length=200, blank=True)
dateLabel = models.CharField(max_length=200, blank=True)
backgroundColor = models.CharField(max_length=200, blank=True)
match = models.ForeignKey(Match, on_delete=models.CASCADE, default=None)

@ -1,6 +1,6 @@
from django.contrib.auth.models import User
from rest_framework import serializers
from .models import Match, Club, Tournament
from .models import Match, Club, Tournament, Team
class UserSerializer(serializers.HyperlinkedModelSerializer):
@ -16,11 +16,17 @@ class ClubSerializer(serializers.HyperlinkedModelSerializer):
class TournamentSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Tournament
fields = ['id', 'name', 'club']
fields = ['id', 'name', 'club', 'auto_scrolling', 'shortname', 'tournament_index']
class MatchSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Match
fields = ['id', 'tournament', 'date', 'enddate', 'title', 'team1', 'team2', 'team3', 'team4',
fields = ['id', 'match_index', 'tournament', 'date', 'enddate', 'title', 'refreshrate', 'team1', 'team2', 'team3', 'team4', 'team5',
'team1scorecolumn1', 'team1scorecolumn2', 'team1scorecolumn3', 'team1scorecolumn4', 'team1scorecolumn5',
'team2scorecolumn1', 'team2scorecolumn2', 'team2scorecolumn3', 'team2scorecolumn4', 'team2scorecolumn5']
class TeamSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Team
fields = ['id', 'name', 'brackgroundColor', 'rank', 'position', 'bracket', 'positionLabel', 'dateLabel', 'match']

@ -105,6 +105,7 @@ td {
width: 28%;
padding: 0px 20px;
vertical-align: top; /* here */
margin-bottom: 40px;
}
@ -134,6 +135,13 @@ td {
font-size: 150%;
}
.teams {
padding-top: 20px;
width: 1000px;
margin: 0 auto;
align-items: center;
}
.smatch {
padding-top: 20px;
width: 800px;

@ -3,12 +3,51 @@
{% load static %}
<head>
{% if tv %}
<script>history.scrollRestoration = "manual"</script>
<script src=
"https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js">
</script>
{% endif %}
<link rel="stylesheet" href="{% static 'scores/style.css' %}">
<title>Padel</title>
<meta http-equiv="refresh" content="15"/>
</head>
<div class="wrapper">
{% if live_matches.count|add:ended_matches.count > 6 and auto_scrolling and tv %}
<script>
var iInterval = 2000;
var iScrollInterval = 10000;
var iFadeInterval = 500;
var fade = function() {
$("body").fadeOut(iFadeInterval, function(){
$("html, body").scrollTop(0);
$("body").fadeIn(iFadeInterval,function(){
setTimeout(loop, iInterval);
});
});
}
var loop = function() {
var iScroll = $(document).height() - $(window).height();
$("html, body").animate({
scrollTop: iScroll
}, {
duration : iScrollInterval,
easing : "linear",
complete : function() {
setTimeout(fade, iInterval);
}
});
};
setTimeout(loop, iInterval);
</script>
{% endif %}
{% if club.header %}
<header class="center">{{ club.header }}</header>

@ -3,12 +3,59 @@
{% load static %}
<head>
<link rel="stylesheet" href="{% static 'scores/style.css' %}">
<title>Padel</title>
<meta http-equiv="refresh" content="15"/>
{% if tv %}
<script>history.scrollRestoration = "manual"</script>
<script src=
"https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js">
</script>
{% endif %}
<link rel="stylesheet" href="{% static 'scores/style.css' %}">
<title>Padel</title>
{% if match.teams %}
<meta http-equiv="refresh" content="15"/>
{% else %}
<meta http-equiv="refresh" content='{{ match.refreshrate }}'/>
{% endif %}
</head>
{% if tv %}
<div class="wrapper" style="zoom:200%">
{% else %}
<div class="wrapper">
{% endif %}
{% if tv %}
<script>
var iInterval = 2000;
var iScrollInterval = 10000;
var iFadeInterval = 500;
var fade = function() {
$("body").fadeOut(iFadeInterval, function(){
$("html, body").scrollTop(0);
$("body").fadeIn(iFadeInterval,function(){
setTimeout(loop, iInterval);
});
});
}
var loop = function() {
var iScroll = $(document).height() - $(window).height();
$("html, body").animate({
scrollTop: iScroll
}, {
duration : iScrollInterval,
easing : "linear",
complete : function() {
setTimeout(fade, iInterval);
}
});
};
setTimeout(loop, iInterval);
</script>
{% endif %}
{% if match.tournament.club.header %}
<header class="scenter">{{ match.tournament.club.header }}</header>
@ -19,15 +66,40 @@
<div class="scenter">{{ match.tournament.name }}</div>
<div class="scontainer">
<div class="smatch">
<h1 class="scenter" style="padding-bottom:20px">{{ match.title }}</h1>
<!-- <p class="duration">
<div class="alignleft"><h1>{{ match.title }}</h1></div>
<div class="big alignright"><a href="/match/{{ match.id }}/">TERRAIN #{{ match.court }}</a></div>
</p> -->
<div class="teams">
{% if match.teams %}
<h1>Liste des équipes<h1>
<table>
<tr>
<th>Rang</th>
<th>Nom</th>
<th>Poids</th>
<th>Entrée</th>
<th>Jour</th>
</tr>
{% for team in teams %}
<tr height='100%' style="background-color:{{ team.backgroundColor }};">
<td class="score">#{{ team.position }}</td>
<td class="name" width='50%'>{{ team.name|linebreaksbr }}</td>
<td class="score">{{ team.rank }}</td>
{% if team.bracket %}
<td class="name" width='20%'>Poule</td>
{% else %}
<td class="name" width='20%'>{{ team.positionLabel }}</td>
{% endif %}
{% if team.dateLabel %}
<td class="name">{{ team.dateLabel }}</td>
{% else %}
<td class="name"> - </td>
{% endif %}
</tr>
{% endfor %}
</table>
{% else %}
<h1 class="scenter" style="padding-bottom:20px">{{ match.title }}</h1>
{% if match.team3 %}
@ -88,6 +160,11 @@
</p>
{% endif %}
{% endif %}
</div>
</div>

@ -3,12 +3,51 @@
{% load static %}
<head>
{% if tv %}
<script>history.scrollRestoration = "manual"</script>
<script src=
"https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js">
</script>
{% endif %}
<link rel="stylesheet" href="{% static 'scores/style.css' %}">
<title>Padel</title>
<meta http-equiv="refresh" content="15"/>
</head>
<div class="wrapper">
{% if live_matches.count|add:ended_matches.count > 6 and auto_scrolling and tv %}
<script>
var iInterval = 2000;
var iScrollInterval = 10000;
var iFadeInterval = 500;
var fade = function() {
$("body").fadeOut(iFadeInterval, function(){
$("html, body").scrollTop(0);
$("body").fadeIn(iFadeInterval,function(){
setTimeout(loop, iInterval);
});
});
}
var loop = function() {
var iScroll = $(document).height() - $(window).height();
$("html, body").animate({
scrollTop: iScroll
}, {
duration : iScrollInterval,
easing : "linear",
complete : function() {
setTimeout(fade, iInterval);
}
});
};
setTimeout(loop, iInterval);
</script>
{% endif %}
{% if tournament.club.header %}
<header class="center">{{ tournament.club.header }}</header>

@ -19,10 +19,32 @@ from django.urls import path
from . import views
urlpatterns = [
path('match/<int:match_id>/', views.match, name='match'),
path('tv/club/<str:club_name>/<int:tournament_id>/equipes/', views.tv_teams_club_name_tournament, name='match_scrolling'),
path('tv/tournoi/<str:tournament_shortname>/equipes/', views.tv_teams_tournament_name, name='match_scrolling'),
path('tv/club/<str:club_name>/<str:tournament_shortname>/equipes/', views.tv_teams_club_name_tournament_name, name='match_scrolling'),
path('tv/', views.index, name='index_scrolling'),
path('tv/tournoi/<str:tournament_shortname>/', views.tv_tournament_name, name='tournament_scrolling'),
path('tv/club/<str:club_name>/', views.club_name, name='club'),
path('tv/club/<str:club_name>/<int:tournament_id>/', views.tv_club_name_tournament, name='tournament_scrolling'),
path('tv/club/<str:club_name>/<str:tournament_shortname>/', views.tv_club_name_tournament_name, name='tournament_scrolling'),
path('club/<str:club_name>/<str:tournament_shortname>/equipes/', views.teams_club_name_tournament_name, name='match'),
path('tournoi/<str:tournament_shortname>/equipes/', views.teams_tournament_name, name='match'),
path('tournoi/<int:tournament_id>/equipes/', views.teams_tournament, name='match'),
path('club/<str:club_name>/<str:tournament_shortname>/equipes/', views.teams_club_name_tournament_name, name='match'),
path('club/<str:club_name>/<int:tournament_id>/equipes', views.teams_club_name_tournament, name='match'),
path('club/<str:club_name>/<str:tournament_shortname>/', views.club_name_tournament_name, name='tournament'),
path('club/<str:club_name>/<int:tournament_id>/', views.club_name_tournament, name='tournament'),
path('club/<str:club_name>/', views.club_name, name='club'),
path('', views.index, name='index'),
path('club/<int:club_id>/', views.club, name='club'),
path('club/<str:club_name>/', views.club_name, name='club'),
path('tournament/<int:tournament_id>/', views.tournament, name='tournament'),
path('club/<str:club_name>/<int:tournament_id>/', views.tournament_club, name='tournament'),
path('match/<int:match_id>/', views.match, name='match'),
path('club/<str:club_name>/<int:tournament_id>/', views.club_name_tournament, name='tournament'),
path('club/<str:club_name>/<str:tournament_shortname>/', views.club_name_tournament_name, name='tournament'),
path('tournoi/<int:tournament_id>/', views.tournament, name='tournament'),
path('tournoi/<str:tournament_shortname>/', views.tournament_name, name='tournament'),
]

@ -2,8 +2,8 @@ from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse
from django.template import loader
from django.contrib.auth.models import User
from .models import Match, Club, Tournament
from .serializers import UserSerializer, MatchSerializer, ClubSerializer, TournamentSerializer
from .models import Match, Club, Tournament, Team
from .serializers import UserSerializer, MatchSerializer, ClubSerializer, TournamentSerializer, TeamSerializer
from rest_framework import viewsets
from rest_framework import permissions
@ -41,9 +41,18 @@ def club_name(request, club_name):
}
return HttpResponse(template.render(context, request))
def tournament_club(request, club_name, tournament_id):
def tournament_name(request, tournament_shortname):
tournamentFound = Tournament.objects.filter(shortname__iexact=tournament_shortname.lower()).first()
return tournament(request, tournamentFound.id)
def club_name_tournament(request, club_name, tournament_id):
return tournament(request, tournament_id)
def club_name_tournament_name(request, club_name, tournament_shortname):
club = get_object_or_404(Club, name__iexact=club_name.lower())
tournamentFound = Tournament.objects.filter(club_id=club.id, shortname__iexact=tournament_shortname.lower()).first()
return tournament(request, tournamentFound.id)
def tournament(request, tournament_id):
tournament = get_object_or_404(Tournament, pk=tournament_id)
@ -61,12 +70,107 @@ def tournament(request, tournament_id):
def match(request, match_id):
match = get_object_or_404(Match, pk=match_id)
teams = Team.objects.filter(match=match.id).order_by('position')
template = loader.get_template('scores/match.html')
context = {
'match': match,
'teams': teams,
}
return HttpResponse(template.render(context, request))
def teams_tournament_name(request, tournament_shortname):
tournament = get_object_or_404(Tournament, shortname__iexact=tournament_shortname.lower())
return teams_tournament(request, tournament.id)
def teams_club_name_tournament(request, club_name, tournament_id):
club = get_object_or_404(Club, name__iexact=club_name.lower())
tournament = get_object_or_404(Tournament, pk=tournament_id)
return teams_tournament(request, tournament.id)
def teams_club_name_tournament_name(request, club_name, tournament_shortname):
club = get_object_or_404(Club, name__iexact=club_name.lower())
tournament = Tournament.objects.filter(club_id=club.id, shortname__iexact=tournament_shortname.lower()).first()
return teams_tournament(request, tournament.id)
def teams_tournament(request, tournament_id):
tournament = get_object_or_404(Tournament, pk=tournament_id)
match = Match.objects.filter(tournament=tournament.id).filter(match_index=0).first()
teams = Team.objects.filter(match=match.id).order_by('position')
template = loader.get_template('scores/match.html')
context = {
'match': match,
'teams': teams,
}
return HttpResponse(template.render(context, request))
def tv_index(request):
club = Club.objects.first()
live_matches = Match.objects.filter(enddate__isnull=True).order_by('court')
ended_matches = Match.objects.filter(enddate__isnull=False).order_by('court')
template = loader.get_template('scores/index.html')
context = {
'club': club,
'live_matches': live_matches,
'ended_matches': ended_matches,
'tv': True,
}
return HttpResponse(template.render(context, request))
def tv_tournament_name(request, tournament_shortname):
tournamentFound = Tournament.objects.filter(shortname__iexact=tournament_shortname.lower()).first()
return tv_tournament(request, tournamentFound.id)
def tv_club_name_tournament(request, club_name, tournament_id):
return tv_tournament(request, tournament_id)
def tv_club_name_tournament_name(request, club_name, tournament_shortname):
club = get_object_or_404(Club, name__iexact=club_name.lower())
tournamentFound = Tournament.objects.filter(club_id=club.id, shortname__iexact=tournament_shortname.lower()).first()
return tv_tournament(request, tournamentFound.id)
def tv_tournament(request, tournament_id):
tournament = get_object_or_404(Tournament, pk=tournament_id)
live_matches = Match.objects.filter(tournament=tournament.id, enddate__isnull=True).order_by('court')
ended_matches = Match.objects.filter(tournament=tournament.id, enddate__isnull=False).order_by('court')
template = loader.get_template('scores/tournament.html')
context = {
'tournament': tournament,
'live_matches': live_matches,
'ended_matches': ended_matches,
'tv': True,
}
return HttpResponse(template.render(context, request))
def tv_teams_tournament_name(request, tournament_shortname):
tournament = get_object_or_404(Tournament, shortname__iexact=tournament_shortname.lower())
return tv_teams_tournament(request, tournament.id)
def tv_teams_club_name_tournament(request, club_name, tournament_id):
club = get_object_or_404(Club, name__iexact=club_name.lower())
tournament = get_object_or_404(Tournament, pk=tournament_id)
return tv_teams_tournament(request, tournament.id)
def tv_teams_club_name_tournament_name(request, club_name, tournament_shortname):
club = get_object_or_404(Club, name__iexact=club_name.lower())
tournament = Tournament.objects.filter(club_id=club.id, shortname__iexact=tournament_shortname.lower()).first()
return tv_teams_tournament(request, tournament.id)
def tv_teams_tournament(request, tournament_id):
tournament = get_object_or_404(Tournament, pk=tournament_id)
match = Match.objects.filter(tournament=tournament.id).filter(match_index=0).first()
teams = Team.objects.filter(match=match.id).order_by('position')
template = loader.get_template('scores/match.html')
context = {
'match': match,
'teams': teams,
'tv': True,
}
return HttpResponse(template.render(context, request))
class UserViewSet(viewsets.ModelViewSet):
"""
@ -96,6 +200,14 @@ class MatchViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows matches to be viewed or edited.
"""
queryset = Match.objects.all().order_by('court')
queryset = Match.objects.all().order_by('match_index')
serializer_class = MatchSerializer
permission_classes = [permissions.IsAuthenticated]
class TeamViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows teams to be viewed or edited.
"""
queryset = Team.objects.all().order_by('id')
serializer_class = TeamSerializer
permission_classes = [permissions.IsAuthenticated]

Loading…
Cancel
Save