[chronojump-server] Creates sprintResult page with all functionalities
- From: Max Ros i Morejon <maxros src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [chronojump-server] Creates sprintResult page with all functionalities
- Date: Tue, 18 Jun 2019 14:17:43 +0000 (UTC)
commit 375bc64483cbca28fdce6bae8a177d00bbd81da3
Author: Max Ros i Morejon <mros33 gmail com>
Date: Tue Jun 18 16:17:22 2019 +0200
Creates sprintResult page with all functionalities
.../organizations/api/serializers.py | 2 +-
.../chronojump_networks/organizations/api/views.py | 6 +-
.../chronojump_networks/organizations/models.py | 35 +-
.../chronojump_networks/results/api/serializers.py | 21 +-
.../chronojump_networks/results/api/urls.py | 22 +-
.../chronojump_networks/results/api/views.py | 81 +++-
.../chronojump_networks/results/models.py | 26 ++
.../chronojump_networks/results/urls.py | 6 +-
.../chronojump_networks/tasks/models.py | 1 +
.../chronojump_networks/templates/layout.html | 11 +-
.../organizations/groups/group_players_list.html | 11 +-
.../players/add_edit_player_form.html | 4 +-
.../organizations/players/players_list.html | 10 +-
.../chronojump_networks/templates/pages/index.html | 4 +-
.../templates/results/results_list.html | 8 +-
.../templates/results/sprints_list.html | 490 +++++++++++++++++++++
chronojumpserver-django/rfid-csharp/RFID.cs | 10 +-
17 files changed, 713 insertions(+), 35 deletions(-)
---
diff --git a/chronojumpserver-django/chronojump_networks/organizations/api/serializers.py
b/chronojumpserver-django/chronojump_networks/organizations/api/serializers.py
index a999c26..7b10180 100644
--- a/chronojumpserver-django/chronojump_networks/organizations/api/serializers.py
+++ b/chronojumpserver-django/chronojump_networks/organizations/api/serializers.py
@@ -8,7 +8,7 @@ class PlayerSerializer(serializers.ModelSerializer):
player_tasks = PlayerTaskSerializer(many=True)
class Meta:
model = Player
- fields = [ 'id', 'name', 'number', 'height', 'weight', 'image', 'player_tasks', 'rfid']
+ fields = [ 'id', 'name', 'number', 'height', 'weight', 'imageName', 'player_tasks', 'rfid']
class GymSerializer(serializers.ModelSerializer):
diff --git a/chronojumpserver-django/chronojump_networks/organizations/api/views.py
b/chronojumpserver-django/chronojump_networks/organizations/api/views.py
index d977a0c..aa4c327 100644
--- a/chronojumpserver-django/chronojump_networks/organizations/api/views.py
+++ b/chronojumpserver-django/chronojump_networks/organizations/api/views.py
@@ -168,7 +168,7 @@ class PlayerListView(ListCreateAPIView):
print(new_photo)
o = Player.objects.create(
name = str(data['name'][0]),
- image = newimage,
+ imageName = newimage,
number = int(data['number'][0]),
height = float(data['height'][0]),
weight = float(data['weight'][0]),
@@ -194,11 +194,11 @@ class PlayerListView(ListCreateAPIView):
try:
photo = data['image'][0]
except KeyError:
- o.image = '../static/images/default_player.png'
+ o.imageName = '../static/images/default_player.png'
else:
photo = data['image'][0]
new_photo = photo.name + '_' + str(int(time()))
- o.image = 'players/' + new_photo
+ o.imageName = 'players/' + new_photo
full_path = os.path.join(settings.MEDIA_ROOT, 'players', new_photo)
path = default_storage.save(full_path, ContentFile(photo.read()))
o.save()
diff --git a/chronojumpserver-django/chronojump_networks/organizations/models.py
b/chronojumpserver-django/chronojump_networks/organizations/models.py
index f7daec0..734e2ca 100644
--- a/chronojumpserver-django/chronojump_networks/organizations/models.py
+++ b/chronojumpserver-django/chronojump_networks/organizations/models.py
@@ -92,11 +92,42 @@ class User(AbstractUser):
gym_list = [gm.id for gm in gym_organization]
stations = Station.objects.filter(gym_id__in = gym_list)
return stations
-
+
def exercises_by_coach(self):
station_list = self.stations_by_coach()
exercices = Exercise.objects.filter(station_id__in = station_list)
return exercices
+
+ def encoder_stations_by_coach(self):
+ group_list = [g.group.id for g in self.groups_by_coach.all()]
+ group_organizations = Organization.objects.filter(groups__in = group_list)
+ organization_list = [gp.id for gp in group_organizations]
+ gym_organization = Gym.objects.filter(organization_id__in = organization_list)
+ gym_list = [gm.id for gm in gym_organization]
+ stations = Station.objects.filter(gym_id__in = gym_list)
+ stations = stations.exclude(type__exact = 'S')
+ return stations
+
+ def encoder_exercises_by_coach(self):
+ station_list = self.encoder_stations_by_coach()
+ exercices = Exercise.objects.filter(station_id__in = station_list)
+ return exercices
+
+ #def sprint_stations_by_coach(self):
+ #group_list = [g.group.id for g in self.groups_by_coach.all()]
+ #group_organizations = Organization.objects.filter(groups__in = group_list)
+ #organization_list = [gp.id for gp in group_organizations]
+ #gym_organization = Gym.objects.filter(organization_id__in = organization_list)
+ #gym_list = [gm.id for gm in gym_organization]
+ #stations = Station.objects.filter(gym_id__in = gym_list)
+ #stations = stations.filter(type__exact = 'S')
+ #return stations
+
+ #def sprint_exercises_by_coach(self):
+ #station_list = self.sprint_stations_by_coach()
+ #exercices = Exercise.objects.filter(station_id__in = station_list)
+ #return exercices
+
class Organization(ChronojumpBaseModel):
@@ -219,7 +250,7 @@ class Player(ChronojumpBaseModel):
height = models.FloatField(default=0)
weight = models.FloatField(default=0)
rfid = models.CharField(max_length=23, unique=True)
- image = models.FileField(upload_to='players', null=True, blank=True,
default='../static/images/player.png')
+ imageName = models.FileField(upload_to='players', null=True, blank=True,
default='../static/images/player.png')
is_available = models.BooleanField(default=True)
number = models.IntegerField(null=True,blank=True)
diff --git a/chronojumpserver-django/chronojump_networks/results/api/serializers.py
b/chronojumpserver-django/chronojump_networks/results/api/serializers.py
index 8cca765..a9b19c5 100644
--- a/chronojumpserver-django/chronojump_networks/results/api/serializers.py
+++ b/chronojumpserver-django/chronojump_networks/results/api/serializers.py
@@ -1,6 +1,6 @@
from rest_framework import serializers
-from ..models import ResultEncoder
+from ..models import ResultEncoder, ResultSprint
class ResultEncoderSerializer(serializers.ModelSerializer):
@@ -33,3 +33,22 @@ class ResultEncoderSerializer(serializers.ModelSerializer):
'pmeanByPower',
'pmaxByPower',
'comments']
+
+class ResultSprintSerializer(serializers.ModelSerializer):
+ person = serializers.StringRelatedField()
+
+ class Meta:
+ model = ResultSprint
+ fields = [ 'id',
+ 'dt',
+ 'person',
+ 'distances',
+ 't1',
+ 't2',
+ 't3',
+ 't4',
+ 'k',
+ 'vmax',
+ 'amax',
+ 'fmax',
+ 'pmax']
diff --git a/chronojumpserver-django/chronojump_networks/results/api/urls.py
b/chronojumpserver-django/chronojump_networks/results/api/urls.py
index 920035a..c1bfd97 100644
--- a/chronojumpserver-django/chronojump_networks/results/api/urls.py
+++ b/chronojumpserver-django/chronojump_networks/results/api/urls.py
@@ -8,18 +8,34 @@ from . import views
urlpatterns = [
url(
# regex=r'^(?P<organization_id>\d+)/(?P<group_id>\d+)/players$',
- regex=r'^list$',
+ regex=r'^encoder/list$',
view=views.ResultEncoderList.as_view(),
name='results_list'
),
url(
- regex=r'^(?P<result_id>\d+)$',
+ regex=r'^encoder/(?P<result_id>\d+)$',
view=views.ResultEncoderRetrieveUpdateDestroyAPIView.as_view(),
name='results'
),
url(
- regex=r'^delete$',
+ regex=r'^encoder/delete$',
view=views.ResultEncoderDestroyAPIView.as_view(),
name='results_delete'
+ ),
+ url(
+ # regex=r'^(?P<organization_id>\d+)/(?P<group_id>\d+)/players$',
+ regex=r'^sprint/list$',
+ view=views.ResultSprintList.as_view(),
+ name='sprints_list'
+ ),
+ url(
+ regex=r'^sprint/(?P<result_id>\d+)$',
+ view=views.ResultSprintRetrieveUpdateDestroyAPIView.as_view(),
+ name='sprints'
+ ),
+ url(
+ regex=r'^sprint/delete$',
+ view=views.ResultSprintDestroyAPIView.as_view(),
+ name='sprints_delete'
)
]
diff --git a/chronojumpserver-django/chronojump_networks/results/api/views.py
b/chronojumpserver-django/chronojump_networks/results/api/views.py
index 943278b..0e7a2bf 100644
--- a/chronojumpserver-django/chronojump_networks/results/api/views.py
+++ b/chronojumpserver-django/chronojump_networks/results/api/views.py
@@ -1,5 +1,5 @@
-from ..models import ResultEncoder
-from .serializers import ResultEncoderSerializer
+from ..models import ResultEncoder, ResultSprint
+from .serializers import ResultEncoderSerializer, ResultSprintSerializer
from django.http import HttpResponse, JsonResponse
from django.shortcuts import get_object_or_404
@@ -81,6 +81,7 @@ class ResultEncoderList(ListAPIView):
d = datetime.now() - timedelta(timeInterval)
print(d)
queryset = ResultEncoder.objects.filter(person__in = player_list, dt__gte = d, station__in =
station_list, exercise__in = exercise_list)
+ stations = stations.exclude(type__exact = 'S')
else:
# No filter by time
queryset = ResultEncoder.objects.filter(person__in = player_list, station__in = station_list,
exercise__in = exercise_list)
@@ -120,3 +121,79 @@ class ResultEncoderDestroyAPIView(DestroyAPIView):
o.delete()
print("Result %d removed" % (int(result_id), ))
return JsonResponse({}, status=204, safe=False)
+
+
+class ResultSprintList(ListAPIView):
+ permission_classes = (IsAuthenticated, )
+ serializer_class = ResultSprintSerializer
+
+ def get(self, request, *args, **kwargs):
+ data = dict(request.GET)
+ org_id = int(data['org_id'][0])
+ coach_id = int(data['coach_id'][0])
+ group_id = str(data['group_id'][0])
+ timeInterval = int(data['timeInterval'][0])
+ player_id = str(data['player_id'][0])
+
+ #GROUP SELECT
+ if group_id.lower() == "all":
+ # Get all results from all the groups of the coach
+ coach = get_object_or_404(User, pk=coach_id)
+ group_list = [g.group.id for g in coach.groups_by_coach.all()]
+
+ players = GroupPlayer.objects.filter(group_id__in = group_list)
+ player_list = [p.player_id for p in players]
+ else:
+ players = GroupPlayer.objects.filter(group_id = int(group_id))
+ player_list = [p.player_id for p in players]
+
+ #PLAYER SELECT
+ if player_id.lower() != "all":
+ players = Player.objects.filter(id = int(player_id))
+ player_list_aux = [p.id for p in players]
+ player_list = [value for value in player_list if value in player_list_aux]
+
+ if timeInterval > 0 :
+ print(timeInterval)
+ d = datetime.now() - timedelta(timeInterval)
+ print(d)
+ queryset = ResultSprint.objects.filter(person__in = player_list, dt__gte = d)
+ else:
+ # No filter by time
+ queryset = ResultSprint.objects.filter(person__in = player_list)
+ # Serialize the results and return
+ serializer = ResultSprintSerializer(queryset, many=True)
+ return Response(serializer.data)
+
+
+class ResultSprintRetrieveUpdateDestroyAPIView(RetrieveUpdateDestroyAPIView):
+
+ permission_classes = (IsAuthenticated, )
+ serializer_class = ResultSprintSerializer
+ lookup_field = 'result_id'
+
+ def retrieve(self, request, *args, **kwars):
+ #print(self.kwargs['task_id'])
+ o = get_object_or_404(Task, id=self.kwargs['result_id'])
+ s = ResultSprintSerializer(o)
+ return Response(s.data)
+
+ def destroy(self, request, *args, **kwargs):
+ o = get_object_or_404(Task, id=self.kwargs['result_id'])
+ o.delete()
+ print("Result %d removed" % (result_id, ))
+ return JsonResponse({}, status=204, safe=False)
+
+class ResultSprintDestroyAPIView(DestroyAPIView):
+ """Remove players from group"""
+ permission_classes = (IsAuthenticated, )
+ serializer_class = ResultSprintSerializer
+
+ def destroy(self, request, *args, **kwargs):
+
+ results_ids = request.data
+ for result_id in results_ids:
+ o = ResultSprint.objects.get(id=int(result_id))
+ o.delete()
+ print("Result %d removed" % (int(result_id), ))
+ return JsonResponse({}, status=204, safe=False)
diff --git a/chronojumpserver-django/chronojump_networks/results/models.py
b/chronojumpserver-django/chronojump_networks/results/models.py
index ee38709..6a82082 100644
--- a/chronojumpserver-django/chronojump_networks/results/models.py
+++ b/chronojumpserver-django/chronojump_networks/results/models.py
@@ -65,3 +65,29 @@ class ResultEncoder(models.Model):
pmeanByPower = models.FloatField(default=0.0)
pmaxByPower = models.FloatField(default=0.0)
comments = models.CharField(max_length=30, blank=True, null=True)
+
+
+class ResultSprint(models.Model):
+
+ class Meta:
+ db_table = 'resultSprint'
+
+ dt = models.DateTimeField(null=True)
+
+ person = models.ForeignKey(Player,
+ on_delete=models.CASCADE,
+ related_name='players_sprints',
+ db_column='personId')
+
+
+ distances = models.CharField(max_length=50, default="5m")
+ k = models.FloatField(default=0.0)
+ vmax = models.FloatField(default=0.0)
+ amax = models.FloatField(default=0.0)
+ fmax = models.FloatField(default=0.0)
+ pmax = models.FloatField(default=0.0)
+ t1 = models.FloatField(default=0.0)
+ t2 = models.FloatField(default=0.0)
+ t3 = models.FloatField(default=0.0)
+ t4 = models.FloatField(default=0.0)
+
diff --git a/chronojumpserver-django/chronojump_networks/results/urls.py
b/chronojumpserver-django/chronojump_networks/results/urls.py
index 7bcf801..b6dffb4 100644
--- a/chronojumpserver-django/chronojump_networks/results/urls.py
+++ b/chronojumpserver-django/chronojump_networks/results/urls.py
@@ -10,7 +10,11 @@ from . import views
app_name = 'results'
urlpatterns = [
url(
- regex=r'^$',
+ regex=r'^encoder$',
view=login_required(TemplateView.as_view(template_name='results/results_list.html')),
name='list'),
+ url(
+ regex=r'^sprint$',
+ view=login_required(TemplateView.as_view(template_name='results/sprints_list.html')),
+ name='sprint'),
]
diff --git a/chronojumpserver-django/chronojump_networks/tasks/models.py
b/chronojumpserver-django/chronojump_networks/tasks/models.py
index c3f580f..29b7a75 100644
--- a/chronojumpserver-django/chronojump_networks/tasks/models.py
+++ b/chronojumpserver-django/chronojump_networks/tasks/models.py
@@ -65,3 +65,4 @@ class Task(models.Model):
default=LATERALITY_BOTH )
comment = models.CharField(max_length=150, null=True, blank=True)
done = models.BooleanField(default=False)
+
diff --git a/chronojumpserver-django/chronojump_networks/templates/layout.html
b/chronojumpserver-django/chronojump_networks/templates/layout.html
index 48cb58d..681aaf1 100644
--- a/chronojumpserver-django/chronojump_networks/templates/layout.html
+++ b/chronojumpserver-django/chronojump_networks/templates/layout.html
@@ -12,8 +12,15 @@
<li class="nav-item active">
<a class="nav-link" href="/">{% trans 'Home' %} <span class="sr-only">(current)</span></a>
</li>
- <li class="nav-item">
- <a class="nav-link active" href="{% url 'results:list' %}">{% trans 'Results' %}</a>
+ <li class="nav-item dropdown active">
+ <a class="nav-link dropdown-toggle" href="#" id="navbarDropdownResults" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
+ {% trans 'Results' %}
+ </a>
+ <div class="dropdown-menu" aria-labelledby="navbarDropdownResults">
+ <h6 class="dropdown-header">{% trans 'Results' %}</h6>
+ <a class="dropdown-item" href="{% url 'results:list' %}">{% trans 'Encoder results' %}</a>
+ <a class="dropdown-item" href="{% url 'results:sprint' %}">{% trans 'Sprint results' %}</a>
+ </div>
</li>
<!--<li class="nav-item">
<a class="nav-link disabled" href="#">{% trans 'Sprints' %}</a>
diff --git
a/chronojumpserver-django/chronojump_networks/templates/organizations/groups/group_players_list.html
b/chronojumpserver-django/chronojump_networks/templates/organizations/groups/group_players_list.html
index fc2639f..ee08c8e 100644
--- a/chronojumpserver-django/chronojump_networks/templates/organizations/groups/group_players_list.html
+++ b/chronojumpserver-django/chronojump_networks/templates/organizations/groups/group_players_list.html
@@ -126,7 +126,7 @@
{
type: "html",
title: "",
- data: 'image',
+ data: 'imageName',
orderable: false,
render: function(value, type, row) {
if (value) {
@@ -231,7 +231,12 @@
/* Task child rows */
function format ( d ) {
// `d` is the original data object for the row
- if (d.player_tasks.length > 0) {
+ //if (d.player_tasks;.length > 0) {
+ var found=0;
+ $.each(d.player_tasks, function(index, task) {
+ if(task.done==0) found=1;
+ })
+ if(found) {
var html = '<table cellpadding="5" cellspacing="10" style="margin-left:50px;">';
html += "<thead><th></th><th>{% trans 'Gym' %}";
html += "<th>{% trans 'Station' %}</th><th>{% trans 'Exercise' %}</th>";
@@ -239,6 +244,7 @@
html += "<th>{% trans 'Load' %}</th></th><th>{% trans 'Speed' %}";
html +="</th><th></th>"
$.each(d.player_tasks, function(index, task) {
+ if(task.done==0) {
console.log(task);
html += '<tbody><tr>';
html += '<td>' + (index + 1) + '</td>';
@@ -274,6 +280,7 @@
html += 'data-task-type="' + task.type + '">'
html += '<i class="material-icons">delete_sweep</i></a>';
html += '</td></tr>';
+ }
});
html += "</tbody></table>";
diff --git
a/chronojumpserver-django/chronojump_networks/templates/organizations/players/add_edit_player_form.html
b/chronojumpserver-django/chronojump_networks/templates/organizations/players/add_edit_player_form.html
index 6dff114..8d8da6a 100644
--- a/chronojumpserver-django/chronojump_networks/templates/organizations/players/add_edit_player_form.html
+++ b/chronojumpserver-django/chronojump_networks/templates/organizations/players/add_edit_player_form.html
@@ -21,11 +21,11 @@
<img id="imgView" src="{% static 'images/default_player.png' %}"
alt="player_image" style="width:100%;
height:100%; object-fit: contain">
</div>
- <div>
+ <div class="form-group col-sm-8">
<!--input id="clearImgId" type="button" name="clearImg" value="ClearImg"-->
<button class="btn btn-outline-secondary" type="button"
id="btn_delete_image">Delete Image</button>
</div>
- <div class="form-group col-sm-4">
+ <div class="form-group col-sm-8">
<p>
<input id="id_image" type="file" class="" name="image"
enctype='multipart/form-data'>
</p>
diff --git a/chronojumpserver-django/chronojump_networks/templates/organizations/players/players_list.html
b/chronojumpserver-django/chronojump_networks/templates/organizations/players/players_list.html
index f23bfac..febbea5 100644
--- a/chronojumpserver-django/chronojump_networks/templates/organizations/players/players_list.html
+++ b/chronojumpserver-django/chronojump_networks/templates/organizations/players/players_list.html
@@ -80,7 +80,7 @@
{
type: "html",
title: "",
- data: 'image',
+ data: 'imageName',
orderable: false,
render: function(value, type, row) {
if (value) {
@@ -314,10 +314,10 @@
$('#weight').val(player.weight);
$('#number').val(player.number);
$('#input_rfid').val(player.rfid);
- console.log(player.image);
- $('#imgView').prop("src", player.image);
- $('#id_image').val(player.image.name);
- image_pl = player.image;
+ console.log(player.imageName);
+ $('#imgView').prop("src", player.imageName);
+ $('#id_image').val(player.imageName.name);
+ image_pl = player.imageName;
}
function putPlayer(player) {
diff --git a/chronojumpserver-django/chronojump_networks/templates/pages/index.html
b/chronojumpserver-django/chronojump_networks/templates/pages/index.html
index 9db1ea6..98f3ca1 100644
--- a/chronojumpserver-django/chronojump_networks/templates/pages/index.html
+++ b/chronojumpserver-django/chronojump_networks/templates/pages/index.html
@@ -60,10 +60,10 @@
<h2 class="text-center">{% trans 'Player results' %}</h2>
<div class="row buttons">
<div class="col-sm-6">
- <a class="btn btn-outline-dark btn-block font-weight-bold text-uppercase" href="{% url
'results:list' %}">{% trans 'Results' %}</a>
+ <a class="btn btn-outline-dark btn-block font-weight-bold text-uppercase" href="{% url
'results:list' %}">{% trans 'Encoder results' %}</a>
</div>
<div class="col-sm-6">
- <a class="btn btn-outline-dark btn-block font-weight-bold text-uppercase" href="#">{% trans
'Sprints' %}</a>
+ <a class="btn btn-outline-dark btn-block font-weight-bold text-uppercase" href="{% url
'results:sprint' %}">{% trans 'Sprint results' %}</a>
</div>
</div>
{% if user.groups_by_coach %}
diff --git a/chronojumpserver-django/chronojump_networks/templates/results/results_list.html
b/chronojumpserver-django/chronojump_networks/templates/results/results_list.html
index 3df7482..0563eb9 100644
--- a/chronojumpserver-django/chronojump_networks/templates/results/results_list.html
+++ b/chronojumpserver-django/chronojump_networks/templates/results/results_list.html
@@ -22,7 +22,7 @@
{% else %}
<img src="{{STATIC_URL}}images/logo_club.png" class="img-fluid float-left" width="48px"
height="48px" style="margin-top:12px;margin-right:10px;" />
{% endif %}
- <h1 class="display-4">{% trans 'Results' %} <small class="text-muted" style="font-size:32px">{% trans
'List' %}</small></h1>
+ <h1 class="display-4">{% trans 'Encoder results' %} <small class="text-muted" style="font-size:32px">{%
trans 'List' %}</small></h1>
</div>
<div class="col-sm-3">
@@ -63,7 +63,7 @@
<label for="stationSelect">{% trans 'Filter by station' %}</label>
<select name="station" class="form-control" id="stationSelect">
<option value="all">{% trans 'All stations' %}
- {% for station in user.stations_by_coach %}
+ {% for station in user.encoder_stations_by_coach %}
<option value={{station.id}}>{{station.name}}</option>
{% endfor %}
</select>
@@ -72,7 +72,7 @@
<label for="exerciseSelect">{% trans 'Filter by exercise' %}</label>
<select name="exercise" class="form-control" id="exerciseSelect">
<option value="all">{% trans 'All exercises' %}
- {% for exercise in user.exercises_by_coach %}
+ {% for exercise in user.encoder_exercises_by_coach %}
<option value={{exercise.id}}>{{exercise.name}}</option>
{% endfor %}
</select>
@@ -548,7 +548,7 @@
$('.time-interval-btn').removeClass('active btn-primary').addClass('btn-secondary');
$(this).removeClass('btn-secondary').addClass('btn-primary active');
$('#time-interval').val(parseInt($(this).attr('data-time-interval')));
- console.log("Chsange data interval to " + $('#time-interval').val());
+ console.log("Change data interval to " + $('#time-interval').val());
table_results.ajax.reload(enableDeletion, true);
})
diff --git a/chronojumpserver-django/chronojump_networks/templates/results/sprints_list.html
b/chronojumpserver-django/chronojump_networks/templates/results/sprints_list.html
new file mode 100644
index 0000000..9265f97
--- /dev/null
+++ b/chronojumpserver-django/chronojump_networks/templates/results/sprints_list.html
@@ -0,0 +1,490 @@
+{% extends 'layout.html' %}
+{% load static i18n %}
+
+{% block title %}Chronojump Networks | {{user.organization.name}} | {% trans 'Sprints' %} {% endblock %}
+
+{% block css %}
+{{ block.super }}
+<link rel="stylesheet" href="https://cdn.datatables.net/1.10.16/css/dataTables.bootstrap4.min.css">
+<link rel="stylesheet" href="https://cdn.datatables.net/buttons/1.5.1/css/buttons.bootstrap4.min.css">
+
+<!--<link rel="stylesheet"
href="https://cdn.datatables.net/fixedcolumns/3.2.4/css/fixedColumns.bootstrap4.min.css">-->
+
+{% endblock %}
+
+{% block content %}
+{% csrf_token %}
+
+<div class="page-header row">
+ <div class="col-sm-9">
+ {% if user.organization.image %}
+ <img src="{{MEDIA_URL}}{{ user.organization.image }}" class="img-fluid float-left" width="48px"
height="48px" style="margin-top:12px;margin-right:10px;" />
+ {% else %}
+ <img src="{{STATIC_URL}}images/logo_club.png" class="img-fluid float-left" width="48px"
height="48px" style="margin-top:12px;margin-right:10px;" />
+ {% endif %}
+ <h1 class="display-4">{% trans 'Sprint results' %} <small class="text-muted" style="font-size:32px">{%
trans 'List' %}</small></h1>
+ </div>
+ <div class="col-sm-3">
+
+ </div>
+</div>
+<div class="row datatables_wrapped">
+ <div class="col form-group">
+ <label>{% trans 'Filter by time' %}</label><br/>
+ <div class="btn-group" role="group" aria-label="Basic example">
+ <button type="button" class="btn btn-primary active time-interval-btn" data-time-interval="1">{% trans
'1d' %}</button>
+ <button type="button" class="btn btn-secondary time-interval-btn" data-time-interval="2">{% trans '2d'
%}</button>
+ <button type="button" class="btn btn-secondary time-interval-btn" data-time-interval="3">{% trans '3d'
%}</button>
+ <button type="button" class="btn btn-secondary time-interval-btn" data-time-interval="7">{% trans '7d'
%}</button>
+ <button type="button" class="btn btn-secondary time-interval-btn" data-time-interval="14">{% trans
'14d' %}</button>
+ <button type="button" class="btn btn-secondary time-interval-btn" data-time-interval="-1">{% trans
'All' %}</button>
+ </div>
+ <input type="hidden" id="time-interval" value="1" />
+ </div>
+ <div class="col form-group">
+ <label for="groupSelect">{% trans 'Filter by group' %}</label>
+ <select name="group" class="form-control" id="groupSelect">
+ <option value="all">{% trans 'All groups' %}
+ {% for group in user.groups_by_coach.all %}
+ <option value={{group.group.id}}>{{group.group.name}}</option>
+ {% endfor %}
+ </select>
+ </div>
+ <div class="col form-group">
+ <label for="playerSelect">{% trans 'Filter by player' %}</label>
+ <select name="player" class="form-control" id="playerSelect">
+ <option value="all">{% trans 'All players' %}
+ {% for player in user.players_by_coach %}
+ <option value={{player.id}}>{{player.name}}</option>
+ {% endfor %}
+ </select>
+ </div>
+ <!--<div class="col form-group">
+ <label for="stationSelect">{% trans 'Filter by station' %}</label>
+ <select name="station" class="form-control" id="stationSelect">
+ <option value="all">{% trans 'All stations' %}
+ {% for station in user.sprint_stations_by_coach %}
+ <option value={{station.id}}>{{station.name}}</option>
+ {% endfor %}
+ </select>
+ </div>
+ <div class="col form-group">
+ <label for="exerciseSelect">{% trans 'Filter by exercise' %}</label>
+ <select name="exercise" class="form-control" id="exerciseSelect">
+ <option value="all">{% trans 'All exercises' %}
+ {% for exercise in user.sprint_exercises_by_coach %}
+ <option value={{exercise.id}}>{{exercise.name}}</option>
+ {% endfor %}
+ </select>
+ </div>-->
+</div>
+<div class="row datatables_wrapped">
+ <div class="col">
+ <table id="sprints" cellspacing="0" cellpadding="0" class="table table-sm" style="width:100%">
+ </table>
+ <div id="hiddenContainer" style="display:none"/>
+ </div>
+</div>
+{% endblock content %}
+
+{% block javascript %}
+{{ block.super }}
+<script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
+<script src="https://cdn.datatables.net/1.10.16/js/dataTables.bootstrap4.min.js"></script>
+<script src="https://cdn.datatables.net/buttons/1.5.1/js/dataTables.buttons.min.js"></script>
+<script src="https://cdn.datatables.net/buttons/1.5.1/js/buttons.bootstrap4.min.js"></script>
+<!--<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
+<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.32/pdfmake.min.js"></script>
+<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.32/vfs_fonts.js"></script>
+<script src="https://cdn.datatables.net/buttons/1.5.1/js/buttons.print.min.js"></script>-->
+<script src="https://cdn.datatables.net/buttons/1.5.1/js/buttons.html5.min.js"></script>
+
+
+<script>
+ var csrftoken = jQuery("[name=csrfmiddlewaretoken]").val();
+ var refreshIntervalId;
+
+ var COLUMN_PLAYER = 4;
+// var COLUMN_STATION = 5;
+// var COLUMN_EXERCISE = 6;
+
+ function formatDateNumber(val) {
+ if (val < 10) {
+ return '0' + val;
+ } else {
+ return val;
+ }
+ }
+
+ $(document).ready(function() {
+ /* Datatable for players in groups */
+ var table_results = $('#sprints').DataTable({
+ lengthChange: false,
+ "ajax": {
+ "processing": true,
+ "url" : "{% url 'api_results:sprints_list' %}",
+ data: function(d){
+ d.group_id = $('#groupSelect').val();
+ d.player_id = $('#playerSelect').val();
+ d.org_id = "{{ user.organization.id }}"
+ d.coach_id = "{{ user.id }}"
+ d.timeInterval = $('#time-interval').val();
+ },
+ "dataSrc": ""
+ },
+ "order": [
+ [0, 'asc']
+ ],
+ "columns": [
+ {
+ type: "num",
+ title: "id",
+ data: "id",
+ visible: false
+ },
+ {
+ type: "date",
+ data: "dt",
+ visible: false
+ },
+ {
+ type: "html",
+ orderable:false,
+ render: function(value, type, row) {
+ return '<input class="deleteCheckbox" type="checkbox" data-result-id="' +
row.id + '"/>';
+ }
+ },
+ {
+ type: "customdate",
+ title: "{% trans 'Date' %}",
+ data: "dt",
+ render: function(value) {
+
+ // Compare with today
+ today = new Date();
+ // To adjust the hour
+ var _offsetHours = today.getTimezoneOffset()/60;
+ var dd = today.getDate();
+ var mm = today.getMonth();
+ var yy = today.getFullYear();
+
+ var dt = new Date(value);
+ dt.setHours(dt.getHours() + _offsetHours);
+ var dd2 = dt.getDate();
+ var mm2 = dt.getMonth();
+ var yy2 = dt.getFullYear();
+ var hh = dt.getHours();
+ var MM = dt.getMinutes();
+ if (dd == dd2 && mm == mm2 && yy == yy2) {
+ // Today, show the result hours and minute
+ return formatDateNumber(hh) + ':' + formatDateNumber(MM);
+ } else if (yy == yy2) {
+ // Same year
+ return formatDateNumber(dd2) + "/" +formatDateNumber(mm2 + 1) + " " +
formatDateNumber(hh) + ":" + formatDateNumber(MM);
+ } else {
+ return formatDateNumber(dd2) + "/" + formatDateNumber(mm2 + 1) + "/"
+ yy2 + " " + formatDateNumber(hh) + ":" + formatDateNumber(MM);
+ }
+
+ }
+ },
+ {
+ type: "html",
+ data: "person",
+ title: "{% trans 'Player' %}"
+ },
+ {
+ type: "html",
+ data: "distances",
+ title: "{% trans 'Distancia' %}"
+ },
+ {
+ type: "num",
+ data: "t1",
+ title: "t1",
+ className: 'colResult',
+ render: $.fn.dataTable.render.number('', ',', 2)
+ },
+ {
+ type: "num",
+ data: "t2",
+ title: "t2",
+ className: 'colResult',
+ render: $.fn.dataTable.render.number('', ',', 2)
+ },
+ {
+ type: "num",
+ data: "t3",
+ title: "t3",
+ className: 'colResult',
+ render: $.fn.dataTable.render.number('', ',', 2)
+ },
+ {
+ type: "num",
+ data: "t4",
+ title: "t4",
+ className: 'colResult',
+ render: $.fn.dataTable.render.number('', ',', 2)
+ },
+ {
+ type: "num",
+ data: "k",
+ title: "k",
+ className: 'colResult',
+ render: $.fn.dataTable.render.number('', ',', 2)
+ },
+ {
+ type: "num",
+ data: "vmax",
+ title: "VMax",
+ className: 'colResult',
+ render: $.fn.dataTable.render.number('', ',', 2)
+ },
+ {
+ type: "num",
+ data: "amax",
+ title: "AMax",
+ className: 'colResult',
+ render: $.fn.dataTable.render.number('', ',', 2)
+ },
+ {
+ type: "num",
+ data: "fmax",
+ title: "FMax",
+ className: 'colResult',
+ render: $.fn.dataTable.render.number('', ',', 2)
+ },
+ {
+ type: "num",
+ data: "pmax",
+ title: "PMax",
+ className: 'colResult',
+ render: $.fn.dataTable.render.number('', ',', 2)
+ }
+ ],
+ "dom": "<'row'<'col-sm-6'B><'col-sm-6'f>>rtip",
+ buttons: [
+ { text: "{% trans 'Export results' %}", className: "btn btn-primary",
+ action: function( e, dt, node, config ) {
+ var columns = ["{% trans 'Date' %}", "{% trans 'Player' %}", "{% trans 'Distancia'
%}", "t1", "t2", "t3", "t4", "k", "VMax", "AMax", "FMax", "FMax"];
+
+ var csv = columns.join(";") + "\n";
+ var today = new Date();
+ var dd = today.getDate();
+ var mm = today.getMonth()+1;
+ var yyyy = today.getFullYear();
+ var hh = today.getHours();
+ var MM = today.getMinutes();
+
+ var filename = "curses_" + yyyy + formatDateNumber(mm) + formatDateNumber(dd) +
formatDateNumber(hh) + formatDateNumber(MM) + ".csv";
+ var rows = $("#sprints").dataTable().$('tr', {"filter":"applied"});
+ rows.each(function( index ) {
+ //console.log( index + ": " + table.row( this ).data() );
+ var data = table_results.row(this).data();
+ var date = new Date(data.dt);
+ var _offsetHours = date.getTimezoneOffset()/60;
+ // Show the date in dd/mm/yyyy
+ var dateStr = formatDateNumber(date.getDate()) + "/" +
formatDateNumber(date.getMonth() + 1 ) + "/" +
+ date.getYear().toString().substr(-2);
+ csv += dateStr + ";"
+ + data.person + ";"
+ + data.personName + ";"
+ + data.distancia +";"
+ + data.t1.toString().replace(".", ",") + ";"
+ + data.t2.toString().replace(".", ",") + ";"
+ + data.t3.toString().replace(".", ",") + ";"
+ + data.t4.toString().replace(".", ",") + ";"
+ + data.k.toString().replace(".", ",") + ";"
+ + data.vmax.toString().replace(".", ",") + ";"
+ + data.amax.toString().replace(".", ",") + ";"
+ + data.fmax.toString().replace(".", ",") + ";"
+ + data.pmax.toString().replace(".", ",") + "\n";
+ });
+ var csvData = 'data:text/csv;charset=utf-8,' + "\uFEFF" + encodeURI(csv);
+ // For IE (tested 10+)
+ //console.log(filename);
+ //console.log(csv);
+ if (window.navigator.msSaveOrOpenBlob) {
+ var blob = new Blob([decodeURIComponent(encodeURI(csv))], {
+ type: "text/csv;charset=utf-8;"
+ });
+ navigator.msSaveBlob(blob, filename);
+ alert();
+ } else {
+ var link=document.createElement('a');
+ /*$(link)
+ .attr({
+ 'download': filename
+ ,'href': csvData
+ //,'target' : '_blank' //if you want it to open in a new window
+ });*/
+ link.href= csvData;
+ link.download=filename;
+ document.getElementById('hiddenContainer').appendChild(link);
+ link.click();
+ }
+ return csv;
+ }},
+ { text: "{% trans 'Delete race' %}",
+ className: "btn btn-danger btnDeleteResults",
+ enabled: false,
+ action: function(e, dt, node, config) {
+ // Ask for confirmation
+ var total = $('.deleteCheckbox:checked').length;
+ if (total == 1) {
+
+ var r = confirm("{% trans 'Are you sure to delete this race?' %}");
+ } else {
+ var r = confirm("{% trans 'Are you sure to delete these races?' %}");
+ }
+ if (r == true) {
+ var results = [];
+ $.each($('.deleteCheckbox:checked'), function(index, value) {
+ var v = $(value);
+ console.log(index + ":" + v.attr('data-result-id'));
+ results.push(v.attr('data-result-id'));
+
+ });
+ var url = "{% url 'api_results:sprints_delete' %}";
+ $.ajax({
+ url: url,
+ type: "DELETE",
+ contentType: 'application/json;charset=UTF-8',
+ data: JSON.stringify(results)
+ }).done(function(msg){
+ // Results have been deleted. Refresh table and enable again the interval
+ //console.log(msg);
+ $('.btnDeleteResults').addClass('disabled');
+ table_results.ajax.reload(enableDeletion, false);
+ refreshIntervalId = refreshIntervalTrigger();
+ console.log("Interval refresh is enabled with id " + refreshIntervalId);
+ })
+ }
+ }}
+ ],
+ initComplete: function() {
+ this.api().columns().every(function() {
+
+ var column = this;
+ var idx = column.index();
+ if (idx == COLUMN_PLAYER) {
+ var select = $('<select class="form-control"><option value="">{% trans "All players"
%}</option></select>')
+ .appendTo($('#playerSelect'))
+ .on('change', function() {
+ // Player selected
+ console.log("canvi player select");
+ var val = $.fn.dataTable.util.escapeRegex(
+ $(this).val()
+ );
+
+ column
+ .search(val ? '^' + val + '$' : '', true, false)
+ .draw();
+ // Hide column if is a selected Player
+ //console.log(val);
+ column.visible(val == '');
+
+ });
+
+ column.data().unique().sort().each(function(d, j) {
+ select.append('<option value="' + d + '">' + d + '</option>')
+ });
+ }
+ });
+ console.log("Enable delection for first time");
+ enableDeletion();
+ },
+ "language": {
+ "lengthMenu": "{% trans 'Showing _MENU_ results per page' %}",
+ "zeroRecords": "{% trans 'There are no results to show' %}",
+ "info": "{% trans 'Showing the results _START_ to _END_ of a total of _TOTAL_ results' %}",
+ "infoEmpty": "{% trans 'The query returns no results' %}",
+ "infoFiltered": "{% trans '_MAX_ results filtered' %}",
+ "decimal": ",",
+ "thousands": ".",
+ "paginate": {
+ "first": '<i class="fa fa-fast-backward"></i>',
+ "last": '<i class="fa fa-fast-forward"></i>',
+ "next": '<i class="fa fa-forward"></i>',
+ "previous": '<i class="fa fa-backward"></i>'
+ },
+ "search": "{% trans 'Search:' %}"
+ }
+ });
+
+ /* Enable the result deletion */
+ function enableDeletion() {
+ // Called every time a delete checkbox is changed
+ //alert();
+ console.log("enableDeletion called");
+ $('.deleteCheckbox').on('change', function() {
+ var totalChecked = $('.deleteCheckbox:checked').length;
+ console.log(totalChecked);
+ if (totalChecked > 0) {
+ // Disable the refresh interval
+ if (refreshIntervalId != -1) {
+ console.log("Clear interval Id " + refreshIntervalId);
+ clearInterval(refreshIntervalId);
+ console.log("Interval refresh is disabled");
+ refreshIntervalId = -1;
+ $('.btnDeleteResults').removeClass('disabled');
+ }
+ console.log("refreshIntervalId = " + refreshIntervalId);
+ } else {
+ // Enable again the refresh interval
+ $('.btnDeleteResults').addClass('disabled');
+ refreshIntervalId = refreshIntervalTrigger();
+ console.log("Interval refresh is enabled with id " + refreshIntervalId);
+ }
+ });
+ }
+
+ $('#results').on( 'draw.dt', function () {
+ console.log( 'Table redrawn' );
+ deselectAllCheckboxes();
+ } );
+
+ function deselectAllCheckboxes() {
+ //$('.deleteCheckbox').attr("checked", false);
+ $('.deleteCheckbox').prop("checked", false);
+ $('.btnDeleteResults').addClass('disabled');
+ if (refreshIntervalId == -1) {
+ refreshIntervalId = refreshIntervalTrigger();
+ console.log("Interval refresh is enabled with id " + refreshIntervalId);
+ }
+ }
+
+ function refreshIntervalTrigger() {
+ return setInterval(function() {
+ /* Set the interval for refresh */
+ table_results.ajax.reload(enableDeletion, false);
+ }, 15000);
+ };
+
+ refreshIntervalId = refreshIntervalTrigger();
+ console.log("Interval refresh is enabled with id " + refreshIntervalId);
+
+ /* Reload results for the group selected */
+ $('#groupSelect').on('change', function() {
+ table_results.ajax.reload(enableDeletion, true);
+ console.log("Reload by group change");
+ });
+
+ /* Reload results for the player selected */
+ $('#playerSelect').on('change', function() {
+ table_results.ajax.reload(enableDeletion, true);
+ console.log("Reload by player change");
+ });
+
+
+ $('.time-interval-btn').on('click', function() {
+ $('.time-interval-btn').removeClass('active btn-primary').addClass('btn-secondary');
+ $(this).removeClass('btn-secondary').addClass('btn-primary active');
+ $('#time-interval').val(parseInt($(this).attr('data-time-interval')));
+ console.log("Change data interval to " + $('#time-interval').val());
+ table_results.ajax.reload(enableDeletion, true);
+ })
+
+ }); // End of document ready
+
+</script>
+{% endblock %}
diff --git a/chronojumpserver-django/rfid-csharp/RFID.cs b/chronojumpserver-django/rfid-csharp/RFID.cs
index 2560bf7..a1838b5 100755
--- a/chronojumpserver-django/rfid-csharp/RFID.cs
+++ b/chronojumpserver-django/rfid-csharp/RFID.cs
@@ -29,17 +29,17 @@ public class RFIDMain
public static void Main()
{
//debug starts
- /*string str = "Called RFIDMain. Writing at /tmp/rfidcalled.txt";
+ string str = "Called RFIDMain. Writing at /tmp/rfidcalled.txt";
Console.WriteLine(str);
- TextWriter writer = File.CreateText("/tmp/rfidcalled.txt");
+ /*TextWriter writer = File.CreateText("/tmp/rfidcalled.txt");
writer.Write(str);
writer.Flush();
writer.Close();
((IDisposable)writer).Dispose();*/
//debug ends
- //removeFile();
+ removeFile();
RFID rfid = new RFID();
RFID.StatusEnum status = rfid.Start();
@@ -52,11 +52,11 @@ public class RFIDMain
Console.WriteLine(status.ToString());
}
- /*private static void removeFile()
+ private static void removeFile()
{
if(File.Exists(rfidFile))
File.Delete(rfidFile);
- }*/
+ }
private static void write(string str)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]