diff --git a/.pylintrc b/.pylintrc index 1bda9b54a..a69fc72bb 100644 --- a/.pylintrc +++ b/.pylintrc @@ -1,2 +1,6 @@ +[[MESSAGES CONTROL] +# pylint and black disagree... +disable=bad-continuation + [TYPECHECK] ignored-classes=Permission diff --git a/README.md b/README.md index 48336d5d2..cd6a01343 100644 --- a/README.md +++ b/README.md @@ -56,15 +56,3 @@ Installer le bon vieux `pyExcelerator` dans l'environnement: ### Méthodes qui ne devraient plus être publiées: - - - - - - - - - - - - diff --git a/app/decorators.py b/app/decorators.py index 3d90aa212..5199f85ed 100644 --- a/app/decorators.py +++ b/app/decorators.py @@ -48,14 +48,17 @@ class ZRequest(object): self.REQUEST_METHOD = request.method.encode("utf-8") self.AUTHENTICATED_USER = current_user if request.method == "POST": - self.form = request.form + self.form = request.form # xxx encode en utf-8 ! + # Encode en utf-8 pour ScoDoc8 #sco8 + self.form = {k: v.encode("utf-8") for (k, v) in request.form.items()} if request.files: # Add files in form: must copy to get a mutable version # request.form is a werkzeug.datastructures.ImmutableMultiDict - self.form = self.form.copy() + # self.form = self.form.copy() self.form.update(request.files) elif request.method == "GET": - self.form = request.args + # Encode en utf-8 pour ScoDoc8 #sco8 + self.form = {k: v.encode("utf-8") for (k, v) in request.args.items()} self.RESPONSE = ZResponse() def __str__(self): @@ -158,7 +161,11 @@ def scodoc7func(context): elif arg_name == "context": pos_arg_values.append(context) else: - pos_arg_values.append(req_args[arg_name]) + # XXX Convert to regular string for ScoDoc8/Python 2 + if type(req_args[arg_name]) == types.UnicodeType: + pos_arg_values.append(req_args[arg_name].encode("utf-8")) + else: + pos_arg_values.append(req_args[arg_name]) current_app.logger.info("pos_arg_values=%s" % pos_arg_values) # Add keyword arguments if nb_default_args: @@ -167,7 +174,11 @@ def scodoc7func(context): kwargs[arg_name] = REQUEST elif arg_name in req_args: # set argument kw optionnel - kwargs[arg_name] = req_args[arg_name] + # XXX Convert to regular string for ScoDoc8/Python 2 + if type(req_args[arg_name]) == types.UnicodeType: + kwargs[arg_name] = req_args[arg_name].encode("utf-8") + else: + kwargs[arg_name] = req_args[arg_name] current_app.logger.info( "scodoc7func_decorator: top_level=%s, pos_arg_values=%s, kwargs=%s" % (top_level, pos_arg_values, kwargs) diff --git a/app/scodoc/ImportScolars.py b/app/scodoc/ImportScolars.py index 20e0180df..8e4f1d571 100644 --- a/app/scodoc/ImportScolars.py +++ b/app/scodoc/ImportScolars.py @@ -36,12 +36,14 @@ import collections import types import re -import sco_utils as scu -import notesdb as ndb -from notes_log import log -from sco_formsemestre_inscriptions import do_formsemestre_inscription_with_modules -from gen_tables import GenTable -from sco_exceptions import ( +import app.scodoc.sco_utils as scu +import app.scodoc.notesdb as ndb +from app.scodoc.notes_log import log +from app.scodoc.sco_formsemestre_inscriptions import ( + do_formsemestre_inscription_with_modules, +) +from app.scodoc.gen_tables import GenTable +from app.scodoc.sco_exceptions import ( AccessDenied, FormatError, ScoException, @@ -50,14 +52,14 @@ from sco_exceptions import ( ScoLockedFormError, ScoGenError, ) -import html_sco_header -import scolars -import sco_formsemestre -import sco_groups -import sco_excel -import sco_groups_view -import sco_news -import sco_preferences +from app.scodoc import html_sco_header +from app.scodoc import sco_etud +from app.scodoc import sco_formsemestre +from app.scodoc import sco_groups +from app.scodoc import sco_excel +from app.scodoc import sco_groups_view +from app.scodoc import sco_news +from app.scodoc import sco_preferences # format description (relative to Product directory)) FORMAT_FILE = "misc/format_import_etudiants.txt" @@ -199,7 +201,7 @@ def sco_import_generate_excel_sample( # rempli table avec données actuelles lines = [] for i in members: - etud = scolars.get_etud_info(etudid=i["etudid"], filled=True)[0] + etud = sco_etud.get_etud_info(etudid=i["etudid"], filled=True)[0] l = [] for field in titles: if field == "groupes": @@ -371,7 +373,7 @@ def scolars_import_excel_file( # xxx Ad-hoc checks (should be in format description) if scu.strlower(titleslist[i]) == "sexe": try: - val = scolars.input_civilite(val) + val = sco_etud.input_civilite(val) except: raise ScoValueError( "valeur invalide pour 'SEXE' (doit etre 'M', 'F', ou 'MME', 'H', 'X' ou vide, mais pas '%s') ligne %d, colonne %s" @@ -405,7 +407,7 @@ def scolars_import_excel_file( if values["code_ine"] and not is_new_ine: raise ScoValueError("Code INE dupliqué (%s)" % values["code_ine"]) # Check nom/prenom - ok, NbHomonyms = scolars.check_nom_prenom( + ok, NbHomonyms = sco_etud.check_nom_prenom( cnx, nom=values["nom"], prenom=values["prenom"] ) if not ok: @@ -513,16 +515,16 @@ def _import_one_student( ) # Identite args = values.copy() - etudid = scolars.identite_create(cnx, args, context=context, REQUEST=REQUEST) + etudid = sco_etud.identite_create(cnx, args, context=context, REQUEST=REQUEST) created_etudids.append(etudid) # Admissions args["etudid"] = etudid args["annee"] = annee_courante - _ = scolars.admission_create(cnx, args) + _ = sco_etud.admission_create(cnx, args) # Adresse args["typeadresse"] = "domicile" args["description"] = "(infos admission)" - _ = scolars.adresse_create(cnx, args) + _ = sco_etud.adresse_create(cnx, args) # Inscription au semestre args["etat"] = "I" # etat insc. semestre if formsemestre_id: @@ -561,7 +563,7 @@ def _import_one_student( def _is_new_ine(cnx, code_ine): "True if this code is not in DB" - etuds = scolars.identite_list(cnx, {"code_ine": code_ine}) + etuds = sco_etud.identite_list(cnx, {"code_ine": code_ine}) return not etuds @@ -642,7 +644,7 @@ def scolars_import_admission( ) else: etud = etuds_by_nomprenom[(nom, prenom)] - cur_adm = scolars.admission_list(cnx, args={"etudid": etud["etudid"]})[0] + cur_adm = sco_etud.admission_list(cnx, args={"etudid": etud["etudid"]})[0] # peuple les champs presents dans le tableau args = {} for idx in fields: @@ -665,17 +667,17 @@ def scolars_import_admission( # Type admission: traitement particulier if not cur_adm["type_admission"] and not args.get("type_admission"): args["type_admission"] = type_admission - scolars.etudident_edit(cnx, args) - adr = scolars.adresse_list(cnx, args={"etudid": etud["etudid"]}) + sco_etud.etudident_edit(cnx, args) + adr = sco_etud.adresse_list(cnx, args={"etudid": etud["etudid"]}) if adr: args["adresse_id"] = adr[0]["adresse_id"] - scolars.adresse_edit( + sco_etud.adresse_edit( cnx, args ) # ne passe pas le contexte: pas de notification ici else: args["typeadresse"] = "domicile" args["description"] = "(infos admission)" - adresse_id = scolars.adresse_create(cnx, args) + adresse_id = sco_etud.adresse_create(cnx, args) # log('import_adm: %s' % args ) # Change les groupes si nécessaire: if args["groupes"]: diff --git a/app/scodoc/TrivialFormulator.py b/app/scodoc/TrivialFormulator.py index 5cadf9290..dd279afa1 100644 --- a/app/scodoc/TrivialFormulator.py +++ b/app/scodoc/TrivialFormulator.py @@ -485,7 +485,7 @@ class TF: lem.append("
- Saisie des absences %s %s, - semaine du lundi %s-
-
- """
- % {"menu_module": menu_module, "url": base_url, "sel": sel}
- )
-
- H += self._gen_form_saisie_groupe(
- etuds, datessem, destination, moduleimpl_id, require_module
- )
-
- H.append(self.sco_footer(REQUEST))
- return "\n".join(H)
-
- security.declareProtected(ScoAbsChange, "SignaleAbsenceGrSemestre")
-
- def SignaleAbsenceGrSemestre(
- self,
- datedebut,
- datefin,
- destination="",
- group_ids=[], # list of groups to display
- nbweeks=4, # ne montre que les nbweeks dernieres semaines
- moduleimpl_id=None,
- REQUEST=None,
- ):
- """Saisie des absences sur une journée sur un semestre (ou intervalle de dates) entier"""
- groups_infos = sco_groups_view.DisplayedGroupsInfos(
- self, group_ids, REQUEST=REQUEST
- )
- if not groups_infos.members:
- return (
- self.sco_header(page_title="Saisie des absences", REQUEST=REQUEST)
- + "Aucun étudiant !" - + self.sco_footer(REQUEST) - ) - formsemestre_id = groups_infos.formsemestre_id - require_module = self.get_preference("abs_require_module", formsemestre_id) - etuds = [ - self.getEtudInfo(etudid=m["etudid"], filled=True)[0] - for m in groups_infos.members - ] - # Restreint aux inscrits au module sélectionné - if moduleimpl_id: - mod_inscrits = set( - [ - x["etudid"] - for x in sco_moduleimpl.do_moduleimpl_inscription_list( - self.Notes, moduleimpl_id=moduleimpl_id - ) - ] - ) - etuds = [e for e in etuds if e["etudid"] in mod_inscrits] - if not moduleimpl_id: - moduleimpl_id = None - base_url_noweeks = ( - "SignaleAbsenceGrSemestre?datedebut=%s&datefin=%s&%s&destination=%s" - % ( - datedebut, - datefin, - groups_infos.groups_query_args, - urllib.quote(destination), - ) - ) - base_url = base_url_noweeks + "&nbweeks=%s" % nbweeks # sans le moduleimpl_id - - if etuds: - nt = self.Notes._getNotesCache().get_NotesTable(self.Notes, formsemestre_id) - sem = sco_formsemestre.do_formsemestre_list( - self, {"formsemestre_id": formsemestre_id} - )[0] - work_saturday = sco_abs.is_work_saturday(self) - jourdebut = ddmmyyyy(datedebut, work_saturday=work_saturday) - jourfin = ddmmyyyy(datefin, work_saturday=work_saturday) - today = ddmmyyyy( - time.strftime("%d/%m/%Y", time.localtime()), - work_saturday=work_saturday, - ) - today.next() - if jourfin > today: # ne propose jamais les semaines dans le futur - jourfin = today - if jourdebut > today: - raise ScoValueError("date de début dans le futur (%s) !" % jourdebut) - # - if not jourdebut.iswork() or jourdebut > jourfin: - raise ValueError( - "date debut invalide (%s, ouvrable=%d)" - % (str(jourdebut), jourdebut.iswork()) - ) - # calcule dates - dates = [] # ddmmyyyy instances - d = ddmmyyyy(datedebut, work_saturday=work_saturday) - while d <= jourfin: - dates.append(d) - d = d.next(7) # avance d'une semaine - # - msg = "Montrer seulement les 4 dernières semaines" - nwl = 4 - if nbweeks: - nbweeks = int(nbweeks) - if nbweeks > 0: - dates = dates[-nbweeks:] - msg = "Montrer toutes les semaines" - nwl = 0 - url_link_semaines = base_url_noweeks + "&nbweeks=%s" % nwl - if moduleimpl_id: - url_link_semaines += "&moduleimpl_id=" + moduleimpl_id - # - dates = [x.ISO() for x in dates] - dayname = sco_abs.day_names(self)[jourdebut.weekday] - - if groups_infos.tous_les_etuds_du_sem: - gr_tit = "en" - else: - if len(groups_infos.group_ids) > 1: - p = "des groupes " - else: - p = "du groupe " - gr_tit = ( - p + '' + groups_infos.groups_titles + "" - ) - - H = [ - self.sco_header( - page_title="Saisie des absences", - init_qtip=True, - javascripts=["js/etud_info.js", "js/abs_ajax.js"], - no_side_bar=1, - REQUEST=REQUEST, - ), - """
Les cases cochées correspondent à des absences. - Les absences saisies ne sont pas justifiées (sauf si un justificatif a été entré - par ailleurs). - Si vous "décochez" une case, l'absence correspondante sera supprimée. - Attention, les modifications sont automatiquement entregistrées au fur et à mesure. - - """ - % destination - ) - return H - - def _TablesAbsEtud( - self, - etudid, - datedebut, - with_evals=True, - format="html", - absjust_only=0, - REQUEST=None, - ): - """Tables des absences justifiees et non justifiees d'un étudiant sur l'année en cours""" - absjust = self.ListeAbsJust(etudid=etudid, datedebut=datedebut) - absnonjust = self.ListeAbsNonJust(etudid=etudid, datedebut=datedebut) - # examens ces jours là ? - if with_evals: - cnx = self.GetDBConnexion() - cursor = cnx.cursor(cursor_factory=notesdb.ScoDocCursor) - for a in absnonjust + absjust: - cursor.execute( - """select eval.* - from notes_evaluation eval, notes_moduleimpl_inscription mi, notes_moduleimpl m - where eval.jour = %(jour)s and eval.moduleimpl_id = m.moduleimpl_id - and mi.moduleimpl_id = m.moduleimpl_id and mi.etudid = %(etudid)s""", - {"jour": a["jour"].strftime("%Y-%m-%d"), "etudid": etudid}, - ) - a["evals"] = cursor.dictfetchall() - cursor.execute( - """SELECT mi.moduleimpl_id - from absences abs, notes_moduleimpl_inscription mi, notes_moduleimpl m - where abs.matin = %(matin)s and abs.jour = %(jour)s and abs.etudid=%(etudid)s and abs.moduleimpl_id=mi.moduleimpl_id and mi.moduleimpl_id=m.moduleimpl_id - and mi.etudid = %(etudid)s""", - { - "matin": bool(a["matin"]), - "jour": a["jour"].strftime("%Y-%m-%d"), - "etudid": etudid, - }, - ) - a["absent"] = cursor.dictfetchall() - - def matin(x): - if x: - return "matin" - else: - return "après-midi" - - def descr_exams(a): - if not a.has_key("evals"): - return "" - ex = [] - for ev in a["evals"]: - mod = sco_moduleimpl.do_moduleimpl_withmodule_list( - self.Notes, moduleimpl_id=ev["moduleimpl_id"] - )[0] - if format == "html": - ex.append( - '%s' - % (mod["moduleimpl_id"], mod["module"]["code"]) - ) - else: - ex.append(mod["module"]["code"]) - if ex: - return ", ".join(ex) - return "" - - def descr_abs(a): - ex = [] - for ev in a.get("absent", []): - mod = sco_moduleimpl.do_moduleimpl_withmodule_list( - self.Notes, moduleimpl_id=ev["moduleimpl_id"] - )[0] - if format == "html": - ex.append( - '%s' - % (mod["moduleimpl_id"], mod["module"]["code"]) - ) - else: - ex.append(mod["module"]["code"]) - if ex: - return ", ".join(ex) - return "" - - # ajoute date formatée et évaluations - for L in (absnonjust, absjust): - for a in L: - if with_evals: - a["exams"] = descr_exams(a) - a["datedmy"] = a["jour"].strftime("%d/%m/%Y") - a["ampm"] = int(a["matin"]) - a["matin"] = matin(a["matin"]) - index = a["description"].find(")") - if index != -1: - a["motif"] = a["description"][1:index] - else: - a["motif"] = "" - a["description"] = descr_abs(a) or "" - - # ajoute lien pour justifier - if format == "html": - for a in absnonjust: - a["justlink"] = "justifier" - a["_justlink_target"] = ( - "doJustifAbsence?etudid=%s&datedebut=%s&datefin=%s&demijournee=%s" - % (etudid, a["datedmy"], a["datedmy"], a["ampm"]) - ) - # - titles = { - "datedmy": "Date", - "matin": "", - "exams": "Examens ce jour", - "justlink": "", - "description": "Modules", - "motif": "Motif", - } - columns_ids = ["datedmy", "matin"] - if format in ("json", "xml"): - columns_ids += ["jour", "ampm"] - if with_evals: - columns_ids.append("exams") - - columns_ids.append("description") - columns_ids.append("motif") - if format == "html": - columns_ids.append("justlink") - - return titles, columns_ids, absnonjust, absjust - - security.declareProtected(ScoView, "EtatAbsencesGr") # ported from dtml - - def EtatAbsencesGr( - self, - group_ids=[], # list of groups to display - debut="", - fin="", - with_boursier=True, # colonne boursier - format="html", - REQUEST=None, - ): - """Liste les absences de groupes""" - datedebut = notesdb.DateDMYtoISO(debut) - datefin = notesdb.DateDMYtoISO(fin) - # Informations sur les groupes à afficher: - groups_infos = sco_groups_view.DisplayedGroupsInfos( - self, group_ids, REQUEST=REQUEST - ) - formsemestre_id = groups_infos.formsemestre_id - sem = groups_infos.formsemestre - - # Construit tableau (etudid, statut, nomprenom, nbJust, nbNonJust, NbTotal) - T = [] - for m in groups_infos.members: - etud = self.getEtudInfo(etudid=m["etudid"], filled=True)[0] - nbabs = self.CountAbs(etudid=etud["etudid"], debut=datedebut, fin=datefin) - nbabsjust = self.CountAbsJust( - etudid=etud["etudid"], debut=datedebut, fin=datefin - ) - nbjustifs_noabs = len( - self.ListeJustifs( - etudid=etud["etudid"], datedebut=datedebut, only_no_abs=True - ) - ) - # retrouve sem dans etud['sems'] - s = None - for s in etud["sems"]: - if s["formsemestre_id"] == formsemestre_id: - break - if not s or s["formsemestre_id"] != formsemestre_id: - raise ValueError( - "EtatAbsencesGr: can't retreive sem" - ) # bug or malicious arg - T.append( - { - "etudid": etud["etudid"], - "etatincursem": s["ins"]["etat"], - "nomprenom": etud["nomprenom"], - "nbabsjust": nbabsjust, - "nbabsnonjust": nbabs - nbabsjust, - "nbabs": nbabs, - "nbjustifs_noabs": nbjustifs_noabs, - "_nomprenom_target": "CalAbs?etudid=%s" % etud["etudid"], - "_nomprenom_td_attrs": 'id="%s" class="etudinfo"' % etud["etudid"], - "boursier": etud["boursier"], - } - ) - if s["ins"]["etat"] == "D": - T[-1]["_css_row_class"] = "etuddem" - T[-1]["nomprenom"] += " (dem)" - columns_ids = [ - "nomprenom", - "nbjustifs_noabs", - "nbabsjust", - "nbabsnonjust", - "nbabs", - ] - if with_boursier: - columns_ids[1:1] = ["boursier"] - if groups_infos.tous_les_etuds_du_sem: - gr_tit = "" - else: - if len(groups_infos.group_ids) > 1: - p = "des groupes" - else: - p = "du groupe" - if format == "html": - h = ' ' + groups_infos.groups_titles + "" - else: - h = groups_infos.groups_titles - gr_tit = p + h - - title = "Etat des absences %s" % gr_tit - if format == "xls" or format == "xml" or format == "json": - columns_ids = ["etudid"] + columns_ids - tab = GenTable( - columns_ids=columns_ids, - rows=T, - preferences=self.get_preferences(formsemestre_id), - titles={ - "etatincursem": "Etat", - "nomprenom": "Nom", - "nbabsjust": "Justifiées", - "nbabsnonjust": "Non justifiées", - "nbabs": "Total", - "nbjustifs_noabs": "Justifs non utilisés", - "boursier": "Bourse", - }, - html_sortable=True, - html_class="table_leftalign", - html_header=self.sco_header( - REQUEST, - page_title=title, - init_qtip=True, - javascripts=["js/etud_info.js"], - ), - html_title=self.Notes.html_sem_header( - REQUEST, "%s" % title, sem, with_page_header=False - ) - + "Période du %s au %s (nombre de demi-journées) |
-Justifs non utilisés: nombre de demi-journées avec justificatif mais sans absences relevées. -
-
-Cliquez sur un nom pour afficher le calendrier des absences
-ou entrez une date pour visualiser les absents un jour donné :
-
- | Matin | Après-midi |
---|---|---|
- %(nomprenom)s | """ - % etud - ) # """ - if nbabsam != 0: - if nbabsjustam: - H.append("Just.") - t_nbabsjustam += 1 - else: - H.append("Abs.") - t_nbabsam += 1 - else: - H.append("") - H.append(' | ') - if nbabspm != 0: - if nbabsjustpm: - H.append("Just.") - t_nbabsjustam += 1 - else: - H.append("Abs.") - t_nbabspm += 1 - else: - H.append("") - H.append(" |
%d abs, %d just. | %d abs, %d just. |
Aucune absence !
") - else: - H.append( - """L'étudiant pense pouvoir justifier cette absence.
Vérifiez le justificatif avant d'enregistrer.
Supprimer ce billet (utiliser en cas d'erreur, par ex. billet en double)
""" - % billet_id - ) - F += 'Liste de tous les billets en attente
' - - return "\n".join(H) + "%s
""" % scu.SCOVERSION - - -# def test_refactor(context, x=1): -# x = context.toto() -# y = ("context=" + sco_edit_module.module_is_locked(context, "alpha")) + "23" -# z = html_sco_header.sco_header( -# context, -# a_long_argument_hahahahaha=1, -# another_very_long_arggggggggggggg=2, -# z=6, -# u=99, -# kkkkkk=1, -# ) +import app.scodoc.sco_utils as scu +from app.scodoc.notes_log import log +from app.scodoc.sco_exceptions import NoteProcessError +from app.scodoc import sco_cache # @@ -134,6 +111,8 @@ class CacheNotesTable: def inval_cache(self, context, formsemestre_id=None, pdfonly=False): # > "expire cache pour un semestre (ou tous si pas d'argument)" + from app.scodoc import sco_parcours_dut + log( "inval_cache, formsemestre_id=%s pdfonly=%s (id=%s)" % (formsemestre_id, pdfonly, id(self)) # > @@ -151,14 +130,16 @@ class CacheNotesTable: self.cache = {} self.pdfcache = {} self._call_all_listeners() - sco_core.get_evaluations_cache( + get_evaluations_cache( context, ).inval_cache() else: # formsemestre_id modifié: # on doit virer formsemestre_id et tous les semestres # susceptibles d'utiliser des UE capitalisées de ce semestre. - to_trash = [formsemestre_id] + list_formsemestre_utilisateurs_uecap( + to_trash = [ + formsemestre_id + ] + sco_parcours_dut.list_formsemestre_utilisateurs_uecap( context, formsemestre_id ) if not pdfonly: @@ -170,7 +151,7 @@ class CacheNotesTable: ) del self.cache[formsemestre_id] self._call_listeners(formsemestre_id) - sco_core.get_evaluations_cache( + get_evaluations_cache( context, ).inval_cache() diff --git a/app/scodoc/sco_cost_formation.py b/app/scodoc/sco_cost_formation.py index 81591f677..eef25381a 100644 --- a/app/scodoc/sco_cost_formation.py +++ b/app/scodoc/sco_cost_formation.py @@ -30,16 +30,13 @@ (coût théorique en heures équivalent TD) """ -import notesdb as ndb -import sco_utils as scu -from notes_log import log -from gen_tables import GenTable -import sco_excel, sco_pdf -from sco_pdf import SU -import sco_formsemestre -import sco_moduleimpl -import sco_formsemestre_status -import VERSION +import app.scodoc.sco_utils as scu +from app.scodoc.gen_tables import GenTable +from app.scodoc import sco_formsemestre +from app.scodoc import sco_moduleimpl +from app.scodoc import sco_formsemestre_status +from app.scodoc import VERSION +from app.scodoc import sco_preferences def formsemestre_table_estim_cost( diff --git a/app/scodoc/sco_debouche.py b/app/scodoc/sco_debouche.py index 450f2ce7d..4e9d52b97 100644 --- a/app/scodoc/sco_debouche.py +++ b/app/scodoc/sco_debouche.py @@ -31,16 +31,19 @@ Rapport (table) avec dernier semestre fréquenté et débouché de chaque étudi from types import StringType import safehtml -import sco_utils as scu -import notesdb as ndb -from notes_log import log -import VERSION -from sco_exceptions import AccessDenied -from scolog import logdb -from gen_tables import GenTable -import sco_formsemestre -import sco_groups -import sco_tag_module +import app.scodoc.sco_utils as scu +import app.scodoc.notesdb as ndb +from app.scodoc.notes_log import log +from app.scodoc import VERSION +from app.scodoc.sco_exceptions import AccessDenied +from app.scodoc.scolog import logdb +from app.scodoc.gen_tables import GenTable +from app.scodoc import html_sco_header +from app.scodoc import sco_core +from app.scodoc import sco_permissions_check +from app.scodoc import sco_preferences +from app.scodoc import sco_tag_module +from app.scodoc import sco_etud def report_debouche_date(context, start_year=None, format="html", REQUEST=None): @@ -104,7 +107,7 @@ def table_debouche_etudids(context, etudids, keep_numeric=True): """Rapport pour ces etudiants""" L = [] for etudid in etudids: - etud = scolars.get_etud_info(filled=1, etudid=etudid)[0] + 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))] @@ -211,12 +214,12 @@ def report_debouche_ask_date(context, REQUEST=None): # def debouche_set(context, object, value, REQUEST=None): # """Set debouche (field in admission table, may be deprecated ?) # """ -# if not sco_permissions.can_edit_suivi(context, REQUEST): +# if not sco_permissions_check.can_edit_suivi(context, REQUEST): # raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !") # adm_id = object # debouche = value.strip('-_ \t') # cnx = ndb.GetDBConnexion() -# adms = scolars.admission_list(cnx, {'etudid' : etudid}) +# adms = sco_etud.admission_list(cnx, {'etudid' : etudid}) # if not adms: # raise ValueError('no admission info for %s !' % etudid) # adm = adms[0] @@ -263,7 +266,7 @@ def itemsuivi_get(cnx, itemsuivi_id, ignore_errors=False): def itemsuivi_suppress(context, itemsuivi_id, REQUEST=None): """Suppression d'un item""" - if not sco_permissions.can_edit_suivi(context, REQUEST): + if not sco_permissions_check.can_edit_suivi(context, REQUEST): raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !") cnx = ndb.GetDBConnexion() item = itemsuivi_get(cnx, itemsuivi_id, ignore_errors=True) @@ -277,7 +280,7 @@ def itemsuivi_create( context, etudid, item_date=None, situation="", REQUEST=None, format=None ): """Creation d'un item""" - if not sco_permissions.can_edit_suivi(context, REQUEST): + if not sco_permissions_check.can_edit_suivi(context, REQUEST): raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !") cnx = ndb.GetDBConnexion() itemsuivi_id = _itemsuivi_create( @@ -295,7 +298,7 @@ def itemsuivi_set_date(context, itemsuivi_id, item_date, REQUEST=None): """set item date item_date is a string dd/mm/yyyy """ - if not sco_permissions.can_edit_suivi(context, REQUEST): + if not sco_permissions_check.can_edit_suivi(context, REQUEST): raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !") # log('itemsuivi_set_date %s : %s' % (itemsuivi_id, item_date)) cnx = ndb.GetDBConnexion() @@ -306,7 +309,7 @@ def itemsuivi_set_date(context, itemsuivi_id, item_date, REQUEST=None): def itemsuivi_set_situation(context, object, value, REQUEST=None): """set situation""" - if not sco_permissions.can_edit_suivi(context, REQUEST): + if not sco_permissions_check.can_edit_suivi(context, REQUEST): raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !") itemsuivi_id = object situation = value.strip("-_ \t") @@ -364,7 +367,7 @@ def itemsuivi_tag_set(context, itemsuivi_id="", taglist=[], REQUEST=None): a string with tag names separated by commas ("un;deux") or a list of strings (["un", "deux"]) """ - if not sco_permissions.can_edit_suivi(context, REQUEST): + if not sco_permissions_check.can_edit_suivi(context, REQUEST): raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !") if not taglist: taglist = [] diff --git a/app/scodoc/sco_dept.py b/app/scodoc/sco_dept.py index 6720c96d7..8461b890b 100644 --- a/app/scodoc/sco_dept.py +++ b/app/scodoc/sco_dept.py @@ -27,17 +27,16 @@ """Page accueil département (liste des semestres, etc) """ -import notesdb as ndb -import sco_utils as scu -from notes_log import log -import sco_modalites -import sco_news -import sco_up_to_date -import sco_formsemestre -from gen_tables import GenTable -from sco_permissions import Permission, ScoEtudInscrit, ScoEditApo -import html_sco_header -import sco_formsemestre_inscriptions +import app.scodoc.sco_utils as scu +from app.scodoc.gen_tables import GenTable +from app.scodoc.sco_permissions import Permission +from app.scodoc import html_sco_header +from app.scodoc import sco_formsemestre +from app.scodoc import sco_formsemestre_inscriptions +from app.scodoc import sco_modalites +from app.scodoc import sco_news +from app.scodoc import sco_preferences +from app.scodoc import sco_up_to_date def index_html(context, REQUEST=None, showcodes=0, showsemtable=0): diff --git a/app/scodoc/sco_dump_db.py b/app/scodoc/sco_dump_db.py index 41f95596a..e682c5e34 100644 --- a/app/scodoc/sco_dump_db.py +++ b/app/scodoc/sco_dump_db.py @@ -51,22 +51,23 @@ import fcntl import subprocess import requests -from email.mime.multipart import MIMEMultipart -from email.mime.text import MIMEText -from email.mime.base import MIMEBase -from email.header import Header -import notesdb as ndb -import sco_utils as scu -from notes_log import log -from sco_exceptions import ScoValueError +import app.scodoc.notesdb as ndb +import app.scodoc.sco_utils as scu +from app.scodoc.notes_log import log +from app.scodoc import html_sco_header +from app.scodoc import sco_preferences +from app.scodoc import VERSION +from app.scodoc.sco_exceptions import ScoValueError SCO_DUMP_LOCK = "/tmp/scodump.lock" def sco_dump_and_send_db(context, REQUEST=None): """Dump base de données du département courant et l'envoie anonymisée pour debug""" - H = [html_sco_header.sco_header(context, REQUEST, page_title="Assistance technique")] + H = [ + html_sco_header.sco_header(context, REQUEST, page_title="Assistance technique") + ] # get currect (dept) DB name: cursor = ndb.SimpleQuery(context, "SELECT current_database()", {}) db_name = cursor.fetchone()[0] @@ -194,7 +195,7 @@ def _send_db(context, REQUEST, ano_db_name): "sent_by": context.Users.user_info(str(REQUEST.AUTHENTICATED_USER))[ "nomcomplet" ], - "sco_version": scu.SCOVERSION, + "sco_version": VERSION.SCOVERSION, "sco_fullversion": scu.get_scodoc_version(), }, ) diff --git a/app/scodoc/sco_edit_formation.py b/app/scodoc/sco_edit_formation.py index 13ae110dc..3b43d53e7 100644 --- a/app/scodoc/sco_edit_formation.py +++ b/app/scodoc/sco_edit_formation.py @@ -28,16 +28,19 @@ """Ajout/Modification/Supression formations (portage from DTML) """ -import notesdb as ndb -import sco_utils as scu -from notes_log import log -from TrivialFormulator import TrivialFormulator, TF, tf_error_message -import sco_codes_parcours -import sco_edit_module -import sco_edit_ue -import sco_formsemestre -from sco_exceptions import ScoValueError -import sco_formations +import app.scodoc.notesdb as ndb +import app.scodoc.sco_utils as scu +from app.scodoc.notes_log import log +from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message +from app.scodoc.sco_exceptions import ScoValueError, ScoLockedFormError +from app.scodoc import html_sco_header +from app.scodoc import sco_codes_parcours +from app.scodoc import sco_core +from app.scodoc import sco_edit_module +from app.scodoc import sco_edit_ue +from app.scodoc import sco_formations +from app.scodoc import sco_formsemestre +from app.scodoc import sco_news def formation_delete(context, formation_id=None, dialog_confirmed=False, REQUEST=None): @@ -105,7 +108,7 @@ def do_formation_delete(context, oid, REQUEST): # delete all UE in this formation ues = sco_edit_ue.do_ue_list(context, {"formation_id": oid}) for ue in ues: - do_ue_delete(ue["ue_id"], REQUEST=REQUEST, force=True) + sco_edit_ue.do_ue_delete(context, ue["ue_id"], REQUEST=REQUEST, force=True) sco_formations._formationEditor.delete(cnx, oid) @@ -113,7 +116,7 @@ def do_formation_delete(context, oid, REQUEST): sco_news.add( context, REQUEST, - typ=NEWS_FORM, + typ=sco_news.NEWS_FORM, object=oid, text="Suppression de la formation %(acronyme)s" % F, ) @@ -277,7 +280,7 @@ def do_formation_create(context, args, REQUEST): sco_news.add( context, REQUEST, - typ=NEWS_FORM, + typ=sco_news.NEWS_FORM, text="Création de la formation %(titre)s (%(acronyme)s)" % args, ) return r diff --git a/app/scodoc/sco_edit_matiere.py b/app/scodoc/sco_edit_matiere.py index 39e53e9a8..d4e2b056d 100644 --- a/app/scodoc/sco_edit_matiere.py +++ b/app/scodoc/sco_edit_matiere.py @@ -28,14 +28,13 @@ """Ajout/Modification/Supression matieres (portage from DTML) """ -import notesdb as ndb -import sco_utils as scu -from notes_log import log -from TrivialFormulator import TrivialFormulator, TF, tf_error_message -import sco_edit_ue -import sco_formsemestre -import sco_news -from sco_exceptions import ScoValueError +import app.scodoc.notesdb as ndb +import app.scodoc.sco_utils as scu +from app.scodoc.notes_log import log +from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message +from app.scodoc.sco_exceptions import ScoValueError, ScoLockedFormError +from app.scodoc import html_sco_header +from app.scodoc import sco_core _matiereEditor = ndb.EditableTable( "notes_matieres", @@ -56,10 +55,8 @@ def do_matiere_edit(context, *args, **kw): "edit a matiere" cnx = ndb.GetDBConnexion() # check - mat = sco_edit_matiere.do_matiere_list( - context, {"matiere_id": args[0]["matiere_id"]} - )[0] - if sco_edit_matiere.matiere_is_locked(context, mat["matiere_id"]): + mat = do_matiere_list(context, {"matiere_id": args[0]["matiere_id"]})[0] + if matiere_is_locked(context, mat["matiere_id"]): raise ScoLockedFormError() # edit _matiereEditor.edit(cnx, *args, **kw) @@ -68,6 +65,10 @@ def do_matiere_edit(context, *args, **kw): def do_matiere_create(context, args, REQUEST): "create a matiere" + from app.scodoc import sco_edit_ue + from app.scodoc import sco_formations + from app.scodoc import sco_news + cnx = ndb.GetDBConnexion() # check ue = sco_edit_ue.do_ue_list(context, {"ue_id": args["ue_id"]})[0] @@ -81,7 +82,7 @@ def do_matiere_create(context, args, REQUEST): sco_news.add( context, REQUEST, - typ=NEWS_FORM, + typ=sco_news.NEWS_FORM, object=ue["formation_id"], text="Modification de la formation %(acronyme)s" % F, ) @@ -90,6 +91,8 @@ def do_matiere_create(context, args, REQUEST): def matiere_create(context, ue_id=None, REQUEST=None): """Creation d'une matiere""" + from app.scodoc import sco_edit_ue + UE = sco_edit_ue.do_ue_list(context, args={"ue_id": ue_id})[0] H = [ html_sco_header.sco_header( @@ -151,11 +154,16 @@ associé. def do_matiere_delete(context, oid, REQUEST): "delete matiere and attached modules" + from app.scodoc import sco_formations + from app.scodoc import sco_edit_ue + from app.scodoc import sco_edit_module + from app.scodoc import sco_news + cnx = ndb.GetDBConnexion() # check mat = do_matiere_list(context, {"matiere_id": oid})[0] ue = sco_edit_ue.do_ue_list(context, {"ue_id": mat["ue_id"]})[0] - locked = sco_edit_matiere.matiere_is_locked(context, mat["matiere_id"]) + locked = matiere_is_locked(context, mat["matiere_id"]) if locked: log("do_matiere_delete: mat=%s" % mat) log("do_matiere_delete: ue=%s" % ue) @@ -175,7 +183,7 @@ def do_matiere_delete(context, oid, REQUEST): sco_news.add( context, REQUEST, - typ=NEWS_FORM, + typ=sco_news.NEWS_FORM, object=ue["formation_id"], text="Modification de la formation %(acronyme)s" % F, ) @@ -183,6 +191,8 @@ def do_matiere_delete(context, oid, REQUEST): def matiere_delete(context, matiere_id=None, REQUEST=None): """Delete an UE""" + from app.scodoc import sco_edit_ue + M = do_matiere_list(context, args={"matiere_id": matiere_id})[0] UE = sco_edit_ue.do_ue_list(context, args={"ue_id": M["ue_id"]})[0] H = [ @@ -212,6 +222,9 @@ def matiere_delete(context, matiere_id=None, REQUEST=None): def matiere_edit(context, matiere_id=None, REQUEST=None): """Edit matiere""" + from app.scodoc import sco_formations + from app.scodoc import sco_edit_ue + F = do_matiere_list(context, args={"matiere_id": matiere_id}) if not F: raise ScoValueError("Matière inexistante !") diff --git a/app/scodoc/sco_edit_module.py b/app/scodoc/sco_edit_module.py index b3f74afaa..e4cc23ae3 100644 --- a/app/scodoc/sco_edit_module.py +++ b/app/scodoc/sco_edit_module.py @@ -25,19 +25,22 @@ # ############################################################################## -"""Ajout/Modification/Supression modules +"""Ajout/Modification/Suppression modules (portage from DTML) """ -import notesdb as ndb -import sco_utils as scu -from notes_log import log -import sco_codes_parcours -from TrivialFormulator import TrivialFormulator, TF -import sco_formsemestre -import sco_edit_ue -import sco_tag_module -from sco_permissions import ScoChangeFormation -from sco_exceptions import ScoValueError +import app.scodoc.notesdb as ndb +import app.scodoc.sco_utils as scu +from app.scodoc.notes_log import log +from app.scodoc.TrivialFormulator import TrivialFormulator +from app.scodoc.sco_permissions import Permission +from app.scodoc.sco_exceptions import ScoValueError, ScoLockedFormError, ScoGenError +from app.scodoc import html_sco_header +from app.scodoc import sco_codes_parcours +from app.scodoc import sco_core +from app.scodoc import sco_edit_matiere +from app.scodoc import sco_formsemestre +from app.scodoc import sco_moduleimpl +from app.scodoc import sco_news _MODULE_HELP = """Les modules sont décrits dans le programme pédagogique. Un module est pour ce @@ -98,6 +101,8 @@ def do_module_list(context, *args, **kw): def do_module_create(context, args, REQUEST): "create a module" # create + from app.scodoc import sco_formations + cnx = ndb.GetDBConnexion() r = _moduleEditor.create(cnx, args) @@ -108,7 +113,7 @@ def do_module_create(context, args, REQUEST): sco_news.add( context, REQUEST, - typ=NEWS_FORM, + typ=sco_news.NEWS_FORM, object=args["formation_id"], text="Modification de la formation %(acronyme)s" % F, ) @@ -117,6 +122,9 @@ def do_module_create(context, args, REQUEST): def module_create(context, matiere_id=None, REQUEST=None): """Creation d'un module""" + from app.scodoc import sco_formations + from app.scodoc import sco_edit_ue + if not matiere_id: raise ScoValueError("invalid matiere !") M = sco_edit_matiere.do_matiere_list(context, args={"matiere_id": matiere_id})[0] @@ -241,8 +249,10 @@ def module_create(context, matiere_id=None, REQUEST=None): def do_module_delete(context, oid, REQUEST): "delete module" + from app.scodoc import sco_formations + mod = do_module_list(context, {"module_id": oid})[0] - if sco_edit_module.module_is_locked(context, mod["module_id"]): + if module_is_locked(context, mod["module_id"]): raise ScoLockedFormError() # S'il y a des moduleimpls, on ne peut pas detruire le module ! @@ -268,7 +278,7 @@ def do_module_delete(context, oid, REQUEST): sco_news.add( context, REQUEST, - typ=NEWS_FORM, + typ=sco_news.NEWS_FORM, object=mod["formation_id"], text="Modification de la formation %(acronyme)s" % F, ) @@ -341,6 +351,9 @@ def check_module_code_unicity(code, field, formation_id, context, module_id=None def module_edit(context, module_id=None, REQUEST=None): """Edit a module""" + from app.scodoc import sco_formations + from app.scodoc import sco_tag_module + if not module_id: raise ScoValueError("invalid module !") Mod = do_module_list(context, args={"module_id": module_id}) @@ -532,6 +545,8 @@ def module_list(context, formation_id, REQUEST=None): """Liste des modules de la formation (XXX inutile ou a revoir) """ + from app.scodoc import sco_formations + if not formation_id: raise ScoValueError("invalid formation !") F = sco_formations.formation_list(context, args={"formation_id": formation_id})[0] @@ -581,6 +596,8 @@ def module_count_moduleimpls(context, module_id): def formation_add_malus_modules(context, formation_id, titre=None, REQUEST=None): """Création d'un module de "malus" dans chaque UE d'une formation""" + from app.scodoc import sco_edit_ue + ue_list = sco_edit_ue.do_ue_list(context, args={"formation_id": formation_id}) for ue in ue_list: @@ -601,6 +618,8 @@ def formation_add_malus_modules(context, formation_id, titre=None, REQUEST=None) def ue_add_malus_module(context, ue_id, titre=None, code=None, REQUEST=None): """Add a malus module in this ue""" + from app.scodoc import sco_edit_ue + ue = sco_edit_ue.do_ue_list(context, args={"ue_id": ue_id})[0] if titre is None: diff --git a/app/scodoc/sco_edit_ue.py b/app/scodoc/sco_edit_ue.py index 5317759fa..74a1fcd1b 100644 --- a/app/scodoc/sco_edit_ue.py +++ b/app/scodoc/sco_edit_ue.py @@ -28,18 +28,27 @@ """Ajout/Modification/Suppression UE """ -import notesdb as ndb -import sco_utils as scu -from notes_log import log -from TrivialFormulator import TrivialFormulator, TF -from gen_tables import GenTable -import sco_groups -import sco_formsemestre -import sco_formsemestre_validation -import sco_codes_parcours -import sco_tag_module -from sco_permissions import ScoChangeFormation, ScoEditFormationTags, ScoImplement -from sco_exceptions import ScoValueError, ScoLockedFormError +import app.scodoc.notesdb as ndb +import app.scodoc.sco_utils as scu +from app.scodoc.notes_log import log +from app.scodoc.TrivialFormulator import TrivialFormulator, TF +from app.scodoc.gen_tables import GenTable +from app.scodoc.sco_permissions import Permission +from app.scodoc.sco_exceptions import ScoValueError, ScoLockedFormError + +from app.scodoc import html_sco_header +from app.scodoc import sco_codes_parcours +from app.scodoc import sco_core +from app.scodoc import sco_edit_matiere +from app.scodoc import sco_edit_module +from app.scodoc import sco_formsemestre +from app.scodoc import sco_groups +from app.scodoc import sco_moduleimpl +from app.scodoc import sco_news +from app.scodoc import sco_permissions +from app.scodoc import sco_preferences +from app.scodoc import sco_tag_module +from app.scodoc import sco_etud _ueEditor = ndb.EditableTable( "notes_ue", @@ -75,6 +84,8 @@ def do_ue_list(context, *args, **kw): def do_ue_create(context, args, REQUEST): "create an ue" + from app.scodoc import sco_formations + cnx = ndb.GetDBConnexion() # check duplicates ues = do_ue_list( @@ -92,7 +103,7 @@ def do_ue_create(context, args, REQUEST): sco_news.add( context, REQUEST, - typ=NEWS_FORM, + typ=sco_news.NEWS_FORM, object=args["formation_id"], text="Modification de la formation %(acronyme)s" % F, ) @@ -100,7 +111,10 @@ def do_ue_create(context, args, REQUEST): def do_ue_delete(context, ue_id, delete_validations=False, REQUEST=None, force=False): - "delete UE and attached matieres (but not modules (it should ?))" + "delete UE and attached matieres (but not modules)" + from app.scodoc import sco_formations + from app.scodoc import sco_parcours_dut + cnx = ndb.GetDBConnexion() log("do_ue_delete: ue_id=%s, delete_validations=%s" % (ue_id, delete_validations)) # check @@ -108,7 +122,7 @@ def do_ue_delete(context, ue_id, delete_validations=False, REQUEST=None, force=F if not ue: raise ScoValueError("UE inexistante !") ue = ue[0] - if sco_edit_ue.ue_is_locked(context, ue["ue_id"]): + if ue_is_locked(context, ue["ue_id"]): raise ScoLockedFormError() # Il y a-t-il des etudiants ayant validé cette UE ? # si oui, propose de supprimer les validations @@ -158,7 +172,7 @@ def do_ue_delete(context, ue_id, delete_validations=False, REQUEST=None, force=F sco_news.add( context, REQUEST, - typ=NEWS_FORM, + typ=sco_news.NEWS_FORM, object=ue["formation_id"], text="Modification de la formation %(acronyme)s" % F, ) @@ -178,6 +192,8 @@ def ue_create(context, formation_id=None, REQUEST=None): def ue_edit(context, ue_id=None, create=False, formation_id=None, REQUEST=None): """Modification ou creation d'une UE""" + from app.scodoc import sco_formations + create = int(create) if not create: U = do_ue_list(context, args={"ue_id": ue_id}) @@ -419,6 +435,9 @@ def ue_list(context, formation_id=None, msg="", REQUEST=None): """Liste des matières et modules d'une formation, avec liens pour editer (si non verrouillée). """ + from app.scodoc import sco_formations + from app.scodoc import sco_formsemestre_validation + authuser = REQUEST.AUTHENTICATED_USER F = sco_formations.formation_list(context, args={"formation_id": formation_id}) @@ -816,6 +835,8 @@ def ue_sharing_code(context, ue_code=None, ue_id=None, hide_ue_id=None): """HTML list of UE sharing this code Either ue_code or ue_id may be specified. """ + from app.scodoc import sco_formations + if ue_id: ue = do_ue_list(context, args={"ue_id": ue_id})[0] if not ue_code: @@ -946,6 +967,8 @@ def ue_is_locked(context, ue_id): # ---- Table recap formation def formation_table_recap(context, formation_id, format="html", REQUEST=None): """Table recapitulant formation.""" + from app.scodoc import sco_formations + F = sco_formations.formation_list(context, args={"formation_id": formation_id}) if not F: raise ScoValueError("invalid formation_id") diff --git a/app/scodoc/sco_edt_cal.py b/app/scodoc/sco_edt_cal.py index 17cd44873..5902652ec 100644 --- a/app/scodoc/sco_edt_cal.py +++ b/app/scodoc/sco_edt_cal.py @@ -38,11 +38,13 @@ import traceback import icalendar import pprint -import sco_utils as scu -from notes_log import log -import sco_formsemestre -import sco_groups -import sco_groups_view +import app.scodoc.sco_utils as scu +from app.scodoc.notes_log import log +from app.scodoc import html_sco_header +from app.scodoc import sco_formsemestre +from app.scodoc import sco_groups +from app.scodoc import sco_groups_view +from app.scodoc import sco_preferences def formsemestre_get_ics_url(context, sem): @@ -52,7 +54,9 @@ def formsemestre_get_ics_url(context, sem): Par exemple: https://example.fr/agenda/{sem[etapes][0]} """ - ics_url_tmpl = sco_preferences.get_preference(context, "edt_sem_ics_url", sem["formsemestre_id"]) + ics_url_tmpl = sco_preferences.get_preference( + context, "edt_sem_ics_url", sem["formsemestre_id"] + ) if not ics_url_tmpl: return None try: @@ -163,7 +167,8 @@ def experimental_calendar(context, group_id=None, formsemestre_id=None, REQUEST= """experimental page""" return "\n".join( [ - html_sco_header.sco_header(context, + html_sco_header.sco_header( + context, REQUEST, javascripts=[ "libjs/purl.js", diff --git a/app/scodoc/sco_entreprises.py b/app/scodoc/sco_entreprises.py index c5f5fdd9f..eae5b31d5 100644 --- a/app/scodoc/sco_entreprises.py +++ b/app/scodoc/sco_entreprises.py @@ -30,8 +30,8 @@ # codes anciens déplacés de ZEntreprise import datetime -import sco_utils as scu -import notesdb as ndb +import app.scodoc.sco_utils as scu +import app.scodoc.notesdb as ndb from notesdb import ScoDocCursor, EditableTable, DateISOtoDMY, DateDMYtoISO diff --git a/app/scodoc/sco_etape_apogee.py b/app/scodoc/sco_etape_apogee.py index 04b2aa891..a18ba57e5 100644 --- a/app/scodoc/sco_etape_apogee.py +++ b/app/scodoc/sco_etape_apogee.py @@ -77,15 +77,10 @@ import re -import sco_utils as scu -from notes_log import log -import sco_formsemestre -import notes_table -import sco_groups -import sco_groups_view -import sco_archives -import sco_apogee_csv -from sco_exceptions import ScoValueError +import app.scodoc.sco_utils as scu +from app.scodoc import sco_archives +from app.scodoc import sco_apogee_csv +from app.scodoc.sco_exceptions import ScoValueError class ApoCSVArchiver(sco_archives.BaseArchiver): @@ -365,12 +360,12 @@ def apo_csv_retreive_etuds_by_nip(context, semset, nips): Tests: from debug import * -import sco_groups -import sco_groups_view -import sco_formsemestre -from sco_etape_apogee import * -from sco_apogee_csv import * -from sco_semset import * +from app.scodoc import sco_groups +from app.scodoc import sco_groups_view +from app.scodoc import sco_formsemestre +from app.scodoc.sco_etape_apogee import * +from app.scodoc.sco_apogee_csv import * +from app.scodoc.sco_semset import * context = go_dept(app, 'RT').Notes csv_data = open('/opt/misc/VDTRT_V1RT.TXT').read() @@ -413,7 +408,7 @@ self=e col_id='apoL_c0129' # -- -import sco_portal_apogee +from app.scodoc import sco_portal_apogee context = go_dept(app, 'GEA').Notes #csv_data = sco_portal_apogee.get_maquette_apogee(context, etape='V1GE', annee_scolaire=2015) csv_data = open('/tmp/V1GE.txt').read() @@ -424,12 +419,12 @@ apo_data = sco_apogee_csv.ApoData(csv_data, periode=1) # les elements inconnus: from debug import * -import sco_groups -import sco_groups_view -import sco_formsemestre -from sco_etape_apogee import * -from sco_apogee_csv import * -from sco_semset import * +from app.scodoc import sco_groups +from app.scodoc import sco_groups_view +from app.scodoc import sco_formsemestre +from app.scodoc.sco_etape_apogee import * +from app.scodoc.sco_apogee_csv import * +from app.scodoc.sco_semset import * context = go_dept(app, 'RT').Notes csv_data = open('/opt/misc/V2RT.csv').read() @@ -447,12 +442,12 @@ for e in apo_data.etuds: # ------ # test export jury intermediaire from debug import * -import sco_groups -import sco_groups_view -import sco_formsemestre -from sco_etape_apogee import * -from sco_apogee_csv import * -from sco_semset import * +from app.scodoc import sco_groups +from app.scodoc import sco_groups_view +from app.scodoc import sco_formsemestre +from app.scodoc.sco_etape_apogee import * +from app.scodoc.sco_apogee_csv import * +from app.scodoc.sco_semset import * context = go_dept(app, 'CJ').Notes csv_data = open('/opt/scodoc/var/scodoc/archives/apo_csv/CJ/2016-1/2017-03-06-21-46-32/V1CJ.csv').read() diff --git a/app/scodoc/sco_etape_apogee_view.py b/app/scodoc/sco_etape_apogee_view.py index 25823ab90..2eeca7c20 100644 --- a/app/scodoc/sco_etape_apogee_view.py +++ b/app/scodoc/sco_etape_apogee_view.py @@ -31,19 +31,23 @@ from cStringIO import StringIO from zipfile import ZipFile -import sco_utils as scu -from notes_log import log -import sco_formsemestre -import sco_formsemestre_status -import notes_table -from gen_tables import GenTable -import sco_semset -import sco_etape_apogee -import sco_apogee_csv -import sco_portal_apogee -from sco_apogee_csv import APO_PORTAL_ENCODING, APO_INPUT_ENCODING -import sco_archives -from sco_exceptions import ScoValueError +import app.scodoc.sco_utils as scu +from app.scodoc.notes_log import log +from app.scodoc import html_sco_header +from app.scodoc import notes_table +from app.scodoc import sco_apogee_csv +from app.scodoc import sco_archives +from app.scodoc import sco_etape_apogee +from app.scodoc import sco_formations +from app.scodoc import sco_formsemestre +from app.scodoc import sco_formsemestre_status +from app.scodoc import sco_portal_apogee +from app.scodoc import sco_preferences +from app.scodoc import sco_semset +from app.scodoc import sco_etud +from app.scodoc.gen_tables import GenTable +from app.scodoc.sco_apogee_csv import APO_PORTAL_ENCODING, APO_INPUT_ENCODING +from app.scodoc.sco_exceptions import ScoValueError def apo_semset_maq_status( @@ -342,7 +346,10 @@ def apo_semset_maq_status( if missing: formation_ids = {sem["formation_id"] for sem in semset.sems} - formations = [sco_formations.formation_list(context, formation_id=i)[0] for i in formation_ids] + formations = [ + sco_formations.formation_list(context, formation_id=i)[0] + for i in formation_ids + ] # log('formations=%s' % formations) H.append( '
%(nomprenom)s est inscrit%(ne)s à ce semestre extérieur.
Voici les UE entregistrées avec leur notes et coefficients.
diff --git a/app/scodoc/sco_formsemestre_inscriptions.py b/app/scodoc/sco_formsemestre_inscriptions.py index 02acb2c5c..3a45091c2 100644 --- a/app/scodoc/sco_formsemestre_inscriptions.py +++ b/app/scodoc/sco_formsemestre_inscriptions.py @@ -27,22 +27,25 @@ """Opérations d'inscriptions aux semestres et modules """ +import time -import sco_utils as scu -from notes_log import log -from sco_exceptions import ScoValueError -from sco_permissions import ScoEtudInscrit -from sco_codes_parcours import UE_STANDARD, UE_SPORT, UE_TYPE_NAME -import notesdb as ndb -from notesdb import ScoDocCursor, DateISOtoDMY, DateDMYtoISO +import app.scodoc.sco_utils as scu +from app.scodoc.notes_log import log +from app.scodoc.scolog import logdb +from app.scodoc.sco_exceptions import ScoValueError +from app.scodoc.sco_permissions import Permission +from app.scodoc.sco_codes_parcours import UE_STANDARD, UE_SPORT, UE_TYPE_NAME +import app.scodoc.notesdb as ndb +from app.scodoc.TrivialFormulator import TrivialFormulator, TF +from app.scodoc import sco_find_etud +from app.scodoc import sco_formsemestre +from app.scodoc import sco_moduleimpl +from app.scodoc import sco_groups +from app.scodoc import sco_etud +from app.scodoc import sco_core +from app.scodoc import sco_formsemestre_edit +from app.scodoc import html_sco_header -from TrivialFormulator import TrivialFormulator, TF - -# from notes_table import * -import sco_find_etud -import sco_formsemestre -import sco_moduleimpl -import sco_groups # --- Gestion des inscriptions aux semestres _formsemestre_inscriptionEditor = ndb.EditableTable( @@ -75,7 +78,7 @@ def do_formsemestre_inscription_create(context, args, REQUEST, method=None): # r = _formsemestre_inscriptionEditor.create(cnx, args) # Evenement - scolars.scolar_events_create( + sco_etud.scolar_events_create( cnx, args={ "etudid": args["etudid"], @@ -135,8 +138,8 @@ def do_formsemestre_desinscription(context, etudid, formsemestre_id, REQUEST=Non "desinscription impossible: l'étudiant a une décision de jury (la supprimer avant si nécessaire)" ) - insem = do_formsemestre_inscription_list(context, - args={"formsemestre_id": formsemestre_id, "etudid": etudid} + insem = do_formsemestre_inscription_list( + context, args={"formsemestre_id": formsemestre_id, "etudid": etudid} ) if not insem: raise ScoValueError("%s n'est pas inscrit au semestre !" % etudid) @@ -160,8 +163,8 @@ def do_formsemestre_desinscription(context, etudid, formsemestre_id, REQUEST=Non ) # --- Semestre extérieur if sem["modalite"] == "EXT": - inscrits = do_formsemestre_inscription_list(context, - args={"formsemestre_id": formsemestre_id} + inscrits = do_formsemestre_inscription_list( + context, args={"formsemestre_id": formsemestre_id} ) nbinscrits = len(inscrits) if nbinscrits == 0: @@ -259,7 +262,7 @@ def formsemestre_inscription_with_modules_form( """Formulaire inscription de l'etud dans l'un des semestres existants. Si only_ext, ne montre que les semestre extérieurs. """ - etud = scolars.get_etud_info(etudid=etudid, filled=1)[0] + etud = sco_etud.get_etud_info(etudid=etudid, filled=1)[0] H = [ html_sco_header.sco_header(context, REQUEST), ""] # Navigation suivant/precedent if etud_index_prev != None: - etud_p = scolars.get_etud_info(etudid=T[etud_index_prev][-1], filled=True)[0] + etud_p = sco_etud.get_etud_info(etudid=T[etud_index_prev][-1], filled=True)[0] Footer.append( 'Etud. précédent (%s)' % (formsemestre_id, etud_index_prev, etud_p["nomprenom"]) ) if etud_index_next != None: - etud_n = scolars.get_etud_info(etudid=T[etud_index_next][-1], filled=True)[0] + etud_n = sco_etud.get_etud_info(etudid=T[etud_index_next][-1], filled=True)[0] Footer.append( 'Etud. suivant (%s)' % (formsemestre_id, etud_index_next, etud_n["nomprenom"]) @@ -333,22 +339,22 @@ def formsemestre_validation_etud( REQUEST=None, ): """Enregistre validation""" - etud = scolars.get_etud_info(etudid=etudid, filled=True)[0] + etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0] Se = sco_parcours_dut.SituationEtudParcours(context, etud, formsemestre_id) # retrouve la decision correspondant au code: choices = Se.get_possible_choices(assiduite=True) choices += Se.get_possible_choices(assiduite=False) - found = False + selected_choice = None for choice in choices: if choice.codechoice == codechoice: - found = True + selected_choice = choice break - if not found: + if not selected_choice: raise ValueError("code choix invalide ! (%s)" % codechoice) # - Se.valide_decision(choice, REQUEST) # enregistre + Se.valide_decision(selected_choice, REQUEST) # enregistre return _redirect_valid_choice( - formsemestre_id, etudid, Se, choice, desturl, sortcol, REQUEST + formsemestre_id, etudid, Se, selected_choice, desturl, sortcol, REQUEST ) @@ -368,7 +374,7 @@ def formsemestre_validation_etud_manu( """Enregistre validation""" if assidu: assidu = 1 - etud = scolars.get_etud_info(etudid=etudid, filled=True)[0] + etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0] Se = sco_parcours_dut.SituationEtudParcours(context, etud, formsemestre_id) if code_etat in Se.parcours.UNUSED_CODES: raise ScoValueError("code decision invalide dans ce parcours") @@ -862,10 +868,10 @@ def do_formsemestre_validation_auto(context, formsemestre_id, REQUEST): nb_valid = 0 conflicts = [] # liste des etudiants avec decision differente déjà saisie for etudid in etudids: - etud = scolars.get_etud_info(etudid=etudid, filled=True)[0] + etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0] Se = sco_parcours_dut.SituationEtudParcours(context, etud, formsemestre_id) - ins = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(context, - {"etudid": etudid, "formsemestre_id": formsemestre_id} + ins = sco_formsemestre_inscriptions.do_formsemestre_inscription_list( + context, {"etudid": etudid, "formsemestre_id": formsemestre_id} )[0] # Conditions pour validation automatique: @@ -964,10 +970,10 @@ def formsemestre_fix_validation_ues(context, formsemestre_id, REQUEST=None): modifs = [] # liste d'étudiants modifiés cnx = context.GetDBConnexion(autocommit=False) for etudid in etudids: - etud = scolars.get_etud_info(etudid=etudid, filled=True)[0] + etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0] Se = sco_parcours_dut.SituationEtudParcours(context, etud, formsemestre_id) - ins = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(context, - {"etudid": etudid, "formsemestre_id": formsemestre_id} + ins = sco_formsemestre_inscriptions.do_formsemestre_inscription_list( + context, {"etudid": etudid, "formsemestre_id": formsemestre_id} )[0] decision_sem = nt.get_etud_decision_sem(etudid) if not decision_sem: @@ -1071,9 +1077,13 @@ def formsemestre_validate_previous_ue(context, formsemestre_id, etudid, REQUEST= """Form. saisie UE validée hors ScoDoc (pour étudiants arrivant avec un UE antérieurement validée). """ - etud = scolars.get_etud_info(etudid=etudid, filled=True)[0] + from app.scodoc import sco_formations + + etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0] sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) - Fo = sco_formations.formation_list(context, args={"formation_id": sem["formation_id"]})[0] + Fo = sco_formations.formation_list( + context, args={"formation_id": sem["formation_id"]} + )[0] H = [ html_sco_header.sco_header( diff --git a/app/scodoc/sco_formulas.py b/app/scodoc/sco_formulas.py index ccac9df84..9bf0683ed 100644 --- a/app/scodoc/sco_formulas.py +++ b/app/scodoc/sco_formulas.py @@ -29,14 +29,10 @@ """ import operator -import traceback from types import FloatType, IntType, LongType, StringType -import sco_utils as scu -from notes_log import log - -class NoteVector: +class NoteVector(object): """Vecteur de notes (ou coefficients) utilisé pour les formules définies par l'utilisateur. Les éléments sont accessibles soit par index v[i], soit par leur nom v['nom'] s'il en ont un. Les éléments sont toujours numériques (float). Les valeurs non numériques ('NI', ...) sont diff --git a/app/scodoc/sco_groups.py b/app/scodoc/sco_groups.py index 00a983066..657994b04 100644 --- a/app/scodoc/sco_groups.py +++ b/app/scodoc/sco_groups.py @@ -43,17 +43,18 @@ import operator import jaxml import xml.dom.minidom -import sco_utils as scu -import notesdb as ndb -from notes_log import log -from scolog import logdb -from TrivialFormulator import TrivialFormulator, TF -import sco_formsemestre -import scolars -import sco_parcours_dut -import sco_codes_parcours -from sco_permissions import ScoEtudChangeGroups -from sco_exceptions import ScoException, AccessDenied, ScoValueError +import app.scodoc.sco_utils as scu +import app.scodoc.notesdb as ndb +from app.scodoc.notes_log import log +from app.scodoc.scolog import logdb +from app.scodoc import html_sco_header +from app.scodoc import sco_codes_parcours +from app.scodoc import sco_core +from app.scodoc import sco_etud +from app.scodoc import sco_formsemestre +from app.scodoc.sco_exceptions import ScoException, AccessDenied, ScoValueError +from app.scodoc.sco_permissions import Permission +from app.scodoc.TrivialFormulator import TrivialFormulator def can_change_groups(context, REQUEST, formsemestre_id): @@ -244,7 +245,7 @@ def get_group_members(context, group_id, etat=None): r = ndb.SimpleDictFetch(context, req, {"group_id": group_id, "etat": etat}) for etud in r: - scolars.format_etud_ident(etud) + sco_etud.format_etud_ident(etud) r.sort(key=operator.itemgetter("nom_disp", "prenom")) # tri selon nom_usuel ou nom @@ -285,7 +286,7 @@ def get_group_infos(context, group_id, etat=None): # was _getlisteetud if t["etat"] == "I": t["etath"] = "" # etudiant inscrit, ne l'indique pas dans la liste HTML elif t["etat"] == "D": - events = scolars.scolar_events_list( + events = sco_etud.scolar_events_list( cnx, args={ "etudid": t["etudid"], @@ -469,14 +470,14 @@ def XMLgetGroupsInPartition(context, partition_id, REQUEST=None): # was XMLgetG group_name=group["group_name"], ) for e in get_group_members(context, group["group_id"]): - etud = scolars.get_etud_info(etudid=e["etudid"], filled=1)[0] + etud = sco_etud.get_etud_info(etudid=e["etudid"], filled=1)[0] doc._push() doc.etud( etudid=e["etudid"], civilite=etud["civilite_str"], sexe=etud["civilite_str"], # compat - nom=scolars.format_nom(etud["nom"]), - prenom=scolars.format_prenom(etud["prenom"]), + nom=sco_etud.format_nom(etud["nom"]), + prenom=sco_etud.format_prenom(etud["prenom"]), origin=comp_origin(etud, sem), ) if e["etudid"] in etuds_set: @@ -494,13 +495,13 @@ def XMLgetGroupsInPartition(context, partition_id, REQUEST=None): # was XMLgetG group_name="", ) for etudid in etuds_set: - etud = scolars.get_etud_info(etudid=etudid, filled=1)[0] + etud = sco_etud.get_etud_info(etudid=etudid, filled=1)[0] doc._push() doc.etud( etudid=etud["etudid"], sexe=etud["civilite_str"], - nom=scolars.format_nom(etud["nom"]), - prenom=scolars.format_prenom(etud["prenom"]), + nom=sco_etud.format_nom(etud["nom"]), + prenom=sco_etud.format_prenom(etud["prenom"]), origin=comp_origin(etud, sem), ) doc._pop() @@ -1297,9 +1298,9 @@ def get_prev_moy(context, etudid, formsemestre_id): """Donne la derniere moyenne generale calculee pour cette étudiant, ou 0 si on n'en trouve pas (nouvel inscrit,...). """ - import sco_parcours_dut + from app.scodoc import sco_parcours_dut - info = scolars.get_etud_info(etudid=etudid, filled=True) + info = sco_etud.get_etud_info(etudid=etudid, filled=True) if not info: raise ScoValueError("etudiant invalide: etudid=%s" % etudid) etud = info[0] @@ -1320,9 +1321,11 @@ def create_etapes_partition(context, formsemestre_id, partition_name="apo_etapes Si la partition existe déjà, ses groupes sont mis à jour (les groupes devenant vides ne sont pas supprimés). """ + from app.scodoc import sco_formsemestre_inscriptions + log("create_etapes_partition(%s)" % formsemestre_id) - ins = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(context, - args={"formsemestre_id": formsemestre_id} + ins = sco_formsemestre_inscriptions.do_formsemestre_inscription_list( + context, args={"formsemestre_id": formsemestre_id} ) etapes = {i["etape"] for i in ins if i["etape"]} partitions = get_partitions_list(context, formsemestre_id, with_default=False) diff --git a/app/scodoc/sco_groups_edit.py b/app/scodoc/sco_groups_edit.py index 4c727cc53..4fd0f7b9a 100644 --- a/app/scodoc/sco_groups_edit.py +++ b/app/scodoc/sco_groups_edit.py @@ -28,14 +28,9 @@ """Formulaires gestion des groupes """ -import re - -import sco_utils as scu -import notesdb as ndb -from notes_log import log -import sco_formsemestre -import sco_groups -from sco_exceptions import AccessDenied +from app.scodoc import html_sco_header +from app.scodoc import sco_groups +from app.scodoc.sco_exceptions import AccessDenied def affectGroups(context, partition_id, REQUEST=None): @@ -49,7 +44,8 @@ def affectGroups(context, partition_id, REQUEST=None): raise AccessDenied("vous n'avez pas la permission d'effectuer cette opération") H = [ - html_sco_header.sco_header(context, + html_sco_header.sco_header( + context, REQUEST, page_title="Affectation aux groupes", javascripts=["js/groupmgr.js"], diff --git a/app/scodoc/sco_groups_view.py b/app/scodoc/sco_groups_view.py index 9af18a487..b0c26bf3f 100644 --- a/app/scodoc/sco_groups_view.py +++ b/app/scodoc/sco_groups_view.py @@ -37,21 +37,20 @@ import time import collections import operator -import sco_utils as scu -from sco_permissions import ScoEtudInscrit, ScoEtudAddAnnotations, ScoAbsChange -from sco_exceptions import ScoValueError -import html_sco_header -from gen_tables import GenTable -import scolars -import sco_abs -import sco_excel -import sco_formsemestre -import sco_moduleimpl -import sco_groups -import sco_trombino -import sco_portal_apogee -import sco_parcours_dut -import sco_report +import app.scodoc.sco_utils as scu +from app.scodoc import html_sco_header +from app.scodoc import sco_abs +from app.scodoc import sco_excel +from app.scodoc import sco_formsemestre +from app.scodoc import sco_groups +from app.scodoc import sco_moduleimpl +from app.scodoc import sco_parcours_dut +from app.scodoc import sco_portal_apogee +from app.scodoc import sco_preferences +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 JAVASCRIPTS = html_sco_header.BOOTSTRAP_MULTISELECT_JS + [ "js/etud_info.js", @@ -452,6 +451,8 @@ def groups_table( format: csv, json, xml, xls, allxls, xlsappel, moodlecsv, pdf Si with_codes, ajoute 4 colonnes avec les codes etudid, NIP, INE et etape """ + from app.scodoc import sco_report + # log( # "enter groups_table %s: %s" # % (groups_infos.members[0]["nom"], groups_infos.members[0].get("etape", "-")) @@ -515,7 +516,7 @@ def groups_table( sco_archives_etud.add_archives_info_to_etud_list(context, groups_infos.members) columns_ids += ["etudarchive"] if with_annotations: - scolars.add_annotations_to_etud_list(context, groups_infos.members) + sco_etud.add_annotations_to_etud_list(context, groups_infos.members) columns_ids += ["annotations_str"] if groups_infos.formsemestre["semestre_id"] >= 0: @@ -785,9 +786,9 @@ def groups_table( # remplis infos lycee si on a que le code lycée # et ajoute infos inscription for m in groups_infos.members: - etud = scolars.get_etud_info(m["etudid"], filled=True)[0] + etud = sco_etud.get_etud_info(m["etudid"], filled=True)[0] m.update(etud) - scolars.etud_add_lycee_infos(etud) + sco_etud.etud_add_lycee_infos(etud) # et ajoute le parcours Se = sco_parcours_dut.SituationEtudParcours( context.Notes, etud, groups_infos.formsemestre_id @@ -873,6 +874,8 @@ def tab_absences_html(context, groups_infos, etat=None, REQUEST=None): def tab_photos_html(context, groups_infos, etat=None, REQUEST=None): """contenu du tab "photos" """ + from app.scodoc import sco_trombino + if not groups_infos.members: return '
Responsable de ce semestre : %s
" + % ", ".join(sem["responsables"]), + footer, + ] + ), + ) + else: + return True, "" diff --git a/app/scodoc/sco_photos.py b/app/scodoc/sco_photos.py index 549ba48e0..480f2f708 100644 --- a/app/scodoc/sco_photos.py +++ b/app/scodoc/sco_photos.py @@ -54,17 +54,18 @@ from cStringIO import StringIO import glob from config import Config -from sco_utils import CONFIG, SCO_SRC_DIR -import notesdb as ndb -from notes_log import log -import scolars -import sco_portal_apogee -from scolog import logdb +import app.scodoc.sco_utils as scu +import app.scodoc.notesdb as ndb +from app.scodoc.notes_log import log +from app.scodoc.scolog import logdb +from app.scodoc import sco_portal_apogee +from app.scodoc import sco_preferences +from app.scodoc import sco_etud # Full paths on server's filesystem. Something like "/opt/scodoc/var/scodoc/photos" PHOTO_DIR = os.path.join(Config.INSTANCE_HOME, "var", "scodoc", "photos") -ICONS_DIR = os.path.join(SCO_SRC_DIR, "app", "static", "icons") +ICONS_DIR = os.path.join(scu.SCO_SRC_DIR, "app", "static", "icons") UNKNOWN_IMAGE_PATH = os.path.join(ICONS_DIR, "unknown.jpg") UNKNOWN_IMAGE_URL = "get_photo_image?etudid=" # with empty etudid => unknown face image IMAGE_EXT = ".jpg" @@ -104,7 +105,7 @@ def etud_photo_url(context, etud, size="small", fast=False, REQUEST=None): if not new_path: # copy failed, can we use external url ? # nb: rarement utile, car le portail est rarement accessible sans authentification - if CONFIG.PUBLISH_PORTAL_PHOTO_URL: + if scu.CONFIG.PUBLISH_PORTAL_PHOTO_URL: photo_url = ext_url else: photo_url = UNKNOWN_IMAGE_URL @@ -118,7 +119,7 @@ def get_photo_image(context, etudid=None, size="small", REQUEST=None): if not etudid: filename = UNKNOWN_IMAGE_PATH else: - etud = scolars.get_etud_info(etudid=etudid, filled=1, REQUEST=REQUEST)[0] + etud = sco_etud.get_etud_info(etudid=etudid, filled=1, REQUEST=REQUEST)[0] filename = photo_pathname(context, etud, size=size) if not filename: filename = UNKNOWN_IMAGE_PATH @@ -173,7 +174,7 @@ def etud_photo_html( """ if not etud: if etudid: - etud = scolars.get_etud_info(etudid=etudid, filled=1, REQUEST=REQUEST)[0] + etud = sco_etud.get_etud_info(etudid=etudid, filled=1, REQUEST=REQUEST)[0] else: raise ValueError("etud_photo_html: either etud or etudid must be specified") photo_url = etud_photo_url(context, etud, size=size, REQUEST=REQUEST) @@ -247,7 +248,7 @@ def store_photo(context, etud, data, REQUEST=None): etud["foto"] = None cnx = ndb.GetDBConnexion() - scolars.identite_edit_nocheck(cnx, etud) + sco_etud.identite_edit_nocheck(cnx, etud) cnx.commit() # if REQUEST: @@ -263,7 +264,7 @@ def suppress_photo(context, etud, REQUEST=None): # 1- remove ref. from database etud["photo_filename"] = None cnx = ndb.GetDBConnexion() - scolars.identite_edit_nocheck(cnx, etud) + sco_etud.identite_edit_nocheck(cnx, etud) cnx.commit() # 2- erase images files if rel_path: @@ -341,7 +342,7 @@ def copy_portal_photo_to_fs(context, etud, REQUEST=None): """Copy the photo from portal (distant website) to local fs. Returns rel. path or None if copy failed, with a diagnotic message """ - scolars.format_etud_ident(etud) + sco_etud.format_etud_ident(etud) url = photo_portal_url(context, etud) if not url: return None, "%(nomprenom)s: pas de code NIP" % etud diff --git a/app/scodoc/sco_placement.py b/app/scodoc/sco_placement.py index 321cf7ac2..344aed158 100644 --- a/app/scodoc/sco_placement.py +++ b/app/scodoc/sco_placement.py @@ -33,20 +33,25 @@ Contribution M. Salomon, UFC / IUT DE BELFORT-MONTBÉLIARD, 2016 import urllib import random -import sco_utils as scu -import notesdb as ndb -from notes_log import log -import scolars -import sco_formsemestre -import sco_moduleimpl -import sco_groups -import sco_evaluations -import sco_saisie_notes -import sco_excel -from sco_excel import * -from TrivialFormulator import TrivialFormulator -from gen_tables import GenTable -import VERSION +import app.scodoc.sco_utils as scu +import app.scodoc.notesdb as ndb +from app.scodoc.notes_log import log +from app.scodoc import html_sco_header +from app.scodoc import sco_edit_module +from app.scodoc import sco_evaluations +from app.scodoc import sco_excel +from app.scodoc import sco_formsemestre +from app.scodoc import sco_formsemestre_inscriptions +from app.scodoc import sco_groups +from app.scodoc import sco_moduleimpl +from app.scodoc import sco_permissions_check +from app.scodoc import sco_preferences +from app.scodoc import sco_saisie_notes +from app.scodoc import sco_etud +from app.scodoc import VERSION +from app.scodoc.gen_tables import GenTable +from app.scodoc.sco_excel import * +from app.scodoc.TrivialFormulator import TrivialFormulator def do_placement_selectetuds(context, REQUEST): @@ -240,7 +245,7 @@ def do_placement(context, REQUEST): # Check access # (admin, respformation, and responsable_id) - if not sco_saisie_notes.can_edit_notes(context, authuser, E["moduleimpl_id"]): + if not sco_permissions_check.can_edit_notes(context, authuser, E["moduleimpl_id"]): return ( "(vérifiez que le semestre n'est pas verrouillé et que vous
@@ -294,12 +299,12 @@ def do_placement(context, REQUEST):
listetud = [] # liste de couples (nom,prenom)
for etudid in etudids:
# infos identite etudiant (xxx sous-optimal: 1/select par etudiant)
- ident = scolars.etudident_list(cnx, {"etudid": etudid})[
+ ident = sco_etud.etudident_list(cnx, {"etudid": etudid})[
0
] # XXX utiliser ZScolar (parent)
# infos inscription
- inscr = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(context,
- {"etudid": etudid, "formsemestre_id": M["formsemestre_id"]}
+ inscr = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
+ context, {"etudid": etudid, "formsemestre_id": M["formsemestre_id"]}
)[0]
if inscr["etat"] != "D":
nom = scu.strupper(ident["nom"])
@@ -395,7 +400,9 @@ def do_placement(context, REQUEST):
def placement_eval_selectetuds(context, evaluation_id, REQUEST=None):
"""Dialogue placement etudiants: choix methode et localisation"""
- evals = sco_evaluations.do_evaluation_list(context, {"evaluation_id": evaluation_id})
+ evals = sco_evaluations.do_evaluation_list(
+ context, {"evaluation_id": evaluation_id}
+ )
if not evals:
raise ScoValueError("invalid evaluation_id")
theeval = evals[0]
diff --git a/app/scodoc/sco_portal_apogee.py b/app/scodoc/sco_portal_apogee.py
index 1b2f57c20..8b7afb370 100644
--- a/app/scodoc/sco_portal_apogee.py
+++ b/app/scodoc/sco_portal_apogee.py
@@ -35,11 +35,10 @@ import xml.sax.saxutils
import xml.dom.minidom
import datetime
-import sco_utils as scu
-from sco_utils import SCO_ENCODING
-from sco_permissions import ScoEtudInscrit
-from sco_exceptions import ScoValueError
-from notes_log import log
+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
SCO_CACHE_ETAPE_FILENAME = os.path.join(scu.SCO_TMP_DIR, "last_etapes.xml")
@@ -247,7 +246,9 @@ def xml_to_list_of_dicts(doc, req=None):
if e.nodeType == e.ELEMENT_NODE:
childs = e.childNodes
if len(childs):
- d[str(e.nodeName)] = childs[0].nodeValue.encode(SCO_ENCODING)
+ d[str(e.nodeName)] = childs[0].nodeValue.encode(
+ scu.SCO_ENCODING
+ )
infos.append(d)
except:
log("*** invalid XML response from Etudiant Web Service")
@@ -260,7 +261,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, SCO_ENCODING)
+ unom = unicode(nom, scu.SCO_ENCODING)
nom_noaccents = str(scu.suppression_diacritics(unom))
nom_utf8 = unom.encode("utf-8")
else:
@@ -268,7 +269,7 @@ def get_infos_apogee_allaccents(context, nom, prenom):
nom_utf8 = nom
if prenom:
- uprenom = unicode(prenom, SCO_ENCODING)
+ uprenom = unicode(prenom, scu.SCO_ENCODING)
prenom_noaccents = str(scu.suppression_diacritics(uprenom))
prenom_utf8 = uprenom.encode("utf-8")
else:
@@ -336,7 +337,7 @@ def get_etud_apogee(context, code_nip):
def get_default_etapes(context):
"""Liste par défaut, lue du fichier de config"""
- filename = SCO_TOOLS_DIR + "/default-etapes.txt"
+ filename = scu.SCO_TOOLS_DIR + "/default-etapes.txt"
log("get_default_etapes: reading %s" % filename)
f = open(filename)
etapes = {}
@@ -366,7 +367,7 @@ def _parse_etapes_from_xml(context, doc):
# Ancien format XML avec des sections par departement:
for d in dom.childNodes[0].childNodes:
if d.nodeType == d.ELEMENT_NODE:
- dept = d.nodeName.encode(SCO_ENCODING)
+ dept = d.nodeName.encode(scu.SCO_ENCODING)
_xml_list_codes(infos, dept, d.childNodes)
else:
# Toutes les étapes:
@@ -415,8 +416,8 @@ def get_etapes_apogee(context):
def _xml_list_codes(target_dict, dept, nodes):
for e in nodes:
if e.nodeType == e.ELEMENT_NODE:
- intitule = e.childNodes[0].nodeValue.encode(SCO_ENCODING)
- code = e.attributes["code"].value.encode(SCO_ENCODING)
+ intitule = e.childNodes[0].nodeValue.encode(scu.SCO_ENCODING)
+ code = e.attributes["code"].value.encode(scu.SCO_ENCODING)
if target_dict.has_key(dept):
target_dict[dept][code] = intitule
else:
diff --git a/app/scodoc/sco_poursuite_dut.py b/app/scodoc/sco_poursuite_dut.py
index 3fa466f6b..0a22ee8b2 100644
--- a/app/scodoc/sco_poursuite_dut.py
+++ b/app/scodoc/sco_poursuite_dut.py
@@ -31,14 +31,16 @@ Recapitule tous les semestres validés dans une feuille excel.
"""
import collections
-import sco_utils as scu
-from notes_log import log
-from gen_tables import GenTable
-import sco_formsemestre
-import sco_groups
-import sco_abs
-from sco_codes_parcours import code_semestre_validant, code_semestre_attente
-import VERSION
+import app.scodoc.sco_utils as scu
+from app.scodoc import sco_abs
+from app.scodoc import sco_core
+from app.scodoc import sco_formsemestre
+from app.scodoc import sco_groups
+from app.scodoc import sco_preferences
+from app.scodoc import sco_etud
+from app.scodoc import VERSION
+from app.scodoc.gen_tables import GenTable
+from app.scodoc.sco_codes_parcours import code_semestre_validant, code_semestre_attente
def etud_get_poursuite_info(context, sem, etud):
@@ -158,7 +160,7 @@ def _getEtudInfoGroupes(context, group_ids, etat=None):
for group_id in group_ids:
members = sco_groups.get_group_members(context, group_id, etat=etat)
for m in members:
- etud = scolars.get_etud_info(etudid=m["etudid"], filled=True)[0]
+ etud = sco_etud.get_etud_info(etudid=m["etudid"], filled=True)[0]
etuds.append(etud)
return etuds
diff --git a/app/scodoc/sco_preferences.py b/app/scodoc/sco_preferences.py
index 350484090..444ab600b 100644
--- a/app/scodoc/sco_preferences.py
+++ b/app/scodoc/sco_preferences.py
@@ -25,17 +25,6 @@
#
##############################################################################
-"""ScoDoc preferences (replaces old Zope properties)
-"""
-
-import sco_utils as scu
-import notesdb as ndb
-from notes_log import log
-from TrivialFormulator import TrivialFormulator, TF
-import sco_formsemestre
-import sco_bulletins_generator
-from sco_exceptions import ScoValueError, ScoException
-
"""Global/Semestre Preferences for ScoDoc (version dec 2008)
Preferences (paramètres) communs à tous les utilisateurs.
@@ -96,10 +85,10 @@ sinon, elle ne concerne que le semestre indiqué.
PREF_CATEGORIES : définition des catégories de préférences (pour
dialogues édition)
-PREFS : pour chaque pref, donne infos pour édition (titre, type...) et
+prefs_definition : pour chaque pref, donne infos pour édition (titre, type...) et
valeur par défaut.
-class sco_base_preferences
+class BasePreferences
Une instance unique par site (département, repéré par URL).
- charge les preferences pour tous le semestres depuis la BD.
.get(formsemestre_id, name)
@@ -111,16 +100,42 @@ Une instance unique par site (département, repéré par URL).
class SemPreferences(context,formsemestre_id)
Une instance par semestre, et une instance pour prefs globales.
-L'attribut .base_prefs point sur sco_base_preferences.
+L'attribut .base_prefs point sur BasePreferences.
.__getitem__ [name]
.is_global(name)
.edit(categories=[])
get_base_preferences(context, formsemestre_id)
- Return base preferences for this context (instance sco_base_preferences)
+ Return base preferences for this context (instance BasePreferences)
"""
+from flask import g
+
+import app.scodoc.sco_utils as scu
+import app.scodoc.notesdb as ndb
+from app.scodoc.notes_log import log
+from app.scodoc.sco_exceptions import ScoValueError, ScoException
+from app.scodoc.TrivialFormulator import TrivialFormulator
+
+_SCO_BASE_PREFERENCES = {} # { URL: BasePreferences instance }
+
+
+def get_base_preferences(context):
+ """Return global preferences for the current department"""
+ dept = g.scodoc_dept
+ if not dept in _SCO_BASE_PREFERENCES:
+ _SCO_BASE_PREFERENCES[dept] = BasePreferences(context)
+ return _SCO_BASE_PREFERENCES[dept]
+
+
+def get_preference(context, name, formsemestre_id=None):
+ """Returns value of named preference.
+ All preferences have a sensible default value, so this
+ function always returns a usable value for all defined preferences names.
+ """
+ return get_base_preferences(context).get(formsemestre_id, name)
+
PREF_CATEGORIES = (
# sur page "Paramètres"
@@ -175,1577 +190,9 @@ PREF_CATEGORIES = (
)
-PREFS = (
- (
- "DeptName",
- {
- "initvalue": "Dept",
- "title": "Nom abrégé du département",
- "size": 12,
- "category": "general",
- "only_global": True,
- },
- ),
- (
- "DeptFullName",
- {
- "initvalue": "nom du département",
- "title": "Nom complet du département",
- "explanation": "inutilisé par défaut",
- "size": 40,
- "category": "general",
- "only_global": True,
- },
- ),
- (
- "UnivName",
- {
- "initvalue": "",
- "title": "Nom de l'Université",
- "explanation": "apparait sur les bulletins et PV de jury",
- "size": 40,
- "category": "general",
- "only_global": True,
- },
- ),
- (
- "InstituteName",
- {
- "initvalue": "",
- "title": "Nom de l'Institut",
- "explanation": 'exemple "IUT de Villetaneuse". Peut être utilisé sur les bulletins.',
- "size": 40,
- "category": "general",
- "only_global": True,
- },
- ),
- (
- "DeptIntranetTitle",
- {
- "initvalue": "Intranet",
- "title": "Nom lien intranet",
- "size": 40,
- "explanation": 'titre du lien "Intranet" en haut à gauche',
- "category": "general",
- "only_global": True,
- },
- ),
- (
- "DeptIntranetURL",
- {
- "initvalue": "",
- "title": """URL de l'"intranet" du département""",
- "size": 40,
- "explanation": 'lien "Intranet" en haut à gauche',
- "category": "general",
- "only_global": True,
- },
- ),
- (
- "emails_notifications",
- {
- "initvalue": "",
- "title": "e-mails à qui notifier les opérations",
- "size": 70,
- "explanation": "adresses séparées par des virgules; notifie les opérations (saisies de notes, etc). (vous pouvez préférer utiliser le flux rss)",
- "category": "general",
- "only_global": False, # peut être spécifique à un semestre
- },
- ),
- # ------------------ MISC
- (
- "use_ue_coefs",
- {
- "initvalue": 0,
- "title": "Utiliser les coefficients d'UE pour calculer la moyenne générale",
- "explanation": """Calcule les moyennes dans chaque UE, puis pondère ces résultats pour obtenir la moyenne générale. Par défaut, le coefficient d'une UE est simplement la somme des coefficients des modules dans lesquels l'étudiant a des notes. Attention: changer ce réglage va modifier toutes les moyennes du semestre !""",
- "input_type": "boolcheckbox",
- "category": "misc",
- "labels": ["non", "oui"],
- "only_global": False,
- },
- ),
- (
- "recap_hidebac",
- {
- "initvalue": 0,
- "title": "Cacher la colonne Bac",
- "explanation": "sur la table récapitulative",
- "input_type": "boolcheckbox",
- "category": "misc",
- "labels": ["non", "oui"],
- "only_global": False,
- },
- ),
- # ------------------ Absences
- (
- "email_chefdpt",
- {
- "initvalue": "",
- "title": "e-mail chef du département",
- "size": 40,
- "explanation": "utilisé pour envoi mail notification absences",
- "category": "abs",
- "only_global": True,
- },
- ),
- (
- "work_saturday",
- {
- "initvalue": 0,
- "title": "Considérer le samedi comme travaillé",
- "input_type": "boolcheckbox",
- "labels": ["non", "oui"],
- "category": "abs",
- "only_global": True, # devrait etre par semestre, mais demanderait modif gestion absences
- },
- ),
- (
- "abs_require_module", # affecte l'UI mais pas les fonctions de base
- {
- "initvalue": 0,
- "title": "Imposer l'indication du module lors de la saisie des absences",
- "input_type": "boolcheckbox",
- "labels": ["non", "oui"],
- "category": "abs",
- "only_global": False,
- },
- ),
- (
- "handle_billets_abs",
- {
- "initvalue": 0,
- "title": 'Gestion de "billets" d\'absence',
- "explanation": 'fonctions pour traiter les "billets" déclarés par les étudiants sur un portail externe',
- "input_type": "boolcheckbox",
- "labels": ["non", "oui"],
- "category": "abs",
- "only_global": True,
- },
- ),
- (
- "abs_notify_chief", # renamed from "send_mail_absence_to_chef"
- {
- "initvalue": 0,
- "title": "Notifier les absences au chef",
- "explanation": "Envoyer un mail au chef si un étudiant a beaucoup d'absences",
- "input_type": "boolcheckbox",
- "labels": ["non", "oui"],
- "category": "abs",
- "only_global": True,
- },
- ),
- (
- "abs_notify_respsem",
- {
- "initvalue": 0,
- "title": "Notifier les absences au dir. des études",
- "explanation": "Envoyer un mail au responsable du semestre si un étudiant a beaucoup d'absences",
- "input_type": "boolcheckbox",
- "labels": ["non", "oui"],
- "category": "abs",
- },
- ),
- (
- "abs_notify_respeval",
- {
- "initvalue": 0,
- "title": "Notifier les absences aux resp. de modules",
- "explanation": "Envoyer un mail à chaque absence aux responsable des modules avec évaluation à cette date",
- "input_type": "boolcheckbox",
- "labels": ["non", "oui"],
- "category": "abs",
- },
- ),
- (
- "abs_notify_etud",
- {
- "initvalue": 0,
- "title": "Notifier les absences aux étudiants concernés",
- "explanation": "Envoyer un mail à l'étudiant s'il a \"beaucoup\" d'absences",
- "input_type": "boolcheckbox",
- "labels": ["non", "oui"],
- "category": "abs",
- },
- ),
- (
- "abs_notify_email",
- {
- "initvalue": "",
- "title": "Notifier à:",
- "explanation": "e-mail à qui envoyer des notification d'absences (en sus des autres destinataires éventuels, comme le chef etc.)",
- "size": 40,
- "category": "abs",
- },
- ),
- (
- "abs_notify_max_freq",
- {
- "initvalue": 7,
- "title": "Fréquence maximale de notification",
- "explanation": "en jours (pas plus de X envois de mail pour chaque étudiant/destinataire)",
- "size": 4,
- "type": "int",
- "convert_numbers": True,
- "category": "abs",
- },
- ),
- (
- "abs_notify_abs_threshold",
- {
- "initvalue": 10,
- "title": "Seuil de première notification",
- "explanation": "nb minimum d'absences (en 1/2 journées) avant notification",
- "size": 4,
- "type": "int",
- "convert_numbers": True,
- "category": "abs",
- },
- ),
- (
- "abs_notify_abs_increment",
- {
- "initvalue": 20, # les notification suivantes seront donc rares
- "title": "Seuil notifications suivantes",
- "explanation": "nb minimum d'absences (en 1/2 journées supplémentaires)",
- "size": 4,
- "type": "int",
- "convert_numbers": True,
- "category": "abs",
- },
- ),
- (
- "abs_notification_mail_tmpl",
- {
- "initvalue": """
---- Ceci est un message de notification automatique issu de ScoDoc ---
+class BasePreferences(object):
+ """Global preferences"""
-L'étudiant %(nomprenom)s
-inscrit en %(inscription)s)
-
-a cumulé %(nbabsjust)s absences justifiées
-et %(nbabsnonjust)s absences NON justifiées.
-
-Le compte a pu changer depuis cet envoi, voir la fiche sur %(url_ficheetud)s.
-
-
-Votre dévoué serveur ScoDoc.
-
-PS: Au dela de %(abs_notify_abs_threshold)s, un email automatique est adressé toutes les %(abs_notify_abs_increment)s absences. Ces valeurs sont modifiables dans les préférences de ScoDoc.
-""",
- "title": """Message notification e-mail""",
- "explanation": """Balises remplacées, voir la documentation""",
- "input_type": "textarea",
- "rows": 15,
- "cols": 64,
- "category": "abs",
- },
- ),
- # portal
- (
- "portal_url",
- {
- "initvalue": "",
- "title": "URL du portail",
- "size": 40,
- "category": "portal",
- "only_global": True,
- },
- ),
- (
- "portal_timeout",
- {
- "initvalue": 3,
- "title": "timeout",
- "explanation": "secondes",
- "size": 3,
- "type": "int",
- "convert_numbers": True,
- "category": "portal",
- "only_global": True,
- },
- ),
- (
- "portal_dept_name",
- {
- "initvalue": "Dept",
- "title": "Code du département sur le portail",
- "category": "portal",
- "only_global": True,
- },
- ),
- (
- "etapes_url",
- {
- "initvalue": "",
- "title": "URL listant les étapes Apogée",
- "size": 40,
- "category": "portal",
- "only_global": True,
- "explanation": "par defaut, selon l'api, getEtapes ou scodocEtapes sur l'URL du portail",
- },
- ),
- (
- "maquette_url",
- {
- "initvalue": "",
- "title": "URL maquettes Apogee",
- "size": 40,
- "category": "portal",
- "only_global": True,
- "explanation": "par defaut, scodocMaquette sur l'URL du portail",
- },
- ),
- (
- "portal_api",
- {
- "initvalue": 1,
- "title": "Version de l'API",
- "explanation": "1 ou 2",
- "size": 3,
- "type": "int",
- "convert_numbers": True,
- "category": "portal",
- "only_global": True,
- },
- ),
- (
- "etud_url",
- {
- "initvalue": "",
- "title": "URL listant les étudiants Apogée",
- "size": 40,
- "category": "portal",
- "only_global": True,
- "explanation": "par defaut, selon l'api, getEtud ou scodocEtudiant sur l'URL du portail",
- },
- ),
- (
- "photo_url",
- {
- "initvalue": "",
- "title": "URL donnant la photo d'un étudiant avec argument nip=",
- "size": 40,
- "category": "portal",
- "only_global": True,
- "explanation": "par defaut, selon l'api, getPhoto ou scodocPhoto sur l'URL du portail",
- },
- ),
- (
- "xml_etapes_by_dept",
- {
- "initvalue": 1,
- "title": "Etapes séparées par département",
- "explanation": "XML getEtapes structuré en départements ?",
- "input_type": "boolcheckbox",
- "labels": ["non", "oui"],
- "category": "portal",
- "only_global": True,
- },
- ),
- (
- "notify_etud_changes_to",
- {
- "initvalue": "",
- "title": "e-mail à qui notifier les changements d'identité des étudiants",
- "explanation": "utile pour mettre à jour manuellement d'autres bases de données",
- "size": 40,
- "category": "portal",
- "only_global": True,
- },
- ),
- (
- "always_require_ine",
- {
- "initvalue": 0,
- "title": "Impose la présence du code INE",
- "explanation": "lors de toute création d'étudiant (manuelle ou non)",
- "input_type": "boolcheckbox",
- "labels": ["non", "oui"],
- "category": "portal",
- "only_global": True,
- },
- ),
- (
- "always_require_apo_sem_codes",
- {
- "initvalue": 0,
- "title": "Impose la présence des codes Apogée",
- "explanation": "lors des créations de semestres",
- "input_type": "boolcheckbox",
- "labels": ["non", "oui"],
- "category": "portal",
- "only_global": True,
- },
- ),
- # exports Apogée
- (
- "export_res_etape",
- {
- "initvalue": 1,
- "title": "Exporter résultat de l'étape",
- "explanation": "remplissage maquettes export Apogée",
- "input_type": "boolcheckbox",
- "labels": ["non", "oui"],
- "category": "portal",
- "only_global": True,
- },
- ),
- (
- "export_res_sem",
- {
- "initvalue": 1,
- "title": "Exporter résultat du semestre",
- "explanation": "remplissage maquettes export Apogée",
- "input_type": "boolcheckbox",
- "labels": ["non", "oui"],
- "category": "portal",
- "only_global": True,
- },
- ),
- (
- "export_res_ues",
- {
- "initvalue": 1,
- "title": "Exporter les résultats d'UE",
- "explanation": "remplissage maquettes export Apogée",
- "input_type": "boolcheckbox",
- "labels": ["non", "oui"],
- "category": "portal",
- "only_global": True,
- },
- ),
- (
- "export_res_modules",
- {
- "initvalue": 1,
- "title": "Exporter les résultats de modules",
- "explanation": "remplissage maquettes export Apogée",
- "input_type": "boolcheckbox",
- "labels": ["non", "oui"],
- "category": "portal",
- "only_global": True,
- },
- ),
- (
- "export_res_sdj",
- {
- "initvalue": 0,
- "title": "Exporter les résultats même sans décision de jury",
- "explanation": "si coché, exporte exporte étudiants même si pas décision de jury saisie (sinon laisse vide)",
- "input_type": "boolcheckbox",
- "labels": ["non", "oui"],
- "category": "portal",
- "only_global": True,
- },
- ),
- (
- "export_res_rat",
- {
- "initvalue": 1,
- "title": "Exporter les RAT comme ATT",
- "explanation": "si coché, exporte exporte étudiants en attente de ratrapage comme ATT (sinon laisse vide)",
- "input_type": "boolcheckbox",
- "labels": ["non", "oui"],
- "category": "portal",
- "only_global": True,
- },
- ),
- # pdf
- (
- "SCOLAR_FONT",
- {
- "initvalue": "Helvetica",
- "title": "Police de caractère principale",
- "explanation": "pour les pdf",
- "size": 25,
- "category": "pdf",
- },
- ),
- (
- "SCOLAR_FONT_SIZE",
- {
- "initvalue": 10,
- "title": "Taille des caractères",
- "explanation": "pour les pdf",
- "size": 4,
- "type": "int",
- "convert_numbers": True,
- "category": "pdf",
- },
- ),
- (
- "SCOLAR_FONT_SIZE_FOOT",
- {
- "initvalue": 6,
- "title": "Taille des caractères pied de page",
- "explanation": "pour les pdf",
- "size": 4,
- "type": "int",
- "convert_numbers": True,
- "category": "pdf",
- },
- ),
- (
- "pdf_footer_x",
- {
- "initvalue": 20,
- "title": "Position horizontale du pied de page pdf (en mm)",
- "size": 8,
- "type": "float",
- "category": "pdf",
- },
- ),
- (
- "pdf_footer_y",
- {
- "initvalue": 6.35,
- "title": "Position verticale du pied de page pdf (en mm)",
- "size": 8,
- "type": "float",
- "category": "pdf",
- },
- ),
- # pvpdf
- (
- "DirectorName",
- {
- "initvalue": "",
- "title": "Nom du directeur de l'établissement",
- "size": 32,
- "explanation": "pour les PV de jury",
- "category": "pvpdf",
- },
- ),
- (
- "DirectorTitle",
- {
- "initvalue": """directeur de l'IUT""",
- "title": 'Titre du "directeur"',
- "explanation": "titre apparaissant à côté de la signature sur les PV de jury",
- "size": 64,
- "category": "pvpdf",
- },
- ),
- (
- "ChiefDeptName",
- {
- "initvalue": "",
- "title": "Nom du chef de département",
- "size": 32,
- "explanation": "pour les bulletins pdf",
- "category": "pvpdf",
- },
- ),
- (
- "INSTITUTION_NAME",
- {
- "initvalue": "Institut Universitaire de Technologie - Université Paris 13",
- "title": "Nom institution sur pied de pages PV",
- "explanation": "(pdf, balises <b> interprétées)",
- "input_type": "textarea",
- "rows": 4,
- "cols": 64,
- "category": "pvpdf",
- },
- ),
- (
- "INSTITUTION_ADDRESS",
- {
- "initvalue": "Web www.iutv.univ-paris13.fr - 99 avenue Jean-Baptiste Clément - F 93430 Villetaneuse",
- "title": "Adresse institution sur pied de pages PV",
- "explanation": "(pdf, balises <b> interprétées)",
- "input_type": "textarea",
- "rows": 4,
- "cols": 64,
- "category": "pvpdf",
- },
- ),
- (
- "INSTITUTION_CITY",
- {
- "initvalue": "Villetaneuse",
- "title": "Ville de l'institution",
- "explanation": "pour les lettres individuelles",
- "size": 64,
- "category": "pvpdf",
- },
- ),
- (
- "PV_INTRO",
- {
- "initvalue": """ Ces paramètres s'appliquent par défaut à tous les semestres, sauf si ceux-ci définissent des valeurs spécifiques. Attention: cliquez sur "Enregistrer les modifications" en bas de page pour appliquer vos changements ! %s %s ")
if modejury:
H.append(
@@ -395,7 +403,7 @@ def make_formsemestre_recapcomplet(
e = nt.identdict[etudid]
if civ_nom_prenom:
- scolars.format_etud_ident(e)
+ sco_etud.format_etud_ident(e)
l = [rank, e["civilite_str"], e["nom_disp"], e["prenom"]] # civ, nom prenom
else:
l = [rank, nt.get_nom_short(etudid)] # rang, nom,
@@ -800,7 +808,9 @@ def _list_notes_evals(context, evals, etudid):
or e["etat"]["evalattente"]
or e["publish_incomplete"]
):
- NotesDB = context._notes_getall(e["evaluation_id"])
+ NotesDB = sco_evaluations.do_evaluation_get_all_notes(
+ context, e["evaluation_id"]
+ )
if NotesDB.has_key(etudid):
val = NotesDB[etudid]["value"]
else:
diff --git a/app/scodoc/sco_report.py b/app/scodoc/sco_report.py
index aafcf0708..95f225172 100644
--- a/app/scodoc/sco_report.py
+++ b/app/scodoc/sco_report.py
@@ -36,19 +36,25 @@ import re
import time
import datetime
-import sco_utils as scu
-import VERSION
-from notes_log import log
-from gen_tables import GenTable
-import sco_excel, sco_pdf
-from notesdb import DateDMYtoISO
-from sco_exceptions import ScoValueError
-import sco_codes_parcours
-from sco_codes_parcours import code_semestre_validant
-import sco_parcours_dut
-import sco_formsemestre
-import sco_formsemestre_status
-from sco_pdf import SU
+import app.scodoc.sco_utils as scu
+from app.scodoc import notesdb as ndb
+from app.scodoc import html_sco_header
+from app.scodoc import sco_codes_parcours
+from app.scodoc import sco_core
+from app.scodoc import sco_etud
+from app.scodoc import sco_excel
+from app.scodoc import sco_formsemestre
+from app.scodoc import sco_formsemestre_inscriptions
+from app.scodoc import sco_formsemestre_status
+from app.scodoc import sco_parcours_dut
+from app.scodoc import sco_pdf
+from app.scodoc import sco_preferences
+from app.scodoc import VERSION
+from app.scodoc.gen_tables import GenTable
+from app.scodoc.notes_log import log
+from app.scodoc.sco_codes_parcours import code_semestre_validant
+from app.scodoc.sco_exceptions import ScoValueError
+from app.scodoc.sco_pdf import SU
MAX_ETUD_IN_DESCR = 20
@@ -63,7 +69,7 @@ def formsemestre_etuds_stats(context, sem, only_primo=False):
etuds = []
for t in T:
etudid = t[-1]
- etud = scolars.get_etud_info(etudid=etudid, filled=True)[0]
+ etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
decision = nt.get_etud_decision_sem(etudid)
if decision:
etud["codedecision"] = decision["code"]
@@ -418,7 +424,7 @@ def table_suivi_cohorte(
civilites = set()
statuts = set()
for etudid in etudids:
- etud = scolars.get_etud_info(etudid=etudid, filled=True)[0]
+ etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
bacspe = etud["bac"] + " / " + etud["specialite"]
# sélection sur bac:
if (
@@ -432,7 +438,9 @@ def table_suivi_cohorte(
orig_set.add(etudid)
# semestres suivants:
for s in etud["sems"]:
- if DateDMYtoISO(s["date_debut"]) > DateDMYtoISO(sem["date_debut"]):
+ if ndb.DateDMYtoISO(s["date_debut"]) > ndb.DateDMYtoISO(
+ sem["date_debut"]
+ ):
S[s["formsemestre_id"]] = s
bacs.add(etud["bac"])
bacspecialites.add(bacspe)
@@ -451,8 +459,8 @@ def table_suivi_cohorte(
logt("B: etuds sets")
sem["members"] = orig_set
for s in sems:
- ins = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(context,
- args={"formsemestre_id": s["formsemestre_id"]}
+ ins = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
+ context, args={"formsemestre_id": s["formsemestre_id"]}
) # sans dems
inset = set([i["etudid"] for i in ins])
s["members"] = orig_set.intersection(inset)
@@ -900,7 +908,7 @@ def _descr_etud_set(context, etudids):
"textual html description of a set of etudids"
etuds = []
for etudid in etudids:
- etuds.append(scolars.get_etud_info(etudid=etudid, filled=True)[0])
+ etuds.append(sco_etud.get_etud_info(etudid=etudid, filled=True)[0])
# sort by name
etuds.sort(lambda x, y: cmp(x["nom"], y["nom"]))
return ", ".join([e["nomprenom"] for e in etuds])
@@ -1032,7 +1040,7 @@ def tsp_etud_list(
civilites = set()
statuts = set()
for etudid in etudids:
- etud = scolars.get_etud_info(etudid=etudid, filled=True)[0]
+ etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
bacspe = etud["bac"] + " / " + etud["specialite"]
# sélection sur bac, primo, ...:
if (
diff --git a/app/scodoc/sco_roles_default.py b/app/scodoc/sco_roles_default.py
index 406daee19..30c5bbb14 100644
--- a/app/scodoc/sco_roles_default.py
+++ b/app/scodoc/sco_roles_default.py
@@ -4,7 +4,7 @@
"""Definition of ScoDoc default roles
"""
-from sco_permissions import Permission as p
+from app.scodoc.sco_permissions import Permission as p
SCO_ROLES_DEFAULTS = {
"Observateur": (p.ScoObservateur,),
@@ -55,4 +55,4 @@ SCO_ROLES_DEFAULTS = {
# Super Admin est un root: création/suppression de départements
# _tous_ les droits
"SuperAdmin": p.ALL_PERMISSIONS,
-}
\ No newline at end of file
+}
diff --git a/app/scodoc/sco_saisie_notes.py b/app/scodoc/sco_saisie_notes.py
index f960c19ce..3501bc054 100644
--- a/app/scodoc/sco_saisie_notes.py
+++ b/app/scodoc/sco_saisie_notes.py
@@ -33,65 +33,32 @@ import time
import datetime
import psycopg2
-import sco_utils as scu
-import notesdb as ndb
-from notes_log import log
-from TrivialFormulator import TrivialFormulator, TF
-from notesdb import ScoDocCursor, quote_dict, DateISOtoDMY, DateDMYtoISO
-from sco_exceptions import (
- InvalidNoteValue,
+import app.scodoc.sco_utils as scu
+import app.scodoc.notesdb as ndb
+from app.scodoc.notes_log import log
+from app.scodoc.sco_exceptions import (
AccessDenied,
+ InvalidNoteValue,
NoteProcessError,
ScoValueError,
)
-from sco_permissions import ScoEditAllNotes
-import sco_core
-import sco_formsemestre
-import sco_moduleimpl
-import sco_groups
-import sco_groups_view
-import sco_evaluations
-import sco_parcours_dut
-import sco_undo_notes
-import htmlutils
-import sco_excel
-import scolars
-import sco_news
-
-
-def can_edit_notes(context, authuser, moduleimpl_id, allow_ens=True):
- """True if authuser can enter or edit notes in this module.
- If allow_ens, grant access to all ens in this module
-
- Si des décisions de jury ont déjà été saisies dans ce semestre,
- seul le directeur des études peut saisir des notes (et il ne devrait pas).
- """
- uid = str(authuser)
- M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0]
- sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"])
- if sem["etat"] != "1":
- return False # semestre verrouillé
-
- if sco_parcours_dut.formsemestre_has_decisions(context, sem["formsemestre_id"]):
- # il y a des décisions de jury dans ce semestre !
- return (
- authuser.has_permission(Permission.ScoEditAllNotes)
- or uid in sem["responsables"]
- )
- else:
- if (
- (not authuser.has_permission(Permission.ScoEditAllNotes))
- and uid != M["responsable_id"]
- and uid not in sem["responsables"]
- ):
- # enseignant (chargé de TD) ?
- if allow_ens:
- for ens in M["ens"]:
- if ens["ens_id"] == uid:
- return True
- return False
- else:
- return True
+from app.scodoc.sco_permissions import Permission
+from app.scodoc.TrivialFormulator import TrivialFormulator, TF
+from app.scodoc import html_sco_header
+from app.scodoc import htmlutils
+from app.scodoc import sco_core
+from app.scodoc import sco_edit_module
+from app.scodoc import sco_evaluations
+from app.scodoc import sco_excel
+from app.scodoc import sco_formsemestre
+from app.scodoc import sco_formsemestre_inscriptions
+from app.scodoc import sco_groups
+from app.scodoc import sco_groups_view
+from app.scodoc import sco_moduleimpl
+from app.scodoc import sco_news
+from app.scodoc import sco_permissions_check
+from app.scodoc import sco_undo_notes
+from app.scodoc import sco_etud
def convert_note_from_string(
@@ -203,7 +170,7 @@ def do_evaluation_upload_xls(context, REQUEST):
)[0]
# Check access
# (admin, respformation, and responsable_id)
- if not can_edit_notes(context, authuser, E["moduleimpl_id"]):
+ if not sco_permissions_check.can_edit_notes(context, authuser, E["moduleimpl_id"]):
# XXX imaginer un redirect + msg erreur
raise AccessDenied("Modification des notes impossible pour %s" % authuser)
#
@@ -265,7 +232,7 @@ def do_evaluation_upload_xls(context, REQUEST):
)
if len(invalids) < 25:
etudsnames = [
- scolars.get_etud_info(etudid=etudid, filled=True)[0]["nomprenom"]
+ sco_etud.get_etud_info(etudid=etudid, filled=True)[0]["nomprenom"]
for etudid in invalids
]
diag.append("Notes invalides pour: " + ", ".join(etudsnames))
@@ -328,11 +295,11 @@ def do_evaluation_set_missing(
)[0]
# Check access
# (admin, respformation, and responsable_id)
- if not can_edit_notes(context, authuser, E["moduleimpl_id"]):
+ if not sco_permissions_check.can_edit_notes(context, authuser, E["moduleimpl_id"]):
# XXX imaginer un redirect + msg erreur
raise AccessDenied("Modification des notes impossible pour %s" % authuser)
#
- NotesDB = context._notes_getall(evaluation_id)
+ NotesDB = sco_evaluations.do_evaluation_get_all_notes(context, evaluation_id)
etudids = sco_groups.do_evaluation_listeetuds_groups(
context, evaluation_id, getallstudents=True, include_dems=False
)
@@ -405,13 +372,19 @@ def evaluation_suppress_alln(context, evaluation_id, REQUEST, dialog_confirmed=F
authuser = REQUEST.AUTHENTICATED_USER
E = sco_evaluations.do_evaluation_list(context, {"evaluation_id": evaluation_id})[0]
- if can_edit_notes(context, authuser, E["moduleimpl_id"], allow_ens=False):
+ if sco_permissions_check.can_edit_notes(
+ context, authuser, E["moduleimpl_id"], allow_ens=False
+ ):
# On a le droit de modifier toutes les notes
# recupere les etuds ayant une note
- NotesDB = context._notes_getall(evaluation_id)
- elif can_edit_notes(context, authuser, E["moduleimpl_id"], allow_ens=True):
+ NotesDB = sco_evaluations.do_evaluation_get_all_notes(context, evaluation_id)
+ elif sco_permissions_check.can_edit_notes(
+ context, authuser, E["moduleimpl_id"], allow_ens=True
+ ):
# Enseignant associé au module: ne peut supprimer que les notes qu'il a saisi
- NotesDB = context._notes_getall(evaluation_id, by_uid=str(authuser))
+ NotesDB = sco_evaluations.do_evaluation_get_all_notes(
+ context, evaluation_id, by_uid=str(authuser)
+ )
else:
raise AccessDenied("Modification des notes impossible pour %s" % authuser)
@@ -496,10 +469,10 @@ def _notes_add(context, uid, evaluation_id, notes, comment=None, do_it=True):
"etudiant %s: valeur de note invalide (%s)" % (etudid, value)
)
# Recherche notes existantes
- NotesDB = context._notes_getall(evaluation_id)
+ NotesDB = sco_evaluations.do_evaluation_get_all_notes(context, evaluation_id)
# Met a jour la base
cnx = context.GetDBConnexion(autocommit=False)
- cursor = cnx.cursor(cursor_factory=ScoDocCursor)
+ cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
nb_changed = 0
nb_suppress = 0
E = sco_evaluations.do_evaluation_list(context, {"evaluation_id": evaluation_id})[0]
@@ -522,7 +495,7 @@ def _notes_add(context, uid, evaluation_id, notes, comment=None, do_it=True):
"uid": uid,
"date": now,
}
- quote_dict(aa)
+ ndb.quote_dict(aa)
cursor.execute(
"insert into notes_notes (etudid,evaluation_id,value,comment,date,uid) values (%(etudid)s,%(evaluation_id)s,%(value)s,%(comment)s,%(date)s,%(uid)s)",
aa,
@@ -554,7 +527,7 @@ def _notes_add(context, uid, evaluation_id, notes, comment=None, do_it=True):
"comment": comment,
"uid": uid,
}
- quote_dict(aa)
+ ndb.quote_dict(aa)
if value != scu.NOTES_SUPPRESS:
if do_it:
cursor.execute(
@@ -614,7 +587,7 @@ def saisie_notes_tableur(context, evaluation_id, group_ids=[], REQUEST=None):
E = evals[0]
M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=E["moduleimpl_id"])[0]
formsemestre_id = M["formsemestre_id"]
- if not can_edit_notes(context, authuser, E["moduleimpl_id"]):
+ if not sco_permissions_check.can_edit_notes(context, authuser, E["moduleimpl_id"]):
return (
html_sco_header.sco_header(context, REQUEST)
+ "
%(DirectorName)s""",
- "title": """Signature des lettres individuelles de diplôme""",
- "explanation": """%(DirectorName)s et %(DirectorTitle)s remplacés""",
- "input_type": "textarea",
- "rows": 4,
- "cols": 64,
- "category": "pvpdf",
- },
- ),
- (
- "PV_LETTER_PASSAGE_SIGNATURE",
- {
- "initvalue": """Pour le Directeur de l'IUT
-et par délégation
-Le Chef du département""",
- "title": """Signature des lettres individuelles de passage d'un semestre à l'autre""",
- "explanation": """%(DirectorName)s et %(DirectorTitle)s remplacés""",
- "input_type": "textarea",
- "rows": 4,
- "cols": 64,
- "category": "pvpdf",
- },
- ),
- (
- "pv_sig_image_height",
- {
- "initvalue": 11,
- "size": 10,
- "title": "Hauteur de l'image de la signature",
- "type": "float",
- "explanation": "Lorsqu'on donne une image de signature, elle est redimensionnée à cette taille (en millimètres)",
- "category": "pvpdf",
- },
- ),
- (
- "PV_LETTER_TEMPLATE",
- {
- "initvalue": """
%(titre_formation)s
-
-%(responsable)s
-
-%(ChiefDeptName)s
-
%(DirectorName)s""",
+ "title": """Signature des lettres individuelles de diplôme""",
+ "explanation": """%(DirectorName)s et %(DirectorTitle)s remplacés""",
+ "input_type": "textarea",
+ "rows": 4,
+ "cols": 64,
+ "category": "pvpdf",
+ },
+ ),
+ (
+ "PV_LETTER_PASSAGE_SIGNATURE",
+ {
+ "initvalue": """Pour le Directeur de l'IUT
+ et par délégation
+ Le Chef du département""",
+ "title": """Signature des lettres individuelles de passage d'un semestre à l'autre""",
+ "explanation": """%(DirectorName)s et %(DirectorTitle)s remplacés""",
+ "input_type": "textarea",
+ "rows": 4,
+ "cols": 64,
+ "category": "pvpdf",
+ },
+ ),
+ (
+ "pv_sig_image_height",
+ {
+ "initvalue": 11,
+ "size": 10,
+ "title": "Hauteur de l'image de la signature",
+ "type": "float",
+ "explanation": "Lorsqu'on donne une image de signature, elle est redimensionnée à cette taille (en millimètres)",
+ "category": "pvpdf",
+ },
+ ),
+ (
+ "PV_LETTER_TEMPLATE",
+ {
+ "initvalue": """
%(titre_formation)s
+
+ %(responsable)s
+
+ %(ChiefDeptName)s
+ Préférences globales pour %s
" % self.scu.ScoURL(),
+ html_sco_header.sco_header(self.context, REQUEST, page_title="Préférences"),
+ "Préférences globales pour %s
" % scu.ScoURL(),
"""%s
" % title},
+ )
+ )
+ subtitle = cat_descr.get("subtitle", None)
+ if subtitle:
+ form.append(
+ (
+ "sepsub_%s" % cat,
+ {
+ "input_type": "separator",
+ "title": '%s
" % title},
- )
- )
- subtitle = cat_descr.get("subtitle", None)
- if subtitle:
- form.append(
- (
- "sepsub_%s" % cat,
- {
- "input_type": "separator",
- "title": 'Modification des notes impossible pour %s
" % authusername
@@ -733,7 +706,7 @@ def saisie_notes_tableur(context, evaluation_id, group_ids=[], REQUEST=None):
)
#
H.append("""
Responsable de ce semestre : %s
" - % ", ".join(sem["responsables"]), - footer, - ] - ), - ) - else: - return True, "" - - @bp.route("/formsemestre_custommenu_edit") @permission_required(Permission.ScoView) @scodoc7func(context) @@ -1044,17 +1012,22 @@ def view_module_abs(context, REQUEST, moduleimpl_id, format="html"): T = [] for etudid in list_insc: - nb_abs = context.Absences.CountAbs( - etudid=etudid, debut=debut_sem, fin=fin_sem, moduleimpl_id=moduleimpl_id + nb_abs = sco_abs.CountAbs( + context, + etudid=etudid, + debut=debut_sem, + fin=fin_sem, + moduleimpl_id=moduleimpl_id, ) if nb_abs: - nb_abs_just = context.Absences.CountAbsJust( + nb_abs_just = sco_abs.CountAbsJust( + context, etudid=etudid, debut=debut_sem, fin=fin_sem, moduleimpl_id=moduleimpl_id, ) - etud = scolars.get_etud_info(etudid=etudid, filled=True)[0] + etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0] T.append( { "nomprenom": etud["nomprenom"], @@ -1312,7 +1285,7 @@ def do_formsemestre_inscription_listinscrits( context, formsemestre_id, format=None, REQUEST=None ): """Liste les inscrits (état I) à ce semestre et cache le résultat""" - cache = context.get_formsemestre_inscription_cache() + cache = sco_core.get_formsemestre_inscription_cache(context) r = cache.get(formsemestre_id) if r is None: # retreive list @@ -1352,7 +1325,7 @@ def formsemestre_desinscription( % (etudid, formsemestre_id) ) if not dialog_confirmed: - etud = scolars.get_etud_info(etudid=etudid, filled=1)[0] + etud = sco_etud.get_etud_info(etudid=etudid, filled=1)[0] if sem["modalite"] != "EXT": msg_ext = """%s sera désinscrit de tous les modules du semestre %s (%s - %s).
@@ -1500,7 +1473,7 @@ def _evaluation_check_write_access(context, REQUEST, moduleimpl_id=None): sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"]) if ( - (not authuser.has_permission(Permission.ScoEditAllEvals, context)) + (not authuser.has_permission(Permission.ScoEditAllEvals)) and uid != M["responsable_id"] and uid not in sem["responsables"] ): @@ -1588,7 +1561,7 @@ def do_evaluation_create( sco_news.add( context, REQUEST, - typ=NEWS_NOTE, + typ=sco_news.NEWS_NOTE, object=moduleimpl_id, text='Création d\'une évaluation dans %(titre)s' % mod, url=mod["url"], @@ -1770,7 +1743,7 @@ def evaluation_listenotes(context, REQUEST=None): F = html_sco_header.sco_footer(context, REQUEST) else: H, F = "", "" - B = context.do_evaluation_listenotes(REQUEST) + B = sco_liste_notes.do_evaluation_listenotes(context, REQUEST) return H + B + F @@ -1828,45 +1801,6 @@ sco_publish( ) -def _notes_getall( - context, evaluation_id, table="notes_notes", filter_suppressed=True, by_uid=None -): - """get tt les notes pour une evaluation: { etudid : { 'value' : value, 'date' : date ... }} - Attention: inclue aussi les notes des étudiants qui ne sont plus inscrits au module. - """ - # log('_notes_getall( e=%s fs=%s )' % (evaluation_id, filter_suppressed)) - do_cache = ( - filter_suppressed and table == "notes_notes" and (by_uid is None) - ) # pas de cache pour (rares) appels via undo_notes ou specifiant un enseignant - if do_cache: - cache = sco_core.get_evaluations_cache(context) - r = cache.get(evaluation_id) - if r != None: - return r - cnx = ndb.GetDBConnexion() - cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor) - cond = " where evaluation_id=%(evaluation_id)s" - if by_uid: - cond += " and uid=%(by_uid)s" - - cursor.execute( - "select * from " + table + cond, - {"evaluation_id": evaluation_id, "by_uid": by_uid}, - ) - res = cursor.dictfetchall() - d = {} - if filter_suppressed: - for x in res: - if x["value"] != scu.NOTES_SUPPRESS: - d[x["etudid"]] = x - else: - for x in res: - d[x["etudid"]] = x - if do_cache: - cache.set(evaluation_id, d) - return d - - # --- Bulletins @bp.route("/formsemestre_bulletins_pdf") @permission_required(Permission.ScoView) @@ -1881,6 +1815,9 @@ def formsemestre_bulletins_pdf( return scu.sendPDFFile(REQUEST, pdfdoc, filename) +_EXPL_BULL = """Versions des bulletins:Opération non autorisée pour %s" @@ -2232,7 +2171,7 @@ def formsemestre_validation_etud_manu( REQUEST=None, ): "Enregistre choix jury pour un étudiant" - if not sco_permissions.can_validate_sem(context, REQUEST, formsemestre_id): + if not sco_permissions_check.can_validate_sem(context, REQUEST, formsemestre_id): return scu.confirm_dialog( context, message="
Opération non autorisée pour %s" @@ -2262,7 +2201,7 @@ def formsemestre_validate_previous_ue( context, formsemestre_id, etudid=None, REQUEST=None ): "Form. saisie UE validée hors ScoDoc " - if not sco_permissions.can_validate_sem(context, REQUEST, formsemestre_id): + if not sco_permissions_check.can_validate_sem(context, REQUEST, formsemestre_id): return scu.confirm_dialog( context, message="
Opération non autorisée pour %s" @@ -2289,7 +2228,7 @@ def formsemestre_ext_edit_ue_validations( context, formsemestre_id, etudid=None, REQUEST=None ): "Form. edition UE semestre extérieur" - if not sco_permissions.can_validate_sem(context, REQUEST, formsemestre_id): + if not sco_permissions_check.can_validate_sem(context, REQUEST, formsemestre_id): return scu.confirm_dialog( context, message="
Opération non autorisée pour %s" @@ -2314,7 +2253,7 @@ sco_publish( @scodoc7func(context) def etud_ue_suppress_validation(context, etudid, formsemestre_id, ue_id, REQUEST=None): """Suppress a validation (ue_id, etudid) and redirect to formsemestre""" - if not sco_permissions.can_validate_sem(context, REQUEST, formsemestre_id): + if not sco_permissions_check.can_validate_sem(context, REQUEST, formsemestre_id): return scu.confirm_dialog( context, message="
Opération non autorisée pour %s" @@ -2332,7 +2271,7 @@ def etud_ue_suppress_validation(context, etudid, formsemestre_id, ue_id, REQUEST @scodoc7func(context) def formsemestre_validation_auto(context, formsemestre_id, REQUEST): "Formulaire saisie automatisee des decisions d'un semestre" - if not sco_permissions.can_validate_sem(context, REQUEST, formsemestre_id): + if not sco_permissions_check.can_validate_sem(context, REQUEST, formsemestre_id): return scu.confirm_dialog( context, message="
Opération non autorisée pour %s" @@ -2351,7 +2290,7 @@ def formsemestre_validation_auto(context, formsemestre_id, REQUEST): @scodoc7func(context) def do_formsemestre_validation_auto(context, formsemestre_id, REQUEST): "Formulaire saisie automatisee des decisions d'un semestre" - if not sco_permissions.can_validate_sem(context, REQUEST, formsemestre_id): + if not sco_permissions_check.can_validate_sem(context, REQUEST, formsemestre_id): return scu.confirm_dialog( context, message="
Opération non autorisée pour %s" @@ -2370,7 +2309,7 @@ def do_formsemestre_validation_auto(context, formsemestre_id, REQUEST): @scodoc7func(context) def formsemestre_fix_validation_ues(context, formsemestre_id, REQUEST=None): "Verif/reparation codes UE" - if not sco_permissions.can_validate_sem(context, REQUEST, formsemestre_id): + if not sco_permissions_check.can_validate_sem(context, REQUEST, formsemestre_id): return scu.confirm_dialog( context, message="
Opération non autorisée pour %s" @@ -2391,7 +2330,7 @@ def formsemestre_validation_suppress_etud( context, formsemestre_id, etudid, REQUEST=None, dialog_confirmed=False ): """Suppression des decisions de jury pour un etudiant.""" - if not sco_permissions.can_validate_sem(context, REQUEST, formsemestre_id): + if not sco_permissions_check.can_validate_sem(context, REQUEST, formsemestre_id): return scu.confirm_dialog( context, message="
Opération non autorisée pour %s" @@ -2401,7 +2340,7 @@ def formsemestre_validation_suppress_etud( ) if not dialog_confirmed: sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) - etud = scolars.get_etud_info(etudid=etudid, filled=1)[0] + etud = sco_etud.get_etud_info(etudid=etudid, filled=1)[0] nt = sco_core.get_notes_cache(context).get_NotesTable( context, formsemestre_id ) # > get_etud_decision_sem @@ -2761,3 +2700,5 @@ sco_publish( ) context.populate(globals()) + +context.Users = scodoc_manager.FakeUsers() diff --git a/app/views/scolar.py b/app/views/scolar.py index ead578c72..eebb7b9b4 100644 --- a/app/views/scolar.py +++ b/app/views/scolar.py @@ -53,7 +53,7 @@ from flask import g from flask import current_app from config import Config -from scodoc_manager import sco_mgr +import scodoc_manager from app.decorators import ( scodoc7func, ScoDoc7Context, @@ -61,33 +61,14 @@ from app.decorators import ( admin_required, login_required, ) -from app.auth.models import Permission from app.views import scolar_bp as bp -from app.scodoc.notes_log import log - import app.scodoc.sco_utils as scu import app.scodoc.notesdb as ndb +from app.scodoc.notes_log import log from app.scodoc.scolog import logdb -from app.scodoc.sco_permissions import ( - ScoAbsChange, - ScoView, - ScoEnsView, - ScoImplement, - ScoChangeFormation, - ScoChangePreferences, - ScoObservateur, - ScoEtudAddAnnotations, - ScoEtudInscrit, - ScoEtudChangeGroups, - ScoEtudChangeAdr, - ScoEditAllEvals, - ScoEditAllNotes, - ScoEditFormationTags, - ScoEditApo, - ScoSuperAdmin, -) +from app.scodoc.sco_permissions import Permission from app.scodoc.sco_exceptions import ( AccessDenied, ScoException, @@ -98,52 +79,43 @@ from app.scodoc.sco_exceptions import ( ScoInvalidDept, ) from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message -from app.scodoc.sco_news import NEWS_INSCR, NEWS_NOTE, NEWS_FORM, NEWS_SEM, NEWS_MISC -from app.scodoc.VERSION import SCOVERSION, SCONEWS - -from app.scodoc.scolars import ( - format_nom, - format_prenom, - format_civilite, - format_lycee, - format_lycee_from_code, -) -from app.scodoc.scolars import format_telephone, format_pays, make_etud_args +from app.scodoc import VERSION from app.scodoc.gen_tables import GenTable -from app.scodoc import scolars -from app.scodoc import sco_codes_parcours -from app.scodoc import sco_preferences -from app.scodoc import sco_formations -from app.scodoc import sco_permissions -from app.scodoc import sco_find_etud -from app.scodoc import sco_photos -from app.scodoc import sco_formsemestre -from app.scodoc import sco_formsemestre_edit -from app.scodoc import sco_formsemestre_inscriptions -from app.scodoc import sco_news from app.scodoc import html_sco_header from app.scodoc import html_sidebar -from app.scodoc import sco_excel from app.scodoc import imageresize from app.scodoc import ImportScolars from app.scodoc import sco_abs -from app.scodoc import sco_portal_apogee -from app.scodoc import sco_synchro_etuds -from app.scodoc import sco_page_etud -from app.scodoc import sco_groups -from app.scodoc import sco_trombino -from app.scodoc import sco_groups_view -from app.scodoc import sco_trombino_tours -from app.scodoc import sco_parcours_dut -from app.scodoc import sco_report from app.scodoc import sco_archives_etud +from app.scodoc import sco_codes_parcours from app.scodoc import sco_debouche -from app.scodoc import sco_groups_edit -from app.scodoc import sco_up_to_date -from app.scodoc import sco_edt_cal from app.scodoc import sco_dept from app.scodoc import sco_dump_db +from app.scodoc import sco_edt_cal +from app.scodoc import sco_excel +from app.scodoc import sco_find_etud +from app.scodoc import sco_formations +from app.scodoc import sco_formsemestre +from app.scodoc import sco_formsemestre_edit +from app.scodoc import sco_formsemestre_inscriptions +from app.scodoc import sco_groups +from app.scodoc import sco_groups_edit +from app.scodoc import sco_groups_view +from app.scodoc import sco_news +from app.scodoc import sco_page_etud +from app.scodoc import sco_parcours_dut +from app.scodoc import sco_permissions +from app.scodoc import sco_permissions_check +from app.scodoc import sco_photos +from app.scodoc import sco_portal_apogee +from app.scodoc import sco_preferences +from app.scodoc import sco_report +from app.scodoc import sco_synchro_etuds +from app.scodoc import sco_trombino +from app.scodoc import sco_trombino_tours +from app.scodoc import sco_up_to_date +from app.scodoc import sco_etud context = ScoDoc7Context("scolar") @@ -189,7 +161,7 @@ def about(context, REQUEST): H.append( '
Logiciel libre écrit en Python.
Utilise ReportLab pour générer les documents PDF, et pyExcelerator pour le traitement des documents Excel.
' ) - H.append("