diff --git a/app/models/etudiants.py b/app/models/etudiants.py index 2b6f6d65..e189ab59 100644 --- a/app/models/etudiants.py +++ b/app/models/etudiants.py @@ -151,5 +151,5 @@ class EtudAnnotation(db.Model): id = db.Column(db.Integer, primary_key=True) date = db.Column(db.DateTime(timezone=True), server_default=db.func.now()) etudid = db.Column(db.Integer) # sans contrainte pour garder logs après suppression - authenticated_user = db.Column(db.Text) + author = db.Column(db.Text) # le pseudo (user_name) comment = db.Column(db.Text) diff --git a/app/models/notes.py b/app/models/notes.py index 5c9164a9..5852e295 100644 --- a/app/models/notes.py +++ b/app/models/notes.py @@ -114,7 +114,7 @@ class NotesAppreciations(db.Model): db.Integer, db.ForeignKey("notes_formsemestre.id"), ) - author = db.Column(db.Text) # login, sans contrainte + author = db.Column(db.Text) # le pseudo (user_name), sans contrainte comment = db.Column(db.Text) # texte libre diff --git a/app/scodoc/notesdb.py b/app/scodoc/notesdb.py index cc2925d6..96da43a9 100644 --- a/app/scodoc/notesdb.py +++ b/app/scodoc/notesdb.py @@ -301,6 +301,8 @@ class EditableTable(object): vals = dictfilter(args, self.dbfields, self.filter_nulls) if self.id_name in vals: del vals[self.id_name] + if "id" in vals: + del vals["id"] if self.html_quote: quote_dict(vals) # quote all HTML markup # format value diff --git a/app/scodoc/pe_avislatex.py b/app/scodoc/pe_avislatex.py index 9699359a..1e6d2f83 100644 --- a/app/scodoc/pe_avislatex.py +++ b/app/scodoc/pe_avislatex.py @@ -393,7 +393,7 @@ def get_avis_poursuite_par_etudiant( result: [ chaine unicode, chaine unicode ] """ if pe_tools.PE_DEBUG: - pe_tools.pe_print(jury.syntheseJury[etudid]["nom"] + " " + etudid) + pe_tools.pe_print(jury.syntheseJury[etudid]["nom"] + " " + str(etudid)) civilite_str = jury.syntheseJury[etudid]["civilite_str"] nom = jury.syntheseJury[etudid]["nom"].replace(" ", "-") @@ -405,7 +405,7 @@ def get_avis_poursuite_par_etudiant( + "_" + pe_tools.remove_accents(prenom) + "_" - + etudid + + str(etudid) ) if pe_tools.PE_DEBUG: pe_tools.pe_print("fichier latex =" + nom_fichier, type(nom_fichier)) diff --git a/app/scodoc/pe_jurype.py b/app/scodoc/pe_jurype.py index b5d9b9c5..bba73248 100644 --- a/app/scodoc/pe_jurype.py +++ b/app/scodoc/pe_jurype.py @@ -423,7 +423,7 @@ class JuryPE(object): fid = sesFormsemestre_idValidants[i] self.PARCOURSINFO_DICT[etudid][nom_sem] = fid # ['formsemestre_id'] if fid != None and pe_tools.PE_DEBUG and pe_tools.PE_DEBUG >= 2: - pe_tools.pe_print(nom_sem + "=" + fid, end="") + pe_tools.pe_print(nom_sem + "=" + str(fid), end="") # self.get_moyennesEtClassements_par_semestre_d_un_etudiant( etudid, fid ) # Quelles sont ses années validantes ('1A', '2A') et ses parcours (3S, 4S) validants ? @@ -1170,7 +1170,7 @@ class JuryPE(object): nom_sem ] # le formsemestre_id du semestre taggué de l'étudiant semtag = self.semTagDict[semtagid] - chaine += "Semestre " + nom_sem + semtagid + "\n" + chaine += "Semestre " + nom_sem + str(semtagid) + "\n" # le détail du calcul tag par tag # chaine += "Détail du calcul du tag\n" # chaine += "-----------------------\n" diff --git a/app/scodoc/pe_semestretag.py b/app/scodoc/pe_semestretag.py index c0a30125..3f745e3d 100644 --- a/app/scodoc/pe_semestretag.py +++ b/app/scodoc/pe_semestretag.py @@ -360,7 +360,12 @@ class SemestreTag(pe_tagtable.TableTag): lesEtuds = [] for etudid in lesEtuds: - descr = "%15s" % self.nt.get_nom_short(etudid)[:15] + delim + etudid + delim + descr = ( + "%15s" % self.nt.get_nom_short(etudid)[:15] + + delim + + str(etudid) + + delim + ) if tag in taglist: for modimpl_id in self.tagdict[tag]: (note, coeff) = self.get_noteEtCoeff_modimpl(modimpl_id, etudid) @@ -433,7 +438,7 @@ class SemestreTag(pe_tagtable.TableTag): + "*" + str(mod["ponderation"]) + ") " - + modid + + str(modid) + ", " ) chaine += "\n" diff --git a/app/scodoc/sco_archives.py b/app/scodoc/sco_archives.py index 469bf060..915b0d18 100644 --- a/app/scodoc/sco_archives.py +++ b/app/scodoc/sco_archives.py @@ -101,7 +101,7 @@ class BaseArchiver(object): if not os.path.isdir(dept_dir): log("creating directory %s" % dept_dir) os.mkdir(dept_dir) - obj_dir = os.path.join(dept_dir, oid) + obj_dir = os.path.join(dept_dir, str(oid)) if not os.path.isdir(obj_dir): log("creating directory %s" % obj_dir) os.mkdir(obj_dir) @@ -144,7 +144,7 @@ class BaseArchiver(object): dt = [int(x) for x in os.path.split(archive_id)[1].split("-")] return datetime.datetime(*dt) - def list_archive(self, archive_id): + def list_archive(self, archive_id: str) -> str: """Return list of filenames (without path) in archive""" try: scu.GSL.acquire() @@ -152,9 +152,7 @@ class BaseArchiver(object): finally: scu.GSL.release() files.sort() - return [ - f.encode(scu.SCO_ENCODING) for f in files if f and f[0] != "_" - ] # sco8 XXX + return [f for f in files if f and f[0] != "_"] def get_archive_name(self, archive_id): """name identifying archive, to be used in web URLs""" @@ -183,7 +181,7 @@ class BaseArchiver(object): """Return description of archive""" return open(os.path.join(archive_id, "_description.txt")).read() - def create_obj_archive(self, context, oid, description): + def create_obj_archive(self, context, oid: int, description: str): """Creates a new archive for this object and returns its id.""" archive_id = ( self.get_obj_dir(context, oid) @@ -196,10 +194,10 @@ class BaseArchiver(object): os.mkdir(archive_id) # if exists, raises an OSError finally: scu.GSL.release() - self.store(archive_id, "_description.txt", description) + self.store(archive_id, "_description.txt", description.encode("utf-8")) return archive_id - def store(self, archive_id, filename, data): + def store(self, archive_id: str, filename: str, data: bytes): """Store data in archive, under given filename. Filename may be modified (sanitized): return used filename The file is created or replaced. @@ -209,21 +207,21 @@ class BaseArchiver(object): try: scu.GSL.acquire() fname = os.path.join(archive_id, filename) - f = open(fname, "w") + f = open(fname, "wb") f.write(data) f.close() finally: scu.GSL.release() return filename - def get(self, archive_id, filename): + def get(self, archive_id: str, filename: str): """Retreive data""" if not scu.is_valid_filename(filename): log('Archiver.get: invalid filename "%s"' % filename) raise ValueError("invalid filename") fname = os.path.join(archive_id, filename) log("reading archive file %s" % fname) - return open(fname).read() + return open(fname, "rb").read() def get_archived_file(self, context, REQUEST, oid, archive_name, filename): """Recupere donnees du fichier indiqué et envoie au client""" @@ -242,8 +240,8 @@ class BaseArchiver(object): return scu.sendCSVFile(REQUEST, data, filename) elif ext == ".pdf": return scu.sendPDFFile(REQUEST, data, filename) - - return data # should set mimetype... + REQUEST.RESPONSE.setHeader("content-type", "application/octet-stream") + return data # should set mimetype for known files like images class SemsArchiver(BaseArchiver): diff --git a/app/scodoc/sco_archives_etud.py b/app/scodoc/sco_archives_etud.py index 94aad219..65a450f3 100644 --- a/app/scodoc/sco_archives_etud.py +++ b/app/scodoc/sco_archives_etud.py @@ -169,9 +169,9 @@ def etud_upload_file_form(context, REQUEST, etudid): url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid) ) else: - data = tf[2]["datafile"][0].read() + data = tf[2]["datafile"].read() descr = tf[2]["description"] - filename = tf[2]["datafile"][0].filename + filename = tf[2]["datafile"].filename _store_etud_file_to_new_archive( context, REQUEST, etudid, data, filename, description=descr ) diff --git a/app/scodoc/sco_debouche.py b/app/scodoc/sco_debouche.py index f7294896..31cbd7e7 100644 --- a/app/scodoc/sco_debouche.py +++ b/app/scodoc/sco_debouche.py @@ -28,7 +28,7 @@ """ Rapport (table) avec dernier semestre fréquenté et débouché de chaque étudiant """ - +import http from flask import url_for, g import app.scodoc.sco_utils as scu @@ -372,3 +372,4 @@ def itemsuivi_tag_set(context, itemsuivi_id="", taglist=[], REQUEST=None): for tagname in to_del: t = ItemSuiviTag(context, tagname) t.remove_tag_from_object(itemsuivi_id) + return "", http.HTTPStatus.NO_CONTENT diff --git a/app/scodoc/sco_etud.py b/app/scodoc/sco_etud.py index 6f48277d..ba7a275b 100644 --- a/app/scodoc/sco_etud.py +++ b/app/scodoc/sco_etud.py @@ -307,9 +307,13 @@ def check_nom_prenom(cnx, nom="", prenom="", etudid=None): return False, 0 # Now count homonyms: cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor) - req = "select etudid from identite where lower(nom) ~ %(nom)s and lower(prenom) ~ %(prenom)s" + req = """SELECT id + FROM identite + WHERE lower(nom) ~ %(nom)s + and lower(prenom) ~ %(prenom)s + """ if etudid: - req += " and etudid <> %(etudid)s" + req += " and id <> %(etudid)s" cursor.execute(req, {"nom": nom, "prenom": prenom, "etudid": etudid}) res = cursor.dictfetchall() return True, len(res) @@ -559,6 +563,7 @@ _admissionEditor = ndb.EditableTable( "annee_bac": pivot_year, "classement": ndb.int_null_is_null, "apb_classement_gr": ndb.int_null_is_null, + "boursier_prec": bool, }, output_formators={"type_admission": lambda x: x or scu.TYPE_ADMISSION_DEFAULT}, convert_null_outputs_to_empty=True, @@ -747,8 +752,7 @@ _etud_annotationsEditor = ndb.EditableTable( "etudid", "author", "comment", - "zope_authenticated_user", - "zope_remote_addr", + "author", ), sortkey="date desc", convert_null_outputs_to_empty=True, @@ -786,8 +790,7 @@ _appreciationsEditor = ndb.EditableTable( "formsemestre_id", "author", "comment", - "zope_authenticated_user", - "zope_remote_addr", + "author", ), sortkey="date desc", convert_null_outputs_to_empty=True, diff --git a/app/scodoc/sco_formations.py b/app/scodoc/sco_formations.py index ae06697d..043a4bec 100644 --- a/app/scodoc/sco_formations.py +++ b/app/scodoc/sco_formations.py @@ -137,7 +137,7 @@ def formation_export( ) -def formation_import_xml(context, doc, import_tags=True): +def formation_import_xml(context, doc: str, import_tags=True): """Create a formation from XML representation (format dumped by formation_export( format='xml' )) XML may contain object (UE, modules) ids: this function returns two diff --git a/app/scodoc/sco_formsemestre_edit.py b/app/scodoc/sco_formsemestre_edit.py index b82f3ef1..1e502e2a 100644 --- a/app/scodoc/sco_formsemestre_edit.py +++ b/app/scodoc/sco_formsemestre_edit.py @@ -1319,10 +1319,14 @@ def formsemestre_delete(context, formsemestre_id, REQUEST=None): return "\n".join(H) + html_sco_header.sco_footer() elif tf[0] == -1: # cancel return flask.redirect( - scu.NotesURL() + "/formsemestre_status?formsemestre_id=" + formsemestre_id + scu.NotesURL() + + "/formsemestre_status?formsemestre_id=" + + str(formsemestre_id) ) else: - return flask.redirect("formsemestre_delete2?formsemestre_id=" + formsemestre_id) + return flask.redirect( + "formsemestre_delete2?formsemestre_id=" + str(formsemestre_id) + ) def formsemestre_delete2( diff --git a/app/scodoc/sco_formsemestre_validation.py b/app/scodoc/sco_formsemestre_validation.py index 84238907..2ce5e291 100644 --- a/app/scodoc/sco_formsemestre_validation.py +++ b/app/scodoc/sco_formsemestre_validation.py @@ -181,7 +181,7 @@ def formsemestre_validation_etud_form( if not desturl: desturl = ( "formsemestre_recapcomplet?modejury=1&hidemodules=1&hidebac=1&pref_override=0&formsemestre_id=" - + formsemestre_id + + str(formsemestre_id) ) if sortcol: desturl += ( @@ -427,7 +427,7 @@ def _redirect_valid_choice( # flask.redirect( 'formsemestre_validation_etud_form?formsemestre_id=%s&etudid=%s&check=1&desturl=%s' % (formsemestre_id, etudid, desturl) ) # else: # if not desturl: -# desturl = 'formsemestre_recapcomplet?modejury=1&hidemodules=1&formsemestre_id=' + formsemestre_id +# desturl = 'formsemestre_recapcomplet?modejury=1&hidemodules=1&formsemestre_id=' + str(formsemestre_id) # flask.redirect(desturl) @@ -1082,7 +1082,7 @@ def formsemestre_validate_previous_ue(context, formsemestre_id, etudid, REQUEST= return "\n".join(H) + tf[1] + X + warn + html_sco_header.sco_footer() elif tf[0] == -1: return flask.redirect( - scu.NotesURL() + "/formsemestre_status?formsemestre_id=" + formsemestre_id + scu.NotesURL() + "/formsemestre_status?formsemestre_id=" + str(formsemestre_id) ) else: if tf[2]["semestre_id"]: diff --git a/app/scodoc/sco_groups.py b/app/scodoc/sco_groups.py index fbbb3c7d..0d891b09 100644 --- a/app/scodoc/sco_groups.py +++ b/app/scodoc/sco_groups.py @@ -1035,7 +1035,9 @@ def partition_delete( # redirect to partition edit page: if redirect: - return flask.redirect("editPartitionForm?formsemestre_id=" + formsemestre_id) + return flask.redirect( + "editPartitionForm?formsemestre_id=" + str(formsemestre_id) + ) def partition_move(context, partition_id, after=0, REQUEST=None, redirect=1): @@ -1068,7 +1070,9 @@ def partition_move(context, partition_id, after=0, REQUEST=None, redirect=1): # redirect to partition edit page: if redirect: - return flask.redirect("editPartitionForm?formsemestre_id=" + formsemestre_id) + return flask.redirect( + "editPartitionForm?formsemestre_id=" + str(formsemestre_id) + ) def partition_rename(context, partition_id, REQUEST=None): @@ -1105,7 +1109,9 @@ def partition_rename(context, partition_id, REQUEST=None): + html_sco_header.sco_footer() ) elif tf[0] == -1: - return flask.redirect("editPartitionForm?formsemestre_id=" + formsemestre_id) + return flask.redirect( + "editPartitionForm?formsemestre_id=" + str(formsemestre_id) + ) else: # form submission return partition_set_name( @@ -1146,7 +1152,9 @@ def partition_set_name(context, partition_id, partition_name, REQUEST=None, redi # redirect to partition edit page: if redirect: - return flask.redirect("editPartitionForm?formsemestre_id=" + formsemestre_id) + return flask.redirect( + "editPartitionForm?formsemestre_id=" + str(formsemestre_id) + ) def group_set_name(context, group_id, group_name, REQUEST=None, redirect=1): @@ -1531,7 +1539,7 @@ def form_group_choice( def make_query_groups(group_ids): if group_ids: - return "&".join(["group_ids%3Alist=" + group_id for group_id in group_ids]) + return "&".join(["group_ids%3Alist=" + str(group_id) for group_id in group_ids]) else: return "" diff --git a/app/scodoc/sco_inscr_passage.py b/app/scodoc/sco_inscr_passage.py index c4b9ef0d..3383e7ad 100644 --- a/app/scodoc/sco_inscr_passage.py +++ b/app/scodoc/sco_inscr_passage.py @@ -353,7 +353,7 @@ def formsemestre_inscr_passage( dest_url="formsemestre_inscr_passage", add_headers=False, cancel_url="formsemestre_inscr_passage?formsemestre_id=" - + formsemestre_id, + + str(formsemestre_id), OK="Effectuer l'opération", parameters={ "formsemestre_id": formsemestre_id, diff --git a/app/scodoc/sco_page_etud.py b/app/scodoc/sco_page_etud.py index bc08c9f5..64e4a08a 100644 --- a/app/scodoc/sco_page_etud.py +++ b/app/scodoc/sco_page_etud.py @@ -295,7 +295,7 @@ def ficheEtud(context, etudid=None, REQUEST=None): ), ) alist.append( - '