[chronojump-server] Tasks can now be added from player list



commit 08d87268116a5a21a05ae32e19b83a9fcc2e797c
Author: Marcos Venteo <mventeo gmail com>
Date:   Sun May 28 13:05:10 2017 +0200

    Tasks can now be added from player list

 chronojump-flask/chronojump_server.py       |  128 ++++++++++------
 chronojump-flask/templates/player_list.html |  214 +++++++++++++++++++++------
 chronojump-flask/templates/results.html     |   12 ++-
 3 files changed, 255 insertions(+), 99 deletions(-)
---
diff --git a/chronojump-flask/chronojump_server.py b/chronojump-flask/chronojump_server.py
index ed15887..1415f09 100644
--- a/chronojump-flask/chronojump_server.py
+++ b/chronojump-flask/chronojump_server.py
@@ -2,6 +2,7 @@ from flask import Flask, render_template, request, jsonify, url_for
 from flask_restful import Resource, Api
 from flaskext.mysql import MySQL
 import subprocess
+from datetime import datetime
 import os
 from werkzeug import secure_filename
 import ConfigParser
@@ -37,51 +38,8 @@ def main():
 # http://192.168.200.1:5000/results
 @app.route("/results")
 def Results():
-    date = request.args.get('date')  # days
-    personId = request.args.get('pId')
-    stationId = request.args.get('sId')
-    cursor = mysql.connect().cursor()
-
-    if date is None or date == "" or date == "Any":
-        dateStr = ""
-    else:
-        dateStr = " AND FLOOR(TO_DAYS(NOW()) - TO_DAYS(dt)) <= " + date
-
-    if stationId is None or stationId == "" or stationId == "All":
-        stationStr = ""
-    else:
-        stationStr = " AND stationId = " + stationId
-
-    if personId is None or personId == "" or personId == "All":
-        personStr = ""
-    else:
-        personStr = " AND person.id = " + personId
-
-    bySpeed = True
-    repetitonString = ""
-    if bySpeed:
-        repString = "lossBySpeed, numBySpeed, rangeBySpeed, vmeanBySpeed, vmaxBySpeed, pmeanBySpeed, 
pmaxBySpeed"
-    else:
-        repString = "lossByPower, numBySpeed, rangeByPower, vmeanByPower, vmaxByPower, pmeanByPower, 
pmaxByPower"
-
-    cursor.execute("SELECT results.dt, person.name, station.name, " +
-                   " results.exerciseName, results.resistance, results.repetitions, " + repString + ", 
comments" +
-                   " FROM results, person, station " +
-                   " WHERE results.personId = person.id " +
-                   " AND results.stationId = station.id " +
-                   personStr + dateStr + stationStr +
-                   " ORDER by results.id DESC")
-    results = cursor.fetchall()
-
-    cursor.execute("SELECT results.personId, person.name FROM results, " +
-                   "person WHERE results.personId = person.id GROUP BY person.id")
-    persons = cursor.fetchall()
-
-    cursor.execute("SELECT * FROM station")
-    stations = cursor.fetchall()
-
-    return render_template('results.html', header=getHeader("Resultats"), date=date, pId=personId, 
sId=stationId, bySpeed=bySpeed, results=results, persons=persons, stations=stations)
-
+    """Show results list."""
+    return render_template('results.html')
 
 @app.route('/player_list', methods=['POST', 'GET'])
 def list():
@@ -206,21 +164,52 @@ def uploader():
 
 
 def get_all_results():
-    """Query to get all the results to serve via ajax."""
+    """Get all the results to serve via ajax."""
     sql = "select results.id, results.dt, person.name, station.name, " \
           " results.exerciseName, results.resistance, results.repetitions, " \
           "lossBySpeed, numBySpeed, rangeBySpeed, vmeanBySpeed, " \
           "vmaxBySpeed, pmeanBySpeed, pmaxBySpeed, comments " \
           "FROM results, person, station where person.id = results.personId and " \
           "station.id = results.stationId order by results.id desc"
-    print sql
     db = mysql.connect()
     cursor = db.cursor()
     cursor.execute(sql)
-    results = cursor.fetchall()
+    rows = cursor.fetchall()
+
+    return rows
 
-    return results
+def get_all_players():
+    """Get all the players, with the tasks associated with them."""
+    sql = "select person.id as person_id, person.imageName, person.name, person.weight,"
+    sql += "person.height,person.RFID, task.id as task_id, task.comment "
+    sql += "from person left join task on task.personId=person.id and task.dt >= curdate()"
+    cursor = mysql.connect().cursor()
 
+    cursor.execute(sql)
+    rows = cursor.fetchall()
+    # We need to group tasks by player
+    player_tasks = {}
+    for row in rows:
+        player_id = row[0]
+        if player_id not in player_tasks.keys():
+            # Add the player
+            player_tasks[player_id] = { 'id': player_id,
+                                        'imageName': row[1],
+                                        'name': row[2],
+                                        'weight': row[3],
+                                        'height': row[4],
+                                        'rfid': row[5],
+                                        'tasks': []
+                                      }
+            # Avoid null tasks
+            if row[7]:
+
+                player_tasks[player_id]['tasks'].append(row[7])
+        else:
+            # Add the task only
+            player_tasks[player_id]['tasks'].append(row[7])
+    _rows =  [ val for key,val in player_tasks.iteritems()]
+    return _rows
 
 class ResultsAPI(Resource):
     """Results resource."""
@@ -229,9 +218,48 @@ class ResultsAPI(Resource):
         results = get_all_results()
         return jsonify(data=results)
 
+class PlayerList(Resource):
+    """Player resource"""
+
+    def get(self):
+        players = get_all_players()
+        return jsonify(data=players)
+
+class Player(Resource):
+
+    def get(self, player_id):
+        pass
+
+
+class TaskList(Resource):
+
+    def get(self):
+        pass
+    def put(self):
+        """ Add a new task to player."""
+        print "Adding new tasks to players"
+        player_id = request.form['player_id']
+        new_task = request.form['new_task']
+        dt = datetime.now()
+        sql = "insert into task values(NULL,"
+        sql += "'" + dt.strftime('%y-%m-%d %H:%M:%S') + "',"
+        sql += str(player_id) + ","
+        sql += "'" + new_task + "')"
 
-api.add_resource(ResultsAPI, '/api/v1/results')
 
+        db = mysql.connect()
+        cursor = db.cursor()
+        cursor.execute(sql)
+        db.commit()
+
+        print sql
+        return jsonify(msg="Task has been done succesfully.")
+
+
+api.add_resource(ResultsAPI, '/api/v1/results')
+api.add_resource(PlayerList, '/api/v1/players')
+api.add_resource(Player, '/api/v1/player/<player_id>')
+api.add_resource(TaskList, '/api/v1/tasks')
 
 if __name__ == "__main__":
     app.run(host="0.0.0.0", debug=True)
diff --git a/chronojump-flask/templates/player_list.html b/chronojump-flask/templates/player_list.html
index 16fa4d5..969f2e4 100644
--- a/chronojump-flask/templates/player_list.html
+++ b/chronojump-flask/templates/player_list.html
@@ -1,53 +1,171 @@
 {% extends 'base.html' %}
+{% block extra_stylesheet %}
+<link href="{{ url_for('static', filename='DataTables/media/css/dataTables.bootstrap.min.css') }}" 
rel="stylesheet" /> {% endblock %}
+{% block extra_js %}
+<script src="{{ url_for('static', filename='DataTables/media/js/jquery.dataTables.min.js') }}"></script>
+<script src="{{ url_for('static', filename='DataTables/media/js/dataTables.bootstrap.min.js') }}"></script>
+<script type="text/javascript">
+
+function addTaskToPlayer(){
+       // Add the task to the player through a ajax call
+       var player_id = $('#player-id').val();
+       var new_task = $('#task-comment').val();
+       console.log('add a new task ' + new_task + ' for player ' + player_id );
+       $('#myModal').modal('hide');
+       $.ajax({
+               url: '/api/v1/tasks',
+               method: 'PUT',
+               data: {
+                       player_id : player_id,
+                       new_task: new_task
+               }
+       }).done(function() {
+               var table = $('#players').DataTable();
+               table.ajax.reload(null, false);
+       });
+       // Reload the table to reflect the changes
+
+}
+
+
+
+       $(document).ready(function() {
+               var table = $('#players').DataTable({
+                       "columns": [{
+                                       type: "num",
+                                       title: "id",
+                                       data: 'id',
+                                       visible: false
+                               },
+                               {
+                                       type: "html",
+                                       title: "foto",
+                                       data: 'imageName',
+                                       orderable: false,
+                                       render: function(value){
+                                               var href='/static/images/'+ value;
+                                               var src = '/static/images/'+ value;
+                                               var html='<a href="'+href+'"><img src="'+src+'" 
class="img-circle" height="60"></a>';
+                                               return html;
+                                       }
+                               },
+                               {
+                                       type: "html",
+                                       data: "name",
+                                       title: "Nom"
+                               },
+                               {
+                                       type: "num",
+                                       data: 'weight',
+                                       title: "Pes",
+                                       render: $.fn.dataTable.render.number('', ',', 2)
+                               },
+                               {
+                                       type: "num",
+                                       data: "height",
+                                       title: "Alçada",
+                                       render: $.fn.dataTable.render.number('', ',', 2)
+                               },
+                               {
+                                       type: "html",
+                                       data: "rfid",
+                                       title: "RFID"
+                               },
+                               {
+                                       type: "html",
+                                       title: "Tasques",
+                                       data: "tasks",
+                                       orderable: false,
+                                       render: function(value) {
+                                               if (value.length > 0) {
+                                                       var html = "<ol>";
+                                                       $.each( value, function( index, value ) {
+                                                         html += "<li>"+ value + "</li>";
+                                                       });
+                                                       html += "</ol>";
+                                                       return html;
+                                               } else {
+                                                       return '<ol></ol>';
+                                               }
+                                       }
+                               },
+                               { type: "html",
+                                 data: null,
+                                 title: "",
+                                 orderable: false,
+                                 render: function(val) {
+                                               return "<button class='btn btn-primary'>Afegeix</button>"
+                                       }}
+                       ],
+                       "pageLength": 10,
+                       "order": [ 
+                               [0, 'desc']
+                       ],
+                       "ajax": "/api/v1/players",
+                       "processing": true,
+                       "severSide": true,
+                       "language": {
+                               "lengthMenu": "Mostrant _MENU_ jugadors per pàgina",
+                               "zeroRecords": "No hi han jugadors per mostrar",
+                               "info": "Mostrant els jugadors _START_ a _END_ d'un total de _TOTAL_",
+                               "infoEmpty": "La busqueda no ha retornat resultats",
+                               "infoFiltered": "(filtrat de _MAX_ jugadors)",
+                               "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": "Cerca:"
+                       }
+               });
+
+               $('#players').on( 'click', 'button', function () {
+                               var player = table.row( $(this).parents('tr') ).data();
+
+                               $('#task-comment').val('');
+                               $('#modal-title').text('Afegir nova tasca per ' + player.name);
+                               $('#myModal').modal();
+                               $('#player-id').val(player.id);
+                               $('#task-comment').focus();
+           } );
+
+
+
+});
+</script>
+{% endblock %}
 
 {% block main_content %}
-               <!--            <form action=player_list method = "POST"> -->
-               <table class="table tabñe-hovered">
-                       <thead>
-                               <th>id</th>
-                               <th>Nom</th>
-                               <th>Pes</th>
-                               <th>Alçada</th>
-                               <th>RFID</th>
-                               <th>Foto</th>
-                               <th>Tasca Id</th>
-                               <th>Tasca</th>
-                       </thead>
-
-                       {% for row in rows %}
-                       <tr>
-                               <td>{{row[0]}}</td>
-                               <td>{{row[1]}}</td>
-                               <td>{{row[2]}}</td>
-                               <td>{{row[3]}}</td>
-                               <td>{{row[4]}}</td>
-
-                               {% if (row[5] and row[5] != None and row[5] != "") %}</td>
-                                       <td>
-                                               <a href="{{ url_for('static', filename='images/' + row[5]) 
}}">
-                                                       <img src="{{ url_for('static', filename='images/' + 
row[5]) }}" class="img-circle" height="60">
-                                               </a>
-                                       </td>
-                               {% else %}
-                                       <td>
-                                               <form action = "{{ url_for('uploader') }}" method = "POST" 
enctype = "multipart/form-data">
-                                                       <input type = "hidden" name = "personId" 
value="{{row[0]}}"/>
-                                                       <input type = "hidden" name = "returnToPage" 
value="playerList"/>
-                                                       <br><input type="file" name="file">
-                                                       <br><input type = "submit" value = "Afegeix" /><br>
-                                               </form>
-                                       </td>
-                               {% endif %}
-
-                               {% if (row[6] and row[6] != None and row[6] != "") %}</td>
-                                       <td>{{row[6]}}</td>
-                                       <td>{{row[7]}}</td>
-                               {% else %}
-                                       <td>&nbsp;</td>
-                                       <td><input type = "text" name = "addTask-{{row[0]}}" value="TODO: 
hability to add task with ENTER" size="40"/></td>
-                               {% endif %}
-                       </tr>
-                       {% endfor %}
-               </table>
 
+<h2>Jugadors</h2>
+               <div class="row" style="margin-top:20px">
+                       <table id="players" class="table table-hovered" cellspacing="0" width="100%">
+                       </table>
+               </div>
+               <div id="myModal" class="modal fade" tabindex="-1" role="dialog">
+                 <div class="modal-dialog" role="document">
+                   <div class="modal-content">
+                     <div class="modal-header">
+                       <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span 
aria-hidden="true">&times;</span></button>
+                       <h4 id="modal-title" class="modal-title">Afegir nova tasca per el jugador</h4>
+                     </div>
+                     <div class="modal-body">
+                                               <form>
+                                                       <input type="hidden" id="player-id">
+                         <div class="form-group">
+                           <label for="recipient-name" class="control-label">Descripció de la tasca:</label>
+                           <textarea rows=2 class="form-control" id="task-comment"></textarea>
+                         </div>
+                       </form>
+                     </div>
+                     <div class="modal-footer">
+                       <button type="button" class="btn btn-dager" data-dismiss="modal">Cancelar</button>
+                       <button type="button" class="btn btn-primary" onclick="addTaskToPlayer()">Afegeix la 
tasca</button>
+                     </div>
+                   </div><!-- /.modal-content -->
+                 </div><!-- /.modal-dialog -->
+               </div><!-- /.modal -->
 {% endblock %}
diff --git a/chronojump-flask/templates/results.html b/chronojump-flask/templates/results.html
index 80a7433..875b0c5 100644
--- a/chronojump-flask/templates/results.html
+++ b/chronojump-flask/templates/results.html
@@ -1,8 +1,18 @@
 {% extends "base.html" %} {% block extra_stylesheet %}
-<link href="{{ url_for('static', filename='DataTables/media/css/dataTables.bootstrap.min.css') }}" 
rel="stylesheet" /> {% endblock %} {% block extra_js %}
+<link href="{{ url_for('static', filename='DataTables/media/css/dataTables.bootstrap.min.css') }}" 
rel="stylesheet" /> {% endblock %}
+{% block extra_js %}
 <script src="{{ url_for('static', filename='DataTables/media/js/jquery.dataTables.min.js') }}"></script>
 <script src="{{ url_for('static', filename='DataTables/media/js/dataTables.bootstrap.min.js') }}"></script>
 <script type="text/javascript">
+
+jQuery.fn.dataTableExt.oSort["customdate-desc"] = function (x, y) {
+       console.log('asc order');
+};
+
+jQuery.fn.dataTableExt.oSort["customdate-asc"] = function (x, y) {
+       console.log('desc order');
+}
+
        $(document).ready(function() {
                // Initialize datatable with results
                var table = $('#results').DataTable({


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]