Fix imports portails + petits bugs

This commit is contained in:
Emmanuel Viennet 2021-08-21 15:17:14 +02:00
parent e54e8147a8
commit c22f4571fa
16 changed files with 61 additions and 65 deletions

View File

@ -48,7 +48,7 @@ def sidebar_common():
"authuser": current_user.user_name, "authuser": current_user.user_name,
} }
H = [ H = [
f"""<a class="scodoc_title" href="about">ScoDoc 8</a> f"""<a class="scodoc_title" href="about">ScoDoc 9</a>
<div id="authuser"><a id="authuserlink" href="{ <div id="authuser"><a id="authuserlink" href="{
url_for("users.user_info_page", scodoc_dept=g.scodoc_dept, user_name=current_user.user_name) url_for("users.user_info_page", scodoc_dept=g.scodoc_dept, user_name=current_user.user_name)
}">{current_user.user_name}</a> }">{current_user.user_name}</a>

View File

@ -53,6 +53,7 @@ import shutil
import glob import glob
import flask import flask
from flask import g
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
from config import Config from config import Config
@ -95,7 +96,7 @@ class BaseArchiver(object):
:return: path to directory of archives for this object (eg formsemestre_id or etudid). :return: path to directory of archives for this object (eg formsemestre_id or etudid).
If directory does not yet exist, create it. If directory does not yet exist, create it.
""" """
dept_dir = os.path.join(self.root, scu.get_dept_id()) dept_dir = os.path.join(self.root, g.scodoc_dept)
try: try:
scu.GSL.acquire() scu.GSL.acquire()
if not os.path.isdir(dept_dir): if not os.path.isdir(dept_dir):
@ -113,7 +114,7 @@ class BaseArchiver(object):
""" """
:return: list of archive oids :return: list of archive oids
""" """
base = os.path.join(self.root, scu.get_dept_id()) + os.path.sep base = os.path.join(self.root, g.scodoc_dept) + os.path.sep
dirs = glob.glob(base + "*") dirs = glob.glob(base + "*")
return [os.path.split(x)[1] for x in dirs] return [os.path.split(x)[1] for x in dirs]

View File

@ -58,6 +58,8 @@ import traceback
from reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate from reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate
from flask import g, url_for
from app.scodoc import VERSION from app.scodoc import VERSION
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
from app.scodoc.notes_log import log from app.scodoc.notes_log import log
@ -139,7 +141,7 @@ def process_field(field, cdict, style, suppress_empty_pars=False, format="pdf"):
return text return text
# --- PDF format: # --- PDF format:
# handle logos: # handle logos:
image_dir = scu.SCODOC_LOGOS_DIR + "/logos_" + scu.get_dept_id() + "/" image_dir = scu.SCODOC_LOGOS_DIR + "/logos_" + g.scodoc_dept + "/"
if not os.path.exists(image_dir): if not os.path.exists(image_dir):
image_dir = scu.SCODOC_LOGOS_DIR + "/" # use global logos image_dir = scu.SCODOC_LOGOS_DIR + "/" # use global logos
if not os.path.exists(image_dir): if not os.path.exists(image_dir):

View File

@ -85,7 +85,7 @@ et sur page "réglages bulletin" (avec formsemestre_id)
# def _sig_filename(side, formsemestre_id=None): # def _sig_filename(side, formsemestre_id=None):
# if not side in ("left", "right"): # if not side in ("left", "right"):
# raise ValueError("side must be left or right") # raise ValueError("side must be left or right")
# dirs = [SCODOC_LOGOS_DIR, scu.get_dept_id()] # dirs = [SCODOC_LOGOS_DIR, g.scodoc_dept]
# if formsemestre_id: # if formsemestre_id:
# dirs.append(formsemestre_id) # dirs.append(formsemestre_id)
# dirs.append("bul_sig_{}".format(side)) # dirs.append("bul_sig_{}".format(side))

View File

@ -911,7 +911,7 @@ def fill_etuds_info(etuds):
# open('/tmp/t','w').write( str(etuds) ) # open('/tmp/t','w').write( str(etuds) )
for etud in etuds: for etud in etuds:
etudid = etud["etudid"] etudid = etud["etudid"]
etud["dept"] = scu.get_dept_id() etud["dept"] = g.scodoc_dept
adrs = adresse_list(cnx, {"etudid": etudid}) adrs = adresse_list(cnx, {"etudid": etudid})
if not adrs: if not adrs:
# certains "vieux" etudiants n'ont pas d'adresse # certains "vieux" etudiants n'ont pas d'adresse

View File

@ -195,7 +195,7 @@ def _build_results_list(dpv_by_sem, etuds_infos):
int(sem["annee_debut"]), sem["mois_debut_ord"] int(sem["annee_debut"]), sem["mois_debut_ord"]
) )
r["sid"] = "{} {} {}".format( r["sid"] = "{} {} {}".format(
sem["sem_id_txt"], scu.get_dept_id(), sem["modalite"] sem["sem_id_txt"], g.scodoc_dept, sem["modalite"]
) )
rows.append(r) rows.append(r)

View File

@ -145,12 +145,13 @@ def list_inscrits_date(sem):
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor) cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
sem["date_debut_iso"] = ndb.DateDMYtoISO(sem["date_debut"]) sem["date_debut_iso"] = ndb.DateDMYtoISO(sem["date_debut"])
cursor.execute( cursor.execute(
"""select I.etudid """SELECT I.etudid
from notes_formsemestre_inscription I, notes_formsemestre S FROM notes_formsemestre_inscription I, notes_formsemestre S
where I.formsemestre_id = S.formsemestre_id WHERE I.formsemestre_id = S.id
and I.formsemestre_id != %(formsemestre_id)s AND S.id != %(formsemestre_id)s
and S.date_debut <= %(date_debut_iso)s AND S.date_debut <= %(date_debut_iso)s
and S.date_fin >= %(date_debut_iso)s""", AND S.date_fin >= %(date_debut_iso)s
""",
sem, sem,
) )
return [x[0] for x in cursor.fetchall()] return [x[0] for x in cursor.fetchall()]

View File

@ -52,6 +52,8 @@ from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY
from reportlab.lib import styles from reportlab.lib import styles
from reportlab.lib.pagesizes import letter, A4, landscape from reportlab.lib.pagesizes import letter, A4, landscape
from flask import g
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
from app.scodoc.sco_utils import ( from app.scodoc.sco_utils import (
CONFIG, CONFIG,
@ -203,7 +205,7 @@ class ScolarsPageTemplate(PageTemplate):
# XXX COPIED from sco_pvpdf, to be refactored (no time now) # XXX COPIED from sco_pvpdf, to be refactored (no time now)
# Search background in dept specific dir, then in global config dir # Search background in dept specific dir, then in global config dir
for image_dir in ( for image_dir in (
SCODOC_LOGOS_DIR + "/logos_" + scu.get_dept_id() + "/", SCODOC_LOGOS_DIR + "/logos_" + g.scodoc_dept + "/",
SCODOC_LOGOS_DIR + "/", # global logos SCODOC_LOGOS_DIR + "/", # global logos
): ):
for suffix in LOGOS_IMAGES_ALLOWED_TYPES: for suffix in LOGOS_IMAGES_ALLOWED_TYPES:

View File

@ -1,7 +1,7 @@
# -*- mode: python -*- # -*- mode: python -*-
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""Definition of ScoDoc 8 permissions """Definition of ScoDoc permissions
used by auth used by auth
""" """

View File

@ -43,18 +43,18 @@ Les images sont servies par ScoDoc, via la méthode getphotofile?etudid=xxx
""" """
import datetime
import glob
import io import io
import os import os
import time
import datetime
import random import random
import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse import requests
import time
import traceback import traceback
from PIL import Image as PILImage from PIL import Image as PILImage
import glob from flask import request, g
from flask import request
from config import Config from config import Config
@ -318,7 +318,7 @@ def get_new_filename(etudid):
"""Constructs a random filename to store a new image. """Constructs a random filename to store a new image.
The path is constructed as: Fxx/etudid The path is constructed as: Fxx/etudid
""" """
dept = scu.get_dept_id() dept = g.scodoc_dept
return find_new_dir() + dept + "_" + str(etudid) return find_new_dir() + dept + "_" + str(etudid)
@ -351,17 +351,15 @@ def copy_portal_photo_to_fs(etud):
f = None f = None
try: try:
log("copy_portal_photo_to_fs: getting %s" % url) log("copy_portal_photo_to_fs: getting %s" % url)
f = six.moves.urllib.request.urlopen( r = requests.get(url, timeout=portal_timeout)
url, timeout=portal_timeout
) # python >= 2.7
except: except:
log("download failed: exception:\n%s" % traceback.format_exc()) log("download failed: exception:\n%s" % traceback.format_exc())
log("called from:\n" + "".join(traceback.format_stack())) log("called from:\n" + "".join(traceback.format_stack()))
return None, "%s: erreur chargement de %s" % (etud["nomprenom"], url) return None, "%s: erreur chargement de %s" % (etud["nomprenom"], url)
if not f: if r.status_code != 200:
log("download failed") log("download failed")
return None, "%s: erreur chargement de %s" % (etud["nomprenom"], url) return None, "%s: erreur chargement de %s" % (etud["nomprenom"], url)
data = f.read() data = r.content # image bytes
try: try:
status, diag = store_photo(etud, data) status, diag = store_photo(etud, data)
except: except:

View File

@ -27,20 +27,19 @@
"""Liaison avec le portail ENT (qui donne accès aux infos Apogée) """Liaison avec le portail ENT (qui donne accès aux infos Apogée)
""" """
import datetime
import os, time import os
import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error import time
import urllib
import xml import xml
import xml.sax.saxutils import xml.sax.saxutils
import xml.dom.minidom import xml.dom.minidom
import datetime
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
from app.scodoc.notes_log import log from app.scodoc.notes_log import log
from app.scodoc.sco_exceptions import ScoValueError from app.scodoc.sco_exceptions import ScoValueError
from app.scodoc import sco_preferences from app.scodoc import sco_preferences
import six import six
from six.moves import range
SCO_CACHE_ETAPE_FILENAME = os.path.join(scu.SCO_TMP_DIR, "last_etapes.xml") SCO_CACHE_ETAPE_FILENAME = os.path.join(scu.SCO_TMP_DIR, "last_etapes.xml")
@ -52,17 +51,19 @@ def has_portal():
class PortalInterface(object): class PortalInterface(object):
def __init__(self): def __init__(self):
self.warning = False self.first_time = True
def get_portal_url(self): def get_portal_url(self):
"URL of portal" "URL of portal"
portal_url = sco_preferences.get_preference("portal_url") portal_url = sco_preferences.get_preference("portal_url")
if not self.warning: if portal_url and not portal_url.endswith("/"):
portal_url += "/"
if self.first_time:
if portal_url: if portal_url:
log("Portal URL=%s" % portal_url) log("Portal URL=%s" % portal_url)
else: else:
log("Portal not configured") log("Portal not configured")
self.warning = True self.first_time = False
return portal_url return portal_url
def get_etapes_url(self): def get_etapes_url(self):
@ -157,14 +158,10 @@ def get_inscrits_etape(code_etape, anneeapogee=None, ntrials=2):
req = ( req = (
etud_url etud_url
+ "?" + "?"
+ six.moves.urllib.parse.urlencode( + urllib.parse.urlencode((("etape", code_etape), ("annee", anneeapogee)))
(("etape", code_etape), ("annee", anneeapogee))
)
) )
else: else:
req = ( req = etud_url + "?" + urllib.parse.urlencode((("etape", code_etape),))
etud_url + "?" + six.moves.urllib.parse.urlencode((("etape", code_etape),))
)
actual_timeout = float(portal_timeout) / ntrials actual_timeout = float(portal_timeout) / ntrials
if portal_timeout > 0: if portal_timeout > 0:
actual_timeout = max(1, actual_timeout) actual_timeout = max(1, actual_timeout)
@ -209,7 +206,7 @@ def query_apogee_portal(**args):
# XXX TODO : va poser problème pour la page modif données étudiants : A VOIR # XXX TODO : va poser problème pour la page modif données étudiants : A VOIR
return [] return []
portal_timeout = sco_preferences.get_preference("portal_timeout") portal_timeout = sco_preferences.get_preference("portal_timeout")
req = etud_url + "?" + six.moves.urllib.parse.urlencode(list(args.items())) req = etud_url + "?" + urllib.parse.urlencode(list(args.items()))
doc = scu.query_portal(req, timeout=portal_timeout) # sco_utils doc = scu.query_portal(req, timeout=portal_timeout) # sco_utils
return xml_to_list_of_dicts(doc, req=req) return xml_to_list_of_dicts(doc, req=req)
@ -242,7 +239,7 @@ def xml_to_list_of_dicts(doc, req=None):
) )
infos = [] infos = []
try: try:
if dom.childNodes[0].nodeName != u"etudiants": if dom.childNodes[0].nodeName != "etudiants":
raise ValueError raise ValueError
etudiants = dom.getElementsByTagName("etudiant") etudiants = dom.getElementsByTagName("etudiant")
for etudiant in etudiants: for etudiant in etudiants:
@ -252,9 +249,7 @@ def xml_to_list_of_dicts(doc, req=None):
if e.nodeType == e.ELEMENT_NODE: if e.nodeType == e.ELEMENT_NODE:
childs = e.childNodes childs = e.childNodes
if len(childs): if len(childs):
d[str(e.nodeName)] = childs[0].nodeValue.encode( d[str(e.nodeName)] = childs[0].nodeValue
scu.SCO_ENCODING
)
infos.append(d) infos.append(d)
except: except:
log("*** invalid XML response from Etudiant Web Service") log("*** invalid XML response from Etudiant Web Service")
@ -320,7 +315,7 @@ def get_etud_apogee(code_nip):
if not etud_url: if not etud_url:
return {} return {}
portal_timeout = sco_preferences.get_preference("portal_timeout") portal_timeout = sco_preferences.get_preference("portal_timeout")
req = etud_url + "?" + six.moves.urllib.parse.urlencode((("nip", code_nip),)) req = etud_url + "?" + urllib.parse.urlencode((("nip", code_nip),))
doc = scu.query_portal(req, timeout=portal_timeout) doc = scu.query_portal(req, timeout=portal_timeout)
d = _normalize_apo_fields(xml_to_list_of_dicts(doc, req=req)) d = _normalize_apo_fields(xml_to_list_of_dicts(doc, req=req))
if not d: if not d:
@ -356,13 +351,13 @@ def _parse_etapes_from_xml(doc):
# parser XML # parser XML
dom = xml.dom.minidom.parseString(doc) dom = xml.dom.minidom.parseString(doc)
infos = {} infos = {}
if dom.childNodes[0].nodeName != u"etapes": if dom.childNodes[0].nodeName != "etapes":
raise ValueError raise ValueError
if xml_etapes_by_dept: if xml_etapes_by_dept:
# Ancien format XML avec des sections par departement: # Ancien format XML avec des sections par departement:
for d in dom.childNodes[0].childNodes: for d in dom.childNodes[0].childNodes:
if d.nodeType == d.ELEMENT_NODE: if d.nodeType == d.ELEMENT_NODE:
dept = d.nodeName.encode(scu.SCO_ENCODING) dept = d.nodeName
_xml_list_codes(infos, dept, d.childNodes) _xml_list_codes(infos, dept, d.childNodes)
else: else:
# Toutes les étapes: # Toutes les étapes:
@ -411,8 +406,8 @@ def get_etapes_apogee():
def _xml_list_codes(target_dict, dept, nodes): def _xml_list_codes(target_dict, dept, nodes):
for e in nodes: for e in nodes:
if e.nodeType == e.ELEMENT_NODE: if e.nodeType == e.ELEMENT_NODE:
intitule = e.childNodes[0].nodeValue.encode(scu.SCO_ENCODING) intitule = e.childNodes[0].nodeValue
code = e.attributes["code"].value.encode(scu.SCO_ENCODING) code = e.attributes["code"].value
if dept in target_dict: if dept in target_dict:
target_dict[dept][code] = intitule target_dict[dept][code] = intitule
else: else:
@ -558,9 +553,7 @@ def get_maquette_apogee(etape="", annee_scolaire=""):
req = ( req = (
maquette_url maquette_url
+ "?" + "?"
+ six.moves.urllib.parse.urlencode( + urllib.parse.urlencode((("etape", etape), ("annee", annee_scolaire)))
(("etape", etape), ("annee", annee_scolaire))
)
) )
doc = scu.query_portal(req, timeout=portal_timeout) doc = scu.query_portal(req, timeout=portal_timeout)
return doc return doc

View File

@ -200,7 +200,7 @@ class CourrierIndividuelTemplate(PageTemplate):
self.logo_header = None self.logo_header = None
# Search logos in dept specific dir, then in global scu.CONFIG dir # Search logos in dept specific dir, then in global scu.CONFIG dir
for image_dir in ( for image_dir in (
scu.SCODOC_LOGOS_DIR + "/logos_" + scu.get_dept_id(), scu.SCODOC_LOGOS_DIR + "/logos_" + g.scodoc_dept,
scu.SCODOC_LOGOS_DIR, # global logos scu.SCODOC_LOGOS_DIR, # global logos
): ):
for suffix in scu.LOGOS_IMAGES_ALLOWED_TYPES: for suffix in scu.LOGOS_IMAGES_ALLOWED_TYPES:

View File

@ -958,7 +958,6 @@ def saisie_notes(evaluation_id, group_ids=[], REQUEST=None):
) )
if form is None: if form is None:
log(f"redirecting to {destination}") log(f"redirecting to {destination}")
stop
return flask.redirect(destination) return flask.redirect(destination)
H.append(form) H.append(form)
# #

View File

@ -114,10 +114,11 @@ def formsemestre_synchro_etuds(
if anneeapogee: if anneeapogee:
base_url += "&anneeapogee=%s" % anneeapogee base_url += "&anneeapogee=%s" % anneeapogee
if anneeapogee == None: # année d'inscription par défaut if anneeapogee is None: # année d'inscription par défaut
anneeapogee = str( anneeapogee = scu.annee_scolaire_debut(
scu.annee_scolaire_debut(sem["annee_debut"], sem["mois_debut_ord"]) sem["annee_debut"], sem["mois_debut_ord"]
) )
anneeapogee = str(anneeapogee)
if type(etuds) == type(""): if type(etuds) == type(""):
etuds = etuds.split(",") # vient du form de confirmation etuds = etuds.split(",") # vient du form de confirmation
@ -132,7 +133,7 @@ def formsemestre_synchro_etuds(
inscrits_without_key_all, inscrits_without_key_all,
etudsapo_ident, etudsapo_ident,
) = list_synch(sem, anneeapogee=anneeapogee) ) = list_synch(sem, anneeapogee=anneeapogee)
breakpoint()
if export_cat_xls: if export_cat_xls:
filename = export_cat_xls filename = export_cat_xls
xls = build_page( xls = build_page(
@ -155,6 +156,7 @@ def formsemestre_synchro_etuds(
read_only=read_only, read_only=read_only,
) )
else: else:
breakpoint()
etuds_set = set(etuds) etuds_set = set(etuds)
a_importer = a_importer.intersection(etuds_set) a_importer = a_importer.intersection(etuds_set)
a_desinscrire = inscrits_set - etuds_set a_desinscrire = inscrits_set - etuds_set
@ -499,7 +501,7 @@ def list_all(etudsapo_set):
# d'interrogation par etudiant. # d'interrogation par etudiant.
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor) cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
cursor.execute("select " + EKEY_SCO + ", etudid from identite") cursor.execute("SELECT " + EKEY_SCO + ", id AS etudid FROM identite")
key2etudid = dict([(x[0], x[1]) for x in cursor.fetchall()]) key2etudid = dict([(x[0], x[1]) for x in cursor.fetchall()])
all_set = set(key2etudid.keys()) all_set = set(key2etudid.keys())
@ -654,7 +656,7 @@ def do_import_etuds_from_portal(sem, a_importer, etudsapo_ident, REQUEST):
{"etudid": etudid}, {"etudid": etudid},
) )
cursor.execute( cursor.execute(
"delete from identite where etudid=%(etudid)s", {"etudid": etudid} "delete from identite where id=%(etudid)s", {"etudid": etudid}
) )
cnx.commit() cnx.commit()
log("do_import_etuds_from_portal: re-raising exception") log("do_import_etuds_from_portal: re-raising exception")

View File

@ -317,9 +317,6 @@ TYPES_ADMISSION = (TYPE_ADMISSION_DEFAULT, "APB", "APB-PC", "CEF", "Direct")
BULLETINS_VERSIONS = ("short", "selectedevals", "long") BULLETINS_VERSIONS = ("short", "selectedevals", "long")
# Support for ScoDoc7 compatibility # Support for ScoDoc7 compatibility
def get_dept_id():
"acronyme du dept courant"
return g.scodoc_dept # en scodoc 8.1 #sco8
def ScoURL(): def ScoURL():

View File

@ -53,6 +53,7 @@ def make_random_etape_etuds(etape, annee):
"""Liste d'etudiants d'une etape""" """Liste d'etudiants d'une etape"""
random.seed(etape + annee) random.seed(etape + annee)
nb = random.randint(0, 50) nb = random.randint(0, 50)
print(f"generating {nb} students")
L = [] L = []
for i in range(nb): for i in range(nb):
if i % 2: if i % 2: