participer.thsf.net/participate.py

1165 lines
47 KiB
Python
Raw Normal View History

2018-02-26 20:41:52 +11:00
#!/usr/bin/env python
# -*- coding: utf-8
# Required modules
import os
import inspect
import random
import binascii
import bcrypt
2018-03-06 08:12:02 +11:00
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
2018-02-26 20:41:52 +11:00
from functools import wraps
2018-03-06 08:12:02 +11:00
import cStringIO
from flask_mail import Mail, Message
2018-02-26 20:41:52 +11:00
# Optionnal modules
import psycopg2
from flask_sqlalchemy import SQLAlchemy
########################################################################
# App settings
########################################################################
app = Flask(__name__)
2018-03-06 08:12:02 +11:00
mail = Mail(app)
# Jinja2 loopcontrols extension
app.jinja_env.add_extension('jinja2.ext.loopcontrols')
2018-02-26 20:41:52 +11:00
# Path to static files
app.static_url_path='/static'
# Set debug mode to False for production
app.debug = True
# Various configuration settings belong here (optionnal)
app.config.from_pyfile('config.local.py')
# Generate a new key: head -n 40 /dev/urandom | md5sum | cut -d' ' -f1
2018-02-27 05:53:06 +11:00
app.secret_key = '9ac80548e3a8d8dfd1aefcd9a3a73473'
2018-02-26 20:41:52 +11:00
# Feel free to use SQLAlchemy (or not)
db = SQLAlchemy(app)
2018-03-06 08:12:02 +11:00
2018-02-26 20:41:52 +11:00
########################################################################
# Sample user database
########################################################################
class Tetawebapp_users(db.Model):
2018-02-27 05:53:06 +11:00
__tablename__ = 'participer_thsf_users'
2018-02-26 20:41:52 +11:00
id = db.Column(db.Integer, primary_key=True)
mail = db.Column(db.Text, nullable=False)
password = db.Column(db.Text, nullable=False)
2018-02-27 05:53:06 +11:00
name = db.Column(db.Text, nullable=True)
phone = db.Column(db.Text, nullable=True)
diet = db.Column(db.Text, nullable=True)
2018-02-28 05:51:43 +11:00
is_admin = db.Column(db.Integer, nullable=False, default=0)
2018-03-06 08:12:02 +11:00
link_id = db.Column(db.Text, nullable=True)
2018-02-26 20:41:52 +11:00
2018-02-27 05:53:06 +11:00
class Tetawebapp_roles(db.Model):
__tablename__ = 'participer_thsf_roles'
id = db.Column(db.Integer, primary_key=True)
role = db.Column(db.Text, nullable=False)
description = db.Column(db.Text, nullable=False)
2018-02-26 20:41:52 +11:00
2018-02-28 05:51:43 +11:00
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)
2018-03-06 08:12:02 +11:00
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)
2018-02-28 05:51:43 +11:00
2018-02-26 20:41:52 +11:00
########################################################################
# Menu and navigation management
########################################################################
def get_menu(page):
""" The main menu is a list of lists in the followin format:
[unicode caption,
{unicode URL endpoint: [unicode route, ...]},
int 0]
- The URL end point is the URL where to point to (href)
- One of the routes MUST match the route called by request
- The int 0 is used to determine which menu entry is actally called.
The value MUST be 0."""
2018-02-27 05:53:06 +11:00
menu = [[u'Accueil', {u'/': [u'/']}, 0],
2018-02-28 05:51:43 +11:00
[u'Mon compte', {u'/account': [u'/account', u'/account/update']}, 0],
2018-03-06 08:12:02 +11:00
[u'Feuille de staff', {u'/staffsheet': [u'/staffsheet', u'/staffsheet/clear/<TURN_ID>/<SLOT_ID>', u'/staffsheet/update/<TURN_ID>/<SLOT_ID>']}, 0],
2018-02-28 05:51:43 +11:00
[u'Déconnexion', {u'/logout': [u'/logout']}, 0],
]
if session['is_admin']:
menu = [[u'Accueil', {u'/': [u'/']}, 0],
2018-02-28 20:25:08 +11:00
[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],
2018-03-06 08:12:02 +11:00
[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],
2018-02-28 20:25:08 +11:00
[u'Liste des staffers', {u'/users': [u'/users', u'/account/<ID>', u'/account/delete/<ID>']}, 0],
2018-02-27 05:53:06 +11:00
[u'Déconnexion', {u'/logout': [u'/logout']}, 0],
2018-02-26 20:41:52 +11:00
]
2018-02-28 20:25:08 +11:00
#~ print '[+] Page: %s' % page
2018-02-26 20:41:52 +11:00
for item in menu:
for url in item[1]:
for route in item[1][url]:
2018-02-28 20:25:08 +11:00
#~ print " [+] Route: %s" %route
2018-02-26 20:41:52 +11:00
if route == page:
2018-02-28 20:25:08 +11:00
#~ print " [+] Selected page: %s" % page
2018-02-26 20:41:52 +11:00
item[2] = 1
return menu
# This should never happen
return menu
def get_navbar(page, selected):
""" The horizontal navbar is a list of lists in the followin format:
[unicode caption, {unicode URL endpoint: [unicode route, ...]}, int 0]
- The URL end point is the URL where to point to (href)
- One of the routes MUST match the route called by request
- The int 0 is used to de """
navbars = [[u'First article', {u'/articles/1': [u'/articles', u'/articles/<ID>']}, 0, 0],
[u'Second article', {u'/articles/2': [u'/articles', u'/articles/<ID>']}, 0, 0],
[u'Third article', {u'/articles/3': [u'/articles', u'/articles/<ID>']}, 0, 0]
]
navbar = []
for item in navbars:
for url in item[1]:
if url == selected:
item[2] = 1
for route in item[1][url]:
if route == page:
navbar.append(item)
navbar[len(navbar) - 1][3] = 1
return navbar
########################################################################
# Session management
########################################################################
def sync_session(request, session):
""" Synchronize cookies with session """
for key in request.cookies:
session[key] = request.cookies[key].encode('utf8')
def sync_cookies(response, session):
""" Synchronize session with cookies """
for key in session:
response.set_cookie(key, value=str(session[key]))
def check_session(func):
""" Check if the session has required token cookie set.
If not, redirects to the login page. """
@wraps(func)
def check(*args, **kwargs):
try:
if session['token'] == request.cookies['token'] and len(session['token']) > 0:
2018-02-28 05:51:43 +11:00
# User is logged in and identified
2018-02-26 20:41:52 +11:00
return func(*args, **kwargs)
else:
2018-02-28 05:51:43 +11:00
# User is not logged in or session expired
2018-02-26 20:41:52 +11:00
session['token'] = ''
2018-02-27 05:53:06 +11:00
response = app.make_response(render_template('login_or_register.html', message=''))
2018-02-26 20:41:52 +11:00
sync_cookies(response, session)
return response
except KeyError:
2018-02-28 05:51:43 +11:00
# User is not logged in
2018-02-27 05:53:06 +11:00
return render_template('login_or_register.html', message='')
2018-02-26 20:41:52 +11:00
return check
def check_login(login, password):
""" Puts the login verification code here """
hashed_password = bcrypt.hashpw(password, bcrypt.gensalt())
2018-03-06 08:12:02 +11:00
stored_hash = Tetawebapp_users.query.filter(Tetawebapp_users.mail==login, Tetawebapp_users.link_id==None).with_entities(Tetawebapp_users.password).first()
2018-02-26 20:41:52 +11:00
if stored_hash:
if bcrypt.checkpw(password, stored_hash[0].encode('utf-8')):
2018-03-06 08:12:02 +11:00
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()
2018-02-28 05:51:43 +11:00
session['is_admin'] = is_admin[0]
2018-03-06 08:12:02 +11:00
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]
2018-02-26 20:41:52 +11:00
return True
return False
2018-02-28 05:51:43 +11:00
def register_user(login, password, confirm):
""" Register new user """
if password != confirm:
# Password does not match confirmation
print "[+] Password mismatch confirmation"
return False
check_user = Tetawebapp_users.query.filter_by(mail=login).count()
if check_user != 0:
# User already exists
print "[+] User already exists"
return False
2018-03-06 08:12:02 +11:00
link_id = gen_token(20)
2018-02-28 05:51:43 +11:00
hashed_password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())
2018-03-06 08:12:02 +11:00
user = Tetawebapp_users(mail=login.encode('utf8'), password=hashed_password, link_id=link_id)
2018-02-28 05:51:43 +11:00
try:
db.session.add(user)
commit = db.session.commit()
except Exception as e:
db.session.rollback()
print "[+] Error at register_user:"
print "------------------------------"
print "%s" % e.message
print "------------------------------"
return False
if commit != None:
2018-03-06 08:12:02 +11:00
print "[+] Error at register_user: commit was not None"
2018-02-28 05:51:43 +11:00
return False
2018-03-06 08:12:02 +11:00
send_mail(login, link_id)
2018-02-28 05:51:43 +11:00
return True
2018-03-06 08:12:02 +11:00
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
2018-02-28 05:51:43 +11:00
def update_user(login, password, confirm, name, phone, diet):
""" Update user infos with provided data """
if password != confirm:
# Password does not match confirmation
print "[+] Password mismatch confirmation"
return False
check_user = Tetawebapp_users.query.filter_by(mail=login).count()
if check_user == 0:
# User does not exist
print "[+] User does not exist"
return False
user = Tetawebapp_users.query.filter_by(mail=login).first()
if len(password) > 0:
# User requested password modification
hashed_password = bcrypt.hashpw(password, bcrypt.gensalt())
setattr(user, 'password', hashed_password)
# Password has been updated if necessary
# Now let's update other data
setattr(user, 'name', name)
setattr(user, 'phone', phone)
setattr(user, 'diet', diet)
try:
db.session.add(user)
commit = db.session.commit()
except Exception as e:
db.session.rollback()
print "[+] Error at update_user:"
print "------------------------------"
print "%s" % e.message
print "------------------------------"
return False
if commit != None:
return False
return True
def update_user_by_id(user_id, login, password, confirm, name, phone, diet):
""" Update user infos with provided data """
if password != confirm:
# Password does not match confirmation
print "[+] Password mismatch confirmation"
return False
check_user = Tetawebapp_users.query.filter_by(id=user_id).count()
if check_user == 0:
# User does not exist
print "[+] User does not exist"
return False
user = Tetawebapp_users.query.filter_by(id=user_id).first()
if len(password) > 0:
# User requested password modification
hashed_password = bcrypt.hashpw(password, bcrypt.gensalt())
setattr(user, 'password', hashed_password)
# Password has been updated if necessary
# Now let's update other data
setattr(user, 'name', name)
setattr(user, 'phone', phone)
setattr(user, 'diet', diet)
try:
db.session.add(user)
commit = db.session.commit()
except Exception as e:
db.session.rollback()
2018-03-06 08:12:02 +11:00
print "[+] Error at update_user_by_id:"
2018-02-28 05:51:43 +11:00
print "------------------------------"
print "%s" % e.message
print "------------------------------"
return False
if commit != None:
return False
return True
def delete_user(user_id):
""" Delete user """
try:
Tetawebapp_users.query.filter_by(id=int(user_id)).delete()
db.session.commit()
return True
except ValueError as e:
return False
except Exception as e:
db.session.rollback()
print "[+] Error at delete_user:"
print "------------------------------"
print "%s" % e.message
print "------------------------------"
return False
2018-03-06 08:12:02 +11:00
def save_turn(role_id, day, start, end, num_slot):
2018-02-28 20:25:08 +11:00
""" Save a new turn """
2018-03-06 08:12:02 +11:00
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)
2018-02-28 20:25:08 +11:00
turn = Tetawebapp_turns(role_id=role_id.encode('utf-8'),
start_time=start.encode('utf-8'),
end_time=end.encode('utf-8'),
2018-03-06 08:12:02 +11:00
num_slot=num_slot.encode('utf-8'),
2018-02-28 20:25:08 +11:00
)
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
2018-03-06 08:12:02 +11:00
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):
2018-03-01 00:30:31 +11:00
""" Update turn with provided data """
check_turn = Tetawebapp_turns.query.filter_by(id=turn_id).count()
if check_turn == 0:
# User does not exist
2018-03-06 08:12:02 +11:00
print "[+] Turn does not exist"
2018-03-01 00:30:31 +11:00
return False
2018-03-06 08:12:02 +11:00
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)
2018-03-01 00:30:31 +11:00
turn = Tetawebapp_turns.query.filter_by(id=turn_id).first()
setattr(turn, 'role_id', role_id)
setattr(turn, 'start_time', start)
setattr(turn, 'end_time', end)
2018-03-06 08:12:02 +11:00
setattr(turn, 'num_slot', num_slot)
2018-03-01 00:30:31 +11:00
try:
db.session.add(turn)
commit = db.session.commit()
except Exception as e:
db.session.rollback()
print "[+] Error at update_turn:"
print "------------------------------"
print "%s" % e.message
print "------------------------------"
return False
if commit != None:
return False
return True
2018-02-28 20:25:08 +11:00
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
2018-03-06 08:12:02 +11:00
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
2018-02-27 05:53:06 +11:00
def check_user_info():
""" Check user info and send appropriate message if info are not complete"""
2018-02-28 05:51:43 +11:00
message = ''
user = Tetawebapp_users.query.filter_by(mail=session['login']).first()
name = user.name
phone = user.phone
diet = user.diet
if name == None or phone == None or diet == None or \
len(name) == 0 or len(phone) == 0 or len(diet) == 0:
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'"
2018-02-27 05:53:06 +11:00
return message.decode('utf-8')
2018-03-06 08:12:02 +11:00
def gen_token(size=42):
2018-02-26 20:41:52 +11:00
""" Generate a random token to be stored in session and cookie """
2018-03-06 08:12:02 +11:00
token = binascii.hexlify(os.urandom(size))
2018-02-26 20:41:52 +11:00
return token
2018-03-06 08:12:02 +11:00
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)
2018-02-26 20:41:52 +11:00
########################################################################
# Routes:
# -------
# Except for the index function, the function name MUST have the same
# name than the URL endpoint to make the menu work properly
########################################################################
@app.errorhandler(404)
def page_not_found(e):
""" 404 not found """
return render_template('error.html'), 404
@app.route("/login", methods=['GET', 'POST'])
def login():
2018-02-28 20:25:08 +11:00
""" Login """
2018-02-28 05:51:43 +11:00
try:
login = request.form.get('login').encode('utf-8')
password = request.form.get('password').encode('utf-8')
if check_login(login, password):
# 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('login_or_register.html', message="Utilisateur ou mot de passe invalide"))
session['token'] = ''
2018-03-06 08:12:02 +11:00
session['login'] = ''
session['is_admin'] = 0
2018-02-27 05:53:06 +11:00
sync_cookies(response, session)
return response
2018-02-28 05:51:43 +11:00
except AttributeError:
return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide")
2018-02-27 05:53:06 +11:00
2018-03-06 08:12:02 +11:00
@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 """
2018-02-28 05:51:43 +11:00
try:
2018-03-06 08:12:02 +11:00
link_id = LINK_ID.encode('utf-8')
2018-02-28 05:51:43 +11:00
login = request.form.get('login').encode('utf-8')
password = request.form.get('password').encode('utf-8')
2018-03-06 08:12:02 +11:00
if check_confirm(login, password, link_id) and confirm_user(login, password, link_id):
2018-02-28 05:51:43 +11:00
# 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()
2018-03-06 08:12:02 +11:00
response = app.make_response(render_template('index.html', menu=menu, message=message, login=login))
2018-02-28 05:51:43 +11:00
# Push token to cookie
sync_cookies(response, session)
return response
2018-03-06 08:12:02 +11:00
# Credentials are not valid
response = app.make_response(render_template('confirm.html', message="Utilisateur ou mot de passe invalide", link_id=link_id))
2018-02-28 05:51:43 +11:00
session['token'] = ''
2018-03-06 08:12:02 +11:00
session['login'] = ''
session['is_admin'] = 0
2018-02-26 20:41:52 +11:00
sync_cookies(response, session)
return response
2018-03-06 08:12:02 +11:00
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 """
try:
login = request.form.get('login').encode('utf-8')
password = request.form.get('password').encode('utf-8')
confirm = request.form.get('confirm').encode('utf-8')
message = "Erreur lors de l'enregsitrement: L'utilisateur existe t-il déjà ?".decode('utf-8')
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'))
2018-02-28 05:51:43 +11:00
except AttributeError:
return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide")
2018-02-26 20:41:52 +11:00
@app.route("/", methods=['GET', 'POST'])
@check_session
def index():
""" Index page """
page = str(request.url_rule)
menu = get_menu(page)
2018-02-27 05:53:06 +11:00
message = check_user_info()
2018-02-28 05:51:43 +11:00
return render_template('index.html', menu=menu, message=message, login=session['login'])
2018-02-26 20:41:52 +11:00
2018-02-27 05:53:06 +11:00
@app.route("/account", methods=['GET', 'POST'])
2018-02-26 20:41:52 +11:00
@check_session
2018-02-27 05:53:06 +11:00
def account():
2018-02-28 05:51:43 +11:00
""" Account page """
2018-02-26 20:41:52 +11:00
page = str(request.url_rule)
menu = get_menu(page)
2018-02-28 05:51:43 +11:00
user = Tetawebapp_users.query.filter_by(mail=session['login']).first()
mail = '' if user.mail == None else user.mail
name = '' if user.name == None else user.name
phone = '' if user.phone == None else user.phone
diet = '' if user.diet == None else user.diet
message = check_user_info()
return render_template('account.html', menu=menu, mail=mail, name=name, phone=phone, diet=diet, message=message)
@app.route("/account/update", methods=['GET', 'POST'])
@check_session
def update_account():
""" Update current account """
try:
page = str(request.url_rule)
menu = get_menu(page)
login = session['login']
password = request.form.get('password').encode('utf-8')
confirm = request.form.get('confirm').encode('utf-8')
name = request.form.get('name').encode('utf-8')
phone = request.form.get('phone').encode('utf-8')
diet = request.form.get('diet').encode('utf-8')
if update_user(login, password, confirm, name, phone, diet):
message = check_user_info()
else:
message = "Erreur lors de l'enregistrement des données."
return render_template('account.html',
menu=menu,
mail=login.decode('utf-8'),
name=name.decode('utf-8'),
phone=phone.decode('utf-8'),
diet=diet.decode('utf-8'),
message=message)
except AttributeError:
return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide")
2018-02-28 20:25:08 +11:00
@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
########################################################################
2018-02-28 05:51:43 +11:00
@app.route("/users", methods=['GET', 'POST'])
@check_session
def list_users():
""" Users list """
page = str(request.url_rule)
menu = get_menu(page)
message = check_user_info()
staffers = Tetawebapp_users.query.filter_by(is_admin=0).order_by(Tetawebapp_users.name).all()
return render_template('list_users.html', menu=menu, staffers=staffers, message=message)
2018-02-26 20:41:52 +11:00
2018-02-27 05:53:06 +11:00
@app.route("/account/<ID>", methods=['GET', 'POST'])
2018-02-26 20:41:52 +11:00
@check_session
2018-02-27 05:53:06 +11:00
def account_by_id(ID):
2018-02-26 20:41:52 +11:00
""" Arcticles page """
2018-02-28 05:51:43 +11:00
try:
if session['is_admin']:
page = str(request.url_rule)
menu = get_menu(page)
2018-03-01 00:30:31 +11:00
message = "ID de l'utilisateur non conforme"
staffers = Tetawebapp_users.query.filter_by(is_admin=0).order_by(Tetawebapp_users.name).all()
user_id = int(ID.encode('utf-8'))
user = Tetawebapp_users.query.filter_by(id=user_id).first()
2018-02-28 05:51:43 +11:00
return render_template('account_by_id.html', menu=menu, user=user)
# 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")
2018-03-01 00:30:31 +11:00
except ValueError:
# ID is not an integer
return render_template('list_users.html', menu=menu, staffers=staffers, message=message)
2018-02-28 05:51:43 +11:00
@app.route("/account/update/<ID>", methods=['GET', 'POST'])
@check_session
def update_account_by_id(ID):
""" Update given account """
try:
if session['is_admin']:
page = str(request.url_rule)
menu = get_menu(page)
login = session['login']
password = request.form.get('password').encode('utf-8')
confirm = request.form.get('confirm').encode('utf-8')
name = request.form.get('name').encode('utf-8')
phone = request.form.get('phone').encode('utf-8')
diet = request.form.get('diet').encode('utf-8')
2018-03-01 00:30:31 +11:00
message = "ID de l'utilisateur non conforme"
staffers = Tetawebapp_users.query.filter_by(is_admin=0).order_by(Tetawebapp_users.name).all()
user_id = int(ID.encode('utf-8'))
if update_user_by_id(user_id, login, password, confirm, name, phone, diet):
2018-02-28 05:51:43 +11:00
user = Tetawebapp_users.query.filter_by(id=ID).first()
message = check_user_info()
else:
message = "Erreur lors de l'enregistrement des données."
2018-03-01 00:30:31 +11:00
return render_template('account_by_id.html', menu=menu, user=user,message=message)
2018-02-28 05:51:43 +11:00
# 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")
2018-03-01 00:30:31 +11:00
except ValueError:
# ID is not an integer
return render_template('list_users.html', menu=menu, staffers=staffers, message=message)
2018-02-28 05:51:43 +11:00
@app.route("/account/delete/<ID>", methods=['GET', 'POST'])
@check_session
def delete_account(ID):
""" Delete given account """
try:
if session['is_admin']:
message = "Erreur lors de la suppression.".decode('utf-8')
page = str(request.url_rule)
menu = get_menu(page)
staffers = Tetawebapp_users.query.filter_by(is_admin=0).order_by(Tetawebapp_users.name).all()
2018-03-01 00:30:31 +11:00
user_id = int(ID.encode('utf-8'))
if delete_user(user_id):
message = ''
staffers = Tetawebapp_users.query.filter_by(is_admin=0).order_by(Tetawebapp_users.name).all()
2018-02-28 05:51:43 +11:00
return render_template('list_users.html', menu=menu, staffers=staffers, 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")
2018-03-01 00:30:31 +11:00
except ValueError:
# ID is not an integer
return render_template('list_users.html', menu=menu, staffers=staffers, message=message)
2018-02-27 05:53:06 +11:00
2018-02-28 20:25:08 +11:00
@app.route("/turns", methods=['GET', 'POST'])
2018-02-27 05:53:06 +11:00
@check_session
2018-03-06 08:12:02 +11:00
def list_turns():
2018-02-28 20:25:08 +11:00
""" List staff turns """
try:
2018-03-06 08:12:02 +11:00
page = str(request.url_rule)
menu = get_menu(page)
message = ''
2018-02-28 20:25:08 +11:00
if session['is_admin']:
page = str(request.url_rule)
menu = get_menu(page)
2018-03-06 08:12:02 +11:00
turns = turns_list()
2018-02-28 20:25:08 +11:00
message = ''
return render_template('list_turns.html', menu=menu, page=page, turns=turns, message=message)
2018-03-06 08:12:02 +11:00
# TODO:
# Here comes the list_turns_by_user_id code
2018-02-28 20:25:08 +11:00
except AttributeError:
# User is not logged in
return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide")
2018-02-27 05:53:06 +11:00
2018-02-28 20:25:08 +11:00
@app.route("/turn/new", methods=['GET', 'POST'])
@check_session
def new_turn():
""" New turn form """
2018-03-06 08:12:02 +11:00
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'
2018-02-28 20:25:08 +11:00
try:
if session['is_admin']:
page = str(request.url_rule)
menu = get_menu(page)
roles = Tetawebapp_roles.query.order_by(Tetawebapp_roles.id).all()
2018-03-06 08:12:02 +11:00
days = [('Mardi', tuesday), ('Mercredi', wenesday), ('Jeudi', thirsday), ('Vendredi', friday), ('Samedi', saturday), ('Dimanche', sunday)]
2018-02-28 20:25:08 +11:00
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")
2018-02-27 05:53:06 +11:00
2018-02-28 20:25:08 +11:00
@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')
2018-03-06 08:12:02 +11:00
num_slot = request.form.get('num_slot').encode('utf-8')
2018-02-28 20:25:08 +11:00
page = str(request.url_rule)
menu = get_menu(page)
2018-03-06 08:12:02 +11:00
turns = turns_list()
2018-02-28 20:25:08 +11:00
message = "Erreur lors de l'enregistrement.".decode('utf-8')
2018-03-06 08:12:02 +11:00
if save_turn(role_id, day, start, end, num_slot):
turns = turns_list()
2018-02-28 20:25:08 +11:00
message=''
return render_template('list_turns.html', menu=menu, page=page, turns=turns, 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")
2018-02-27 05:53:06 +11:00
2018-02-28 20:25:08 +11:00
@app.route("/turn/<ID>", methods=['GET', 'POST'])
@check_session
2018-03-01 00:30:31 +11:00
def turn_by_id(ID):
try:
if session['is_admin']:
2018-03-06 08:12:02 +11:00
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)]
2018-03-01 00:30:31 +11:00
page = str(request.url_rule)
menu = get_menu(page)
roles = Tetawebapp_roles.query.order_by(Tetawebapp_roles.id).all()
message = 'ID du tour de staff non conforme'
2018-03-06 08:12:02 +11:00
turns = turns_list()
2018-03-01 00:30:31 +11:00
turn_id = int(ID.encode('utf-8'))
2018-03-06 08:12:02 +11:00
turn = get_turn_by_id(turn_id)
2018-03-01 00:30:31 +11:00
return render_template('turn_by_id.html', menu=menu, page=page, turn=turn, 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")
except ValueError:
# ID is not an integer
return render_template('list_turns.html', menu=menu, page=page, turns=turns, message=message)
@app.route("/turn/update/<ID>", methods=['GET', 'POST'])
@check_session
def update_turn(ID):
""" Update given staff turn """
try:
role_id = request.form.get('role_id').encode('utf-8')
start = request.form.get('start').encode('utf-8')
end = request.form.get('end').encode('utf-8')
2018-03-06 08:12:02 +11:00
num_slot = request.form.get('num_slot').encode('utf-8')
day = request.form.get('day').encode('utf-8')
2018-03-01 00:30:31 +11:00
if session['is_admin']:
page = str(request.url_rule)
menu = get_menu(page)
2018-03-06 08:12:02 +11:00
turns = turns_list()
2018-03-01 00:30:31 +11:00
message = "Erreur lors de l'enregistrement.".decode('utf-8')
turn_id = int(ID.encode('utf-8'))
2018-03-06 08:12:02 +11:00
if update_turn_by_id(turn_id, role_id, day, start, end, num_slot):
turns = turns_list()
2018-03-01 00:30:31 +11:00
message = ''
return render_template('list_turns.html', menu=menu, page=page, turns=turns, 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")
except ValueError:
# ID is not an integer
return render_template('list_turns.html', menu=menu, page=page, turns=turns, message=message)
2018-02-28 20:25:08 +11:00
@app.route("/turn/delete/<ID>", 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)
2018-03-06 08:12:02 +11:00
turns = turns_list()
2018-03-01 00:30:31 +11:00
turn_id = int(ID.encode('utf-8'))
if drop_turn(turn_id):
2018-02-28 20:25:08 +11:00
message = ''
2018-03-06 08:12:02 +11:00
turns = turns_list()
2018-02-28 20:25:08 +11:00
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")
2018-03-01 00:30:31 +11:00
except ValueError:
# ID is not an integer
return render_template('list_turns.html', menu=menu, page=page, turns=turns, message=message)
2018-02-26 20:41:52 +11:00
2018-03-06 08:12:02 +11:00
@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("&nbsp;", 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")
2018-02-26 20:41:52 +11:00
########################################################################
# Main
########################################################################
if __name__ == '__main__':
app.run(host='0.0.0.0')