"Firt release"
This commit is contained in:
+504
-55
@@ -7,8 +7,18 @@ import inspect
|
||||
import random
|
||||
import binascii
|
||||
import bcrypt
|
||||
from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash
|
||||
import datetime
|
||||
import ast
|
||||
from reportlab.lib import colors
|
||||
from reportlab.lib.enums import TA_LEFT, TA_CENTER
|
||||
from reportlab.lib.pagesizes import A4, cm, portrait
|
||||
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, PageBreak, Indenter
|
||||
from reportlab.lib.colors import black, white, orange, bisque, lightsalmon
|
||||
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
|
||||
from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash, send_file
|
||||
from functools import wraps
|
||||
import cStringIO
|
||||
from flask_mail import Mail, Message
|
||||
|
||||
# Optionnal modules
|
||||
import psycopg2
|
||||
@@ -18,6 +28,9 @@ from flask_sqlalchemy import SQLAlchemy
|
||||
# App settings
|
||||
########################################################################
|
||||
app = Flask(__name__)
|
||||
mail = Mail(app)
|
||||
# Jinja2 loopcontrols extension
|
||||
app.jinja_env.add_extension('jinja2.ext.loopcontrols')
|
||||
# Path to static files
|
||||
app.static_url_path='/static'
|
||||
# Set debug mode to False for production
|
||||
@@ -30,6 +43,7 @@ app.secret_key = '9ac80548e3a8d8dfd1aefcd9a3a73473'
|
||||
db = SQLAlchemy(app)
|
||||
|
||||
|
||||
|
||||
########################################################################
|
||||
# Sample user database
|
||||
########################################################################
|
||||
@@ -42,6 +56,7 @@ class Tetawebapp_users(db.Model):
|
||||
phone = db.Column(db.Text, nullable=True)
|
||||
diet = db.Column(db.Text, nullable=True)
|
||||
is_admin = db.Column(db.Integer, nullable=False, default=0)
|
||||
link_id = db.Column(db.Text, nullable=True)
|
||||
|
||||
class Tetawebapp_roles(db.Model):
|
||||
__tablename__ = 'participer_thsf_roles'
|
||||
@@ -53,10 +68,16 @@ class Tetawebapp_turns(db.Model):
|
||||
__tablename__ = 'participer_thsf_turns'
|
||||
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('Jeudi', 'Vendredi', 'Samedi', 'Dimanche'), nullable=False)
|
||||
start_time = db.Column(db.Time, nullable=False)
|
||||
end_time = db.Column(db.Time, nullable=False)
|
||||
start_time = db.Column(db.DateTime, nullable=False)
|
||||
end_time = db.Column(db.DateTime, nullable=False)
|
||||
num_slot = db.Column(db.Integer, nullable=False, default=2)
|
||||
|
||||
class Tetawebapp_staffs(db.Model):
|
||||
__tablename__ = 'participer_thsf_staffs'
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
turn_id = db.Column(db.Integer, db.ForeignKey('participer_thsf_turns.id'), nullable=False)
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('participer_thsf_users.id'), default=0, nullable=False)
|
||||
slot_num = db.Column(db.Integer, nullable=False)
|
||||
|
||||
########################################################################
|
||||
# Menu and navigation management
|
||||
@@ -73,14 +94,13 @@ 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'/turns': [u'/turns']}, 0],
|
||||
[u'Feuilles de staff', {u'/staff_sheets': [u'/staff_sheet']}, 0],
|
||||
[u'Feuille de staff', {u'/staffsheet': [u'/staffsheet', u'/staffsheet/clear/<TURN_ID>/<SLOT_ID>', u'/staffsheet/update/<TURN_ID>/<SLOT_ID>']}, 0],
|
||||
[u'Déconnexion', {u'/logout': [u'/logout']}, 0],
|
||||
]
|
||||
if session['is_admin']:
|
||||
menu = [[u'Accueil', {u'/': [u'/']}, 0],
|
||||
[u'Tours de staff', {u'/turns': [u'/turns', u'/turn/<ID>', u'/turn/new', u'/turn/add', u'/turn/delete/<ID>', u'/turn/update/<ID>']}, 0],
|
||||
[u'Feuilles de staff', {u'/staff_sheets': [u'/staff_sheet']}, 0],
|
||||
[u'Feuille de staff', {u'/staffsheet': [u'/staffsheet', u'/staffsheet/clear/<TURN_ID>/<SLOT_ID>', u'/staffsheet/update/<TURN_ID>/<SLOT_ID>', u'/staffsheet/pdf']}, 0],
|
||||
[u'Liste des staffers', {u'/users': [u'/users', u'/account/<ID>', u'/account/delete/<ID>']}, 0],
|
||||
[u'Déconnexion', {u'/logout': [u'/logout']}, 0],
|
||||
]
|
||||
@@ -154,11 +174,27 @@ def check_session(func):
|
||||
def check_login(login, password):
|
||||
""" Puts the login verification code here """
|
||||
hashed_password = bcrypt.hashpw(password, bcrypt.gensalt())
|
||||
stored_hash = Tetawebapp_users.query.filter_by(mail=login).with_entities(Tetawebapp_users.password).first()
|
||||
is_admin = Tetawebapp_users.query.filter_by(mail=login).with_entities(Tetawebapp_users.is_admin).first()
|
||||
stored_hash = Tetawebapp_users.query.filter(Tetawebapp_users.mail==login, Tetawebapp_users.link_id==None).with_entities(Tetawebapp_users.password).first()
|
||||
if stored_hash:
|
||||
if bcrypt.checkpw(password, stored_hash[0].encode('utf-8')):
|
||||
is_admin = Tetawebapp_users.query.filter_by(mail=login).with_entities(Tetawebapp_users.is_admin).first()
|
||||
user_id = Tetawebapp_users.query.filter_by(mail=login).with_entities(Tetawebapp_users.id).first()
|
||||
session['is_admin'] = is_admin[0]
|
||||
session['user_id'] = user_id[0]
|
||||
return True
|
||||
print "[+] Login failed"
|
||||
return False
|
||||
|
||||
def check_confirm(login, password, link_id):
|
||||
""" Check identity when confirming email address """
|
||||
hashed_password = bcrypt.hashpw(password, bcrypt.gensalt())
|
||||
stored_hash = Tetawebapp_users.query.filter(Tetawebapp_users.mail==login, Tetawebapp_users.link_id==link_id).with_entities(Tetawebapp_users.password).first()
|
||||
if stored_hash:
|
||||
if bcrypt.checkpw(password, stored_hash[0].encode('utf-8')):
|
||||
is_admin = Tetawebapp_users.query.filter_by(mail=login).with_entities(Tetawebapp_users.is_admin).first()
|
||||
user_id = Tetawebapp_users.query.filter_by(mail=login).with_entities(Tetawebapp_users.id).first()
|
||||
session['is_admin'] = is_admin[0]
|
||||
session['user_id'] = user_id[0]
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -173,8 +209,9 @@ def register_user(login, password, confirm):
|
||||
# User already exists
|
||||
print "[+] User already exists"
|
||||
return False
|
||||
link_id = gen_token(20)
|
||||
hashed_password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())
|
||||
user = Tetawebapp_users(mail=login.encode('utf8'), password=hashed_password)
|
||||
user = Tetawebapp_users(mail=login.encode('utf8'), password=hashed_password, link_id=link_id)
|
||||
try:
|
||||
db.session.add(user)
|
||||
commit = db.session.commit()
|
||||
@@ -186,9 +223,31 @@ def register_user(login, password, confirm):
|
||||
print "------------------------------"
|
||||
return False
|
||||
if commit != None:
|
||||
print "[+] Error at register_user: commit was not None"
|
||||
return False
|
||||
send_mail(login, link_id)
|
||||
return True
|
||||
|
||||
def confirm_user(login, password, link_id):
|
||||
""" Confirm user """
|
||||
if check_confirm(login, password, link_id):
|
||||
user = Tetawebapp_users.query.filter_by(mail=login).first()
|
||||
setattr(user, 'link_id', None)
|
||||
try:
|
||||
db.session.add(user)
|
||||
commit = db.session.commit()
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
print "[+] Error at confirm_user:"
|
||||
print "------------------------------"
|
||||
print "%s" % e.message
|
||||
print "------------------------------"
|
||||
return False
|
||||
if commit != None:
|
||||
return False
|
||||
return True
|
||||
return False
|
||||
|
||||
def update_user(login, password, confirm, name, phone, diet):
|
||||
""" Update user infos with provided data """
|
||||
if password != confirm:
|
||||
@@ -250,7 +309,7 @@ def update_user_by_id(user_id, login, password, confirm, name, phone, diet):
|
||||
commit = db.session.commit()
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
print "[+] Error at update_user:"
|
||||
print "[+] Error at update_user_by_id:"
|
||||
print "------------------------------"
|
||||
print "%s" % e.message
|
||||
print "------------------------------"
|
||||
@@ -275,12 +334,22 @@ def delete_user(user_id):
|
||||
print "------------------------------"
|
||||
return False
|
||||
|
||||
def save_turn(role_id, day, start, end):
|
||||
def save_turn(role_id, day, start, end, num_slot):
|
||||
""" Save a new turn """
|
||||
days = ['2018-05-08', '2018-05-09', '2018-05-10', '2018-05-11', '2018-05-12', '2018-05-13', '2018-05-14']
|
||||
day_index = days.index(day)
|
||||
sday = day
|
||||
eday = day
|
||||
if str(start[0]) == '0':
|
||||
sday = days[day_index+1]
|
||||
if str(end[0]) == '0':
|
||||
eday = days[day_index+1]
|
||||
start = '%s %s' % (sday, start)
|
||||
end = '%s %s' % (eday, end)
|
||||
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'),
|
||||
num_slot=num_slot.encode('utf-8'),
|
||||
)
|
||||
try:
|
||||
db.session.add(turn)
|
||||
@@ -296,18 +365,45 @@ def save_turn(role_id, day, start, end):
|
||||
return False
|
||||
return True
|
||||
|
||||
def update_turn_by_id(turn_id, role_id, wday, start, end):
|
||||
def get_turn_by_id(turn_id):
|
||||
""" Get specified stafff turn """
|
||||
days = {'2018-05-08': 'Mardi',
|
||||
'2018-05-09': 'Mercredi',
|
||||
'2018-05-10': 'Jeudi',
|
||||
'2018-05-11': 'Vendredi',
|
||||
'2018-05-12': 'Samedi',
|
||||
'2018-05-13': 'Dimanche',
|
||||
'2018-05-14': 'Lundi'}
|
||||
turn = Tetawebapp_turns.query.filter_by(id=turn_id).first()
|
||||
s_day, s_time = str(turn.start_time).split(' ')
|
||||
e_day, e_time = str(turn.end_time).split(' ')
|
||||
if s_time[0] == '0':
|
||||
s_day = (datetime.datetime.strptime(s_day, '%Y-%m-%d')-datetime.timedelta(1)).strftime("%Y-%m-%d")
|
||||
day = days[s_day]
|
||||
return {'id': turn_id, 'role_id': turn.role_id, 'day': day, 'start_time': s_time, 'end_time': e_time, 'num_slot': turn.num_slot}
|
||||
|
||||
def update_turn_by_id(turn_id, role_id, day, start, end, num_slot):
|
||||
""" Update turn with provided data """
|
||||
check_turn = Tetawebapp_turns.query.filter_by(id=turn_id).count()
|
||||
if check_turn == 0:
|
||||
# User does not exist
|
||||
print "[+] User does not exist"
|
||||
print "[+] Turn does not exist"
|
||||
return False
|
||||
days = ['2018-05-08', '2018-05-09', '2018-05-10', '2018-05-11', '2018-05-12', '2018-05-13', '2018-05-14']
|
||||
day_index = days.index(day)
|
||||
sday = day
|
||||
eday = day
|
||||
if str(start[0]) == '0':
|
||||
sday = days[day_index +1]
|
||||
if str(end[0]) == '0':
|
||||
eday = days[day_index +1]
|
||||
start = '%s %s' % (sday, start)
|
||||
end = '%s %s' % (eday, end)
|
||||
turn = Tetawebapp_turns.query.filter_by(id=turn_id).first()
|
||||
setattr(turn, 'role_id', role_id)
|
||||
setattr(turn, 'wday', wday)
|
||||
setattr(turn, 'start_time', start)
|
||||
setattr(turn, 'end_time', end)
|
||||
setattr(turn, 'num_slot', num_slot)
|
||||
try:
|
||||
db.session.add(turn)
|
||||
commit = db.session.commit()
|
||||
@@ -339,6 +435,104 @@ def drop_turn(turn_id):
|
||||
print "------------------------------"
|
||||
return False
|
||||
|
||||
def turns_list():
|
||||
""" List staff turns """
|
||||
turns = []
|
||||
tuesday = '2018-05-08 06:00:00'
|
||||
wenesday = '2018-05-09 06:00:00'
|
||||
thirsday = '2018-05-10 06:00:00'
|
||||
friday = '2018-05-11 06:00:00'
|
||||
saturday = '2018-05-12 06:00:00'
|
||||
sunday = '2018-05-13 06:00:00'
|
||||
monday = '2018-05-14 06:00:00'
|
||||
tuesday_turns = Tetawebapp_turns.query.filter(Tetawebapp_turns.start_time > tuesday, Tetawebapp_turns.start_time < wenesday)
|
||||
tuesday_turns = tuesday_turns.join(Tetawebapp_roles, Tetawebapp_turns.role_id==Tetawebapp_roles.id)
|
||||
tuesday_turns = tuesday_turns.add_columns(Tetawebapp_roles.role).order_by(Tetawebapp_turns.role_id, Tetawebapp_turns.start_time).all()
|
||||
wenesday_turns = Tetawebapp_turns.query.filter(Tetawebapp_turns.start_time > wenesday, Tetawebapp_turns.start_time < thirsday)
|
||||
wenesday_turns = wenesday_turns.join(Tetawebapp_roles, Tetawebapp_turns.role_id==Tetawebapp_roles.id)
|
||||
wenesday_turns = wenesday_turns.add_columns(Tetawebapp_roles.role).order_by(Tetawebapp_turns.role_id, Tetawebapp_turns.start_time).all()
|
||||
thirsday_turns = Tetawebapp_turns.query.filter(Tetawebapp_turns.start_time > thirsday, Tetawebapp_turns.start_time < friday)
|
||||
thirsday_turns = thirsday_turns.join(Tetawebapp_roles, Tetawebapp_turns.role_id==Tetawebapp_roles.id)
|
||||
thirsday_turns = thirsday_turns.add_columns(Tetawebapp_roles.role).order_by(Tetawebapp_turns.role_id, Tetawebapp_turns.start_time).all()
|
||||
friday_turns = Tetawebapp_turns.query.filter(Tetawebapp_turns.start_time > friday, Tetawebapp_turns.start_time < saturday)
|
||||
friday_turns = friday_turns.join(Tetawebapp_roles, Tetawebapp_turns.role_id==Tetawebapp_roles.id)
|
||||
friday_turns = friday_turns.add_columns(Tetawebapp_roles.role).order_by(Tetawebapp_turns.role_id, Tetawebapp_turns.start_time).all()
|
||||
saturday_turns = Tetawebapp_turns.query.filter(Tetawebapp_turns.start_time > saturday, Tetawebapp_turns.start_time < sunday)
|
||||
saturday_turns = saturday_turns.join(Tetawebapp_roles, Tetawebapp_turns.role_id==Tetawebapp_roles.id)
|
||||
saturday_turns = saturday_turns.add_columns(Tetawebapp_roles.role).order_by(Tetawebapp_turns.role_id, Tetawebapp_turns.start_time).all()
|
||||
sunday_turns = Tetawebapp_turns.query.filter(Tetawebapp_turns.start_time > sunday, Tetawebapp_turns.start_time < monday)
|
||||
sunday_turns = sunday_turns.join(Tetawebapp_roles, Tetawebapp_turns.role_id==Tetawebapp_roles.id)
|
||||
sunday_turns = sunday_turns.add_columns(Tetawebapp_roles.role).order_by(Tetawebapp_turns.role_id, Tetawebapp_turns.start_time).all()
|
||||
turns.append(('Mardi', tuesday_turns))
|
||||
turns.append(('Mercredi', wenesday_turns))
|
||||
turns.append(('Jeudi', thirsday_turns))
|
||||
turns.append(('Vendredi', friday_turns))
|
||||
turns.append(('Samedi', saturday_turns))
|
||||
turns.append(('Dimanche', sunday_turns))
|
||||
return turns
|
||||
|
||||
def get_staffs():
|
||||
""" """
|
||||
try:
|
||||
staffs = Tetawebapp_staffs.query.join(Tetawebapp_users, Tetawebapp_staffs.user_id==Tetawebapp_users.id)
|
||||
staffs = staffs.add_columns(Tetawebapp_users.name).all()
|
||||
return staffs
|
||||
except Exception as e:
|
||||
print "[+] Error at get_staffs:"
|
||||
print "------------------------------"
|
||||
print "%s" % e.message
|
||||
print "------------------------------"
|
||||
return False
|
||||
|
||||
|
||||
def drop_staff_slot(turn_id, slot_num, user_id):
|
||||
""" Drop staff given slot """
|
||||
slot = Tetawebapp_staffs.query.filter_by(turn_id=turn_id, slot_num=slot_num).first()
|
||||
if slot.user_id == user_id:
|
||||
try:
|
||||
Tetawebapp_staffs.query.filter_by(turn_id=turn_id, slot_num=slot_num).delete()
|
||||
db.session.commit()
|
||||
return True
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
print "[+] Error at drop_staff_slot:"
|
||||
print "------------------------------"
|
||||
print "%s" % e.message
|
||||
print "------------------------------"
|
||||
return False
|
||||
return False
|
||||
|
||||
def save_staff_slot(turn_id, slot_id, user_id):
|
||||
""" Save staff given slot """
|
||||
slot = Tetawebapp_staffs(user_id=user_id,
|
||||
turn_id=turn_id,
|
||||
slot_num=slot_id)
|
||||
try:
|
||||
db.session.add(slot)
|
||||
commit = db.session.commit()
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
print "[+] Error at save_staff_slot:"
|
||||
print "------------------------------"
|
||||
print "%s" % e.message
|
||||
print "------------------------------"
|
||||
return False
|
||||
if commit != None:
|
||||
return False
|
||||
return True
|
||||
|
||||
def get_roles():
|
||||
""" Get full roles list """
|
||||
try:
|
||||
roles = Tetawebapp_roles.query.filter(Tetawebapp_roles.id > 3).all()
|
||||
return roles
|
||||
except Exception as e:
|
||||
print "[+] Error at get_staffs:"
|
||||
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 = ''
|
||||
@@ -351,11 +545,28 @@ def check_user_info():
|
||||
message = "Vos informations personnelles ne sont pas complètement renseignées. N'oubliez pas de remplir votre fiche située dans la section 'Mon compte'"
|
||||
return message.decode('utf-8')
|
||||
|
||||
def gen_token():
|
||||
def gen_token(size=42):
|
||||
""" Generate a random token to be stored in session and cookie """
|
||||
token = binascii.hexlify(os.urandom(42))
|
||||
token = binascii.hexlify(os.urandom(size))
|
||||
return token
|
||||
|
||||
def send_mail(email, link_id):
|
||||
msg = Message("Confirmation d'inscription au staff THSF",
|
||||
sender="dave.null@tetalab.org",
|
||||
recipients=[email])
|
||||
msg.body = "Bonjour,\nVous recevez ce courriel car vous avez souhaité faire partie de l'équipe du staff du THSF.\n\n"
|
||||
msg.body += "Pour confirmer votre inscription, rendez vous à la page suivante:\n"
|
||||
msg.body += "https://wemake.thsf.net/confirm/%s\n\n" % str(link_id)
|
||||
msg.body += "Si vous n'êtes pas à l'origine de cette inscription, ignorez simplement ce courriel.\n"
|
||||
msg.body += "Votre compte sera automatiquement supprimé dans les 24 heures.\n\n"
|
||||
msg.body += "Si vous désirez vous désinscrire, faites simplement une demande sur https://bofh.tetalab.org\n\n"
|
||||
msg.body += "Dans tous les cas la base de données sera totalement réinitialisée à la fin du THSF.\n\n"
|
||||
msg.body += "Votre aide nous est précieuse.\nMerci et bravo à vous.\n"
|
||||
msg.body += "-- \n"
|
||||
msg.body += "L'équipe d'organisation du THSF\n"
|
||||
msg.body += "(Ce mail vous est envoyé par un robot qui n' a pas réussi le test de Turing, inutile de lui répondre)"
|
||||
mail.send(msg)
|
||||
|
||||
########################################################################
|
||||
# Routes:
|
||||
# -------
|
||||
@@ -388,11 +599,50 @@ def login():
|
||||
# Credentials are not valid
|
||||
response = app.make_response(render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide"))
|
||||
session['token'] = ''
|
||||
session['login'] = ''
|
||||
session['is_admin'] = 0
|
||||
sync_cookies(response, session)
|
||||
return response
|
||||
except AttributeError:
|
||||
return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide")
|
||||
|
||||
@app.route("/confirm/<LINK_ID>", methods=['GET', 'POST'])
|
||||
def confirm(LINK_ID):
|
||||
""" Index page """
|
||||
link_id = LINK_ID.encode('utf-8')
|
||||
return render_template('confirm.html', message="Merci de confirmer votre enregistrement", link_id=link_id)
|
||||
|
||||
@app.route("/confirm/link/<LINK_ID>", methods=['GET', 'POST'])
|
||||
def confirm_link(LINK_ID):
|
||||
""" Index page """
|
||||
try:
|
||||
link_id = LINK_ID.encode('utf-8')
|
||||
login = request.form.get('login').encode('utf-8')
|
||||
password = request.form.get('password').encode('utf-8')
|
||||
if check_confirm(login, password, link_id) and confirm_user(login, password, link_id):
|
||||
# Generate and store a token in session
|
||||
session['token'] = gen_token()
|
||||
session['login'] = login
|
||||
# Return user to index page
|
||||
page = '/'
|
||||
menu = get_menu(page)
|
||||
message = check_user_info()
|
||||
response = app.make_response(render_template('index.html', menu=menu, message=message, login=login))
|
||||
# Push token to cookie
|
||||
sync_cookies(response, session)
|
||||
return response
|
||||
# Credentials are not valid
|
||||
response = app.make_response(render_template('confirm.html', message="Utilisateur ou mot de passe invalide", link_id=link_id))
|
||||
session['token'] = ''
|
||||
session['login'] = ''
|
||||
session['is_admin'] = 0
|
||||
sync_cookies(response, session)
|
||||
return response
|
||||
except AttributeError:
|
||||
return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide")
|
||||
link_id = LINK_ID.encode('utf-8')
|
||||
return render_template('confirm.html', message="Merci de confirmer votre enregistrement", link_id=link_id)
|
||||
|
||||
@app.route("/register", methods=['GET', 'POST'])
|
||||
def register():
|
||||
""" Allow self registration """
|
||||
@@ -400,24 +650,11 @@ def register():
|
||||
login = request.form.get('login').encode('utf-8')
|
||||
password = request.form.get('password').encode('utf-8')
|
||||
confirm = request.form.get('confirm').encode('utf-8')
|
||||
if register_user(login, password, confirm):
|
||||
# Generate and store a token in session
|
||||
session['token'] = gen_token()
|
||||
session['login'] = login
|
||||
# Return user to index page
|
||||
page = '/'
|
||||
menu = get_menu(page)
|
||||
message = check_user_info()
|
||||
response = app.make_response(render_template('index.html', menu=menu, login=login, message=message))
|
||||
# Push token to cookie
|
||||
sync_cookies(response, session)
|
||||
return response
|
||||
# Error while registering user
|
||||
message = "Erreur lors de l'enregsitrement: L'utilisateur existe t-il déjà ?".decode('utf-8')
|
||||
response = app.make_response(render_template('login_or_register.html', message=message))
|
||||
session['token'] = ''
|
||||
sync_cookies(response, session)
|
||||
return response
|
||||
if register_user(login, password, confirm):
|
||||
message = "Merci de votre engagement. Un courriel contenant les instructions de confirmation votre inscription vient de vous être envoyé."
|
||||
# Error while registering user
|
||||
return render_template('login_or_register.html', message=message.decode('utf-8'))
|
||||
except AttributeError:
|
||||
return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide")
|
||||
|
||||
@@ -578,15 +815,20 @@ def delete_account(ID):
|
||||
|
||||
@app.route("/turns", methods=['GET', 'POST'])
|
||||
@check_session
|
||||
def list_turn():
|
||||
def list_turns():
|
||||
""" List staff turns """
|
||||
try:
|
||||
page = str(request.url_rule)
|
||||
menu = get_menu(page)
|
||||
message = ''
|
||||
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()
|
||||
turns = turns_list()
|
||||
message = ''
|
||||
return render_template('list_turns.html', menu=menu, page=page, turns=turns, message=message)
|
||||
# TODO:
|
||||
# Here comes the list_turns_by_user_id code
|
||||
except AttributeError:
|
||||
# User is not logged in
|
||||
return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide")
|
||||
@@ -595,12 +837,19 @@ def list_turn():
|
||||
@check_session
|
||||
def new_turn():
|
||||
""" New turn form """
|
||||
tuesday = '2018-05-08'
|
||||
wenesday = '2018-05-09'
|
||||
thirsday = '2018-05-10'
|
||||
friday = '2018-05-11'
|
||||
saturday = '2018-05-12'
|
||||
sunday = '2018-05-13'
|
||||
monday = '2018-05-14'
|
||||
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']
|
||||
days = [('Mardi', tuesday), ('Mercredi', wenesday), ('Jeudi', thirsday), ('Vendredi', friday), ('Samedi', saturday), ('Dimanche', sunday)]
|
||||
return render_template('new_turn.html', menu=menu, page=page, roles=roles, days=days)
|
||||
except AttributeError:
|
||||
# User is not logged in
|
||||
@@ -616,18 +865,15 @@ def add_turn():
|
||||
day = request.form.get('day').encode('utf-8')
|
||||
start = request.form.get('start').encode('utf-8')
|
||||
end = request.form.get('end').encode('utf-8')
|
||||
num_slot = request.form.get('num_slot').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()
|
||||
turns = turns_list()
|
||||
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()
|
||||
if save_turn(role_id, day, start, end, num_slot):
|
||||
turns = turns_list()
|
||||
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:
|
||||
@@ -639,14 +885,21 @@ def add_turn():
|
||||
def turn_by_id(ID):
|
||||
try:
|
||||
if session['is_admin']:
|
||||
tuesday = '2018-05-08'
|
||||
wenesday = '2018-05-09'
|
||||
thirsday = '2018-05-10'
|
||||
friday = '2018-05-11'
|
||||
saturday = '2018-05-12'
|
||||
sunday = '2018-05-13'
|
||||
monday = '2018-05-14'
|
||||
days = [('Mardi', tuesday), ('Mercredi', wenesday), ('Jeudi', thirsday), ('Vendredi', friday), ('Samedi', saturday), ('Dimanche', sunday)]
|
||||
page = str(request.url_rule)
|
||||
menu = get_menu(page)
|
||||
roles = Tetawebapp_roles.query.order_by(Tetawebapp_roles.id).all()
|
||||
days = ['Jeudi', 'Vendredi', 'Samedi', 'Dimanche']
|
||||
message = 'ID du tour de staff non conforme'
|
||||
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()
|
||||
turns = turns_list()
|
||||
turn_id = int(ID.encode('utf-8'))
|
||||
turn = Tetawebapp_turns.query.filter_by(id=ID).first()
|
||||
turn = get_turn_by_id(turn_id)
|
||||
return render_template('turn_by_id.html', menu=menu, page=page, turn=turn, roles=roles, days=days)
|
||||
except AttributeError:
|
||||
# User is not logged in
|
||||
@@ -661,17 +914,18 @@ def update_turn(ID):
|
||||
""" Update given staff turn """
|
||||
try:
|
||||
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')
|
||||
num_slot = request.form.get('num_slot').encode('utf-8')
|
||||
day = request.form.get('day').encode('utf-8')
|
||||
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()
|
||||
turns = turns_list()
|
||||
message = "Erreur lors de l'enregistrement.".decode('utf-8')
|
||||
turn_id = int(ID.encode('utf-8'))
|
||||
if update_turn_by_id(turn_id, 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()
|
||||
if update_turn_by_id(turn_id, role_id, day, start, end, num_slot):
|
||||
turns = turns_list()
|
||||
message = ''
|
||||
return render_template('list_turns.html', menu=menu, page=page, turns=turns, message=message)
|
||||
# User is not admin
|
||||
@@ -692,11 +946,11 @@ def delete_turn(ID):
|
||||
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()
|
||||
turns = turns_list()
|
||||
turn_id = int(ID.encode('utf-8'))
|
||||
if drop_turn(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()
|
||||
turns = turns_list()
|
||||
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
|
||||
@@ -708,6 +962,201 @@ def delete_turn(ID):
|
||||
# ID is not an integer
|
||||
return render_template('list_turns.html', menu=menu, page=page, turns=turns, message=message)
|
||||
|
||||
@app.route("/staffsheet", methods=['GET', 'POST'])
|
||||
@check_session
|
||||
def staffsheet():
|
||||
try:
|
||||
user_id = session['user_id']
|
||||
if len(check_user_info()) == 0:
|
||||
page = str(request.url_rule)
|
||||
menu = get_menu(page)
|
||||
turns = turns_list()
|
||||
staffs = get_staffs()
|
||||
roles = get_roles()
|
||||
return render_template('staffsheet.html', menu=menu, turns=turns, staffs=staffs, user_id=user_id, roles=roles, message='')
|
||||
else:
|
||||
return account()
|
||||
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("/staffsheet/pdf", methods=['GET', 'POST'])
|
||||
def staffsheet_pdf():
|
||||
turns = turns_list()
|
||||
staffs = get_staffs()
|
||||
roles = get_roles()
|
||||
data = render_template('staffsheet_txt.html', turns=turns, staffs=staffs, roles=roles)
|
||||
data = [line for line in data.split('\n') if len(line) > 0]
|
||||
data = '\n'.join(data)
|
||||
data = [line for line in data.split('",\n') if len(line) > 0]
|
||||
data = '", '.join(data)
|
||||
ddata = [ast.literal_eval(line) for line in data.split('\n')]
|
||||
pdf = cStringIO.StringIO()
|
||||
doc = SimpleDocTemplate(pdf, pagesize=A4, rightMargin=3,leftMargin=3, topMargin=3,bottomMargin=3)
|
||||
elements = []
|
||||
styles = getSampleStyleSheet()
|
||||
styles.add(ParagraphStyle(name='master_title',
|
||||
alignment=TA_LEFT,
|
||||
fontSize=20,
|
||||
leading=25,
|
||||
spaceBefore=10,
|
||||
spaceAfter=10,
|
||||
))
|
||||
styles.add(ParagraphStyle(name='day_title',
|
||||
alignment=TA_LEFT,
|
||||
backColor=orange,
|
||||
borderWidth=1,
|
||||
borderColor=black,
|
||||
borderPadding=5,
|
||||
spaceBefore=10,
|
||||
spaceAfter=10
|
||||
))
|
||||
styles.add(ParagraphStyle(name='role_title',
|
||||
alignment=TA_LEFT,
|
||||
backColor=lightsalmon,
|
||||
borderWidth=1,
|
||||
borderColor=black,
|
||||
borderPadding=5,
|
||||
spaceBefore=10,
|
||||
spaceAfter=10
|
||||
))
|
||||
styles.add(ParagraphStyle(name='turn',
|
||||
alignment=TA_LEFT,
|
||||
backColor=white,
|
||||
borderWidth=1,
|
||||
borderColor=black,
|
||||
borderPadding=5,
|
||||
spaceBefore=10,
|
||||
spaceAfter=0
|
||||
))
|
||||
styles.add(ParagraphStyle(name='basic_text',
|
||||
alignment=TA_LEFT,
|
||||
spaceBefore=5,
|
||||
spaceAfter=5
|
||||
))
|
||||
styles.add(ParagraphStyle(name='row1',
|
||||
alignment=TA_LEFT,
|
||||
backColor=white,
|
||||
spaceBefore=10,
|
||||
spaceAfter=10
|
||||
))
|
||||
styles.add(ParagraphStyle(name='row2',
|
||||
alignment=TA_CENTER,
|
||||
backColor=white,
|
||||
spaceBefore=10,
|
||||
spaceAfter=10
|
||||
))
|
||||
|
||||
elements.append(Paragraph("<b>Fiches de poste</b>", styles['master_title']))
|
||||
elements.append(Paragraph("Les postes de référents (référent staff, référent bar, référent run) sont réservés à des personnes ayant une bonne connaissance du lieu et de l'évènement.",
|
||||
styles['basic_text']))
|
||||
for role in roles:
|
||||
elements.append(Paragraph("<b>%s</b>" % role.role, styles['day_title']))
|
||||
desc = role.description.split('|')
|
||||
for point in desc:
|
||||
elements.append(Paragraph(point, styles['basic_text'], bulletText='-'))
|
||||
elements.append(PageBreak())
|
||||
elements.append(Paragraph("<b>Feuilles de staff</b>", styles['master_title']))
|
||||
elements.append(Paragraph("<b>Ménage le soir même pour tous les derniers créneaux du jour</b>", styles['basic_text'], bulletText='-'))
|
||||
elements.append(Paragraph("Tâches dévolues <b>à tous et à tous moments</b>:", styles['basic_text'], bulletText='-'))
|
||||
elements.append(Indenter(left=20, right=0) )
|
||||
elements.append(Paragraph("Veiller à la sécurité générale du lieu", styles['basic_text'], bulletText='-'))
|
||||
elements.append(Paragraph("Ramassage bouteilles ou objets en verre", styles['basic_text'], bulletText='-'))
|
||||
elements.append(Paragraph("Séparation des bagarres (rarissime)", styles['basic_text'], bulletText='-'))
|
||||
elements.append(Paragraph("Sécurisation des personnes en difficulté (ou trop alcoolisées), etc...", styles['basic_text'], bulletText='-'))
|
||||
elements.append(Paragraph("<b>Sourire et bonne humeur</b> quel que soit le niveau de fatigue ;)", styles['basic_text'], bulletText='-'))
|
||||
elements.append(Indenter(left=-20, right=0) )
|
||||
for day in turns:
|
||||
wday = day[0]
|
||||
day_turns = day[1]
|
||||
cur_role = ''
|
||||
if wday not in ['Mardi', 'Mercredi']:
|
||||
elements.append(PageBreak())
|
||||
elements.append(Paragraph("<b>%s</b>" % wday, styles['day_title']))
|
||||
for turn in day_turns:
|
||||
rows = []
|
||||
role = turn[1]
|
||||
start_time = turn[0].start_time
|
||||
end_time = turn[0].end_time
|
||||
num_slot = turn[0].num_slot
|
||||
role_id = turn[0].role_id
|
||||
turn_id = turn[0].id
|
||||
if role != cur_role:
|
||||
cur_role = role
|
||||
elements.append(Paragraph("<b>%s</b>" % role, styles['role_title']))
|
||||
row = (Paragraph("<b>%s / %s</b>" % (start_time.strftime('%HH%M'), end_time.strftime('%HH%M')), styles['row1']),)
|
||||
for slot in range(0, num_slot):
|
||||
cols_width = [100] + [485/num_slot] * num_slot
|
||||
allocated_slot = []
|
||||
for sslot in staffs:
|
||||
if sslot[0].turn_id == turn_id and sslot[0].slot_num == slot:
|
||||
allocated_slot.append(sslot[0].slot_num)
|
||||
row += (Paragraph(sslot[1], styles['row2']),)
|
||||
if slot not in allocated_slot:
|
||||
row += (Paragraph(" ", styles['row2']),)
|
||||
rows.append(row)
|
||||
table = Table(rows, colWidths=cols_width, rowHeights=23)
|
||||
table.setStyle(TableStyle( [('GRID', (0,0), (-1,-1), 0.25, colors.black),
|
||||
('ALIGN', (1,1), (-1,-1), 'RIGHT')]))
|
||||
elements.append(table)
|
||||
styles.wordWrap = 'CJK'
|
||||
doc.build(elements)
|
||||
pdf_out = pdf.getvalue()
|
||||
pdf.close()
|
||||
response = app.make_response(pdf_out)
|
||||
response.headers['Content-Disposition'] = "attachment; filename=feuille_staff_thsf.pdf"
|
||||
response.mimetype = 'application/pdf'
|
||||
return response
|
||||
|
||||
@app.route("/staffsheet/clear/<TURN_ID>/<SLOT_ID>", methods=['GET', 'POST'])
|
||||
@check_session
|
||||
def clear_staff_slot(TURN_ID, SLOT_ID):
|
||||
try:
|
||||
turn_id = int(TURN_ID.encode('utf-8'))
|
||||
slot_id = int(SLOT_ID.encode('utf-8'))
|
||||
user_id = session['user_id']
|
||||
message = "Erreur lors de l'enregistrement des données"
|
||||
if (drop_staff_slot(turn_id, slot_id, user_id)):
|
||||
message = ''
|
||||
page = str(request.url_rule)
|
||||
menu = get_menu(page)
|
||||
turns = turns_list()
|
||||
staffs = get_staffs()
|
||||
roles = get_roles()
|
||||
user_id = session['user_id']
|
||||
return render_template('staffsheet.html', menu=menu, turns=turns, staffs=staffs, user_id=user_id, roles=roles, message=message.decode('utf-8'))
|
||||
except AttributeError:
|
||||
# User is not logged in
|
||||
return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide")
|
||||
except ValueError:
|
||||
# At least one ID is not integer
|
||||
return render_template('login_or_register.html', message="Identifiants non conformes")
|
||||
|
||||
@app.route("/staffsheet/update/<TURN_ID>/<SLOT_ID>", methods=['GET', 'POST'])
|
||||
@check_session
|
||||
def update_staff_slot(TURN_ID, SLOT_ID):
|
||||
try:
|
||||
turn_id = int(TURN_ID.encode('utf-8'))
|
||||
slot_id = int(SLOT_ID.encode('utf-8'))
|
||||
user_id = session['user_id']
|
||||
message = "Erreur lors de l'enregistrement des données"
|
||||
if (save_staff_slot(turn_id, slot_id, user_id)):
|
||||
message = ''
|
||||
page = str(request.url_rule)
|
||||
menu = get_menu(page)
|
||||
turns = turns_list()
|
||||
staffs = get_staffs()
|
||||
roles = get_roles()
|
||||
user_id = session['user_id']
|
||||
return render_template('staffsheet.html', menu=menu, turns=turns, staffs=staffs, user_id=user_id, roles=roles, message=message.decode('utf-8'))
|
||||
except AttributeError as e:
|
||||
# User is not logged in
|
||||
print e
|
||||
return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide")
|
||||
except ValueError:
|
||||
# At least one ID is not integer
|
||||
return render_template('login_or_register.html', message="Identifiants non conformes")
|
||||
|
||||
########################################################################
|
||||
# Main
|
||||
########################################################################
|
||||
|
||||
Reference in New Issue
Block a user