diff --git a/app/scodoc/SuppressAccents.py b/app/scodoc/SuppressAccents.py index f0b4d34f..18332fbb 100644 --- a/app/scodoc/SuppressAccents.py +++ b/app/scodoc/SuppressAccents.py @@ -5,6 +5,7 @@ Source: http://wikipython.flibuste.net/moin.py/JouerAvecUnicode#head-1213938516c633958921591439c33d202244e2f4 """ +import six _reptable = {} @@ -202,5 +203,5 @@ def suppression_diacritics(s): @rtype: unicode """ if isinstance(s, str): - s = unicode(s, "utf8", "replace") + s = six.text_type(s, "utf8", "replace") return s.translate(_reptable) diff --git a/app/scodoc/TrivialFormulator.py b/app/scodoc/TrivialFormulator.py index 3934d576..06b0f60e 100644 --- a/app/scodoc/TrivialFormulator.py +++ b/app/scodoc/TrivialFormulator.py @@ -196,12 +196,12 @@ class TF: for (field, descr) in self.formdescription: # special case for boolcheckbox if descr.get("input_type", None) == "boolcheckbox" and self.submitted(): - if not self.values.has_key(field): + if field not in self.values: self.values[field] = 0 else: self.values[field] = 1 - if not self.values.has_key(field): - if descr.has_key("default"): # first: default in form description + if field not in self.values: + if "default" in descr: # first: default in form description self.values[field] = descr["default"] else: # then: use initvalues dict self.values[field] = self.initvalues.get(field, "") @@ -214,7 +214,7 @@ class TF: ): self.values[field] = str(self.values[field]) # - if not self.values.has_key("tf-checked"): + if "tf-checked" not in self.values: if self.submitted(): # si rien n'est coché, tf-checked n'existe plus dans la reponse self.values["tf-checked"] = [] @@ -264,14 +264,14 @@ class TF: ) ok = 0 if typ[:3] == "int" or typ == "float" or typ == "real": - if descr.has_key("min_value") and val < descr["min_value"]: + if "min_value" in descr and val < descr["min_value"]: msg.append( "La valeur (%d) du champ '%s' est trop petite (min=%s)" % (val, field, descr["min_value"]) ) ok = 0 - if descr.has_key("max_value") and val > descr["max_value"]: + if "max_value" in descr and val > descr["max_value"]: msg.append( "La valeur (%s) du champ '%s' est trop grande (max=%s)" % (val, field, descr["max_value"]) @@ -279,7 +279,7 @@ class TF: ok = 0 # allowed values - if descr.has_key("allowed_values"): + if "allowed_values" in descr: if descr.get("input_type", None) == "checkbox": # for checkboxes, val is a list for v in val: @@ -293,7 +293,7 @@ class TF: elif not val in descr["allowed_values"]: msg.append("valeur invalide (%s) pour le champ '%s'" % (val, field)) ok = 0 - if descr.has_key("validator"): + if "validator" in descr: if not descr["validator"](val, field): msg.append("valeur invalide (%s) pour le champ '%s'" % (val, field)) ok = 0 diff --git a/app/scodoc/notesdb.py b/app/scodoc/notesdb.py index b46b2c9b..3df2fd46 100644 --- a/app/scodoc/notesdb.py +++ b/app/scodoc/notesdb.py @@ -1,8 +1,8 @@ # -*- mode: python -*- # -*- coding: utf-8 -*- -from __future__ import absolute_import -import pdb, os, sys, string + +import string import traceback import psycopg2 import psycopg2.pool diff --git a/app/scodoc/pe_avislatex.py b/app/scodoc/pe_avislatex.py index fbf356f8..ba8654d5 100644 --- a/app/scodoc/pe_avislatex.py +++ b/app/scodoc/pe_avislatex.py @@ -224,9 +224,9 @@ def get_code_latex_avis_etudiant( scu.SCO_ENCODING ) - # Gestion des pb d'encodage XXX debug - assert isinstance(tag_latex, unicode) - assert isinstance(valeur, unicode) + # Vérification des pb d'encodage (debug) + # assert isinstance(tag_latex, unicode) + # assert isinstance(valeur, unicode) # Substitution code = code.replace("**" + tag_latex + "**", valeur) diff --git a/app/scodoc/pe_jurype.py b/app/scodoc/pe_jurype.py index 4c9fd4be..55bf2601 100644 --- a/app/scodoc/pe_jurype.py +++ b/app/scodoc/pe_jurype.py @@ -46,10 +46,10 @@ import os try: from cStringIO import StringIO -except: +except ImportError: try: from StringIO import StringIO - except: + except ImportError: from io import StringIO from zipfile import ZipFile, BadZipfile import pprint @@ -382,7 +382,7 @@ class JuryPE: c'est à dire ceux pour lesquels il faudra prendre en compte ses notes dans les calculs de moyenne (type 1A=S1+S2/2) """ - if not self.PARCOURSINFO_DICT.has_key(etudid): + if etudid not in self.PARCOURSINFO_DICT: etud = self.get_cache_etudInfo_d_un_etudiant( self.context, etudid ) # On charge les données de l'étudiant @@ -476,7 +476,7 @@ class JuryPE: reponse = True if pe_tools.PE_DEBUG and pe_tools.PE_DEBUG >= 2: pe_tools.pe_print(" -> à éliminer car réorienté (NAR)") - if "DEM" in parcours.values(): # Eliminé car DEM + if "DEM" in list(parcours.values()): # Eliminé car DEM reponse = True if pe_tools.PE_DEBUG and pe_tools.PE_DEBUG >= 2: pe_tools.pe_print(" -> à éliminer car DEM") @@ -567,8 +567,8 @@ class JuryPE: dec = nt.get_etud_decision_sem( etudid ) # quelle est la décision du jury ? - if ( - dec and dec["code"] in sco_codes_parcours.CODES_SEM_VALIDES.keys() + if dec and dec["code"] in list( + sco_codes_parcours.CODES_SEM_VALIDES.keys() ): # isinstance( sesMoyennes[i+1], float) and # mT = sesMoyennes[i+1] # substitue la moyenne si le semestre suivant est "valide" leFid = sem["formsemestre_id"] @@ -603,7 +603,7 @@ class JuryPE: charge également les données des nouveaux étudiants qui en font partis. """ # Semestre taggué avec classement dans le groupe - if not self.semTagDict.has_key(fid): + if fid not in self.semTagDict: nt = self.get_cache_notes_d_un_semestre(self.context, fid) # Création du semestres @@ -656,7 +656,7 @@ class JuryPE: * '3S', '4S' => fusion des semestres * [ 'Si', 'iA' , ... ] => une liste combinant les formats précédents """ - champs_possibles = JuryPE.PARCOURS.keys() + champs_possibles = list(JuryPE.PARCOURS.keys()) if ( not isinstance(liste_semestres, list) and not isinstance(liste_semestres, str) @@ -962,7 +962,7 @@ class JuryPE: allTags = allTags.union(set(self.get_allTagForAggregat(nom))) return sorted(list(allTags)) if len(allTags) > 0 else [] - def table_syntheseJury(self, mode="singlesheet"): # XXX was str_syntheseJury + def table_syntheseJury(self, mode="singlesheet"): # was str_syntheseJury """Table(s) du jury mode: singlesheet ou multiplesheet pour export excel """ @@ -1011,7 +1011,7 @@ class JuryPE: ] # Les aggrégats à afficher par ordre tel que indiqué dans le dictionnaire parcours - aggregats = JuryPE.PARCOURS.keys() # ['S1', 'S2', ..., '1A', '4S'] + aggregats = list(JuryPE.PARCOURS.keys()) # ['S1', 'S2', ..., '1A', '4S'] aggregats = sorted( aggregats, key=lambda t: JuryPE.PARCOURS[t]["ordre"] ) # Tri des aggrégats diff --git a/app/scodoc/pe_semestretag.py b/app/scodoc/pe_semestretag.py index 13c36d21..18e5ba7c 100644 --- a/app/scodoc/pe_semestretag.py +++ b/app/scodoc/pe_semestretag.py @@ -130,7 +130,7 @@ class SemestreTag(pe_tagtable.TableTag): self.add_moyennesTag(tag, self.comp_MoyennesTag(tag, force=True)) self.add_moyennesTag("dut", self.get_moyennes_DUT()) self.taglist = sorted( - self.tagdict.keys() + ["dut"] + list(self.tagdict.keys()) + ["dut"] ) # actualise la liste des tags # ----------------------------------------------------------------------------- @@ -170,7 +170,7 @@ class SemestreTag(pe_tagtable.TableTag): tag ) # extrait un tagname et un éventuel coefficient de pondération (par defaut: 1) # tagname = tagname - if not tagdict.has_key(tagname): # Ajout d'une clé pour le tag + if tagname not in tagdict: # Ajout d'une clé pour le tag tagdict[tagname] = {} # Ajout du modimpl au tagname considéré diff --git a/app/scodoc/pe_settag.py b/app/scodoc/pe_settag.py index 2db2b4a1..05eba20f 100644 --- a/app/scodoc/pe_settag.py +++ b/app/scodoc/pe_settag.py @@ -126,7 +126,7 @@ class SetTag(pe_tagtable.TableTag): # ------------------------------------------------------------------------------------------------------------------- def get_etudids(self): - return self.identdict.keys() + return list(self.identdict.keys()) # ------------------------------------------------------------------------------------------------------------------- def do_taglist(self): @@ -272,7 +272,7 @@ class SetTagInterClasse(pe_tagtable.TableTag): # ------------------------------------------------------------------------------------------------------------------- def get_etudids(self): - return self.identdict.keys() + return list(self.identdict.keys()) # ------------------------------------------------------------------------------------------------------------------- def do_taglist(self): diff --git a/app/scodoc/pe_tools.py b/app/scodoc/pe_tools.py index 16b394fe..966799c8 100644 --- a/app/scodoc/pe_tools.py +++ b/app/scodoc/pe_tools.py @@ -44,6 +44,7 @@ import unicodedata import app.scodoc.sco_utils as scu from app.scodoc.notes_log import log +import six PE_DEBUG = 0 @@ -141,8 +142,8 @@ def escape_for_latex(s): } exp = re.compile( "|".join( - re.escape(unicode(key)) - for key in sorted(conv.keys(), key=lambda item: -len(item)) + re.escape(six.text_type(key)) + for key in sorted(list(conv.keys()), key=lambda item: -len(item)) ) ) return exp.sub(lambda match: conv[match.group()], s) diff --git a/app/scodoc/pe_view.py b/app/scodoc/pe_view.py index 7f989957..b1eeba62 100644 --- a/app/scodoc/pe_view.py +++ b/app/scodoc/pe_view.py @@ -98,7 +98,7 @@ def pe_view_sem_recap( jury = pe_jurype.JuryPE(context, semBase) # Ajout avis LaTeX au même zip: - etudids = jury.syntheseJury.keys() + etudids = list(jury.syntheseJury.keys()) # Récupération du template latex, du footer latex et du tag identifiant les annotations relatives aux PE # (chaines unicodes, html non quoté) diff --git a/app/scodoc/sco_abs.py b/app/scodoc/sco_abs.py index 74043f9b..c05924a6 100644 --- a/app/scodoc/sco_abs.py +++ b/app/scodoc/sco_abs.py @@ -215,7 +215,7 @@ def DateRangeISO(context, date_beg, date_end, workable=1): r.append(cur) cur = cur.next_day() - return map(lambda x: x.ISO(), r) + return [x.ISO() for x in r] def day_names(context): @@ -413,7 +413,7 @@ def ListeAbsDate(context, etudid, beg_date, end_date): A[(jour, matin)]["begin"] = dat + " 12:00:00" A[(jour, matin)]["end"] = dat + " 17:59:59" # sort - R = A.values() + R = list(A.values()) R.sort(key=lambda x: (x["begin"])) return R diff --git a/app/scodoc/sco_abs_views.py b/app/scodoc/sco_abs_views.py index 41f5ec44..fc3408d7 100644 --- a/app/scodoc/sco_abs_views.py +++ b/app/scodoc/sco_abs_views.py @@ -961,7 +961,7 @@ def _TablesAbsEtud( return "après-midi" def descr_exams(a): - if not a.has_key("evals"): + if "evals" not in a: return "" ex = [] for ev in a["evals"]: diff --git a/app/scodoc/sco_apogee_csv.py b/app/scodoc/sco_apogee_csv.py index 633cfbeb..e75b6324 100644 --- a/app/scodoc/sco_apogee_csv.py +++ b/app/scodoc/sco_apogee_csv.py @@ -89,6 +89,7 @@ import os from cStringIO import StringIO from zipfile import ZipFile import pprint +from functools import reduce # Pour la détection auto de l'encodage des fichiers Apogée: try: @@ -832,7 +833,7 @@ class ApoData: Si les id Apogée ne sont pas uniques (ce n'est pas garanti), garde le premier """ elts = collections.OrderedDict() - for col_id in sorted(cols.keys(), reverse=True): + for col_id in sorted(list(cols.keys()), reverse=True): col = cols[col_id] if col["Code"] in elts: elts[col["Code"]].append(col) @@ -967,7 +968,7 @@ class ApoData: % (declared, present) ) # l'ensemble de tous les codes des elements apo des semestres: - sem_elems = reduce(set.union, self.get_codes_by_sem().values(), set()) + sem_elems = reduce(set.union, list(self.get_codes_by_sem().values()), set()) return maq_elems, sem_elems @@ -1081,7 +1082,7 @@ def _apo_read_cols(f): if int(m.group(1)) != i: raise FormatError("invalid column id: %s for index %s" % (col_id, i)) - cols[col_id] = DictCol(zip(col_keys, fs)) + cols[col_id] = DictCol(list(zip(col_keys, fs))) cols[col_id].lineno = f.lineno # for debuging purpose return cols diff --git a/app/scodoc/sco_bulletins.py b/app/scodoc/sco_bulletins.py index 46a56a14..693b4e52 100644 --- a/app/scodoc/sco_bulletins.py +++ b/app/scodoc/sco_bulletins.py @@ -31,7 +31,7 @@ import time from types import StringType import pprint -import urllib +import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error from app.scodoc import htmlutils import email from email.mime.multipart import MIMEMultipart @@ -1111,7 +1111,7 @@ def _formsemestre_bulletinetud_header_html( # Menu endpoint = "notes.formsemestre_bulletinetud" url = REQUEST.URL0 - qurl = urllib.quote_plus(url + "?" + REQUEST.QUERY_STRING) + qurl = six.moves.urllib.parse.quote_plus(url + "?" + REQUEST.QUERY_STRING) menuBul = [ { diff --git a/app/scodoc/sco_bulletins_generator.py b/app/scodoc/sco_bulletins_generator.py index 41182296..8f0d2707 100644 --- a/app/scodoc/sco_bulletins_generator.py +++ b/app/scodoc/sco_bulletins_generator.py @@ -72,7 +72,7 @@ def bulletin_class_descriptions(): def bulletin_class_names(): - return BULLETIN_CLASSES.keys() + return list(BULLETIN_CLASSES.keys()) def bulletin_default_class_name(): diff --git a/app/scodoc/sco_codes_parcours.py b/app/scodoc/sco_codes_parcours.py index c1f0da02..da948d0a 100644 --- a/app/scodoc/sco_codes_parcours.py +++ b/app/scodoc/sco_codes_parcours.py @@ -29,6 +29,7 @@ """ from types import ListType, TupleType, FloatType import collections +from six.moves import range NOTES_TOLERANCE = 0.00499999999999 # si note >= (BARRE-TOLERANCE), considere ok # (permet d'eviter d'afficher 10.00 sous barre alors que la moyenne vaut 9.999) @@ -212,7 +213,7 @@ class TypeParcours: UNUSED_CODES = set() # Ensemble des codes jury non autorisés dans ce parcours UE_IS_MODULE = False # 1 seul module par UE (si plusieurs modules, etudiants censéments inscrits à un seul d'entre eux) ECTS_ONLY = False # Parcours avec progression basée uniquement sur les ECTS - ALLOWED_UE_TYPES = UE_TYPE_NAME.keys() # par defaut, autorise tous les types d'UE + ALLOWED_UE_TYPES = list(UE_TYPE_NAME.keys()) # par defaut, autorise tous les types d'UE def check(self, formation=None): return True, "" # status, diagnostic_message @@ -664,7 +665,7 @@ register_parcours(ParcoursMasterIG()) # ------------------------- -_tp = TYPES_PARCOURS.items() +_tp = list(TYPES_PARCOURS.items()) _tp.sort(key=lambda x: x[1].__doc__) # sort by intitulé FORMATION_PARCOURS_DESCRS = [p[1].__doc__ for p in _tp] # intitulés (eg pour menu) FORMATION_PARCOURS_TYPES = [p[0] for p in _tp] # codes numeriques (TYPE_PARCOURS) diff --git a/app/scodoc/sco_compute_moy.py b/app/scodoc/sco_compute_moy.py index f0d0e3ae..d9012c4b 100644 --- a/app/scodoc/sco_compute_moy.py +++ b/app/scodoc/sco_compute_moy.py @@ -284,7 +284,7 @@ def do_moduleimpl_moyennes(context, nt, mod): for e in valid_evals: if e["evaluation_type"] != EVALUATION_NORMALE: continue - if e["notes"].has_key(etudid): + if etudid in e["notes"]: note = e["notes"][etudid]["value"] if note is None: # ABSENT note = 0 @@ -315,7 +315,7 @@ def do_moduleimpl_moyennes(context, nt, mod): for e in evals: if ( (e["etat"]["evalcomplete"] or e["etat"]["evalattente"]) - and e["notes"].has_key(etudid) + and etudid in e["notes"] ) and (e["note_max"] > 0): note = e["notes"][etudid]["value"] if note is None: @@ -352,7 +352,7 @@ def do_moduleimpl_moyennes(context, nt, mod): R[etudid] = user_moy # Note de rattrapage ou deuxième session ? if eval_rattr: - if eval_rattr["notes"].has_key(etudid): + if etudid in eval_rattr["notes"]: note = eval_rattr["notes"][etudid]["value"] if note != None and note != NOTES_NEUTRALISE and note != NOTES_ATTENTE: if type(R[etudid]) != FloatType: @@ -397,7 +397,7 @@ def do_formsemestre_moyennes(context, nt, formsemestre_id): )[0] modimpl["module"] = mod # add module dict to moduleimpl (used by nt) moduleimpl_id = modimpl["moduleimpl_id"] - assert not D.has_key(moduleimpl_id) + assert moduleimpl_id not in D D[moduleimpl_id], valid_evals_mod, attente, expr_diag = do_moduleimpl_moyennes( context, nt, modimpl ) diff --git a/app/scodoc/sco_core.py b/app/scodoc/sco_core.py index 571283c0..97c848a3 100644 --- a/app/scodoc/sco_core.py +++ b/app/scodoc/sco_core.py @@ -5,7 +5,7 @@ """ import time -import thread +import six.moves._thread from scodoc_manager import sco_mgr import app.scodoc.sco_utils as scu @@ -27,7 +27,7 @@ CACHE_evaluations = {} def get_evaluations_cache(context): """returns cache for evaluations""" u = sco_mgr.get_db_uri() - if CACHE_evaluations.has_key(u): + if u in CACHE_evaluations: return CACHE_evaluations[u] else: log("get_evaluations_cache: new simpleCache") @@ -41,7 +41,7 @@ class CacheNotesTable: def __init__(self): log("new CacheTable (id=%s)" % id(self)) # - self.lock = thread.allocate_lock() + self.lock = six.moves._thread.allocate_lock() self.owner_thread = None # thread owning this cache self.nref = 0 # Cache des NotesTables @@ -55,13 +55,13 @@ class CacheNotesTable: def acquire(self): "If this thread does not own the cache, acquire the lock" - if thread.get_ident() != self.owner_thread: + if six.moves._thread.get_ident() != self.owner_thread: if self.lock.locked(): log( - "acquire: ident=%s waiting for lock" % thread.get_ident() + "acquire: ident=%s waiting for lock" % six.moves._thread.get_ident() ) # XXX debug self.lock.acquire() - self.owner_thread = thread.get_ident() + self.owner_thread = six.moves._thread.get_ident() if self.owner_thread is None: # bug catching log("WARNING: None thread id !") self.nref += 1 @@ -76,10 +76,10 @@ class CacheNotesTable: self.lock.release() self.owner_thread = None # Debug: - if thread.get_ident() != cur_owner_thread: + if six.moves._thread.get_ident() != cur_owner_thread: log( "WARNING: release: ident=%s != owner=%s nref=%d" - % (thread.get_ident(), cur_owner_thread, self.nref) + % (six.moves._thread.get_ident(), cur_owner_thread, self.nref) ) raise NoteProcessError("problem with notes cache") @@ -88,7 +88,7 @@ class CacheNotesTable: try: self.acquire() - if self.cache.has_key(formsemestre_id): + if formsemestre_id in self.cache: # log('cache hit %s (id=%s, thread=%s)' # % (formsemestre_id, id(self), thread.get_ident())) return self.cache[formsemestre_id] @@ -107,7 +107,7 @@ class CacheNotesTable: def get_cached_formsemestre_ids(self): "List of currently cached formsemestre_id" - return self.cache.keys() + return list(self.cache.keys()) def inval_cache(self, context, formsemestre_id=None, pdfonly=False): # > "expire cache pour un semestre (ou tous si pas d'argument)" @@ -144,7 +144,7 @@ class CacheNotesTable: ) if not pdfonly: for formsemestre_id in to_trash: - if self.cache.has_key(formsemestre_id): + if formsemestre_id in self.cache: log( "delete %s from cache (id=%s)" % (formsemestre_id, id(self)) @@ -191,7 +191,7 @@ class CacheNotesTable: if r: log( "get_bulletins_pdf(%s): cache hit %s (id=%s, thread=%s)" - % (version, formsemestre_id, id(self), thread.get_ident()) + % (version, formsemestre_id, id(self), six.moves._thread.get_ident()) ) return r finally: @@ -219,7 +219,7 @@ class CacheNotesTable: def get_notes_cache(context): "returns CacheNotesTable instance for us" u = sco_mgr.get_db_uri() # identifie le dept de facon unique - if not NOTES_CACHE_INST.has_key(u): + if u not in NOTES_CACHE_INST: log("getNotesCache: creating cache for %s" % u) NOTES_CACHE_INST[u] = CacheNotesTable() return NOTES_CACHE_INST[u] @@ -247,7 +247,7 @@ def inval_cache( # Cache inscriptions semestres def get_formsemestre_inscription_cache(context, format=None): u = sco_mgr.get_db_uri() - if CACHE_formsemestre_inscription.has_key(u): + if u in CACHE_formsemestre_inscription: return CACHE_formsemestre_inscription[u] else: log("get_formsemestre_inscription_cache: new simpleCache") diff --git a/app/scodoc/sco_debouche.py b/app/scodoc/sco_debouche.py index 4e9d52b9..0355ca79 100644 --- a/app/scodoc/sco_debouche.py +++ b/app/scodoc/sco_debouche.py @@ -110,7 +110,7 @@ def table_debouche_etudids(context, etudids, keep_numeric=True): etud = sco_etud.get_etud_info(filled=1, etudid=etudid)[0] # retrouve le "dernier" semestre (au sens de la date de fin) sems = etud["sems"] - es = [(sems[i]["date_fin_iso"], i) for i in range(len(sems))] + es = [(s["date_fin-iso"], i) for i, s in enumerate(sems)] imax = max(es)[1] last_sem = sems[imax] nt = sco_core.get_notes_cache( diff --git a/app/scodoc/sco_edit_formation.py b/app/scodoc/sco_edit_formation.py index 2231a14c..078ef425 100644 --- a/app/scodoc/sco_edit_formation.py +++ b/app/scodoc/sco_edit_formation.py @@ -265,14 +265,14 @@ def do_formation_create(context, args, REQUEST): cnx = ndb.GetDBConnexion() # check unique acronyme/titre/version a = args.copy() - if a.has_key("formation_id"): + if "formation_id" in a: del a["formation_id"] F = sco_formations.formation_list(context, args=a) if len(F) > 0: log("do_formation_create: error: %d formations matching args=%s" % (len(F), a)) raise ScoValueError("Formation non unique (%s) !" % str(a)) # Si pas de formation_code, l'enleve (default SQL) - if args.has_key("formation_code") and not args["formation_code"]: + if "formation_code" in args and not args["formation_code"]: del args["formation_code"] # r = sco_formations._formationEditor.create(cnx, args) @@ -294,10 +294,10 @@ def do_formation_edit(context, args): # car cela ne change que du cosmetique, (sauf eventuellement le code formation ?) # mais si verrouillée on ne peut changer le type de parcours if sco_formations.formation_has_locked_sems(context, args["formation_id"]): - if args.has_key("type_parcours"): + if "type_parcours" in args: del args["type_parcours"] # On ne peut jamais supprimer le code formation: - if args.has_key("formation_code") and not args["formation_code"]: + if "formation_code" in args and not args["formation_code"]: del args["formation_code"] cnx = ndb.GetDBConnexion() diff --git a/app/scodoc/sco_edit_module.py b/app/scodoc/sco_edit_module.py index b9c80e2d..fdec4467 100644 --- a/app/scodoc/sco_edit_module.py +++ b/app/scodoc/sco_edit_module.py @@ -133,7 +133,7 @@ def module_create(context, matiere_id=None, REQUEST=None): context, args={"formation_id": UE["formation_id"]} )[0] parcours = sco_codes_parcours.get_parcours_from_code(Fo["type_parcours"]) - semestres_indices = range(1, parcours.NB_SEM + 1) + semestres_indices = list(range(1, parcours.NB_SEM + 1)) H = [ html_sco_header.sco_header(context, REQUEST, page_title="Création d'un module"), """

Création d'un module dans la matière %(titre)s""" % M, @@ -374,7 +374,7 @@ def module_edit(context, module_id=None, REQUEST=None): Mids = ["%s!%s" % (x["ue_id"], x["matiere_id"]) for x in M] Mod["ue_matiere_id"] = "%s!%s" % (Mod["ue_id"], Mod["matiere_id"]) - semestres_indices = range(1, parcours.NB_SEM + 1) + semestres_indices = list(range(1, parcours.NB_SEM + 1)) dest_url = scu.NotesURL() + "/ue_list?formation_id=" + Mod["formation_id"] diff --git a/app/scodoc/sco_edit_ue.py b/app/scodoc/sco_edit_ue.py index cc11aa4d..8cd5d32b 100644 --- a/app/scodoc/sco_edit_ue.py +++ b/app/scodoc/sco_edit_ue.py @@ -300,7 +300,7 @@ def ue_edit(context, ue_id=None, create=False, formation_id=None, REQUEST=None): ] if parcours.UE_IS_MODULE: # demande le semestre pour creer le module immediatement: - semestres_indices = range(1, parcours.NB_SEM + 1) + semestres_indices = list(range(1, parcours.NB_SEM + 1)) fw.append( ( "semestre_id", @@ -901,7 +901,7 @@ def do_ue_edit(context, args, bypass_lock=False, dont_invalidate_cache=False): if (not bypass_lock) and ue_is_locked(context, ue["ue_id"]): raise ScoLockedFormError() # check: acronyme unique dans cette formation - if args.has_key("acronyme"): + if "acronyme" in args: new_acro = args["acronyme"] ues = do_ue_list( context, {"formation_id": ue["formation_id"], "acronyme": new_acro} @@ -910,7 +910,7 @@ def do_ue_edit(context, args, bypass_lock=False, dont_invalidate_cache=False): raise ScoValueError('Acronyme d\'UE "%s" déjà utilisé !' % args["acronyme"]) # On ne peut pas supprimer le code UE: - if args.has_key("ue_code") and not args["ue_code"]: + if "ue_code" in args and not args["ue_code"]: del args["ue_code"] cnx = ndb.GetDBConnexion() diff --git a/app/scodoc/sco_edt_cal.py b/app/scodoc/sco_edt_cal.py index 5902652e..73ab2b3e 100644 --- a/app/scodoc/sco_edt_cal.py +++ b/app/scodoc/sco_edt_cal.py @@ -33,7 +33,7 @@ XXX incompatible avec les ics HyperPlanning Paris 13 (était pour GPU). """ -import urllib2 +import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse import traceback import icalendar import pprint @@ -80,7 +80,7 @@ def formsemestre_load_ics(context, sem): ics_data = "" else: log("Loading edt from %s" % ics_url) - f = urllib2.urlopen( + f = six.moves.urllib.request.urlopen( ics_url, timeout=5 ) # 5s TODO: add config parameter, eg for slow networks ics_data = f.read() diff --git a/app/scodoc/sco_entreprises.py b/app/scodoc/sco_entreprises.py index eae5b31d..cf78f660 100644 --- a/app/scodoc/sco_entreprises.py +++ b/app/scodoc/sco_entreprises.py @@ -116,7 +116,7 @@ class EntreprisesEditor(EditableTable): for key in r: v = r[key] # format value - if not disable_formatting and self.output_formators.has_key(key): + if not disable_formatting and key in self.output_formators: v = self.output_formators[key](v) d[key] = v R.append(d) diff --git a/app/scodoc/sco_etape_apogee_view.py b/app/scodoc/sco_etape_apogee_view.py index 2eeca7c2..f16033d6 100644 --- a/app/scodoc/sco_etape_apogee_view.py +++ b/app/scodoc/sco_etape_apogee_view.py @@ -521,7 +521,7 @@ def view_apo_etuds(context, semset_id, title="", nips=[], format="html", REQUEST context, semset_id, title=title, - etuds=etuds.values(), + etuds=list(etuds.values()), keys=("nip", "etape_apo", "nom", "prenom", "inscriptions_scodoc"), format=format, REQUEST=REQUEST, diff --git a/app/scodoc/sco_etape_bilan.py b/app/scodoc/sco_etape_bilan.py index 94ee49b8..df9921e8 100644 --- a/app/scodoc/sco_etape_bilan.py +++ b/app/scodoc/sco_etape_bilan.py @@ -711,7 +711,7 @@ class EtapeBilan: rows = [] for data_etu in sorted( - self.etudiants.values(), key=lambda etu: etu.get_identity() + list(self.etudiants.values()), key=lambda etu: etu.get_identity() ): nip = data_etu.nip etudid = data_etu.etudid diff --git a/app/scodoc/sco_etud.py b/app/scodoc/sco_etud.py index 931c3fc3..7bcea4bd 100644 --- a/app/scodoc/sco_etud.py +++ b/app/scodoc/sco_etud.py @@ -339,7 +339,7 @@ def _check_duplicate_code(cnx, args, code_name, context, edit=True, REQUEST=None dest_url = "ficheEtud" parameters = {"etudid": etudid} else: - if args.has_key("tf-submitted"): + if "tf-submitted" in args: del args["tf-submitted"] OK = "Continuer" dest_url = "etudident_create_form" @@ -407,7 +407,7 @@ def identite_create(cnx, args, context=None, REQUEST=None): _check_duplicate_code(cnx, args, "code_nip", context, edit=False, REQUEST=REQUEST) _check_duplicate_code(cnx, args, "code_ine", context, edit=False, REQUEST=REQUEST) - if args.has_key("etudid"): + if "etudid" in args: etudid = args["etudid"] r = identite_list(cnx, {"etudid": etudid}) if r: @@ -593,7 +593,7 @@ class EtudIdentEditor: res = [] for i in R: res.append(i) - if A.has_key(i["etudid"]): + if i["etudid"] in A: # merge res[-1].update(A[i["etudid"]]) else: # pas d'etudiant trouve @@ -632,11 +632,11 @@ def make_etud_args(etudid=None, code_nip=None, REQUEST=None, raise_exc=True): elif code_nip: args = {"code_nip": code_nip} elif REQUEST: - if REQUEST.form.has_key("etudid"): + if "etudid" in REQUEST.form: args = {"etudid": REQUEST.form["etudid"]} - elif REQUEST.form.has_key("code_nip"): + elif "code_nip" in REQUEST.form: args = {"code_nip": REQUEST.form["code_nip"]} - elif REQUEST.form.has_key("code_ine"): + elif "code_ine" in REQUEST.form: args = {"code_ine": REQUEST.form["code_ine"]} if not args and raise_exc: raise ValueError("getEtudInfo: no parameter !") diff --git a/app/scodoc/sco_evaluations.py b/app/scodoc/sco_evaluations.py index 51e03d12..07a8968c 100644 --- a/app/scodoc/sco_evaluations.py +++ b/app/scodoc/sco_evaluations.py @@ -31,7 +31,7 @@ import datetime import operator import pprint import time -import urllib +import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error from app.scodoc.notes_log import log, logCallStack import app.scodoc.sco_utils as scu @@ -481,7 +481,7 @@ def do_evaluation_etat( groups[group["group_id"]] = group # isMissing = False - if NotesDB.has_key(i["etudid"]): + if i["etudid"] in NotesDB: val = NotesDB[i["etudid"]]["value"] if val == scu.NOTES_ATTENTE: isMissing = True @@ -792,7 +792,7 @@ def formsemestre_evaluations_cal(context, formsemestre_id, REQUEST=None): e[2] = color_futur CalHTML = sco_abs.YearTable( - context, year, events=events.values(), halfday=False, pad_width=None + context, year, events=list(events.values()), halfday=False, pad_width=None ) H = [ @@ -840,12 +840,16 @@ def evaluation_date_first_completion(context, evaluation_id): # retire de insem ceux qui ne sont pas inscrits au module # ins = [i for i in insem if i["etudid"] in insmodset] - notes = do_evaluation_get_all_notes( - context, evaluation_id, filter_suppressed=False - ).values() - notes_log = do_evaluation_get_all_notes( - context, evaluation_id, filter_suppressed=False, table="notes_notes_log" - ).values() + notes = list( + do_evaluation_get_all_notes( + context, evaluation_id, filter_suppressed=False + ).values() + ) + notes_log = list( + do_evaluation_get_all_notes( + context, evaluation_id, filter_suppressed=False, table="notes_notes_log" + ).values() + ) date_premiere_note = {} # etudid : date for note in notes + notes_log: etudid = note["etudid"] @@ -1102,7 +1106,11 @@ def evaluation_describe(context, evaluation_id="", edit_in_place=True, REQUEST=N group_id = sco_groups.get_default_group(context, formsemestre_id) H.append( '(absences ce jour)' - % (scu.ScoURL(), group_id, urllib.quote(E["jour"], safe="")) + % ( + scu.ScoURL(), + group_id, + six.moves.urllib.parse.quote(E["jour"], safe=""), + ) ) H.append( '

Coefficient dans le module: %s, notes sur %g ' @@ -1249,8 +1257,9 @@ def evaluation_create_form( initvalues["visibulletinlist"] = ["X"] else: initvalues["visibulletinlist"] = [] - if REQUEST.form.get("tf-submitted", False) and not REQUEST.form.has_key( - "visibulletinlist" + if ( + REQUEST.form.get("tf-submitted", False) + and "visibulletinlist" not in REQUEST.form ): REQUEST.form["visibulletinlist"] = [] # diff --git a/app/scodoc/sco_excel.py b/app/scodoc/sco_excel.py index a2fb9cc6..3556efce 100644 --- a/app/scodoc/sco_excel.py +++ b/app/scodoc/sco_excel.py @@ -39,6 +39,7 @@ from app.scodoc.notes_log import log from app.scodoc.scolog import logdb from app.scodoc.sco_exceptions import ScoValueError from app.scodoc import sco_preferences +import six # colors, voir exemple format.py @@ -454,7 +455,7 @@ def Excel_to_list(data, convert_to_string=str): # we may need 'encoding' argume if not values: diag.append("Aucune valeur trouvée dans le classeur !") return diag, None - indexes = values.keys() + indexes = list(values.keys()) # search numbers of rows and cols rows = [x[0] for x in indexes] cols = [x[1] for x in indexes] @@ -466,7 +467,7 @@ def Excel_to_list(data, convert_to_string=str): # we may need 'encoding' argume for row_idx, col_idx in indexes: v = values[(row_idx, col_idx)] - if isinstance(v, unicode): + if isinstance(v, six.text_type): v = v.encode(scu.SCO_ENCODING, "backslashreplace") elif convert_to_string: v = convert_to_string(v) diff --git a/app/scodoc/sco_formsemestre.py b/app/scodoc/sco_formsemestre.py index 51dd9759..8fbe9c22 100644 --- a/app/scodoc/sco_formsemestre.py +++ b/app/scodoc/sco_formsemestre.py @@ -243,7 +243,7 @@ def do_formsemestre_create(context, args, REQUEST, silent=False): ) # news - if not args.has_key("titre"): + if "titre" not in args: args["titre"] = "sans titre" args["formsemestre_id"] = formsemestre_id args["url"] = "Notes/formsemestre_status?formsemestre_id=%(formsemestre_id)s" % args @@ -622,7 +622,7 @@ def list_formsemestre_by_etape( context, sem, year=int(annee_scolaire), REQUEST=REQUEST ): ds[sem["formsemestre_id"]] = sem - sems = ds.values() + sems = list(ds.values()) else: sems = do_formsemestre_list(context) if annee_scolaire: diff --git a/app/scodoc/sco_formsemestre_edit.py b/app/scodoc/sco_formsemestre_edit.py index 6ac094f7..511ab7bb 100644 --- a/app/scodoc/sco_formsemestre_edit.py +++ b/app/scodoc/sco_formsemestre_edit.py @@ -56,6 +56,7 @@ from app.scodoc import sco_permissions_check from app.scodoc import sco_portal_apogee from app.scodoc import sco_preferences from app.scodoc import sco_users +import six def _default_sem_title(F): @@ -77,7 +78,7 @@ def formsemestre_createwithmodules(context, REQUEST=None): """

Mise en place d'un semestre de formation

""", ] r = do_formsemestre_createwithmodules(context, REQUEST=REQUEST) - if isinstance(r, basestring): + if isinstance(r, six.string_types): H.append(r) else: return r # response redirect @@ -106,7 +107,7 @@ def formsemestre_editwithmodules(context, REQUEST, formsemestre_id): ) else: r = do_formsemestre_createwithmodules(context, REQUEST=REQUEST, edit=1) - if isinstance(r, basestring): + if isinstance(r, six.string_types): H.append(r) else: return r # response redirect @@ -153,7 +154,7 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False): login2display = {} # user_name : forme pour affichage = "NOM Prenom (login)" for u in userlist: login2display[u.user_name] = u.get_nomplogin() - allowed_user_names = login2display.values() + [""] + allowed_user_names = list(login2display.values()) + [""] # formation_id = REQUEST.form["formation_id"] F = sco_formations.formation_list(context, args={"formation_id": formation_id}) @@ -239,7 +240,7 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False): semestre_ids = {} for mod in mods: semestre_ids[mod["semestre_id"]] = 1 - semestre_ids = semestre_ids.keys() + semestre_ids = list(semestre_ids.keys()) semestre_ids.sort() modalites = sco_modalites.do_modalite_list(context) @@ -632,8 +633,9 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False): initvalues["gestion_compensation_lst"] = ["X"] else: initvalues["gestion_compensation_lst"] = [] - if REQUEST.form.get("tf-submitted", False) and not REQUEST.form.has_key( - "gestion_compensation_lst" + if ( + REQUEST.form.get("tf-submitted", False) + and "gestion_compensation_lst" not in REQUEST.form ): REQUEST.form["gestion_compensation_lst"] = [] @@ -642,8 +644,9 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False): initvalues["gestion_semestrielle_lst"] = ["X"] else: initvalues["gestion_semestrielle_lst"] = [] - if REQUEST.form.get("tf-submitted", False) and not REQUEST.form.has_key( - "gestion_semestrielle_lst" + if ( + REQUEST.form.get("tf-submitted", False) + and "gestion_semestrielle_lst" not in REQUEST.form ): REQUEST.form["gestion_semestrielle_lst"] = [] @@ -652,8 +655,9 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False): initvalues["bul_publish_xml_lst"] = ["X"] else: initvalues["bul_publish_xml_lst"] = [] - if REQUEST.form.get("tf-submitted", False) and not REQUEST.form.has_key( - "bul_publish_xml_lst" + if ( + REQUEST.form.get("tf-submitted", False) + and "bul_publish_xml_lst" not in REQUEST.form ): REQUEST.form["bul_publish_xml_lst"] = [] @@ -897,7 +901,7 @@ def formsemestre_clone(context, formsemestre_id, REQUEST=None): login2display = {} # user_name : forme pour affichage = "NOM Prenom (login)" for u in userlist: login2display[u.user_name] = u.get_nomplogin() - allowed_user_names = login2display.values() + [""] + allowed_user_names = list(login2display.values()) + [""] initvalues = { "formsemestre_id": sem["formsemestre_id"], diff --git a/app/scodoc/sco_formsemestre_inscriptions.py b/app/scodoc/sco_formsemestre_inscriptions.py index 1b007aac..375c4311 100644 --- a/app/scodoc/sco_formsemestre_inscriptions.py +++ b/app/scodoc/sco_formsemestre_inscriptions.py @@ -568,11 +568,11 @@ function chkbx_select(field_id, state) { for ue in ues: ue_id = ue["ue_id"] for moduleimpl_id in tf[2]["moduleimpls_%s" % ue_id]: - if a_desinscrire.has_key(moduleimpl_id): + if moduleimpl_id in a_desinscrire: del a_desinscrire[moduleimpl_id] # supprime ceux auxquel pas inscrit for moduleimpl_id in a_desinscrire.keys(): - if not insdict.has_key(moduleimpl_id): + if moduleimpl_id not in insdict: del a_desinscrire[moduleimpl_id] a_inscrire = set() diff --git a/app/scodoc/sco_formsemestre_status.py b/app/scodoc/sco_formsemestre_status.py index af90c0da..698125cb 100644 --- a/app/scodoc/sco_formsemestre_status.py +++ b/app/scodoc/sco_formsemestre_status.py @@ -28,7 +28,7 @@ """Tableau de bord semestre """ -import urllib +import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error import cgi from flask import current_app @@ -482,9 +482,9 @@ def retreive_formsemestre_from_request(context, REQUEST): """ # Search formsemestre group_ids = REQUEST.form.get("group_ids", []) - if REQUEST.form.has_key("formsemestre_id"): + if "formsemestre_id" in REQUEST.form: formsemestre_id = REQUEST.form["formsemestre_id"] - elif REQUEST.form.has_key("moduleimpl_id"): + elif "moduleimpl_id" in REQUEST.form: modimpl = sco_moduleimpl.do_moduleimpl_list( context, moduleimpl_id=REQUEST.form["moduleimpl_id"] ) @@ -492,7 +492,7 @@ def retreive_formsemestre_from_request(context, REQUEST): return None # suppressed ? modimpl = modimpl[0] formsemestre_id = modimpl["formsemestre_id"] - elif REQUEST.form.has_key("evaluation_id"): + elif "evaluation_id" in REQUEST.form: E = sco_evaluations.do_evaluation_list( context, {"evaluation_id": REQUEST.form["evaluation_id"]} ) @@ -503,7 +503,7 @@ def retreive_formsemestre_from_request(context, REQUEST): context, moduleimpl_id=E["moduleimpl_id"] )[0] formsemestre_id = modimpl["formsemestre_id"] - elif REQUEST.form.has_key("group_id"): + elif "group_id" in REQUEST.form: group = sco_groups.get_group(context, REQUEST.form["group_id"]) formsemestre_id = group["formsemestre_id"] elif group_ids: @@ -515,7 +515,7 @@ def retreive_formsemestre_from_request(context, REQUEST): group_id = group_ids[0] group = sco_groups.get_group(context, group_id) formsemestre_id = group["formsemestre_id"] - elif REQUEST.form.has_key("partition_id"): + elif "partition_id" in REQUEST.form: partition = sco_groups.get_partition(context, REQUEST.form["partition_id"]) formsemestre_id = partition["formsemestre_id"] else: @@ -781,7 +781,7 @@ def _make_listes_sem(context, sem, REQUEST=None, with_absences=True): query_args = cgi.parse_qs(REQUEST.QUERY_STRING) if "head_message" in query_args: del query_args["head_message"] - destination = "%s?%s" % (REQUEST.URL, urllib.urlencode(query_args, True)) + destination = "%s?%s" % (REQUEST.URL, six.moves.urllib.parse.urlencode(query_args, True)) destination = destination.replace( "%", "%%" ) # car ici utilisee dans un format string ! diff --git a/app/scodoc/sco_formsemestre_validation.py b/app/scodoc/sco_formsemestre_validation.py index 072c15b8..3f8539ae 100644 --- a/app/scodoc/sco_formsemestre_validation.py +++ b/app/scodoc/sco_formsemestre_validation.py @@ -27,7 +27,7 @@ """Semestres: validation semestre et UE dans parcours """ -import urllib, time, datetime +import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error, time, datetime import app.scodoc.notesdb as ndb import app.scodoc.sco_utils as scu @@ -618,7 +618,7 @@ def formsemestre_recap_parcours_table( # UEs for ue in ues: - if decisions_ue and decisions_ue.has_key(ue["ue_id"]): + if decisions_ue and ue["ue_id"] in decisions_ue: code = decisions_ue[ue["ue_id"]]["code"] else: code = "" @@ -732,7 +732,7 @@ def form_decision_manuelle( ) # Choix code semestre: - codes = sco_codes_parcours.CODES_EXPL.keys() + codes = list(sco_codes_parcours.CODES_EXPL.keys()) codes.sort() # fortuitement, cet ordre convient bien ! H.append( @@ -789,7 +789,7 @@ def form_decision_manuelle( H.append("") # Choix code devenir - codes = sco_codes_parcours.DEVENIR_EXPL.keys() + codes = list(sco_codes_parcours.DEVENIR_EXPL.keys()) codes.sort() # fortuitement, cet ordre convient aussi bien ! if Se.sem["semestre_id"] == -1: @@ -1146,7 +1146,7 @@ def formsemestre_validate_previous_ue(context, formsemestre_id, etudid, REQUEST= "explanation": "Facultatif: indice du semestre dans la formation", "allow_null": True, "allowed_values": [""] + [str(x) for x in range(11)], - "labels": ["-"] + range(11), + "labels": ["-"] + list(range(11)), }, ), ( diff --git a/app/scodoc/sco_formulas.py b/app/scodoc/sco_formulas.py index 9bf0683e..f463c4db 100644 --- a/app/scodoc/sco_formulas.py +++ b/app/scodoc/sco_formulas.py @@ -30,6 +30,7 @@ import operator from types import FloatType, IntType, LongType, StringType +from functools import reduce class NoteVector(object): @@ -41,7 +42,7 @@ class NoteVector(object): def __init__(self, *args, **kwargs): if args: - self.v = map(float, args) # cast to list of float + self.v = list(map(float, args)) # cast to list of float elif "v" in kwargs: v = kwargs["v"] if not isinstance(v, NoteVector): @@ -49,7 +50,7 @@ class NoteVector(object): for i in range(len(v)): try: v[i] = float(v[i]) - except: + except ValueError: v[i] = 0.0 self.v = v else: diff --git a/app/scodoc/sco_groups.py b/app/scodoc/sco_groups.py index 15a81067..1048c5e1 100644 --- a/app/scodoc/sco_groups.py +++ b/app/scodoc/sco_groups.py @@ -55,6 +55,7 @@ from app.scodoc import sco_permissions_check from app.scodoc.sco_exceptions import ScoException, AccessDenied, ScoValueError from app.scodoc.sco_permissions import Permission from app.scodoc.TrivialFormulator import TrivialFormulator +import six def checkGroupName( @@ -684,7 +685,9 @@ def setGroups( if not group_name: continue # ajax arguments are encoded in utf-8: - group_name = unicode(group_name, "utf-8").encode(scu.SCO_ENCODING) + group_name = six.text_type(group_name, "utf-8").encode( + scu.SCO_ENCODING + ) # #py3 #sco8 group_id = createGroup(context, partition_id, group_name, REQUEST=REQUEST) # Place dans ce groupe les etudiants indiqués: for etudid in fs[1:-1]: diff --git a/app/scodoc/sco_groups_view.py b/app/scodoc/sco_groups_view.py index bafd65f7..2a9430e3 100644 --- a/app/scodoc/sco_groups_view.py +++ b/app/scodoc/sco_groups_view.py @@ -32,7 +32,7 @@ # Re-ecriture en 2014 (re-organisation de l'interface, modernisation du code) import datetime import cgi -import urllib +import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error import time import collections import operator @@ -51,6 +51,7 @@ from app.scodoc import sco_etud from app.scodoc.gen_tables import GenTable from app.scodoc.sco_exceptions import ScoValueError from app.scodoc.sco_permissions import Permission +from six.moves import range JAVASCRIPTS = html_sco_header.BOOTSTRAP_MULTISELECT_JS + [ "js/etud_info.js", @@ -936,7 +937,7 @@ def form_choix_saisie_semaine(context, groups_infos, REQUEST=None): moduleimpl_id = query_args.get("moduleimpl_id", [""])[0] if "head_message" in query_args: del query_args["head_message"] - destination = "%s?%s" % (REQUEST.URL, urllib.urlencode(query_args, True)) + destination = "%s?%s" % (REQUEST.URL, six.moves.urllib.parse.urlencode(query_args, True)) destination = destination.replace( "%", "%%" ) # car ici utilisee dans un format string ! diff --git a/app/scodoc/sco_import_etuds.py b/app/scodoc/sco_import_etuds.py index 448d6797..ca456bef 100644 --- a/app/scodoc/sco_import_etuds.py +++ b/app/scodoc/sco_import_etuds.py @@ -302,20 +302,20 @@ def scolars_import_excel_file( # check columns titles if len(fs) != len(titles): - missing = {}.fromkeys(titles.keys()) + missing = {}.fromkeys(list(titles.keys())) unknown = [] for f in fs: - if missing.has_key(f): + if f in missing: del missing[f] else: unknown.append(f) raise ScoValueError( "Nombre de colonnes incorrect (devrait être %d, et non %d)
(colonnes manquantes: %s, colonnes invalides: %s)" - % (len(titles), len(fs), missing.keys(), unknown) + % (len(titles), len(fs), list(missing.keys()), unknown) ) titleslist = [] for t in fs: - if not titles.has_key(t): + if t not in titles: raise ScoValueError('Colonne invalide: "%s"' % t) titleslist.append(t) # # ok, same titles @@ -573,7 +573,7 @@ def _import_one_student( else: groupes = [] group_ids = [gi[group_name] for group_name in groupes] - group_ids = {}.fromkeys(group_ids).keys() # uniq + group_ids = list({}.fromkeys(group_ids).keys()) # uniq if None in group_ids: raise ScoValueError( "groupe invalide sur la ligne %d (groupe %s)" % (linenum, groupes) @@ -714,7 +714,7 @@ def scolars_import_admission( gi = sco_groups.GroupIdInferer(context, formsemestre_id) groupes = args["groupes"].split(";") group_ids = [gi[group_name] for group_name in groupes] - group_ids = {}.fromkeys(group_ids).keys() # uniq + group_ids = list({}.fromkeys(group_ids).keys()) # uniq if None in group_ids: raise ScoValueError( "groupe invalide sur la ligne %d (groupe %s)" @@ -779,19 +779,19 @@ def adm_get_fields(titles, formsemestre_id): def adm_convert_text(v): - if type(v) == types.FloatType: + if type(v) == float: return "{:g}".format(v) # evite "1.0" return v def adm_convert_int(v): - if type(v) != types.IntType and not v: + if type(v) != int and not v: return None return int(float(v)) # accept "10.0" def adm_convert_real(v): - if type(v) != types.FloatType and not v: + if type(v) != float and not v: return None return float(v) @@ -821,7 +821,7 @@ def adm_table_description_format(context): tab = GenTable( titles=titles, columns_ids=columns_ids, - rows=Fmt.values(), + rows=list(Fmt.values()), html_sortable=True, html_class="table_leftalign", preferences=sco_preferences.SemPreferences( diff --git a/app/scodoc/sco_import_users.py b/app/scodoc/sco_import_users.py index 5c6acd75..d4cc07ac 100644 --- a/app/scodoc/sco_import_users.py +++ b/app/scodoc/sco_import_users.py @@ -80,14 +80,14 @@ def import_excel_file(datafile, REQUEST=None, context=None): cols = {}.fromkeys(TITLES) unknown = [] for tit in fs: - if not cols.has_key(tit): + if tit not in cols: unknown.append(tit) else: del cols[tit] if cols or unknown: raise ScoValueError( "colonnes incorrectes (on attend %d, et non %d)
(colonnes manquantes: %s, colonnes invalides: %s)" - % (len(TITLES), len(fs), cols.keys(), unknown) + % (len(TITLES), len(fs), list(cols.keys()), unknown) ) # ok, same titles... U = [] diff --git a/app/scodoc/sco_inscr_passage.py b/app/scodoc/sco_inscr_passage.py index 48e1df0c..2aa52226 100644 --- a/app/scodoc/sco_inscr_passage.py +++ b/app/scodoc/sco_inscr_passage.py @@ -82,13 +82,13 @@ def list_authorized_etuds_by_sem(context, sem, delai=274): } # ajoute attribut inscrit qui indique si l'étudiant est déjà inscrit dans le semestre dest. for e in r[src["formsemestre_id"]]["etuds"]: - e["inscrit"] = inscrits.has_key(e["etudid"]) + e["inscrit"] = e["etudid"] in inscrits # Ajoute liste des etudiants actuellement inscrits for e in inscrits.values(): e["inscrit"] = True r[sem["formsemestre_id"]] = { - "etuds": inscrits.values(), + "etuds": list(inscrits.values()), "infos": { "id": sem["formsemestre_id"], "title": "Semestre cible: " + sem["titreannee"], diff --git a/app/scodoc/sco_liste_notes.py b/app/scodoc/sco_liste_notes.py index 5fab6478..5e083890 100644 --- a/app/scodoc/sco_liste_notes.py +++ b/app/scodoc/sco_liste_notes.py @@ -27,7 +27,7 @@ """Liste des notes d'une évaluation """ -import urllib +import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error from types import StringType import app.scodoc.sco_utils as scu @@ -59,13 +59,13 @@ def do_evaluation_listenotes(context, REQUEST): args: evaluation_id """ mode = None - if REQUEST.form.has_key("evaluation_id"): + if "evaluation_id" in REQUEST.form: evaluation_id = REQUEST.form["evaluation_id"] mode = "eval" evals = sco_evaluations.do_evaluation_list( context, {"evaluation_id": evaluation_id} ) - if REQUEST.form.has_key("moduleimpl_id"): + if "moduleimpl_id" in REQUEST.form: moduleimpl_id = REQUEST.form["moduleimpl_id"] mode = "module" evals = sco_evaluations.do_evaluation_list( @@ -511,7 +511,7 @@ def _make_table_notes( + "\n", '

', ] - commentkeys = K.items() # [ (comment, key), ... ] + commentkeys = list(K.items()) # [ (comment, key), ... ] commentkeys.sort(lambda x, y: cmp(int(x[1]), int(y[1]))) for (comment, key) in commentkeys: C.append( @@ -554,7 +554,7 @@ def _add_eval_columns( NotesDB = sco_evaluations.do_evaluation_get_all_notes(context, evaluation_id) for row in rows: etudid = row["etudid"] - if NotesDB.has_key(etudid): + if etudid in NotesDB: val = NotesDB[etudid]["value"] if val is None: nb_abs += 1 @@ -591,7 +591,7 @@ def _add_eval_columns( row["_css_row_class"] = "etudabs" # regroupe les commentaires if explanation: - if K.has_key(explanation): + if explanation in K: expl_key = "(%s)" % K[explanation] else: K[explanation] = K.nextkey() @@ -745,7 +745,7 @@ def evaluation_check_absences(context, evaluation_id): ExcNonJust = [] # note EXC mais absent non justifie AbsButExc = [] # note ABS mais justifié for etudid in etudids: - if NotesDB.has_key(etudid): + if etudid in NotesDB: val = NotesDB[etudid]["value"] if ( val != None and val != scu.NOTES_NEUTRALISE and val != scu.NOTES_ATTENTE @@ -824,8 +824,8 @@ def evaluation_check_absences_html( 'signaler cette absence' % ( etud["etudid"], - urllib.quote(E["jour"]), - urllib.quote(E["jour"]), + six.moves.urllib.parse.quote(E["jour"]), + six.moves.urllib.parse.quote(E["jour"]), demijournee, E["moduleimpl_id"], ) diff --git a/app/scodoc/sco_modalites.py b/app/scodoc/sco_modalites.py index 5b70d66c..b1789236 100644 --- a/app/scodoc/sco_modalites.py +++ b/app/scodoc/sco_modalites.py @@ -45,7 +45,7 @@ def list_formsemestres_modalites(context, sems): if sem["modalite"] not in modalites: m = do_modalite_list(context, args={"modalite": sem["modalite"]})[0] modalites[m["modalite"]] = m - modalites = modalites.values() + modalites = list(modalites.values()) modalites.sort(key=lambda x: x["numero"]) return modalites diff --git a/app/scodoc/sco_moduleimpl_status.py b/app/scodoc/sco_moduleimpl_status.py index 51c47834..47882044 100644 --- a/app/scodoc/sco_moduleimpl_status.py +++ b/app/scodoc/sco_moduleimpl_status.py @@ -28,7 +28,7 @@ """Tableau de bord module """ import time -import urllib +import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error import app.scodoc.sco_utils as scu from app.scodoc.sco_permissions import Permission @@ -136,7 +136,7 @@ def moduleimpl_evaluation_menu(context, evaluation_id, nbnotes=0, REQUEST=None): "title": "Absences ce jour", "endpoint": "absences.EtatAbsencesDate", "args": { - "date": urllib.quote(E["jour"], safe=""), + "date": six.moves.urllib.parse.quote(E["jour"], safe=""), "group_ids": group_id, }, "enabled": E["jour"], diff --git a/app/scodoc/sco_news.py b/app/scodoc/sco_news.py index c9ffe606..dcbecf77 100644 --- a/app/scodoc/sco_news.py +++ b/app/scodoc/sco_news.py @@ -46,6 +46,7 @@ from app.scodoc import sco_formsemestre from app.scodoc import sco_moduleimpl from app.scodoc import sco_preferences from app.scodoc import sco_users +import six _scolar_news_editor = ndb.EditableTable( "scolar_news", @@ -69,7 +70,7 @@ NEWS_MAP = { NEWS_SEM: "création semestre", NEWS_MISC: "opération", # unused } -NEWS_TYPES = NEWS_MAP.keys() +NEWS_TYPES = list(NEWS_MAP.keys()) scolar_news_create = _scolar_news_editor.create scolar_news_list = _scolar_news_editor.list @@ -126,7 +127,7 @@ def scolar_news_summary(context, n=5): key = (r["type"], r["object"], dmy) selected_news[key] = r - news = selected_news.values() + news = list(selected_news.values()) # sort by date, descending news.sort(lambda x, y: cmp(y["date"], x["date"])) news = news[:n] @@ -139,7 +140,7 @@ def scolar_news_summary(context, n=5): for k in n.keys(): if n[k] is None: n[k] = "" - if _scolar_news_editor.output_formators.has_key(k): + if k in _scolar_news_editor.output_formators: n[k] = _scolar_news_editor.output_formators[k](n[k]) # date resumee j, m = n["date"].split("/")[:2] @@ -233,15 +234,15 @@ def scolar_news_summary_rss(context, title, sco_url, n=5): text = html2text(n["text"]) items.append( PyRSS2Gen.RSSItem( - title=unicode("%s %s" % (n["rssdate"], text), SCO_ENCODING), + title=six.text_type("%s %s" % (n["rssdate"], text), SCO_ENCODING), link=sco_url + "/" + n["url"], pubDate=n["date822"], ) ) rss = PyRSS2Gen.RSS2( - title=unicode(title, SCO_ENCODING), + title=six.text_type(title, SCO_ENCODING), link=sco_url, - description=unicode(title, SCO_ENCODING), + description=six.text_type(title, SCO_ENCODING), lastBuildDate=datetime.datetime.now(), items=items, ) diff --git a/app/scodoc/sco_page_etud.py b/app/scodoc/sco_page_etud.py index f3881310..9bc9974e 100644 --- a/app/scodoc/sco_page_etud.py +++ b/app/scodoc/sco_page_etud.py @@ -494,7 +494,7 @@ def ficheEtud(context, etudid=None, REQUEST=None): def menus_etud(context, REQUEST=None): """Menu etudiant (operations sur l'etudiant)""" - if not REQUEST.form.has_key("etudid"): + if "etudid" not in REQUEST.form: return "" authuser = REQUEST.AUTHENTICATED_USER diff --git a/app/scodoc/sco_parcours_dut.py b/app/scodoc/sco_parcours_dut.py index 49b1d9dd..ce7a48b1 100644 --- a/app/scodoc/sco_parcours_dut.py +++ b/app/scodoc/sco_parcours_dut.py @@ -349,7 +349,7 @@ class SituationEtudParcoursGeneric: self.etudid, self.sem, self.nt, sem, nt ) - self.ue_acros = ue_acros.keys() + self.ue_acros = list(ue_acros.keys()) self.ue_acros.sort() self.nb_max_ue = nb_max_ue self.sems = sems @@ -389,7 +389,7 @@ class SituationEtudParcoursGeneric: if self.sem["semestre_id"] == NO_SEMESTRE_ID: indices = [NO_SEMESTRE_ID] else: - indices = range(1, self.parcours.NB_SEM + 1) + indices = list(range(1, self.parcours.NB_SEM + 1)) for i in indices: # cherche dans les semestres de l'étudiant, en partant du plus récent sem = None diff --git a/app/scodoc/sco_pdf.py b/app/scodoc/sco_pdf.py index 4ae9118d..7ebc7d28 100644 --- a/app/scodoc/sco_pdf.py +++ b/app/scodoc/sco_pdf.py @@ -64,6 +64,7 @@ from app.scodoc.sco_exceptions import ScoGenError from SuppressAccents import suppression_diacritics from app.scodoc import VERSION from VERSION import SCOVERSION, SCONAME +import six PAGE_HEIGHT = defaultPageSize[1] PAGE_WIDTH = defaultPageSize[0] @@ -81,7 +82,7 @@ def SU(s): # eg 'e\xcc\x81' COMBINING ACUTE ACCENT par '\xc3\xa9' LATIN SMALL LETTER E WITH ACUTE # car les "combining accents" ne sont pas traités par ReportLab mais peuvent # nous être envoyés par certains navigateurs ou imports - u = unicodedata.normalize("NFC", unicode(s, SCO_ENCODING, "replace")) + u = unicodedata.normalize("NFC", six.text_type(s, SCO_ENCODING, "replace")) return u.encode("utf8") @@ -330,19 +331,19 @@ def pdf_basic_page( # Gestion du lock pdf -import threading, time, Queue, thread +import threading, time, six.moves.queue, six.moves._thread class PDFLock: def __init__(self, timeout=15): - self.Q = Queue.Queue(1) + self.Q = six.moves.queue.Queue(1) self.timeout = timeout self.current_thread = None self.nref = 0 def release(self): "Release lock. Raise Empty if not acquired first" - if self.current_thread == thread.get_ident(): + if self.current_thread == six.moves._thread.get_ident(): self.nref -= 1 if self.nref == 0: log("PDFLock: release from %s" % self.current_thread) @@ -354,14 +355,14 @@ class PDFLock: def acquire(self): "Acquire lock. Raise ScoGenError if can't lock after timeout." - if self.current_thread == thread.get_ident(): + if self.current_thread == six.moves._thread.get_ident(): self.nref += 1 return # deja lock pour ce thread try: self.Q.put(1, True, self.timeout) - except Queue.Full: + except six.moves.queue.Full: raise ScoGenError(msg="Traitement PDF occupé: ré-essayez") - self.current_thread = thread.get_ident() + self.current_thread = six.moves._thread.get_ident() self.nref = 1 log("PDFLock: granted to %s" % self.current_thread) diff --git a/app/scodoc/sco_photos.py b/app/scodoc/sco_photos.py index 5e20a8e8..0b2a7ae9 100644 --- a/app/scodoc/sco_photos.py +++ b/app/scodoc/sco_photos.py @@ -47,7 +47,7 @@ import os import time import datetime import random -import urllib2 +import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse import traceback from PIL import Image as PILImage from cStringIO import StringIO @@ -355,7 +355,7 @@ def copy_portal_photo_to_fs(context, etud, REQUEST=None): f = None try: log("copy_portal_photo_to_fs: getting %s" % url) - f = urllib2.urlopen(url, timeout=portal_timeout) # python >= 2.7 + f = six.moves.urllib.request.urlopen(url, timeout=portal_timeout) # python >= 2.7 except: log("download failed: exception:\n%s" % traceback.format_exc()) log("called from:\n" + "".join(traceback.format_stack())) diff --git a/app/scodoc/sco_placement.py b/app/scodoc/sco_placement.py index 344aed15..21e92862 100644 --- a/app/scodoc/sco_placement.py +++ b/app/scodoc/sco_placement.py @@ -30,7 +30,7 @@ Contribution M. Salomon, UFC / IUT DE BELFORT-MONTBÉLIARD, 2016 """ -import urllib +import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error import random import app.scodoc.sco_utils as scu @@ -155,7 +155,7 @@ def do_placement_selectetuds(context, REQUEST): ) ] - if not (REQUEST.form.has_key("group_ids") and REQUEST.form["group_ids"]): + if not ("group_ids" in REQUEST.form and REQUEST.form["group_ids"]): submitbuttonattributes = ['disabled="1"'] else: submitbuttonattributes = [] # groupe(s) preselectionnés @@ -208,7 +208,10 @@ def do_placement_selectetuds(context, REQUEST): columns = tf[2]["columns"] numbering = tf[2]["numbering"] if columns in ("3", "4", "5", "6", "7", "8"): - gs = [("group_ids%3Alist=" + urllib.quote_plus(x)) for x in group_ids] + gs = [ + ("group_ids%3Alist=" + six.moves.urllib.parse.quote_plus(x)) + for x in group_ids + ] query = ( "evaluation_id=%s&placement_method=%s&teachers=%s&building=%s&room=%s&columns=%s&numbering=%s&" % ( diff --git a/app/scodoc/sco_portal_apogee.py b/app/scodoc/sco_portal_apogee.py index 8b7afb37..fd8ac01a 100644 --- a/app/scodoc/sco_portal_apogee.py +++ b/app/scodoc/sco_portal_apogee.py @@ -29,7 +29,7 @@ """ import os, time -import urllib +import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error import xml import xml.sax.saxutils import xml.dom.minidom @@ -39,6 +39,8 @@ import app.scodoc.sco_utils as scu from app.scodoc.notes_log import log from app.scodoc.sco_exceptions import ScoValueError from app.scodoc import sco_preferences +import six +from six.moves import range SCO_CACHE_ETAPE_FILENAME = os.path.join(scu.SCO_TMP_DIR, "last_etapes.xml") @@ -155,10 +157,10 @@ def get_inscrits_etape(context, code_etape, anneeapogee=None, ntrials=2): req = ( etud_url + "?" - + urllib.urlencode((("etape", code_etape), ("annee", anneeapogee))) + + six.moves.urllib.parse.urlencode((("etape", code_etape), ("annee", anneeapogee))) ) else: - req = etud_url + "?" + urllib.urlencode((("etape", code_etape),)) + req = etud_url + "?" + six.moves.urllib.parse.urlencode((("etape", code_etape),)) actual_timeout = float(portal_timeout) / ntrials if portal_timeout > 0: actual_timeout = max(1, actual_timeout) @@ -172,7 +174,7 @@ def get_inscrits_etape(context, code_etape, anneeapogee=None, ntrials=2): # Filtre sur annee inscription Apogee: def check_inscription(e): - if e.has_key("inscription"): + if "inscription" in e: if e["inscription"] == anneeapogee: return True else: @@ -203,7 +205,7 @@ def query_apogee_portal(context, **args): # XXX TODO : va poser problème pour la page modif données étudiants : A VOIR return [] portal_timeout = sco_preferences.get_preference(context, "portal_timeout") - req = etud_url + "?" + urllib.urlencode(args.items()) + req = etud_url + "?" + six.moves.urllib.parse.urlencode(list(args.items())) doc = scu.query_portal(req, timeout=portal_timeout) # sco_utils return xml_to_list_of_dicts(doc, req=req) @@ -261,7 +263,7 @@ def xml_to_list_of_dicts(doc, req=None): def get_infos_apogee_allaccents(context, nom, prenom): "essai recup infos avec differents codages des accents" if nom: - unom = unicode(nom, scu.SCO_ENCODING) + unom = six.text_type(nom, scu.SCO_ENCODING) nom_noaccents = str(scu.suppression_diacritics(unom)) nom_utf8 = unom.encode("utf-8") else: @@ -269,7 +271,7 @@ def get_infos_apogee_allaccents(context, nom, prenom): nom_utf8 = nom if prenom: - uprenom = unicode(prenom, scu.SCO_ENCODING) + uprenom = six.text_type(prenom, scu.SCO_ENCODING) prenom_noaccents = str(scu.suppression_diacritics(uprenom)) prenom_utf8 = uprenom.encode("utf-8") else: @@ -325,7 +327,7 @@ def get_etud_apogee(context, code_nip): if not etud_url: return {} portal_timeout = sco_preferences.get_preference(context, "portal_timeout") - req = etud_url + "?" + urllib.urlencode((("nip", code_nip),)) + req = etud_url + "?" + six.moves.urllib.parse.urlencode((("nip", code_nip),)) doc = scu.query_portal(req, timeout=portal_timeout) d = _normalize_apo_fields(xml_to_list_of_dicts(doc, req=req)) if not d: @@ -346,7 +348,7 @@ def get_default_etapes(context): if line and line[0] != "#": dept, code, intitule = [x.strip() for x in line.split(":")] if dept and code: - if etapes.has_key(dept): + if dept in etapes: etapes[dept][code] = intitule else: etapes[dept] = {code: intitule} @@ -418,7 +420,7 @@ def _xml_list_codes(target_dict, dept, nodes): if e.nodeType == e.ELEMENT_NODE: intitule = e.childNodes[0].nodeValue.encode(scu.SCO_ENCODING) code = e.attributes["code"].value.encode(scu.SCO_ENCODING) - if target_dict.has_key(dept): + if dept in target_dict: target_dict[dept][code] = intitule else: target_dict[dept] = {code: intitule} @@ -442,19 +444,19 @@ def get_etapes_apogee_dept(context): log("get_etapes_apogee_dept: pas de sections par departement") infos = get_etapes_apogee(context) - if portal_dept_name and not infos.has_key(portal_dept_name): + if portal_dept_name and portal_dept_name not in infos: log( "get_etapes_apogee_dept: pas de section '%s' dans la reponse portail" % portal_dept_name ) return [] if portal_dept_name: - etapes = infos[portal_dept_name].items() + etapes = list(infos[portal_dept_name].items()) else: # prend toutes les etapes etapes = [] for k in infos.keys(): - etapes += infos[k].items() + etapes += list(infos[k].items()) etapes.sort() # tri sur le code etape return etapes @@ -483,7 +485,7 @@ def _normalize_apo_fields(infolist): ajoute les champs 'etape' (= None) et 'prenom' ('') s'ils ne sont pas présents. """ for infos in infolist: - if infos.has_key("paiementinscription"): + if "paiementinscription" in infos: infos["paiementinscription"] = ( scu.strlower(infos["paiementinscription"]) == "true" ) @@ -495,7 +497,7 @@ def _normalize_apo_fields(infolist): infos["paiementinscription"] = None infos["paiementinscription_str"] = "?" - if infos.has_key("datefinalisationinscription"): + if "datefinalisationinscription" in infos: infos["datefinalisationinscription"] = _portal_date_dmy2date( infos["datefinalisationinscription"] ) @@ -506,10 +508,10 @@ def _normalize_apo_fields(infolist): infos["datefinalisationinscription"] = None infos["datefinalisationinscription_str"] = "" - if not infos.has_key("etape"): + if "etape" not in infos: infos["etape"] = None - if not infos.has_key("prenom"): + if "prenom" not in infos: infos["prenom"] = "" return infolist @@ -529,7 +531,7 @@ def check_paiement_etuds(context, etuds): """ # interrogation séquentielle longue... for etud in etuds: - if not etud.has_key("code_nip"): + if "code_nip" not in etud: etud["paiementinscription"] = None etud["paiementinscription_str"] = "(pas de code)" etud["datefinalisationinscription"] = None @@ -563,7 +565,7 @@ def get_maquette_apogee(context, etape="", annee_scolaire=""): req = ( maquette_url + "?" - + urllib.urlencode((("etape", etape), ("annee", annee_scolaire))) + + six.moves.urllib.parse.urlencode((("etape", etape), ("annee", annee_scolaire))) ) doc = scu.query_portal(req, timeout=portal_timeout) return doc diff --git a/app/scodoc/sco_preferences.py b/app/scodoc/sco_preferences.py index b526b834..4d60b8db 100644 --- a/app/scodoc/sco_preferences.py +++ b/app/scodoc/sco_preferences.py @@ -1797,9 +1797,7 @@ class BasePreferences(object): self.prefs[p["formsemestre_id"]] = {} # Convert types: - if p["name"] in self.prefs_dict and self.prefs_dict[p["name"]].has_key( - "type" - ): + if p["name"] in self.prefs_dict and "type" in self.prefs_dict[p["name"]]: typ = self.prefs_dict[p["name"]]["type"] if typ == "float": # special case for float values (where NULL means 0) @@ -1879,7 +1877,7 @@ class BasePreferences(object): modif = False cnx = ndb.GetDBConnexion() if name is None: - names = self.prefs[formsemestre_id].keys() + names = list(self.prefs[formsemestre_id].keys()) else: names = [name] for name in names: diff --git a/app/scodoc/sco_prepajury.py b/app/scodoc/sco_prepajury.py index 5104af00..74de7ad4 100644 --- a/app/scodoc/sco_prepajury.py +++ b/app/scodoc/sco_prepajury.py @@ -135,14 +135,14 @@ def feuille_preparation_jury(context, formsemestre_id, REQUEST): nbabsjust[etudid] = AbsEtudSem.CountAbs() - AbsEtudSem.CountAbsJust() # Codes des UE "semestre précédent": - ue_prev_codes = prev_moy_ue.keys() + ue_prev_codes = list(prev_moy_ue.keys()) ue_prev_codes.sort( lambda x, y, prev_ue_acro=prev_ue_acro: cmp( # pylint: disable=undefined-variable prev_ue_acro[x], prev_ue_acro[y] ) ) # Codes des UE "semestre courant": - ue_codes = moy_ue.keys() + ue_codes = list(moy_ue.keys()) ue_codes.sort( lambda x, y, ue_acro=ue_acro: cmp( # pylint: disable=undefined-variable ue_acro[x], ue_acro[y] @@ -280,7 +280,7 @@ def feuille_preparation_jury(context, formsemestre_id, REQUEST): # L.append([""]) # Explications des codes - codes = sco_codes_parcours.CODES_EXPL.keys() + codes = list(sco_codes_parcours.CODES_EXPL.keys()) codes.sort() L.append(["Explication des codes"]) for code in codes: diff --git a/app/scodoc/sco_pvjury.py b/app/scodoc/sco_pvjury.py index f68c6fb2..727a12ae 100644 --- a/app/scodoc/sco_pvjury.py +++ b/app/scodoc/sco_pvjury.py @@ -572,10 +572,10 @@ def formsemestre_pvjury( for row in rows: counts[row["decision"]] += 1 # add codes for previous (for explanation, without count) - if row.has_key("prev_decision") and row["prev_decision"]: + if "prev_decision" in row and row["prev_decision"]: counts[row["prev_decision"]] += 0 # Légende des codes - codes = counts.keys() # sco_codes_parcours.CODES_EXPL.keys() + codes = list(counts.keys()) # sco_codes_parcours.CODES_EXPL.keys() codes.sort() H.append("

Explication des codes

") lines = [] diff --git a/app/scodoc/sco_pvpdf.py b/app/scodoc/sco_pvpdf.py index d4e346d1..73db208e 100644 --- a/app/scodoc/sco_pvpdf.py +++ b/app/scodoc/sco_pvpdf.py @@ -835,7 +835,7 @@ def _pvjury_pdf_type( def _format_pv_cell(x): """convert string to paragraph""" - if type(x) == types.StringType: + if type(x) == bytes: return Paragraph(SU(x), cell_style) else: return x @@ -862,7 +862,7 @@ def _pvjury_pdf_type( ) # Légende des codes - codes = sco_codes_parcours.CODES_EXPL.keys() + codes = list(sco_codes_parcours.CODES_EXPL.keys()) codes.sort() objects += sco_pdf.makeParas( """ diff --git a/app/scodoc/sco_recapcomplet.py b/app/scodoc/sco_recapcomplet.py index db61c9f3..88b17a65 100644 --- a/app/scodoc/sco_recapcomplet.py +++ b/app/scodoc/sco_recapcomplet.py @@ -616,7 +616,7 @@ def make_formsemestre_recapcomplet( 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 + if F[0][i] in cod2mod: # lien vers etat module mod = cod2mod[F[0][i]] cells += '%s' % ( cls, @@ -765,7 +765,7 @@ def make_formsemestre_recapcomplet( # recap des decisions jury (nombre dans chaque code): if codes_nb: H.append("

Décisions du jury

") - cods = codes_nb.keys() + cods = list(codes_nb.keys()) cods.sort() for cod in cods: H.append("" % (cod, codes_nb[cod])) @@ -812,7 +812,7 @@ def _list_notes_evals(context, evals, etudid): NotesDB = sco_evaluations.do_evaluation_get_all_notes( context, e["evaluation_id"] ) - if NotesDB.has_key(etudid): + if etudid in NotesDB: val = NotesDB[etudid]["value"] else: # Note manquante mais prise en compte immédiate: affiche ATT diff --git a/app/scodoc/sco_report.py b/app/scodoc/sco_report.py index 9166e2b4..f78c6e37 100644 --- a/app/scodoc/sco_report.py +++ b/app/scodoc/sco_report.py @@ -31,7 +31,7 @@ """ import os import tempfile -import urllib +import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error import re import time import datetime @@ -76,7 +76,7 @@ def formsemestre_etuds_stats(context, sem, only_primo=False): etud["etat"] = nt.get_etud_etat(etudid) if etud["etat"] == "D": etud["codedecision"] = "DEM" - if not etud.has_key("codedecision"): + if "codedecision" not in etud: etud["codedecision"] = "(nd)" # pas de decision jury # Ajout devenir (autorisations inscriptions), utile pour stats passage aut_list = sco_parcours_dut.formsemestre_get_autorisation_inscription( @@ -116,9 +116,9 @@ def _categories_and_results(etuds, category, result): for etud in etuds: categories[etud[category]] = True results[etud[result]] = True - categories = categories.keys() + categories = list(categories.keys()) categories.sort() - results = results.keys() + results = list(results.keys()) results.sort() return categories, results @@ -147,7 +147,7 @@ def _results_by_category( results = {} # { result_value : True } for etud in etuds: results[etud[result]] = True - if Count.has_key(etud[category]): + if etud[category] in Count: Count[etud[category]][etud[result]] += 1 else: Count[etud[category]] = scu.DictDefault(kv_dict={etud[result]: 1}) @@ -162,7 +162,7 @@ def _results_by_category( for l in C: l["sumpercent"] = "%2.1f%%" % ((100.0 * l["sum"]) / tot) # - codes = results.keys() + codes = list(results.keys()) codes.sort() bottom_titles = [] @@ -298,7 +298,7 @@ def formsemestre_report_counts( F = ["""

Aucun étudiant

"""] else: if allkeys: - keys = etuds[0].keys() + keys = list(etuds[0].keys()) else: # clés présentées à l'utilisateur: keys = [ @@ -448,7 +448,7 @@ def table_suivi_cohorte( civilites.add(etud["civilite"]) if etud["statut"]: # ne montre pas les statuts non renseignés statuts.add(etud["statut"]) - sems = S.values() + sems = list(S.values()) # tri les semestres par date de debut for s in sems: d, m, y = [int(x) for x in s["date_debut"].split("/")] @@ -1066,7 +1066,7 @@ def tsp_etud_list( def tsp_grouped_list(context, codes_etuds): """Liste pour table regroupant le nombre d'étudiants (+ bulle avec les noms) de chaque parcours""" L = [] - parcours = codes_etuds.keys() + parcours = list(codes_etuds.keys()) parcours.sort() for p in parcours: nb = len(codes_etuds[p]) @@ -1128,7 +1128,7 @@ def table_suivi_parcours( ) # Calcule intitulés de colonnes S = set() - sems_ids = list(apply(S.union, [e["decisions_jury"].keys() for e in etuds])) + sems_ids = list(S.union(*[list(e["decisions_jury"].keys()) for e in etuds])) sems_ids.sort() sem_tits = ["S%s" % s for s in sems_ids] titles.update([(s, s) for s in sem_tits]) @@ -1338,7 +1338,7 @@ def graph_parcours( edges[(s["formsemestre_id"], nid)].add(etudid) diploma_nodes.append(nid) # - g = scu.pydot.graph_from_edges(edges.keys()) + g = scu.pydot.graph_from_edges(list(edges.keys())) for fid in isolated_nodes: if not fid in connected_nodes: n = scu.pydot.Node(name=fid) @@ -1528,7 +1528,7 @@ def formsemestre_graph_parcours( op = "only_primo=on&" else: op = "" - url = urllib.quote( + url = six.moves.urllib.parse.quote( "formsemestre_graph_parcours?formsemestre_id=%s&%sbac=%s&bacspecialite=%s&civilite=%s&statut=%s&format=" % (formsemestre_id, op, bac, bacspecialite, civilite, statut) ) diff --git a/app/scodoc/sco_saisie_notes.py b/app/scodoc/sco_saisie_notes.py index e37c0e6f..08101e12 100644 --- a/app/scodoc/sco_saisie_notes.py +++ b/app/scodoc/sco_saisie_notes.py @@ -306,7 +306,7 @@ def do_evaluation_set_missing( ) notes = [] for etudid in etudids: # pour tous les inscrits - if not NotesDB.has_key(etudid): # pas de note + if etudid not in NotesDB: # pas de note notes.append((etudid, value)) # Check value L, invalids, _, _, _ = _check_notes(notes, E, M["module"]) @@ -455,9 +455,7 @@ def _notes_add(context, uid, evaluation_id, notes, comment=None, do_it=True): Return number of changed notes """ uid = str(uid) - now = apply( - psycopg2.Timestamp, time.localtime()[:6] - ) # datetime.datetime.now().isoformat() + now = psycopg2.Timestamp(*time.localtime()[:6]) # datetime.datetime.now().isoformat() # Verifie inscription et valeur note _ = {}.fromkeys( sco_groups.do_evaluation_listeetuds_groups( @@ -484,7 +482,7 @@ def _notes_add(context, uid, evaluation_id, notes, comment=None, do_it=True): try: for (etudid, value) in notes: changed = False - if not NotesDB.has_key(etudid): + if etudid not in NotesDB: # nouvelle note if value != scu.NOTES_SUPPRESS: if do_it: @@ -1024,7 +1022,7 @@ def _get_sorted_etuds(context, E, etudids, formsemestre_id): e["absinfo"] = '' + " ".join(warn_abs_lst) + " " # Note actuelle de l'étudiant: - if NotesDB.has_key(etudid): + if etudid in NotesDB: e["val"] = _displayNote(NotesDB[etudid]["value"]) comment = NotesDB[etudid]["comment"] if comment is None: diff --git a/app/scodoc/sco_semset.py b/app/scodoc/sco_semset.py index 1fbe912a..56407b56 100644 --- a/app/scodoc/sco_semset.py +++ b/app/scodoc/sco_semset.py @@ -235,7 +235,7 @@ class SemSet(dict): nt = sco_core.get_notes_cache( context, ).get_NotesTable(context, sem["formsemestre_id"]) - sem["etuds"] = nt.identdict.values() + sem["etuds"] = list(nt.identdict.values()) sem["nips"] = {e["code_nip"] for e in sem["etuds"] if e["code_nip"]} sem["etuds_without_nip"] = { e["etudid"] for e in sem["etuds"] if not e["code_nip"] diff --git a/app/scodoc/sco_synchro_etuds.py b/app/scodoc/sco_synchro_etuds.py index cb425976..cd85a0ff 100644 --- a/app/scodoc/sco_synchro_etuds.py +++ b/app/scodoc/sco_synchro_etuds.py @@ -281,11 +281,11 @@ def build_page( ) year = time.localtime()[0] if anneeapogee and abs(year - int(anneeapogee)) < 50: - years = range( - min(year - 1, int(anneeapogee) - 1), max(year, int(anneeapogee)) + 1 + years = list( + range(min(year - 1, int(anneeapogee) - 1), max(year, int(anneeapogee)) + 1) ) else: - years = range(year - 1, year + 1) + years = list(range(year - 1, year + 1)) anneeapogee = "" options = [] for y in years: @@ -478,7 +478,7 @@ def list_synch(context, sem, anneeapogee=None): }, }, "inscrits_without_key": { - "etuds": inscrits_without_key.values(), + "etuds": list(inscrits_without_key.values()), "infos": { "id": "inscrits_without_key", "title": "Etudiants ScoDoc sans clé Apogée (NIP)", @@ -709,7 +709,7 @@ def do_import_etud_admission( e = al[0] if get_opt_str(etud, "inscription"): e["annee"] = args["annee"] - keys = args.keys() + keys = list(args.keys()) for k in keys: if not args[k]: del args[k] diff --git a/app/scodoc/sco_tag_module.py b/app/scodoc/sco_tag_module.py index 9a2d4ac5..63321e0a 100644 --- a/app/scodoc/sco_tag_module.py +++ b/app/scodoc/sco_tag_module.py @@ -246,7 +246,7 @@ def module_tag_set(context, module_id="", taglist=[], REQUEST=None): # if not taglist: taglist = [] - elif type(taglist) == types.StringType: + elif type(taglist) == bytes: taglist = taglist.split(",") taglist = [t.strip() for t in taglist] log("module_tag_set: module_id=%s taglist=%s" % (module_id, taglist)) diff --git a/app/scodoc/sco_trombino.py b/app/scodoc/sco_trombino.py index cecfc961..3572a9dd 100644 --- a/app/scodoc/sco_trombino.py +++ b/app/scodoc/sco_trombino.py @@ -649,7 +649,7 @@ def zip_excel_import_files( log("zip: ignoring %s" % name) if Filename2Etud: # lignes excel non traitées - unmatched_files = Filename2Etud.keys() + unmatched_files = list(Filename2Etud.keys()) else: unmatched_files = [] # 3- Result page diff --git a/app/scodoc/sco_ue_external.py b/app/scodoc/sco_ue_external.py index 16edd46b..3b40dc1a 100644 --- a/app/scodoc/sco_ue_external.py +++ b/app/scodoc/sco_ue_external.py @@ -152,7 +152,7 @@ def external_ue_inscrit_et_note( ) # Inscription des étudiants sco_moduleimpl.do_moduleimpl_inscrit_etuds( - context, moduleimpl_id, formsemestre_id, notes_etuds.keys(), REQUEST=REQUEST + context, moduleimpl_id, formsemestre_id, list(notes_etuds.keys()), REQUEST=REQUEST ) # Création d'une évaluation si il n'y en a pas déjà: @@ -179,7 +179,7 @@ def external_ue_inscrit_et_note( context, REQUEST.AUTHENTICATED_USER, evaluation_id, - notes_etuds.items(), + list(notes_etuds.items()), do_it=True, ) diff --git a/app/scodoc/sco_undo_notes.py b/app/scodoc/sco_undo_notes.py index 3649120a..c9e81524 100644 --- a/app/scodoc/sco_undo_notes.py +++ b/app/scodoc/sco_undo_notes.py @@ -102,17 +102,17 @@ class NotesOperation(dict): def list_operations(context, evaluation_id): """returns list of NotesOperation for this evaluation""" - notes = sco_evaluations.do_evaluation_get_all_notes( + notes = list(sco_evaluations.do_evaluation_get_all_notes( context, evaluation_id, filter_suppressed=False - ).values() - notes_log = sco_evaluations.do_evaluation_get_all_notes( + ).values()) + notes_log = list(sco_evaluations.do_evaluation_get_all_notes( context, evaluation_id, filter_suppressed=False, table="notes_notes_log" - ).values() + ).values()) dt = OPERATION_DATE_TOLERANCE NotesDates = {} # { uid : intervalmap } for note in notes + notes_log: - if not NotesDates.has_key(note["uid"]): + if note["uid"] not in NotesDates: NotesDates[note["uid"]] = intervalmap() nd = NotesDates[note["uid"]] if nd[note["date"]] is None: diff --git a/app/scodoc/sco_utils.py b/app/scodoc/sco_utils.py index 02c5ac62..5f072725 100644 --- a/app/scodoc/sco_utils.py +++ b/app/scodoc/sco_utils.py @@ -38,11 +38,11 @@ import numbers import os import re import sys -import thread +import six.moves._thread import time import types -import urllib -import urllib2 +import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error +import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse import xml.sax.saxutils # XML generation package (apt-get install jaxml) @@ -54,7 +54,7 @@ try: STRING_TYPES = six.string_types except ImportError: # fallback for very old ScoDoc instances - STRING_TYPES = types.StringType + STRING_TYPES = bytes from PIL import Image as PILImage @@ -72,9 +72,7 @@ from app.scodoc import VERSION # ----- TEMPORAIRE POUR MIGRATION SCODOC7 -> SCODOC8 avant python3 def sco8_join(L, sep="\n"): # sco8 - return sep.join( - [x if not isinstance(x, types.UnicodeType) else x.encode("utf-8") for x in L] - ) + return sep.join([x if not isinstance(x, str) else x.encode("utf-8") for x in L]) # ----- CALCUL ET PRESENTATION DES NOTES @@ -139,7 +137,7 @@ def fmt_note(val, note_max=None, keep_numeric=False): return "EXC" # excuse, note neutralise if val == NOTES_ATTENTE: return "ATT" # attente, note neutralisee - if type(val) == types.FloatType or type(val) == types.IntType: + if type(val) == float or type(val) == int: if note_max != None and note_max > 0: val = val * 20.0 / note_max if keep_numeric: @@ -199,7 +197,7 @@ class DictDefault(dict): # obsolete, use collections.defaultdict self.update(kv_dict) def __getitem__(self, k): - if self.has_key(k): + if k in self: return self.get(k) value = copy.copy(self.defaultvalue) self[k] = value @@ -229,7 +227,7 @@ def group_by_key(d, key): # ----- Global lock for critical sections (except notes_tables caches) -GSL = thread.allocate_lock() # Global ScoDoc Lock +GSL = six.moves._thread.allocate_lock() # Global ScoDoc Lock # ----- Repertoire "var" (local) SCODOC_VAR_DIR = os.path.join(Config.INSTANCE_HOME, "var", "scodoc") @@ -436,12 +434,12 @@ isiterable = lambda obj: getattr(obj, "__iter__", False) def unescape_html_dict(d): """un-escape all dict values, recursively""" try: - indices = d.keys() + indices = list(d.keys()) except: - indices = range(len(d)) + indices = list(range(len(d))) for k in indices: v = d[k] - if type(v) == types.StringType: + if type(v) == bytes: d[k] = unescape_html(v) elif isiterable(v): unescape_html_dict(v) @@ -486,7 +484,7 @@ def simple_dictlist2xml(dictlist, doc=None, tagname=None, quote=False): raise ValueError("invalid empty tagname !") if not doc: doc = jaxml.XML_document(encoding=SCO_ENCODING) - scalar_types = [types.StringType, types.UnicodeType, types.IntType, types.FloatType] + scalar_types = [bytes, str, int, float] for d in dictlist: doc._push() if ( @@ -507,7 +505,7 @@ def simple_dictlist2xml(dictlist, doc=None, tagname=None, quote=False): [(k, v) for (k, v) in d.items() if type(v) in scalar_types] ) getattr(doc, tagname)(**d_scalar) - d_list = dict([(k, v) for (k, v) in d.items() if type(v) == types.ListType]) + d_list = dict([(k, v) for (k, v) in d.items() if type(v) == list]) if d_list: for (k, v) in d_list.items(): simple_dictlist2xml(v, doc=doc, tagname=k, quote=quote) @@ -545,7 +543,7 @@ def stripquotes(s): def suppress_accents(s): "s is an ordinary string, encoding given by SCO_ENCODING" - return str(suppression_diacritics(unicode(s, SCO_ENCODING))) + return str(suppression_diacritics(six.text_type(s, SCO_ENCODING))) def sanitize_string(s): @@ -639,7 +637,7 @@ def sendJSON(REQUEST, data): def sendXML(REQUEST, data, tagname=None, force_outer_xml_tag=True): - if type(data) != types.ListType: + if type(data) != list: data = [data] # always list-of-dicts if force_outer_xml_tag: root_tagname = tagname + "_list" @@ -898,7 +896,7 @@ def query_portal(req, msg="Portail Apogee", timeout=3): log("query_portal: %s" % req) try: - f = urllib2.urlopen(req, timeout=timeout) # seconds / request + f = six.moves.urllib.request.urlopen(req, timeout=timeout) # seconds / request except: log("query_portal: can't connect to %s" % msg) return "" @@ -913,7 +911,7 @@ def query_portal(req, msg="Portail Apogee", timeout=3): def AnneeScolaire(REQUEST=None): # TODO remplacer REQUEST #sco8 "annee de debut de l'annee scolaire courante" - if REQUEST and REQUEST.form.has_key("sco_year"): + if REQUEST and "sco_year" in REQUEST.form: year = REQUEST.form["sco_year"] try: year = int(year) @@ -992,7 +990,7 @@ def confirm_dialog( if not dest_url: dest_url = REQUEST.URL # strip remaining parameters from destination url: - dest_url = urllib.splitquery(dest_url)[0] + dest_url = six.moves.urllib.parse.splitquery(dest_url)[0] H = [ """""" % dest_url, message,
%s%d