Files
aem_monespace/monaem/views/default.py
2023-06-22 10:26:17 +02:00

1149 lines
41 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf8 -*-
import re
from pyramid.response import Response,FileResponse
from pyramid.renderers import render, get_renderer
from pyramid.view import (
view_config,
forbidden_view_config,
)
from pyramid.security import (
remember,
forget,
)
from pyramid.httpexceptions import (
HTTPFound,
)
from ..security import groupfinder
from pyramid_mailer import get_mailer
from pyramid_mailer.message import Message, Attachment
from datetime import *
from dateutil.relativedelta import relativedelta
from email.utils import formataddr
from docutils.core import publish_parts
from time import strftime
from user_agents import parse
from markdown2 import Markdown
import math
import os.path
import subprocess
import pkg_resources
import tempfile
import transaction
import hashlib
import hmac
import json
from PIL import Image
import shutil
import locale
from datetime import datetime
import magic
from ..models.default import *
from ..models.reservation import *
def to_age(dob, type):
today = date.today()
age = relativedelta(today, dob)
if type == '>':
if age.years >= 0:
a = '%s ans %s mois' % (age.years, age.months)
else:
a = '???'
else:
if age.years < 0 or age.years < 0:
if age.years <= -1:
a = '%sa %sm' % (age.years, age.months)
else:
a = '%sm' % (age.months)
else:
a = ''
return a.replace('-', '')
def to_decimal(x):
import decimal
return decimal.Decimal(str(x))
def to_sha1(message):
return hashlib.sha1(message.encode('utf-8')).hexdigest()
def to_int(x):
try:
number = int(x.replace(',', '.'))
return number
except ValueError:
return 0
def to_euro(x):
"""Takes a float and returns 12 345,67 €"""
locale.setlocale(locale.LC_ALL, '')
return locale.currency(x, True, True)
def to_euroz(x):
"""Takes a float and returns 12 345,67 € if non zero"""
if x == 0:
return ""
else:
return to_euro(x)
def to_percent(x):
"""Takes a float and returns a string"""
return (u"%.2f " % x).replace('.', ',') + "%"
def to_date(date_text):
try:
madate = datetime.strptime(date_text, '%d/%m/%Y')
if madate.year >= 1900:
return madate
else:
return False
except ValueError:
return False
def to_time(date_text):
try:
madate = datetime.strptime(date_text, '%H:%M')
return madate
except ValueError:
return False
def isMinor(dob):
today = date.today()
age = relativedelta(today, dob)
if age.years < 18:
minor = True
else:
minor = False
return minor
def toSemaine(strDate):
chaine = strDate.replace(' Feb', ' Fév')
chaine = chaine.replace(' Mar', ' Mars')
chaine = chaine.replace(' Apr', ' Avr')
chaine = chaine.replace(' May', ' Mai')
chaine = chaine.replace(' Jun', ' Juin')
chaine = chaine.replace(' Jul', ' Juil')
chaine = chaine.replace(' Aug', ' Août')
chaine = chaine.replace(' Dec', ' Déc')
chaine = chaine.replace('Mon', 'Lun')
chaine = chaine.replace('Tue', 'Mar')
chaine = chaine.replace('Wed', 'Mer')
chaine = chaine.replace('Thu', 'Jeu')
chaine = chaine.replace('Fri', 'Ven')
chaine = chaine.replace('Sat', 'Sam')
chaine = chaine.replace('Sun', 'Dim')
return chaine
# - - - - - - - - - - - - - - - - - - - - - - - - - -
def envoyerMail(request, destinataires, objet, corps):
# lire l'adresse email de l'agence
logged_in = request.authenticated_userid
if logged_in is None:
# user anonyme
agence_email = request.registry.settings['monaem.admin_email']
else:
# user connecté, lire son numéro d'agence
agence = get_eleve_agence(request, logged_in)
agence_email = agence.email if agence else request.registry.settings['monaem.admin_email']
message = Message(subject=u"[MARIETTON] %s" % objet,
sender=agence_email,
recipients=destinataires,
html=corps)
mailer = get_mailer(request)
mailer.send_immediately(message, fail_silently=True)
@view_config(route_name='affiche_message', renderer='../templates/default/affiche_message.pt')
def affiche_message(request):
login = request.matchdict['login']
messages = request.session.pop_flash()
return {
'page_title': "Demande effectuée",
'login': login,
'messages': messages,
'url_identification': request.route_url('login_as', login=login)
}
@view_config(route_name='agence', renderer='../templates/default/agence.pt', permission='view')
def agence(request):
"""Mon agence"""
logged_in = request.authenticated_userid
# get agence
item = get_eleve_agence(request, logged_in)
return {
'page_title': "Mon agence MARIETTON",
'item': item,
}
@view_config(route_name='change_details', renderer='../templates/default/change_details.pt', permission='view')
def change_details(request):
url = request.route_url('change_details')
logged_in = request.authenticated_userid
member = get_eleves_by_code(request, logged_in)
if 'form.submitted' in request.params:
new_values = {}
for param, db_value in member.items():
if param in request.params and request.params[param] != db_value:
new_values[param] = request.params[param]
if new_values:
update_details(request, logged_in, new_values)
request.session.flash(u"Vos coordonnées ont été mises à jour avec succès.", 'success')
# si élève appartient à une agence
if member.AGENCE > 0:
# envoyer un message à la secrétaire
body = getMessageText(request, 'changeCoord', member.NOMPREN, logged_in, '', '', '')
agence_email = get_eleve_agence(request, logged_in).email
destinataires = [agence_email]
envoyerMail(request, destinataires, "Changement de coordonnées", body)
return HTTPFound(location=request.route_url('home'))
return {
'page_title': "Changer mes coordonnées",
'url': url,
'member': member,
}
@view_config(route_name='change_password', renderer='../templates/default/change_password.pt', permission='view')
def change_password(request):
url = request.route_url('change_password')
logged_in = request.authenticated_userid
message = ''
member = get_eleves_by_code(request, logged_in)
if 'form.submitted' in request.params:
old_password = request.params['old_password']
new_password = request.params['new_password1']
new_password2 = request.params['new_password2']
if len(new_password) >= 8 and len(new_password) <= 20:
if re.match(r'^(?=.*\d)(?=.*[!@#$%^&*\_\-\.\+,;\:\\/§à\]\[\?\{\}])(?=.*[a-z])(?=.*[A-Z])[0-9a-zA-Z!@#$%^&*\_\-\.\+,;\:\\/§à\]\[\?\{\}]{8,}$',new_password):
if new_password == new_password2 :
if member.mdp_hash == to_sha1(old_password):
update_password(request, logged_in, new_password)
request.session.flash(u"Votre mot de passe a été mis à jour avec succès.", 'success')
return HTTPFound(location=request.route_url('home'))
else:
message = "Le mot de passe fourni est incorrect."
else:
message = "Le mot de passe et sa confirmation ne sont pas identiques."
else:
message = "Le mot de passe doit contenir au minimum une lettre, un nombre,un majuscule, un minuscle, et un caractère speciaux."
else:
message = "La longueur du mot de passe n'est pas respectée, minimum 8, maximum 20."
return {
'page_title': "Changer mon mot de passe",
'url': url,
'member': member,
'message': message,
}
@view_config(route_name='date_examen', renderer='../templates/default/date_examen.pt', permission='view')
def date_examen(request):
""" Date examen view """
logged_in = request.authenticated_userid
item = get_date_examen(request, logged_in)
return {
'page_title': "Prochaine date d'examen",
'item': item,
}
@view_config(route_name='email_password', renderer='../templates/default/email_password.pt')
def email_password(request):
url = request.route_url('email_password')
message = ''
login = ''
date_naissance = ''
if 'form.submitted' in request.params:
login = request.params['login']
date_naissance = request.params['date_naissance']
member = get_eleves_by_date_nais(request, login, date_naissance)
if member:
if member.email:
lien = update_membre_mdp_oublie(request, login)
# Fabrication du corps du Message
body = getMessageText(request, 'emailPassword', member.NOMPREN, lien, '', '', '')
destinataires = [member.email]
envoyerMail(request, destinataires, "Oubli de mot de passe", body)
request.session.flash(
u"Le lien permettant de redéfinir votre mot de passe vous a été envoyé à l'adresse : %s." % member.email,
'success')
return HTTPFound(location=request.route_url('affiche_message', login=login))
else:
message = "L'adresse e-mail de cet élève n'est pas renseignée. Contactez votre agence."
else:
message = "Aucun élève trouvé avec ce code et cette date de naissance. Veuillez réessayer."
return {
'page_title': "Mot de passe oublié ?",
'url': url,
'message': message,
'login': login,
'date_naissance': date_naissance,
}
@view_config(route_name='email_code', renderer='../templates/default/email_code.pt')
def email_code(request):
url = request.route_url('email_code')
message = ''
if 'form.submitted' in request.params:
name = request.params['name']
forname = request.params['forname']
birthday = request.params['birthday']
member = get_eleves_by_name_date_nais(request, name, forname, birthday)
if not member:
message = "Aucun utilisateur trouvé avec ce nom, prenom et cette date de naissance. Veuillez réessayer."
else:
# a member has been found
if member.email:
# Fabrication du corps du Message
body = getMessageText(request, 'emailCode', member.NOMPREN, member.CD_CLI, '', '', '')
destinataires = [member.email]
envoyerMail(request, destinataires, "Oubli de code élève", body)
request.session.flash(u"Votre code élève vous a été envoyé à l'adresse : %s." % member.email)
return HTTPFound(location=request.route_url('affiche_message', login=member.CD_CLI))
else:
message = "L'adresse e-mail de ce compte n'est pas renseignée. Veuillez contacter votre agence."
return {
'page_title': "Code élève oublié ?",
'url': url,
'message': message,
}
@view_config(route_name='stages_reservation', renderer='../templates/default/stages_reservation.pt', permission='view')
def stages_reservation(request):
std = {
'POINT' : {
'title' : "RECUPERATION DE POINTS",
'link' : 2763
},
'PEM125' : {
'title' : "PRISE EN MAIN 125",
'link' : 2765
},
'PASSERELLE' : {
'title' : 'PASSERELLE A2 à A',
'link' : 2766
},
'B96' : {
'title':'B96',
'link' : 2786
}
}
logged_in = request.authenticated_userid
url = request.route_url('stages_reservation')
eleve = get_eleves_by_code(request, logged_in)
permis = eleve.PERMIS_DEMANDE
stages = get_stages_by_type(request, eleve.FORMULE,None,15)
if 'form.submitted' in request.params:
params = dict(request.params)
cd_cli = logged_in
new_stage = get_stage_by_id(request, params['stage_id'])
if new_stage.dispo <= 0:
request.session.flash(u"Ce stage nest plus disponible", 'danger')
return HTTPFound(location=request.route_url('stages_reserves'))
else:
debut_stage = ins_stage_eleve(request, eleve.FORMULE, new_stage.stage_id, cd_cli, eleve.NOM, eleve.PRENOM)
if debut_stage != None:
# si déjà inscrit, retourne aux dispo
request.session.flash(u"Vous êtes déjà inscrit(e) au stage du %s." % debut_stage.strftime("%d-%m-%Y"), 'danger')
else:
nompren = "%s %s %s" % (eleve.CIVILITE, eleve.NOM, eleve.PRENOM)
body = getConfirmText(request, eleve.FORMULE, nompren, cd_cli,
'%s au %s à %s' % (new_stage.debut.strftime("%d-%m-%Y"), new_stage.fin.strftime("%d-%m-%Y"), new_stage.debut.strftime("%Hh%M")),
new_stage.lieu1, new_stage.lieu2)
# envoyer un message à l'élève et la secrétaire
agence_email = get_eleve_agence(request, cd_cli).email
destinataires = [eleve.email, agence_email,]
envoyerMail(request, destinataires, "Votre réservation pour le stage de %s" %std[eleve.FORMULE]['title'], body)
request.session.flash(u"Vous avez réservé votre date de stage le %s à %s " % (new_stage.debut.date().strftime("%d-%m-%Y"), new_stage.fin.strftime("%d-%m-%Y")), 'success')
return HTTPFound(location=request.route_url('home'))
return {
'eleve': eleve,
'message': "",
'link': std[eleve.FORMULE]['link'],
'stages': stages,
'url': url,
'page_title': "Mon espace",
}
@view_config(route_name='stages_dates', renderer='../templates/default/stages_dates.pt', permission='view')
def stages_dates(request):
logged_in = request.authenticated_userid
url = request.route_url('stages_dates')
eleve = get_eleves_by_code(request, logged_in)
items = get_eleve_stage(request, logged_in)
permis = eleve.PERMIS_DEMANDE
std = {
'POINT' : {
'title' : "RECUPERATION DE POINTS",
'link' : 2763
},
'PEM125' : {
'title' : "PRISE EN MAIN 125",
'link' : 2765
},
'PASSERELLE' : {
'title' : 'PASSERELLE A2 à A',
'link' : 2766
},
'B96' : {
'title':'B96',
'link' : 2786
}
}
diff = False
nbdaysbefore_stage = 15
stages = []
if items:
stage = items[0]
debut_en_clair = 'Il commence le %s.' % stage.debut_en_clair
lieu_stage = 'VAUGNERAY'
if permis[:1] == 'A': # and stage.date_debut < datetime(2016,11,20):
debut_en_clair = ''
if eleve.FORMULE == 'POINT':
if stage.groupe == 'A':
lieu_stage = 'CHARPENNES'
stage_startdate = datetime.strptime(str(stage.stage_debut), '%d-%m-%Y').date()
datenow = datetime.now().date()
nbdaysbefore_stage = stage_startdate - datenow
if stage.debut_en_clair:
diff = nbdaysbefore_stage.days > 1 and eleve.FORMULE in ['B96', 'PEM125', 'PASSERELLE', 'POINT']
else:
stage = items
debut_en_clair = ''
lieu_stage = ''
stages = get_stages_by_type(request, eleve.FORMULE,stage_startdate.strftime('%Y-%m-%d'),nbdaysbefore_stage.days)
if 'form.submitted' in request.params:
params = dict(request.params)
cd_cli = logged_in
new_stage = get_stage_by_id(request, params['stage_id'])
if items:
stage = items[0]
else:
stage = items
diffdate = new_stage.debut.date() - datetime.strptime(str(stage.stage_debut), '%d-%m-%Y').date()
if diffdate.days == 0:
request.session.flash(u"Vous êtes déjà inscrit(e) au stage du %s." % stage.stage_debut, 'danger')
return HTTPFound(location=request.route_url('stages_dates'))
else:
stage_ligne = dict(get_stage_ligne_by_cd_cli(request, cd_cli, stage.groupe))
# Delete stage_ligne
query = """ CALL spDel_PLA_STAGE_LIGNES(:type,:semaine,:groupe,:cd_cli)"""
request.dbsession.execute(query, {'type': stage_ligne['TYPE'], 'semaine': stage_ligne['SEMAINE'], 'groupe': stage_ligne['GROUPE'], "cd_cli": stage_ligne['CD_CLI']})
debut_stage = ins_stage_eleve(request, eleve.FORMULE, new_stage.stage_id, cd_cli, eleve.NOM, eleve.PRENOM)
if debut_stage != None:
# si déjà inscrit, retourne aux dispo
request.session.flash(u"Vous êtes déjà inscrit(e) au stage du %s." % debut_stage.strftime("%d-%m-%Y"), 'danger')
else:
nompren = "%s %s %s" % (eleve.CIVILITE, eleve.NOM, eleve.PRENOM)
body = getConfirmText(request, eleve.FORMULE, nompren, cd_cli,
'%s au %s à %s' % (new_stage.debut.strftime("%d-%m-%Y"), new_stage.fin.strftime("%d-%m-%Y"), new_stage.debut.strftime("%Hh%M")),
new_stage.lieu1, new_stage.lieu2)
# envoyer un message à l'élève et la secrétaire
agence_email = get_eleve_agence(request, cd_cli).email
destinataires = [eleve.email, agence_email,]
envoyerMail(request, destinataires, "Votre réservation pour le stage de %s" %std[eleve.FORMULE]['title'], body)
request.session.flash(u"Vous avez modifié votre date de stage le %s à %s " % (new_stage.debut.date().strftime("%d-%m-%Y"), new_stage.fin.strftime("%d-%m-%Y")), 'success')
return HTTPFound(location=request.route_url('home'))
return {
'eleve': eleve,
'message': "",
'debut_en_clair': debut_en_clair,
'stage': stage,
'lieu_stage': lieu_stage,
'link': std[eleve.FORMULE]['link'],
'stages': stages,
'url': url,
'diff': diff,
'page_title': "Mon espace",
}
@view_config(route_name='home', renderer='../templates/default/home.pt', permission='view')
def home(request):
"""Home view"""
logged_in = request.authenticated_userid
url = request.route_url('home')
eleve = get_eleves_by_code(request, logged_in)
permis = eleve.PERMIS_DEMANDE
suivi_list = ['B', 'B78', 'A1', 'A2', 'POINT', 'AL', 'A','AM']
if permis in suivi_list:
hasSuivi = True
else:
hasSuivi = False
# lire le carnet de rendez-vous
nb_rdv = len(get_rdv_by_code(request, logged_in))
# lire les justifs
justifs = get_eleve_docs(request, logged_in, 'JUST')
docs = get_eleve_docs(request, logged_in, 'DOC')
diff = False
items = get_eleve_stage(request, logged_in)
if items:
stage = items[0]
debut_en_clair = 'Il commence le %s.' % stage.debut_en_clair
lieu_stage = 'VAUGNERAY'
if permis[:1] == 'A': # and stage.date_debut < datetime(2016,11,20):
debut_en_clair = ''
if eleve.FORMULE == 'POINT':
if stage.groupe == 'A':
lieu_stage = 'CHARPENNES'
if stage['type'] == 'B':
if stage['groupe'] == 'J':
lieu_stage = 'VAISE'
elif stage['groupe'] == 'K' :
lieu_stage = 'CHARPENNES'
elif stage['groupe'] == 'L' :
lieu_stage = "PRESQUILE"
if stage.debut_en_clair:
startedDateStage = datetime.strptime(str(stage.stage_debut), '%d-%m-%Y').date()
dateNow = datetime.now().date()
diffDate = startedDateStage - dateNow
diff = diffDate.days > 1 and eleve.FORMULE in ['B96', 'PEM125', 'PASSERELLE', 'POINT']
else:
stage = items
debut_en_clair = ''
lieu_stage = ''
examen = get_date_examen(request, logged_in)
# lire le compte
items = get_eleve_cpt_extrait(request, logged_in)
# calculer le solde de l'élève
sum_to_pay = 0
sum_paid = 0
for item in items:
sum_to_pay += float(item.DEBIT)
sum_paid += float(item.CREDIT)
solde = sum_to_pay - eleve.encours_societe - sum_paid
# get date de fin code
dates = get_dates_fin_validite(request, logged_in)
if dates:
date_fin_code = dates[0].date_fin_code
date_fin_vm = dates[0].date_fin_vm
else:
date_fin_code = None
date_fin_vm = None
# Lire toutes les FAQS sauf les 'INTERNE'
faqs = get_faqs(request, -1)
# calcul des clés élève
d = date.today()
# calculer le jour de l'année d'auj
yearday = (d - date(d.year, 1, 1)).days + 1
keyE = int(yearday * d.year / d.day * eleve.CD_CLI)
param_suivi = 'codeE=%s&key=%s&En=%s&MnR=%s&filiere=%s&agence=%s&permis=%s&formule=%s' % (
str(eleve.CD_CLI), keyE, eleve.NOMPREN, eleve.CD_MON, eleve.filiere, eleve.AGENCE, eleve.PERMIS_DEMANDE,
eleve.FORMULE)
suivi_pedago_list = ['CE', 'C', 'D', 'DE', 'BE', 'BEPCA', 'C1', 'D1', 'GL', 'B96']
if permis in suivi_pedago_list:
hasOutilPedago = True
else:
hasOutilPedago = False
return {
'page_title': "Mon espace",
'nb_rdv': nb_rdv,
'stage': stage,
'examen': examen,
'faqs': faqs,
'eleve': eleve,
'reservation' : eleve.FORMULE in ['B96', 'PEM125', 'PASSERELLE', 'POINT'],
'today': strftime("%d/%m/%Y"),
'solde': solde,
'remain_to_pay': to_euro(solde * -1),
'date_fin_code': date_fin_code,
'date_fin_vm': date_fin_vm,
'has_email': bool(eleve.email),
'debut_en_clair': debut_en_clair,
'lieu_stage': lieu_stage,
'hasSuivi': hasSuivi,
'justifs': justifs,
'docs': docs,
'param_suivi': param_suivi,
'hasOutilPedago': hasOutilPedago,
'diff': diff,
'logged_in': str(logged_in)
}
@view_config(route_name='fiche_inscription', renderer='../templates/default/fiche_inscription.pt', permission='view')
def fiche_inscription(request):
""" Fiche inscription view """
logged_in = request.authenticated_userid
eleve = get_eleves_by_code(request, logged_in)
return {
'page_title': "Fiche d'inscription",
'item': eleve,
}
@view_config(route_name='login', renderer='../templates/default/login.pt', permission='view')
@view_config(route_name='login_as', renderer='../templates/default/login.pt', permission='view')
@forbidden_view_config(renderer='../templates/default/login.pt')
def login(request):
current_route_path = request.current_route_path()
if 'login_as' in current_route_path:
login = request.matchdict['login']
login_url = request.route_url('login_as', login=login)
else:
login = ''
login_url = request.route_url('login')
referrer = request.url
if referrer == login_url:
referrer = '/' # never use the login form itself as came_from
came_from = request.params.get('came_from', referrer)
message = ''
password = ''
if 'form.submitted' in request.params:
login = request.params['login']
password = request.params['password']
record = get_eleves_by_code(request, login)
if record:
# controler que la fiche n'est pas cloturee
if record.STATUT < 10:
# On encode le password pour ne plus avoir de plantage avec les "é"
if (record.mdp_hash == to_sha1(password)):
# get user agent string from request
ua_string = request.user_agent
user_agent = parse(ua_string)
device = str(user_agent).split('/')
update_last_connection(request, login, device[0])
# force le commit car il ne se fait pas automatiquement après l'update
transaction.commit()
headers = remember(request, login)
return HTTPFound(location=came_from, headers=headers)
else:
message = "Le code élève ou le mot de passe est incorrect. Identification échouée."
else:
message = "Votre espace client a été clôturé. Accès refusé."
else:
message = "Le code élève ou le mot de passe est incorrect. Identification échouée."
return {
'page_title': "Se connecter",
'message': message,
'url': login_url,
'came_from': came_from,
'login': login,
'password': password,
}
@view_config(route_name='logout')
def logout(request):
headers = forget(request)
request.session.flash(u"Vous avez bien été déconnecté.", 'success')
return HTTPFound(location=request.route_url('login', login=''),
headers=headers)
@view_config(route_name='connecter_a', permission='manage')
def connecter_a(request):
# paramètre fourni ?
login = request.matchdict["login"]
if len(login) > 0:
request.session.invalidate()
headers = forget(request)
headers = remember(request, login)
return HTTPFound(location="/", headers=headers)
else:
return HTTPFound(location="/")
@view_config(route_name='redefinir_mdp', renderer='..//templates/default/redefinir_mdp.pt')
def redefinir_mdp(request):
lien = request.matchdict["lien"]
# tester si le champ "motdepasse_oublie" est encore valide
message = ''
if is_lien_mdp_oublie(request, lien) == True:
membre = get_mdp_oublie_infos(request, lien)
if 'form.submitted' in request.params:
new_password = request.params['new_password1']
if len(new_password) >= 8 and len(new_password) <= 20:
if re.match(r'^(?=.*\d)(?=.*[!@#$%^&*\_\-\.\+,;\:\\/§à\]\[\?\{\}])(?=.*[a-z])(?=.*[A-Z])[0-9a-zA-Z!@#$%^&*\_\-\.\+,;\:\\/§à\]\[\?\{\}]{8,}$',new_password):
new_password2 = request.params['new_password2']
if new_password == new_password2 :
update_password(request, membre.CD_CLI, new_password)
request.session.flash(u"Votre mot de passe a été mis à jour avec succès.", 'success')
return HTTPFound(location=request.route_url('login'))
else:
message = "Le mot de passe et sa confirmation ne sont pas identiques."
else:
message = "Le mot de passe doit contenir au minimum une lettre, un nombre,un majuscule, un minuscle, et un caractère speciaux."
else:
message = "La longueur du mot de passe n'est pas respectée, minimum 8, maximum 20."
else:
return HTTPFound(location=request.route_url('login'))
return {
'page_title': "Redéfinir le mot de passe",
'message': message,
}
@view_config(route_name='show_iframe', renderer='../templates/default/show_iframe.pt', permission='view')
def show_iframe(request):
param = request.matchdict['param']
logged_in = request.authenticated_userid
eleve = get_eleves_by_code(request, logged_in)
if param == 'suivi':
# calcul des clés élève
d = date.today()
# calculer le jour de l'année d'auj
yearday = (d - date(d.year, 1, 1)).days + 1
keyE = int(yearday * d.year / d.day * eleve.CD_CLI)
param = 'codeE=%s&key=%s&En=%s&MnR=%s&filiere=%s&agence=%s&permis=%s&formule=%s' % (
str(eleve.CD_CLI), keyE, eleve.NOMPREN, eleve.CD_MON, eleve.filiere, eleve.AGENCE, eleve.PERMIS_DEMANDE,
eleve.FORMULE)
iframe_src = "https://www.suivi-eleve.marietton.com/suivi.php?%s" % param
else:
# videos pédagogiques
param = 'codeE=%s&filiere=%s&agence=%s' % (str(eleve.CD_CLI), eleve.filiere, eleve.AGENCE)
iframe_src = "https://suivi-eleve.marietton.com/contenu-pedago/index.php?%s" % param
return {
'page_title': "",
'iframe_src': iframe_src,
}
@view_config(route_name='faq_view', renderer='../templates/default/faq_view.pt')
def faq_view(request):
faq_id = request.matchdict['faq_id']
faq = get_faqs(request, faq_id)
intitule = faq.intitule
# insèrer le path de static/img
img_path = 'image:: %s/static/img/' % request.application_url
texte = faq.texte.replace('image:: static/img/', img_path)
# convertir reST en HTML
texte = publish_parts(texte, writer_name='html')['html_body']
return {
'page_title': intitule,
'texte': texte,
'faq_id': faq_id,
}
@view_config(route_name='member_search', renderer='../templates/default/member_search.pt', permission='manage')
def member_search(request):
url = request.route_url('member_search')
message = ''
members = []
name = ''
if 'form.submitted' in request.params:
name = request.params['name']
members = get_eleves_by_name(request, name)
if len(members) == 0:
message = "Elève non trouvé : %s" % name
return {
'page_title': "Rechercher un élève",
'url': url,
'message': message,
'members': members,
'name': name,
}
@view_config(route_name='ajax_dept_nais')
def ajax_dept_nais(request):
recherche = request.GET['recherche']
# lire les departements commencant par
items = get_departements(request, recherche)
liste = []
for row in items:
d = row.libelle + " | " + row.code
liste.append(d)
return Response(json.dumps(liste))
@view_config(route_name='ajax_codepostal')
def ajax_codepostal(request):
recherche = request.GET['recherche']
# lire les codes postaux commencant par
items = get_codespostaux(request, recherche)
liste = []
for row in items:
d = row.code_postal + " - " + row.libelle
liste.append(d)
return Response(json.dumps(liste))
def getMessageText(request, ref, nomEleve, codeEleve, dateRDV, Lieu1RDV, Lieu2RDV):
if ref == 'emailPassword':
body = """
<p>Bonjour %s,</p>
<p>Vous avez oublié votre mot de passe. Par mesure de sécurité, nous vous demandons de bien vouloir le réinitialiser en cliquant sur ce lien :</p>
<p>%s</p>
<p>Ce lien ne sera valable que pendant 48 heures.</p>
""" % (nomEleve, request.route_url('redefinir_mdp', lien=codeEleve))
elif ref == 'emailCode':
body = """
<p>Bonjour %s,</p>
<p>Pour faire suite à votre demande, voici le code élève de votre compte MARIETTON : %s</p>
<p>Merci de bien vouloir le mémoriser pour une connexion ultérieure.</p>
""" % (nomEleve, codeEleve)
elif ref == 'annuleRDV':
body = """
<p>Bonjour,</p>
<p>L'élève : %s (%s), </p>
<p>vient d'<b>annuler son rendez-vous %s du planning %s</b>.</p>
<p>%s</p>
""" % (nomEleve, codeEleve, dateRDV, Lieu1RDV, Lieu2RDV)
elif ref == 'envoiPassRousseau':
body = """
<p>Bonjour %s,</p>
<p>Léquipe Marietton vous remercie pour votre inscription.</p>
<p>Vos identifiants de connexion au site [https://www.marietton.com/salle-de-code-acces.php](https://www.marietton.com/salle-de-code-acces.php) sont les suivants :</p>
<p>votre identifiant : %s</p>
<p>votre mot de passe : %s</p>
<p>Nous vous souhaitons à présent une agréable formation.</p>""" % (nomEleve, codeEleve, Lieu1RDV, Lieu2RDV)
elif ref == 'dispoPassRousseau':
body = """
<p>Bonjour %s,</p>
<p>Léquipe Marietton vous remercie pour votre inscription.</p>
<p>Nous vous invitons à contacter communication@marietton.com sur la disponibilité des PASS Rousseau.</p>""" % (
nomEleve)
else:
# message changeCoord
body = """
<p>Bonjour,</p>
<p>L'élève : %s (%s), </p>
<p>vient de changer ses coordonnées via son espace élève.</p>""" % (nomEleve, codeEleve)
# ajouter salutation
corps = """
%s
<p>Cordialement,<br>
<a href="https://monespace.marietton.com">Espace Client MARIETTON</a>
<p>
<p></p>""" % body
return corps
def getConfirmText(request, ref, nomEleve, codeEleve, dateRDV, lieu1RDV, lieu2RDV):
# lire le message selon la référence du tarif
body = get_messageConformation(request, ref)
# convertir confirmation de mardown en HTML
if body:
markdowner = Markdown()
body = markdowner.convert(body)
# remplacer les mots clés
body = body.replace("!civNomPrenom!", nomEleve)
body = body.replace("!codeClient!", str(codeEleve))
body = body.replace("!dateRDV!", dateRDV)
body = body.replace("!lieu1RDV!", lieu1RDV)
body = body.replace("!lieu2RDV!", lieu2RDV)
else:
body = 'Texte de confirmation non trouvé pour %s' % ref
return body
@view_config(route_name='justifs_list', renderer='../templates/default/justifs_list.pt', permission='view')
def justifs_list(request):
logged_in = request.authenticated_userid
# initialiser la liste des justifs à télécharger
init_eleve_justifs(request, logged_in)
justifs = get_eleve_docs(request, logged_in, 'JUST')
justifs_manquant = get_eleve_justifs_manquant(request, logged_in)
return {
'page_title': "Justificatifs à télécharger",
'justifs': justifs,
'justifs_manquant': justifs_manquant,
'code_add': '',
'cd_cli' : logged_in
}
def downloadFile2Temp(input_file, input_name, ext_allowed):
# récupère son extension
input_extension = input_name.split('.')[-1]
mime = magic.from_buffer(input_file.read(), mime=True)
# extensions autorisées ?
if mime not in ext_allowed:
return "ERREUR: Le format du fichier n'est pas valide. Téléchargement impossible."
# Finally write the data to a temporary file
temp_file_path = os.path.join('/tmp/', input_name)
# supprimer le fichier s'il existe déjà
if os.path.exists(temp_file_path):
os.remove(temp_file_path)
input_file.seek(0)
with open(temp_file_path, 'wb') as output_file:
shutil.copyfileobj(input_file, output_file)
# controler la taille du fichier < 4 Mo
filesize = round(os.path.getsize(temp_file_path) / 1024)
if filesize > 4096:
os.remove(temp_file_path)
return "ERREUR: La taille du fichier dépasse la limite autorisée. Téléchargement impossible."
if input_extension in ['jpeg', 'jpg', 'png']:
# using the Python Image Library (PIL) to resize an image
resize_photos(temp_file_path)
return temp_file_path
def tempFile2Dossier(request, no_ligne, cd_cli, temp_file, filename, logged_in):
# créer le répertoire du chantier
path = '%s/%s' % (request.registry.settings['monaem.justifs_dir'], cd_cli)
os.makedirs(path, exist_ok=True)
filepath = os.path.join('%s/%s' % (path, filename))
# supprimer le fichier s'il existe déjà
if os.path.exists(filepath):
os.remove(filepath)
# Finally move the temporary file to folder
shutil.move(temp_file, filepath)
filesize = round(os.path.getsize(filepath) / 1024)
new_values = {}
new_values['nom_fic'] = filename
new_values['taille_fic'] = filesize
new_values['cd_uti'] = 'WEB'
update_eleve_justif(request, no_ligne, new_values)
def resize_photos(image_file):
# using the Python Image Library (PIL) to resize an image
img_org = Image.open(image_file)
# get the size of the original image
width_org, height_org = img_org.size
# set the resizing factor so the aspect ratio can be retained
# factor > 1.0 increases size
# factor < 1.0 decreases size
factor = 0.75
width = int(width_org * factor)
height = int(height_org * factor)
# best down-sizing filter
img_anti = img_org.resize((width, height), Image.ANTIALIAS)
# split image filename into name and extension
name, ext = os.path.splitext(image_file)
# create a new file name for saving the result
img_anti.save(image_file)
return
@view_config(route_name='doc_upload', renderer='../templates/default/doc_upload.pt', permission='view')
def doc_upload(request):
logged_in = request.authenticated_userid.upper()
no_ligne = request.matchdict['no_ligne']
cd_cli = request.matchdict['cd_cli']
url = request.route_url("doc_upload", no_ligne=no_ligne, cd_cli=cd_cli)
message = ""
# lire le document à uploader
justif = get_eleve_justifs_byligne(request, no_ligne)
if justif is None:
request.session.flash(u"Le justif %s est introuvable" % (noligne), 'danger')
return HTTPFound(location=request.route_url("home", cd_cli=cd_cli))
url_retour = request.route_url('justifs_list')
if 'form.submitted' in request.params:
libelle_fic = None
if 'libelle_fic' in request.params:
new_values = {}
new_values['libelle_fic'] = request.params['libelle_fic']
new_values['cd_uti'] = 'WEB'
if 'nom_fic' in request.params:
new_values['nom_fic'] = request.params['nom_fic']
update_eleve_justif(request, no_ligne, new_values)
request.session.flash('Le e-photo est enregistré avec succès.', 'success')
if request.POST['uploadfile'] != b'':
# récupère le fichier download dans le dossier /tmp
input_file = request.POST['uploadfile'].file
input_name = request.POST['uploadfile'].filename
input_parts = input_name.split('.')
input_ext = input_parts[len(input_parts) - 1]
ext_allowed = ['image/jpeg', 'image/jpg', 'image/png', 'application/pdf']
temp_file = downloadFile2Temp(input_file, input_name, ext_allowed)
if temp_file[:8] == 'ERREUR: ':
request.session.flash(temp_file, 'danger')
return HTTPFound(location=url)
# fabriquer le nom du document
TODAY = date.today().strftime('%Y-%m-%d')
filename = '%s_%s_%s_%s.%s' % (cd_cli, justif.type, justif.code, TODAY, input_ext)
tempFile2Dossier(request, no_ligne, cd_cli, temp_file, filename, logged_in)
request.session.flash('%s : Ce fichier est téléchargé avec succès.' % input_name, 'success')
return HTTPFound(location=url_retour)
return {
'page_title': "Télécharger un document",
'url': url,
'url_retour': url_retour,
'justif': justif,
}
@view_config(route_name='doc_edit', renderer='../templates/default/doc_edit.pt', permission='view')
def doc_edit(request):
logged_in = request.authenticated_userid.upper()
no_ligne = request.matchdict['no_ligne']
cd_cli = request.matchdict['cd_cli']
url = request.route_url("doc_edit", no_ligne=no_ligne, cd_cli=cd_cli)
message = ""
# lire le document à uploader
justif = get_eleve_justifs_byligne(request, no_ligne)
if justif is None:
request.session.flash(u"Le justif %s est introuvable" % (no_ligne), 'danger')
return HTTPFound(location=request.route_url("fiche_eleve", cd_cli=cd_cli))
url_retour = request.route_url('justifs_list')
if 'form.submitted' in request.params:
new_values = {}
new_values['cd_uti'] = 'WEB'
if 'libelle_fic' in request.params:
new_values['libelle_fic'] = request.params['libelle_fic']
update_eleve_justif(request, no_ligne, new_values)
request.session.flash('Le fichier est validé avec succès.', 'success')
return HTTPFound(location=url_retour)
if 'form.erased' in request.params:
new_values = {}
new_values['cd_uti'] = 'WEB'
new_values['nom_fic'] = ''
new_values['libelle_fic'] = ''
new_values['taille_fic'] = 0
# supprimer le fichier de la pièce
file_path = '%s/%s/%s' % (request.registry.settings['monaem.justifs_dir'], cd_cli, justif.nom_fic)
if os.path.exists(file_path):
os.remove(file_path)
update_eleve_justif(request, no_ligne, new_values)
request.session.flash('Le fichier est effacé avec succès.', 'success')
return HTTPFound(location=url_retour)
if 'form.deleted' in request.params:
# supprimer le fichier de la pièce
file_path = '%s/%s/%s' % (request.registry.settings['monaem.justifs_dir'], cd_cli, justif.nom_fic)
if os.path.exists(file_path):
os.remove(file_path)
delete_eleve_justif(request, no_ligne)
request.session.flash('Le fichier est supprimé avec succès.', 'success')
return HTTPFound(location=url_retour)
return {
'page_title': "Modifier un document",
'url': url,
'url_retour': url_retour,
'justif': justif,
}
@view_config(route_name='download', renderer='', permission='view')
def download(request):
filename = request.matchdict['filename']
cd_cli = request.matchdict['cd_cli']
logged_in = request.authenticated_userid
file_path = '%s/%s/%s' % (request.registry.settings['monaem.justifs_dir'], cd_cli, filename)
if str(logged_in) != str(cd_cli) or not os.path.exists(file_path):
return Response(status=404)
else: #there is no overwrite
response = FileResponse(file_path)
response.headers['Content-Disposition'] = ("inline; filename=%s"%(filename))
return response