Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into ScoDoc8

This commit is contained in:
viennet 2021-01-08 22:25:29 +01:00
commit 8018a0b092
13 changed files with 81 additions and 33 deletions

View File

@ -936,7 +936,7 @@ class ZAbsences(
moduleimpl_id = None moduleimpl_id = None
groups_infos = sco_groups_view.DisplayedGroupsInfos( groups_infos = sco_groups_view.DisplayedGroupsInfos(
self, group_ids, REQUEST=REQUEST self, group_ids, moduleimpl_id=moduleimpl_id, REQUEST=REQUEST
) )
if not groups_infos.members: if not groups_infos.members:
return ( return (

View File

@ -764,14 +764,11 @@ UE11 Découverte métiers <span class="ue_code">(code UCOD46, 16 ECTS, Apo <span
# Semestres dans lesquel il est inscrit # Semestres dans lesquel il est inscrit
ins = self.Notes.do_formsemestre_inscription_list({"etudid": etudid}) ins = self.Notes.do_formsemestre_inscription_list({"etudid": etudid})
etud["ins"] = ins etud["ins"] = ins
now = time.strftime("%Y-%m-%d")
sems = [] sems = []
cursem = None # semestre "courant" ou il est inscrit cursem = None # semestre "courant" ou il est inscrit
for i in ins: for i in ins:
sem = sco_formsemestre.get_formsemestre(self, i["formsemestre_id"]) sem = sco_formsemestre.get_formsemestre(self, i["formsemestre_id"])
debut = DateDMYtoISO(sem["date_debut"]) if sco_formsemestre.sem_est_courant(self, sem):
fin = DateDMYtoISO(sem["date_fin"])
if debut <= now and now <= fin:
cursem = sem cursem = sem
curi = i curi = i
sem["ins"] = i sem["ins"] = i

View File

@ -693,7 +693,7 @@ class SeqGenTable:
def excel(self): def excel(self):
"""Export des genTables dans un unique fichier excel avec plusieurs feuilles tagguées""" """Export des genTables dans un unique fichier excel avec plusieurs feuilles tagguées"""
book = sco_excel.Workbook() # Le fichier xls en devenir book = sco_excel.Workbook() # pylint: disable=no-member
for (_, gt) in self.genTables.items(): for (_, gt) in self.genTables.items():
gt.excel(wb=book) # Ecrit dans un fichier excel gt.excel(wb=book) # Ecrit dans un fichier excel
return book.savetostr() return book.savetostr()

View File

@ -198,7 +198,7 @@ class BulletinGenerator:
document.addPageTemplates( document.addPageTemplates(
ScolarsPageTemplate( ScolarsPageTemplate(
document, document,
self.context, context=self.context,
author="%s %s (E. Viennet) [%s]" author="%s %s (E. Viennet) [%s]"
% (SCONAME, SCOVERSION, self.description), % (SCONAME, SCOVERSION, self.description),
title="Bulletin %s de %s" title="Bulletin %s de %s"

View File

@ -86,7 +86,7 @@ def pdfassemblebulletins(
document.addPageTemplates( document.addPageTemplates(
ScolarsPageTemplate( ScolarsPageTemplate(
document, document,
context, context=context,
author="%s %s (E. Viennet)" % (SCONAME, SCOVERSION), author="%s %s (E. Viennet)" % (SCONAME, SCOVERSION),
title="Bulletin %s" % bul_title, title="Bulletin %s" % bul_title,
subject="Bulletin de note", subject="Bulletin de note",

View File

@ -374,8 +374,8 @@ def sem_in_semestre_scolaire(context, sem, year=False, saison=0, REQUEST=None):
si saison non spécifiée: année complète si saison non spécifiée: année complète
pivot de saison au 1er décembre pivot de saison au 1er décembre
XXX TODO: la période (ici appelée "saison" devrait être éditable XXX TODO: la période (ici appelée "saison" devrait être éditable
manuellement dans le formsemestre_edit afin de couvrir els cas particulier manuellement dans le formsemestre_edit afin de couvrir les cas particulier
comme un semestre S2 qui commecerait en décembre... voire novembre. comme un semestre S2 qui commencerait en décembre... voire novembre.
) )
""" """
if not year: if not year:
@ -429,6 +429,14 @@ def sem_une_annee(context, sem):
return debut == fin return debut == fin
def sem_est_courant(context, sem):
"""Vrai si la date actuelle (now) est dans le semestre (les dates de début et fin sont incluses)"""
now = time.strftime("%Y-%m-%d")
debut = DateDMYtoISO(sem["date_debut"])
fin = DateDMYtoISO(sem["date_fin"])
return (debut <= now) and (now <= fin)
def scodoc_get_all_unlocked_sems(context): def scodoc_get_all_unlocked_sems(context):
"""Liste de tous les semestres non verrouillés de tous les départements""" """Liste de tous les semestres non verrouillés de tous les départements"""
depts = context.list_depts() depts = context.list_depts()

View File

@ -298,6 +298,7 @@ class DisplayedGroupsInfos:
formsemestre_id=None, formsemestre_id=None,
etat=None, etat=None,
select_all_when_unspecified=False, select_all_when_unspecified=False,
moduleimpl_id=None, # used to find formsemestre when unspecified
REQUEST=None, REQUEST=None,
): ):
# log('DisplayedGroupsInfos %s' % group_ids) # log('DisplayedGroupsInfos %s' % group_ids)
@ -306,10 +307,15 @@ class DisplayedGroupsInfos:
group_ids = [group_ids] # cas ou un seul parametre, pas de liste group_ids = [group_ids] # cas ou un seul parametre, pas de liste
else: else:
group_ids = [] group_ids = []
if not formsemestre_id and moduleimpl_id:
mods = context.Notes.do_moduleimpl_list(moduleimpl_id=moduleimpl_id)
if len(mods) != 1:
raise ValueError("invalid moduleimpl_id")
formsemestre_id = mods[0]["formsemestre_id"]
if not group_ids: # appel sans groupe (eg page accueil) if not group_ids: # appel sans groupe (eg page accueil)
if not formsemestre_id: if not formsemestre_id:
raise Exception("missing parameter") # formsemestre_id or group_ids raise Exception("missing parameter formsemestre_id or group_ids")
if select_all_when_unspecified: if select_all_when_unspecified:
group_ids = [sco_groups.get_default_group(context, formsemestre_id)] group_ids = [sco_groups.get_default_group(context, formsemestre_id)]
else: else:
@ -856,7 +862,9 @@ def tab_photos_html(context, groups_infos, etat=None, REQUEST=None):
return sco_trombino.trombino_html(context, groups_infos, REQUEST=REQUEST) return sco_trombino.trombino_html(context, groups_infos, REQUEST=REQUEST)
def form_choix_jour_saisie_hebdo(context, groups_infos, REQUEST=None): def form_choix_jour_saisie_hebdo(
context, groups_infos, moduleimpl_id=None, REQUEST=None
):
"""Formulaire choix jour semaine pour saisie.""" """Formulaire choix jour semaine pour saisie."""
authuser = REQUEST.AUTHENTICATED_USER authuser = REQUEST.AUTHENTICATED_USER
if not authuser.has_permission(ScoAbsChange, context): if not authuser.has_permission(ScoAbsChange, context):
@ -871,7 +879,10 @@ def form_choix_jour_saisie_hebdo(context, groups_infos, REQUEST=None):
) )
FA.append('<input type="hidden" name="datefin" value="%(date_fin)s"/>' % sem) FA.append('<input type="hidden" name="datefin" value="%(date_fin)s"/>' % sem)
FA.append(groups_infos.get_form_elem()) FA.append(groups_infos.get_form_elem())
if moduleimpl_id:
FA.append(
'<input type="hidden" name="moduleimpl_id" value="%s"/>' % moduleimpl_id
)
FA.append('<input type="hidden" name="destination" value=""/>') FA.append('<input type="hidden" name="destination" value=""/>')
FA.append( FA.append(

View File

@ -43,14 +43,13 @@ import sco_formsemestre
import sco_formsemestre_status import sco_formsemestre_status
from sco_formsemestre_status import makeMenu from sco_formsemestre_status import makeMenu
import sco_compute_moy import sco_compute_moy
import ZAbsences
# ported from old DTML code in oct 2009 # ported from old DTML code in oct 2009
# menu evaluation dans moduleimpl # menu evaluation dans moduleimpl
def moduleimpl_evaluation_menu(context, evaluation_id, nbnotes=0, REQUEST=None): def moduleimpl_evaluation_menu(context, evaluation_id, nbnotes=0, REQUEST=None):
"Menu avec actions sur une evaluation" "Menu avec actions sur une evaluation"
authuser = REQUEST.AUTHENTICATED_USER
E = context.do_evaluation_list({"evaluation_id": evaluation_id})[0] E = context.do_evaluation_list({"evaluation_id": evaluation_id})[0]
modimpl = context.do_moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0] modimpl = context.do_moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0]
@ -224,7 +223,6 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
) )
H.append("</td></tr>") H.append("</td></tr>")
else: else:
t0, t1 = "<em>règle de calcul standard</em>", ""
H.append( H.append(
'<tr><td colspan="4"><em title="mode de calcul de la moyenne du module">règle de calcul standard</em>' '<tr><td colspan="4"><em title="mode de calcul de la moyenne du module">règle de calcul standard</em>'
) )
@ -235,10 +233,21 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
) )
H.append("</td></tr>") H.append("</td></tr>")
H.append( H.append(
'<tr><td colspan="2"><a class="stdlink" href="view_module_abs?moduleimpl_id=%s">Absences</a>&nbsp;' '<tr><td colspan="4"><span class="moduleimpl_abs_link"><a class="stdlink" href="view_module_abs?moduleimpl_id=%s">Absences dans ce module</a></span>'
% moduleimpl_id % moduleimpl_id
) )
H.append("</table>") # Adapté à partir d'une suggestion de DS (Le Havre)
# Liens saisies absences seulement si permission et date courante dans le semestre
if authuser.has_permission(
ScoAbsChange, context
) and sco_formsemestre.sem_est_courant(context, sem):
datelundi = ZAbsences.ddmmyyyy(time.strftime("%d/%m/%Y")).prev_monday()
H.append(
'<span class="moduleimpl_abs_link"><a class="stdlink" href="Absences/SignaleAbsenceGrHebdo?formsemestre_id=%s&moduleimpl_id=%s&datelundi=%s">Saisie Absences hebdo.</a></span>'
% (formsemestre_id, moduleimpl_id, datelundi)
)
H.append("</td></tr></table>")
# #
if has_expression and nt.expr_diagnostics: if has_expression and nt.expr_diagnostics:
H.append( H.append(
@ -478,7 +487,11 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
% etat % etat
) )
if etat["moy"]: if etat["moy"]:
H.append("%s / %g" % (etat["moy"], eval["note_max"])) H.append("<b>%s / %g</b>" % (etat["moy"], eval["note_max"]))
H.append(
"""&nbsp; (<a href="evaluation_listenotes?evaluation_id=%s">afficher</a>)"""
% (eval["evaluation_id"],)
)
else: else:
H.append( H.append(
"""<a class="redlink" href="saisie_notes?evaluation_id=%s">saisir notes</a>""" """<a class="redlink" href="saisie_notes?evaluation_id=%s">saisir notes</a>"""
@ -488,7 +501,6 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
# #
if etat["nb_notes"] == 0: if etat["nb_notes"] == 0:
H.append("""<tr class="%s"><td colspan="8">&nbsp;""" % tr_class) H.append("""<tr class="%s"><td colspan="8">&nbsp;""" % tr_class)
# XXX
H.append("""</td></tr>""") H.append("""</td></tr>""")
else: # il y a deja des notes saisies else: # il y a deja des notes saisies
gr_moyennes = etat["gr_moyennes"] gr_moyennes = etat["gr_moyennes"]
@ -505,7 +517,7 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
if gr_moyenne["gr_nb_notes"] > 0: if gr_moyenne["gr_nb_notes"] > 0:
H.append("%(gr_moy)s" % gr_moyenne) H.append("%(gr_moy)s" % gr_moyenne)
H.append( H.append(
"""&nbsp; (<a href="evaluation_listenotes?tf-submitted=1&amp;evaluation_id=%s&amp;group_ids%%3Alist=%s">%s</a> notes""" """&nbsp; (<a href="evaluation_listenotes?tf-submitted=1&amp;evaluation_id=%s&amp;group_ids%%3Alist=%s">%s notes</a>"""
% ( % (
eval["evaluation_id"], eval["evaluation_id"],
gr_moyenne["group_id"], gr_moyenne["group_id"],

View File

@ -31,7 +31,10 @@
Tout accès à ReportLab doit donc être précédé d'un PDFLOCK.acquire() Tout accès à ReportLab doit donc être précédé d'un PDFLOCK.acquire()
et terminé par un PDFLOCK.release() et terminé par un PDFLOCK.release()
""" """
import time, cStringIO import time
import cStringIO
import re
import os
from types import StringType from types import StringType
import unicodedata import unicodedata
import traceback import traceback
@ -49,9 +52,12 @@ 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 sco_utils import * import sco_utils as scu
from sco_utils import CONFIG, SCO_ENCODING, SCODOC_LOGOS_DIR, LOGOS_IMAGES_ALLOWED_TYPES
from notes_log import log from notes_log import log
from sco_exceptions import ScoGenError
from SuppressAccents import suppression_diacritics from SuppressAccents import suppression_diacritics
import VERSION
from VERSION import SCOVERSION, SCONAME from VERSION import SCOVERSION, SCONAME
PAGE_HEIGHT = defaultPageSize[1] PAGE_HEIGHT = defaultPageSize[1]
@ -107,7 +113,7 @@ def makeParas(txt, style, suppress_empty=False):
if suppress_empty: if suppress_empty:
r = [] r = []
for para in paras: for para in paras:
m = re.match("\s*<\s*para.*>\s*(.*)\s*<\s*/\s*para\s*>\s*", para) m = re.match(r"\s*<\s*para.*>\s*(.*)\s*<\s*/\s*para\s*>\s*", para)
if not m: if not m:
r.append(para) # not a paragraph, keep it r.append(para) # not a paragraph, keep it
else: else:
@ -229,7 +235,10 @@ class ScolarsPageTemplate(PageTemplate):
# ---- Logo: a small image, positionned at top left of the page # ---- Logo: a small image, positionned at top left of the page
if self.logo is not None: if self.logo is not None:
# draws the logo if it exists # draws the logo if it exists
((width, height), image) = self.logo ( # pylint: disable=unpacking-non-sequence
(width, height),
image,
) = self.logo
canvas.drawImage(image, inch, doc.pagesize[1] - inch, width, height) canvas.drawImage(image, inch, doc.pagesize[1] - inch, width, height)
# ---- Filigranne (texte en diagonal en haut a gauche de chaque page) # ---- Filigranne (texte en diagonal en haut a gauche de chaque page)
@ -300,7 +309,7 @@ def pdf_basic_page(
document.addPageTemplates( document.addPageTemplates(
ScolarsPageTemplate( ScolarsPageTemplate(
document, document,
context, context=context,
title=title, title=title,
author="%s %s (E. Viennet)" % (SCONAME, SCOVERSION), author="%s %s (E. Viennet)" % (SCONAME, SCOVERSION),
footer_template="Edité par %(scodoc_name)s le %(day)s/%(month)s/%(year)s à %(hour)sh%(minute)s", footer_template="Edité par %(scodoc_name)s le %(day)s/%(month)s/%(year)s à %(hour)sh%(minute)s",

View File

@ -366,7 +366,7 @@ def _trombino_pdf(context, groups_infos, REQUEST):
document.addPageTemplates( document.addPageTemplates(
ScolarsPageTemplate( ScolarsPageTemplate(
document, document,
context, context=context,
preferences=context.get_preferences(sem["formsemestre_id"]), preferences=context.get_preferences(sem["formsemestre_id"]),
) )
) )
@ -515,7 +515,7 @@ def _listeappel_photos_pdf(context, groups_infos, REQUEST):
document.addPageTemplates( document.addPageTemplates(
ScolarsPageTemplate( ScolarsPageTemplate(
document, document,
context, context=context,
preferences=context.get_preferences(sem["formsemestre_id"]), preferences=context.get_preferences(sem["formsemestre_id"]),
) )
) )

View File

@ -276,7 +276,9 @@ def pdf_trombino_tours(
filename = "trombino-%s-%s.pdf" % (DeptName, groups_infos.groups_filename) filename = "trombino-%s-%s.pdf" % (DeptName, groups_infos.groups_filename)
document = BaseDocTemplate(report) document = BaseDocTemplate(report)
document.addPageTemplates( document.addPageTemplates(
ScolarsPageTemplate(document, preferences=context.get_preferences()) ScolarsPageTemplate(
document, context=context, preferences=context.get_preferences()
)
) )
document.build(objects) document.build(objects)
data = report.getvalue() data = report.getvalue()
@ -468,7 +470,9 @@ def pdf_feuille_releve_absences(
else: else:
document = BaseDocTemplate(report, pagesize=taille) document = BaseDocTemplate(report, pagesize=taille)
document.addPageTemplates( document.addPageTemplates(
ScolarsPageTemplate(document, preferences=context.get_preferences()) ScolarsPageTemplate(
document, context=context, preferences=context.get_preferences()
)
) )
document.build(objects) document.build(objects)
data = report.getvalue() data = report.getvalue()

View File

@ -17,6 +17,7 @@ usage() {
set -euo pipefail set -euo pipefail
cd /opt/scodoc/Products/ScoDoc || exit 2 cd /opt/scodoc/Products/ScoDoc || exit 2
source config/config.sh
source config/utils.sh source config/utils.sh
if [ $# -lt 1 ] if [ $# -lt 1 ]
@ -38,7 +39,11 @@ shift
if [ "$recreate_dept" = 1 ] if [ "$recreate_dept" = 1 ]
then then
cfg_pathname="${SCODOC_VAR_DIR}/config/depts/$DEPT".cfg
if [ -e "$cfg_pathname" ]
then
(cd config || terminate "no config directory"; ./delete_dept.sh -n "$DEPT") || terminate "error deleting dept $DEPT" (cd config || terminate "no config directory"; ./delete_dept.sh -n "$DEPT") || terminate "error deleting dept $DEPT"
fi
(cd config || terminate "no config directory"; ./create_dept.sh -n "$DEPT") || terminate "error creating dept $DEPT" (cd config || terminate "no config directory"; ./create_dept.sh -n "$DEPT") || terminate "error creating dept $DEPT"
# systemctl start scodoc # systemctl start scodoc
fi fi

View File

@ -1223,7 +1223,7 @@ ul.ue_inscr_list li.etud {
} }
#grouplists table { #grouplists table {
//border: 1px solid black; /*border: 1px solid black;*/
border-spacing: 1px; border-spacing: 1px;
} }
@ -1236,7 +1236,9 @@ div.moduleimpl_tableaubord {
padding: 7px; padding: 7px;
border: 2px solid gray; border: 2px solid gray;
} }
span.moduleimpl_abs_link {
padding-right: 2em;
}
.moduleimpl_evaluations_top_links { .moduleimpl_evaluations_top_links {
font-size: 80%; font-size: 80%;
margin-bottom: 3px; margin-bottom: 3px;