[chronojump-server] Now we can add images to the players. The photo of the players is composed with the timestamp to avo
- From: Marcos Venteo Garcia <mventeo src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [chronojump-server] Now we can add images to the players. The photo of the players is composed with the timestamp to avo
- Date: Wed, 14 Jun 2017 20:32:07 +0000 (UTC)
commit c8655a77678ea9380d325f18bc4802b36cd6c1cc
Author: Marcos Venteo <mventeo gmail com>
Date: Wed Jun 14 22:31:11 2017 +0200
Now we can add images to the players. The photo of the players is composed with the timestamp to avoid
cache problems of the browsers.
chronojumpserver/__init__.py | 2 +-
chronojumpserver/forms.py | 4 +-
chronojumpserver/js/players.js | 4 +-
.../static/images/photos/player_1_1497471778.jpg | Bin 0 -> 25133 bytes
chronojumpserver/static/style.css | 51 +++++++++--------
chronojumpserver/templates/_formhelpers.html | 34 ++++++++---
chronojumpserver/templates/layout.html | 28 ++++++---
chronojumpserver/templates/player_detail.html | 2 +-
chronojumpserver/views.py | 62 +++++++++++++++----
9 files changed, 126 insertions(+), 61 deletions(-)
---
diff --git a/chronojumpserver/__init__.py b/chronojumpserver/__init__.py
index 8bb33fd..5ae3ba6 100755
--- a/chronojumpserver/__init__.py
+++ b/chronojumpserver/__init__.py
@@ -21,7 +21,7 @@ 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['UPLOAD_FOLDER'] = "static/images"
+app.config['UPLOAD_FOLDER'] = "static/images/photos"
@app.route('/js/<path:filename>')
diff --git a/chronojumpserver/forms.py b/chronojumpserver/forms.py
index 5e4ae78..9766cf1 100755
--- a/chronojumpserver/forms.py
+++ b/chronojumpserver/forms.py
@@ -7,8 +7,8 @@ from wtforms.validators import DataRequired, Length
class PersonForm(FlaskForm):
- fullname = StringField('Nom Complet', validators=[DataRequired()])
+ fullname = StringField('Nom Complet', validators=[DataRequired('El nom complet és
obligatori!'.decode('utf-8'))])
height=FloatField('Alçada'.decode('utf-8'), validators=[DataRequired()])
weight=FloatField('Pes', [])
- image=FileField('Image', validators=[FileRequired])
+ photo=FileField('Foto del Jugador')
rfid = StringField('RFID', [validators.Length(max=23)])
diff --git a/chronojumpserver/js/players.js b/chronojumpserver/js/players.js
index 78c4d27..6be7a7f 100755
--- a/chronojumpserver/js/players.js
+++ b/chronojumpserver/js/players.js
@@ -67,8 +67,8 @@ $(document).ready(function() {
data: 'imageName',
orderable: false,
render: function(value) {
- var href = '/static/images/' + value;
- var src = '/static/images/' + value;
+ var href = '/static/images/photos/' + value;
+ var src = '/static/images/photos/' + value;
var html = '<a href="' + href + '" class="player-link"><img src="' + src + '" class="img-circle"
height="60"></a>';
return html;
}
diff --git a/chronojumpserver/static/images/photos/player_1_1497471778.jpg
b/chronojumpserver/static/images/photos/player_1_1497471778.jpg
new file mode 100644
index 0000000..b9e74dd
Binary files /dev/null and b/chronojumpserver/static/images/photos/player_1_1497471778.jpg differ
diff --git a/chronojumpserver/static/style.css b/chronojumpserver/static/style.css
index 1c3766a..1b00f92 100755
--- a/chronojumpserver/static/style.css
+++ b/chronojumpserver/static/style.css
@@ -2,51 +2,54 @@
TODO: Some comment here Marcos
*/
+
/* Stylesheet from chronojump home page */
+
body {
- font-family: "Source Sans Pro",HelveticaNeue-Light,"Helvetica Neue Light","Helvetica
Neue",Helvetica,Arial,"Lucida Grande",sans-serif;
- padding-bottom: 70px;
- margin-top: 100px;
+ font-family: "Source Sans Pro", HelveticaNeue-Light, "Helvetica Neue Light", "Helvetica Neue", Helvetica,
Arial, "Lucida Grande", sans-serif;
+ padding-bottom: 70px;
+ margin-top: 100px;
}
body.home {
- margin-top: 0px;
+ margin-top: 0px;
}
-
.navbar-fixed-top {
- background-color: #0f2351;
- height: 80px;
+ background-color: #0f2351;
+ height: 80px;
+}
+
+.navbar-collapse {
+ background-color: #0f2351;
}
.header-index {
- background-color: #0f2351;
- height: 250px;
+ background-color: #0f2351;
+ height: 250px;
}
.header-index h1, .header-index h4 {
- color: #fff;
- font-weight: bold;
+ color: #fff;
+ font-weight: bold;
}
-.navbar-fixed-top ul.nav > li > a{
- padding-top: 30px;
- color: #d5d9db;
- font-weight: 600;
+.navbar-fixed-top ul.nav>li>a {
+ padding-top: 30px;
+ color: #d5d9db;
+ font-weight: 600;
}
-.navbar-fixed-top ul.nav > li > a:hover{
- color: #fff;
- font-weight: 600;
+.navbar-fixed-top ul.nav>li>a:hover {
+ color: #fff;
+ font-weight: 600;
}
-#main {
-
-}
+#main {}
.footer {
- background-color: #2b2b2b;
- color: #ffffff;
+ background-color: #2b2b2b;
+ color: #ffffff;
}
.task-link {
@@ -54,5 +57,5 @@ body.home {
}
#results .colResult {
- color: green;
+ color: green;
}
diff --git a/chronojumpserver/templates/_formhelpers.html b/chronojumpserver/templates/_formhelpers.html
old mode 100644
new mode 100755
index 554b8b5..fb48425
--- a/chronojumpserver/templates/_formhelpers.html
+++ b/chronojumpserver/templates/_formhelpers.html
@@ -9,16 +9,32 @@
<input class="form-control" type="text" value="{{field.data}}" name="{{field.name}}"
id="{{field.name}}"/>
{% elif field.type == "FileField" %}
<div class="text-center">
-
- <img class="img-rounded " src="/static/images/{{field.data}}">
- <a id="btn_{{field.name}}" class="btn btn-default btn-block"
onclick="selectFile_{{field.name}}(event)">Seleccionar foto</a>
- <input class="hidden" type="file" name="{{field.name}}" id="{{field.name}}"/ />
+ {% if field.data %}
+ <img id="img_{{field.name}}" class="img-rounded " src="/static/images/photos/{{field.data}}">
+ {% else %}
+ <img id="img_{{field.name}}" class="img-rounded ">
+ {% endif %}
+ <a id="btn_{{field.name}}" class="btn btn-default btn-block">Seleccionar foto</a>
+ <input class="hidden" type="file" name="{{field.name}}" id="{{field.name}}"
value="{{field.data}}"/>
<script type="text/javascript">
- function selectFile_{{field.name}}(e){
- e.preventDefault();
- document.getElementById('{{field.name}}').click();
- console.log('File selected');
- };
+ $('#btn_{{field.name}}').click(function(e) {
+ e.preventDefault();
+ $('#{{field.name}}').click();
+ });
+ /* Update the image and set the selected file for submit later */
+ $('#{{field.name}}').change(function(e) {
+ var _fileInput = this;
+
+ if (_fileInput.files && _fileInput.files.length > 0) {
+ var reader = new FileReader();
+ var _file = _fileInput.files[0];
+ reader.onload = function (e) {
+ $('#img_{{field.name}}').attr('src', e.target.result);
+ }
+
+ reader.readAsDataURL(_file);
+ };
+ });
</script>
</div>
{% endif %}
diff --git a/chronojumpserver/templates/layout.html b/chronojumpserver/templates/layout.html
index e17ebe2..f77959a 100755
--- a/chronojumpserver/templates/layout.html
+++ b/chronojumpserver/templates/layout.html
@@ -8,6 +8,8 @@
<link rel="stylesheet" type="text/css" href="{{ url_for('assets',
filename='font-awesome/css/font-awesome.min.css')}}" />
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='style.css')}}" />
{% endblock %}
+ <!-- Load jquery here to use in case of embedded javascript -->
+ <script src="{{ url_for('assets', filename='jquery/jquery-3.2.1.min.js')}}" /></script>
</head>
<body class="{% block body_class %}{% endblock %}">
@@ -15,18 +17,26 @@
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container-fluid">
<div class="navbar-header">
+ <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
+ <span class="sr-only">Toggle navigation</span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ </button>
<a class="navbar-brand" href="/">
<img alt="Brand" src="{{ url_for('static', filename='chronojump-logo.png')}}"
height="60px">
</a>
</div>
- <ul class="nav navbar-nav navbar-right">
- <li><a href="/">Inici</a></li>
- <li><a href="/results">Resultats</a></li>
- <li><a href="/player_list">Llistat Jugadors</a></li>
- <li><a href="/player_add">Afegir Jugador</a></li>
- <li><a href="#">RFID Perduda</a></li>
- </li>
- </ul>
+ <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
+ <ul class="nav navbar-nav navbar-right">
+ <li><a href="/">Inici</a></li>
+ <li><a href="/results">Resultats</a></li>
+ <li><a href="/player_list">Llistat Jugadors</a></li>
+ <li><a href="/player_add">Afegir Jugador</a></li>
+ <li><a href="#">RFID Perduda</a></li>
+ </li>
+ </ul>
+ </div>
</div>
</nav>
{% endblock %}
@@ -43,7 +53,7 @@
</nav>
{% endblock %}
{% block script %}
- <script src="{{ url_for('assets', filename='jquery/jquery-3.2.1.min.js')}}" /></script>
+
<script src="{{ url_for('assets', filename='bootstrap/js/bootstrap.min.js')}}" /></script>
{% endblock %}
</body>
diff --git a/chronojumpserver/templates/player_detail.html b/chronojumpserver/templates/player_detail.html
index f8f7100..bcbd582 100755
--- a/chronojumpserver/templates/player_detail.html
+++ b/chronojumpserver/templates/player_detail.html
@@ -9,7 +9,7 @@
{{ form.csrf_token }}
<div class="row">
<div class="col-sm-4">
- {{ render_field(form.image)}}
+ {{ render_field(form.photo)}}
</div>
<div class="col-sm-8">
{{ render_field(form.fullname) }}
diff --git a/chronojumpserver/views.py b/chronojumpserver/views.py
index 3ea1b44..7fcc156 100755
--- a/chronojumpserver/views.py
+++ b/chronojumpserver/views.py
@@ -1,18 +1,19 @@
# -*- coding: utf-8 -*-
-"""Chronojump Server views controller.
-
-"""
+"""Chronojump Server views controller."""
from chronojumpserver import app
from flask import render_template, request, redirect, url_for
+from flask_wtf.file import FileField
from chronojumpserver.models import Person, Station
from chronojumpserver.forms import PersonForm
from chronojumpserver.database import db_session
-from werkzeug import secure_filename
+import os
+from time import time
@app.route('/')
def index():
+ """Chronojump Server Home page."""
return render_template('index.html')
@@ -31,39 +32,74 @@ def show_players():
@app.route('/player/<player_id>', methods=['GET', 'POST'])
def player_detail(player_id):
"""Show players detail."""
+ has_errors = False
+ msg = ""
# Get the player id passed by argument
player = Person.query.filter(Person.id == player_id).first()
form = PersonForm()
+
if request.method == "GET":
form.fullname.data = player.name
form.height.data = player.height
form.weight.data = player.weight
form.rfid.data = player.rfid
- form.image.data = player.imageName
+
elif request.method == "POST":
+ # Save the image in photos folder
if form.validate_on_submit():
- # Update the player
+ """Form Valid. Update the player."""
+ # Check if a photo has been passed too
+ f = form.photo.data
+ # compose filename with id to avoid multiple images
+ if f:
+ # Update the photo too. First we'll erase the previous photo to
+ # assure there is only one photo of the player and to force the
+ # browser to load the photo beacause of the cache
+ if player.imageName:
+ fullpath = os.path.join('chronojumpserver',
+ app.config['UPLOAD_FOLDER'],
+ player.imageName)
+ # Remove if exists
+ if os.path.exists(fullpath):
+ os.unlink(fullpath)
+ # Set the new photo
+ new_photo = 'player_' + player_id + \
+ '_' + str(int(time())) + '.jpg'
+ fullpath = os.path.join('chronojumpserver',
+ app.config['UPLOAD_FOLDER'],
+ new_photo)
+ # save the photo
+ f.save(fullpath)
+ player.imageName = new_photo
+ # Save the player
db_session.query(Person).filter_by(id=player_id).update({
"name": form.fullname.data,
"height": form.height.data,
"weight": form.weight.data,
- "rfid": form.rfid.data
+ "rfid": form.rfid.data,
+ "imageName": player.imageName
})
db_session.commit()
+ # Update done
+
+ msg = "S'han guardat correctament les dades"
else:
- print "Form is not valid!!!"
+ # There are some errors in the form
+ msg = 'Hi han hagut errors, revisa el formulari.'
+ has_errors = True
- return render_template('player_detail.html', form=form)
+ form.photo.data = player.imageName
+ return render_template('player_detail.html', form=form, msg=msg,
+ has_errors=has_errors)
@app.route('/player/add', methods=['GET', 'POST'])
def add_player():
- """Show players detail."""
- # Get the player id passed by argument
+ """Show form to add a new player."""
form = PersonForm()
- if request.method == "POST" and form.validate_on_submit():
- # Update the player
+ if request.method == "POST":
+ """Form is valid, add the new player."""
player = Person(
name=form.fullname.data,
height=form.height.data,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]