forked from ScoDoc/ScoDoc
Fixes - fiche utilisateur ok
This commit is contained in:
parent
77fc1c7de2
commit
4a43e96fe9
@ -151,5 +151,5 @@ class EtudAnnotation(db.Model):
|
|||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
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
|
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)
|
comment = db.Column(db.Text)
|
||||||
|
@ -114,7 +114,7 @@ class NotesAppreciations(db.Model):
|
|||||||
db.Integer,
|
db.Integer,
|
||||||
db.ForeignKey("notes_formsemestre.id"),
|
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
|
comment = db.Column(db.Text) # texte libre
|
||||||
|
|
||||||
|
|
||||||
|
@ -301,6 +301,8 @@ class EditableTable(object):
|
|||||||
vals = dictfilter(args, self.dbfields, self.filter_nulls)
|
vals = dictfilter(args, self.dbfields, self.filter_nulls)
|
||||||
if self.id_name in vals:
|
if self.id_name in vals:
|
||||||
del vals[self.id_name]
|
del vals[self.id_name]
|
||||||
|
if "id" in vals:
|
||||||
|
del vals["id"]
|
||||||
if self.html_quote:
|
if self.html_quote:
|
||||||
quote_dict(vals) # quote all HTML markup
|
quote_dict(vals) # quote all HTML markup
|
||||||
# format value
|
# format value
|
||||||
|
@ -393,7 +393,7 @@ def get_avis_poursuite_par_etudiant(
|
|||||||
result: [ chaine unicode, chaine unicode ]
|
result: [ chaine unicode, chaine unicode ]
|
||||||
"""
|
"""
|
||||||
if pe_tools.PE_DEBUG:
|
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"]
|
civilite_str = jury.syntheseJury[etudid]["civilite_str"]
|
||||||
nom = jury.syntheseJury[etudid]["nom"].replace(" ", "-")
|
nom = jury.syntheseJury[etudid]["nom"].replace(" ", "-")
|
||||||
@ -405,7 +405,7 @@ def get_avis_poursuite_par_etudiant(
|
|||||||
+ "_"
|
+ "_"
|
||||||
+ pe_tools.remove_accents(prenom)
|
+ pe_tools.remove_accents(prenom)
|
||||||
+ "_"
|
+ "_"
|
||||||
+ etudid
|
+ str(etudid)
|
||||||
)
|
)
|
||||||
if pe_tools.PE_DEBUG:
|
if pe_tools.PE_DEBUG:
|
||||||
pe_tools.pe_print("fichier latex =" + nom_fichier, type(nom_fichier))
|
pe_tools.pe_print("fichier latex =" + nom_fichier, type(nom_fichier))
|
||||||
|
@ -423,7 +423,7 @@ class JuryPE(object):
|
|||||||
fid = sesFormsemestre_idValidants[i]
|
fid = sesFormsemestre_idValidants[i]
|
||||||
self.PARCOURSINFO_DICT[etudid][nom_sem] = fid # ['formsemestre_id']
|
self.PARCOURSINFO_DICT[etudid][nom_sem] = fid # ['formsemestre_id']
|
||||||
if fid != None and pe_tools.PE_DEBUG and pe_tools.PE_DEBUG >= 2:
|
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 )
|
# self.get_moyennesEtClassements_par_semestre_d_un_etudiant( etudid, fid )
|
||||||
|
|
||||||
# Quelles sont ses années validantes ('1A', '2A') et ses parcours (3S, 4S) validants ?
|
# Quelles sont ses années validantes ('1A', '2A') et ses parcours (3S, 4S) validants ?
|
||||||
@ -1170,7 +1170,7 @@ class JuryPE(object):
|
|||||||
nom_sem
|
nom_sem
|
||||||
] # le formsemestre_id du semestre taggué de l'étudiant
|
] # le formsemestre_id du semestre taggué de l'étudiant
|
||||||
semtag = self.semTagDict[semtagid]
|
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
|
# le détail du calcul tag par tag
|
||||||
# chaine += "Détail du calcul du tag\n"
|
# chaine += "Détail du calcul du tag\n"
|
||||||
# chaine += "-----------------------\n"
|
# chaine += "-----------------------\n"
|
||||||
|
@ -360,7 +360,12 @@ class SemestreTag(pe_tagtable.TableTag):
|
|||||||
lesEtuds = []
|
lesEtuds = []
|
||||||
|
|
||||||
for etudid in 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:
|
if tag in taglist:
|
||||||
for modimpl_id in self.tagdict[tag]:
|
for modimpl_id in self.tagdict[tag]:
|
||||||
(note, coeff) = self.get_noteEtCoeff_modimpl(modimpl_id, etudid)
|
(note, coeff) = self.get_noteEtCoeff_modimpl(modimpl_id, etudid)
|
||||||
@ -433,7 +438,7 @@ class SemestreTag(pe_tagtable.TableTag):
|
|||||||
+ "*"
|
+ "*"
|
||||||
+ str(mod["ponderation"])
|
+ str(mod["ponderation"])
|
||||||
+ ") "
|
+ ") "
|
||||||
+ modid
|
+ str(modid)
|
||||||
+ ", "
|
+ ", "
|
||||||
)
|
)
|
||||||
chaine += "\n"
|
chaine += "\n"
|
||||||
|
@ -101,7 +101,7 @@ class BaseArchiver(object):
|
|||||||
if not os.path.isdir(dept_dir):
|
if not os.path.isdir(dept_dir):
|
||||||
log("creating directory %s" % dept_dir)
|
log("creating directory %s" % dept_dir)
|
||||||
os.mkdir(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):
|
if not os.path.isdir(obj_dir):
|
||||||
log("creating directory %s" % obj_dir)
|
log("creating directory %s" % obj_dir)
|
||||||
os.mkdir(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("-")]
|
dt = [int(x) for x in os.path.split(archive_id)[1].split("-")]
|
||||||
return datetime.datetime(*dt)
|
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"""
|
"""Return list of filenames (without path) in archive"""
|
||||||
try:
|
try:
|
||||||
scu.GSL.acquire()
|
scu.GSL.acquire()
|
||||||
@ -152,9 +152,7 @@ class BaseArchiver(object):
|
|||||||
finally:
|
finally:
|
||||||
scu.GSL.release()
|
scu.GSL.release()
|
||||||
files.sort()
|
files.sort()
|
||||||
return [
|
return [f for f in files if f and f[0] != "_"]
|
||||||
f.encode(scu.SCO_ENCODING) for f in files if f and f[0] != "_"
|
|
||||||
] # sco8 XXX
|
|
||||||
|
|
||||||
def get_archive_name(self, archive_id):
|
def get_archive_name(self, archive_id):
|
||||||
"""name identifying archive, to be used in web URLs"""
|
"""name identifying archive, to be used in web URLs"""
|
||||||
@ -183,7 +181,7 @@ class BaseArchiver(object):
|
|||||||
"""Return description of archive"""
|
"""Return description of archive"""
|
||||||
return open(os.path.join(archive_id, "_description.txt")).read()
|
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."""
|
"""Creates a new archive for this object and returns its id."""
|
||||||
archive_id = (
|
archive_id = (
|
||||||
self.get_obj_dir(context, oid)
|
self.get_obj_dir(context, oid)
|
||||||
@ -196,10 +194,10 @@ class BaseArchiver(object):
|
|||||||
os.mkdir(archive_id) # if exists, raises an OSError
|
os.mkdir(archive_id) # if exists, raises an OSError
|
||||||
finally:
|
finally:
|
||||||
scu.GSL.release()
|
scu.GSL.release()
|
||||||
self.store(archive_id, "_description.txt", description)
|
self.store(archive_id, "_description.txt", description.encode("utf-8"))
|
||||||
return archive_id
|
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.
|
"""Store data in archive, under given filename.
|
||||||
Filename may be modified (sanitized): return used filename
|
Filename may be modified (sanitized): return used filename
|
||||||
The file is created or replaced.
|
The file is created or replaced.
|
||||||
@ -209,21 +207,21 @@ class BaseArchiver(object):
|
|||||||
try:
|
try:
|
||||||
scu.GSL.acquire()
|
scu.GSL.acquire()
|
||||||
fname = os.path.join(archive_id, filename)
|
fname = os.path.join(archive_id, filename)
|
||||||
f = open(fname, "w")
|
f = open(fname, "wb")
|
||||||
f.write(data)
|
f.write(data)
|
||||||
f.close()
|
f.close()
|
||||||
finally:
|
finally:
|
||||||
scu.GSL.release()
|
scu.GSL.release()
|
||||||
return filename
|
return filename
|
||||||
|
|
||||||
def get(self, archive_id, filename):
|
def get(self, archive_id: str, filename: str):
|
||||||
"""Retreive data"""
|
"""Retreive data"""
|
||||||
if not scu.is_valid_filename(filename):
|
if not scu.is_valid_filename(filename):
|
||||||
log('Archiver.get: invalid filename "%s"' % filename)
|
log('Archiver.get: invalid filename "%s"' % filename)
|
||||||
raise ValueError("invalid filename")
|
raise ValueError("invalid filename")
|
||||||
fname = os.path.join(archive_id, filename)
|
fname = os.path.join(archive_id, filename)
|
||||||
log("reading archive file %s" % fname)
|
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):
|
def get_archived_file(self, context, REQUEST, oid, archive_name, filename):
|
||||||
"""Recupere donnees du fichier indiqué et envoie au client"""
|
"""Recupere donnees du fichier indiqué et envoie au client"""
|
||||||
@ -242,8 +240,8 @@ class BaseArchiver(object):
|
|||||||
return scu.sendCSVFile(REQUEST, data, filename)
|
return scu.sendCSVFile(REQUEST, data, filename)
|
||||||
elif ext == ".pdf":
|
elif ext == ".pdf":
|
||||||
return scu.sendPDFFile(REQUEST, data, filename)
|
return scu.sendPDFFile(REQUEST, data, filename)
|
||||||
|
REQUEST.RESPONSE.setHeader("content-type", "application/octet-stream")
|
||||||
return data # should set mimetype...
|
return data # should set mimetype for known files like images
|
||||||
|
|
||||||
|
|
||||||
class SemsArchiver(BaseArchiver):
|
class SemsArchiver(BaseArchiver):
|
||||||
|
@ -169,9 +169,9 @@ def etud_upload_file_form(context, REQUEST, etudid):
|
|||||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
data = tf[2]["datafile"][0].read()
|
data = tf[2]["datafile"].read()
|
||||||
descr = tf[2]["description"]
|
descr = tf[2]["description"]
|
||||||
filename = tf[2]["datafile"][0].filename
|
filename = tf[2]["datafile"].filename
|
||||||
_store_etud_file_to_new_archive(
|
_store_etud_file_to_new_archive(
|
||||||
context, REQUEST, etudid, data, filename, description=descr
|
context, REQUEST, etudid, data, filename, description=descr
|
||||||
)
|
)
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
"""
|
"""
|
||||||
Rapport (table) avec dernier semestre fréquenté et débouché de chaque étudiant
|
Rapport (table) avec dernier semestre fréquenté et débouché de chaque étudiant
|
||||||
"""
|
"""
|
||||||
|
import http
|
||||||
from flask import url_for, g
|
from flask import url_for, g
|
||||||
|
|
||||||
import app.scodoc.sco_utils as scu
|
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:
|
for tagname in to_del:
|
||||||
t = ItemSuiviTag(context, tagname)
|
t = ItemSuiviTag(context, tagname)
|
||||||
t.remove_tag_from_object(itemsuivi_id)
|
t.remove_tag_from_object(itemsuivi_id)
|
||||||
|
return "", http.HTTPStatus.NO_CONTENT
|
||||||
|
@ -307,9 +307,13 @@ def check_nom_prenom(cnx, nom="", prenom="", etudid=None):
|
|||||||
return False, 0
|
return False, 0
|
||||||
# Now count homonyms:
|
# Now count homonyms:
|
||||||
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
|
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:
|
if etudid:
|
||||||
req += " and etudid <> %(etudid)s"
|
req += " and id <> %(etudid)s"
|
||||||
cursor.execute(req, {"nom": nom, "prenom": prenom, "etudid": etudid})
|
cursor.execute(req, {"nom": nom, "prenom": prenom, "etudid": etudid})
|
||||||
res = cursor.dictfetchall()
|
res = cursor.dictfetchall()
|
||||||
return True, len(res)
|
return True, len(res)
|
||||||
@ -559,6 +563,7 @@ _admissionEditor = ndb.EditableTable(
|
|||||||
"annee_bac": pivot_year,
|
"annee_bac": pivot_year,
|
||||||
"classement": ndb.int_null_is_null,
|
"classement": ndb.int_null_is_null,
|
||||||
"apb_classement_gr": 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},
|
output_formators={"type_admission": lambda x: x or scu.TYPE_ADMISSION_DEFAULT},
|
||||||
convert_null_outputs_to_empty=True,
|
convert_null_outputs_to_empty=True,
|
||||||
@ -747,8 +752,7 @@ _etud_annotationsEditor = ndb.EditableTable(
|
|||||||
"etudid",
|
"etudid",
|
||||||
"author",
|
"author",
|
||||||
"comment",
|
"comment",
|
||||||
"zope_authenticated_user",
|
"author",
|
||||||
"zope_remote_addr",
|
|
||||||
),
|
),
|
||||||
sortkey="date desc",
|
sortkey="date desc",
|
||||||
convert_null_outputs_to_empty=True,
|
convert_null_outputs_to_empty=True,
|
||||||
@ -786,8 +790,7 @@ _appreciationsEditor = ndb.EditableTable(
|
|||||||
"formsemestre_id",
|
"formsemestre_id",
|
||||||
"author",
|
"author",
|
||||||
"comment",
|
"comment",
|
||||||
"zope_authenticated_user",
|
"author",
|
||||||
"zope_remote_addr",
|
|
||||||
),
|
),
|
||||||
sortkey="date desc",
|
sortkey="date desc",
|
||||||
convert_null_outputs_to_empty=True,
|
convert_null_outputs_to_empty=True,
|
||||||
|
@ -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
|
"""Create a formation from XML representation
|
||||||
(format dumped by formation_export( format='xml' ))
|
(format dumped by formation_export( format='xml' ))
|
||||||
XML may contain object (UE, modules) ids: this function returns two
|
XML may contain object (UE, modules) ids: this function returns two
|
||||||
|
@ -1319,10 +1319,14 @@ def formsemestre_delete(context, formsemestre_id, REQUEST=None):
|
|||||||
return "\n".join(H) + html_sco_header.sco_footer()
|
return "\n".join(H) + html_sco_header.sco_footer()
|
||||||
elif tf[0] == -1: # cancel
|
elif tf[0] == -1: # cancel
|
||||||
return flask.redirect(
|
return flask.redirect(
|
||||||
scu.NotesURL() + "/formsemestre_status?formsemestre_id=" + formsemestre_id
|
scu.NotesURL()
|
||||||
|
+ "/formsemestre_status?formsemestre_id="
|
||||||
|
+ str(formsemestre_id)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return flask.redirect("formsemestre_delete2?formsemestre_id=" + formsemestre_id)
|
return flask.redirect(
|
||||||
|
"formsemestre_delete2?formsemestre_id=" + str(formsemestre_id)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def formsemestre_delete2(
|
def formsemestre_delete2(
|
||||||
|
@ -181,7 +181,7 @@ def formsemestre_validation_etud_form(
|
|||||||
if not desturl:
|
if not desturl:
|
||||||
desturl = (
|
desturl = (
|
||||||
"formsemestre_recapcomplet?modejury=1&hidemodules=1&hidebac=1&pref_override=0&formsemestre_id="
|
"formsemestre_recapcomplet?modejury=1&hidemodules=1&hidebac=1&pref_override=0&formsemestre_id="
|
||||||
+ formsemestre_id
|
+ str(formsemestre_id)
|
||||||
)
|
)
|
||||||
if sortcol:
|
if sortcol:
|
||||||
desturl += (
|
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) )
|
# flask.redirect( 'formsemestre_validation_etud_form?formsemestre_id=%s&etudid=%s&check=1&desturl=%s' % (formsemestre_id, etudid, desturl) )
|
||||||
# else:
|
# else:
|
||||||
# if not desturl:
|
# 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)
|
# 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()
|
return "\n".join(H) + tf[1] + X + warn + html_sco_header.sco_footer()
|
||||||
elif tf[0] == -1:
|
elif tf[0] == -1:
|
||||||
return flask.redirect(
|
return flask.redirect(
|
||||||
scu.NotesURL() + "/formsemestre_status?formsemestre_id=" + formsemestre_id
|
scu.NotesURL() + "/formsemestre_status?formsemestre_id=" + str(formsemestre_id)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
if tf[2]["semestre_id"]:
|
if tf[2]["semestre_id"]:
|
||||||
|
@ -1035,7 +1035,9 @@ def partition_delete(
|
|||||||
|
|
||||||
# redirect to partition edit page:
|
# redirect to partition edit page:
|
||||||
if redirect:
|
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):
|
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:
|
# redirect to partition edit page:
|
||||||
if redirect:
|
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):
|
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()
|
+ html_sco_header.sco_footer()
|
||||||
)
|
)
|
||||||
elif tf[0] == -1:
|
elif tf[0] == -1:
|
||||||
return flask.redirect("editPartitionForm?formsemestre_id=" + formsemestre_id)
|
return flask.redirect(
|
||||||
|
"editPartitionForm?formsemestre_id=" + str(formsemestre_id)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
# form submission
|
# form submission
|
||||||
return partition_set_name(
|
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:
|
# redirect to partition edit page:
|
||||||
if redirect:
|
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):
|
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):
|
def make_query_groups(group_ids):
|
||||||
if 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:
|
else:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
@ -353,7 +353,7 @@ def formsemestre_inscr_passage(
|
|||||||
dest_url="formsemestre_inscr_passage",
|
dest_url="formsemestre_inscr_passage",
|
||||||
add_headers=False,
|
add_headers=False,
|
||||||
cancel_url="formsemestre_inscr_passage?formsemestre_id="
|
cancel_url="formsemestre_inscr_passage?formsemestre_id="
|
||||||
+ formsemestre_id,
|
+ str(formsemestre_id),
|
||||||
OK="Effectuer l'opération",
|
OK="Effectuer l'opération",
|
||||||
parameters={
|
parameters={
|
||||||
"formsemestre_id": formsemestre_id,
|
"formsemestre_id": formsemestre_id,
|
||||||
|
@ -295,7 +295,7 @@ def ficheEtud(context, etudid=None, REQUEST=None):
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
alist.append(
|
alist.append(
|
||||||
'<tr><td><span class="annodate">Le %(date)s par %(zope_authenticated_user)s : </span><span class="annoc">%(comment)s</span></td>%(dellink)s</tr>'
|
'<tr><td><span class="annodate">Le %(date)s par %(author)s : </span><span class="annoc">%(comment)s</span></td>%(dellink)s</tr>'
|
||||||
% a
|
% a
|
||||||
)
|
)
|
||||||
info["liste_annotations"] = "\n".join(alist)
|
info["liste_annotations"] = "\n".join(alist)
|
||||||
|
@ -95,9 +95,9 @@ def can_suppress_annotation(annotation_id):
|
|||||||
if len(annos) != 1:
|
if len(annos) != 1:
|
||||||
raise sco_exceptions.ScoValueError("annotation inexistante !")
|
raise sco_exceptions.ScoValueError("annotation inexistante !")
|
||||||
anno = annos[0]
|
anno = annos[0]
|
||||||
return (
|
return (current_user.user_name == anno["author"]) or current_user.has_permission(
|
||||||
current_user.user_name == anno["zope_authenticated_user"]
|
Permission.ScoEtudAddAnnotations
|
||||||
) or current_user.has_permission(Permission.ScoEtudAddAnnotations)
|
)
|
||||||
|
|
||||||
|
|
||||||
def can_edit_suivi():
|
def can_edit_suivi():
|
||||||
|
@ -321,7 +321,7 @@ def get_new_filename(context, etudid):
|
|||||||
The path is constructed as: Fxx/etudid
|
The path is constructed as: Fxx/etudid
|
||||||
"""
|
"""
|
||||||
dept = scu.get_dept_id()
|
dept = scu.get_dept_id()
|
||||||
return find_new_dir() + dept + "_" + etudid
|
return find_new_dir() + dept + "_" + str(etudid)
|
||||||
|
|
||||||
|
|
||||||
def find_new_dir():
|
def find_new_dir():
|
||||||
|
@ -1123,13 +1123,13 @@ def _form_saisie_notes(context, E, M, group_ids, destination="", REQUEST=None):
|
|||||||
explanation += '<span id="jurylink_%s" class="jurylink"></span>' % etudid
|
explanation += '<span id="jurylink_%s" class="jurylink"></span>' % etudid
|
||||||
|
|
||||||
# Valeur actuelle du champ:
|
# Valeur actuelle du champ:
|
||||||
initvalues["note_" + etudid] = e["val"]
|
initvalues["note_" + str(etudid)] = e["val"]
|
||||||
label_link = '<a class="etudinfo" id="%s">%s</a>' % (etudid, label)
|
label_link = '<a class="etudinfo" id="%s">%s</a>' % (etudid, label)
|
||||||
|
|
||||||
# Element de formulaire:
|
# Element de formulaire:
|
||||||
descr.append(
|
descr.append(
|
||||||
(
|
(
|
||||||
"note_" + etudid,
|
"note_" + str(etudid),
|
||||||
{
|
{
|
||||||
"size": 5,
|
"size": 5,
|
||||||
"title": label_link,
|
"title": label_link,
|
||||||
|
@ -211,7 +211,7 @@ def formsemestre_synchro_etuds(
|
|||||||
dest_url="formsemestre_synchro_etuds",
|
dest_url="formsemestre_synchro_etuds",
|
||||||
add_headers=False,
|
add_headers=False,
|
||||||
cancel_url="formsemestre_synchro_etuds?formsemestre_id="
|
cancel_url="formsemestre_synchro_etuds?formsemestre_id="
|
||||||
+ formsemestre_id,
|
+ str(formsemestre_id),
|
||||||
OK="Effectuer l'opération",
|
OK="Effectuer l'opération",
|
||||||
parameters={
|
parameters={
|
||||||
"formsemestre_id": formsemestre_id,
|
"formsemestre_id": formsemestre_id,
|
||||||
|
@ -1173,7 +1173,7 @@ def AddBilletAbsenceForm(context, etudid, REQUEST=None):
|
|||||||
justified=tf[2]["justified"],
|
justified=tf[2]["justified"],
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return flask.redirect("listeBilletsEtud?etudid=" + etudid)
|
return flask.redirect("listeBilletsEtud?etudid=" + str(etudid))
|
||||||
|
|
||||||
|
|
||||||
def _tableBillets(context, billets, etud=None, title=""):
|
def _tableBillets(context, billets, etud=None, title=""):
|
||||||
|
@ -40,6 +40,7 @@ from xml.etree import ElementTree
|
|||||||
import flask
|
import flask
|
||||||
from flask import url_for, g
|
from flask import url_for, g
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
|
from flask_login import current_user
|
||||||
|
|
||||||
from config import Config
|
from config import Config
|
||||||
import scodoc_manager
|
import scodoc_manager
|
||||||
@ -483,7 +484,7 @@ def formation_import_xml_form(context, REQUEST):
|
|||||||
return flask.redirect(scu.NotesURL())
|
return flask.redirect(scu.NotesURL())
|
||||||
else:
|
else:
|
||||||
formation_id, _, _ = sco_formations.formation_import_xml(
|
formation_id, _, _ = sco_formations.formation_import_xml(
|
||||||
context, tf[2]["xmlfile"]
|
context, tf[2]["xmlfile"].read()
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -1078,7 +1079,9 @@ def edit_ue_expr(context, REQUEST, formsemestre_id, ue_id):
|
|||||||
if tf[0] == 0:
|
if tf[0] == 0:
|
||||||
return "\n".join(H) + tf[1] + html_sco_header.sco_footer()
|
return "\n".join(H) + tf[1] + html_sco_header.sco_footer()
|
||||||
elif tf[0] == -1:
|
elif tf[0] == -1:
|
||||||
return flask.redirect("formsemestre_status?formsemestre_id=" + formsemestre_id)
|
return flask.redirect(
|
||||||
|
"formsemestre_status?formsemestre_id=" + str(formsemestre_id)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
if el:
|
if el:
|
||||||
el[0]["computation_expr"] = tf[2]["computation_expr"]
|
el[0]["computation_expr"] = tf[2]["computation_expr"]
|
||||||
@ -1091,7 +1094,7 @@ def edit_ue_expr(context, REQUEST, formsemestre_id, ue_id):
|
|||||||
) # > modif regle calcul
|
) # > modif regle calcul
|
||||||
return flask.redirect(
|
return flask.redirect(
|
||||||
"formsemestre_status?formsemestre_id="
|
"formsemestre_status?formsemestre_id="
|
||||||
+ formsemestre_id
|
+ str(formsemestre_id)
|
||||||
+ "&head_message=règle%20de%20calcul%20modifiée"
|
+ "&head_message=règle%20de%20calcul%20modifiée"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1329,7 +1332,7 @@ def etud_desinscrit_ue(context, etudid, formsemestre_id, ue_id, REQUEST=None):
|
|||||||
return flask.redirect(
|
return flask.redirect(
|
||||||
scu.ScoURL()
|
scu.ScoURL()
|
||||||
+ "/Notes/moduleimpl_inscriptions_stats?formsemestre_id="
|
+ "/Notes/moduleimpl_inscriptions_stats?formsemestre_id="
|
||||||
+ formsemestre_id
|
+ str(formsemestre_id)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -1344,7 +1347,7 @@ def etud_inscrit_ue(context, etudid, formsemestre_id, ue_id, REQUEST=None):
|
|||||||
return flask.redirect(
|
return flask.redirect(
|
||||||
scu.ScoURL()
|
scu.ScoURL()
|
||||||
+ "/Notes/moduleimpl_inscriptions_stats?formsemestre_id="
|
+ "/Notes/moduleimpl_inscriptions_stats?formsemestre_id="
|
||||||
+ formsemestre_id
|
+ str(formsemestre_id)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -1767,7 +1770,6 @@ def appreciation_add_form(
|
|||||||
):
|
):
|
||||||
"form ajout ou edition d'une appreciation"
|
"form ajout ou edition d'une appreciation"
|
||||||
cnx = ndb.GetDBConnexion()
|
cnx = ndb.GetDBConnexion()
|
||||||
authuser = REQUEST.AUTHENTICATED_USER
|
|
||||||
if id: # edit mode
|
if id: # edit mode
|
||||||
apps = sco_etud.appreciations_list(cnx, args={"id": id})
|
apps = sco_etud.appreciations_list(cnx, args={"id": id})
|
||||||
if not apps:
|
if not apps:
|
||||||
@ -1783,8 +1785,8 @@ def appreciation_add_form(
|
|||||||
edit = 0
|
edit = 0
|
||||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||||
# check custom access permission
|
# check custom access permission
|
||||||
can_edit_app = (str(authuser) in sem["responsables"]) or (
|
can_edit_app = (current_user.id in sem["responsables"]) or (
|
||||||
authuser.has_permission(Permission.ScoEtudInscrit)
|
current_user.has_permission(Permission.ScoEtudInscrit)
|
||||||
)
|
)
|
||||||
if not can_edit_app:
|
if not can_edit_app:
|
||||||
raise AccessDenied("vous n'avez pas le droit d'ajouter une appreciation")
|
raise AccessDenied("vous n'avez pas le droit d'ajouter une appreciation")
|
||||||
@ -1839,10 +1841,8 @@ def appreciation_add_form(
|
|||||||
args = {
|
args = {
|
||||||
"etudid": etudid,
|
"etudid": etudid,
|
||||||
"formsemestre_id": formsemestre_id,
|
"formsemestre_id": formsemestre_id,
|
||||||
"author": str(authuser),
|
"author": current_user.user_name,
|
||||||
"comment": tf[2]["comment"],
|
"comment": tf[2]["comment"],
|
||||||
"zope_authenticated_user": str(authuser),
|
|
||||||
"zope_remote_addr": REQUEST.REMOTE_ADDR,
|
|
||||||
}
|
}
|
||||||
if edit:
|
if edit:
|
||||||
args["id"] = id
|
args["id"] = id
|
||||||
|
@ -43,6 +43,7 @@ import psycopg2
|
|||||||
import flask
|
import flask
|
||||||
from flask import g, url_for
|
from flask import g, url_for
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
|
from flask_login import current_user
|
||||||
|
|
||||||
from config import Config
|
from config import Config
|
||||||
import scodoc_manager
|
import scodoc_manager
|
||||||
@ -454,18 +455,28 @@ sco_publish(
|
|||||||
|
|
||||||
# Debouche / devenir etudiant
|
# Debouche / devenir etudiant
|
||||||
sco_publish(
|
sco_publish(
|
||||||
"/itemsuivi_suppress", sco_debouche.itemsuivi_suppress, Permission.ScoEtudChangeAdr
|
"/itemsuivi_suppress",
|
||||||
|
sco_debouche.itemsuivi_suppress,
|
||||||
|
Permission.ScoEtudChangeAdr,
|
||||||
|
methods=["GET", "POST"],
|
||||||
)
|
)
|
||||||
sco_publish(
|
sco_publish(
|
||||||
"/itemsuivi_create", sco_debouche.itemsuivi_create, Permission.ScoEtudChangeAdr
|
"/itemsuivi_create",
|
||||||
|
sco_debouche.itemsuivi_create,
|
||||||
|
Permission.ScoEtudChangeAdr,
|
||||||
|
methods=["GET", "POST"],
|
||||||
)
|
)
|
||||||
sco_publish(
|
sco_publish(
|
||||||
"/itemsuivi_set_date", sco_debouche.itemsuivi_set_date, Permission.ScoEtudChangeAdr
|
"/itemsuivi_set_date",
|
||||||
|
sco_debouche.itemsuivi_set_date,
|
||||||
|
Permission.ScoEtudChangeAdr,
|
||||||
|
methods=["GET", "POST"],
|
||||||
)
|
)
|
||||||
sco_publish(
|
sco_publish(
|
||||||
"/itemsuivi_set_situation",
|
"/itemsuivi_set_situation",
|
||||||
sco_debouche.itemsuivi_set_situation,
|
sco_debouche.itemsuivi_set_situation,
|
||||||
Permission.ScoEtudChangeAdr,
|
Permission.ScoEtudChangeAdr,
|
||||||
|
methods=["GET", "POST"],
|
||||||
)
|
)
|
||||||
sco_publish(
|
sco_publish(
|
||||||
"/itemsuivi_list_etud", sco_debouche.itemsuivi_list_etud, Permission.ScoView
|
"/itemsuivi_list_etud", sco_debouche.itemsuivi_list_etud, Permission.ScoView
|
||||||
@ -475,24 +486,25 @@ sco_publish(
|
|||||||
"/itemsuivi_tag_search", sco_debouche.itemsuivi_tag_search, Permission.ScoView
|
"/itemsuivi_tag_search", sco_debouche.itemsuivi_tag_search, Permission.ScoView
|
||||||
)
|
)
|
||||||
sco_publish(
|
sco_publish(
|
||||||
"/itemsuivi_tag_set", sco_debouche.itemsuivi_tag_set, Permission.ScoEtudChangeAdr
|
"/itemsuivi_tag_set",
|
||||||
|
sco_debouche.itemsuivi_tag_set,
|
||||||
|
Permission.ScoEtudChangeAdr,
|
||||||
|
methods=["GET", "POST"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/doAddAnnotation", methods=["GET", "POST"])
|
@bp.route("/doAddAnnotation", methods=["GET", "POST"])
|
||||||
@permission_required(Permission.ScoEtudAddAnnotations)
|
@permission_required(Permission.ScoEtudAddAnnotations)
|
||||||
@scodoc7func(context)
|
@scodoc7func(context)
|
||||||
def doAddAnnotation(context, etudid, comment, REQUEST):
|
def doAddAnnotation(etudid, comment):
|
||||||
"ajoute annotation sur etudiant"
|
"ajoute annotation sur etudiant"
|
||||||
authuser = REQUEST.AUTHENTICATED_USER
|
|
||||||
cnx = ndb.GetDBConnexion()
|
cnx = ndb.GetDBConnexion()
|
||||||
sco_etud.etud_annotations_create(
|
sco_etud.etud_annotations_create(
|
||||||
cnx,
|
cnx,
|
||||||
args={
|
args={
|
||||||
"etudid": etudid,
|
"etudid": etudid,
|
||||||
"comment": comment,
|
"comment": comment,
|
||||||
"zope_authenticated_user": str(authuser),
|
"authenticated_user": current_user.user_name,
|
||||||
"zope_remote_addr": REQUEST.REMOTE_ADDR,
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
logdb(cnx, method="addAnnotation", etudid=etudid)
|
logdb(cnx, method="addAnnotation", etudid=etudid)
|
||||||
@ -1473,7 +1485,7 @@ def _etudident_create_or_edit_form(context, REQUEST, edit):
|
|||||||
formsemestre_id=formsemestre_id
|
formsemestre_id=formsemestre_id
|
||||||
) # > etudident_create_or_edit
|
) # > etudident_create_or_edit
|
||||||
#
|
#
|
||||||
return flask.redirect("ficheEtud?etudid=" + etudid)
|
return flask.redirect("ficheEtud?etudid=" + str(etudid))
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/etudident_delete", methods=["GET", "POST"])
|
@bp.route("/etudident_delete", methods=["GET", "POST"])
|
||||||
@ -1968,7 +1980,9 @@ def form_students_import_infos_admissions(context, REQUEST, formsemestre_id=None
|
|||||||
return "\n".join(H) + tf[1] + help_text + F
|
return "\n".join(H) + tf[1] + help_text + F
|
||||||
elif tf[0] == -1:
|
elif tf[0] == -1:
|
||||||
return flask.redirect(
|
return flask.redirect(
|
||||||
scu.ScoURL() + "/formsemestre_status?formsemestre_id=" + formsemestre_id
|
scu.ScoURL()
|
||||||
|
+ "/formsemestre_status?formsemestre_id="
|
||||||
|
+ str(formsemestre_id)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return sco_import_etuds.students_import_admission(
|
return sco_import_etuds.students_import_admission(
|
||||||
|
@ -15,8 +15,9 @@ BASEURL = "https://scodoc.xxx.net/ScoDoc/RT/Scolarite"
|
|||||||
USER = "XXX"
|
USER = "XXX"
|
||||||
PASSWORD = "XXX"
|
PASSWORD = "XXX"
|
||||||
|
|
||||||
values = {'__ac_name' : USER,
|
values = {
|
||||||
'__ac_password' : PASSWORD,
|
"__ac_name": USER,
|
||||||
|
"__ac_password": PASSWORD,
|
||||||
}
|
}
|
||||||
|
|
||||||
# Configure memorisation des cookies:
|
# Configure memorisation des cookies:
|
||||||
@ -31,12 +32,12 @@ response = urllib2.urlopen(req)
|
|||||||
# --- Use API
|
# --- Use API
|
||||||
|
|
||||||
# Affiche la liste des formations en format XML
|
# Affiche la liste des formations en format XML
|
||||||
req = urllib2.Request(BASEURL+'/Notes/formation_list?format=xml' )
|
req = urllib2.Request(BASEURL + "/Notes/formation_list?format=xml")
|
||||||
response = urllib2.urlopen(req)
|
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:
|
# Recupere la liste de tous les semestres:
|
||||||
req = urllib2.Request(BASEURL+'/Notes/formsemestre_list?format=json') # format json
|
req = urllib2.Request(BASEURL + "/Notes/formsemestre_list?format=json") # format json
|
||||||
response = urllib2.urlopen(req)
|
response = urllib2.urlopen(req)
|
||||||
js_data = response.read()
|
js_data = response.read()
|
||||||
|
|
||||||
@ -50,32 +51,49 @@ data = json.loads(js_data) # decode la reponse JSON
|
|||||||
if not data:
|
if not data:
|
||||||
print "Aucun semestre !"
|
print "Aucun semestre !"
|
||||||
else:
|
else:
|
||||||
formsemestre_id = str(data[0]['formsemestre_id'])
|
formsemestre_id = str(data[0]["formsemestre_id"])
|
||||||
# Obtient la liste des groupes:
|
# Obtient la liste des groupes:
|
||||||
req = urllib2.Request(BASEURL+'/Notes/formsemestre_partition_list?format=json&formsemestre_id='+formsemestre_id) # format json
|
req = urllib2.Request(
|
||||||
|
BASEURL
|
||||||
|
+ "/Notes/formsemestre_partition_list?format=json&formsemestre_id="
|
||||||
|
+ str(formsemestre_id)
|
||||||
|
) # format json
|
||||||
response = urllib2.urlopen(req)
|
response = urllib2.urlopen(req)
|
||||||
js_data = response.read()
|
js_data = response.read()
|
||||||
data = json.loads(js_data)
|
data = json.loads(js_data)
|
||||||
group_id = data[0]['group'][0]['group_id'] # premier groupe (normalement existe toujours)
|
group_id = data[0]["group"][0][
|
||||||
|
"group_id"
|
||||||
|
] # premier groupe (normalement existe toujours)
|
||||||
# Liste les étudiants de ce groupe:
|
# Liste les étudiants de ce groupe:
|
||||||
req = urllib2.Request(BASEURL+'/Notes/group_list?format=json&with_codes=1&group_id='+group_id) # format json
|
req = urllib2.Request(
|
||||||
|
BASEURL + "/Notes/group_list?format=json&with_codes=1&group_id=" + str(group_id)
|
||||||
|
) # format json
|
||||||
response = urllib2.urlopen(req)
|
response = urllib2.urlopen(req)
|
||||||
js_data = response.read()
|
js_data = response.read()
|
||||||
data = json.loads(js_data)
|
data = json.loads(js_data)
|
||||||
# Le code du premier étudiant:
|
# Le code du premier étudiant:
|
||||||
if not data:
|
if not data:
|
||||||
print "pas d'etudiants dans ce semestre !"
|
print ("pas d'etudiants dans ce semestre !")
|
||||||
else:
|
else:
|
||||||
etudid = data[0]['etudid']
|
etudid = data[0]["etudid"]
|
||||||
# Récupère bulletin de notes:
|
# Récupère bulletin de notes:
|
||||||
req = urllib2.Request(BASEURL+'/Notes/formsemestre_bulletinetud?formsemestre_id='+formsemestre_id+'&etudid=' + etudid + '&format=xml') # format XML ici !
|
req = urllib2.Request(
|
||||||
|
BASEURL
|
||||||
|
+ "/Notes/formsemestre_bulletinetud?formsemestre_id="
|
||||||
|
+ str(formsemestre_id)
|
||||||
|
+ "&etudid="
|
||||||
|
+ str(etudid)
|
||||||
|
+ "&format=xml"
|
||||||
|
) # format XML ici !
|
||||||
response = urllib2.urlopen(req)
|
response = urllib2.urlopen(req)
|
||||||
xml_bulletin = response.read()
|
xml_bulletin = response.read()
|
||||||
print '----- Bulletin de notes en XML:'
|
print "----- Bulletin de notes en XML:"
|
||||||
print xml_bulletin
|
print xml_bulletin
|
||||||
# Récupère la moyenne générale:
|
# Récupère la moyenne générale:
|
||||||
import xml.dom.minidom
|
import xml.dom.minidom
|
||||||
doc = xml.dom.minidom.parseString(xml_bulletin)
|
|
||||||
moy = doc.getElementsByTagName('note')[0].getAttribute('value') # une chaine unicode
|
|
||||||
print '\nMoyenne generale: ', moy
|
|
||||||
|
|
||||||
|
doc = xml.dom.minidom.parseString(xml_bulletin)
|
||||||
|
moy = doc.getElementsByTagName("note")[0].getAttribute(
|
||||||
|
"value"
|
||||||
|
) # une chaine unicode
|
||||||
|
print "\nMoyenne generale: ", moy
|
||||||
|
Loading…
Reference in New Issue
Block a user