"first proto"

This commit is contained in:
Doug Le Tough 2018-02-26 19:53:06 +01:00
vanhempi 99181ffa08
commit 7332af1dc0
16 muutettua tiedostoa jossa 369 lisäystä ja 110 poistoa

Näytä tiedosto

@ -1,3 +1,3 @@
SQLALCHEMY_TRACK_MODIFICATIONS = True
SQLALCHEMY_DATABASE_URI = "postgresql://tetawebapp:tetawebapp@localhost/tetawebapp"
SQLALCHEMY_DATABASE_URI = "postgresql://participer_thsf:participer_thsf@localhost/participer_thsf"
UPLOADED_FILES_DEST = "./upload"

Näytä tiedosto

@ -25,7 +25,7 @@ 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
app.secret_key = 'ce1d1c9ff0ff388a838b3a1e3207dd27'
app.secret_key = '9ac80548e3a8d8dfd1aefcd9a3a73473'
# Feel free to use SQLAlchemy (or not)
db = SQLAlchemy(app)
@ -34,12 +34,19 @@ db = SQLAlchemy(app)
# Sample user database
########################################################################
class Tetawebapp_users(db.Model):
__tablename__ = 'tetawebapp_users'
__tablename__ = 'participer_thsf_users'
id = db.Column(db.Integer, primary_key=True)
mail = db.Column(db.Text, nullable=False)
password = db.Column(db.Text, nullable=False)
name = db.Column(db.Text, nullable=False)
name = db.Column(db.Text, nullable=True)
phone = db.Column(db.Text, nullable=True)
diet = db.Column(db.Text, nullable=True)
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)
########################################################################
# Menu and navigation management
@ -54,9 +61,11 @@ def get_menu(page):
- 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."""
menu = [[u'Home', {u'/': [u'/']}, 0],
[u'Articles', {u'/articles': [u'/articles', u'/articles/<ID>']}, 0],
[u'Basics', {u'/basics': [u'/basics']}, 0],
menu = [[u'Accueil', {u'/': [u'/']}, 0],
[u'Mon compte', {u'/account': [u'/account', u'/account/<ID>']}, 0],
[u'Mes quarts', {u'/turn': [u'/turn']}, 0],
[u'Feuille de staff', {u'/staff_sheet': [u'/staff_sheet']}, 0],
[u'Déconnexion', {u'/logout': [u'/logout']}, 0],
[u'Inputs', {u'/inputs': [u'/inputs']}, 0],
[u'Ajax', {u'/ajax': [u'/ajax']}, 0],
[u'Database', {u'/database': [u'/database']}, 0],
@ -116,11 +125,11 @@ def check_session(func):
return func(*args, **kwargs)
else:
session['token'] = ''
response = app.make_response(render_template('login.html', message=''))
response = app.make_response(render_template('login_or_register.html', message=''))
sync_cookies(response, session)
return response
except KeyError:
return render_template('login.html', message='')
return render_template('login_or_register.html', message='')
return check
def check_login(login, password):
@ -133,6 +142,11 @@ def check_login(login, password):
return True
return False
def check_user_info():
""" Check user info and send appropriate message if info are not complete"""
message = "Vos informations personnelles ne sont pas totalement renseignées. N'oubliez pas de remplir votre fiche située dans la section 'Mon compte'"
return message.decode('utf-8')
def gen_token():
""" Generate a random token to be stored in session and cookie """
token = binascii.hexlify(os.urandom(42))
@ -151,6 +165,27 @@ def page_not_found(e):
@app.route("/login", methods=['GET', 'POST'])
def login():
login = request.form.get('login')
password = request.form.get('password')
if check_login(login, password):
# Generate and store a token in session
session['token'] = gen_token()
# 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))
# 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='Invalid user or password'))
session['token'] = ''
sync_cookies(response, session)
return response
@app.route("/register", methods=['GET', 'POST'])
def register():
login = request.form.get('login')
password = request.form.get('password')
if check_login(login, password):
@ -164,7 +199,7 @@ def login():
sync_cookies(response, session)
return response
# Credentials are not valid
response = app.make_response(render_template('login.html', message='Invalid user or password'))
response = app.make_response(render_template('login_or_register.html', message='Invalid user or password'))
session['token'] = ''
sync_cookies(response, session)
return response
@ -175,26 +210,50 @@ def index():
""" Index page """
page = str(request.url_rule)
menu = get_menu(page)
return render_template('index.html', menu=menu)
message = check_user_info()
return render_template('index.html', menu=menu, message=message)
@app.route("/articles", methods=['GET', 'POST'])
@app.route("/account", methods=['GET', 'POST'])
@check_session
def articles():
def account():
""" Arcticles page """
page = str(request.url_rule)
menu = get_menu(page)
navbar = get_navbar(page, '')
return render_template('articles.html', menu=menu, navbar=navbar)
return render_template('account.html', menu=menu)
@app.route("/articles/<ID>", methods=['GET', 'POST'])
@app.route("/account/<ID>", methods=['GET', 'POST'])
@check_session
def articles_by_id(ID):
def account_by_id(ID):
""" Arcticles page """
page = str(request.url_rule)
menu = get_menu(page)
selected = page.replace('<ID>', ID)
navbar = get_navbar(page, selected)
return render_template('articles_by_id.html', menu=menu, navbar=navbar, ID=ID)
return render_template('account_by_id.html', menu=menu, navbar=navbar, ID=ID)
@app.route("/logout", methods=['GET', 'POST'])
@check_session
def logout():
""" Logout user """
# Remove session token
session['token'] = 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
@app.route("/basics", methods=['GET', 'POST'])
@check_session

Näytä tiedosto

@ -0,0 +1,26 @@
Define IP_ADDR 0.0.0.0
Define TCP_PORT 80
Define SRV_NAME participer.redatomik.org
Define ROOT_DIR /var/www/participer.redatomik.org
Define WSGI_ALIAS /var/www/participer.redatomik.org/participer.redatomik.org.wsgi
Define DAEMON_PROCESS participer.redatomik.org
Define APACHE_USER apache
Define APACHE_GROUP apache
Define THREAD_NUMBER 5
<VirtualHost ${IP_ADDR}:${TCP_PORT}>
ServerName ${SRV_NAME}
ServerAdmin bofh@tetalab.org
DocumentRoot ${ROOT_DIR}
WSGIDaemonProcess ${DAEMON_PROCESS} user=${APACHE_USER} group=${APACHE_GROUP} threads=${THREAD_NUMBER}
WSGIScriptAlias / ${WSGI_ALIAS}
<Directory ${ROOT_DIR}>
WSGIProcessGroup ${DAEMON_PROCESS}
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
AllowOverride All
Require all granted
</Directory>
ErrorLog /var/log/httpd/${SRV_NAME}.error.log
CustomLog /var/log/httpd/${SRV_NAME}.access.log combined
</VirtualHost>

26
participer.thsf.net.conf Normal file
Näytä tiedosto

@ -0,0 +1,26 @@
Define IP_ADDR 0.0.0.0
Define TCP_PORT 80
Define SRV_NAME participer.thsf.net
Define ROOT_DIR /var/www/participer.thsf.net
Define WSGI_ALIAS /var/www/participer.thsf.net/participer.thsf.net.wsgi
Define DAEMON_PROCESS participer.thsf.net
Define APACHE_USER apache
Define APACHE_GROUP apache
Define THREAD_NUMBER 5
<VirtualHost ${IP_ADDR}:${TCP_PORT}>
ServerName ${SRV_NAME}
ServerAdmin bofh@tetalab.org
DocumentRoot ${ROOT_DIR}
WSGIDaemonProcess ${DAEMON_PROCESS} user=${APACHE_USER} group=${APACHE_GROUP} threads=${THREAD_NUMBER}
WSGIScriptAlias / ${WSGI_ALIAS}
<Directory ${ROOT_DIR}>
WSGIProcessGroup ${DAEMON_PROCESS}
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
AllowOverride All
Require all granted
</Directory>
ErrorLog /var/log/httpd/${SRV_NAME}.error.log
CustomLog /var/log/httpd/${SRV_NAME}.access.log combined
</VirtualHost>

Näytä tiedosto

@ -0,0 +1,19 @@
function register() {
var mail = document.getElementById('reg_mail').value;
var password = document.getElementById('reg_password').value;
var confirm = document.getElementById('reg_confirm').value;
var regEmail = new RegExp('^[0-9a-z._-]+@{1}[0-9a-z.-]{2,}[.]{1}[a-z]{2,5}$','i');
if (password.length < 8){
alert("Le mot de passe doit avoir une longueur d'au moins 8 caractères");
return false;
}
if (password != confirm){
alert("Confirmation mot de passe incohérente");
return false;
}
if (! regEmail.test(mail)){
alert("Adresse email invalide");
return false;
}
return true;
}

Näytä tiedosto

@ -14,8 +14,6 @@
--text-color: #555555;
--white: #FFFFFF;
--black: #000000;
--font-normal: url("/static/fonts/RobotoCondensed-Regular.ttf") format("truetype");
--font-bold: url("/static/fonts/RobotoCondensed-Bold.ttf") format("truetype");
--banner-logo: url(/static/images/logo.png);
--add_icon: url(/static/images/add.png);
--edit_icon: url(/static/images/edit.png);

Näytä tiedosto

@ -6,15 +6,15 @@
*/
@font-face {
font-family: "Roboto Condensed";
font-style: normal;
font-weight: 400;
src: var(--font-normal);
font-family: 'Roboto Condensed';
font-style: normal;
font-weight: 400;
src: url(/static/fonts/RobotoCondensed-Regular.ttf) format('truetype');
}
@font-face {
font-family: "Roboto Condensed";
font-style: normal;
font-weight: 700;
src: var(--font-bold);
font-family: 'Roboto Condensed';
font-style: normal;
font-weight: 700;
src: url(/static/fonts/RobotoCondensed-Bold.ttf) format('truetype');
}

Näytä tiedosto

@ -0,0 +1,5 @@
main > article > p.note {
color: var(--text-color);
display: block;
font-size: 12px;
}

Näytä tiedosto

@ -7,13 +7,13 @@
*/
* {
box-sizing: border-box;
box-sizing: border-box;
}
body {
margin: 10px;
font-family: "Roboto Condensed";
background-color: var(--dark-bg);
font-family: 'Roboto Condensed';
background-color: var(--dark-bg);
}
div.content {
@ -224,8 +224,8 @@ footer {
color: var(--white);
}
input[type="text"],
input[type="password"],
input[type='text'],
input[type='password'],
textarea,
select,
pre {
@ -235,7 +235,7 @@ pre {
background-color: var(--white);
color: var(--text-color);
padding: 5px;
font-family: "Roboto Condensed";
font-family: 'Roboto Condensed';
margin: 5px;
}
@ -244,8 +244,8 @@ pre {
}
button,
input[type="button"],
input[type="submit"] {
input[type='button'],
input[type='submit'] {
border-color: var(--dark-border);
border-style: solid;
border-width: 1px;
@ -253,15 +253,15 @@ input[type="submit"] {
color: var(--white);
font-weight: bold;
padding: 5px;
font-family: "Roboto Condensed";
font-family: 'Roboto Condensed';
margin: 5px;
border-radius: 4px;
}
button:hover,
input[type="button"]:hover,
input[type="submit"]:hover,
input[type="file"]:hover {
input[type='button']:hover,
input[type='submit']:hover,
input[type='file']:hover {
background-color: var(--light-coloured-bg);
color: var(--text-color);
cursor: pointer;
@ -280,7 +280,7 @@ div.file_upload {
border-color: var(--clear-bg);
}
input[type="file"] {
input[type='file'] {
position: absolute;
width: 18px;
height: 18px;
@ -368,3 +368,17 @@ input.upload {
background-repeat: no-repeat;
background-position: center center;
}
form {
width: 350px;
text-align: center;
line-height: 40px;
}
form > label {
float: left;
}
form > input[type='text'], form > input[type='password'] {
float: right;
}

28
templates/account.html Normal file
Näytä tiedosto

@ -0,0 +1,28 @@
{% extends "index.html" %}
{% block title %}Articles{% endblock %}
{% block main %}
<article>
<h3>Informations personnelles</h3>
<p>
Merci de bien vouloir remplir vos informations personnelles afin que l'équipe d'organisation
du THSF puisse rester en contact avec vous avant et tout au long de l'évènement.
</p>
<p>
Notez que:
<ul>
<li>Votre adresse mail doit être valide et consultée régulièrement si vous ne voulez pas manquez des informations importantes telels que les dates de réunions de staff</li>
<li>Votre numéro de téléphone nous permettra de vous contacter pendant l'évènement</li>
<li>Si vous avez un régime alimentaire particulier (intolérences, veganisme, religieux), merci de le préciser dans le champs prévu à cet effet</li>
<li>Aucune des données que vous nous transmettrez ne sera fournie à un tiers</li>
</ul>
</p>
<form method='POST' action='/account'>
<label>Adresse email: </label><input id='login' name='login' type='text' /><br/>
<label>Prénom ou pseudo: </label><input id='pseudo' name='pseudo' type='text' /><br/>
<label>Nouveau mot de passe: </label><input id='password' name='password' type='password' /><br/>
<label>Répetez mot de passe: </label><input id='confirm' name='confirm' type='password' /><br/>
<label>Numéro de téléphone: </label><input id='phone' name='phone' type='text' /><br/>
<label>Régime alimentaire: </label><input id='diet' name='diet' type='text' /><br/>
<input type='submit' value='Update' onclick='javascript:return update_account();'>
</article>
{% endblock %}

Näytä tiedosto

@ -2,7 +2,7 @@
{% block title %}Articles{% endblock %}
{% block main %}
<article>
<h3>Choose your article</h3>
<h3>Informations personnelles</h3>
<p>
Please select your article
</p>

Näytä tiedosto

@ -1,19 +1,21 @@
<!DOCTYPE html>
<html lang='zxx'>
<head>
<title>TetaWebApp - {% block title %}Accueil{% endblock %}</title>
<title>We Make THSF - {% block title %}Accueil{% endblock %}</title>
<meta name="viewport" content="initial-scale=1.0" />
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="/static/styles/colors.css" />
<link rel="stylesheet" type="text/css" href="/static/styles/fonts.css" />
<link rel="stylesheet" type="text/css" href="/static/styles/tetawebapp.css" />
<link rel="stylesheet" type="text/css" href="/static/styles/participate.css" />
<link rel="icon" type="image/png" href="/static/images/favicon.png" />
<script src="/static/scripts/tetawebapp.js"></script>
<script src="/static/scripts/participate.js"></script>
</head>
{% block bodyheader %}
<body>
{% endblock %}
<header>{% block banner %}TetaWebApp{% endblock %}</header>
<header>{% block banner %}We Make THSF{% endblock %}</header>
<div class='content'>
{% block nav %}
<nav class='vertical'>
@ -46,54 +48,32 @@
{% endif %}
{% block main %}
<article class='right'>
<h3>TetaWebApp demo</h3>
{% if message != '' %}
<pre>{{ message }}</pre>
{% endif %}
<h3>We Make THSF</h3>
<p>
Welcome to the <strong>TetaWebApp</strong> demo
Comme chaque année le <a href='https://www.thsf.net>'>Toulouse Hacker Space Factory</a> aura lieu à
<a href='http://mixart-myrys.org'>Mix'Art Myrys</a>.
</p>
<p>
TetaWebApp is a basic web application template based on <a href='http://flask.pocoo.org/'>Python/Flask</a>
and <a href='https://www.w3schools.com/js/js_ajax_intro.asp'>AJAX</a> made by
<a href='mailto:doug.letough@free.fr'>Doug Le Tough</a> from <a href='https://www.tetalab.org'>Tetalab</a>.
Ce festival ne pourrait pas avoir lieu sans votre implication et cette année encore votre aide est la bienvenue et nous
est précieuse.
</p>
<p>
The goal of this project is to provide a basic framework to make any web application you need while
letting you complete freedom on how to use or extend it <strong>without</strong> using any Google,
Bootstrap or any other piece of <strong>shitty free spyware</strong>.
</p>
TetaWebApp will <strong>never</strong> download or upload anything in any way.
<p>
</p>
<p>There is <strong>no</strong> limitation, you can use all or only parts of <strong>TetaWebApp</strong>
and you can <strong title='bullshit inside'>virtually</strong> do any app you want with TetaWebApp.
</p>
<p>
But be sure that freedom has a cost: You <strong>will</strong> need work to make it work ;-)
</p>
<p>
<strong>TetaWebApp</strong> is released under the only real <strong>free</strong> license: The
<a href='http://www.wtfpl.net/'><img src='http://www.wtfpl.net/wp-content/uploads/2012/12/wtfpl-badge-2.png'
title='WTFPL' alt='WTFPL' /></a>.
</p>
<pre>
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
</pre>
<p>
Get a copy of <strong>TetaWebApp</strong>:<br/>
<pre>
git clone git://git.tetalab.org/tetalab/tetawebapp
</pre>
Ce site vous permettra:
<ul>
<li>
de vous enregistrer afin de faire partie du "Staff", cette équipe de super-héros sans qui le THSF ne
saurait être un moment agréable, sûr et convivial.
</li>
<li>
de sélectionner le poste et les créneaux horaires pendant lesquels vous souhaitez vous rendre disponible.
</li>
<li>
d'être tenu informé des évolutions de l'organisation et du déroulement du THSF via la mailing list du staff.
</li>
</ul>
</p>
</article>
{% endblock %}

Näytä tiedosto

@ -4,11 +4,6 @@
{% block main %}
<article class='login'>
<h3>Login</h3>
<p>The demo login is:</p>
<ul>
<li>Login: demo</li>
<li>Password: demo</li>
</ul>
</article>
{% if message != '' %}
<pre>{{ message }}</pre>

Näytä tiedosto

@ -0,0 +1,70 @@
{% extends "index.html" %}
{% block title %}Login{% endblock %}
{% block nav %}{% endblock %}
{% block main %}
<article class='left'>
<h3>We Make THSF</h3>
<p>
Comme chaque année le <a href='https://www.thsf.net>'>Toulouse Hacker Space Factory</a> aura lieu à
<a href='http://mixart-myrys.org'>Mix'Art Myrys</a>.
</p>
<p>
Ce festival ne pourrait pas avoir lieu sans votre implication et cette année encore votre aide est la bienvenue et nous
est précieuse.
</p>
<p>
Ce site vous permettra:
<ul>
<li>
de vous enregistrer afin de faire partie du "Staff", cette équipe de super-héros sans qui le THSF ne
saurait être un moment agréable, sûr et convivial.
</li>
<li>
de sélectionner le poste et les créneaux horaires pendant lesquels vous souhaitez vous rendre disponible.
</li>
<li>
d'être tenu informé des évolutions de l'organisation et du déroulement du THSF via la mailing list du staff.
</li>
</ul>
</p>
<p>
Nul besoin de compétences particulières pour rejoindre notre équipe sinon votre meilleure volonté et votre bonne humeur
qui feront du THSF un moment unique de partage.
</p>
<p>
Pour vous enregistrer, munissez vous de votre adresse email et renseignez les champs de la section "<strong>Inscription</strong>".
</p>
<p>
Si vous vous être préalablement enregistré, renseignez uniquement les champs de la section "<strong>Connexion</strong>"
</p>
<p class='note'>Aucun électron n'a été maltraité lors de la mise au point de ce site.
Par ailleurs ce site n'utilise ni ressources hébergées par des tiers, ni bullshitwares, ni trackers.</p>
</article>
{% if message != '' %}
<pre>{{ message }}</pre>
{% endif %}
<hr/>
<article class='login'>
<h3>Connexion</h3>
</article>
<article class='left'>
<form method='POST' action='/login'>
<label>Adresse mail: </label><input id='login' name='login' type='text' /><br/>
<label>Mot de passe: </label><input id='password' name='password' type='password' /><br/>
<input type='submit' value='Log me in' onclick='javascript:return verify_login();'>
</form>
</article>
<hr/>
<article class='login'>
<h3>Inscription</h3>
</article>
<article class='left'>
<form method='POST' action='/register'>
<label>Adresse mail: </label><input id='reg_mail' name='login' type='text' /><br/>
<label>Mot de passe (8 char min.): </label><input id='reg_password' name='password' type='password' /><br/>
<label>Confirmation: </label><input id='reg_confirm' name='confirm' type='password' /><br/>
<input type='submit' value='Register me NOW !' onclick='javascript:return register();'>
</form>
</article>
<hr/>
{% endblock %}

19
templates/register.html Normal file
Näytä tiedosto

@ -0,0 +1,19 @@
{% extends "index.html" %}
{% block title %}Register{% endblock %}
{% block nav %}{% endblock %}
{% block main %}
<article class='login'>
<h3>Register</h3>
</article>
{% if message != '' %}
<pre>{{ message }}</pre>
{% endif %}
<article class='left'>
<form method='POST' action='/login'>
Login: <input id='login' name='login' type='text' />
Password: <input id='password' name='password' type='password' />
Confirm: <input id='password' name='password' type='password' />
<input type='submit' value='Register me NOW !' onclick='javascript:return register();'>
</form>
</article>
{% endblock %}

Näytä tiedosto

@ -1,48 +1,68 @@
\echo ******************************
\echo * Dropping database tetawebapp
\echo * Dropping database participer_thsf
\echo ******************************
\c postgres;
drop database tetawebapp;
drop database participer_thsf;
\echo **************************
\echo * Dropping role tetawebapp
\echo * Dropping role participer_thsf
\echo **************************
drop role tetawebapp;
drop role participer_thsf;
\echo ***************************************************
\echo * Creating role tetawebapp with password tetawebapp
\echo * Creating role participer_thsf with password participer_thsf
\echo ***************************************************
create role tetawebapp with LOGIN ENCRYPTED PASSWORD 'tetawebapp';
create role participer_thsf with LOGIN ENCRYPTED PASSWORD 'participer_thsf';
\echo ******************************
\echo * Creating database tetawebapp
\echo * Creating database participer_thsf
\echo ******************************
create database tetawebapp;
create database participer_thsf;
\echo *******************************************
\echo * Giving tetawebapp ownership to tetawebapp
\echo * Giving participer_thsf ownership to participer_thsf
\echo *******************************************
alter database tetawebapp owner to tetawebapp;
alter database participer_thsf owner to participer_thsf;
\echo *********************************
\echo * Creating tetawebapp_users table
\echo * Creating participer_thsf_users table
\echo *********************************
\c tetawebapp;
CREATE TABLE tetawebapp_users (
\c participer_thsf;
CREATE TABLE participer_thsf_users (
id serial primary key,
mail text not NULL,
password text not NULL,
name text not NULL
name text,
phone text,
diet text
);
CREATE TABLE participer_thsf_roles (
id serial primary key,
role text not NULL,
description text not NULL
);
\echo *************************************************
\echo * Giving tetawebapp_users ownership to tetawebapp
\echo * Giving participer_thsf_users ownership to participer_thsf
\echo *************************************************
alter table tetawebapp_users owner to tetawebapp;
alter table participer_thsf_users owner to participer_thsf;
\echo *********************************************************************
\echo * Inserting user demo identified by password demo to tetawebapp_users
\echo * Inserting user demo identified by password demo to participer_thsf_users
\echo *********************************************************************
insert into tetawebapp_users (mail, password, name) values ('demo', '$2b$12$yjv4QMctGJFj2HmmbF6u5uDq9ATIl/Y9Z96MbaqRrcG6AE0CGHKSS', 'demo');
insert into participer_thsf_users (mail, password, name) values ('demo', '$2b$12$yjv4QMctGJFj2HmmbF6u5uDq9ATIl/Y9Z96MbaqRrcG6AE0CGHKSS', 'demo');
\echo *********************************************************************
\echo * Inserting roles to participer_thsf_roles
\echo *********************************************************************
insert into participer_thsf_roles (role, description) values ('Préparation/Installation/signalétique', 'Fermeture des zones inaccessibles au public|Prépa buvette : allumage tireuses et frigos 4h avant ouverture + approvisionnement des bars en produits destinés à la vente|Préparation des différents postes / stands selon besoins : PLN, billetterie, T-Shirts...|Prépa toilettes public : aspiration/pompage, nettoyage à grandes eaux, remplissage du produit, changement poubelles, approvisionnement PQ|Nettoyage lieu, réapprovisionnement poubelles aux endroits stratégiques');
insert into participer_thsf_roles (role, description) values ('Volante', 'veille à la sécurité du lieu : rondes, surveillance accès, gestion de crises, messager, remplaçant, etc... (collaboration avec référent staff)|Ramassage verre, check PQ, ménage ponctuel|Sur le dernier créneau horaire, nettoyage de deux blocs WC|Au moins une personne connaissant bien Myrys sur chaque créneau horaire');
insert into participer_thsf_roles (role, description) values ('P.L.N', 'Accueil public, explication du concept de PLN, tampons (si besoin)|Informer et guider le public (prog, espaces, toilettes,...)|Comptage du public');
insert into participer_thsf_roles (role, description) values ('Buvette','Service au bar et encaissement (caisse ou tickets boisson selon besoins)|Nettoyage régulier : bar, tireuses, cendriers, verres abandonnés...');
insert into participer_thsf_roles (role, description) values ('Billeterie','Vente de tickets boisson / 1 ticket = 2,50 €|Poinçonnage des cartes VIP. 1 poinçon = 1 ticket = 1 euros|Tickets valables sur les 4 jours mais NON REMBOURSABLES');
insert into participer_thsf_roles (role, description) values ('Catering', 'Vérification de l''accès au catering (badge)|Service à l''assiette si besoin, gestion des quantités, réapprovisionnement du buffet|Maintenir la propreté des espaces catering (cuisine, buffet, tables, salle d''AG, tables extérieures, jardins)|Informer / rappeler le principe d''autogestion pour la vaisselle');
insert into participer_thsf_roles (role, description) values ('Ménage', 'Nettoyage général à la fermeture du lieu : ramasser verres / déchets / cendriers, sortir poubelles, cleaner surfaces (bar, stand,...) + balai');