[chronojump-server] Enabling again the RFID Read from arduino device. In Production Mode the read is made by RFID.cs pro



commit c38759987b70e14f86d98288e5c57502ebb87c03
Author: Marcos Venteo García <mventeo gmail com>
Date:   Sun Jun 18 11:18:16 2017 +0200

    Enabling again the RFID Read from arduino device. In Production Mode the read is made by RFID.cs program 
as usual.
    The registration of the RFID is made during the add or update process via an AJAX call. The AJAX call 
will check if the RFID is read and it is unique, returning an error otherwise.
    
    More changes:
    Added more tests to person model, to assure the integrity of the model.

 chronojumpserver/__init__.py                  |    3 ++
 chronojumpserver/api.py                       |   46 +++++++++++++++++++++++++
 chronojumpserver/js/player_detail.js          |   42 ++++++++++++++++++++++
 chronojumpserver/js/players.js                |    2 +-
 chronojumpserver/models.py                    |   19 +++++++---
 chronojumpserver/static/style.css             |    4 ++
 chronojumpserver/templates/_formhelpers.html  |    2 +-
 chronojumpserver/templates/layout.html        |    1 +
 chronojumpserver/templates/player_detail.html |   18 ++++++++--
 chronojumpserver/tests/test_tasks.py          |   20 +++++++++++
 chronojumpserver/views.py                     |   35 ++++++++++++------
 11 files changed, 170 insertions(+), 22 deletions(-)
---
diff --git a/chronojumpserver/__init__.py b/chronojumpserver/__init__.py
index 5ae3ba6..a7fb7c0 100755
--- a/chronojumpserver/__init__.py
+++ b/chronojumpserver/__init__.py
@@ -21,8 +21,11 @@ app.config['MYSQL_DATABASE_DB'] = config.get("db", "name")
 app.config['MYSQL_DATABASE_HOST'] = config.get("db", "server")
 app.config['CLUB_NAME'] = config.get("club", "name")
 app.secret_key = config.get("security", "secret_key")
+app.config['SECRET_KEY'] = app.secret_key
 app.config['UPLOAD_FOLDER'] = "static/images/photos"
 
+#Initialize SocketIO
+
 
 @app.route('/js/<path:filename>')
 def js(filename):
diff --git a/chronojumpserver/api.py b/chronojumpserver/api.py
index 17ad657..18b96d8 100755
--- a/chronojumpserver/api.py
+++ b/chronojumpserver/api.py
@@ -6,6 +6,9 @@
 from chronojumpserver import app
 from chronojumpserver.models import Person, Result, Station
 from flask import jsonify, request
+from time import sleep
+import os
+import subprocess
 
 
 @app.route('/api/v1/results')
@@ -26,6 +29,7 @@ def get_all_players():
         players.append(_player)
     return jsonify(data=players)
 
+
 @app.route('/api/v1/exercises')
 def get_exercises_by_station():
     stationId = request.args.get('station_id')
@@ -34,3 +38,45 @@ def get_exercises_by_station():
     for exercise in station.exercises:
         exercises.append({'id': exercise.id, 'name': exercise.name})
     return jsonify(exercises=exercises)
+
+
+@app.route('/api/v1/rfid/register')
+def register_rfid():
+    """Call an external program to read rfid and return the value read."""
+    status_code = 200
+    msg = ""
+
+    # From original crhonojump-flask source read RFID
+    rfidFile = '/tmp/chronojump_rfid.txt'
+    if os.environ.get('NO_MONO', False):
+        sleep(4)
+    else:
+        if os.access(rfidFile, os.W_OK):
+            os.remove(rfidFile)
+        # Call Mono program to read from RFID Reader
+        rfidReadedStatus = subprocess.call(
+            "mono chronojumpserver/rfid-csharp/RFID.exe", shell=True)
+
+        print rfidReadedStatus
+
+    # Read the RFID read
+    try:
+        with open(rfidFile) as f:
+            rfid = f.read()
+    except:
+        rfid = ""
+
+    if rfid:
+        """Check if the RFID exists."""
+        p = Person.query.filter(Person.rfid == rfid).first()
+        if p:
+            status_code = 404
+            msg = "RFID ERROR: El RFID %s ja està assignat a un altre jugador." % rfid
+    else:
+        status_code = 404
+        msg = "RFID ERROR: No s'ha pogut llegir cap rfid en el temps assignat."
+
+
+    response = jsonify(rfid=rfid, msg=msg)
+    response.status_code = status_code
+    return response
diff --git a/chronojumpserver/js/player_detail.js b/chronojumpserver/js/player_detail.js
new file mode 100644
index 0000000..0c99e77
--- /dev/null
+++ b/chronojumpserver/js/player_detail.js
@@ -0,0 +1,42 @@
+/*!
+ * Player Detail javascript functions for Chronojump Server
+ * Author: Marcos Venteo <mventeo gmail com>
+ * version: 1.0
+ *
+ * Copyright (C) 2017  Xavier de Blas <xaviblas gmail com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+$('#registerRFID').on('click', function () {
+    var $btn = $(this).button('loading')
+    // CAll by AJAX the method to read the RFID
+    $.ajax({
+      url: '/api/v1/rfid/register',
+      method: 'GET'
+    }).done(function(data) {
+        console.log('RFID readed is ' + data.rfid);
+        $("#rfid").val(data.rfid);
+    }).fail(function(xhr, status, error){
+        var err = eval("(" + xhr.responseText + ")");
+        alert(err.msg);
+    }).always(function(){
+        $btn.button('reset');
+    });
+
+
+
+})
diff --git a/chronojumpserver/js/players.js b/chronojumpserver/js/players.js
index 6be7a7f..6afe4b6 100755
--- a/chronojumpserver/js/players.js
+++ b/chronojumpserver/js/players.js
@@ -63,7 +63,7 @@ $(document).ready(function() {
       },
       {
         type: "html",
-        title: "foto",
+        title: "",
         data: 'imageName',
         orderable: false,
         render: function(value) {
diff --git a/chronojumpserver/models.py b/chronojumpserver/models.py
index fdf1cce..9221510 100755
--- a/chronojumpserver/models.py
+++ b/chronojumpserver/models.py
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-from chronojumpserver.database import Base
+from chronojumpserver.database import Base, db_session
 from datetime import datetime
 from sqlalchemy import Column, Integer, String, Float, Date, Enum, ForeignKey, UniqueConstraint
 from sqlalchemy.types import Boolean, Enum
@@ -15,9 +15,9 @@ class Person(Base):
     __tablename__ = 'person'
     id = Column(Integer, primary_key=True)
     name = Column(String(30), unique=True)
-    weight = Column(Float)
-    height = Column(Float)
-    rfid = Column(String(23))
+    weight = Column(Float, nullable=False)
+    height = Column(Float, nullable=False)
+    rfid = Column(String(23), nullable=False, unique=True)
     imageName = Column(String(50))
     results = relationship("Result",
                            order_by="desc(Result.dt)",
@@ -30,7 +30,7 @@ class Person(Base):
                            primaryjoin="and_(Task.personId==Person.id,"
                                        "Task.done==0)")
 
-    def __init__(self, name=None, weight=0.0, height=0.0, rfid=None,
+    def __init__(self, name=None, weight=None, height=None, rfid=None,
                  imageName=None):
         """Initialize Person class."""
         self.name = name
@@ -56,6 +56,15 @@ class Person(Base):
         return '<Person %r>' % (self.name,)
 
 
+    def add(self):
+        db_session.add(self)
+        db_session.commit()
+
+    @classmethod
+    def getByName(cls, name):
+        o = cls.query.filter(cls.name == name).first()
+        return o
+
 class Station(Base):
     """Station model.
 
diff --git a/chronojumpserver/static/style.css b/chronojumpserver/static/style.css
index 1b00f92..8861d3b 100755
--- a/chronojumpserver/static/style.css
+++ b/chronojumpserver/static/style.css
@@ -59,3 +59,7 @@ body.home {
 #results .colResult {
   color: green;
 }
+
+#players td {
+    vertical-align: middle;
+}
diff --git a/chronojumpserver/templates/_formhelpers.html b/chronojumpserver/templates/_formhelpers.html
index 8afd25c..51ecc1b 100755
--- a/chronojumpserver/templates/_formhelpers.html
+++ b/chronojumpserver/templates/_formhelpers.html
@@ -47,5 +47,5 @@
 {% endmacro %}
 
 {% macro render_field_without_label(field, readonly) %}
-<input class="form-control" type="text" value="{{field.data}}" name="{{field.name}}" id="{{field.name}}"/>
+<input class="form-control" type="text" value="{{field.data}}" name="{{field.name}}" id="{{field.name}}" 
readonly/>
 {% endmacro %}
diff --git a/chronojumpserver/templates/layout.html b/chronojumpserver/templates/layout.html
index f60cd08..3905877 100755
--- a/chronojumpserver/templates/layout.html
+++ b/chronojumpserver/templates/layout.html
@@ -55,6 +55,7 @@
     {% block script %}
 
     <script src="{{ url_for('assets', filename='bootstrap/js/bootstrap.min.js')}}" /></script>
+    
     {% endblock %}
 </body>
 </html>
diff --git a/chronojumpserver/templates/player_detail.html b/chronojumpserver/templates/player_detail.html
index 899c004..5e5e398 100755
--- a/chronojumpserver/templates/player_detail.html
+++ b/chronojumpserver/templates/player_detail.html
@@ -18,14 +18,21 @@
       {{ render_field(form.photo)}}
     </div>
     <div class="col-sm-8">
-
-      {{ render_field(form.fullname) }} {{ render_field(form.height) }} {{ render_field(form.weight) }}
+      {{ render_field(form.fullname) }}
+      <div class="row">
+          <div class="col-sm-6">
+            {{ render_field(form.height) }}
+          </div>
+          <div class="col-sm-6">
+             {{ render_field(form.weight) }}
+          </div>
+      </div>
       <div class="form-group">
         <label for="rfid">RFID</label>
         <div class="input-group">
           {{ render_field_without_label(form.rfid, true) }}
           <span class="input-group-btn">
-                  <button class="btn btn-info" type="button">RFID Perduda</button>
+                <button id="registerRFID" class="btn btn-info" type="button" 
data-loading-text="Registrant..." autocomplete="off">Registrar RFID</button>
           </span>
         </div>
       </div>
@@ -35,3 +42,8 @@
 </form>
 
 {% endblock %}
+
+{% block script %}
+{{ super() }}
+<script src="{{ url_for('js', filename='player_detail.js') }}"></script>
+{% endblock %}
diff --git a/chronojumpserver/tests/test_tasks.py b/chronojumpserver/tests/test_tasks.py
index 501be70..e37e339 100755
--- a/chronojumpserver/tests/test_tasks.py
+++ b/chronojumpserver/tests/test_tasks.py
@@ -57,6 +57,26 @@ class TestGetTasks(unittest.TestCase):
         task1 = Task.query.first()
         print task1.serialize
 
+class TestCreateTasks(unittest.TestCase):
+
+    @classmethod
+    def startUpClass(cls):
+        """Create test data."""
+        engine.execute('drop database if exists chronojump')
+        engine.execute('create database chronojump')
+        init_db
+        # Create Test Data
+
+        pass
+
+    @classmethod
+    def tearDownClass(cls):
+        """Nothing for the moment."""
+        pass
+
+
+
+
 if __name__ == "__main__":
     print "Unit testing"
     unittest.main(verbosity=2)
diff --git a/chronojumpserver/views.py b/chronojumpserver/views.py
index 17b78a3..e322c1e 100755
--- a/chronojumpserver/views.py
+++ b/chronojumpserver/views.py
@@ -97,19 +97,30 @@ def player_detail(player_id):
 @app.route('/player/add', methods=['GET', 'POST'])
 def add_player():
     """Show form to add a new player."""
+    has_errors = False
+    msg = None
     form = PersonForm()
+
     if request.method == "POST":
-        """Form is valid, add the new player."""
-        player = Person(
-            name=form.fullname.data,
-            height=form.height.data,
-            weight=form.weight.data,
-            rfid=form.rfid.data
-        )
-        db_session.add(player)
-        db_session.commit()
-        redirect(url_for('show_players'))
+        if form.validate_on_submit():
+            """Form is valid, add the new player."""
+            player = Person(
+                name=form.fullname.data,
+                height=form.height.data,
+                weight=form.weight.data,
+                rfid=form.rfid.data
+            )
+            db_session.add(player)
+            db_session.commit()
+            msg = "Ej jugador %s s'ha creat correctament." % form.fullname.data
+        else:
+            # There are some errors in the form
+            msg = 'Hi han hagut errors, revisa el formulari.'
+            has_errors = True
     else:
-        print "Form is not valid!!!"
+        """To remove None default values in the form."""
+        form.fullname.data = ""
+        form.rfid.data = ""
 
-    return render_template('player_detail.html', form=form)
+    return render_template('player_detail.html', form=form, msg=msg,
+        has_errors=has_errors)


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