Formatage de tous les fichiers python (sauf migrations) avec black
This commit is contained in:
Lyanis Souidi 2024-06-05 10:23:21 +02:00
parent 1167c13787
commit d6d6899a53
Signed by: lyanis
GPG Key ID: 202150AA0DAB9FAC
29 changed files with 187 additions and 134 deletions

View File

@ -1,5 +1,6 @@
"""api.__init__
"""
from flask_json import as_json
from flask import Blueprint
from flask import request, g

View File

@ -35,9 +35,9 @@ def after_cas_login():
if user.cas_allow_login:
current_app.logger.info(f"CAS: login {user.user_name}")
if login_user(user):
flask.session[
"scodoc_cas_login_date"
] = datetime.datetime.now().isoformat()
flask.session["scodoc_cas_login_date"] = (
datetime.datetime.now().isoformat()
)
user.cas_last_login = datetime.datetime.utcnow()
if flask.session.get("CAS_EDT_ID"):
# essaie de récupérer l'edt_id s'il est présent
@ -45,8 +45,10 @@ def after_cas_login():
# via l'expression `cas_edt_id_from_xml_regexp`
# voir flask_cas.routing
edt_id = flask.session.get("CAS_EDT_ID")
current_app.logger.info(f"""after_cas_login: storing edt_id for {
user.user_name}: '{edt_id}'""")
current_app.logger.info(
f"""after_cas_login: storing edt_id for {
user.user_name}: '{edt_id}'"""
)
user.edt_id = edt_id
db.session.add(user)
db.session.commit()

View File

@ -14,6 +14,7 @@ from app.auth.models import User, is_valid_password
_ = lambda x: x # sans babel
_l = _
# See http://flask.pocoo.org/snippets/63/
def is_safe_url(target):
ref_url = urlparse(request.host_url)

View File

@ -56,16 +56,20 @@ def _get_jury_but_etud_result(
rcue_dict = {
"ue_1": {
"ue_id": rcue.ue_1.id,
"moy": None
"moy": (
None
if (dec_ue1.moy_ue is None or np.isnan(dec_ue1.moy_ue))
else dec_ue1.moy_ue,
else dec_ue1.moy_ue
),
"code": dec_ue1.code_valide,
},
"ue_2": {
"ue_id": rcue.ue_2.id,
"moy": None
"moy": (
None
if (dec_ue2.moy_ue is None or np.isnan(dec_ue2.moy_ue))
else dec_ue2.moy_ue,
else dec_ue2.moy_ue
),
"code": dec_ue2.code_valide,
},
"moy": rcue.moy_rcue,

View File

@ -345,9 +345,9 @@ def check_entreprises_import(m):
adresse=entreprise_data["adresse"],
ville=entreprise_data["ville"],
codepostal=entreprise_data["code_postal"],
pays=entreprise_data["pays"]
if entreprise_data["pays"]
else "FRANCE",
pays=(
entreprise_data["pays"] if entreprise_data["pays"] else "FRANCE"
),
visible=True,
)
entreprises_import.append(entreprise_import)

View File

@ -1,5 +1,6 @@
"""évènements scolaires dans la vie d'un étudiant(inscription, ...)
"""
from app import db
from app.models import SHORT_STR_LEN

View File

@ -3,6 +3,7 @@ Gestion de l'archivage des justificatifs
Ecrit par Matthias HARTMANN
"""
import os
from datetime import datetime
from shutil import rmtree

View File

@ -60,13 +60,15 @@ def formation_table_recap(formation_id, fmt="html") -> Response:
"_sem_order": f"{li:04d}",
"code": ue.acronyme,
"titre": ue.titre or "",
"_titre_target": url_for(
"_titre_target": (
url_for(
"notes.ue_edit",
scodoc_dept=g.scodoc_dept,
ue_id=ue.id,
)
if can_edit
else None,
else None
),
"apo": ue.code_apogee or "",
"_apo_td_attrs": f""" data-oid="{ue.id}" data-value="{ue.code_apogee or ''}" """,
"coef": ue.coefficient or "",
@ -83,19 +85,23 @@ def formation_table_recap(formation_id, fmt="html") -> Response:
# le module (ou ressource ou sae)
T.append(
{
"sem": f"S{mod.semestre_id}"
"sem": (
f"S{mod.semestre_id}"
if mod.semestre_id is not None
else "-",
else "-"
),
"_sem_order": f"{li:04d}",
"code": mod.code,
"titre": mod.abbrev or mod.titre,
"_titre_target": url_for(
"_titre_target": (
url_for(
"notes.module_edit",
scodoc_dept=g.scodoc_dept,
module_id=mod.id,
)
if can_edit
else None,
else None
),
"apo": mod.code_apogee,
"_apo_td_attrs": f""" data-oid="{mod.id}" data-value="{mod.code_apogee or ''}" """,
"coef": mod.coefficient,

View File

@ -466,9 +466,9 @@ def etud_add_group_infos(
etud['groupes'] = "TDB, Gr2, TPB1"
etud['partitionsgroupes'] = "Groupes TD:TDB, Groupes TP:Gr2 (...)"
"""
etud[
"partitions"
] = collections.OrderedDict() # partition_id : group + partition_name
etud["partitions"] = (
collections.OrderedDict()
) # partition_id : group + partition_name
if not formsemestre_id:
etud["groupes"] = ""
return etud

View File

@ -32,7 +32,7 @@ def clone_partitions_and_groups(
# Création des groupes dans les nouvelles partitions:
for newpart in sco_groups.get_partitions_list(formsemestre_id):
for (new_partition_id, list_groups) in list_groups_per_part:
for new_partition_id, list_groups in list_groups_per_part:
if newpart["partition_id"] == new_partition_id:
for group in list_groups:
new_group = sco_groups.create_group(

View File

@ -86,9 +86,11 @@ def group_rename(group_id):
"size": 12,
"allow_null": False,
"validator": lambda val, _: len(val) < GROUPNAME_STR_LEN,
"explanation": "doit être unique dans cette partition"
"explanation": (
"doit être unique dans cette partition"
if group.partition.groups_editable
else "groupes non modifiables dans cette partition",
else "groupes non modifiables dans cette partition"
),
"enabled": group.partition.groups_editable,
},
),

View File

@ -585,8 +585,8 @@ def groups_table(
etud_info["_nom_disp_order"] = etud_sort_key(etud_info)
etud_info["_prenom_target"] = fiche_url
etud_info["_nom_disp_td_attrs"] = (
'id="%s" class="etudinfo"' % (etud_info["etudid"])
etud_info["_nom_disp_td_attrs"] = 'id="%s" class="etudinfo"' % (
etud_info["etudid"]
)
etud_info["bourse_str"] = "oui" if etud_info["boursier"] else "non"
if etud_info["etat"] == "D":

View File

@ -2291,7 +2291,9 @@ class BasePreferences:
if "explanation" in descr:
del descr["explanation"]
if formsemestre_id:
descr["explanation"] = f"""ou <span class="spanlink"
descr[
"explanation"
] = f"""ou <span class="spanlink"
onclick="set_global_pref(this, '{pref_name}');"
>utiliser paramètre global</span>"""
if formsemestre_id and self.is_global(formsemestre_id, pref_name):

View File

@ -31,9 +31,9 @@ def trombino_doc(groups_infos):
)
section = document.sections[0]
footer = section.footer
footer.paragraphs[
0
].text = f"Généré par {sco_version.SCONAME} le {scu.timedate_human_repr()}"
footer.paragraphs[0].text = (
f"Généré par {sco_version.SCONAME} le {scu.timedate_human_repr()}"
)
nb_images = len(groups_infos.members)
table = document.add_table(rows=2 * (nb_images // N_PER_ROW + 1), cols=N_PER_ROW)

View File

@ -419,9 +419,11 @@ def _get_dates_from_assi_form(
]
):
form.set_error(
(
"La date de début n'appartient à aucun semestre de l'étudiant"
if formsemestre is None
else "La date de début n'appartient pas au semestre",
else "La date de début n'appartient pas au semestre"
),
form.date_debut,
)
@ -433,9 +435,11 @@ def _get_dates_from_assi_form(
]
):
form.set_error(
(
"La date de fin n'appartient à aucun semestre de l'étudiant"
if not formsemestre
else "La date de fin n'appartient pas au semestre",
else "La date de fin n'appartient pas au semestre"
),
form.date_fin,
)

View File

@ -4,7 +4,6 @@ Tableau de bord utilisateur
Emmanuel Viennet, 2023
"""
from flask import flash, redirect, render_template, url_for
from flask import g, request
from flask_login import login_required

View File

@ -2,6 +2,7 @@
Routes for CAS authentication
Modified for ScoDoc
"""
import re
import ssl
from urllib.error import URLError

View File

@ -7,65 +7,84 @@ Source: http://wikipython.flibuste.net/moin.py/JouerAvecUnicode#head-1213938516c
"""
_reptable = {}
def _fill_reptable():
_corresp = [
(u"A", [0x00C0,0x00C1,0x00C2,0x00C3,0x00C4,0x00C5,0x0100,0x0102,0x0104]),
(u"AE", [0x00C6]),
(u"a", [0x00E0,0x00E1,0x00E2,0x00E3,0x00E4,0x00E5,0x0101,0x0103,0x0105]),
(u"ae", [0x00E6]),
(u"C", [0x00C7,0x0106,0x0108,0x010A,0x010C]),
(u"c", [0x00E7,0x0107,0x0109,0x010B,0x010D]),
(u"D", [0x00D0,0x010E,0x0110]),
(u"d", [0x00F0,0x010F,0x0111]),
(u"E", [0x00C8,0x00C9,0x00CA,0x00CB,0x0112,0x0114,0x0116,0x0118,0x011A]),
(u"e", [0x00E8,0x00E9,0x00EA,0x00EB,0x0113,0x0115,0x0117,0x0119,0x011B]),
(u"G", [0x011C,0x011E,0x0120,0x0122]),
(u"g", [0x011D,0x011F,0x0121,0x0123]),
(u"H", [0x0124,0x0126]),
(u"h", [0x0125,0x0127]),
(u"I", [0x00CC,0x00CD,0x00CE,0x00CF,0x0128,0x012A,0x012C,0x012E,0x0130]),
(u"i", [0x00EC,0x00ED,0x00EE,0x00EF,0x0129,0x012B,0x012D,0x012F,0x0131]),
(u"IJ", [0x0132]),
(u"ij", [0x0133]),
(u"J", [0x0134]),
(u"j", [0x0135]),
(u"K", [0x0136]),
(u"k", [0x0137,0x0138]),
(u"L", [0x0139,0x013B,0x013D,0x013F,0x0141]),
(u"l", [0x013A,0x013C,0x013E,0x0140,0x0142]),
(u"N", [0x00D1,0x0143,0x0145,0x0147,0x014A]),
(u"n", [0x00F1,0x0144,0x0146,0x0148,0x0149,0x014B]),
(u"O", [0x00D2,0x00D3,0x00D4,0x00D5,0x00D6,0x00D8,0x014C,0x014E,0x0150]),
(u"o", [0x00F2,0x00F3,0x00F4,0x00F5,0x00F6,0x00F8,0x014D,0x014F,0x0151]),
(u"OE", [0x0152]),
(u"oe", [0x0153]),
(u"R", [0x0154,0x0156,0x0158]),
(u"r", [0x0155,0x0157,0x0159]),
(u"S", [0x015A,0x015C,0x015E,0x0160]),
(u"s", [0x015B,0x015D,0x015F,0x01610,0x017F]),
(u"T", [0x0162,0x0164,0x0166]),
(u"t", [0x0163,0x0165,0x0167]),
(u"U", [0x00D9,0x00DA,0x00DB,0x00DC,0x0168,0x016A,0x016C,0x016E,0x0170,0x172]),
(u"u", [0x00F9,0x00FA,0x00FB,0x00FC,0x0169,0x016B,0x016D,0x016F,0x0171]),
(u"W", [0x0174]),
(u"w", [0x0175]),
(u"Y", [0x00DD,0x0176,0x0178]),
(u"y", [0x00FD,0x00FF,0x0177]),
(u"Z", [0x0179,0x017B,0x017D]),
(u"z", [0x017A,0x017C,0x017E]),
(u"2", [0x00B2]), # deux exposant
(u" ", [0x00A0]), # &nbsp
(u"", [0xB0]), # degre
(u"", [0xA9]), # copyright
(u"1/2", [0xBD]), # 1/2
("A", [0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x0100, 0x0102, 0x0104]),
("AE", [0x00C6]),
("a", [0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x0101, 0x0103, 0x0105]),
("ae", [0x00E6]),
("C", [0x00C7, 0x0106, 0x0108, 0x010A, 0x010C]),
("c", [0x00E7, 0x0107, 0x0109, 0x010B, 0x010D]),
("D", [0x00D0, 0x010E, 0x0110]),
("d", [0x00F0, 0x010F, 0x0111]),
("E", [0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x0112, 0x0114, 0x0116, 0x0118, 0x011A]),
("e", [0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0113, 0x0115, 0x0117, 0x0119, 0x011B]),
("G", [0x011C, 0x011E, 0x0120, 0x0122]),
("g", [0x011D, 0x011F, 0x0121, 0x0123]),
("H", [0x0124, 0x0126]),
("h", [0x0125, 0x0127]),
("I", [0x00CC, 0x00CD, 0x00CE, 0x00CF, 0x0128, 0x012A, 0x012C, 0x012E, 0x0130]),
("i", [0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x0129, 0x012B, 0x012D, 0x012F, 0x0131]),
("IJ", [0x0132]),
("ij", [0x0133]),
("J", [0x0134]),
("j", [0x0135]),
("K", [0x0136]),
("k", [0x0137, 0x0138]),
("L", [0x0139, 0x013B, 0x013D, 0x013F, 0x0141]),
("l", [0x013A, 0x013C, 0x013E, 0x0140, 0x0142]),
("N", [0x00D1, 0x0143, 0x0145, 0x0147, 0x014A]),
("n", [0x00F1, 0x0144, 0x0146, 0x0148, 0x0149, 0x014B]),
("O", [0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D8, 0x014C, 0x014E, 0x0150]),
("o", [0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F8, 0x014D, 0x014F, 0x0151]),
("OE", [0x0152]),
("oe", [0x0153]),
("R", [0x0154, 0x0156, 0x0158]),
("r", [0x0155, 0x0157, 0x0159]),
("S", [0x015A, 0x015C, 0x015E, 0x0160]),
("s", [0x015B, 0x015D, 0x015F, 0x01610, 0x017F]),
("T", [0x0162, 0x0164, 0x0166]),
("t", [0x0163, 0x0165, 0x0167]),
(
"U",
[
0x00D9,
0x00DA,
0x00DB,
0x00DC,
0x0168,
0x016A,
0x016C,
0x016E,
0x0170,
0x172,
],
),
("u", [0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0169, 0x016B, 0x016D, 0x016F, 0x0171]),
("W", [0x0174]),
("w", [0x0175]),
("Y", [0x00DD, 0x0176, 0x0178]),
("y", [0x00FD, 0x00FF, 0x0177]),
("Z", [0x0179, 0x017B, 0x017D]),
("z", [0x017A, 0x017C, 0x017E]),
("2", [0x00B2]), # deux exposant
(" ", [0x00A0]), # &nbsp
("", [0xB0]), # degre
("", [0xA9]), # copyright
("1/2", [0xBD]), # 1/2
]
global _reptable
for repchar,codes in _corresp :
for code in codes :
for repchar, codes in _corresp:
for code in codes:
_reptable[code] = repchar
_fill_reptable()
def suppression_diacritics(s) :
def suppression_diacritics(s):
"""Suppression des accents et autres marques.
@param s: le texte à nettoyer.
@ -73,6 +92,6 @@ def suppression_diacritics(s) :
@return: le texte nettoyé de ses marques diacritiques.
@rtype: unicode
"""
if isinstance(s,str) :
s = unicode(s,"utf8","replace")
if isinstance(s, str):
s = unicode(s, "utf8", "replace")
return s.translate(_reptable)

View File

@ -34,7 +34,7 @@ response = urllib2.urlopen(req)
# Affiche la liste des formations en format XML
req = urllib2.Request(BASEURL + "/Notes/formation_list?fmt=xml")
response = urllib2.urlopen(req)
print response.read()[:100] # limite aux 100 premiers caracteres...
print(response.read()[:100]) # limite aux 100 premiers caracteres...
# Recupere la liste de tous les semestres:
req = urllib2.Request(BASEURL + "/Notes/formsemestre_list?fmt=json") # format json
@ -49,7 +49,7 @@ except:
data = json.loads(js_data) # decode la reponse JSON
if not data:
print "Aucun semestre !"
print("Aucun semestre !")
else:
formsemestre_id = str(data[0]["formsemestre_id"])
# Obtient la liste des groupes:
@ -73,7 +73,7 @@ else:
data = json.loads(js_data)
# Le code du premier étudiant:
if not data:
print ("pas d'etudiants dans ce semestre !")
print("pas d'etudiants dans ce semestre !")
else:
etudid = data[0]["etudid"]
# Récupère bulletin de notes:
@ -87,8 +87,8 @@ else:
) # format XML ici !
response = urllib2.urlopen(req)
xml_bulletin = response.read()
print "----- Bulletin de notes en XML:"
print xml_bulletin
print("----- Bulletin de notes en XML:")
print(xml_bulletin)
# Récupère la moyenne générale:
import xml.dom.minidom
@ -96,4 +96,4 @@ else:
moy = doc.getElementsByTagName("note")[0].getAttribute(
"value"
) # une chaine unicode
print "\nMoyenne generale: ", moy
print("\nMoyenne generale: ", moy)

View File

@ -35,30 +35,30 @@ Utilise geopy http://www.geopy.org/ et l'API Google
from geopy import geocoders
import time
SOURCE = '../config/etablissements-orig.csv'
DEST = '../config/etablissements-geocode.csv'
SOURCE = "../config/etablissements-orig.csv"
DEST = "../config/etablissements-geocode.csv"
g = geocoders.Google(domain="maps.google.fr") #, api_key='XXX')
g = geocoders.Google(domain="maps.google.fr") # , api_key='XXX')
inf = open(SOURCE)
out = open(DEST, 'w')
out = open(DEST, "w")
head = inf.readline()
out.write(head.strip() + ';LAT;LNG'+'\n')
out.write(head.strip() + ";LAT;LNG" + "\n")
for line in inf:
address = ' '.join(line.split(';')[2:]).strip()
print address
address = " ".join(line.split(";")[2:]).strip()
print(address)
try:
place, (lat, lng) = g.geocode(address)
except: # multiple possible locations ?
time.sleep(0.11)
try:
place, (lat, lng) = g.geocode(address + ' France', exactly_one=False)[0]
place, (lat, lng) = g.geocode(address + " France", exactly_one=False)[0]
except:
place, (lat, lng) = 'NOT FOUND', (0.,0.)
print "%s: %.5f, %.5f" % (address, lat, lng)
out.write( line.strip() + ';%s;%s\n' % (lat,lng) )
place, (lat, lng) = "NOT FOUND", (0.0, 0.0)
print(f"{address}: {lat:.5f}, {lng:.5f}")
out.write(line.strip() + ";%s;%s\n" % (lat, lng))
time.sleep(0.11) # Google API Rate limit of 10 requests per second.
inf.close()

View File

@ -23,6 +23,7 @@ idx_nom = 0
SCO_ENCODING = "iso8859-15"
# from SuppressAccents import suppression_diacritics
# XXX a revoir si ce script est utile: en python3, unicodedata.normalize("NFD", s).encode("ascii", "ignore").decode(SCO_ENCODING)
def suppr_acc_and_ponct(s):
s = s.replace(" ", "")
@ -42,7 +43,7 @@ for row in reader:
if row[0][0] != "#":
key = make_key(row[idx_nom], row[idx_prenom])
if noms.has_key(key):
raise ValueError, "duplicate key: %s" % key
raise ValueError(f"duplicate key: {key}")
noms[key] = row
cnx = psycopg.connect(DBCNXSTRING)
@ -55,16 +56,16 @@ cursor.execute(
R = cursor.dictfetchall()
nok = 0
print "nom,prenom,ine,nip"
print("nom,prenom,ine,nip")
for e in R:
key = make_key(e["nom"], e["prenom"])
if not noms.has_key(key):
print "** no match for %s (%s)" % (key, e["etudid"])
print(f"** no match for {key} ({e["etudid"]})")
else:
info = noms[key]
print "%s,%s,%s,%s" % (e["nom"], e["prenom"], e["code_ine"], e["code_nip"])
print(f"{e["nom"]},{e["prenom"]},{e["code_ine"]},{e["code_nip"]}")
nok += 1
cnx.commit()
print "%d etudiants, %d ok" % (len(R), nok)
print(f"{len(R)} etudiants, {nok} ok")

View File

@ -14,6 +14,7 @@ Utilisation :
Lancer :
pytest tests/api/test_api_formsemestre.py
"""
import requests
from app.scodoc import sco_utils as scu

View File

@ -1,5 +1,6 @@
"""Utilitaires pour les tests de l'API
"""
import json

View File

@ -1,6 +1,7 @@
"""
Quelques fonctions d'initialisation pour tests unitaires
"""
import datetime
from app import db, models
@ -82,9 +83,11 @@ def build_formation_test(
coefficient=1.0,
titre=f"module test {i}",
semestre_id=2,
module_type=scu.ModuleType.RESSOURCE
module_type=(
scu.ModuleType.RESSOURCE
if parcours.APC_SAE
else scu.ModuleType.STANDARD,
else scu.ModuleType.STANDARD
),
)
module_ids.append(module_id)
if with_ue_sport:

View File

@ -4,6 +4,7 @@ Utiliser comme:
pytest tests/unit/test_bulletin_bonus.py
"""
from app.but.bulletin_but_pdf import BulletinGeneratorStandardBUT

View File

@ -2,6 +2,7 @@
Vérif moyennes de modules des bulletins
et aussi moyennes modules et UE internes (via nt)
"""
import datetime
import numpy as np
from flask import g

View File

@ -3,6 +3,7 @@ Commande permettant de supprimer les assiduités et les justificatifs
Ecrit par Matthias HARTMANN
"""
import sqlalchemy as sa
from app import db

View File

@ -185,7 +185,7 @@ def import_scodoc7_dept(dept_id: str, dept_db_uri=None):
default_user = get_super_admin()
#
t0 = time.time()
for (table, id_name) in SCO7_TABLES_ORDONNEES:
for table, id_name in SCO7_TABLES_ORDONNEES:
logging.info(f"{dept.acronym}: converting {table}...")
klass = get_class_for_table(table)
t1 = time.time()

View File

@ -3,6 +3,7 @@ Script de migration des données de la base "absences" -> "assiduites"/"justific
Ecrit par Matthias HARTMANN
"""
from datetime import date, datetime, time, timedelta
from json import dump, dumps
from sqlalchemy import not_