page accueil ScoDoc8 (prototype)

This commit is contained in:
Emmanuel Viennet 2021-07-04 12:32:13 +02:00
parent ac7cd6a99c
commit c9310d358e
10 changed files with 195 additions and 41 deletions

View File

@ -72,11 +72,16 @@ def create_app(config_class=Config):
app.register_blueprint(essais_bp, url_prefix="/Essais") app.register_blueprint(essais_bp, url_prefix="/Essais")
from app.main import bp as main_bp
from app.views import scodoc_bp
from app.views import scolar_bp from app.views import scolar_bp
from app.views import notes_bp from app.views import notes_bp
from app.views import users_bp from app.views import users_bp
from app.views import absences_bp from app.views import absences_bp
app.register_blueprint(main_bp) # XXX à enlever en production #sco8
# https://scodoc.fr/ScoDoc
app.register_blueprint(scodoc_bp)
# https://scodoc.fr/ScoDoc/RT/Scolarite/... # https://scodoc.fr/ScoDoc/RT/Scolarite/...
app.register_blueprint(scolar_bp, url_prefix="/ScoDoc/<scodoc_dept>/Scolarite") app.register_blueprint(scolar_bp, url_prefix="/ScoDoc/<scodoc_dept>/Scolarite")
# https://scodoc.fr/ScoDoc/RT/Scolarite/Notes/... # https://scodoc.fr/ScoDoc/RT/Scolarite/Notes/...
@ -88,10 +93,6 @@ def create_app(config_class=Config):
absences_bp, url_prefix="/ScoDoc/<scodoc_dept>/Scolarite/Absences" absences_bp, url_prefix="/ScoDoc/<scodoc_dept>/Scolarite/Absences"
) )
from app.main import bp as main_bp
app.register_blueprint(main_bp)
if not app.debug and not app.testing: if not app.debug and not app.testing:
if app.config["MAIL_SERVER"]: if app.config["MAIL_SERVER"]:
auth = None auth = None

View File

@ -13,6 +13,7 @@ from time import time
from flask import current_app, url_for, g from flask import current_app, url_for, g
from flask_login import UserMixin, AnonymousUserMixin from flask_login import UserMixin, AnonymousUserMixin
from werkzeug.security import generate_password_hash, check_password_hash from werkzeug.security import generate_password_hash, check_password_hash
import jwt import jwt
@ -54,6 +55,8 @@ class User(UserMixin, db.Model):
self.roles = [] self.roles = []
self.user_roles = [] self.user_roles = []
super(User, self).__init__(**kwargs) super(User, self).__init__(**kwargs)
self._format_noms()
# Ajoute roles:
if ( if (
not self.roles not self.roles
and self.email and self.email
@ -127,6 +130,13 @@ class User(UserMixin, db.Model):
"prenom": (self.prenom or "").encode("utf-8"), # sco8 "prenom": (self.prenom or "").encode("utf-8"), # sco8
"roles_string": self.get_roles_string(), # eg "Ens_RT, Ens_Info" "roles_string": self.get_roles_string(), # eg "Ens_RT, Ens_Info"
"user_name": self.user_name.encode("utf-8"), # sco8 "user_name": self.user_name.encode("utf-8"), # sco8
# Les champs calculés:
"nom_fmt": self.get_nom_fmt(),
"prenom_fmt": self.get_prenom_fmt(),
"nomprenom": self.get_nomprenom(),
"prenomnom": self.get_prenomnom(),
"nomplogin": self.get_nomplogin(),
"nomcomplet": self.get_nomcomplet(),
} }
if include_email: if include_email:
data["email"] = self.email or "" data["email"] = self.email or ""
@ -151,6 +161,7 @@ class User(UserMixin, db.Model):
for r_d in data["roles_string"].split(","): for r_d in data["roles_string"].split(","):
role, dept = UserRole.role_dept_from_string(r_d) role, dept = UserRole.role_dept_from_string(r_d)
self.add_role(role, dept) self.add_role(role, dept)
self._format_noms()
def get_token(self, expires_in=3600): def get_token(self, expires_in=3600):
now = datetime.utcnow() now = datetime.utcnow()
@ -252,6 +263,35 @@ class User(UserMixin, db.Model):
else: else:
return None return None
def get_nom_fmt(self):
"""Nom formatté: "Martin" """
if self.nom:
return sco_etud.format_nom(self.nom, uppercase=False)
else:
return self.user_name
def get_prenom_fmt(self):
"""Prénom formaté (minuscule capitalisées)"""
return sco_etud.format_prenom(self.prenom)
def get_nomprenom(self):
"""Nom capitalisé suivi de l'initiale du prénom:
Viennet E.
"""
prenom_abbrv = scu.abbrev_prenom(sco_etud.format_prenom(self.prenom))
return (self.get_nom_fmt() + " " + prenom_abbrv).strip()
def get_prenomnom(self):
"""L'initiale du prénom suivie du nom: "J.-C. Dupont" """
prenom_abbrv = scu.abbrev_prenom(sco_etud.format_prenom(self.prenom))
return (prenom_abbrv + " " + self.get_nom_fmt()).strip()
def get_nomcomplet(self):
"Prénom et nom complets"
return sco_etud.format_prenom(self.prenom) + " " + self.get_nom_fmt()
# nomnoacc était le nom en minuscules sans accents (inutile)
class AnonymousUser(AnonymousUserMixin): class AnonymousUser(AnonymousUserMixin):
def has_permission(self, perm, dept=None): def has_permission(self, perm, dept=None):

View File

@ -1,4 +1,36 @@
# -*- coding: UTF-8 -* # -*- mode: python -*-
# -*- coding: utf-8 -*-
##############################################################################
#
# ScoDoc
#
# Copyright (c) 1999 - 2021 Emmanuel Viennet. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Emmanuel Viennet emmanuel.viennet@viennet.net
#
##############################################################################
"""
Module main: essais divers
Emmanuel Viennet, 2021
"""
import pprint import pprint
from pprint import pprint as pp from pprint import pprint as pp
import functools import functools
@ -10,11 +42,19 @@ import flask
from flask import request, render_template, redirect from flask import request, render_template, redirect
from flask_login import login_required from flask_login import login_required
from app.main import bp from app.main import bp
from app.decorators import scodoc7func, admin_required from app.decorators import scodoc7func, admin_required
from app.scodoc import VERSION
context = None context = None # temporaire pour #sco8
# -------------------------------------------------------------
#
# ESSAIS DIVERS pour #sco8
#
# -------------------------------------------------------------
@bp.route("/") @bp.route("/")

View File

@ -285,7 +285,7 @@ def user_info(user_name=None, user=None):
"nom_fmt": user_name, "nom_fmt": user_name,
"nomcomplet": user_name, "nomcomplet": user_name,
"nomplogin": user_name, "nomplogin": user_name,
"nomnoacc": scu.suppress_accents(user_name), # "nomnoacc": scu.suppress_accents(user_name),
"passwd_temp": 0, "passwd_temp": 0,
"status": "", "status": "",
"date_expiration": None, "date_expiration": None,
@ -294,31 +294,6 @@ def user_info(user_name=None, user=None):
# Ensure we never publish password hash # Ensure we never publish password hash
if "password_hash" in info: if "password_hash" in info:
del info["password_hash"] del info["password_hash"]
#
p = format_prenom(info["prenom"])
if info["nom"]:
n = format_nom(
info["nom"], uppercase=False
) # strcapitalize(strlower(info['nom']))
else:
n = user_name
prenom_abbrv = scu.abbrev_prenom(p)
# nomprenom est le nom capitalisé suivi de l'initiale du prénom
info["nomprenom"] = (n + " " + prenom_abbrv).strip()
# prenomnom est l'initiale du prénom suivie du nom
info["prenomnom"] = (prenom_abbrv + " " + n).strip()
# nom_fmt et prenom_fmt: minuscule capitalisé
info["nom_fmt"] = n
info["prenom_fmt"] = sco_etud.format_prenom(p)
# nomcomplet est le prenom et le nom complets
info["nomcomplet"] = info["prenom_fmt"] + " " + info["nom_fmt"]
# nomplogin est le nom en majuscules suivi du prénom et du login
# e.g. Dupont Pierre (dupont)
info["nomplogin"] = "%s %s (%s)" % (scu.strupper(n), p, info["user_name"])
# nomnoacc est le nom en minuscules sans accents
info["nomnoacc"] = scu.suppress_accents(scu.strlower(info["nom"]))
return info return info

View File

@ -1,5 +1,10 @@
{% extends 'bootstrap/base.html' %} {% extends 'bootstrap/base.html' %}
{% block styles %}
{{super()}}
<link rel="stylesheet" href="/ScoDoc/static/css/scodoc.css">
{% endblock %}
{% block title %} {% block title %}
{% if title %}{{ title }} - ScoDoc{% else %}Welcome to ScoDoc{% endif %} {% if title %}{{ title }} - ScoDoc{% else %}Welcome to ScoDoc{% endif %}
{% endblock %} {% endblock %}
@ -15,7 +20,7 @@
<span class="icon-bar"></span> <span class="icon-bar"></span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
</button> </button>
<a class="navbar-brand" href="{{ url_for('main.index') }}">ScoDoc</a> <a class="navbar-brand" href="{{ url_for('scodoc.index') }}">ScoDoc</a>
</div> </div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">

View File

@ -2,9 +2,17 @@
{% import 'bootstrap/wtf.html' as wtf %} {% import 'bootstrap/wtf.html' as wtf %}
{% block app_content %} {% block app_content %}
<h1>Prototype ScoDoc 8: accueil</h1>
<div class="row"> <div class="row">
<h2>Avec login requis</h2>
<h2>Prototype ScoDoc 8</h2>
<div style="font-size: 140%">=> <a href="{{url_for('scodoc.index')}}">Page d'accueil ScoDoc 8</a></div>
<h2>Essais divers</h2>
<h3>Avec login requis</h3>
<ul> <ul>
<li><a href="{{ url_for('main.test_vue') }}"><tt>test_vue</tt>, login requis</a></li> <li><a href="{{ url_for('main.test_vue') }}"><tt>test_vue</tt>, login requis</a></li>
<li><a href="{{ url_for('main.a_zope_function', y=22) }}">a_zope_function</a> : affichage objets "Zope"</li> <li><a href="{{ url_for('main.a_zope_function', y=22) }}">a_zope_function</a> : affichage objets "Zope"</li>
@ -12,7 +20,7 @@
<tt>x=11, y=22</tt> <tt>x=11, y=22</tt>
</li> </li>
</ul> </ul>
<h2>Sans login</h2> <h3>Sans login</h3>
<ul> <ul>
<li><a href="{{ url_for('main.a_zope_form_get') }}"><tt>a_zope_form_get</tt></a> : formulaire GET ala ScoDoc non <li><a href="{{ url_for('main.a_zope_form_get') }}"><tt>a_zope_form_get</tt></a> : formulaire GET ala ScoDoc non
protégé renvoyant vers une page protégée</li> protégé renvoyant vers une page protégée</li>
@ -29,12 +37,12 @@
ScoImplement dans RT ScoImplement dans RT
</li> </li>
</ul> </ul>
<h2>Essais décorateurs et appels</h2> <h3>Essais décorateurs et appels</h3>
<ul> <ul>
<li><a href="{{ url_for('essais.sco_exemple', scodoc_dept='RT') }}">sco_exemple</a></li> <li><a href="{{ url_for('essais.sco_exemple', scodoc_dept='RT') }}">sco_exemple</a></li>
</ul> </ul>
<h2>Config</h2> <h3>Config</h3>
<div> <div>
<tt>static_url_path={{current_app.static_url_path}}</tt><br /> <tt>static_url_path={{current_app.static_url_path}}</tt><br />
<tt>static_folder={{current_app.static_folder}}</tt> <tt>static_folder={{current_app.static_folder}}</tt>

31
app/templates/scodoc.html Normal file
View File

@ -0,0 +1,31 @@
{% extends 'base.html' %}
{% import 'bootstrap/wtf.html' as wtf %}
{% block app_content %}
<h2>ScoDoc: gestion scolarité</h2>
<p>Bonjour <font color="red"><b>{{current_user.get_nomcomplet()}}</b></font>.</p>
<p>N'oubliez pas de vous <a href="{{url_for('auth.logout')}}">déconnecter</a> après usage.</p>
<ul class="main">
{% for dept in dept_ids %}
<li>
<a class="stdlink {{'link_accessible' if current_user.has_permission(Permission.ScoView, dept=dept) else 'link_unauthorized'}}"
href="{{url_for('scolar.index_html', scodoc_dept=dept)}}">Département
{{dept}}</a>
</li>
{% endfor %}
</ul>
<form action="table_etud_in_accessible_depts" method="POST">
<b>Chercher étudiant:</b>
<input type="text" name="expnom" width="12" spellcheck="false" value="">
<input type="submit" value="Chercher">
<br />(entrer une partie du nom ou le code NIP, cherche dans tous les départements autorisés)
</form>
<div style="margin-top: 1cm; font-size: 120%;">
<p><a href="/ScoDoc/static/mobile">Version mobile (expérimentale, à vos risques et périls)</a></p>
</div>
{% endblock %}

View File

@ -3,12 +3,13 @@
""" """
from flask import Blueprint from flask import Blueprint
scodoc_bp = Blueprint("scodoc", __name__)
scolar_bp = Blueprint("scolar", __name__) scolar_bp = Blueprint("scolar", __name__)
notes_bp = Blueprint("notes", __name__) notes_bp = Blueprint("notes", __name__)
users_bp = Blueprint("users", __name__) users_bp = Blueprint("users", __name__)
absences_bp = Blueprint("absences", __name__) absences_bp = Blueprint("absences", __name__)
essais_bp = Blueprint("essais", __name__) essais_bp = Blueprint("essais", __name__)
from app.views import notes, scolar, absences, users, essais from app.views import scodoc, notes, scolar, absences, users, essais
scolar.context.Notes = notes.context # XXX transitoire #sco8 scolar.context.Notes = notes.context # XXX transitoire #sco8

54
app/views/scodoc.py Normal file
View File

@ -0,0 +1,54 @@
# -*- mode: python -*-
# -*- coding: utf-8 -*-
##############################################################################
#
# ScoDoc
#
# Copyright (c) 1999 - 2021 Emmanuel Viennet. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Emmanuel Viennet emmanuel.viennet@viennet.net
#
##############################################################################
"""
Module main: page d'accueil, avec liste des départements
Emmanuel Viennet, 2021
"""
import flask
from flask import request, render_template, redirect
from flask_login import login_required
from app.views import scodoc_bp as bp
from scodoc_manager import sco_mgr
from app.scodoc import VERSION
from app.scodoc.sco_permissions import Permission
@bp.route("/ScoDoc")
@bp.route("/ScoDoc/index")
def index():
dept_ids = sco_mgr.get_dept_ids()
return render_template(
"scodoc.html",
title=VERSION.SCONAME,
current_app=flask.current_app,
dept_ids=dept_ids,
Permission=Permission,
)

View File

@ -92,7 +92,6 @@ class FakeUsers(object):
"nom_fmt": user_name, "nom_fmt": user_name,
"nomcomplet": user_name, "nomcomplet": user_name,
"nomplogin": user_name, "nomplogin": user_name,
"nomnoacc": user_name,
"passwd_temp": 0, "passwd_temp": 0,
"status": "", "status": "",
"date_expiration": None, "date_expiration": None,