diff --git a/ImportScolars.py b/ImportScolars.py index c819551e..47c18bdb 100644 --- a/ImportScolars.py +++ b/ImportScolars.py @@ -116,8 +116,7 @@ def sco_import_format(with_codesemestre=True): def sco_import_format_dict(with_codesemestre=True): - """ Attribut: { 'type': , 'table', 'allow_nulls' , 'description' } - """ + """Attribut: { 'type': , 'table', 'allow_nulls' , 'description' }""" fmt = sco_import_format(with_codesemestre=with_codesemestre) R = collections.OrderedDict() for l in fmt: @@ -260,7 +259,7 @@ def scolars_import_excel_file( if not data: # probably a bug raise ScoException("scolars_import_excel_file: empty file !") - formsemestre_to_invalidate = Set() + formsemestre_to_invalidate = set() # 1- --- check title line titles = {} @@ -555,18 +554,18 @@ def scolars_import_admission( """Importe données admission depuis un fichier Excel quelconque par exemple ceux utilisés avec APB - Cherche dans ce fichier les étudiants qui correspondent à des inscrits du + Cherche dans ce fichier les étudiants qui correspondent à des inscrits du semestre formsemestre_id. - Le fichier n'a pas l'INE ni le NIP ni l'etudid, la correspondance se fait - via les noms/prénoms qui doivent être égaux (la casse, les accents et caractères spéciaux + Le fichier n'a pas l'INE ni le NIP ni l'etudid, la correspondance se fait + via les noms/prénoms qui doivent être égaux (la casse, les accents et caractères spéciaux étant ignorés). - On tolère plusieurs variantes pour chaque nom de colonne (ici aussi, la casse, les espaces + On tolère plusieurs variantes pour chaque nom de colonne (ici aussi, la casse, les espaces et les caractères spéciaux sont ignorés. Ainsi, la colonne "Prénom:" sera considéré comme "prenom". Le parametre type_admission remplace les valeurs vides (dans la base ET dans le fichier importé) du champ type_admission. Si une valeur existe ou est présente dans le fichier importé, ce paramètre est ignoré. - + TODO: - choix onglet du classeur """ @@ -611,7 +610,7 @@ def scolars_import_admission( % formsemestre_id, ) - modifiable_fields = Set(ADMISSION_MODIFIABLE_FIELDS) + modifiable_fields = set(ADMISSION_MODIFIABLE_FIELDS) nline = 2 # la premiere ligne de donnees du fichier excel est 2 n_import = 0 @@ -748,8 +747,7 @@ def adm_convert_real(v): def adm_table_description_format(context): - """Table HTML (ou autre format) decrivant les donnees d'admissions importables - """ + """Table HTML (ou autre format) decrivant les donnees d'admissions importables""" Fmt = sco_import_format_dict(with_codesemestre=False) for k in Fmt: Fmt[k]["attribute"] = k diff --git a/ZNotes.py b/ZNotes.py index b8be58c3..f88a9042 100644 --- a/ZNotes.py +++ b/ZNotes.py @@ -28,8 +28,6 @@ """Interface Zope <-> Notes """ -from sets import Set - from sco_zope import * # --------------- @@ -2241,7 +2239,7 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl {"moduleimpl_id": moduleimpl_id}, ) # Inscriptions au module: - inmod_set = Set( + inmod_set = set( [ x["etudid"] for x in self.do_moduleimpl_inscription_list( diff --git a/ZScoDoc.py b/ZScoDoc.py index a3f1d890..83732b4d 100644 --- a/ZScoDoc.py +++ b/ZScoDoc.py @@ -101,8 +101,7 @@ class ZScoDoc(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Imp return self.absolute_url() def _check_admin_perm(self, REQUEST): - """Check if user has permission to add/delete departements - """ + """Check if user has permission to add/delete departements""" authuser = REQUEST.AUTHENTICATED_USER if authuser.has_role("manager") or authuser.has_permission(ScoSuperAdmin, self): return "" @@ -110,8 +109,7 @@ class ZScoDoc(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Imp return """

Vous n'avez pas le droit d'accéder à cette page

""" def _check_users_folder(self, REQUEST=None): - """Vérifie UserFolder et le crée s'il le faut - """ + """Vérifie UserFolder et le crée s'il le faut""" try: udb = self.UsersDB return "" @@ -127,8 +125,7 @@ class ZScoDoc(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Imp security.declareProtected("View", "create_users_folder") def create_users_folder(self, REQUEST=None): - """Create Zope user folder - """ + """Create Zope user folder""" e = self._check_admin_perm(REQUEST) if e: return e @@ -304,8 +301,7 @@ class ZScoDoc(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Imp security.declareProtected("View", "delete_dept") def delete_dept(self, REQUEST=None, DeptId="", force=False): - """Supprime un departement (de Zope seulement, ne touche pas la BD) - """ + """Supprime un departement (de Zope seulement, ne touche pas la BD)""" e = self._check_admin_perm(REQUEST) if e: return e @@ -373,8 +369,7 @@ class ZScoDoc(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Imp security.declareProtected("View", "index_html") def index_html(self, REQUEST=None, message=None): - """Top level page for ScoDoc - """ + """Top level page for ScoDoc""" authuser = REQUEST.AUTHENTICATED_USER deptList = self.list_depts() self._fix_users_folder() # fix our exUserFolder @@ -825,8 +820,7 @@ subversion: %(svn_version)s security.declareProtected("View", "scodoc_admin") def scodoc_admin(self, REQUEST=None): - """Page Operations d'administration - """ + """Page Operations d'administration""" e = self._check_admin_perm(REQUEST) if e: return e @@ -847,8 +841,8 @@ subversion: %(svn_version)s ] deptList = [x.id for x in self.list_depts()] # definis dans Zope - deptIds = Set(self._list_depts_ids()) # definis sur le filesystem - existingDepts = Set(deptList) + deptIds = set(self._list_depts_ids()) # definis sur le filesystem + existingDepts = set(deptList) addableDepts = deptIds - existingDepts if not addableDepts: diff --git a/sco_bulletins.py b/sco_bulletins.py index ed4a19d5..e20d72de 100644 --- a/sco_bulletins.py +++ b/sco_bulletins.py @@ -98,7 +98,7 @@ def formsemestre_bulletinetud_dict( ): """Collecte informations pour bulletin de notes Retourne un dictionnaire (avec valeur par défaut chaine vide). - Le contenu du dictionnaire dépend des options (rangs, ...) + Le contenu du dictionnaire dépend des options (rangs, ...) et de la version choisie (short, long, selectedevals). Cette fonction est utilisée pour les bulletins HTML et PDF, mais pas ceux en XML. @@ -131,9 +131,11 @@ def formsemestre_bulletinetud_dict( I["etud"] = context.getEtudInfo(etudid=etudid, filled=1)[0] I["descr_situation"] = I["etud"]["inscriptionstr"] if I["etud"]["inscription_formsemestre_id"]: - I["descr_situation_html"] = ( - """%s""" - % (I["etud"]["inscription_formsemestre_id"], I["descr_situation"]) + I[ + "descr_situation_html" + ] = """%s""" % ( + I["etud"]["inscription_formsemestre_id"], + I["descr_situation"], ) else: I["descr_situation_html"] = I["descr_situation"] @@ -314,14 +316,13 @@ def formsemestre_bulletinetud_dict( u["ue_descr_txt"] = "Capitalisée le %s" % DateISOtoDMY( ue_status["event_date"] ) - u["ue_descr_html"] = ( - '%s' - % ( - sem_origin["formsemestre_id"], - etudid, - sem_origin["titreannee"], - u["ue_descr_txt"], - ) + u[ + "ue_descr_html" + ] = '%s' % ( + sem_origin["formsemestre_id"], + etudid, + sem_origin["titreannee"], + u["ue_descr_txt"], ) # log('cap details %s' % ue_status['moy']) if ue_status["moy"] != "NA" and ue_status["formsemestre_id"]: @@ -539,7 +540,7 @@ def _ue_mod_bulletin(context, etudid, formsemestre_id, ue_id, modimpls, nt, vers # Evaluations incomplètes ou futures: mod["evaluations_incompletes"] = [] if context.get_preference("bul_show_all_evals", formsemestre_id): - complete_eval_ids = Set([e["evaluation_id"] for e in evals]) + complete_eval_ids = set([e["evaluation_id"] for e in evals]) all_evals = context.do_evaluation_list( args={"moduleimpl_id": modimpl["moduleimpl_id"]} ) @@ -578,8 +579,7 @@ def _ue_mod_bulletin(context, etudid, formsemestre_id, ue_id, modimpls, nt, vers def get_etud_rangs_groups( context, etudid, formsemestre_id, partitions, partitions_etud_groups, nt ): - """Ramene rang et nb inscrits dans chaque partition - """ + """Ramene rang et nb inscrits dans chaque partition""" rang_gr, ninscrits_gr, gr_name = {}, {}, {} for partition in partitions: if partition["partition_name"] != None: @@ -616,7 +616,7 @@ def etud_descr_situation_semestre( situation : chaine résumant en français la situation de l'étudiant. Par ex. "Inscrit le 31/12/1999. Décision jury: Validé. ..." - + date_inscription : (vide si show_date_inscr est faux) date_demission : (vide si pas demission ou si show_date_inscr est faux) descr_inscription : "Inscrit" ou "Pas inscrit[e]" @@ -820,8 +820,7 @@ def formsemestre_bulletinetud( def can_send_bulletin_by_mail(context, formsemestre_id, REQUEST): - """True if current user is allowed to send a bulletin by mail - """ + """True if current user is allowed to send a bulletin by mail""" authuser = REQUEST.AUTHENTICATED_USER sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) return ( @@ -1177,8 +1176,7 @@ def _formsemestre_bulletinetud_header_html( def formsemestre_bulletins_choice( context, REQUEST, formsemestre_id, title="", explanation="", choose_mail=False ): - """Choix d'une version de bulletin - """ + """Choix d'une version de bulletin""" sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) H = [ context.html_sem_header(REQUEST, title, sem), diff --git a/sco_bulletins_json.py b/sco_bulletins_json.py index 80b273e1..9420398c 100644 --- a/sco_bulletins_json.py +++ b/sco_bulletins_json.py @@ -273,7 +273,7 @@ def formsemestre_bulletinetud_published_dict( ) ) # Evaluations incomplètes ou futures: - complete_eval_ids = Set([e["evaluation_id"] for e in evals]) + complete_eval_ids = set([e["evaluation_id"] for e in evals]) if context.get_preference("bul_show_all_evals", formsemestre_id): all_evals = context.do_evaluation_list( args={"moduleimpl_id": modimpl["moduleimpl_id"]} diff --git a/sco_bulletins_xml.py b/sco_bulletins_xml.py index 2e78eb9f..c1cfe8ee 100644 --- a/sco_bulletins_xml.py +++ b/sco_bulletins_xml.py @@ -265,7 +265,7 @@ def make_xml_formsemestre_bulletinetud( doc.note(value=val) doc._pop() # Evaluations incomplètes ou futures: - complete_eval_ids = Set([e["evaluation_id"] for e in evals]) + complete_eval_ids = set([e["evaluation_id"] for e in evals]) if context.get_preference("bul_show_all_evals", formsemestre_id): all_evals = context.do_evaluation_list( args={"moduleimpl_id": modimpl["moduleimpl_id"]} diff --git a/sco_compute_moy.py b/sco_compute_moy.py index fa7d05a3..b6cb01ed 100644 --- a/sco_compute_moy.py +++ b/sco_compute_moy.py @@ -28,7 +28,6 @@ """Calcul des moyennes de module """ -from sets import Set import traceback from sco_utils import * @@ -92,8 +91,7 @@ formsemestre_ue_computation_expr_edit = _formsemestre_ue_computation_exprEditor. def get_ue_expression(formsemestre_id, ue_id, cnx, html_quote=False): - """Returns UE expression (formula), or None if no expression has been defined - """ + """Returns UE expression (formula), or None if no expression has been defined""" el = formsemestre_ue_computation_expr_list( cnx, {"formsemestre_id": formsemestre_id, "ue_id": ue_id} ) @@ -196,7 +194,7 @@ def do_moduleimpl_moyennes(context, nt, mod): moduleimpl_id ) # tous, y compris demissions # Inscrits au semestre (pour traiter les demissions): - inssem_set = Set( + inssem_set = set( [ x["etudid"] for x in context.do_formsemestre_inscription_listinscrits( diff --git a/sco_evaluations.py b/sco_evaluations.py index 246ebcb6..a2faa17b 100644 --- a/sco_evaluations.py +++ b/sco_evaluations.py @@ -27,7 +27,6 @@ """Evaluations """ -from sets import Set from notes_log import log, logCallStack from sco_utils import * @@ -117,7 +116,7 @@ def do_evaluation_etat( context, evaluation_id, partition_id=None, select_first_partition=False ): """donne infos sur l'etat du evaluation - { nb_inscrits, nb_notes, nb_abs, nb_neutre, nb_att, + { nb_inscrits, nb_notes, nb_abs, nb_neutre, nb_att, moyenne, mediane, mini, maxi, date_last_modif, gr_complets, gr_incomplets, evalcomplete } evalcomplete est vrai si l'eval est complete (tous les inscrits @@ -176,7 +175,7 @@ def do_evaluation_etat( # au module (pour gerer les modules optionnels correctement) insem = context.do_formsemestre_inscription_listinscrits(formsemestre_id) insmod = context.do_moduleimpl_inscription_list(moduleimpl_id=E["moduleimpl_id"]) - insmodset = Set([x["etudid"] for x in insmod]) + insmodset = set([x["etudid"] for x in insmod]) # retire de insem ceux qui ne sont pas inscrits au module ins = [i for i in insem if i["etudid"] in insmodset] @@ -292,50 +291,50 @@ def do_evaluation_etat( def do_evaluation_list_in_sem(context, formsemestre_id): """Liste les evaluations de tous les modules de ce semestre. - Donne pour chaque eval son état (voir do_evaluation_etat) - { evaluation_id,nb_inscrits, nb_notes, nb_abs, nb_neutre, moy, median, last_modif ... } + Donne pour chaque eval son état (voir do_evaluation_etat) + { evaluation_id,nb_inscrits, nb_notes, nb_abs, nb_neutre, moy, median, last_modif ... } - Exemple: - [ { - 'coefficient': 1.0, - 'description': 'QCM et cas pratiques', - 'etat': {'evalattente': False, - 'evalcomplete': True, - 'evaluation_id': 'GEAEVAL82883', - 'gr_incomplets': [], - 'gr_moyennes': [{'gr_median': '12.00', - 'gr_median_num' : 12., - 'gr_moy': '11.88', - 'gr_moy_num' : 11.88, - 'gr_nb_att': 0, - 'gr_nb_notes': 166, - 'group_id': 'GEAG266762', - 'group_name': None}], - 'groups': {'GEAG266762': {'etudid': 'GEAEID80603', - 'group_id': 'GEAG266762', - 'group_name': None, - 'partition_id': 'GEAP266761'} - }, - 'last_modif': datetime.datetime(2015, 12, 3, 15, 15, 16), - 'median': '12.00', - 'moy': '11.84', - 'nb_abs': 2, - 'nb_att': 0, - 'nb_inscrits': 166, - 'nb_neutre': 0, - 'nb_notes': 168, - 'nb_notes_total': 169 - }, - 'evaluation_id': 'GEAEVAL82883', - 'evaluation_type': 0, - 'heure_debut': datetime.time(8, 0), - 'heure_fin': datetime.time(9, 30), - 'jour': datetime.date(2015, 11, 3), // vide => 1/1/1 - 'moduleimpl_id': 'GEAMIP80490', - 'note_max': 20.0, - 'numero': 0, - 'publish_incomplete': 0, - 'visibulletin': 1} ] + Exemple: + [ { + 'coefficient': 1.0, + 'description': 'QCM et cas pratiques', + 'etat': {'evalattente': False, + 'evalcomplete': True, + 'evaluation_id': 'GEAEVAL82883', + 'gr_incomplets': [], + 'gr_moyennes': [{'gr_median': '12.00', + 'gr_median_num' : 12., + 'gr_moy': '11.88', + 'gr_moy_num' : 11.88, + 'gr_nb_att': 0, + 'gr_nb_notes': 166, + 'group_id': 'GEAG266762', + 'group_name': None}], + 'groups': {'GEAG266762': {'etudid': 'GEAEID80603', + 'group_id': 'GEAG266762', + 'group_name': None, + 'partition_id': 'GEAP266761'} + }, + 'last_modif': datetime.datetime(2015, 12, 3, 15, 15, 16), + 'median': '12.00', + 'moy': '11.84', + 'nb_abs': 2, + 'nb_att': 0, + 'nb_inscrits': 166, + 'nb_neutre': 0, + 'nb_notes': 168, + 'nb_notes_total': 169 + }, + 'evaluation_id': 'GEAEVAL82883', + 'evaluation_type': 0, + 'heure_debut': datetime.time(8, 0), + 'heure_fin': datetime.time(9, 30), + 'jour': datetime.date(2015, 11, 3), // vide => 1/1/1 + 'moduleimpl_id': 'GEAMIP80490', + 'note_max': 20.0, + 'numero': 0, + 'publish_incomplete': 0, + 'visibulletin': 1} ] """ req = "select E.* from notes_evaluation E, notes_moduleimpl MI where MI.formsemestre_id = %(formsemestre_id)s and MI.moduleimpl_id = E.moduleimpl_id" @@ -410,8 +409,7 @@ def do_evaluation_etat_in_sem(context, formsemestre_id, REQUEST=None): def do_evaluation_etat_in_mod(context, nt, moduleimpl_id): - """ - """ + """""" evals = nt.get_mod_evaluation_etat_list(moduleimpl_id) etat = _eval_etat(evals) etat["attente"] = moduleimpl_id in [ @@ -522,7 +520,7 @@ def evaluation_date_first_completion(context, evaluation_id): # au module (pour gerer les modules optionnels correctement) insem = context.do_formsemestre_inscription_listinscrits(formsemestre_id) insmod = context.do_moduleimpl_inscription_list(moduleimpl_id=E["moduleimpl_id"]) - insmodset = Set([x["etudid"] for x in insmod]) + insmodset = set([x["etudid"] for x in insmod]) # retire de insem ceux qui ne sont pas inscrits au module ins = [i for i in insem if i["etudid"] in insmodset] diff --git a/sco_formsemestre_inscriptions.py b/sco_formsemestre_inscriptions.py index 0761aef1..4292c4ee 100644 --- a/sco_formsemestre_inscriptions.py +++ b/sco_formsemestre_inscriptions.py @@ -28,12 +28,13 @@ """Opérations d'inscriptions aux semestres et modules """ +from sco_utils import ScoEtudInscrit, log, ScoValueError, DictDefault +from sco_utils import UE_STANDARD, UE_SPORT, UE_TYPE_NAME +from notesdb import ScoDocCursor, DateISOtoDMY, DateDMYtoISO -from notesdb import * -from sco_utils import * -from notes_log import log from TrivialFormulator import TrivialFormulator, TF -from notes_table import * + +# from notes_table import * import sco_find_etud import sco_formsemestre import sco_groups @@ -283,7 +284,7 @@ def formsemestre_inscription_option(context, etudid, formsemestre_id, REQUEST=No modimpls_by_ue_ids = DictDefault(defaultvalue=[]) # ue_id : [ moduleimpl_id ] modimpls_by_ue_names = DictDefault(defaultvalue=[]) # ue_id : [ moduleimpl_name ] ues = [] - ue_ids = Set() + ue_ids = set() initvalues = {} for mod in mods: ue_id = mod["ue"]["ue_id"] @@ -402,7 +403,7 @@ function chkbx_select(field_id, state) { if not insdict.has_key(moduleimpl_id): del a_desinscrire[moduleimpl_id] - a_inscrire = Set() + a_inscrire = set() for ue in ues: ue_id = ue["ue_id"] a_inscrire.update(tf[2]["moduleimpls_%s" % ue_id]) @@ -526,7 +527,7 @@ def do_moduleimpl_incription_options( ) if not inscr: raise ScoValueError( - "pas inscrit a ce module ! (etudid=%s, moduleimpl_id=%)" + "pas inscrit a ce module ! (etudid=%s, moduleimpl_id=%s)" % (etudid, moduleimpl_id) ) oid = inscr[0]["moduleimpl_inscription_id"] diff --git a/sco_formulas.py b/sco_formulas.py index ae0a7b1f..8bd0d107 100644 --- a/sco_formulas.py +++ b/sco_formulas.py @@ -28,7 +28,6 @@ """Une classe "vecteur" pour les formules utilisateurs de calcul des moyennes """ -from sets import Set import operator import traceback from types import FloatType, IntType, LongType, StringType @@ -174,8 +173,7 @@ formula_builtins = { def eval_user_expression(context, expression, variables): - """Evalue l'expression (formule utilisateur) avec les variables (dict) données. - """ + """Evalue l'expression (formule utilisateur) avec les variables (dict) données.""" variables["__builtins__"] = formula_builtins # log('Evaluating %s with %s' % (expression, variables)) # may raise exception if user expression is invalid diff --git a/sco_inscr_passage.py b/sco_inscr_passage.py index aee4b4ff..d59307c4 100644 --- a/sco_inscr_passage.py +++ b/sco_inscr_passage.py @@ -28,7 +28,6 @@ """Form. pour inscription rapide des etudiants d'un semestre dans un autre Utilise les autorisations d'inscription délivrées en jury. """ -from sets import Set from gen_tables import GenTable @@ -117,8 +116,7 @@ def list_inscrits(context, formsemestre_id, with_dems=False): def list_etuds_from_sem(context, src, dst): - """Liste des etudiants du semestre src qui sont autorisés à passer dans le semestre dst. - """ + """Liste des etudiants du semestre src qui sont autorisés à passer dans le semestre dst.""" target = dst["semestre_id"] dpv = sco_pvjury.dict_pvjury(context, src["formsemestre_id"]) if not dpv: @@ -274,7 +272,7 @@ def formsemestre_inscr_passage( - on peut choisir les groupes TD, TP, TA - seuls les etudiants non inscrits changent (de groupe) - les etudiants inscrit qui se trouvent décochés sont désinscrits - - Confirmation: indiquer les étudiants inscrits et ceux désinscrits, le total courant. + - Confirmation: indiquer les étudiants inscrits et ceux désinscrits, le total courant. """ inscrit_groupes = int(inscrit_groupes) @@ -292,11 +290,11 @@ def formsemestre_inscr_passage( etuds = etuds.split(",") # vient du form de confirmation auth_etuds_by_sem, inscrits, candidats = list_authorized_etuds_by_sem(context, sem) - etuds_set = Set(etuds) - candidats_set = Set(candidats) - inscrits_set = Set(inscrits) + etuds_set = set(etuds) + candidats_set = set(candidats) + inscrits_set = set(inscrits) candidats_non_inscrits = candidats_set - inscrits_set - inscrits_ailleurs = Set(list_inscrits_date(context, sem)) + inscrits_ailleurs = set(list_inscrits_date(context, sem)) def set_to_sorted_etud_list(etudset): etuds = [candidats[etudid] for etudid in etudset] @@ -489,7 +487,7 @@ def etuds_select_boxes( """Boites pour selection étudiants par catégorie auth_etuds_by_cat = { category : { 'info' : {}, 'etuds' : ... } inscrits_ailleurs = - sel_inscrits= + sel_inscrits= export_cat_xls = """ if export_cat_xls: @@ -619,11 +617,8 @@ def etuds_select_box_xls(context, src_cat): "export a box to excel" etuds = src_cat["etuds"] columns_ids = ["etudid", "sexe", "nom", "prenom", "etape"] - titles = {} - map( - lambda x, titles=titles: titles.__setitem__(x[0], x[1]), - zip(columns_ids, columns_ids), - ) + titles = {x: x for x in columns_ids} + # Ajoute colonne paiement inscription columns_ids.append("paiementinscription_str") titles["paiementinscription_str"] = "paiement inscription" diff --git a/sco_liste_notes.py b/sco_liste_notes.py index 591e74f8..79777ed8 100644 --- a/sco_liste_notes.py +++ b/sco_liste_notes.py @@ -41,14 +41,12 @@ import sco_excel from gen_tables import GenTable from htmlutils import histogram_notes -from sets import Set - def do_evaluation_listenotes(context, REQUEST): """ Affichage des notes d'une évaluation - args: evaluation_id + args: evaluation_id """ cnx = context.GetDBConnexion() mode = None @@ -267,8 +265,8 @@ def _make_table_notes( "prenom": "Prénom", "nomprenom": "Nom", "expl_key": "Rem.", - "email" : "e-mail", - "emailperso" : "e-mail perso" + "email": "e-mail", + "emailperso": "e-mail perso", } rows = [] @@ -323,8 +321,8 @@ def _make_table_notes( "prenom": strcapitalize(strlower(etud["prenom"])), "nomprenom": etud["nomprenom"], "group": grc, - "email" : etud["email"], - "emailperso" : etud["emailperso"], + "email": etud["email"], + "emailperso": etud["emailperso"], "_css_row_class": css_row_class or "", } ) @@ -381,7 +379,7 @@ def _make_table_notes( # Si module, ajoute moyenne du module: if len(evals) > 1: - notes = _add_moymod_column( + _add_moymod_column( context, sem["formsemestre_id"], e, @@ -397,7 +395,7 @@ def _make_table_notes( # Ajoute colonnes emails tout à droite: if with_emails: - columns_ids += [ "email", "emailperso" ] + columns_ids += ["email", "emailperso"] # Ajoute lignes en tête et moyennes if len(evals) > 0: rows = [coefs, note_max] + rows @@ -646,6 +644,7 @@ def _add_moymod_column( note_sur_20, keep_numeric, ): + """Ajoute la colonne moymod à rows""" col_id = "moymod" nt = context._getNotesCache().get_NotesTable( context, formsemestre_id @@ -701,7 +700,7 @@ def _eval_demijournee(E): def evaluation_check_absences(context, evaluation_id): """Vérifie les absences au moment de cette évaluation. Cas incohérents que l'on peut rencontrer pour chaque étudiant: - note et absent + note et absent ABS et pas noté absent ABS et absent justifié EXC et pas noté absent @@ -722,13 +721,13 @@ def evaluation_check_absences(context, evaluation_id): # Liste les absences à ce moment: A = context.Absences.ListeAbsJour(DateDMYtoISO(E["jour"]), am=am, pm=pm) - As = Set([x["etudid"] for x in A]) # ensemble des etudiants absents + As = set([x["etudid"] for x in A]) # ensemble des etudiants absents NJ = context.Absences.ListeAbsNonJustJour(DateDMYtoISO(E["jour"]), am=am, pm=pm) - NJs = Set([x["etudid"] for x in NJ]) # ensemble des etudiants absents non justifies + NJs = set([x["etudid"] for x in NJ]) # ensemble des etudiants absents non justifies Just = context.Absences.ListeAbsJour( DateDMYtoISO(E["jour"]), am=am, pm=pm, is_abs=None, is_just=True ) - Justs = Set([x["etudid"] for x in Just]) # ensemble des etudiants avec justif + Justs = set([x["etudid"] for x in Just]) # ensemble des etudiants avec justif # Les notes: NotesDB = context._notes_getall(evaluation_id) @@ -860,8 +859,7 @@ def evaluation_check_absences_html( def formsemestre_check_absences_html(context, formsemestre_id, REQUEST=None): - """Affiche etat verification absences pour toutes les evaluations du semestre ! - """ + """Affiche etat verification absences pour toutes les evaluations du semestre !""" sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) H = [ context.html_sem_header( diff --git a/sco_moduleimpl_status.py b/sco_moduleimpl_status.py index e9d969f5..21dd699b 100644 --- a/sco_moduleimpl_status.py +++ b/sco_moduleimpl_status.py @@ -27,7 +27,6 @@ """Tableau de bord module """ -from sets import Set from notesdb import * from sco_utils import * diff --git a/sco_parcours_dut.py b/sco_parcours_dut.py index 2da3d034..d45309c5 100644 --- a/sco_parcours_dut.py +++ b/sco_parcours_dut.py @@ -80,8 +80,7 @@ class DecisionSem: def SituationEtudParcours(context, etud, formsemestre_id): - """renvoie une instance de SituationEtudParcours (ou sous-classe spécialisée) - """ + """renvoie une instance de SituationEtudParcours (ou sous-classe spécialisée)""" nt = context._getNotesCache().get_NotesTable( context, formsemestre_id ) # > get_etud_decision_sem, get_etud_moy_gen, get_ues, get_etud_ue_status, etud_check_conditions_ues @@ -248,7 +247,7 @@ class SituationEtudParcoursGeneric: decision = self.nt.get_etud_decision_sem(self.etudid) return decision and code_semestre_validant(decision["code"]) else: - to_validate = Set( + to_validate = set( range(1, self.parcours.NB_SEM + 1) ) # ensemble des indices à valider if exclude_current and self.sem["semestre_id"] in to_validate: @@ -652,8 +651,7 @@ class SituationEtudParcoursGeneric: class SituationEtudParcoursECTS(SituationEtudParcoursGeneric): - """Gestion parcours basés sur ECTS - """ + """Gestion parcours basés sur ECTS""" def __init__(self, context, etud, formsemestre_id, nt): SituationEtudParcoursGeneric.__init__(self, context, etud, formsemestre_id, nt) @@ -663,7 +661,7 @@ class SituationEtudParcoursECTS(SituationEtudParcoursGeneric): def get_possible_choices(self, assiduite=True): """Listes de décisions "recommandées" (hors décisions manuelles) - + Dans ce type de parcours, on n'utilise que ADM, AJ, et ADJ (?). """ etud_moy_infos = self.nt.get_etud_moy_infos(self.etudid) @@ -939,8 +937,7 @@ def do_formsemestre_validate_ue( semestre_id=None, is_external=0, ): - """Ajoute ou change validation UE - """ + """Ajoute ou change validation UE""" args = { "formsemestre_id": formsemestre_id, "etudid": etudid, @@ -1026,17 +1023,17 @@ def formsemestre_get_autorisation_inscription(context, etudid, origin_formsemest def formsemestre_get_etud_capitalisation(context, sem, etudid): """Liste des UE capitalisées (ADM) correspondant au semestre sem et à l'étudiant. - + Recherche dans les semestres de la même formation (code) avec le même semestre_id et une date de début antérieure à celle du semestre mentionné. Et aussi les UE externes validées. - + Resultat: [ { 'formsemestre_id' : 'ue_id' : ue_id dans le semestre origine - 'ue_code' : + 'ue_code' : 'moy_ue' : - 'event_date' : - 'is_external' + 'event_date' : + 'is_external' } ] """ cnx = context.GetDBConnexion() diff --git a/sco_portal_apogee.py b/sco_portal_apogee.py index e1b5c1a6..f1e30162 100644 --- a/sco_portal_apogee.py +++ b/sco_portal_apogee.py @@ -28,7 +28,16 @@ """Liaison avec le portail ENT (qui donne accès aux infos Apogée) """ -from sco_utils import * +import os, time +import urllib +import xml +import xml.sax.saxutils +import xml.dom.minidom +import datetime + +import sco_utils +from sco_utils import ScoEtudInscrit, log, ScoValueError, DictDefault +from sco_utils import SCO_TMPDIR, SCO_ENCODING SCO_CACHE_ETAPE_FILENAME = os.path.join(SCO_TMPDIR, "last_etapes.xml") @@ -153,7 +162,7 @@ def get_inscrits_etape(context, code_etape, anneeapogee=None, ntrials=2): if portal_timeout > 0: actual_timeout = max(1, actual_timeout) for _ntrial in range(ntrials): - doc = query_portal(req, timeout=actual_timeout) + doc = sco_utils.query_portal(req, timeout=actual_timeout) if doc: break if not doc: @@ -194,7 +203,7 @@ def query_apogee_portal(context, **args): return [] portal_timeout = context.get_preference("portal_timeout") req = etud_url + "?" + urllib.urlencode(args.items()) - doc = query_portal(req, timeout=portal_timeout) # sco_utils + doc = sco_utils.query_portal(req, timeout=portal_timeout) # sco_utils return xml_to_list_of_dicts(doc, req=req) @@ -250,7 +259,7 @@ def get_infos_apogee_allaccents(context, nom, prenom): "essai recup infos avec differents codages des accents" if nom: unom = unicode(nom, SCO_ENCODING) - nom_noaccents = str(suppression_diacritics(unom)) + nom_noaccents = str(sco_utils.suppression_diacritics(unom)) nom_utf8 = unom.encode("utf-8") else: nom_noaccents = nom @@ -258,7 +267,7 @@ def get_infos_apogee_allaccents(context, nom, prenom): if prenom: uprenom = unicode(prenom, SCO_ENCODING) - prenom_noaccents = str(suppression_diacritics(uprenom)) + prenom_noaccents = str(sco_utils.suppression_diacritics(uprenom)) prenom_utf8 = uprenom.encode("utf-8") else: prenom_noaccents = prenom @@ -314,7 +323,7 @@ def get_etud_apogee(context, code_nip): return {} portal_timeout = context.get_preference("portal_timeout") req = etud_url + "?" + urllib.urlencode((("nip", code_nip),)) - doc = query_portal(req, timeout=portal_timeout) + doc = sco_utils.query_portal(req, timeout=portal_timeout) d = _normalize_apo_fields(xml_to_list_of_dicts(doc, req=req)) if not d: return None @@ -378,7 +387,7 @@ def get_etapes_apogee(context): "get_etapes_apogee: requesting '%s' with timeout=%s" % (etapes_url, portal_timeout) ) - doc = query_portal(etapes_url, timeout=portal_timeout) + doc = sco_utils.query_portal(etapes_url, timeout=portal_timeout) try: infos = _parse_etapes_from_xml(context, doc) # cache le resultat (utile si le portail repond de façon intermitente) @@ -473,7 +482,7 @@ def _normalize_apo_fields(infolist): for infos in infolist: if infos.has_key("paiementinscription"): infos["paiementinscription"] = ( - strlower(infos["paiementinscription"]) == "true" + sco_utils.strlower(infos["paiementinscription"]) == "true" ) if infos["paiementinscription"]: infos["paiementinscription_str"] = "ok" @@ -508,7 +517,7 @@ def check_paiement_etuds(context, etuds): Seuls les etudiants avec code NIP sont renseignés. - Renseigne l'attribut booleen 'paiementinscription' dans chaque etud, ainsi que l'étape. + Renseigne l'attribut booleen 'paiementinscription' dans chaque etud. En sortie: modif les champs de chaque etud 'paiementinscription' : True, False ou None @@ -553,5 +562,5 @@ def get_maquette_apogee(context, etape="", annee_scolaire=""): + "?" + urllib.urlencode((("etape", etape), ("annee", annee_scolaire))) ) - doc = query_portal(req, timeout=portal_timeout) + doc = sco_utils.query_portal(req, timeout=portal_timeout) return doc diff --git a/sco_recapcomplet.py b/sco_recapcomplet.py index 3a86ccd7..fb28e871 100644 --- a/sco_recapcomplet.py +++ b/sco_recapcomplet.py @@ -35,6 +35,7 @@ import sco_evaluations import sco_formsemestre import sco_formsemestre_status import sco_bulletins_xml +import sco_bulletins_json import sco_codes_parcours import sco_bac @@ -71,7 +72,7 @@ def formsemestre_recapcomplet( else: hidebac = int(hidebac) xml_with_decisions = int(xml_with_decisions) - isFile = tabformat in ("csv", "xls", "xml", "xlsall") + isFile = tabformat in ("csv", "xls", "xml", "xlsall", "json") H = [] if not isFile: H += [ @@ -103,6 +104,7 @@ def formsemestre_recapcomplet( ("xlsall", "Fichier tableur avec toutes les évals"), ("csv", "Fichier tableur (CSV)"), ("xml", "Fichier XML"), + ("json", "JSON"), ): if format == tabformat: selected = " selected" @@ -129,8 +131,7 @@ def formsemestre_recapcomplet( H.append("checked") H.append(""" >cacher bac""") if tabformat == "xml": - REQUEST.RESPONSE.setHeader("content-type", "text/xml") - + REQUEST.RESPONSE.setHeader("content-type", XML_MIMETYPE) H.append( do_formsemestre_recapcomplet( context, @@ -181,7 +182,7 @@ def do_formsemestre_recapcomplet( context=None, REQUEST=None, formsemestre_id=None, - format="html", # html, xml, xls, xlsall + format="html", # html, xml, xls, xlsall, json hidemodules=False, # ne pas montrer les modules (ignoré en XML) hidebac=False, # pas de colonne Bac (ignoré en XML) xml_nodate=False, # format XML sans dates (sert pour debug cache: comparaison de XML) @@ -191,8 +192,7 @@ def do_formsemestre_recapcomplet( disable_etudlink=False, rank_partition_id=None, # si None, calcul rang global ): - """Calcule et renvoie le tableau récapitulatif. - """ + """Calcule et renvoie le tableau récapitulatif.""" data, filename, format = make_formsemestre_recapcomplet(**vars()) if format == "xml" or format == "html": return data @@ -200,6 +200,8 @@ def do_formsemestre_recapcomplet( return sendCSVFile(REQUEST, data, filename) elif format[:3] == "xls": return sco_excel.sendExcelFile(REQUEST, data, filename) + elif format == "json": + return sendJSON(REQUEST, data) else: raise ValueError("unknown format %s" % format) @@ -208,7 +210,7 @@ def make_formsemestre_recapcomplet( context=None, REQUEST=None, formsemestre_id=None, - format="html", # html, xml, xls, xlsall + format="html", # html, xml, xls, xlsall, json hidemodules=False, # ne pas montrer les modules (ignoré en XML) hidebac=False, # pas de colonne Bac (ignoré en XML) xml_nodate=False, # format XML sans dates (sert pour debug cache: comparaison de XML) @@ -226,6 +228,10 @@ def make_formsemestre_recapcomplet( return _formsemestre_recapcomplet_xml( context, formsemestre_id, xml_nodate, xml_with_decisions=xml_with_decisions ) + elif format == "json": + return _formsemestre_recapcomplet_json( + context, formsemestre_id, xml_nodate, xml_with_decisions=xml_with_decisions + ) if format[:3] == "xls": keep_numeric = True # pas de conversion des notes en strings else: @@ -261,7 +267,7 @@ def make_formsemestre_recapcomplet( else: rank_partition = sco_groups.get_default_partition(context, formsemestre_id) rank_label = "Rg" - + T = nt.get_table_moyennes_triees() if not T: return "", "", format @@ -556,19 +562,18 @@ def make_formsemestre_recapcomplet( cls = "recap_tit_ue" else: cls = "recap_tit" - if i == 0 or F[0][i] == "classement": # Rang: force tri numerique pour sortable + if ( + i == 0 or F[0][i] == "classement" + ): # Rang: force tri numerique pour sortable cls = cls + " sortnumeric" if cod2mod.has_key(F[0][i]): # lien vers etat module mod = cod2mod[F[0][i]] - cells += ( - '%s' - % ( - cls, - mod["moduleimpl_id"], - mod["module"]["titre"], - context.Users.user_info(mod["responsable_id"])["nomcomplet"], - F[0][i], - ) + cells += '%s' % ( + cls, + mod["moduleimpl_id"], + mod["module"]["titre"], + context.Users.user_info(mod["responsable_id"])["nomcomplet"], + F[0][i], ) else: cells += '%s' % (cls, F[0][i]) @@ -788,8 +793,7 @@ def _list_notes_evals_stats(context, evals, key): def _formsemestre_recapcomplet_xml( context, formsemestre_id, xml_nodate, xml_with_decisions=False ): - "XML export: liste tous les bulletins XML" - # REQUEST.RESPONSE.setHeader('content-type', XML_MIMETYPE) + "XML export: liste tous les bulletins XML." nt = context._getNotesCache().get_NotesTable( context, formsemestre_id @@ -827,3 +831,42 @@ def _formsemestre_recapcomplet_xml( ) doc._pop() return repr(doc), "", "xml" + + +def _formsemestre_recapcomplet_json( + context, formsemestre_id, xml_nodate, xml_with_decisions=False +): + "JSON export: liste tous les bulletins JSON" + if xml_nodate: + docdate = "" + else: + docdate = datetime.datetime.now().isoformat() + evals = sco_evaluations.do_evaluation_etat_in_sem(context, formsemestre_id) + J = { + "docdate": docdate, + "formsemestre_id": formsemestre_id, + "evals_info": { + "nb_evals_completes": evals["nb_evals_completes"], + "nb_evals_en_cours": evals["nb_evals_en_cours"], + "nb_evals_vides": evals["nb_evals_vides"], + "date_derniere_note": evals["last_modif"], + }, + "bulletins": [], + } + bulletins = J["bulletins"] + nt = context._getNotesCache().get_NotesTable( + context, formsemestre_id + ) # > get_table_moyennes_triees + T = nt.get_table_moyennes_triees() + for t in T: + etudid = t[-1] + bulletins.append( + sco_bulletins_json.formsemestre_bulletinetud_published_dict( + context, + formsemestre_id, + etudid, + force_publishing=True, + xml_with_decisions=xml_with_decisions, + ) + ) + return J, "", "json" diff --git a/sco_report.py b/sco_report.py index af9ac196..4c439349 100644 --- a/sco_report.py +++ b/sco_report.py @@ -29,8 +29,8 @@ - statistiques decisions - suivi cohortes """ -from mx.DateTime import DateTime as mxDateTime import mx.DateTime +from mx.DateTime import DateTime as mxDateTime import tempfile, urllib, re @@ -396,12 +396,12 @@ def table_suivi_cohorte( logt("A: orig etuds set") S = {formsemestre_id: sem} # ensemble de formsemestre_id - orig_set = Set() # ensemble d'etudid du semestre d'origine - bacs = Set() - bacspecialites = Set() - annee_bacs = Set() - sexes = Set() - statuts = Set() + orig_set = set() # ensemble d'etudid du semestre d'origine + bacs = set() + bacspecialites = set() + annee_bacs = set() + sexes = set() + statuts = set() for etudid in etudids: etud = context.getEtudInfo(etudid=etudid, filled=True)[0] bacspe = etud["bac"] + " / " + etud["specialite"] @@ -429,7 +429,7 @@ def table_suivi_cohorte( # tri les semestres par date de debut for s in sems: d, m, y = [int(x) for x in s["date_debut"].split("/")] - s["date_debut_mx"] = mxDateTime(y, m, d) + s["date_debut_mx"] = mxDateTime(y, m, d) # pylint: disable=not-callable sems.sort(lambda x, y: cmp(x["date_debut_mx"], y["date_debut_mx"])) # 2-- Pour chaque semestre, trouve l'ensemble des etudiants venant de sem @@ -439,7 +439,7 @@ def table_suivi_cohorte( ins = context.do_formsemestre_inscription_list( args={"formsemestre_id": s["formsemestre_id"]} ) # sans dems - inset = Set([i["etudid"] for i in ins]) + inset = set([i["etudid"] for i in ins]) s["members"] = orig_set.intersection(inset) nb_dipl = 0 # combien de diplomes dans ce semestre ? if s["semestre_id"] == nt.parcours.NB_SEM: @@ -461,7 +461,7 @@ def table_suivi_cohorte( # semestre de depart: porigin = periodsem() d, m, y = [int(x) for x in sem["date_debut"].split("/")] - porigin.datedebut = mxDateTime(y, m, d) + porigin.datedebut = mxDateTime(y, m, d) # pylint: disable=not-callable porigin.sems = [sem] # @@ -480,7 +480,7 @@ def table_suivi_cohorte( P.append(p) # 4-- regroupe par indice de semestre S_i - indices_sems = list(Set([s["semestre_id"] for s in sems])) + indices_sems = list(set([s["semestre_id"] for s in sems])) indices_sems.sort() for p in P: p.nb_etuds = 0 # nombre total d'etudiants dans la periode @@ -518,7 +518,7 @@ def table_suivi_cohorte( d = {"row_title": "Autre semestre"} for p in P: - etuds_period = Set() + etuds_period = set() for s in p.sems: if s["semestre_id"] == idx_sem: etuds_period = etuds_period.union(s["members"]) @@ -533,8 +533,8 @@ def table_suivi_cohorte( logt("D: cout dems reos") sem["dems"], sem["reos"] = _count_dem_reo(context, formsemestre_id, sem["members"]) for p in P: - p.dems = Set() - p.reos = Set() + p.dems = set() + p.reos = set() for s in p.sems: d, r = _count_dem_reo(context, s["formsemestre_id"], s["members"]) p.dems.update(d) @@ -879,8 +879,8 @@ def _count_dem_reo(context, formsemestre_id, etudids): nt = context._getNotesCache().get_NotesTable( context, formsemestre_id ) # > get_etud_etat, get_etud_decision_sem - dems = Set() - reos = Set() + dems = set() + reos = set() for etudid in etudids: if nt.get_etud_etat(etudid) == "D": dems.add(etudid) @@ -994,11 +994,11 @@ def tsp_etud_list( ) # > get_etudids, etudids = nt.get_etudids() etuds = [] - bacs = Set() - bacspecialites = Set() - annee_bacs = Set() - sexes = Set() - statuts = Set() + bacs = set() + bacspecialites = set() + annee_bacs = set() + sexes = set() + statuts = set() for etudid in etudids: etud = context.getEtudInfo(etudid=etudid, filled=True)[0] bacspe = etud["bac"] + " / " + etud["specialite"] @@ -1228,25 +1228,25 @@ def graph_parcours( if not etuds: return "", etuds, bacs, bacspecialites, annee_bacs, sexes, statuts edges = DictDefault( - defaultvalue=Set() + defaultvalue=set() ) # {(formsemestre_id_origin, formsemestre_id_dest) : etud_set} sems = {} - effectifs = DictDefault(defaultvalue=Set()) # formsemestre_id : etud_set + effectifs = DictDefault(defaultvalue=set()) # formsemestre_id : etud_set decisions = DictDefault(defaultvalue={}) # formsemestre_id : { code : nb_etud } isolated_nodes = [] - connected_nodes = Set() + connected_nodes = set() diploma_nodes = [] dem_nodes = {} # formsemestre_id : noeud pour demissionnaires nar_nodes = {} # formsemestre_id : noeud pour NAR for etud in etuds: - next = None + nxt = None etudid = etud["etudid"] for s in etud["sems"]: # du plus recent au plus ancien nt = context._getNotesCache().get_NotesTable( context, s["formsemestre_id"] ) # > get_etud_decision_sem, get_etud_etat dec = nt.get_etud_decision_sem(etudid) - if next: + if nxt: if ( s["semestre_id"] == nt.parcours.NB_SEM and dec @@ -1255,17 +1255,17 @@ def graph_parcours( ): # cas particulier du diplome puis poursuite etude edges[ - ("_dipl_" + s["formsemestre_id"], next["formsemestre_id"]) + ("_dipl_" + s["formsemestre_id"], nxt["formsemestre_id"]) ].add(etudid) else: - edges[(s["formsemestre_id"], next["formsemestre_id"])].add(etudid) + edges[(s["formsemestre_id"], nxt["formsemestre_id"])].add(etudid) connected_nodes.add(s["formsemestre_id"]) - connected_nodes.add(next["formsemestre_id"]) + connected_nodes.add(nxt["formsemestre_id"]) else: isolated_nodes.append(s["formsemestre_id"]) sems[s["formsemestre_id"]] = s effectifs[s["formsemestre_id"]].add(etudid) - next = s + nxt = s # Compte decisions jury de chaque semestres: dc = decisions[s["formsemestre_id"]] if dec: diff --git a/sco_synchro_etuds.py b/sco_synchro_etuds.py index 0a81e3c6..1bfef292 100644 --- a/sco_synchro_etuds.py +++ b/sco_synchro_etuds.py @@ -29,8 +29,8 @@ """ -from sco_utils import * -from notesdb import * +from sco_utils import ScoEtudInscrit, annee_scolaire_debut, log, ScoValueError +from notesdb import ScoDocCursor import sco_portal_apogee import sco_inscr_passage @@ -698,7 +698,7 @@ def do_import_etud_admission( log("do_import_etud_admission: etud=%s" % etud) al = scolars.admission_list(cnx, args={"etudid": etudid}) if not al: - adm_id = scolars.admission_create(cnx, args) + scolars.admission_create(cnx, args) # -> adm_id else: # existing data: merge e = al[0] diff --git a/sco_utils.py b/sco_utils.py index 2cc6535c..059d3cc7 100644 --- a/sco_utils.py +++ b/sco_utils.py @@ -61,8 +61,6 @@ except ImportError: # fallback for very old ScoDoc instances STRING_TYPES = StringType -from sets import Set - from PIL import Image as PILImage # XML generation package (apt-get install jaxml) @@ -215,6 +213,7 @@ if SCO_SRCDIR: SCO_SRCDIR += "/" else: SCO_SRCDIR = "/opt/scodoc/Products/ScoDoc/" # debug mode +CONFIG = None try: _config_filename = SCO_SRCDIR + "config/scodoc_config.py" _config_text = open(_config_filename).read() @@ -512,7 +511,7 @@ def make_filename(name): VALID_CARS = ( "-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.!" # no / ! ) -VALID_CARS_SET = Set(VALID_CARS) +VALID_CARS_SET = set(VALID_CARS) VALID_EXP = re.compile("^[" + VALID_CARS + "]+$") @@ -558,12 +557,14 @@ def sendPDFFile(REQUEST, data, filename): class ScoDocJSONEncoder(json.JSONEncoder): - def default(self, o): + def default(self, o): # pylint: disable=E0202 import sco_formsemestre - # horrible hack pour encoder les dates + # horrible hack pour encoder les dates mx if str(type(o)) == "": return o.strftime("%Y-%m-%dT%H:%M:%S") + if isinstance(o, (datetime.date, datetime.datetime)): + return o.isoformat() elif isinstance(o, sco_formsemestre.ApoEtapeVDI): return str(o) else: