1
0
forked from ScoDoc/ScoDoc

fix migration adresses + cosmetique

This commit is contained in:
Emmanuel Viennet 2021-09-11 15:59:06 +02:00
parent 4b2d5f01a4
commit badf83cc7f
14 changed files with 80 additions and 65 deletions

View File

@ -148,9 +148,15 @@ Mémo pour développeurs: séquence re-création d'une base:
flask import-scodoc7-users flask import-scodoc7-users
flask import-scodoc7-dept STID SCOSTID flask import-scodoc7-dept STID SCOSTID
Si la base utilisée pour les dev n'est plus en phase avec les scripts de
migration, utiliser les commandes `flask db history`et `flask db stamp`pour se
positionner à la bonne étape.
# Paquet debian 11 # Paquet debian 11
Les scripts associés au paquet Debian (.deb) sont dans `tools/debian`. Les scripts associés au paquet Debian (.deb) sont dans `tools/debian`. Le plus
important est `postinst`qui se charge de configurer le système (install ou
upgrade de scodoc9).
La préparation d'une release se fait à l'aide du script La préparation d'une release se fait à l'aide du script
`tools/build_release.sh`. `tools/build_release.sh`.

View File

@ -32,7 +32,7 @@ db = SQLAlchemy()
migrate = Migrate(compare_type=True) migrate = Migrate(compare_type=True)
login = LoginManager() login = LoginManager()
login.login_view = "auth.login" login.login_view = "auth.login"
login.login_message = "Please log in to access this page." login.login_message = "Identifiez-vous pour accéder à cette page."
mail = Mail() mail = Mail()
bootstrap = Bootstrap() bootstrap = Bootstrap()
moment = Moment() moment = Moment()

View File

@ -16,20 +16,20 @@ _l = _
class LoginForm(FlaskForm): class LoginForm(FlaskForm):
user_name = StringField(_l("Username"), validators=[DataRequired()]) user_name = StringField(_l("Nom d'utilisateur"), validators=[DataRequired()])
password = PasswordField(_l("Password"), validators=[DataRequired()]) password = PasswordField(_l("Mot de passe"), validators=[DataRequired()])
remember_me = BooleanField(_l("Remember Me")) remember_me = BooleanField(_l("mémoriser la connexion"))
submit = SubmitField(_l("Sign In")) submit = SubmitField(_l("Suivant"))
class UserCreationForm(FlaskForm): class UserCreationForm(FlaskForm):
user_name = StringField(_l("Username"), validators=[DataRequired()]) user_name = StringField(_l("Nom d'utilisateur"), validators=[DataRequired()])
email = StringField(_l("Email"), validators=[DataRequired(), Email()]) email = StringField(_l("Email"), validators=[DataRequired(), Email()])
password = PasswordField(_l("Password"), validators=[DataRequired()]) password = PasswordField(_l("Mot de passe"), validators=[DataRequired()])
password2 = PasswordField( password2 = PasswordField(
_l("Repeat Password"), validators=[DataRequired(), EqualTo("password")] _l("Répéter"), validators=[DataRequired(), EqualTo("password")]
) )
submit = SubmitField(_l("Register")) submit = SubmitField(_l("Inscrire"))
def validate_user_name(self, user_name): def validate_user_name(self, user_name):
user = User.query.filter_by(user_name=user_name.data).first() user = User.query.filter_by(user_name=user_name.data).first()
@ -48,9 +48,9 @@ class ResetPasswordRequestForm(FlaskForm):
class ResetPasswordForm(FlaskForm): class ResetPasswordForm(FlaskForm):
password = PasswordField(_l("Password"), validators=[DataRequired()]) password = PasswordField(_l("Mot de passe"), validators=[DataRequired()])
password2 = PasswordField( password2 = PasswordField(
_l("Repeat Password"), validators=[DataRequired(), EqualTo("password")] _l("Répéter"), validators=[DataRequired(), EqualTo("password")]
) )
submit = SubmitField(_l("Request Password Reset")) submit = SubmitField(_l("Request Password Reset"))

View File

@ -38,7 +38,7 @@ def login():
user = User.query.filter_by(user_name=form.user_name.data).first() user = User.query.filter_by(user_name=form.user_name.data).first()
if user is None or not user.check_password(form.password.data): if user is None or not user.check_password(form.password.data):
current_app.logger.info("login: invalid (%s)", form.user_name.data) current_app.logger.info("login: invalid (%s)", form.user_name.data)
flash(_("Invalid user name or password")) flash(_("Nom ou mot de passe invalide"))
return redirect(url_for("auth.login")) return redirect(url_for("auth.login"))
login_user(user, remember=form.remember_me.data) login_user(user, remember=form.remember_me.data)
current_app.logger.info("login: success (%s)", form.user_name.data) current_app.logger.info("login: success (%s)", form.user_name.data)
@ -95,7 +95,7 @@ def reset_password_request():
current_app.logger.info( current_app.logger.info(
"reset_password_request: for unkown user '{}'".format(form.email.data) "reset_password_request: for unkown user '{}'".format(form.email.data)
) )
flash(_("Check your email for the instructions to reset your password")) flash(_("Voir les instructions enoyez par mail"))
return redirect(url_for("auth.login")) return redirect(url_for("auth.login"))
return render_template( return render_template(
"auth/reset_password_request.html", title=_("Reset Password"), form=form "auth/reset_password_request.html", title=_("Reset Password"), form=form

View File

@ -152,10 +152,10 @@ def sidebar():
# Logo # Logo
H.append( H.append(
f"""<div class="logo-insidebar"> f"""<div class="logo-insidebar">
<div class="sidebar-bottom"><a href="{ url_for( 'scolar.about', scodoc_dept=g.scodoc_dept ) }" class="sidebar">À propos</a><br/> <div class="sidebar-bottom"><a href="{ url_for( 'scodoc.about', scodoc_dept=g.scodoc_dept ) }" class="sidebar">À propos</a><br/>
<a href="{ scu.SCO_USER_MANUAL }" target="_blank" class="sidebar">Aide</a> <a href="{ scu.SCO_USER_MANUAL }" target="_blank" class="sidebar">Aide</a>
</div></div> </div></div>
<div class="logo-logo"><a href= { url_for( 'scolar.about', scodoc_dept=g.scodoc_dept ) } <div class="logo-logo"><a href= { url_for( 'scodoc.about', scodoc_dept=g.scodoc_dept ) }
">{ scu.icontag("scologo_img", no_size=True) }</a> ">{ scu.icontag("scologo_img", no_size=True) }</a>
</div> </div>
</div> </div>

View File

@ -258,6 +258,7 @@ def user_info(user_name_or_id=None, user=None):
info = u.to_dict() info = u.to_dict()
else: else:
info = None info = None
user_name = "inconnu"
else: else:
info = user.to_dict() info = user.to_dict()
user_name = user.user_name user_name = user.user_name

View File

@ -2614,7 +2614,8 @@ div.maindiv {
margin: 1em; margin: 1em;
} }
ul.main { ul.main {
list-style-type: square; list-style-type: square;
margin-top: 1em;
} }
ul.main li { ul.main li {

25
app/templates/about.html Normal file
View File

@ -0,0 +1,25 @@
{% extends 'base.html' %}
{% import 'bootstrap/wtf.html' as wtf %}
{% block app_content %}
<h2>Système de gestion scolarité</h2>
<p>&copy; Emmanuel Viennet 2021</p>
<p>Version {{ version }}</p>
<p>ScoDoc est un logiciel libre écrit en
<a href="http://www.python.org" target="_blank" rel="noopener noreferrer">Python</a>.
Information et documentation sur <a href="https://scodoc.org" target="_blank">scodoc.org</a>.
</p>
<h2>Dernières évolutions</h2>
{{ news|safe }}
<div class="about-logo">
{{ logo|safe }}
</div>
{% endblock %}

View File

@ -2,14 +2,19 @@
{% import 'bootstrap/wtf.html' as wtf %} {% import 'bootstrap/wtf.html' as wtf %}
{% block app_content %} {% block app_content %}
<h1>Sign In</h1> <h1>Connexion</h1>
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-md-4">
{{ wtf.quick_form(form) }} {{ wtf.quick_form(form) }}
</div> </div>
</div> </div>
<br> <br>
Forgot Your Password? En cas d'oubli de votre mot de passe
<a href="{{ url_for('auth.reset_password_request') }}">Click to Reset It</a> <a href="{{ url_for('auth.reset_password_request') }}">cliquez ici pour le réinitialiser</a>.
</p> </p>
<p class="help">L'accès à ScoDoc est strictement réservé aux personnels de
l'établissement. Les étudiants n'y ont pas accès. Pour toute information,
contactez la personne responsable de votre établissement.</p>
{% endblock %} {% endblock %}

View File

@ -2,7 +2,7 @@
{% import 'bootstrap/wtf.html' as wtf %} {% import 'bootstrap/wtf.html' as wtf %}
{% block app_content %} {% block app_content %}
<h2>ScoDoc: gestion scolarité (version béta)</h2> <h2>ScoDoc 9 - suivi scolarité</h2>
{% if not current_user.is_anonymous %} {% if not current_user.is_anonymous %}
<p>Bonjour <font color="red"><b>{{current_user.get_nomcomplet()}}</b> <p>Bonjour <font color="red"><b>{{current_user.get_nomcomplet()}}</b>
@ -24,10 +24,6 @@
{% endfor %} {% endfor %}
</ul> </ul>
<p>
<font color="red">Ceci est une version de test,
ne pas utiliser en production !</font>
</p>
{% if current_user.is_authenticated %} {% if current_user.is_authenticated %}
<form action="{{url_for('scodoc.table_etud_in_accessible_depts')}}" method="POST"> <form action="{{url_for('scodoc.table_etud_in_accessible_depts')}}" method="POST">
@ -43,4 +39,9 @@
<p><a href="/ScoDoc/static/mobile">Charger la version mobile (expérimentale)</a></p> <p><a href="/ScoDoc/static/mobile">Charger la version mobile (expérimentale)</a></p>
</div> --> </div> -->
<div style="margin-top: 1cm;">
Service réservé aux personnels et enseignants, basé sur <a href="{{url_for('scodoc.about')}}">le logiciel libre
ScoDoc.</a>
</div>
{% endblock %} {% endblock %}

View File

@ -131,6 +131,18 @@ def get_etud_dept():
return Departement.query.get(last_etud.dept_id).acronym return Departement.query.get(last_etud.dept_id).acronym
@bp.route("/ScoDoc/about")
@bp.route("/ScoDoc/Scolarite/<scodoc_dept>/about")
def about(scodoc_dept=None):
"version info"
return render_template(
"about.html",
version=scu.get_scodoc_version(),
news=sco_version.SCONEWS,
logo=scu.icontag("borgne_img"),
)
# ---- CONFIGURATION # ---- CONFIGURATION

View File

@ -131,34 +131,6 @@ def sco_publish(route, function, permission, methods=["GET"]):
# -------------------------------------------------------------------- # --------------------------------------------------------------------
@bp.route("/about")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func
def about():
"version info"
H = [
"""<h2>Système de gestion scolarité</h2>
<p>&copy; Emmanuel Viennet 1997-2021</p>
<p>Version %s</p>
"""
% (scu.get_scodoc_version())
]
H.append(
'<p>Logiciel libre écrit en <a href="http://www.python.org" target="_blank" rel="noopener noreferrer">Python</a>.</p>'
)
H.append("<h2>Dernières évolutions</h2>" + sco_version.SCONEWS)
H.append(
'<div class="about-logo">'
+ scu.icontag("borgne_img")
+ " <em>Au pays des aveugles...</em></div>"
)
d = ""
return (
html_sco_header.sco_header() + "\n".join(H) + d + html_sco_header.sco_footer()
)
# -------------------------------------------------------------------- # --------------------------------------------------------------------
# #
# PREFERENCES # PREFERENCES
@ -311,15 +283,6 @@ def showEtudLog(etudid, format="html", REQUEST=None):
# ---------- PAGE ACCUEIL (listes) -------------- # ---------- PAGE ACCUEIL (listes) --------------
# @bp.route("/")
@bp.route("/kimo")
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func
def kimo(REQUEST=None, showcodes=0, showsemtable=0):
import time
return f"{time.time()} := {g.scodoc_dept}"
@bp.route("/") @bp.route("/")

View File

@ -1,14 +1,14 @@
# -*- mode: python -*- # -*- mode: python -*-
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
SCOVERSION = "9.0.13" SCOVERSION = "9.0.14"
SCONAME = "ScoDoc" SCONAME = "ScoDoc"
SCONEWS = """ SCONEWS = """
<h4>Année 2021</h4> <h4>Année 2021</h4>
<ul> <ul>
<li>ScoDoc 9: nouvelle architecture logicielle</li> <li>ScoDoc 9: nouvelle architecture logicielle (Flask/Python3/Debian 11)</li>
<li>Version mobile (en test)</li> <li>Version mobile (en test)</li>
<li>Évaluations de type "deuxième session"</li> <li>Évaluations de type "deuxième session"</li>
<li>Gestion du genre neutre (pas d'affichage de la civilité)</li> <li>Gestion du genre neutre (pas d'affichage de la civilité)</li>

View File

@ -380,6 +380,7 @@ def convert_object(
"absences", "absences",
"absences_notifications", "absences_notifications",
"itemsuivi", # etudid n'était pas une clé "itemsuivi", # etudid n'était pas une clé
"adresse", # etudid n'était pas une clé
}: }:
# tables avec "fausses" clés # tables avec "fausses" clés
# (l'object référencé a pu disparaitre) # (l'object référencé a pu disparaitre)