diff --git a/participate.py b/participate.py index 8014bdd..347d115 100755 --- a/participate.py +++ b/participate.py @@ -54,7 +54,7 @@ class Tetawebapp_turns(db.Model): id = db.Column(db.Integer, primary_key=True) role_id = db.Column(db.Integer, db.ForeignKey('participer_thsf_roles.id'), nullable=False) user_id = db.Column(db.Integer, db.ForeignKey('participer_thsf_users.id'), nullable=True) - wday = db.Column(db.Enum('J', 'V', 'S', 'D'), nullable=False) + wday = db.Column(db.Enum('Jeudi', 'Vendredi', 'Samedi', 'Dimanche'), nullable=False) start_time = db.Column(db.Time, nullable=False) end_time = db.Column(db.Time, nullable=False) @@ -73,21 +73,24 @@ def get_menu(page): The value MUST be 0.""" menu = [[u'Accueil', {u'/': [u'/']}, 0], [u'Mon compte', {u'/account': [u'/account', u'/account/update']}, 0], - [u'Mes tours de staff', {u'/turn': [u'/turn']}, 0], + [u'Mes tours de staff', {u'/turns': [u'/turns']}, 0], [u'Feuilles de staff', {u'/staff_sheets': [u'/staff_sheet']}, 0], [u'Déconnexion', {u'/logout': [u'/logout']}, 0], ] if session['is_admin']: menu = [[u'Accueil', {u'/': [u'/']}, 0], - [u'Tours de staff', {u'/staff': [u'/staff']}, 0], + [u'Tours de staff', {u'/turns': [u'/turns', u'/turn/', u'/turn/new', u'/turn/add', u'/turn/delete/', u'/turn/update/']}, 0], [u'Feuilles de staff', {u'/staff_sheets': [u'/staff_sheet']}, 0], - [u'Liste des staffers', {u'/users': [u'/users', u'/account/']}, 0], + [u'Liste des staffers', {u'/users': [u'/users', u'/account/', u'/account/delete/']}, 0], [u'Déconnexion', {u'/logout': [u'/logout']}, 0], ] + #~ print '[+] Page: %s' % page for item in menu: for url in item[1]: for route in item[1][url]: + #~ print " [+] Route: %s" %route if route == page: + #~ print " [+] Selected page: %s" % page item[2] = 1 return menu # This should never happen @@ -272,6 +275,44 @@ def delete_user(user_id): print "------------------------------" return False +def save_turn(role_id, day, start, end): + """ Save a new turn """ + turn = Tetawebapp_turns(role_id=role_id.encode('utf-8'), + wday=day.encode('utf-8'), + start_time=start.encode('utf-8'), + end_time=end.encode('utf-8'), + ) + try: + db.session.add(turn) + commit = db.session.commit() + except Exception as e: + db.session.rollback() + print "[+] Error at save_turn:" + print "------------------------------" + print "%s" % e.message + print "------------------------------" + return False + if commit != None: + return False + return True + +def drop_turn(turn_id): + """ Delete staff turn """ + try: + Tetawebapp_turns.query.filter_by(id=int(turn_id)).delete() + db.session.commit() + return True + except ValueError as e: + print e + return False + except Exception as e: + db.session.rollback() + print "[+] Error at drop_turn:" + print "------------------------------" + print "%s" % e.message + print "------------------------------" + return False + def check_user_info(): """ Check user info and send appropriate message if info are not complete""" message = '' @@ -302,6 +343,7 @@ def page_not_found(e): @app.route("/login", methods=['GET', 'POST']) def login(): + """ Login """ try: login = request.form.get('login').encode('utf-8') password = request.form.get('password').encode('utf-8') @@ -327,6 +369,7 @@ def login(): @app.route("/register", methods=['GET', 'POST']) def register(): + """ Allow self registration """ try: login = request.form.get('login').encode('utf-8') password = request.form.get('password').encode('utf-8') @@ -402,6 +445,23 @@ def update_account(): except AttributeError: return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide") +@app.route("/logout", methods=['GET', 'POST']) +@check_session +def logout(): + """ Logout user """ + # Remove session token + session['token'] = None + session['login'] = None + session['is_admin'] = 0 + # Return user to index page + response = app.make_response(render_template('login_or_register.html', message='')) + # Push token to cookie + sync_cookies(response, session) + return response + +######################################################################## +# Admin zone +######################################################################## @app.route("/users", methods=['GET', 'POST']) @check_session def list_users(): @@ -476,21 +536,106 @@ def delete_account(ID): # User is not logged in return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide") -@app.route("/logout", methods=['GET', 'POST']) +@app.route("/turns", methods=['GET', 'POST']) @check_session -def logout(): - """ Logout user """ - # Remove session token - session['token'] = None - session['login'] = None - # Return user to index page - response = app.make_response(render_template('login_or_register.html', message='')) - # Push token to cookie - sync_cookies(response, session) - return response +def list_turn(): + """ List staff turns """ + try: + if session['is_admin']: + page = str(request.url_rule) + menu = get_menu(page) + turns = Tetawebapp_turns.query.join(Tetawebapp_roles, Tetawebapp_turns.role_id==Tetawebapp_roles.id).add_columns(Tetawebapp_roles.role).order_by(Tetawebapp_turns.role_id).all() + message = '' + return render_template('list_turns.html', menu=menu, page=page, turns=turns, message=message) + except AttributeError: + # User is not logged in + return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide") + +@app.route("/turn/new", methods=['GET', 'POST']) +@check_session +def new_turn(): + """ New turn form """ + try: + if session['is_admin']: + page = str(request.url_rule) + menu = get_menu(page) + roles = Tetawebapp_roles.query.order_by(Tetawebapp_roles.id).all() + days = ['Jeudi', 'Vendredi', 'Samedi', 'Dimanche'] + return render_template('new_turn.html', menu=menu, page=page, roles=roles, days=days) + except AttributeError: + # User is not logged in + return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide") + +@app.route("/turn/add", methods=['GET', 'POST']) +@check_session +def add_turn(): + """ Add staff turn """ + try: + if session['is_admin']: + role_id = request.form.get('role_id').encode('utf-8') + day = request.form.get('day').encode('utf-8') + start = request.form.get('start').encode('utf-8') + end = request.form.get('end').encode('utf-8') + page = str(request.url_rule) + menu = get_menu(page) + turns = Tetawebapp_turns.query.join(Tetawebapp_roles, Tetawebapp_turns.role_id==Tetawebapp_roles.id).add_columns(Tetawebapp_roles.role).order_by(Tetawebapp_turns.role_id).all() + message = "Erreur lors de l'enregistrement.".decode('utf-8') + if save_turn(role_id, day, start, end): + turns = Tetawebapp_turns.query.join(Tetawebapp_roles, Tetawebapp_turns.role_id==Tetawebapp_roles.id).add_columns(Tetawebapp_roles.role).order_by(Tetawebapp_turns.role_id).all() + message='' + return render_template('list_turns.html', menu=menu, page=page, turns=turns, message=message) + # Error while saving turn + roles = Tetawebapp_roles.query.order_by(Tetawebapp_roles.id).all() + days = ['Jeudi', 'Vendredi', 'Samedi', 'Dimanche'] + return render_template('new_turn.html', menu=menu, page=page, roles=roles, days=days, message=message) + # User is not admin + return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide") + except AttributeError as e: + # User is not logged in + return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide") + +@app.route("/turn/", methods=['GET', 'POST']) +@check_session +def update_turn_by_id(ID): + +#~ @app.route("/turn/update/", methods=['GET', 'POST']) +#~ @check_session +#~ def update_turn(ID): + #~ """ Update given staff turn """ + #~ try: + #~ if session['is_admin']: + #~ page = str(request.url_rule) + #~ menu = get_menu(page) + #~ turn = Tetawebapp_turns.query.filter_by(id=ID).join(Tetawebapp_roles, Tetawebapp_turns.role_id==Tetawebapp_roles.id).add_columns(Tetawebapp_roles.role).order_by(Tetawebapp_turns.role_id).all() + #~ return render_template('update_turn.html', menu=menu, page=page, turn=turn) + #~ # User is not admin + #~ return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide") + #~ except AttributeError: + #~ # User is not logged in + #~ return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide") +@app.route("/turn/delete/", methods=['GET', 'POST']) +@check_session +def delete_turn(ID): + """ Delete given staff turn """ + try: + if session['is_admin']: + message = 'Erreur lors de la suppression.' + page = str(request.url_rule) + menu = get_menu(page) + turns = Tetawebapp_turns.query.join(Tetawebapp_roles, Tetawebapp_turns.role_id==Tetawebapp_roles.id).add_columns(Tetawebapp_roles.role).order_by(Tetawebapp_turns.role_id).all() + if drop_turn(ID): + message = '' + turns = Tetawebapp_turns.query.join(Tetawebapp_roles, Tetawebapp_turns.role_id==Tetawebapp_roles.id).add_columns(Tetawebapp_roles.role).order_by(Tetawebapp_turns.role_id).all() + return render_template('list_turns.html', menu=menu, turns=turns, message=message) + return render_template('list_turns.html', menu=menu, turns=turns, message=message) + # User is not admin + return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide") + except AttributeError: + # User is not logged in + return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide") diff --git a/participate.sql b/participate.sql index 349268c..2709770 100644 --- a/participate.sql +++ b/participate.sql @@ -54,7 +54,7 @@ CREATE TABLE participer_thsf_roles ( \echo ********************************* \echo * Creating participer_thsf_turns table \echo ********************************* -CREATE TYPE dow AS ENUM ('J', 'V', 'S', 'D'); +CREATE TYPE dow AS ENUM ('Jeudi', 'Vendredi', 'Samedi', 'Dimanche'); CREATE TABLE participer_thsf_turns ( id serial primary key, role_id integer not NULL, diff --git a/static/scripts/participate.js b/static/scripts/participate.js index ab6a665..b4b5fde 100644 --- a/static/scripts/participate.js +++ b/static/scripts/participate.js @@ -37,3 +37,25 @@ function delete_account(id) { document.location='/account/delete/'+id; } } + +function delete_turn(id) { + if (confirm("La suppression d'un tour de staff est définitive.\n\nConfirmer ?")) { + document.location='/turn/delete/'+id; + } +} + +function save_turn() { + var start = document.getElementById('start').value; + var end = document.getElementById('end').value; + var s_start = start.split(':'); + var s_end = end.split(':'); + var regTime = new RegExp('^[0-9]{2}:[0-9]{2}:[0-9]{2}$','i'); + if (! regTime.test(start) || s_start[0] > 23 || s_start[1] > 59 || s_start[2] > 59){ + alert("Heure de début invalide.\n\nVeuillez respecter le format HH:MM:SS"); + return false; + } + if (! regTime.test(end)){ + alert("Heure de fin invalide.\n\nVeuillez respecter le format HH:MM:SS"); + return false; + } +} diff --git a/static/styles/tetawebapp.css b/static/styles/tetawebapp.css index 41a690a..1235994 100644 --- a/static/styles/tetawebapp.css +++ b/static/styles/tetawebapp.css @@ -370,7 +370,7 @@ input.upload { } form { - width: 400px; + width: 450px; text-align: center; line-height: 40px; } @@ -379,8 +379,9 @@ form > label { float: left; } -form > input[type='text'], form > input[type='password'] { +form > input[type='text'], form > input[type='password'], form > select { float: right; + width: 200px; } div.table_header { diff --git a/templates/account.html b/templates/account.html index 90f9935..caf6751 100644 --- a/templates/account.html +++ b/templates/account.html @@ -1,5 +1,5 @@ {% extends "index.html" %} -{% block title %}Articles{% endblock %} +{% block title %}Mon compte{% endblock %} {% block main %}

Informations personnelles

@@ -17,12 +17,13 @@

-
-
-
-
-
-
- +
+
+
+
+
+
+ +
{% endblock %} diff --git a/templates/account_by_id.html b/templates/account_by_id.html index e878ec2..2ebd5fd 100644 --- a/templates/account_by_id.html +++ b/templates/account_by_id.html @@ -1,15 +1,16 @@ {% extends "index.html" %} -{% block title %}Articles{% endblock %} +{% block title %}Modification de compte{% endblock %} {% block main %}

Informations du compte

-
-
-
-
-
-
- +
+
+
+
+
+
+ +
{% endblock %} diff --git a/templates/list_turns.html b/templates/list_turns.html new file mode 100644 index 0000000..1e9160e --- /dev/null +++ b/templates/list_turns.html @@ -0,0 +1,29 @@ +{% extends "index.html" %} +{% block title %}Liste des tours de staff{% endblock %} + {% block main %} +
+

Liste des tours de staff enregistrés

+
+
ID
+
Role
+
Jour
+
Début
+
Fin
+
Action
+
+ {% set row_class = cycler('odd', 'even') %} + {% for turn in turns %} +
+
{{ turn[0].id }}
+
{{ turn[1] }}
+
{{ turn[0].wday }}
+
{{ turn[0].start_time }}
+
{{ turn[0].end_time }}
+
+ + +
+
+ {% endfor %} +
+ {% endblock %} diff --git a/templates/list_users.html b/templates/list_users.html index 741d9fe..376c0ca 100644 --- a/templates/list_users.html +++ b/templates/list_users.html @@ -1,5 +1,5 @@ {% extends "index.html" %} -{% block title %}Articles{% endblock %} +{% block title %}liste des utilisateurs{% endblock %} {% block main %}

Liste des staffers enregistrés

diff --git a/templates/new_turn.html b/templates/new_turn.html new file mode 100644 index 0000000..da879f2 --- /dev/null +++ b/templates/new_turn.html @@ -0,0 +1,22 @@ +{% extends "index.html" %} +{% block title %}Nouveau tour de staff{% endblock %} + {% block main %} +
+

Nouveau tour de staff

+
+
+
+
+
+ +
+
+ {% endblock %} diff --git a/templates/register.html b/templates/register.html index 9afd32f..a6b6c13 100644 --- a/templates/register.html +++ b/templates/register.html @@ -1,5 +1,5 @@ {% extends "index.html" %} -{% block title %}Register{% endblock %} +{% block title %}Inscription{% endblock %} {% block nav %}{% endblock %} {% block main %}