WIP: refactoring

This commit is contained in:
Emmanuel Viennet 2021-06-13 18:29:53 +02:00
parent 7b61b25ff1
commit d586359e3d
64 changed files with 780 additions and 3474 deletions

View File

@ -240,14 +240,14 @@ def students_import_excel(
dest = "formsemestre_status?formsemestre_id=%s" % formsemestre_id dest = "formsemestre_status?formsemestre_id=%s" % formsemestre_id
else: else:
dest = context.NotesURL() dest = context.NotesURL()
H = [context.sco_header(REQUEST, page_title="Import etudiants")] H = [html_sco_header.sco_header(context, REQUEST, page_title="Import etudiants")]
H.append("<ul>") H.append("<ul>")
for d in diag: for d in diag:
H.append("<li>%s</li>" % d) H.append("<li>%s</li>" % d)
H.append("</ul>") H.append("</ul>")
H.append("<p>Import terminé !</p>") H.append("<p>Import terminé !</p>")
H.append('<p><a class="stdlink" href="%s">Continuer</a></p>' % dest) H.append('<p><a class="stdlink" href="%s">Continuer</a></p>' % dest)
return "\n".join(H) + context.sco_footer(REQUEST) return "\n".join(H) + html_sco_header.sco_footer(context, REQUEST)
def scolars_import_excel_file( def scolars_import_excel_file(

View File

@ -55,12 +55,12 @@ import sco_entreprises
def entreprise_header(context, REQUEST=None, page_title=""): def entreprise_header(context, REQUEST=None, page_title=""):
"common header for all Entreprises pages" "common header for all Entreprises pages"
return context.sco_header(REQUEST, container=context, page_title=page_title) return html_sco_header.sco_header(context, REQUEST, container=context, page_title=page_title)
def entreprise_footer(context, REQUEST): def entreprise_footer(context, REQUEST):
"common entreprise footer" "common entreprise footer"
return context.sco_footer(REQUEST) return html_sco_header.sco_footer(context, REQUEST)
class ZEntreprises( class ZEntreprises(

View File

@ -74,6 +74,7 @@ except:
import sco_utils as scu import sco_utils as scu
import VERSION import VERSION
import mails
from notes_log import log from notes_log import log
import sco_find_etud import sco_find_etud
import sco_users import sco_users
@ -94,6 +95,7 @@ from sco_permissions import (
ScoSuperAdmin, ScoSuperAdmin,
) )
from sco_exceptions import ScoValueError, ScoLockedFormError, ScoGenError, AccessDenied from sco_exceptions import ScoValueError, ScoLockedFormError, ScoGenError, AccessDenied
import html_sco_header
class ZScoDoc(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Implicit): class ZScoDoc(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Implicit):
@ -264,8 +266,8 @@ class ZScoDoc(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Imp
if not REQUEST.AUTHENTICATED_USER.has_role("Manager"): if not REQUEST.AUTHENTICATED_USER.has_role("Manager"):
raise AccessDenied("vous n'avez pas le droit d'effectuer cette opération") raise AccessDenied("vous n'avez pas le droit d'effectuer cette opération")
H = [ H = [
self.scodoc_top_html_header( html_sco_header.scodoc_top_html_header(
REQUEST, page_title="ScoDoc: changement mot de passe" self, REQUEST, page_title="ScoDoc: changement mot de passe"
) )
] ]
if message: if message:
@ -367,54 +369,6 @@ class ZScoDoc(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Imp
+ """ supprimé du serveur web (la base de données n'est pas affectée)!</p><p><a href="/ScoDoc">Continuer</a></p>""" + """ supprimé du serveur web (la base de données n'est pas affectée)!</p><p><a href="/ScoDoc">Continuer</a></p>"""
) )
_top_level_css = """
<style type="text/css">
</style>"""
_html_begin = """<?xml version="1.0" encoding="%(encoding)s"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>%(page_title)s</title>
<meta http-equiv="Content-Type" content="text/html; charset=%(encoding)s" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta name="LANG" content="fr" />
<meta name="DESCRIPTION" content="ScoDoc" />
<link type="text/css" rel="stylesheet" href="/ScoDoc/static/libjs/jquery-ui-1.10.4.custom/css/smoothness/jquery-ui-1.10.4.custom.min.css" />
<link href="/ScoDoc/static/css/scodoc.css" rel="stylesheet" type="text/css" />
<link href="/ScoDoc/static/css/menu.css" rel="stylesheet" type="text/css" />
<script language="javascript" type="text/javascript" src="/ScoDoc/static/libjs/menu.js"></script>
<script language="javascript" type="text/javascript" src="/ScoDoc/static/libjs/sorttable.js"></script>
<script language="javascript" type="text/javascript" src="/ScoDoc/static/libjs/bubble.js"></script>
<script type="text/javascript">
window.onload=function(){enableTooltips("gtrcontent")};
</script>
<script language="javascript" type="text/javascript" src="/ScoDoc/static/jQuery/jquery.js"></script>
<script language="javascript" type="text/javascript" src="/ScoDoc/static/jQuery/jquery-migrate-1.2.0.min.js"></script>
<script language="javascript" type="text/javascript" src="/ScoDoc/static/libjs/jquery.field.min.js"></script>
<script language="javascript" type="text/javascript" src="/ScoDoc/static/libjs/jquery-ui-1.10.4.custom/js/jquery-ui-1.10.4.custom.min.js"></script>
<script language="javascript" type="text/javascript" src="/ScoDoc/static/libjs/qtip/jquery.qtip-3.0.3.min.js"></script>
<link type="text/css" rel="stylesheet" href="/ScoDoc/static/libjs/qtip/jquery.qtip-3.0.3.min.css" />
<script language="javascript" type="text/javascript" src="/ScoDoc/static/js/scodoc.js"></script>
<script language="javascript" type="text/javascript" src="/ScoDoc/static/js/etud_info.js"></script>
"""
def scodoc_top_html_header(self, REQUEST, page_title="ScoDoc"):
H = [
self._html_begin
% {"page_title": "ScoDoc: bienvenue", "encoding": scu.SCO_ENCODING},
self._top_level_css,
"""</head><body class="gtrcontent" id="gtrcontent">""",
scu.CUSTOM_HTML_HEADER_CNX,
]
return "\n".join(H)
security.declareProtected("View", "index_html") security.declareProtected("View", "index_html")
def index_html(self, REQUEST=None, message=None): def index_html(self, REQUEST=None, message=None):
@ -441,7 +395,9 @@ class ZScoDoc(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Imp
pass pass
H = [ H = [
self.scodoc_top_html_header(REQUEST, page_title="ScoDoc: bienvenue"), html_sco_header.scodoc_top_html_header(
self, REQUEST, page_title="ScoDoc: bienvenue"
),
self._check_users_folder(REQUEST=REQUEST), # ensure setup is done self._check_users_folder(REQUEST=REQUEST), # ensure setup is done
] ]
if message: if message:
@ -573,7 +529,7 @@ E. Viennet (Université Paris 13).</p>
) )
H = [ H = [
self.standard_html_header(REQUEST), html_sco_header.standard_html_header(),
"""<div style="margin: 1em;"> """<div style="margin: 1em;">
<h2>Scolarité du département %s</h2>""" <h2>Scolarité du département %s</h2>"""
% deptfoldername, % deptfoldername,
@ -587,7 +543,7 @@ E. Viennet (Université Paris 13).</p>
</div> </div>
""" """
% self.ScoDocURL(), % self.ScoDocURL(),
self.standard_html_footer(REQUEST), html_sco_header.standard_html_footer(),
] ]
return "\n".join(H) return "\n".join(H)
@ -626,69 +582,6 @@ E. Viennet (Université Paris 13).</p>
return "<!-- query string -->\n" + "\n".join(H) return "<!-- query string -->\n" + "\n".join(H)
security.declareProtected("View", "standard_html_header")
def standard_html_header(self, REQUEST=None):
"""Standard HTML header for pages outside depts"""
# not used in ZScolar, see sco_header
return """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>
<title>ScoDoc: accueil</title>
<META http-equiv="Content-Type" content="text/html; charset=%s">
<META http-equiv="Content-Style-Type" content="text/css">
<META name="LANG" content="fr">
<META name="DESCRIPTION" content="ScoDoc: gestion scolarite">
<link HREF="/ScoDoc/static/css/scodoc.css" rel="stylesheet" type="text/css"/>
</head><body>%s""" % (
scu.SCO_ENCODING,
scu.CUSTOM_HTML_HEADER_CNX,
)
security.declareProtected("View", "standard_html_footer")
def standard_html_footer(self, REQUEST=None):
"""Le pied de page HTML de la page d'accueil."""
return """<p class="footer">
Problème de connexion (identifiant, mot de passe): <em>contacter votre responsable ou chef de département</em>.</p>
<p>Probl&egrave;mes et suggestions sur le logiciel: <a href="mailto:%s">%s</a></p>
<p><em>ScoDoc est un logiciel libre développé par Emmanuel Viennet.</em></p>
</body></html>""" % (
scu.SCO_USERS_LIST,
scu.SCO_USERS_LIST,
)
# sendEmail is not used through the web
def sendEmail(self, msg):
# sends an email to the address using the mailhost, if there is one
try:
mail_host = self.MailHost
except:
log("warning: sendEmail: no MailHost found !")
return
# a failed notification shouldn't cause a Zope error on a site.
try:
mail_host.send(msg.as_string())
log("sendEmail: ok")
except Exception as e:
log("sendEmail: exception while sending message")
log(e)
pass
def sendEmailFromException(self, msg):
# Send email by hand, as it seems to be not possible to use Zope Mail Host
# from an exception handler (see https://bugs.launchpad.net/zope2/+bug/246748)
log("sendEmailFromException")
try:
p = os.popen("sendmail -t", "w") # old brute force method
p.write(msg.as_string())
exitcode = p.close()
if exitcode:
log("sendmail exit code: %s" % exitcode)
except:
log("an exception occurred sending mail")
security.declareProtected("View", "standard_error_message") security.declareProtected("View", "standard_error_message")
def standard_error_message( def standard_error_message(
@ -736,18 +629,18 @@ Problème de connexion (identifiant, mot de passe): <em>contacter votre responsa
elif error_type in ("ScoValueError", "FormatError"): elif error_type in ("ScoValueError", "FormatError"):
# Not a bug, presents a gentle message to the user: # Not a bug, presents a gentle message to the user:
H = [ H = [
self.standard_html_header(REQUEST), html_sco_header.standard_html_header(),
"""<h2>Erreur !</h2><p>%s</p>""" % error_value, """<h2>Erreur !</h2><p>%s</p>""" % error_value,
] ]
if error_value.dest_url: if error_value.dest_url:
H.append('<p><a href="%s">Continuer</a></p>' % error_value.dest_url) H.append('<p><a href="%s">Continuer</a></p>' % error_value.dest_url)
H.append(self.standard_html_footer(REQUEST)) H.append(html_sco_header.standard_html_footer())
return "\n".join(H) return "\n".join(H)
else: # Other exceptions, try carefully to build an error page... else: # Other exceptions, try carefully to build an error page...
# log('exc A') # log('exc A')
H = [] H = []
try: try:
H.append(self.standard_html_header(REQUEST)) H.append(html_sco_header.standard_html_header())
except: except:
pass pass
H.append( H.append(
@ -785,7 +678,7 @@ Problème de connexion (identifiant, mot de passe): <em>contacter votre responsa
% params % params
) )
try: try:
H.append(self.standard_html_footer(REQUEST)) H.append(html_sco_header.standard_html_footer())
except: except:
log("no footer found for error page") log("no footer found for error page")
pass pass
@ -801,81 +694,12 @@ ErrorType: %(error_type)s
% params % params
) )
self.send_debug_alert(txt, REQUEST=REQUEST) mails.send_debug_alert(context, txt, REQUEST=REQUEST)
# --- # ---
log("done processing exception") log("done processing exception")
# log( '\n page=\n' + '\n'.join(H) ) # log( '\n page=\n' + '\n'.join(H) )
return "\n".join(H) return "\n".join(H)
def _report_request(self, REQUEST, fmt="txt"):
"""string describing current request for bug reports"""
QUERY_STRING = REQUEST.get("QUERY_STRING", "")
if QUERY_STRING:
QUERY_STRING = "?" + QUERY_STRING
if fmt == "txt":
REFERER = REQUEST.get("HTTP_REFERER", "")
HTTP_USER_AGENT = REQUEST.get("HTTP_USER_AGENT", "")
else:
REFERER = "na"
HTTP_USER_AGENT = "na"
params = dict(
AUTHENTICATED_USER=REQUEST.get("AUTHENTICATED_USER", ""),
dt=time.asctime(),
URL=REQUEST.get("URL", ""),
QUERY_STRING=QUERY_STRING,
METHOD=REQUEST.get("REQUEST_METHOD", ""),
REFERER=REFERER,
HTTP_USER_AGENT=HTTP_USER_AGENT,
form=REQUEST.get("form", ""),
HTTP_X_FORWARDED_FOR=REQUEST.get("HTTP_X_FORWARDED_FOR", ""),
svn_version=scu.get_svn_version(self.file_path),
SCOVERSION=VERSION.SCOVERSION,
)
txt = (
"""
Version: %(SCOVERSION)s
User: %(AUTHENTICATED_USER)s
Date: %(dt)s
URL: %(URL)s%(QUERY_STRING)s
Method: %(METHOD)s
REFERER: %(REFERER)s
Form: %(form)s
Origin: %(HTTP_X_FORWARDED_FOR)s
Agent: %(HTTP_USER_AGENT)s
"""
% params
)
if fmt == "html":
txt = txt.replace("\n", "<br/>")
return txt
security.declareProtected(
ScoSuperAdmin, "send_debug_alert"
) # not called through the web
def send_debug_alert(self, txt, REQUEST=None):
"""Send an alert email (bug report) to ScoDoc developpers"""
if not scu.SCO_EXC_MAIL:
log("send_debug_alert: email disabled")
return
if REQUEST:
txt = self._report_request(REQUEST) + txt
URL = REQUEST.get("URL", "")
else:
URL = "send_debug_alert"
msg = MIMEMultipart()
subj = Header("[scodoc] exc %s" % URL, scu.SCO_ENCODING)
msg["Subject"] = subj
recipients = [scu.SCO_EXC_MAIL]
msg["To"] = " ,".join(recipients)
msg["From"] = "scodoc-alert"
msg.epilogue = ""
msg.attach(MIMEText(txt, "plain", scu.SCO_ENCODING))
self.sendEmailFromException(msg)
log("Sent mail alert:\n" + txt)
security.declareProtected("View", "scodoc_admin") security.declareProtected("View", "scodoc_admin")
def scodoc_admin(self, REQUEST=None): def scodoc_admin(self, REQUEST=None):
@ -885,7 +709,9 @@ Agent: %(HTTP_USER_AGENT)s
return e return e
H = [ H = [
self.scodoc_top_html_header(REQUEST, page_title="ScoDoc: bienvenue"), html_sco_header.scodoc_top_html_header(
self, REQUEST, page_title="ScoDoc: bienvenue"
),
""" """
<h3>Administration ScoDoc</h3> <h3>Administration ScoDoc</h3>

File diff suppressed because it is too large Load Diff

View File

@ -626,7 +626,7 @@ class GenTable:
if with_html_headers: if with_html_headers:
H.append( H.append(
self.html_header self.html_header
or context.sco_header( or html_sco_header.sco_header(context,
REQUEST, REQUEST,
page_title=page_title, page_title=page_title,
javascripts=javascripts, javascripts=javascripts,
@ -637,7 +637,7 @@ class GenTable:
H.append(html_title) H.append(html_title)
H.append(self.html()) H.append(self.html())
if with_html_headers: if with_html_headers:
H.append(context.sco_footer(REQUEST)) H.append(html_sco_header.sco_footer(context, REQUEST))
return "\n".join(H) return "\n".join(H)
elif format == "pdf": elif format == "pdf":
objects = self.pdf() objects = self.pdf()

View File

@ -28,6 +28,7 @@
import cgi import cgi
import sco_utils as scu import sco_utils as scu
import VERSION
""" """
HTML Header/Footer for ScoDoc pages HTML Header/Footer for ScoDoc pages
@ -49,6 +50,87 @@ BOOTSTRAP_MULTISELECT_CSS = [
"libjs/bootstrap-multiselect/bootstrap-multiselect.css", "libjs/bootstrap-multiselect/bootstrap-multiselect.css",
] ]
def standard_html_header():
"""Standard HTML header for pages outside depts"""
# not used in ZScolar, see sco_header
return """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>
<title>ScoDoc: accueil</title>
<META http-equiv="Content-Type" content="text/html; charset=%s">
<META http-equiv="Content-Style-Type" content="text/css">
<META name="LANG" content="fr">
<META name="DESCRIPTION" content="ScoDoc: gestion scolarite">
<link HREF="/ScoDoc/static/css/scodoc.css" rel="stylesheet" type="text/css"/>
</head><body>%s""" % (
scu.SCO_ENCODING,
scu.CUSTOM_HTML_HEADER_CNX,
)
def standard_html_footer():
"""Le pied de page HTML de la page d'accueil."""
return """<p class="footer">
Problème de connexion (identifiant, mot de passe): <em>contacter votre responsable ou chef de département</em>.</p>
<p>Probl&egrave;mes et suggestions sur le logiciel: <a href="mailto:%s">%s</a></p>
<p><em>ScoDoc est un logiciel libre développé par Emmanuel Viennet.</em></p>
</body></html>""" % (
scu.SCO_USERS_LIST,
scu.SCO_USERS_LIST,
)
_TOP_LEVEL_CSS = """
<style type="text/css">
</style>"""
_HTML_BEGIN = """<?xml version="1.0" encoding="%(encoding)s"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>%(page_title)s</title>
<meta http-equiv="Content-Type" content="text/html; charset=%(encoding)s" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta name="LANG" content="fr" />
<meta name="DESCRIPTION" content="ScoDoc" />
<link type="text/css" rel="stylesheet" href="/ScoDoc/static/libjs/jquery-ui-1.10.4.custom/css/smoothness/jquery-ui-1.10.4.custom.min.css" />
<link href="/ScoDoc/static/css/scodoc.css" rel="stylesheet" type="text/css" />
<link href="/ScoDoc/static/css/menu.css" rel="stylesheet" type="text/css" />
<script language="javascript" type="text/javascript" src="/ScoDoc/static/libjs/menu.js"></script>
<script language="javascript" type="text/javascript" src="/ScoDoc/static/libjs/sorttable.js"></script>
<script language="javascript" type="text/javascript" src="/ScoDoc/static/libjs/bubble.js"></script>
<script type="text/javascript">
window.onload=function(){enableTooltips("gtrcontent")};
</script>
<script language="javascript" type="text/javascript" src="/ScoDoc/static/jQuery/jquery.js"></script>
<script language="javascript" type="text/javascript" src="/ScoDoc/static/jQuery/jquery-migrate-1.2.0.min.js"></script>
<script language="javascript" type="text/javascript" src="/ScoDoc/static/libjs/jquery.field.min.js"></script>
<script language="javascript" type="text/javascript" src="/ScoDoc/static/libjs/jquery-ui-1.10.4.custom/js/jquery-ui-1.10.4.custom.min.js"></script>
<script language="javascript" type="text/javascript" src="/ScoDoc/static/libjs/qtip/jquery.qtip-3.0.3.min.js"></script>
<link type="text/css" rel="stylesheet" href="/ScoDoc/static/libjs/qtip/jquery.qtip-3.0.3.min.css" />
<script language="javascript" type="text/javascript" src="/ScoDoc/static/js/scodoc.js"></script>
<script language="javascript" type="text/javascript" src="/ScoDoc/static/js/etud_info.js"></script>
"""
def scodoc_top_html_header(context, REQUEST, page_title="ScoDoc"):
H = [
HTML_BEGIN % {"page_title": "ScoDoc: bienvenue", "encoding": scu.SCO_ENCODING},
TOP_LEVEL_CSS,
"""</head><body class="gtrcontent" id="gtrcontent">""",
scu.CUSTOM_HTML_HEADER_CNX,
]
return "\n".join(H)
# Header: # Header:
def sco_header( def sco_header(
context, context,
@ -72,14 +154,6 @@ def sco_header(
): ):
"Main HTML page header for ScoDoc" "Main HTML page header for ScoDoc"
# If running for first time, initialize roles and permissions
try:
ri = context.roles_initialized
except:
ri = None # old instances does not have this attribute
if ri == "0":
context._setup_initial_roles_and_permissions()
# context est une instance de ZScolar. container est une instance qui "acquiert" ZScolar # context est une instance de ZScolar. container est une instance qui "acquiert" ZScolar
if container: if container:
context = container # je pense que cela suffit pour ce qu'on veut. context = container # je pense que cela suffit pour ce qu'on veut.
@ -93,7 +167,7 @@ def sco_header(
head_message = REQUEST.form["head_message"] head_message = REQUEST.form["head_message"]
params = { params = {
"page_title": page_title or context.title_or_id(), "page_title": page_title or VERSION.SCONAME,
"no_side_bar": no_side_bar, "no_side_bar": no_side_bar,
"ScoURL": context.ScoURL(), "ScoURL": context.ScoURL(),
"encoding": scu.SCO_ENCODING, "encoding": scu.SCO_ENCODING,
@ -228,7 +302,7 @@ def sco_header(
H.append(scu.CUSTOM_HTML_HEADER) H.append(scu.CUSTOM_HTML_HEADER)
# #
if not no_side_bar: if not no_side_bar:
H.append(context.sidebar(REQUEST)) H.append(html_sidebar.sidebar(context, REQUEST))
H.append("""<div class="gtrcontent" id="gtrcontent">""") H.append("""<div class="gtrcontent" id="gtrcontent">""")
# #
# Barre menu semestre: # Barre menu semestre:
@ -264,4 +338,28 @@ def sco_footer(context, REQUEST=None):
) )
def html_sem_header(
context,
REQUEST,
title,
sem=None,
with_page_header=True,
with_h2=True,
page_title=None,
**args
):
"Titre d'une page semestre avec lien vers tableau de bord"
# sem now unused and thus optional...
if with_page_header:
h = sco_header(
context, REQUEST, page_title="%s" % (page_title or title), **args
)
else:
h = ""
if with_h2:
return h + """<h2 class="formsemestre">%s</h2>""" % (title)
else:
return h
from sco_formsemestre_status import formsemestre_page_title from sco_formsemestre_status import formsemestre_page_title

View File

@ -53,7 +53,7 @@ def sidebar_common(context, REQUEST=None):
'<a class="scodoc_title" href="about">ScoDoc</a>', '<a class="scodoc_title" href="about">ScoDoc</a>',
'<div id="authuser"><a id="authuserlink" href="%(ScoURL)s/Users/userinfo">%(authuser)s</a><br/><a id="deconnectlink" href="%(ScoURL)s/acl_users/logout">déconnexion</a></div>' '<div id="authuser"><a id="authuserlink" href="%(ScoURL)s/Users/userinfo">%(authuser)s</a><br/><a id="deconnectlink" href="%(ScoURL)s/acl_users/logout">déconnexion</a></div>'
% params, % params,
context.sidebar_dept(REQUEST), sidebar_dept(context, REQUEST),
"""<h2 class="insidebar">Scolarit&eacute;</h2> """<h2 class="insidebar">Scolarit&eacute;</h2>
<a href="%(ScoURL)s" class="sidebar">Semestres</a> <br/> <a href="%(ScoURL)s" class="sidebar">Semestres</a> <br/>
<a href="%(NotesURL)s" class="sidebar">Programmes</a> <br/> <a href="%(NotesURL)s" class="sidebar">Programmes</a> <br/>

141
app/scodoc/mails.py Normal file
View File

@ -0,0 +1,141 @@
# -*- mode: python -*-
# -*- coding: utf-8 -*-
##############################################################################
#
# Gestion scolarite IUT
#
# Copyright (c) 1999 - 2021 Emmanuel Viennet. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Emmanuel Viennet emmanuel.viennet@viennet.net
#
##############################################################################
"""Gestion des emails
"""
# XXX WIP: à ré-écrire pour ScoDoc 8 (étaient des méthodes de ZScoDoc)
import os
from email.MIMEMultipart import ( # pylint: disable=no-name-in-module,import-error
MIMEMultipart,
)
from email.MIMEText import MIMEText # pylint: disable=no-name-in-module,import-error
from email.MIMEBase import MIMEBase # pylint: disable=no-name-in-module,import-error
from email.Header import Header # pylint: disable=no-name-in-module,import-error
from email import Encoders # pylint: disable=no-name-in-module,import-error
import sco_utils as scu
from notes_log import log
def sendEmail(context, msg): # TODO A REECRIRE ScoDoc8
"""Send an email to the address using the mailhost, if there is one."""
raise NotImplementedError()
try:
mail_host = context.MailHost
except:
log("warning: sendEmail: no MailHost found !")
return
# a failed notification shouldn't cause a Zope error on a site.
try:
mail_host.send(msg.as_string())
log("sendEmail: ok")
except Exception as e:
log("sendEmail: exception while sending message")
log(e)
pass
def sendEmailFromException(context, msg):
# Send email by hand, as it seems to be not possible to use Zope Mail Host
# from an exception handler (see https://bugs.launchpad.net/zope2/+bug/246748)
log("sendEmailFromException")
try:
p = os.popen("sendmail -t", "w") # old brute force method
p.write(msg.as_string())
exitcode = p.close()
if exitcode:
log("sendmail exit code: %s" % exitcode)
except:
log("an exception occurred sending mail")
def send_debug_alert(context, txt, REQUEST=None):
"""Send an alert email (bug report) to ScoDoc developpers"""
if not scu.SCO_EXC_MAIL:
log("send_debug_alert: email disabled")
return
if REQUEST:
txt = _report_request(context, REQUEST) + txt
URL = REQUEST.get("URL", "")
else:
URL = "send_debug_alert"
msg = MIMEMultipart()
subj = Header("[scodoc] exc %s" % URL, scu.SCO_ENCODING)
msg["Subject"] = subj
recipients = [scu.SCO_EXC_MAIL]
msg["To"] = " ,".join(recipients)
msg["From"] = "scodoc-alert"
msg.epilogue = ""
msg.attach(MIMEText(txt, "plain", scu.SCO_ENCODING))
sendEmailFromException(context, msg)
log("Sent mail alert:\n" + txt)
def _report_request(context, REQUEST, fmt="txt"):
"""string describing current request for bug reports"""
QUERY_STRING = REQUEST.get("QUERY_STRING", "")
if QUERY_STRING:
QUERY_STRING = "?" + QUERY_STRING
if fmt == "txt":
REFERER = REQUEST.get("HTTP_REFERER", "")
HTTP_USER_AGENT = REQUEST.get("HTTP_USER_AGENT", "")
else:
REFERER = "na"
HTTP_USER_AGENT = "na"
params = dict(
AUTHENTICATED_USER=REQUEST.get("AUTHENTICATED_USER", ""),
dt=time.asctime(),
URL=REQUEST.get("URL", ""),
QUERY_STRING=QUERY_STRING,
METHOD=REQUEST.get("REQUEST_METHOD", ""),
REFERER=REFERER,
HTTP_USER_AGENT=HTTP_USER_AGENT,
form=REQUEST.get("form", ""),
HTTP_X_FORWARDED_FOR=REQUEST.get("HTTP_X_FORWARDED_FOR", ""),
svn_version=scu.get_svn_version(context.file_path),
SCOVERSION=VERSION.SCOVERSION,
)
txt = (
"""
Version: %(SCOVERSION)s
User: %(AUTHENTICATED_USER)s
Date: %(dt)s
URL: %(URL)s%(QUERY_STRING)s
Method: %(METHOD)s
REFERER: %(REFERER)s
Form: %(form)s
Origin: %(HTTP_X_FORWARDED_FOR)s
Agent: %(HTTP_USER_AGENT)s
"""
% params
)
if fmt == "html":
txt = txt.replace("\n", "<br/>")
return txt

View File

@ -21,6 +21,8 @@ from email.MIMEBase import MIMEBase # pylint: disable=no-name-in-module,import-
from email.Header import Header # pylint: disable=no-name-in-module,import-error from email.Header import Header # pylint: disable=no-name-in-module,import-error
from email import Encoders # pylint: disable=no-name-in-module,import-error from email import Encoders # pylint: disable=no-name-in-module,import-error
import mails
# Simple & stupid file logguer, used only to debug # Simple & stupid file logguer, used only to debug
# (logging to SQL is done in scolog) # (logging to SQL is done in scolog)
@ -120,7 +122,7 @@ def sendAlarm(context, subj, txt):
msg.epilogue = "" msg.epilogue = ""
txt = MIMEText(txt, "plain", sco_utils.SCO_ENCODING) txt = MIMEText(txt, "plain", sco_utils.SCO_ENCODING)
msg.attach(txt) msg.attach(txt)
context.sendEmail(msg) mails.sendEmail(context, msg)
# Debug: log call stack # Debug: log call stack

View File

@ -309,7 +309,7 @@ class NotesTable:
# fallback *** should not occur *** # fallback *** should not occur ***
# txt = '\nkey missing in cmprows !!!\nx=%s\ny=%s\n' % (str(x),str(y)) # txt = '\nkey missing in cmprows !!!\nx=%s\ny=%s\n' % (str(x),str(y))
# txt += '\nrangalpha=%s' % str(rangalpha) + '\n\nT=%s' % str(T) # txt += '\nrangalpha=%s' % str(rangalpha) + '\n\nT=%s' % str(T)
# context.send_debug_alert(txt, REQUEST=None) # send_debug_alert(txt, REQUEST=None)
# return cmp(x,y) # return cmp(x,y)
T.sort(cmprows) T.sort(cmprows)

View File

@ -54,7 +54,7 @@ import pe_avislatex
def _pe_view_sem_recap_form(context, formsemestre_id, REQUEST=None): def _pe_view_sem_recap_form(context, formsemestre_id, REQUEST=None):
H = [ H = [
context.sco_header(REQUEST, page_title="Avis de poursuite d'études"), html_sco_header.sco_header(context, REQUEST, page_title="Avis de poursuite d'études"),
"""<h2 class="formsemestre">Génération des avis de poursuites d'études</h2> """<h2 class="formsemestre">Génération des avis de poursuites d'études</h2>
<p class="help"> <p class="help">
Cette fonction génère un ensemble de fichiers permettant d'éditer des avis de poursuites d'études. Cette fonction génère un ensemble de fichiers permettant d'éditer des avis de poursuites d'études.
@ -77,7 +77,7 @@ def _pe_view_sem_recap_form(context, formsemestre_id, REQUEST=None):
formsemestre_id=formsemestre_id formsemestre_id=formsemestre_id
), ),
] ]
return "\n".join(H) + context.sco_footer(REQUEST) return "\n".join(H) + html_sco_header.sco_footer(context, REQUEST)
def pe_view_sem_recap( def pe_view_sem_recap(

View File

@ -37,7 +37,7 @@ from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText from email.mime.text import MIMEText
from email.header import Header from email.header import Header
import mails
import notesdb as ndb import notesdb as ndb
import sco_utils as scu import sco_utils as scu
from notes_log import log from notes_log import log
@ -114,7 +114,7 @@ def abs_notify_send(
for email in destinations: for email in destinations:
del msg["To"] del msg["To"]
msg["To"] = email msg["To"] = email
context.sendEmail(msg) mails.sendEmail(context, msg)
ndb.SimpleQuery( ndb.SimpleQuery(
context, context,
"""insert into absences_notifications (etudid, email, nbabs, nbabsjust, formsemestre_id) values (%(etudid)s, %(email)s, %(nbabs)s, %(nbabsjust)s, %(formsemestre_id)s)""", """insert into absences_notifications (etudid, email, nbabs, nbabsjust, formsemestre_id) values (%(etudid)s, %(email)s, %(nbabs)s, %(nbabsjust)s, %(formsemestre_id)s)""",

View File

@ -116,7 +116,7 @@ def doSignaleAbsence(
if modimpl["moduleimpl_id"] == moduleimpl_id: if modimpl["moduleimpl_id"] == moduleimpl_id:
M = "dans le module %s" % modimpl["module"]["code"] M = "dans le module %s" % modimpl["module"]["code"]
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, page_title="Signalement d'une absence pour %(nomprenom)s" % etud REQUEST, page_title="Signalement d'une absence pour %(nomprenom)s" % etud
), ),
"""<h2>Signalement d'absences</h2>""", """<h2>Signalement d'absences</h2>""",
@ -140,7 +140,7 @@ def doSignaleAbsence(
% etud % etud
) )
H.append(sco_find_etud.form_search_etud(context, REQUEST)) H.append(sco_find_etud.form_search_etud(context, REQUEST))
H.append(context.sco_footer(REQUEST)) H.append(html_sco_header.sco_footer(context, REQUEST))
return "\n".join(H) return "\n".join(H)
@ -203,7 +203,7 @@ def SignaleAbsenceEtud(context, REQUEST=None): # etudid implied
menu_module += """</select></p>""" menu_module += """</select></p>"""
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, page_title="Signalement d'une absence pour %(nomprenom)s" % etud REQUEST, page_title="Signalement d'une absence pour %(nomprenom)s" % etud
), ),
"""<table><tr><td> """<table><tr><td>
@ -258,7 +258,7 @@ Raison: <input type="text" name="description" size="42"/> (optionnel)
"menu_module": menu_module, "menu_module": menu_module,
"disabled": "disabled" if disabled else "", "disabled": "disabled" if disabled else "",
}, },
context.sco_footer(REQUEST), html_sco_header.sco_footer(context, REQUEST),
] ]
return "\n".join(H) return "\n".join(H)
@ -316,7 +316,7 @@ def doJustifAbsence(
nbadded += 1 nbadded += 1
# #
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, page_title="Justification d'une absence pour %(nomprenom)s" % etud REQUEST, page_title="Justification d'une absence pour %(nomprenom)s" % etud
), ),
"""<h2>Justification d'absences</h2>""", """<h2>Justification d'absences</h2>""",
@ -342,7 +342,7 @@ def doJustifAbsence(
% etud % etud
) )
H.append(sco_find_etud.form_search_etud(context, REQUEST)) H.append(sco_find_etud.form_search_etud(context, REQUEST))
H.append(context.sco_footer(REQUEST)) H.append(html_sco_header.sco_footer(context, REQUEST))
return "\n".join(H) return "\n".join(H)
@ -352,7 +352,7 @@ def JustifAbsenceEtud(context, REQUEST=None): # etudid implied
etud = context.getEtudInfo(filled=1, REQUEST=REQUEST)[0] etud = context.getEtudInfo(filled=1, REQUEST=REQUEST)[0]
etudid = etud["etudid"] etudid = etud["etudid"]
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, page_title="Justification d'une absence pour %(nomprenom)s" % etud REQUEST, page_title="Justification d'une absence pour %(nomprenom)s" % etud
), ),
"""<table><tr><td> """<table><tr><td>
@ -396,7 +396,7 @@ Raison: <input type="text" name="description" size="42"/> (optionnel)
</form> """ </form> """
% etud, % etud,
context.sco_footer(REQUEST), html_sco_header.sco_footer(context, REQUEST),
] ]
return "\n".join(H) return "\n".join(H)
@ -421,7 +421,7 @@ def doAnnuleAbsence(
nbadded += 1 nbadded += 1
# #
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, page_title="Annulation d'une absence pour %(nomprenom)s" % etud REQUEST, page_title="Annulation d'une absence pour %(nomprenom)s" % etud
), ),
"""<h2>Annulation d'absences pour %(nomprenom)s</h2>""" % etud, """<h2>Annulation d'absences pour %(nomprenom)s</h2>""" % etud,
@ -447,7 +447,7 @@ autre absence pour <b>%(nomprenom)s</b></a></li>
% etud % etud
) )
H.append(sco_find_etud.form_search_etud(context, REQUEST)) H.append(sco_find_etud.form_search_etud(context, REQUEST))
H.append(context.sco_footer(REQUEST)) H.append(html_sco_header.sco_footer(context, REQUEST))
return "\n".join(H) return "\n".join(H)
@ -458,7 +458,7 @@ def AnnuleAbsenceEtud(context, REQUEST=None): # etudid implied
etudid = etud["etudid"] etudid = etud["etudid"]
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, page_title="Annulation d'une absence pour %(nomprenom)s" % etud REQUEST, page_title="Annulation d'une absence pour %(nomprenom)s" % etud
), ),
"""<table><tr><td> """<table><tr><td>
@ -532,7 +532,7 @@ def AnnuleAbsenceEtud(context, REQUEST=None): # etudid implied
</form> </form>
</td></tr></table>""" </td></tr></table>"""
% etud, % etud,
context.sco_footer(REQUEST), html_sco_header.sco_footer(context, REQUEST),
] ]
return "\n".join(H) return "\n".join(H)
@ -557,7 +557,7 @@ def doAnnuleJustif(
nbadded += 1 nbadded += 1
# #
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, REQUEST,
page_title="Annulation d'une justification pour %(nomprenom)s" % etud, page_title="Annulation d'une justification pour %(nomprenom)s" % etud,
), ),
@ -584,7 +584,7 @@ autre absence pour <b>%(nomprenom)s</b></a></li>
% etud % etud
) )
H.append(sco_find_etud.form_search_etud(context, REQUEST)) H.append(sco_find_etud.form_search_etud(context, REQUEST))
H.append(context.sco_footer(REQUEST)) H.append(html_sco_header.sco_footer(context, REQUEST))
return "\n".join(H) return "\n".join(H)
@ -592,7 +592,7 @@ def EtatAbsences(context, REQUEST=None):
"""Etat des absences: choix du groupe""" """Etat des absences: choix du groupe"""
# crude portage from 1999 DTML # crude portage from 1999 DTML
H = [ H = [
context.sco_header(REQUEST, page_title="Etat des absences"), html_sco_header.sco_header(context, REQUEST, page_title="Etat des absences"),
"""<h2>Etat des absences pour un groupe</h2> """<h2>Etat des absences pour un groupe</h2>
<form action="EtatAbsencesGr" method="GET">""", <form action="EtatAbsencesGr" method="GET">""",
formChoixSemestreGroupe(context), formChoixSemestreGroupe(context),
@ -609,7 +609,7 @@ def EtatAbsences(context, REQUEST=None):
</td></tr></table> </td></tr></table>
</form>""" </form>"""
% (scu.AnneeScolaire(REQUEST), datetime.datetime.now().strftime("%d/%m/%Y")), % (scu.AnneeScolaire(REQUEST), datetime.datetime.now().strftime("%d/%m/%Y")),
context.sco_footer(REQUEST), html_sco_header.sco_footer(context, REQUEST),
] ]
return "\n".join(H) return "\n".join(H)
@ -672,7 +672,7 @@ def CalAbs(context, REQUEST=None): # etud implied
# #
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, REQUEST,
page_title="Calendrier des absences de %(nomprenom)s" % etud, page_title="Calendrier des absences de %(nomprenom)s" % etud,
cssstyles=["css/calabs.css"], cssstyles=["css/calabs.css"],
@ -712,7 +712,7 @@ def CalAbs(context, REQUEST=None): # etud implied
H.append("selected") H.append("selected")
H.append(""">%s</option>""" % y) H.append(""">%s</option>""" % y)
H.append("""</select></form>""") H.append("""</select></form>""")
H.append(context.sco_footer(REQUEST)) H.append(html_sco_header.sco_footer(context, REQUEST))
return "\n".join(H) return "\n".join(H)
@ -777,7 +777,7 @@ def ListeAbsEtud(
# Mise en forme HTML: # Mise en forme HTML:
H = [] H = []
H.append( H.append(
context.sco_header(REQUEST, page_title="Absences de %s" % etud["nomprenom"]) html_sco_header.sco_header(context, REQUEST, page_title="Absences de %s" % etud["nomprenom"])
) )
H.append( H.append(
"""<h2>Absences de %s (à partir du %s)</h2>""" """<h2>Absences de %s (à partir du %s)</h2>"""
@ -795,7 +795,7 @@ def ListeAbsEtud(
H.append(tab_absjust.html()) H.append(tab_absjust.html())
else: else:
H.append("""<h3>Pas d'absences justifiées</h3>""") H.append("""<h3>Pas d'absences justifiées</h3>""")
return "\n".join(H) + context.sco_footer(REQUEST) return "\n".join(H) + html_sco_header.sco_footer(context, REQUEST)
elif format == "text": elif format == "text":
T = [] T = []
@ -828,7 +828,7 @@ def absences_index_html(context, REQUEST=None):
authuser = REQUEST.AUTHENTICATED_USER authuser = REQUEST.AUTHENTICATED_USER
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, REQUEST,
page_title="Gestion des absences", page_title="Gestion des absences",
cssstyles=["css/calabs.css"], cssstyles=["css/calabs.css"],
@ -877,7 +877,7 @@ saisir les absences de toute cette semaine.</p>
"""<p class="scoinfo">Vous n'avez pas l'autorisation d'ajouter, justifier ou supprimer des absences.</p>""" """<p class="scoinfo">Vous n'avez pas l'autorisation d'ajouter, justifier ou supprimer des absences.</p>"""
) )
H.append(context.sco_footer(REQUEST)) H.append(html_sco_header.sco_footer(context, REQUEST))
return "\n".join(H) return "\n".join(H)

View File

@ -65,7 +65,7 @@ _help_txt = """
def apo_compare_csv_form(context, REQUEST=None): def apo_compare_csv_form(context, REQUEST=None):
"""Form: submit 2 CSV files to compare them.""" """Form: submit 2 CSV files to compare them."""
H = [ H = [
context.sco_header(REQUEST, page_title="Comparaison de fichiers Apogée"), html_sco_header.sco_header(context, REQUEST, page_title="Comparaison de fichiers Apogée"),
"""<h2>Comparaison de fichiers Apogée</h2> """<h2>Comparaison de fichiers Apogée</h2>
<form id="apo_csv_add" action="apo_compare_csv" method="post" enctype="multipart/form-data"> <form id="apo_csv_add" action="apo_compare_csv" method="post" enctype="multipart/form-data">
""", """,
@ -84,7 +84,7 @@ def apo_compare_csv_form(context, REQUEST=None):
<input type="submit" value="Comparer ces fichiers"/> <input type="submit" value="Comparer ces fichiers"/>
</div> </div>
</form>""", </form>""",
context.sco_footer(REQUEST), html_sco_header.sco_footer(context, REQUEST),
] ]
return "\n".join(H) return "\n".join(H)
@ -95,14 +95,14 @@ def apo_compare_csv(context, A_file, B_file, autodetect=True, REQUEST=None):
B = _load_apo_data(B_file, autodetect=autodetect) B = _load_apo_data(B_file, autodetect=autodetect)
H = [ H = [
context.sco_header(REQUEST, page_title="Comparaison de fichiers Apogée"), html_sco_header.sco_header(context, REQUEST, page_title="Comparaison de fichiers Apogée"),
"<h2>Comparaison de fichiers Apogée</h2>", "<h2>Comparaison de fichiers Apogée</h2>",
_help_txt, _help_txt,
'<div class="apo_compare_csv">', '<div class="apo_compare_csv">',
_apo_compare_csv(context, A, B, REQUEST=None), _apo_compare_csv(context, A, B, REQUEST=None),
"</div>", "</div>",
"""<p><a href="apo_compare_csv_form" class="stdlink">Autre comparaison</a></p>""", """<p><a href="apo_compare_csv_form" class="stdlink">Autre comparaison</a></p>""",
context.sco_footer(REQUEST), html_sco_header.sco_footer(context, REQUEST),
] ]
return "\n".join(H) return "\n".join(H)

View File

@ -299,7 +299,7 @@ def do_formsemestre_archive(
if data: if data:
data = "\n".join( data = "\n".join(
[ [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, REQUEST,
page_title="Moyennes archivées le %s" % date, page_title="Moyennes archivées le %s" % date,
head_message="Moyennes archivées le %s" % date, head_message="Moyennes archivées le %s" % date,
@ -308,7 +308,7 @@ def do_formsemestre_archive(
'<h2 class="fontorange">Valeurs archivées le %s</h2>' % date, '<h2 class="fontorange">Valeurs archivées le %s</h2>' % date,
'<style type="text/css">table.notes_recapcomplet tr { color: rgb(185,70,0); }</style>', '<style type="text/css">table.notes_recapcomplet tr { color: rgb(185,70,0); }</style>',
data, data,
context.sco_footer(REQUEST), html_sco_header.sco_footer(context, REQUEST),
] ]
) )
PVArchive.store(archive_id, "Tableau_moyennes.html", data) PVArchive.store(archive_id, "Tableau_moyennes.html", data)
@ -381,7 +381,7 @@ def formsemestre_archive(context, REQUEST, formsemestre_id, group_ids=[]):
) )
H = [ H = [
context.html_sem_header( html_sco_header.html_sem_header(context,
REQUEST, REQUEST,
"Archiver les PV et résultats du semestre", "Archiver les PV et résultats du semestre",
sem=sem, sem=sem,
@ -400,7 +400,7 @@ enregistrés et non modifiables, on peut les retrouver ultérieurement.
F = [ F = [
"""<p><em>Note: les documents sont aussi affectés par les réglages sur la page "<a href="edit_preferences">Paramétrage</a>" (accessible à l'administrateur du département).</em> """<p><em>Note: les documents sont aussi affectés par les réglages sur la page "<a href="edit_preferences">Paramétrage</a>" (accessible à l'administrateur du département).</em>
</p>""", </p>""",
context.sco_footer(REQUEST), html_sco_header.sco_footer(context, REQUEST),
] ]
descr = [ descr = [
@ -503,7 +503,7 @@ def formsemestre_list_archives(context, REQUEST, formsemestre_id):
L.append(a) L.append(a)
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
H = [context.html_sem_header(REQUEST, "Archive des PV et résultats ", sem)] H = [html_sco_header.html_sem_header(context, REQUEST, "Archive des PV et résultats ", sem)]
if not L: if not L:
H.append("<p>aucune archive enregistrée</p>") H.append("<p>aucune archive enregistrée</p>")
else: else:
@ -529,7 +529,7 @@ def formsemestre_list_archives(context, REQUEST, formsemestre_id):
H.append("</ul></li>") H.append("</ul></li>")
H.append("</ul>") H.append("</ul>")
return "\n".join(H) + context.sco_footer(REQUEST) return "\n".join(H) + html_sco_header.sco_footer(context, REQUEST)
def formsemestre_get_archived_file( def formsemestre_get_archived_file(

View File

@ -131,7 +131,7 @@ def etud_upload_file_form(context, REQUEST, etudid):
) )
etud = context.getEtudInfo(filled=1, REQUEST=REQUEST)[0] etud = context.getEtudInfo(filled=1, REQUEST=REQUEST)[0]
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, REQUEST,
page_title="Chargement d'un document associé à %(nomprenom)s" % etud, page_title="Chargement d'un document associé à %(nomprenom)s" % etud,
), ),
@ -162,7 +162,7 @@ def etud_upload_file_form(context, REQUEST, etudid):
cancelbutton="Annuler", cancelbutton="Annuler",
) )
if tf[0] == 0: if tf[0] == 0:
return "\n".join(H) + tf[1] + context.sco_footer(REQUEST) return "\n".join(H) + tf[1] + html_sco_header.sco_footer(context, REQUEST)
elif tf[0] == -1: elif tf[0] == -1:
return REQUEST.RESPONSE.redirect( return REQUEST.RESPONSE.redirect(
context.NotesURL() + "/ficheEtud?etudid=" + etudid context.NotesURL() + "/ficheEtud?etudid=" + etudid
@ -252,7 +252,7 @@ def etudarchive_generate_excel_sample(context, group_id=None, REQUEST=None):
def etudarchive_import_files_form(context, group_id, REQUEST=None): def etudarchive_import_files_form(context, group_id, REQUEST=None):
"""Formualaire pour importation fichiers d'un groupe""" """Formualaire pour importation fichiers d'un groupe"""
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, page_title="Import de fichiers associés aux étudiants" REQUEST, page_title="Import de fichiers associés aux étudiants"
), ),
"""<h2 class="formsemestre">Téléchargement de fichier associés aux étudiants</h2> """<h2 class="formsemestre">Téléchargement de fichier associés aux étudiants</h2>
@ -276,7 +276,7 @@ def etudarchive_import_files_form(context, group_id, REQUEST=None):
""" """
% group_id, % group_id,
] ]
F = context.sco_footer(REQUEST) F = html_sco_header.sco_footer(context, REQUEST)
tf = TrivialFormulator( tf = TrivialFormulator(
REQUEST.URL0, REQUEST.URL0,
REQUEST.form, REQUEST.form,
@ -329,4 +329,4 @@ def etudarchive_import_files(
r = sco_trombino.zip_excel_import_files( r = sco_trombino.zip_excel_import_files(
context, xlsfile, zipfile, REQUEST, callback, filename_title, page_title context, xlsfile, zipfile, REQUEST, callback, filename_title, page_title
) )
return r + context.sco_footer(REQUEST) return r + html_sco_header.sco_footer(context, REQUEST)

View File

@ -41,6 +41,7 @@ from email.header import Header
from reportlab.lib.colors import Color from reportlab.lib.colors import Color
import mails
import sco_utils as scu import sco_utils as scu
import notesdb as ndb import notesdb as ndb
from notes_log import log from notes_log import log
@ -831,7 +832,7 @@ def formsemestre_bulletinetud(
R.append('<div id="radar_bulletin"></div>') R.append('<div id="radar_bulletin"></div>')
# --- Pied de page # --- Pied de page
R.append(context.sco_footer(REQUEST)) R.append(html_sco_header.sco_footer(context, REQUEST))
return "".join(R) return "".join(R)
@ -1010,7 +1011,7 @@ def mail_bulletin(context, formsemestre_id, I, pdfdata, filename, recipient_addr
email.encoders.encode_base64(att) email.encoders.encode_base64(att)
msg.attach(att) msg.attach(att)
log("mail bulletin a %s" % msg["To"]) log("mail bulletin a %s" % msg["To"])
context.sendEmail(msg) mails.sendEmail(context, msg)
def _formsemestre_bulletinetud_header_html( def _formsemestre_bulletinetud_header_html(
@ -1026,7 +1027,7 @@ def _formsemestre_bulletinetud_header_html(
authuser = REQUEST.AUTHENTICATED_USER authuser = REQUEST.AUTHENTICATED_USER
uid = str(authuser) uid = str(authuser)
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
page_title="Bulletin de %(nomprenom)s" % etud, page_title="Bulletin de %(nomprenom)s" % etud,
REQUEST=REQUEST, REQUEST=REQUEST,
javascripts=[ javascripts=[
@ -1196,7 +1197,7 @@ def formsemestre_bulletins_choice(
"""Choix d'une version de bulletin""" """Choix d'une version de bulletin"""
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
H = [ H = [
context.html_sem_header(REQUEST, title, sem), html_sco_header.html_sem_header(context, REQUEST, title, sem),
""" """
<form name="f" method="GET" action="%s"> <form name="f" method="GET" action="%s">
<input type="hidden" name="formsemestre_id" value="%s"></input> <input type="hidden" name="formsemestre_id" value="%s"></input>
@ -1219,7 +1220,7 @@ def formsemestre_bulletins_choice(
H.append("""<p class="help">""" + explanation + """</p>""") H.append("""<p class="help">""" + explanation + """</p>""")
return "\n".join(H) + context.sco_footer(REQUEST) return "\n".join(H) + html_sco_header.sco_footer(context, REQUEST)
expl_bull = """Versions des bulletins:<ul><li><bf>courte</bf>: moyennes des modules</li><li><bf>intermédiaire</bf>: moyennes des modules et notes des évaluations sélectionnées</li><li><bf>complète</bf>: toutes les notes</li><ul>""" expl_bull = """Versions des bulletins:<ul><li><bf>courte</bf>: moyennes des modules</li><li><bf>intermédiaire</bf>: moyennes des modules et notes des évaluations sélectionnées</li><li><bf>complète</bf>: toutes les notes</li><ul>"""

4
app/scodoc/sco_core.py Executable file → Normal file
View File

@ -16,8 +16,8 @@ def sco_get_version(context, REQUEST=None):
def test_refactor(context, x=1): def test_refactor(context, x=1):
x = context.toto() x = context.toto()
y = ("context=" + context.module_is_locked("alpha")) + "23" y = ("context=" + sco_edit_module.module_is_locked(context, "alpha")) + "23"
z = context.sco_header( z = html_sco_header.sco_header(context,
a_long_argument_hahahahaha=1, a_long_argument_hahahahaha=1,
another_very_long_arggggggggggggg=2, another_very_long_arggggggggggggg=2,
z=6, z=6,

View File

@ -191,11 +191,11 @@ def table_debouche_etudids(context, etudids, keep_numeric=True):
def report_debouche_ask_date(context, REQUEST=None): def report_debouche_ask_date(context, REQUEST=None):
"""Formulaire demande date départ""" """Formulaire demande date départ"""
return ( return (
context.sco_header(REQUEST) html_sco_header.sco_header(context, REQUEST)
+ """<form method="GET"> + """<form method="GET">
Date de départ de la recherche: <input type="text" name="start_year" value="" size=10/> Date de départ de la recherche: <input type="text" name="start_year" value="" size=10/>
</form>""" </form>"""
+ context.sco_footer(REQUEST) + html_sco_header.sco_footer(context, REQUEST)
) )

View File

@ -171,7 +171,7 @@ Chercher étape courante: <input name="etape_apo" type="text" size="8" spellchec
""" """
) )
# #
return context.sco_header(REQUEST) + "\n".join(H) + context.sco_footer(REQUEST) return html_sco_header.sco_header(context, REQUEST) + "\n".join(H) + html_sco_header.sco_footer(context, REQUEST)
def _sem_table(context, sems): def _sem_table(context, sems):

View File

@ -66,7 +66,7 @@ SCO_DUMP_LOCK = "/tmp/scodump.lock"
def sco_dump_and_send_db(context, REQUEST=None): 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""" """Dump base de données du département courant et l'envoie anonymisée pour debug"""
H = [context.sco_header(REQUEST, page_title="Assistance technique")] H = [html_sco_header.sco_header(context, REQUEST, page_title="Assistance technique")]
# get currect (dept) DB name: # get currect (dept) DB name:
cursor = ndb.SimpleQuery(context, "SELECT current_database()", {}) cursor = ndb.SimpleQuery(context, "SELECT current_database()", {})
db_name = cursor.fetchone()[0] db_name = cursor.fetchone()[0]
@ -123,7 +123,7 @@ def sco_dump_and_send_db(context, REQUEST=None):
fcntl.flock(x, fcntl.LOCK_UN) fcntl.flock(x, fcntl.LOCK_UN)
log("sco_dump_and_send_db: done.") log("sco_dump_and_send_db: done.")
return "\n".join(H) + context.sco_footer(REQUEST) return "\n".join(H) + html_sco_header.sco_footer(context, REQUEST)
def _duplicate_db(db_name, ano_db_name): def _duplicate_db(db_name, ano_db_name):

View File

@ -46,7 +46,7 @@ def formation_delete(context, formation_id=None, dialog_confirmed=False, REQUEST
F = F[0] F = F[0]
H = [ H = [
context.sco_header(REQUEST, page_title="Suppression d'une formation"), html_sco_header.sco_header(context, REQUEST, page_title="Suppression d'une formation"),
"""<h2>Suppression de la formation %(titre)s (%(acronyme)s)</h2>""" % F, """<h2>Suppression de la formation %(titre)s (%(acronyme)s)</h2>""" % F,
] ]
@ -86,7 +86,7 @@ def formation_delete(context, formation_id=None, dialog_confirmed=False, REQUEST
% context.NotesURL() % context.NotesURL()
) )
H.append(context.sco_footer(REQUEST)) H.append(html_sco_header.sco_footer(context, REQUEST))
return "\n".join(H) return "\n".join(H)
@ -99,7 +99,7 @@ def formation_edit(context, formation_id=None, create=False, REQUEST=None):
"""Edit or create a formation""" """Edit or create a formation"""
if create: if create:
H = [ H = [
context.sco_header(REQUEST, page_title="Création d'une formation"), html_sco_header.sco_header(context, REQUEST, page_title="Création d'une formation"),
"""<h2>Création d'une formation</h2> """<h2>Création d'une formation</h2>
<p class="help">Une "formation" décrit une filière, comme un DUT ou une Licence. La formation se subdivise en unités pédagogiques (UE, matières, modules). Elle peut se diviser en plusieurs semestres (ou sessions), qui seront mis en place séparément. <p class="help">Une "formation" décrit une filière, comme un DUT ou une Licence. La formation se subdivise en unités pédagogiques (UE, matières, modules). Elle peut se diviser en plusieurs semestres (ou sessions), qui seront mis en place séparément.
@ -121,7 +121,7 @@ def formation_edit(context, formation_id=None, create=False, REQUEST=None):
is_locked = context.formation_has_locked_sems(formation_id) is_locked = context.formation_has_locked_sems(formation_id)
submitlabel = "Modifier les valeurs" submitlabel = "Modifier les valeurs"
H = [ H = [
context.sco_header(REQUEST, page_title="Modification d'une formation"), html_sco_header.sco_header(context, REQUEST, page_title="Modification d'une formation"),
"""<h2>Modification de la formation %(acronyme)s</h2>""" % initvalues, """<h2>Modification de la formation %(acronyme)s</h2>""" % initvalues,
] ]
if is_locked: if is_locked:
@ -191,7 +191,7 @@ def formation_edit(context, formation_id=None, create=False, REQUEST=None):
submitlabel=submitlabel, submitlabel=submitlabel,
) )
if tf[0] == 0: if tf[0] == 0:
return "\n".join(H) + tf[1] + context.sco_footer(REQUEST) return "\n".join(H) + tf[1] + html_sco_header.sco_footer(context, REQUEST)
elif tf[0] == -1: elif tf[0] == -1:
return REQUEST.RESPONSE.redirect(context.NotesURL()) return REQUEST.RESPONSE.redirect(context.NotesURL())
else: else:
@ -214,7 +214,7 @@ def formation_edit(context, formation_id=None, create=False, REQUEST=None):
"Valeurs incorrectes: il existe déjà une formation avec même titre, acronyme et version." "Valeurs incorrectes: il existe déjà une formation avec même titre, acronyme et version."
) )
+ tf[1] + tf[1]
+ context.sco_footer(REQUEST) + html_sco_header.sco_footer(context, REQUEST)
) )
# #
if create: if create:

View File

@ -40,7 +40,7 @@ def matiere_create(context, ue_id=None, REQUEST=None):
"""Creation d'une matiere""" """Creation d'une matiere"""
UE = context.do_ue_list(args={"ue_id": ue_id})[0] UE = context.do_ue_list(args={"ue_id": ue_id})[0]
H = [ H = [
context.sco_header(REQUEST, page_title="Création d'une matière"), html_sco_header.sco_header(context, REQUEST, page_title="Création d'une matière"),
"""<h2>Création d'une matière dans l'UE %(titre)s (%(acronyme)s)</h2>""" % UE, """<h2>Création d'une matière dans l'UE %(titre)s (%(acronyme)s)</h2>""" % UE,
"""<p class="help">Les matières sont des groupes de modules dans une UE """<p class="help">Les matières sont des groupes de modules dans une UE
d'une formation donnée. Les matières servent surtout pour la d'une formation donnée. Les matières servent surtout pour la
@ -78,7 +78,7 @@ associé.
dest_url = context.NotesURL() + "/ue_list?formation_id=" + UE["formation_id"] dest_url = context.NotesURL() + "/ue_list?formation_id=" + UE["formation_id"]
if tf[0] == 0: if tf[0] == 0:
return "\n".join(H) + tf[1] + context.sco_footer(REQUEST) return "\n".join(H) + tf[1] + html_sco_header.sco_footer(context, REQUEST)
elif tf[0] == -1: elif tf[0] == -1:
return REQUEST.RESPONSE.redirect(dest_url) return REQUEST.RESPONSE.redirect(dest_url)
else: else:
@ -89,7 +89,7 @@ associé.
"\n".join(H) "\n".join(H)
+ tf_error_message("Titre de matière déjà existant dans cette UE") + tf_error_message("Titre de matière déjà existant dans cette UE")
+ tf[1] + tf[1]
+ context.sco_footer(REQUEST) + html_sco_header.sco_footer(context, REQUEST)
) )
_ = context.do_matiere_create(tf[2], REQUEST) _ = context.do_matiere_create(tf[2], REQUEST)
return REQUEST.RESPONSE.redirect(dest_url) return REQUEST.RESPONSE.redirect(dest_url)
@ -100,7 +100,7 @@ def matiere_delete(context, matiere_id=None, REQUEST=None):
M = context.do_matiere_list(args={"matiere_id": matiere_id})[0] M = context.do_matiere_list(args={"matiere_id": matiere_id})[0]
UE = context.do_ue_list(args={"ue_id": M["ue_id"]})[0] UE = context.do_ue_list(args={"ue_id": M["ue_id"]})[0]
H = [ H = [
context.sco_header(REQUEST, page_title="Suppression d'une matière"), html_sco_header.sco_header(context, REQUEST, page_title="Suppression d'une matière"),
"<h2>Suppression de la matière %(titre)s" % M, "<h2>Suppression de la matière %(titre)s" % M,
" dans l'UE (%(acronyme)s))</h2>" % UE, " dans l'UE (%(acronyme)s))</h2>" % UE,
] ]
@ -114,7 +114,7 @@ def matiere_delete(context, matiere_id=None, REQUEST=None):
cancelbutton="Annuler", cancelbutton="Annuler",
) )
if tf[0] == 0: if tf[0] == 0:
return "\n".join(H) + tf[1] + context.sco_footer(REQUEST) return "\n".join(H) + tf[1] + html_sco_header.sco_footer(context, REQUEST)
elif tf[0] == -1: elif tf[0] == -1:
return REQUEST.RESPONSE.redirect(dest_url) return REQUEST.RESPONSE.redirect(dest_url)
else: else:
@ -138,7 +138,7 @@ def matiere_edit(context, matiere_id=None, REQUEST=None):
ue_names = ["%(acronyme)s (%(titre)s)" % u for u in ues] ue_names = ["%(acronyme)s (%(titre)s)" % u for u in ues]
ue_ids = [u["ue_id"] for u in ues] ue_ids = [u["ue_id"] for u in ues]
H = [ H = [
context.sco_header(REQUEST, page_title="Modification d'une matière"), html_sco_header.sco_header(context, REQUEST, page_title="Modification d'une matière"),
"""<h2>Modification de la matière %(titre)s""" % F, """<h2>Modification de la matière %(titre)s""" % F,
"""(formation %(acronyme)s, version %(version)s)</h2>""" % Fo, """(formation %(acronyme)s, version %(version)s)</h2>""" % Fo,
] ]
@ -182,7 +182,7 @@ associé.
dest_url = context.NotesURL() + "/ue_list?formation_id=" + U["formation_id"] dest_url = context.NotesURL() + "/ue_list?formation_id=" + U["formation_id"]
if tf[0] == 0: if tf[0] == 0:
return "\n".join(H) + tf[1] + help + context.sco_footer(REQUEST) return "\n".join(H) + tf[1] + help + html_sco_header.sco_footer(context, REQUEST)
elif tf[0] == -1: elif tf[0] == -1:
return REQUEST.RESPONSE.redirect(dest_url) return REQUEST.RESPONSE.redirect(dest_url)
else: else:
@ -195,7 +195,7 @@ associé.
"\n".join(H) "\n".join(H)
+ tf_error_message("Titre de matière déjà existant dans cette UE") + tf_error_message("Titre de matière déjà existant dans cette UE")
+ tf[1] + tf[1]
+ context.sco_footer(REQUEST) + html_sco_header.sco_footer(context, REQUEST)
) )
# changement d'UE ? # changement d'UE ?

View File

@ -66,7 +66,7 @@ def module_create(context, matiere_id=None, REQUEST=None):
parcours = sco_codes_parcours.get_parcours_from_code(Fo["type_parcours"]) parcours = sco_codes_parcours.get_parcours_from_code(Fo["type_parcours"])
semestres_indices = range(1, parcours.NB_SEM + 1) semestres_indices = range(1, parcours.NB_SEM + 1)
H = [ H = [
context.sco_header(REQUEST, page_title="Création d'un module"), html_sco_header.sco_header(context, REQUEST, page_title="Création d'un module"),
"""<h2>Création d'un module dans la matière %(titre)s""" % M, """<h2>Création d'un module dans la matière %(titre)s""" % M,
""" (UE %(acronyme)s)</h2>""" % UE, """ (UE %(acronyme)s)</h2>""" % UE,
_MODULE_HELP, _MODULE_HELP,
@ -170,7 +170,7 @@ def module_create(context, matiere_id=None, REQUEST=None):
submitlabel="Créer ce module", submitlabel="Créer ce module",
) )
if tf[0] == 0: if tf[0] == 0:
return "\n".join(H) + tf[1] + context.sco_footer(REQUEST) return "\n".join(H) + tf[1] + html_sco_header.sco_footer(context, REQUEST)
else: else:
context.do_module_create(tf[2], REQUEST) context.do_module_create(tf[2], REQUEST)
return REQUEST.RESPONSE.redirect( return REQUEST.RESPONSE.redirect(
@ -187,7 +187,9 @@ def module_delete(context, module_id=None, REQUEST=None):
raise ScoValueError("Module inexistant !") raise ScoValueError("Module inexistant !")
Mod = Mods[0] Mod = Mods[0]
H = [ H = [
context.sco_header(REQUEST, page_title="Suppression d'un module"), html_sco_header.sco_header(
context, REQUEST, page_title="Suppression d'un module"
),
"""<h2>Suppression du module %(titre)s (%(code)s)</h2>""" % Mod, """<h2>Suppression du module %(titre)s (%(code)s)</h2>""" % Mod,
] ]
@ -201,7 +203,7 @@ def module_delete(context, module_id=None, REQUEST=None):
cancelbutton="Annuler", cancelbutton="Annuler",
) )
if tf[0] == 0: if tf[0] == 0:
return "\n".join(H) + tf[1] + context.sco_footer(REQUEST) return "\n".join(H) + tf[1] + html_sco_header.sco_footer(context, REQUEST)
elif tf[0] == -1: elif tf[0] == -1:
return REQUEST.RESPONSE.redirect(dest_url) return REQUEST.RESPONSE.redirect(dest_url)
else: else:
@ -226,7 +228,7 @@ def module_edit(context, module_id=None, REQUEST=None):
if not Mod: if not Mod:
raise ScoValueError("invalid module !") raise ScoValueError("invalid module !")
Mod = Mod[0] Mod = Mod[0]
unlocked = not context.module_is_locked(module_id) unlocked = not module_is_locked(context, module_id)
Fo = context.formation_list(args={"formation_id": Mod["formation_id"]})[0] Fo = context.formation_list(args={"formation_id": Mod["formation_id"]})[0]
parcours = sco_codes_parcours.get_parcours_from_code(Fo["type_parcours"]) parcours = sco_codes_parcours.get_parcours_from_code(Fo["type_parcours"])
M = ndb.SimpleDictFetch( M = ndb.SimpleDictFetch(
@ -243,7 +245,8 @@ def module_edit(context, module_id=None, REQUEST=None):
dest_url = context.NotesURL() + "/ue_list?formation_id=" + Mod["formation_id"] dest_url = context.NotesURL() + "/ue_list?formation_id=" + Mod["formation_id"]
H = [ H = [
context.sco_header( html_sco_header.sco_header(
context,
REQUEST, REQUEST,
page_title="Modification du module %(titre)s" % Mod, page_title="Modification du module %(titre)s" % Mod,
cssstyles=["libjs/jQuery-tagEditor/jquery.tag-editor.css"], cssstyles=["libjs/jQuery-tagEditor/jquery.tag-editor.css"],
@ -375,7 +378,7 @@ def module_edit(context, module_id=None, REQUEST=None):
) )
if tf[0] == 0: if tf[0] == 0:
return "\n".join(H) + tf[1] + context.sco_footer(REQUEST) return "\n".join(H) + tf[1] + html_sco_header.sco_footer(context, REQUEST)
elif tf[0] == -1: elif tf[0] == -1:
return REQUEST.RESPONSE.redirect(dest_url) return REQUEST.RESPONSE.redirect(dest_url)
else: else:
@ -412,7 +415,9 @@ def module_list(context, formation_id, REQUEST=None):
raise ScoValueError("invalid formation !") raise ScoValueError("invalid formation !")
F = context.formation_list(args={"formation_id": formation_id})[0] F = context.formation_list(args={"formation_id": formation_id})[0]
H = [ H = [
context.sco_header(REQUEST, page_title="Liste des modules de %(titre)s" % F), html_sco_header.sco_header(
context, REQUEST, page_title="Liste des modules de %(titre)s" % F
),
"""<h2>Listes des modules dans la formation %(titre)s (%(acronyme)s)</h2>""" """<h2>Listes des modules dans la formation %(titre)s (%(acronyme)s)</h2>"""
% F, % F,
'<ul class="notes_module_list">', '<ul class="notes_module_list">',
@ -430,11 +435,29 @@ def module_list(context, formation_id, REQUEST=None):
) )
H.append("</li>") H.append("</li>")
H.append("</ul>") H.append("</ul>")
H.append(context.sco_footer(REQUEST)) H.append(html_sco_header.sco_footer(context, REQUEST))
return "\n".join(H) return "\n".join(H)
# def module_is_locked(context, module_id):
"""True if module should not be modified
(used in a locked formsemestre)
"""
r = ndb.SimpleDictFetch(
context,
"""SELECT mi.* from notes_modules mod, notes_formsemestre sem, notes_moduleimpl mi
WHERE mi.module_id = mod.module_id AND mi.formsemestre_id = sem.formsemestre_id
AND mi.module_id = %(module_id)s AND sem.etat = 0
""",
{"module_id": module_id},
)
return len(r) > 0
def module_count_moduleimpls(context, module_id):
"Number of moduleimpls using this module"
mods = sco_moduleimpl.do_moduleimpl_list(context, module_id=module_id)
return len(mods)
def formation_add_malus_modules(context, formation_id, titre=None, REQUEST=None): def formation_add_malus_modules(context, formation_id, titre=None, REQUEST=None):

View File

@ -73,7 +73,7 @@ def ue_edit(context, ue_id=None, create=False, formation_id=None, REQUEST=None):
parcours = sco_codes_parcours.get_parcours_from_code(Fo["type_parcours"]) parcours = sco_codes_parcours.get_parcours_from_code(Fo["type_parcours"])
H = [ H = [
context.sco_header(REQUEST, page_title=title, javascripts=["js/edit_ue.js"]), html_sco_header.sco_header(context, REQUEST, page_title=title, javascripts=["js/edit_ue.js"]),
"<h2>" + title, "<h2>" + title,
" (formation %(acronyme)s, version %(version)s)</h2>" % Fo, " (formation %(acronyme)s, version %(version)s)</h2>" % Fo,
""" """
@ -186,7 +186,7 @@ def ue_edit(context, ue_id=None, create=False, formation_id=None, REQUEST=None):
if tf[0] == 0: if tf[0] == 0:
X = """<div id="ue_list_code"></div> X = """<div id="ue_list_code"></div>
""" """
return "\n".join(H) + tf[1] + X + context.sco_footer(REQUEST) return "\n".join(H) + tf[1] + X + html_sco_header.sco_footer(context, REQUEST)
else: else:
if create: if create:
if not tf[2]["ue_code"]: if not tf[2]["ue_code"]:
@ -323,7 +323,7 @@ def ue_list(context, formation_id=None, msg="", REQUEST=None):
"delete_small_dis_img", title="Suppression impossible (module utilisé)" "delete_small_dis_img", title="Suppression impossible (module utilisé)"
) )
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, REQUEST,
cssstyles=["libjs/jQuery-tagEditor/jquery.tag-editor.css"], cssstyles=["libjs/jQuery-tagEditor/jquery.tag-editor.css"],
javascripts=[ javascripts=[
@ -466,7 +466,7 @@ Si vous souhaitez modifier cette formation (par exemple pour y ajouter un module
'<span class="ue_type">%s</span>' '<span class="ue_type">%s</span>'
% sco_codes_parcours.UE_TYPE_NAME[UE["type"]] % sco_codes_parcours.UE_TYPE_NAME[UE["type"]]
) )
ue_editable = editable and not context.ue_is_locked(UE["ue_id"]) ue_editable = editable and not ue_is_locked(context, UE["ue_id"])
if ue_editable: if ue_editable:
H.append( H.append(
'<a class="stdlink" href="ue_edit?ue_id=%(ue_id)s">modifier</a>' % UE '<a class="stdlink" href="ue_edit?ue_id=%(ue_id)s">modifier</a>' % UE
@ -479,20 +479,20 @@ Si vous souhaitez modifier cette formation (par exemple pour y ajouter un module
for Mat in Matlist: for Mat in Matlist:
if not parcours.UE_IS_MODULE: if not parcours.UE_IS_MODULE:
H.append('<li class="notes_matiere_list">') H.append('<li class="notes_matiere_list">')
if editable and not context.matiere_is_locked(Mat["matiere_id"]): if editable and not sco_edit_matiere.matiere_is_locked(context, Mat["matiere_id"]):
H.append( H.append(
'<a class="stdlink" href="matiere_edit?matiere_id=%(matiere_id)s">' '<a class="stdlink" href="matiere_edit?matiere_id=%(matiere_id)s">'
% Mat % Mat
) )
H.append("%(titre)s" % Mat) H.append("%(titre)s" % Mat)
if editable and not context.matiere_is_locked(Mat["matiere_id"]): if editable and not sco_edit_matiere.matiere_is_locked(context, Mat["matiere_id"]):
H.append("</a>") H.append("</a>")
H.append('<ul class="notes_module_list">') H.append('<ul class="notes_module_list">')
Modlist = context.do_module_list(args={"matiere_id": Mat["matiere_id"]}) Modlist = context.do_module_list(args={"matiere_id": Mat["matiere_id"]})
im = 0 im = 0
for Mod in Modlist: for Mod in Modlist:
Mod["nb_moduleimpls"] = context.module_count_moduleimpls( Mod["nb_moduleimpls"] = sco_edit_module.module_count_moduleimpls(context,
Mod["module_id"] Mod["module_id"]
) )
klass = "notes_module_list" klass = "notes_module_list"
@ -526,7 +526,7 @@ Si vous souhaitez modifier cette formation (par exemple pour y ajouter un module
H.append("</span>") H.append("</span>")
mod_editable = ( mod_editable = (
editable # and not context.module_is_locked(Mod['module_id']) editable # and not sco_edit_module.module_is_locked(context, Mod['module_id'])
) )
if mod_editable: if mod_editable:
H.append( H.append(
@ -669,7 +669,7 @@ Si vous souhaitez modifier cette formation (par exemple pour y ajouter un module
warn, _ = sco_formsemestre_validation.check_formation_ues(context, formation_id) warn, _ = sco_formsemestre_validation.check_formation_ues(context, formation_id)
H.append(warn) H.append(warn)
H.append(context.sco_footer(REQUEST)) H.append(html_sco_header.sco_footer(context, REQUEST))
return "".join(H) return "".join(H)
@ -732,7 +732,7 @@ def do_ue_edit(context, args, bypass_lock=False, dont_invalidate_cache=False):
# check # check
ue_id = args["ue_id"] ue_id = args["ue_id"]
ue = context.do_ue_list({"ue_id": ue_id})[0] ue = context.do_ue_list({"ue_id": ue_id})[0]
if (not bypass_lock) and context.ue_is_locked(ue["ue_id"]): if (not bypass_lock) and ue_is_locked(context, ue["ue_id"]):
raise ScoLockedFormError() raise ScoLockedFormError()
# check: acronyme unique dans cette formation # check: acronyme unique dans cette formation
if args.has_key("acronyme"): if args.has_key("acronyme"):
@ -782,6 +782,22 @@ def edit_ue_set_code_apogee(context, id=None, value=None, REQUEST=None):
return value return value
def ue_is_locked(context, ue_id):
"""True if UE should not be modified
(contains modules used in a locked formsemestre)
"""
r = ndb.SimpleDictFetch(
context,
"""SELECT ue.* FROM notes_ue ue, notes_modules mod, notes_formsemestre sem, notes_moduleimpl mi
WHERE ue.ue_id = mod.ue_id
AND mi.module_id = mod.module_id AND mi.formsemestre_id = sem.formsemestre_id
AND ue.ue_id = %(ue_id)s AND sem.etat = 0
""",
{"ue_id": ue_id},
)
return len(r) > 0
# ---- Table recap formation # ---- Table recap formation
def formation_table_recap(context, formation_id, format="html", REQUEST=None): def formation_table_recap(context, formation_id, format="html", REQUEST=None):
"""Table recapitulant formation.""" """Table recapitulant formation."""
@ -796,7 +812,7 @@ def formation_table_recap(context, formation_id, format="html", REQUEST=None):
for Mat in Matlist: for Mat in Matlist:
Modlist = context.do_module_list(args={"matiere_id": Mat["matiere_id"]}) Modlist = context.do_module_list(args={"matiere_id": Mat["matiere_id"]})
for Mod in Modlist: for Mod in Modlist:
Mod["nb_moduleimpls"] = context.module_count_moduleimpls( Mod["nb_moduleimpls"] = sco_edit_module.module_count_moduleimpls(context,
Mod["module_id"] Mod["module_id"]
) )
# #

View File

@ -163,7 +163,7 @@ def experimental_calendar(context, group_id=None, formsemestre_id=None, REQUEST=
"""experimental page""" """experimental page"""
return "\n".join( return "\n".join(
[ [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, REQUEST,
javascripts=[ javascripts=[
"libjs/purl.js", "libjs/purl.js",
@ -195,7 +195,7 @@ def experimental_calendar(context, group_id=None, formsemestre_id=None, REQUEST=
"""</form><div id="loading">loading...</div> """</form><div id="loading">loading...</div>
<div id="calendar"></div> <div id="calendar"></div>
""", """,
context.sco_footer(REQUEST), html_sco_header.sco_footer(context, REQUEST),
"""<script> """<script>
$(document).ready(function() { $(document).ready(function() {

View File

@ -98,7 +98,7 @@ def apo_semset_maq_status(
ok_for_export &= semset["jury_ok"] ok_for_export &= semset["jury_ok"]
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, REQUEST,
page_title="Export Apogée", page_title="Export Apogée",
javascripts=["js/apo_semset_maq_status.js"], javascripts=["js/apo_semset_maq_status.js"],
@ -420,7 +420,7 @@ def apo_semset_maq_status(
""" """
% (APO_INPUT_ENCODING,) % (APO_INPUT_ENCODING,)
) )
H.append(context.sco_footer(REQUEST)) H.append(html_sco_header.sco_footer(context, REQUEST))
return "\n".join(H) return "\n".join(H)
@ -559,7 +559,7 @@ def _view_etuds_page(
etuds.sort(key=lambda x: (x["nom"], x["prenom"])) etuds.sort(key=lambda x: (x["nom"], x["prenom"]))
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, page_title=title, init_qtip=True, javascripts=["js/etud_info.js"] REQUEST, page_title=title, init_qtip=True, javascripts=["js/etud_info.js"]
), ),
"<h2>%s</h2>" % title, "<h2>%s</h2>" % title,
@ -591,7 +591,7 @@ def _view_etuds_page(
% semset_id % semset_id
) )
return "\n".join(H) + context.sco_footer(REQUEST) return "\n".join(H) + html_sco_header.sco_footer(context, REQUEST)
def view_apo_csv_store( def view_apo_csv_store(
@ -704,7 +704,7 @@ def view_apo_csv(context, etape_apo="", semset_id="", format="html", REQUEST=Non
) = sco_etape_apogee.apo_csv_semset_check(context, semset) ) = sco_etape_apogee.apo_csv_semset_check(context, semset)
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, REQUEST,
page_title="Maquette Apogée enregistrée pour %s" % etape_apo, page_title="Maquette Apogée enregistrée pour %s" % etape_apo,
init_qtip=True, init_qtip=True,
@ -728,7 +728,7 @@ def view_apo_csv(context, etape_apo="", semset_id="", format="html", REQUEST=Non
# Liste des étudiants (sans les résultats pour le moment): TODO # Liste des étudiants (sans les résultats pour le moment): TODO
etuds = apo_data.etuds etuds = apo_data.etuds
if not etuds: if not etuds:
return "\n".join(H) + "<p>Aucun étudiant</p>" + context.sco_footer(REQUEST) return "\n".join(H) + "<p>Aucun étudiant</p>" + html_sco_header.sco_footer(context, REQUEST)
# Ajout infos sur ScoDoc vs Apogee # Ajout infos sur ScoDoc vs Apogee
for e in etuds: for e in etuds:
@ -771,7 +771,7 @@ def view_apo_csv(context, etape_apo="", semset_id="", format="html", REQUEST=Non
"""<div><a class="stdlink" href="apo_semset_maq_status?semset_id=%s">Retour</a> """<div><a class="stdlink" href="apo_semset_maq_status?semset_id=%s">Retour</a>
</div>""" </div>"""
% semset_id, % semset_id,
context.sco_footer(REQUEST), html_sco_header.sco_footer(context, REQUEST),
] ]
return "\n".join(H) return "\n".join(H)

View File

@ -494,7 +494,7 @@ def formsemestre_evaluations_cal(context, formsemestre_id, REQUEST=None):
) )
H = [ H = [
context.html_sem_header( html_sco_header.html_sem_header(context,
REQUEST, "Evaluations du semestre", sem, cssstyles=["css/calabs.css"] REQUEST, "Evaluations du semestre", sem, cssstyles=["css/calabs.css"]
), ),
'<div class="cal_evaluations">', '<div class="cal_evaluations">',
@ -508,7 +508,7 @@ def formsemestre_evaluations_cal(context, formsemestre_id, REQUEST=None):
"""<p><a href="formsemestre_evaluations_delai_correction?formsemestre_id=%s" class="stdlink">voir les délais de correction</a></p> """<p><a href="formsemestre_evaluations_delai_correction?formsemestre_id=%s" class="stdlink">voir les délais de correction</a></p>
""" """
% (formsemestre_id,), % (formsemestre_id,),
context.sco_footer(REQUEST), html_sco_header.sco_footer(context, REQUEST),
] ]
return "\n".join(H) return "\n".join(H)
@ -825,12 +825,12 @@ def evaluation_create_form(
context._evaluation_check_write_access(REQUEST, moduleimpl_id=moduleimpl_id) context._evaluation_check_write_access(REQUEST, moduleimpl_id=moduleimpl_id)
except AccessDenied as e: except AccessDenied as e:
return ( return (
context.sco_header(REQUEST) html_sco_header.sco_header(context, REQUEST)
+ "<h2>Opération non autorisée</h2><p>" + "<h2>Opération non autorisée</h2><p>"
+ str(e) + str(e)
+ "</p>" + "</p>"
+ '<p><a href="%s">Revenir</a></p>' % (str(REQUEST.HTTP_REFERER),) + '<p><a href="%s">Revenir</a></p>' % (str(REQUEST.HTTP_REFERER),)
+ context.sco_footer(REQUEST) + html_sco_header.sco_footer(context, REQUEST)
) )
if readonly: if readonly:
edit = True # montre les donnees existantes edit = True # montre les donnees existantes
@ -1054,8 +1054,8 @@ def evaluation_create_form(
dest_url = "moduleimpl_status?moduleimpl_id=%s" % M["moduleimpl_id"] dest_url = "moduleimpl_status?moduleimpl_id=%s" % M["moduleimpl_id"]
if tf[0] == 0: if tf[0] == 0:
head = context.sco_header(REQUEST, page_title=page_title) head = html_sco_header.sco_header(context, REQUEST, page_title=page_title)
return head + "\n".join(H) + "\n" + tf[1] + help + context.sco_footer(REQUEST) return head + "\n".join(H) + "\n" + tf[1] + help + html_sco_header.sco_footer(context, REQUEST)
elif tf[0] == -1: elif tf[0] == -1:
return REQUEST.RESPONSE.redirect(dest_url) return REQUEST.RESPONSE.redirect(dest_url)
else: else:

View File

@ -279,7 +279,7 @@ def scodoc_table_results(
info_sems.append("</ul>") info_sems.append("</ul>")
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, REQUEST,
page_title="Export résultats", page_title="Export résultats",
init_qtip=True, init_qtip=True,
@ -307,7 +307,7 @@ def scodoc_table_results(
""", """,
"\n".join(info_sems), "\n".join(info_sems),
"""</div>""", """</div>""",
context.sco_footer(REQUEST), html_sco_header.sco_footer(context, REQUEST),
] ]
return "\n".join(H) return "\n".join(H)

View File

@ -35,7 +35,7 @@ import sco_utils as scu
import notesdb as ndb import notesdb as ndb
from notes_log import log from notes_log import log
from gen_tables import GenTable from gen_tables import GenTable
import html_sco_header
import scolars import scolars
import sco_formsemestre import sco_formsemestre
import sco_groups import sco_groups
@ -88,9 +88,9 @@ def form_search_etud(
if add_headers: if add_headers:
return ( return (
context.sco_header(REQUEST, page_title="Choix d'un étudiant") html_sco_header.sco_header(context, REQUEST, page_title="Choix d'un étudiant")
+ "\n".join(H) + "\n".join(H)
+ context.sco_footer(REQUEST) + html_sco_header.sco_footer(context, REQUEST)
) )
else: else:
return "\n".join(H) return "\n".join(H)
@ -122,7 +122,7 @@ def search_etud_in_dept(context, expnom="", REQUEST=None):
return context.ficheEtud(etudid=etuds[0]["etudid"], REQUEST=REQUEST) return context.ficheEtud(etudid=etuds[0]["etudid"], REQUEST=REQUEST)
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
page_title="Recherche d'un étudiant", page_title="Recherche d'un étudiant",
no_side_bar=True, no_side_bar=True,
init_qtip=True, init_qtip=True,
@ -175,7 +175,7 @@ def search_etud_in_dept(context, expnom="", REQUEST=None):
H.append( H.append(
"""<p class="help">La recherche porte sur tout ou partie du NOM ou du NIP de l'étudiant</p>""" """<p class="help">La recherche porte sur tout ou partie du NOM ou du NIP de l'étudiant</p>"""
) )
return "\n".join(H) + context.sco_footer(REQUEST) return "\n".join(H) + html_sco_header.sco_footer(context, REQUEST)
# Was chercheEtudsInfo() # Was chercheEtudsInfo()
@ -336,9 +336,9 @@ def table_etud_in_accessible_depts(context, expnom=None, REQUEST=None):
H.append("</div>") H.append("</div>")
return ( return (
context.scodoc_top_html_header(REQUEST, page_title="Choix d'un étudiant") html_sco_header.scodoc_top_html_header(context, REQUEST, page_title="Choix d'un étudiant")
+ "\n".join(H) + "\n".join(H)
+ context.standard_html_footer(REQUEST) + html_sco_header.standard_html_footer()
) )

View File

@ -42,6 +42,22 @@ from sco_exceptions import ScoValueError
from sco_permissions import ScoChangeFormation from sco_permissions import ScoChangeFormation
import VERSION import VERSION
_formationEditor = ndb.EditableTable(
"notes_formations",
"formation_id",
(
"formation_id",
"acronyme",
"titre",
"titre_officiel",
"version",
"formation_code",
"type_parcours",
"code_specialite",
),
sortkey="acronyme",
)
def formation_export( def formation_export(
context, formation_id, export_ids=False, export_tags=True, format=None, REQUEST=None context, formation_id, export_ids=False, export_tags=True, format=None, REQUEST=None

View File

@ -84,7 +84,7 @@ def formsemestre_custommenu_edit(context, formsemestre_id, REQUEST=None):
context.NotesURL() + "/formsemestre_status?formsemestre_id=%s" % formsemestre_id context.NotesURL() + "/formsemestre_status?formsemestre_id=%s" % formsemestre_id
) )
H = [ H = [
context.html_sem_header(REQUEST, "Modification du menu du semestre ", sem), html_sco_header.html_sem_header(context, REQUEST, "Modification du menu du semestre ", sem),
"""<p class="help">Ce menu, spécifique à chaque semestre, peut être utilisé pour placer des liens vers vos applications préférées.</p> """<p class="help">Ce menu, spécifique à chaque semestre, peut être utilisé pour placer des liens vers vos applications préférées.</p>
<p class="help">Procédez en plusieurs fois si vous voulez ajouter plusieurs items.</p>""", <p class="help">Procédez en plusieurs fois si vous voulez ajouter plusieurs items.</p>""",
] ]
@ -127,7 +127,7 @@ def formsemestre_custommenu_edit(context, formsemestre_id, REQUEST=None):
name="tf", name="tf",
) )
if tf[0] == 0: if tf[0] == 0:
return "\n".join(H) + "\n" + tf[1] + context.sco_footer(REQUEST) return "\n".join(H) + "\n" + tf[1] + html_sco_header.sco_footer(context, REQUEST)
elif tf[0] == -1: elif tf[0] == -1:
return REQUEST.RESPONSE.redirect(dest_url) return REQUEST.RESPONSE.redirect(dest_url)
else: else:

View File

@ -55,7 +55,8 @@ def _default_sem_title(F):
def formsemestre_createwithmodules(context, REQUEST=None): def formsemestre_createwithmodules(context, REQUEST=None):
"""Page création d'un semestre""" """Page création d'un semestre"""
H = [ H = [
context.sco_header( html_sco_header.sco_header(
context,
REQUEST, REQUEST,
page_title="Création d'un semestre", page_title="Création d'un semestre",
javascripts=["libjs/AutoSuggest.js"], javascripts=["libjs/AutoSuggest.js"],
@ -64,7 +65,7 @@ def formsemestre_createwithmodules(context, REQUEST=None):
), ),
"""<h2>Mise en place d'un semestre de formation</h2>""", """<h2>Mise en place d'un semestre de formation</h2>""",
do_formsemestre_createwithmodules(context, REQUEST=REQUEST), do_formsemestre_createwithmodules(context, REQUEST=REQUEST),
context.sco_footer(REQUEST), html_sco_header.sco_footer(context, REQUEST),
] ]
return "\n".join(H) return "\n".join(H)
@ -74,7 +75,7 @@ def formsemestre_editwithmodules(context, REQUEST, formsemestre_id):
# portage from dtml # portage from dtml
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
H = [ H = [
context.html_sem_header( html_sco_header.html_sem_header(context,
REQUEST, REQUEST,
"Modification du semestre", "Modification du semestre",
sem, sem,
@ -98,7 +99,7 @@ def formsemestre_editwithmodules(context, REQUEST, formsemestre_id):
<p class="help">Les modules ont toujours un responsable. Par défaut, c'est le directeur des études.</p>""" <p class="help">Les modules ont toujours un responsable. Par défaut, c'est le directeur des études.</p>"""
) )
return "\n".join(H) + context.sco_footer(REQUEST) return "\n".join(H) + html_sco_header.sco_footer(context, REQUEST)
def can_edit_sem(context, REQUEST, formsemestre_id="", sem=None): def can_edit_sem(context, REQUEST, formsemestre_id="", sem=None):
@ -186,7 +187,7 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
else: else:
semestre_id_labels.append(sid) semestre_id_labels.append(sid)
# Liste des modules dans ce semestre de cette formation # Liste des modules dans ce semestre de cette formation
# on pourrait faire un simple context.module_list( ) # on pourrait faire un simple module_list( )
# mais si on veut l'ordre du PPN (groupe par UE et matieres) il faut: # mais si on veut l'ordre du PPN (groupe par UE et matieres) il faut:
mods = [] # liste de dicts mods = [] # liste de dicts
uelist = context.do_ue_list({"formation_id": formation_id}) uelist = context.do_ue_list({"formation_id": formation_id})
@ -866,7 +867,7 @@ def formsemestre_clone(context, formsemestre_id, REQUEST=None):
} }
H = [ H = [
context.html_sem_header( html_sco_header.html_sem_header(context,
REQUEST, REQUEST,
"Copie du semestre", "Copie du semestre",
sem, sem,
@ -948,7 +949,7 @@ def formsemestre_clone(context, formsemestre_id, REQUEST=None):
if ndb.DateDMYtoISO(tf[2]["date_debut"]) > ndb.DateDMYtoISO(tf[2]["date_fin"]): if ndb.DateDMYtoISO(tf[2]["date_debut"]) > ndb.DateDMYtoISO(tf[2]["date_fin"]):
msg = '<ul class="tf-msg"><li class="tf-msg">Dates de début et fin incompatibles !</li></ul>' msg = '<ul class="tf-msg"><li class="tf-msg">Dates de début et fin incompatibles !</li></ul>'
if tf[0] == 0 or msg: if tf[0] == 0 or msg:
return "".join(H) + msg + tf[1] + context.sco_footer(REQUEST) return "".join(H) + msg + tf[1] + html_sco_header.sco_footer(context, REQUEST)
elif tf[0] == -1: # cancel elif tf[0] == -1: # cancel
return REQUEST.RESPONSE.redirect( return REQUEST.RESPONSE.redirect(
"formsemestre_status?formsemestre_id=%s" % formsemestre_id "formsemestre_status?formsemestre_id=%s" % formsemestre_id
@ -1222,7 +1223,7 @@ def formsemestre_delete(context, formsemestre_id, REQUEST=None):
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
F = context.formation_list(args={"formation_id": sem["formation_id"]})[0] F = context.formation_list(args={"formation_id": sem["formation_id"]})[0]
H = [ H = [
context.html_sem_header(REQUEST, "Suppression du semestre", sem), html_sco_header.html_sem_header(context, REQUEST, "Suppression du semestre", sem),
"""<div class="ue_warning"><span>Attention !</span> """<div class="ue_warning"><span>Attention !</span>
<p class="help">A n'utiliser qu'en cas d'erreur lors de la saisie d'une formation. Normalement, <p class="help">A n'utiliser qu'en cas d'erreur lors de la saisie d'une formation. Normalement,
<b>un semestre ne doit jamais être supprimé</b> (on perd la mémoire des notes et de tous les événements liés à ce semestre !).</p> <b>un semestre ne doit jamais être supprimé</b> (on perd la mémoire des notes et de tous les événements liés à ce semestre !).</p>
@ -1262,7 +1263,7 @@ def formsemestre_delete(context, formsemestre_id, REQUEST=None):
) )
else: else:
H.append(tf[1]) H.append(tf[1])
return "\n".join(H) + context.sco_footer(REQUEST) return "\n".join(H) + html_sco_header.sco_footer(context, REQUEST)
elif tf[0] == -1: # cancel elif tf[0] == -1: # cancel
return REQUEST.RESPONSE.redirect( return REQUEST.RESPONSE.redirect(
context.NotesURL() context.NotesURL()
@ -1500,7 +1501,7 @@ def formsemestre_edit_uecoefs(context, formsemestre_id, err_ue_id=None, REQUEST=
return err return err
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
footer = context.sco_footer(REQUEST) footer = html_sco_header.sco_footer(context, REQUEST)
help = """<p class="help"> help = """<p class="help">
Seuls les modules ont un coefficient. Cependant, il est nécessaire d'affecter un coefficient aux UE capitalisée pour pouvoir les prendre en compte dans la moyenne générale. Seuls les modules ont un coefficient. Cependant, il est nécessaire d'affecter un coefficient aux UE capitalisée pour pouvoir les prendre en compte dans la moyenne générale.
</p> </p>
@ -1522,7 +1523,7 @@ def formsemestre_edit_uecoefs(context, formsemestre_id, err_ue_id=None, REQUEST=
<p class="warning">Les coefficients indiqués ici ne s'appliquent que pour le traitement des UE capitalisées. <p class="warning">Les coefficients indiqués ici ne s'appliquent que pour le traitement des UE capitalisées.
</p> </p>
""" """
H = [context.html_sem_header(REQUEST, "Coefficients des UE du semestre", sem), help] H = [html_sco_header.html_sem_header(context, REQUEST, "Coefficients des UE du semestre", sem), help]
# #
ues, modimpls = notes_table.get_sem_ues_modimpls(context, formsemestre_id) ues, modimpls = notes_table.get_sem_ues_modimpls(context, formsemestre_id)
for ue in ues: for ue in ues:
@ -1632,7 +1633,7 @@ def formsemestre_edit_uecoefs(context, formsemestre_id, err_ue_id=None, REQUEST=
formsemestre_id=formsemestre_id formsemestre_id=formsemestre_id
) # > modif coef UE cap (modifs notes de _certains_ etudiants) ) # > modif coef UE cap (modifs notes de _certains_ etudiants)
header = context.html_sem_header( header = html_sco_header.html_sem_header(context,
REQUEST, "Coefficients des UE du semestre", sem REQUEST, "Coefficients des UE du semestre", sem
) )
return ( return (

View File

@ -77,7 +77,7 @@ def formsemestre_ext_create_form(context, etudid, formsemestre_id, REQUEST=None)
"""Formulaire creation/inscription à un semestre extérieur""" """Formulaire creation/inscription à un semestre extérieur"""
etud = context.getEtudInfo(etudid=etudid, filled=1)[0] etud = context.getEtudInfo(etudid=etudid, filled=1)[0]
H = [ H = [
context.sco_header(REQUEST), html_sco_header.sco_header(context, REQUEST),
"""<h2>Enregistrement d'une inscription antérieure dans un autre établissement</h2> """<h2>Enregistrement d'une inscription antérieure dans un autre établissement</h2>
<p class="help"> <p class="help">
Cette opération créé un semestre extérieur ("ancien") et y inscrit juste cet étudiant. Cette opération créé un semestre extérieur ("ancien") et y inscrit juste cet étudiant.
@ -94,7 +94,7 @@ def formsemestre_ext_create_form(context, etudid, formsemestre_id, REQUEST=None)
"""<h3><a href="ficheEtud?etudid=%s" class="stdlink">Etudiant %s</a></h3>""" """<h3><a href="ficheEtud?etudid=%s" class="stdlink">Etudiant %s</a></h3>"""
% (etudid, etud["nomprenom"]), % (etudid, etud["nomprenom"]),
] ]
F = context.sco_footer(REQUEST) F = html_sco_header.sco_footer(context, REQUEST)
orig_sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) orig_sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
# Ne propose que des semestres de semestre_id strictement inférieur au semestre courant # Ne propose que des semestres de semestre_id strictement inférieur au semestre courant
# et seulement si pas inscrit au même semestre_id d'un semestre ordinaire ScoDoc. # et seulement si pas inscrit au même semestre_id d'un semestre ordinaire ScoDoc.
@ -259,7 +259,7 @@ def _make_page(context, etud, sem, tf, message="", REQUEST=None):
nt = context._getNotesCache().get_NotesTable(context, sem["formsemestre_id"]) nt = context._getNotesCache().get_NotesTable(context, sem["formsemestre_id"])
moy_gen = nt.get_etud_moy_gen(etud["etudid"]) moy_gen = nt.get_etud_moy_gen(etud["etudid"])
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, REQUEST,
page_title="Validation des UE d'un semestre extérieur", page_title="Validation des UE d'un semestre extérieur",
javascripts=["js/formsemestre_ext_edit_ue_validations.js"], javascripts=["js/formsemestre_ext_edit_ue_validations.js"],
@ -285,7 +285,7 @@ def _make_page(context, etud, sem, tf, message="", REQUEST=None):
</a></div> </a></div>
""" """
% (sem["formsemestre_id"], etud["etudid"]), % (sem["formsemestre_id"], etud["etudid"]),
context.sco_footer(REQUEST), html_sco_header.sco_footer(context, REQUEST),
] ]
return H return H

View File

@ -120,7 +120,7 @@ def formsemestre_inscription_with_modules_form(
Si only_ext, ne montre que les semestre extérieurs. Si only_ext, ne montre que les semestre extérieurs.
""" """
etud = context.getEtudInfo(etudid=etudid, filled=1)[0] etud = context.getEtudInfo(etudid=etudid, filled=1)[0]
H = [context.sco_header(REQUEST), "<h2>Inscription de %s" % etud["nomprenom"]] H = [html_sco_header.sco_header(context, REQUEST), "<h2>Inscription de %s" % etud["nomprenom"]]
if only_ext: if only_ext:
H.append(" dans un semestre extérieur") H.append(" dans un semestre extérieur")
H.append( H.append(
@ -130,7 +130,7 @@ def formsemestre_inscription_with_modules_form(
</p> </p>
<h3>Choisir un semestre:</h3>""" <h3>Choisir un semestre:</h3>"""
) )
F = context.sco_footer(REQUEST) F = html_sco_header.sco_footer(context, REQUEST)
sems = sco_formsemestre.do_formsemestre_list(context, args={"etat": "1"}) sems = sco_formsemestre.do_formsemestre_list(context, args={"etat": "1"})
insem = context.do_formsemestre_inscription_list( insem = context.do_formsemestre_inscription_list(
args={"etudid": etudid, "etat": "I"} args={"etudid": etudid, "etat": "I"}
@ -177,11 +177,11 @@ def formsemestre_inscription_with_modules(
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
etud = context.getEtudInfo(etudid=etudid, filled=1)[0] etud = context.getEtudInfo(etudid=etudid, filled=1)[0]
H = [ H = [
context.html_sem_header( html_sco_header.html_sem_header(context,
REQUEST, "Inscription de %s dans ce semestre" % etud["nomprenom"], sem REQUEST, "Inscription de %s dans ce semestre" % etud["nomprenom"], sem
) )
] ]
F = context.sco_footer(REQUEST) F = html_sco_header.sco_footer(context, REQUEST)
# Check 1: déjà inscrit ici ? # Check 1: déjà inscrit ici ?
ins = context.Notes.do_formsemestre_inscription_list({"etudid": etudid}) ins = context.Notes.do_formsemestre_inscription_list({"etudid": etudid})
already = False already = False
@ -277,9 +277,9 @@ def formsemestre_inscription_option(context, etudid, formsemestre_id, REQUEST=No
context, formsemestre_id context, formsemestre_id
) # > get_etud_ue_status ) # > get_etud_ue_status
F = context.sco_footer(REQUEST) F = html_sco_header.sco_footer(context, REQUEST)
H = [ H = [
context.sco_header(REQUEST) html_sco_header.sco_header(context, REQUEST)
+ "<h2>Inscription de %s aux modules de %s (%s - %s)</h2>" + "<h2>Inscription de %s aux modules de %s (%s - %s)</h2>"
% (etud["nomprenom"], sem["titre_num"], sem["date_debut"], sem["date_fin"]) % (etud["nomprenom"], sem["titre_num"], sem["date_debut"], sem["date_fin"])
] ]
@ -549,13 +549,13 @@ def do_moduleimpl_incription_options(
if REQUEST: if REQUEST:
H = [ H = [
context.sco_header(REQUEST), html_sco_header.sco_header(context, REQUEST),
"""<h3>Modifications effectuées</h3> """<h3>Modifications effectuées</h3>
<p><a class="stdlink" href="%s/ficheEtud?etudid=%s"> <p><a class="stdlink" href="%s/ficheEtud?etudid=%s">
Retour à la fiche étudiant</a></p> Retour à la fiche étudiant</a></p>
""" """
% (context.ScoURL(), etudid), % (context.ScoURL(), etudid),
context.sco_footer(REQUEST), html_sco_header.sco_footer(context, REQUEST),
] ]
return "\n".join(H) return "\n".join(H)
@ -600,7 +600,7 @@ def formsemestre_inscrits_ailleurs(context, formsemestre_id, REQUEST=None):
""" """
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
H = [ H = [
context.html_sem_header( html_sco_header.html_sem_header(context,
REQUEST, "Inscriptions multiples parmi les étudiants du semestre ", sem REQUEST, "Inscriptions multiples parmi les étudiants du semestre ", sem
) )
] ]
@ -639,4 +639,4 @@ def formsemestre_inscrits_ailleurs(context, formsemestre_id, REQUEST=None):
) )
else: else:
H.append("""<p>Aucun étudiant en inscription multiple (c'est normal) !</p>""") H.append("""<p>Aucun étudiant en inscription multiple (c'est normal) !</p>""")
return "\n".join(H) + context.sco_footer(REQUEST) return "\n".join(H) + html_sco_header.sco_footer(context, REQUEST)

View File

@ -687,7 +687,7 @@ def formsemestre_description_table(
base_url="%s?formsemestre_id=%s&with_evals=%s" base_url="%s?formsemestre_id=%s&with_evals=%s"
% (REQUEST.URL0, formsemestre_id, with_evals), % (REQUEST.URL0, formsemestre_id, with_evals),
page_title=title, page_title=title,
html_title=context.html_sem_header( html_title=html_sco_header.html_sem_header(context,
REQUEST, "Description du semestre", sem, with_page_header=False REQUEST, "Description du semestre", sem, with_page_header=False
), ),
pdf_title=title, pdf_title=title,
@ -718,21 +718,7 @@ def formsemestre_description(
return tab.make_page(context, format=format, REQUEST=REQUEST) return tab.make_page(context, format=format, REQUEST=REQUEST)
def formsemestre_lists(context, formsemestre_id, REQUEST=None):
"""Listes des étudiants
XXX (ancienne page, remplacée par groups_view, va être supprimée)
"""
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
H = [
context.html_sem_header(REQUEST, "", sem),
_make_listes_sem(context, sem, REQUEST),
context.sco_footer(REQUEST),
]
return "\n".join(H)
# genere liste html pour accès aux groupes de ce semestre # genere liste html pour accès aux groupes de ce semestre
# XXX #sco8 vérifier si c'est encore utilisé !
def _make_listes_sem(context, sem, REQUEST=None, with_absences=True): def _make_listes_sem(context, sem, REQUEST=None, with_absences=True):
context = context context = context
authuser = REQUEST.AUTHENTICATED_USER authuser = REQUEST.AUTHENTICATED_USER
@ -896,7 +882,7 @@ def formsemestre_status_head(
page_title = page_title or "Modules de " page_title = page_title or "Modules de "
H = [ H = [
context.html_sem_header( html_sco_header.html_sem_header(context,
REQUEST, page_title, sem, with_page_header=False, with_h2=False REQUEST, page_title, sem, with_page_header=False, with_h2=False
), ),
"""<table> """<table>
@ -965,7 +951,9 @@ def formsemestre_status(context, formsemestre_id=None, REQUEST=None):
) )
H = [ H = [
context.sco_header(REQUEST, page_title="Semestre %s" % sem["titreannee"]), html_sco_header.sco_header(
context, REQUEST, page_title="Semestre %s" % sem["titreannee"]
),
'<div class="formsemestre_status">', '<div class="formsemestre_status">',
formsemestre_status_head( formsemestre_status_head(
context, formsemestre_id=formsemestre_id, page_title="Tableau de bord" context, formsemestre_id=formsemestre_id, page_title="Tableau de bord"
@ -1137,7 +1125,11 @@ def formsemestre_status(context, formsemestre_id=None, REQUEST=None):
""" """
) )
# --- LISTE DES ETUDIANTS # --- LISTE DES ETUDIANTS
H += ['<div id="groupes">', context.make_listes_sem(sem, REQUEST), "</div>"] H += [
'<div id="groupes">',
_make_listes_sem(context, sem, REQUEST),
"</div>",
]
# --- Lien mail enseignants: # --- Lien mail enseignants:
adrlist = list(mails_enseignants - set([""])) adrlist = list(mails_enseignants - set([""]))
if adrlist: if adrlist:
@ -1145,4 +1137,4 @@ def formsemestre_status(context, formsemestre_id=None, REQUEST=None):
'<p><a class="stdlink" href="mailto:?cc=%s">Courrier aux %d enseignants du semestre</a></p>' '<p><a class="stdlink" href="mailto:?cc=%s">Courrier aux %d enseignants du semestre</a></p>'
% (",".join(adrlist), len(adrlist)) % (",".join(adrlist), len(adrlist))
) )
return "".join(H) + context.sco_footer(REQUEST) return "".join(H) + html_sco_header.sco_footer(context, REQUEST)

View File

@ -97,7 +97,7 @@ def formsemestre_validation_etud_form(
raise ScoValueError("validation: semestre verrouille") raise ScoValueError("validation: semestre verrouille")
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, REQUEST,
page_title="Parcours %(nomprenom)s" % etud, page_title="Parcours %(nomprenom)s" % etud,
javascripts=["js/recap_parcours.js"], javascripts=["js/recap_parcours.js"],
@ -119,7 +119,7 @@ def formsemestre_validation_etud_form(
% (formsemestre_id, etud_index_next, etud_n["nomprenom"]) % (formsemestre_id, etud_index_next, etud_n["nomprenom"])
) )
Footer.append("</p>") Footer.append("</p>")
Footer.append(context.sco_footer(REQUEST)) Footer.append(html_sco_header.sco_footer(context, REQUEST))
H.append('<table style="width: 100%"><tr><td>') H.append('<table style="width: 100%"><tr><td>')
if not check: if not check:
@ -214,7 +214,7 @@ def formsemestre_validation_etud_form(
'<a href="formsemestre_validation_suppress_etud?etudid=%s&formsemestre_id=%s" class="stdlink">Supprimer décision existante</a>' '<a href="formsemestre_validation_suppress_etud?etudid=%s&formsemestre_id=%s" class="stdlink">Supprimer décision existante</a>'
% (etudid, formsemestre_id) % (etudid, formsemestre_id)
) )
H.append(context.sco_footer(REQUEST)) H.append(html_sco_header.sco_footer(context, REQUEST))
return "\n".join(H) return "\n".join(H)
# Infos sur decisions déjà saisies # Infos sur decisions déjà saisies
@ -257,7 +257,7 @@ def formsemestre_validation_etud_form(
H.append('<input type="hidden" name="sortcol" value="%s"/>' % sortcol) H.append('<input type="hidden" name="sortcol" value="%s"/>' % sortcol)
H.append("</form></div>") H.append("</form></div>")
H.append(context.sco_footer(REQUEST)) H.append(html_sco_header.sco_footer(context, REQUEST))
return "\n".join(H) return "\n".join(H)
# Explication sur barres actuelles # Explication sur barres actuelles
@ -822,7 +822,7 @@ def formsemestre_validation_auto(context, formsemestre_id, REQUEST):
"Formulaire saisie automatisee des decisions d'un semestre" "Formulaire saisie automatisee des decisions d'un semestre"
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
H = [ H = [
context.html_sem_header( html_sco_header.html_sem_header(context,
REQUEST, "Saisie automatique des décisions du semestre", sem REQUEST, "Saisie automatique des décisions du semestre", sem
), ),
""" """
@ -843,7 +843,7 @@ def formsemestre_validation_auto(context, formsemestre_id, REQUEST):
</form> </form>
""" """
% formsemestre_id, % formsemestre_id,
context.sco_footer(REQUEST), html_sco_header.sco_footer(context, REQUEST),
] ]
return "\n".join(H) return "\n".join(H)
@ -913,7 +913,7 @@ def do_formsemestre_validation_auto(context, formsemestre_id, REQUEST):
"do_formsemestre_validation_auto: %d validations, %d conflicts" "do_formsemestre_validation_auto: %d validations, %d conflicts"
% (nb_valid, len(conflicts)) % (nb_valid, len(conflicts))
) )
H = [context.sco_header(REQUEST, page_title="Saisie automatique")] H = [html_sco_header.sco_header(context, REQUEST, page_title="Saisie automatique")]
H.append( H.append(
"""<h2>Saisie automatique des décisions du semestre %s</h2> """<h2>Saisie automatique des décisions du semestre %s</h2>
<p>Opération effectuée.</p> <p>Opération effectuée.</p>
@ -936,7 +936,7 @@ def do_formsemestre_validation_auto(context, formsemestre_id, REQUEST):
'<a href="formsemestre_recapcomplet?formsemestre_id=%s&modejury=1&hidemodules=1&hidebac=1&pref_override=0">continuer</a>' '<a href="formsemestre_recapcomplet?formsemestre_id=%s&modejury=1&hidemodules=1&hidebac=1&pref_override=0">continuer</a>'
% formsemestre_id % formsemestre_id
) )
H.append(context.sco_footer(REQUEST)) H.append(html_sco_header.sco_footer(context, REQUEST))
return "\n".join(H) return "\n".join(H)
@ -1011,7 +1011,7 @@ def formsemestre_fix_validation_ues(context, formsemestre_id, REQUEST=None):
cnx.commit() cnx.commit()
# #
H = [ H = [
context.sco_header(REQUEST, page_title="Réparation des codes UE"), html_sco_header.sco_header(context, REQUEST, page_title="Réparation des codes UE"),
sco_formsemestre_status.formsemestre_status_head( sco_formsemestre_status.formsemestre_status_head(
context, REQUEST=REQUEST, formsemestre_id=formsemestre_id context, REQUEST=REQUEST, formsemestre_id=formsemestre_id
), ),
@ -1026,7 +1026,7 @@ def formsemestre_fix_validation_ues(context, formsemestre_id, REQUEST=None):
context._inval_cache(formsemestre_id=formsemestre_id) # > modif decision UE context._inval_cache(formsemestre_id=formsemestre_id) # > modif decision UE
else: else:
H.append("<h2>Aucune modification: codes UE corrects ou inexistants</h2>") H.append("<h2>Aucune modification: codes UE corrects ou inexistants</h2>")
H.append(context.sco_footer(REQUEST)) H.append(html_sco_header.sco_footer(context, REQUEST))
return "\n".join(H) return "\n".join(H)
@ -1069,7 +1069,7 @@ def formsemestre_validate_previous_ue(context, formsemestre_id, etudid, REQUEST=
Fo = context.formation_list(args={"formation_id": sem["formation_id"]})[0] Fo = context.formation_list(args={"formation_id": sem["formation_id"]})[0]
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, REQUEST,
page_title="Validation UE", page_title="Validation UE",
javascripts=["js/validate_previous_ue.js"], javascripts=["js/validate_previous_ue.js"],
@ -1160,7 +1160,7 @@ def formsemestre_validate_previous_ue(context, formsemestre_id, etudid, REQUEST=
<div id="ue_list_code"><!-- filled by ue_sharing_code --></div> <div id="ue_list_code"><!-- filled by ue_sharing_code --></div>
""" """
warn, ue_multiples = check_formation_ues(context, Fo["formation_id"]) warn, ue_multiples = check_formation_ues(context, Fo["formation_id"])
return "\n".join(H) + tf[1] + X + warn + context.sco_footer(REQUEST) return "\n".join(H) + tf[1] + X + warn + html_sco_header.sco_footer(context, REQUEST)
elif tf[0] == -1: elif tf[0] == -1:
return REQUEST.RESPONSE.redirect( return REQUEST.RESPONSE.redirect(
context.NotesURL() context.NotesURL()

View File

@ -818,7 +818,7 @@ def editPartitionForm(context, formsemestre_id=None, REQUEST=None):
) )
# #
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, page_title="Partitions...", javascripts=["js/editPartitionForm.js"] REQUEST, page_title="Partitions...", javascripts=["js/editPartitionForm.js"]
), ),
r"""<script type="text/javascript"> r"""<script type="text/javascript">
@ -926,7 +926,7 @@ def editPartitionForm(context, formsemestre_id=None, REQUEST=None):
</div> </div>
""" """
) )
return "\n".join(H) + context.sco_footer(REQUEST) return "\n".join(H) + html_sco_header.sco_footer(context, REQUEST)
def partition_set_attr(context, partition_id, attr, value, REQUEST=None): def partition_set_attr(context, partition_id, attr, value, REQUEST=None):
@ -1061,11 +1061,11 @@ def partition_rename(context, partition_id, REQUEST=None):
) )
if tf[0] == 0: if tf[0] == 0:
return ( return (
context.sco_header(REQUEST) html_sco_header.sco_header(context, REQUEST)
+ "\n".join(H) + "\n".join(H)
+ "\n" + "\n"
+ tf[1] + tf[1]
+ context.sco_footer(REQUEST) + html_sco_header.sco_footer(context, REQUEST)
) )
elif tf[0] == -1: elif tf[0] == -1:
return REQUEST.RESPONSE.redirect( return REQUEST.RESPONSE.redirect(
@ -1164,11 +1164,11 @@ def group_rename(context, group_id, REQUEST=None):
) )
if tf[0] == 0: if tf[0] == 0:
return ( return (
context.sco_header(REQUEST) html_sco_header.sco_header(context, REQUEST)
+ "\n".join(H) + "\n".join(H)
+ "\n" + "\n"
+ tf[1] + tf[1]
+ context.sco_footer(REQUEST) + html_sco_header.sco_footer(context, REQUEST)
) )
elif tf[0] == -1: elif tf[0] == -1:
return REQUEST.RESPONSE.redirect( return REQUEST.RESPONSE.redirect(
@ -1207,7 +1207,7 @@ def groups_auto_repartition(context, partition_id=None, REQUEST=None):
] ]
H = [ H = [
context.sco_header(REQUEST, page_title="Répartition des groupes"), html_sco_header.sco_header(context, REQUEST, page_title="Répartition des groupes"),
"<h2>Répartition des groupes de %s</h2>" % partition["partition_name"], "<h2>Répartition des groupes de %s</h2>" % partition["partition_name"],
"<p>Semestre %s</p>" % sem["titreannee"], "<p>Semestre %s</p>" % sem["titreannee"],
"""<p class="help">Les groupes existants seront <b>effacés</b> et remplacés par """<p class="help">Les groupes existants seront <b>effacés</b> et remplacés par
@ -1227,7 +1227,7 @@ def groups_auto_repartition(context, partition_id=None, REQUEST=None):
name="tf", name="tf",
) )
if tf[0] == 0: if tf[0] == 0:
return "\n".join(H) + "\n" + tf[1] + context.sco_footer(REQUEST) return "\n".join(H) + "\n" + tf[1] + html_sco_header.sco_footer(context, REQUEST)
elif tf[0] == -1: elif tf[0] == -1:
return REQUEST.RESPONSE.redirect(dest_url) return REQUEST.RESPONSE.redirect(dest_url)
else: else:
@ -1248,7 +1248,7 @@ def groups_auto_repartition(context, partition_id=None, REQUEST=None):
# checkGroupName(group_name) # checkGroupName(group_name)
# except: # except:
# H.append('<p class="warning">Nom de groupe invalide: %s</p>'%group_name) # H.append('<p class="warning">Nom de groupe invalide: %s</p>'%group_name)
# return '\n'.join(H) + tf[1] + context.sco_footer(REQUEST) # return '\n'.join(H) + tf[1] + html_sco_header.sco_footer(context, REQUEST)
group_ids.append( group_ids.append(
createGroup(context, partition_id, group_name, REQUEST=REQUEST) createGroup(context, partition_id, group_name, REQUEST=REQUEST)
) )

View File

@ -49,7 +49,7 @@ def affectGroups(context, partition_id, REQUEST=None):
raise AccessDenied("vous n'avez pas la permission d'effectuer cette opération") raise AccessDenied("vous n'avez pas la permission d'effectuer cette opération")
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, REQUEST,
page_title="Affectation aux groupes", page_title="Affectation aux groupes",
javascripts=["js/groupmgr.js"], javascripts=["js/groupmgr.js"],
@ -99,6 +99,6 @@ Editer groupes de
</div> </div>
""", """,
context.sco_footer(REQUEST), html_sco_header.sco_footer(context, REQUEST),
] ]
return "\n".join(H) return "\n".join(H)

View File

@ -102,7 +102,7 @@ def groups_view(
) )
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, javascripts=JAVASCRIPTS, cssstyles=CSSSTYLES, init_qtip=True REQUEST, javascripts=JAVASCRIPTS, cssstyles=CSSSTYLES, init_qtip=True
) )
] ]
@ -150,7 +150,7 @@ def groups_view(
) )
) )
H.append(context.sco_footer(REQUEST)) H.append(html_sco_header.sco_footer(context, REQUEST))
return "\n".join(H) return "\n".join(H)

View File

@ -33,6 +33,7 @@ from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText from email.mime.text import MIMEText
from email.header import Header from email.header import Header
import mails
import notesdb as ndb import notesdb as ndb
import sco_utils as scu import sco_utils as scu
from notes_log import log from notes_log import log
@ -231,4 +232,4 @@ Pour plus d'informations sur ce logiciel, voir %s
msg.epilogue = "" msg.epilogue = ""
txt = MIMEText(txt, "plain", scu.SCO_ENCODING) txt = MIMEText(txt, "plain", scu.SCO_ENCODING)
msg.attach(txt) msg.attach(txt)
context.sendEmail(msg) mails.sendEmail(context, msg)

View File

@ -278,8 +278,8 @@ def formsemestre_inscr_passage(
# -- check lock # -- check lock
if sem["etat"] != "1": if sem["etat"] != "1":
raise ScoValueError("opération impossible: semestre verrouille") raise ScoValueError("opération impossible: semestre verrouille")
header = context.sco_header(REQUEST, page_title="Passage des étudiants") header = html_sco_header.sco_header(context, REQUEST, page_title="Passage des étudiants")
footer = context.sco_footer(REQUEST) footer = html_sco_header.sco_footer(context, REQUEST)
H = [header] H = [header]
if type(etuds) == type(""): if type(etuds) == type(""):
etuds = etuds.split(",") # vient du form de confirmation etuds = etuds.split(",") # vient du form de confirmation
@ -412,7 +412,7 @@ def build_page(
inscrit_groupes_checked = "" inscrit_groupes_checked = ""
H = [ H = [
context.html_sem_header( html_sco_header.html_sem_header(context,
REQUEST, "Passages dans le semestre", sem, with_page_header=False REQUEST, "Passages dans le semestre", sem, with_page_header=False
), ),
"""<form method="post" action="%s">""" % REQUEST.URL0, """<form method="post" action="%s">""" % REQUEST.URL0,

View File

@ -775,7 +775,7 @@ def evaluation_check_absences_html(
if with_header: if with_header:
H = [ H = [
context.html_sem_header(REQUEST, "Vérification absences à l'évaluation"), html_sco_header.html_sem_header(context, REQUEST, "Vérification absences à l'évaluation"),
sco_evaluations.evaluation_describe( sco_evaluations.evaluation_describe(
context, evaluation_id=evaluation_id, REQUEST=REQUEST context, evaluation_id=evaluation_id, REQUEST=REQUEST
), ),
@ -851,7 +851,7 @@ def evaluation_check_absences_html(
etudlist(AbsButExc) etudlist(AbsButExc)
if with_header: if with_header:
H.append(context.sco_footer(REQUEST)) H.append(html_sco_header.sco_footer(context, REQUEST))
return "\n".join(H) return "\n".join(H)
@ -859,7 +859,7 @@ def formsemestre_check_absences_html(context, formsemestre_id, REQUEST=None):
"""Affiche etat verification absences pour toutes les evaluations du semestre !""" """Affiche etat verification absences pour toutes les evaluations du semestre !"""
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
H = [ H = [
context.html_sem_header( html_sco_header.html_sem_header(context,
REQUEST, "Vérification absences aux évaluations de ce semestre", sem REQUEST, "Vérification absences aux évaluations de ce semestre", sem
), ),
"""<p class="help">Vérification de la cohérence entre les notes saisies et les absences signalées. """<p class="help">Vérification de la cohérence entre les notes saisies et les absences signalées.
@ -890,5 +890,5 @@ def formsemestre_check_absences_html(context, formsemestre_id, REQUEST=None):
) )
if evals: if evals:
H.append("</div>") H.append("</div>")
H.append(context.sco_footer(REQUEST)) H.append(html_sco_header.sco_footer(context, REQUEST))
return "\n".join(H) return "\n".join(H)

View File

@ -78,7 +78,7 @@ def scodoc_table_etuds_lycees(context, format="html", REQUEST=None):
if format != "html": if format != "html":
return t return t
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, REQUEST,
page_title=tab.page_title, page_title=tab.page_title,
init_google_maps=True, init_google_maps=True,
@ -91,7 +91,7 @@ def scodoc_table_etuds_lycees(context, format="html", REQUEST=None):
"""<div id="lyc_map_canvas"></div> """<div id="lyc_map_canvas"></div>
""", """,
js_coords_lycees(etuds_by_lycee), js_coords_lycees(etuds_by_lycee),
context.sco_footer(REQUEST), html_sco_header.sco_footer(context, REQUEST),
] ]
return "\n".join(H) return "\n".join(H)
@ -194,7 +194,7 @@ def formsemestre_etuds_lycees(
) )
] ]
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, REQUEST,
page_title=tab.page_title, page_title=tab.page_title,
init_google_maps=True, init_google_maps=True,
@ -207,7 +207,7 @@ def formsemestre_etuds_lycees(
"""<div id="lyc_map_canvas"></div> """<div id="lyc_map_canvas"></div>
""", """,
js_coords_lycees(etuds_by_lycee), js_coords_lycees(etuds_by_lycee),
context.sco_footer(REQUEST), html_sco_header.sco_footer(context, REQUEST),
] ]
return "\n".join(H) return "\n".join(H)

View File

@ -62,13 +62,13 @@ def moduleimpl_inscriptions_edit(
# -- check lock # -- check lock
if sem["etat"] != "1": if sem["etat"] != "1":
raise ScoValueError("opération impossible: semestre verrouille") raise ScoValueError("opération impossible: semestre verrouille")
header = context.sco_header( header = html_sco_header.sco_header(context,
REQUEST, REQUEST,
page_title="Inscription au module", page_title="Inscription au module",
init_qtip=True, init_qtip=True,
javascripts=["js/etud_info.js"], javascripts=["js/etud_info.js"],
) )
footer = context.sco_footer(REQUEST) footer = html_sco_header.sco_footer(context, REQUEST)
H = [ H = [
header, header,
"""<h2>Inscriptions au module <a href="moduleimpl_status?moduleimpl_id=%s">%s</a> (%s)</a></h2> """<h2>Inscriptions au module <a href="moduleimpl_status?moduleimpl_id=%s">%s</a> (%s)</a></h2>
@ -273,7 +273,7 @@ def moduleimpl_inscriptions_stats(context, formsemestre_id, REQUEST=None):
mod["nb_inscrits"] = nb_inscrits mod["nb_inscrits"] = nb_inscrits
options.append(mod) options.append(mod)
# Page HTML: # Page HTML:
H = [context.html_sem_header(REQUEST, "Inscriptions aux modules du semestre")] H = [html_sco_header.html_sem_header(context, REQUEST, "Inscriptions aux modules du semestre")]
H.append("<h3>Inscrits au semestre: %d étudiants</h3>" % len(inscrits)) H.append("<h3>Inscrits au semestre: %d étudiants</h3>" % len(inscrits))
@ -393,7 +393,7 @@ def moduleimpl_inscriptions_stats(context, formsemestre_id, REQUEST=None):
""" """
) )
H.append(context.sco_footer(REQUEST)) H.append(html_sco_header.sco_footer(context, REQUEST))
return "\n".join(H) return "\n".join(H)

View File

@ -162,7 +162,7 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
arrow_up, arrow_down, arrow_none = sco_groups.getArrowIconsTags(context, REQUEST) arrow_up, arrow_down, arrow_none = sco_groups.getArrowIconsTags(context, REQUEST)
# #
H = [ H = [
context.sco_header(REQUEST, page_title="Module %(titre)s" % Mod), html_sco_header.sco_header(context, REQUEST, page_title="Module %(titre)s" % Mod),
"""<h2 class="formsemestre">Module <tt>%(code)s</tt> %(titre)s</h2>""" % Mod, """<h2 class="formsemestre">Module <tt>%(code)s</tt> %(titre)s</h2>""" % Mod,
# XXX """caneditevals=%s caneditnotes=%s""" % (caneditevals,caneditnotes), # XXX """caneditevals=%s caneditnotes=%s""" % (caneditevals,caneditnotes),
"""<div class="moduleimpl_tableaubord"> """<div class="moduleimpl_tableaubord">
@ -619,5 +619,5 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
scu.icontag("status_visible_img"), scu.icontag("status_visible_img"),
) )
) )
H.append(context.sco_footer(REQUEST)) H.append(html_sco_header.sco_footer(context, REQUEST))
return "".join(H) return "".join(H)

View File

@ -39,6 +39,7 @@ from email.header import Header
import notesdb as ndb # pylint: disable=unused-wildcard-import import notesdb as ndb # pylint: disable=unused-wildcard-import
from notes_log import log from notes_log import log
import mails
import scolars import scolars
from sco_utils import SCO_ENCODING, SCO_ANNONCES_WEBSITE from sco_utils import SCO_ENCODING, SCO_ANNONCES_WEBSITE
import sco_formsemestre import sco_formsemestre
@ -298,4 +299,4 @@ def _send_news_by_mail(context, n):
del msg["To"] del msg["To"]
msg["To"] = email_addr msg["To"] = email_addr
# log('xxx mail: %s' % msg) # log('xxx mail: %s' % msg)
context.sendEmail(msg) mails.sendEmail(context, msg)

View File

@ -42,6 +42,7 @@ import sco_formsemestre
from scolars import format_telephone, format_pays, make_etud_args from scolars import format_telephone, format_pays, make_etud_args
import sco_formsemestre_status import sco_formsemestre_status
import htmlutils import htmlutils
import html_sco_header
from sco_bulletins import etud_descr_situation_semestre from sco_bulletins import etud_descr_situation_semestre
import sco_parcours_dut import sco_parcours_dut
import sco_codes_parcours import sco_codes_parcours
@ -481,7 +482,7 @@ def ficheEtud(context, etudid=None, REQUEST=None):
</div> </div>
""" """
header = context.sco_header( header = html_sco_header.sco_header(context,
REQUEST, REQUEST,
page_title="Fiche étudiant %(prenom)s %(nom)s" % info, page_title="Fiche étudiant %(prenom)s %(nom)s" % info,
cssstyles=["libjs/jQuery-tagEditor/jquery.tag-editor.css"], cssstyles=["libjs/jQuery-tagEditor/jquery.tag-editor.css"],
@ -494,7 +495,7 @@ def ficheEtud(context, etudid=None, REQUEST=None):
"js/etud_debouche.js", "js/etud_debouche.js",
], ],
) )
return header + tmpl % info + context.sco_footer(REQUEST) return header + tmpl % info + html_sco_header.sco_footer(context, REQUEST)
def menus_etud(context, REQUEST=None): def menus_etud(context, REQUEST=None):
@ -592,9 +593,9 @@ def etud_info_html(context, etudid, with_photo="1", REQUEST=None, debug=False):
H += "</div>" H += "</div>"
if debug: if debug:
return ( return (
context.standard_html_header(context) html_sco_header.standard_html_header()
+ H + H
+ context.standard_html_footer(context) + html_sco_header.standard_html_footer()
) )
else: else:
return H return H

View File

@ -406,7 +406,7 @@ def placement_eval_selectetuds(context, evaluation_id, REQUEST=None):
page_title = 'Placement "%s"' % theeval["description"] page_title = 'Placement "%s"' % theeval["description"]
else: else:
page_title = "Placement des étudiants" page_title = "Placement des étudiants"
H = [context.sco_header(REQUEST, page_title=page_title)] H = [html_sco_header.sco_header(context, REQUEST, page_title=page_title)]
formid = "placementfile" formid = "placementfile"
if not REQUEST.form.get("%s-submitted" % formid, False): if not REQUEST.form.get("%s-submitted" % formid, False):
@ -436,7 +436,7 @@ def placement_eval_selectetuds(context, evaluation_id, REQUEST=None):
</ul> </ul>
""" """
) )
H.append(context.sco_footer(REQUEST)) H.append(html_sco_header.sco_footer(context, REQUEST))
return "\n".join(H) return "\n".join(H)

View File

@ -1941,7 +1941,7 @@ class sco_base_preferences:
def edit(self, REQUEST): def edit(self, REQUEST):
"""HTML dialog: edit global preferences""" """HTML dialog: edit global preferences"""
H = [ H = [
self.context.sco_header(REQUEST, page_title="Préférences"), self.html_sco_header.sco_header(context, REQUEST, page_title="Préférences"),
"<h2>Préférences globales pour %s</h2>" % self.context.ScoURL(), "<h2>Préférences globales pour %s</h2>" % self.context.ScoURL(),
"""<p class="help">Ces paramètres s'appliquent par défaut à tous les semestres, sauf si ceux-ci définissent des valeurs spécifiques.</p> """<p class="help">Ces paramètres s'appliquent par défaut à tous les semestres, sauf si ceux-ci définissent des valeurs spécifiques.</p>
<p class="msg">Attention: cliquez sur "Enregistrer les modifications" en bas de page pour appliquer vos changements !</p> <p class="msg">Attention: cliquez sur "Enregistrer les modifications" en bas de page pour appliquer vos changements !</p>
@ -1956,7 +1956,7 @@ class sco_base_preferences:
submitlabel="Enregistrer les modifications", submitlabel="Enregistrer les modifications",
) )
if tf[0] == 0: if tf[0] == 0:
return "\n".join(H) + tf[1] + self.context.sco_footer(REQUEST) return "\n".join(H) + tf[1] + self.html_sco_header.sco_footer(context, REQUEST)
elif tf[0] == -1: elif tf[0] == -1:
return REQUEST.RESPONSE.redirect(self.context.ScoURL()) # cancel return REQUEST.RESPONSE.redirect(self.context.ScoURL()) # cancel
else: else:
@ -2065,7 +2065,7 @@ function set_global_pref(el, pref_name) {
+ "/formsemestre_status?formsemestre_id=%s" % self.formsemestre_id + "/formsemestre_status?formsemestre_id=%s" % self.formsemestre_id
) )
if tf[0] == 0: if tf[0] == 0:
return "\n".join(H) + tf[1] + self.context.sco_footer(REQUEST) return "\n".join(H) + tf[1] + self.html_sco_header.sco_footer(context, REQUEST)
elif tf[0] == -1: elif tf[0] == -1:
return REQUEST.RESPONSE.redirect( return REQUEST.RESPONSE.redirect(
dest_url + "&head_message=Annulé" dest_url + "&head_message=Annulé"

View File

@ -498,13 +498,13 @@ def formsemestre_pvjury(
"""Page récapitulant les décisions de jury """Page récapitulant les décisions de jury
dpv: result of dict_pvjury dpv: result of dict_pvjury
""" """
footer = context.sco_footer(REQUEST) footer = html_sco_header.sco_footer(context, REQUEST)
dpv = dict_pvjury(context, formsemestre_id, with_prev=True) dpv = dict_pvjury(context, formsemestre_id, with_prev=True)
if not dpv: if not dpv:
if format == "html": if format == "html":
return ( return (
context.sco_header(REQUEST) html_sco_header.sco_header(context, REQUEST)
+ "<h2>Aucune information disponible !</h2>" + "<h2>Aucune information disponible !</h2>"
+ footer + footer
) )
@ -540,7 +540,7 @@ def formsemestre_pvjury(
) )
tab.base_url = "%s?formsemestre_id=%s" % (REQUEST.URL0, formsemestre_id) tab.base_url = "%s?formsemestre_id=%s" % (REQUEST.URL0, formsemestre_id)
H = [ H = [
context.html_sem_header( html_sco_header.html_sem_header(context,
REQUEST, REQUEST,
"Décisions du jury pour le semestre", "Décisions du jury pour le semestre",
sem, sem,
@ -629,7 +629,7 @@ def formsemestre_pvjury_pdf(
etudids = [m["etudid"] for m in groups_infos.members] etudids = [m["etudid"] for m in groups_infos.members]
H = [ H = [
context.html_sem_header( html_sco_header.html_sem_header(context,
REQUEST, REQUEST,
"Edition du PV de jury %s" % etuddescr, "Edition du PV de jury %s" % etuddescr,
sem=sem, sem=sem,
@ -645,7 +645,7 @@ def formsemestre_pvjury_pdf(
F = [ F = [
"""<p><em>Voir aussi si besoin les réglages sur la page "Paramétrage" (accessible à l'administrateur du département).</em> """<p><em>Voir aussi si besoin les réglages sur la page "Paramétrage" (accessible à l'administrateur du département).</em>
</p>""", </p>""",
context.sco_footer(REQUEST), html_sco_header.sco_footer(context, REQUEST),
] ]
descr = descrform_pvjury(context, sem) descr = descrform_pvjury(context, sem)
if etudid: if etudid:
@ -811,7 +811,7 @@ def formsemestre_lettres_individuelles(
etudids = [m["etudid"] for m in groups_infos.members] etudids = [m["etudid"] for m in groups_infos.members]
H = [ H = [
context.html_sem_header( html_sco_header.html_sem_header(context,
REQUEST, REQUEST,
"Edition des lettres individuelles", "Edition des lettres individuelles",
sem=sem, sem=sem,
@ -824,7 +824,7 @@ def formsemestre_lettres_individuelles(
""" """
% formsemestre_id, % formsemestre_id,
] ]
F = context.sco_footer(REQUEST) F = html_sco_header.sco_footer(context, REQUEST)
descr = descrform_lettres_individuelles() descr = descrform_lettres_individuelles()
menu_choix_groupe = ( menu_choix_groupe = (
"""<div class="group_ids_sel_menu">Groupes d'étudiants à lister: """ """<div class="group_ids_sel_menu">Groupes d'étudiants à lister: """

View File

@ -84,7 +84,7 @@ def formsemestre_recapcomplet(
H = [] H = []
if not isFile: if not isFile:
H += [ H += [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, REQUEST,
page_title="Récapitulatif", page_title="Récapitulatif",
no_side_bar=True, no_side_bar=True,
@ -183,7 +183,7 @@ def formsemestre_recapcomplet(
<p class="infop">utilise les coefficients d'UE pour calculer la moyenne générale.</p> <p class="infop">utilise les coefficients d'UE pour calculer la moyenne générale.</p>
""" """
) )
H.append(context.sco_footer(REQUEST)) H.append(html_sco_header.sco_footer(context, REQUEST))
return "".join(H) # HTML or binary data... return "".join(H) # HTML or binary data...

View File

@ -355,7 +355,7 @@ def formsemestre_report_counts(
if format != "html": if format != "html":
return t return t
H = [ H = [
context.sco_header(REQUEST, page_title=title), html_sco_header.sco_header(context, REQUEST, page_title=title),
t, t,
"\n".join(F), "\n".join(F),
"""<p class="help">Le tableau affiche le nombre d'étudiants de ce semestre dans chacun """<p class="help">Le tableau affiche le nombre d'étudiants de ce semestre dans chacun
@ -363,7 +363,7 @@ def formsemestre_report_counts(
pour les lignes et les colonnes. Le <tt>codedecision</tt> est le code de la décision pour les lignes et les colonnes. Le <tt>codedecision</tt> est le code de la décision
du jury. du jury.
</p>""", </p>""",
context.sco_footer(REQUEST), html_sco_header.sco_footer(context, REQUEST),
] ]
return "\n".join(H) return "\n".join(H)
@ -744,7 +744,7 @@ def formsemestre_suivi_cohorte(
) )
H = [ H = [
context.sco_header(REQUEST, page_title=tab.page_title), html_sco_header.sco_header(context, REQUEST, page_title=tab.page_title),
"""<h2 class="formsemestre">Suivi cohorte: devenir des étudiants de ce semestre</h2>""", """<h2 class="formsemestre">Suivi cohorte: devenir des étudiants de ce semestre</h2>""",
_gen_form_selectetuds( _gen_form_selectetuds(
formsemestre_id, formsemestre_id,
@ -765,7 +765,7 @@ def formsemestre_suivi_cohorte(
t, t,
help, help,
expl, expl,
context.sco_footer(REQUEST), html_sco_header.sco_footer(context, REQUEST),
] ]
return "\n".join(H) return "\n".join(H)
@ -1215,7 +1215,7 @@ def formsemestre_suivi_parcours(
] ]
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, REQUEST,
page_title=tab.page_title, page_title=tab.page_title,
init_qtip=True, init_qtip=True,
@ -1224,7 +1224,7 @@ def formsemestre_suivi_parcours(
"""<h2 class="formsemestre">Parcours suivis par les étudiants de ce semestre</h2>""", """<h2 class="formsemestre">Parcours suivis par les étudiants de ce semestre</h2>""",
"\n".join(F), "\n".join(F),
t, t,
context.sco_footer(REQUEST), html_sco_header.sco_footer(context, REQUEST),
] ]
return "\n".join(H) return "\n".join(H)
@ -1543,7 +1543,7 @@ def formsemestre_graph_parcours(
) )
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, REQUEST,
page_title="Parcours étudiants de %(titreannee)s" % sem, page_title="Parcours étudiants de %(titreannee)s" % sem,
no_side_bar=True, no_side_bar=True,
@ -1582,7 +1582,7 @@ def formsemestre_graph_parcours(
passant la souris sur le chiffre). passant la souris sur le chiffre).
</p>""" </p>"""
% MAX_ETUD_IN_DESCR, % MAX_ETUD_IN_DESCR,
context.sco_footer(REQUEST), html_sco_header.sco_footer(context, REQUEST),
] ]
REQUEST.RESPONSE.setHeader("content-type", "application/xhtml+xml") REQUEST.RESPONSE.setHeader("content-type", "application/xhtml+xml")
return "\n".join(H) return "\n".join(H)

View File

@ -342,10 +342,10 @@ def do_evaluation_set_missing(
diag = "Valeur %s invalide" % value diag = "Valeur %s invalide" % value
if diag: if diag:
return ( return (
context.sco_header(REQUEST) html_sco_header.sco_header(context, REQUEST)
+ '<h2>%s</h2><p><a href="saisie_notes?evaluation_id=%s">Recommencer</a>' + '<h2>%s</h2><p><a href="saisie_notes?evaluation_id=%s">Recommencer</a>'
% (diag, evaluation_id) % (diag, evaluation_id)
+ context.sco_footer(REQUEST) + html_sco_header.sco_footer(context, REQUEST)
) )
# Confirm action # Confirm action
if not dialog_confirmed: if not dialog_confirmed:
@ -381,7 +381,7 @@ def do_evaluation_set_missing(
url=mod["url"], url=mod["url"],
) )
return ( return (
context.sco_header(REQUEST) html_sco_header.sco_header(context, REQUEST)
+ """<h2>%d notes changées</h2> + """<h2>%d notes changées</h2>
<ul> <ul>
<li><a class="stdlink" href="saisie_notes?evaluation_id=%s"> <li><a class="stdlink" href="saisie_notes?evaluation_id=%s">
@ -391,7 +391,7 @@ def do_evaluation_set_missing(
</ul> </ul>
""" """
% (nb_changed, evaluation_id, M["moduleimpl_id"]) % (nb_changed, evaluation_id, M["moduleimpl_id"])
+ context.sco_footer(REQUEST) + html_sco_header.sco_footer(context, REQUEST)
) )
@ -458,7 +458,7 @@ def evaluation_suppress_alln(context, evaluation_id, REQUEST, dialog_confirmed=F
url=mod["url"], url=mod["url"],
) )
return context.sco_header(REQUEST) + "\n".join(H) + context.sco_footer(REQUEST) return html_sco_header.sco_header(context, REQUEST) + "\n".join(H) + html_sco_header.sco_footer(context, REQUEST)
def _notes_add(context, uid, evaluation_id, notes, comment=None, do_it=True): def _notes_add(context, uid, evaluation_id, notes, comment=None, do_it=True):
@ -601,14 +601,14 @@ def saisie_notes_tableur(context, evaluation_id, group_ids=[], REQUEST=None):
formsemestre_id = M["formsemestre_id"] formsemestre_id = M["formsemestre_id"]
if not can_edit_notes(context, authuser, E["moduleimpl_id"]): if not can_edit_notes(context, authuser, E["moduleimpl_id"]):
return ( return (
context.sco_header(REQUEST) html_sco_header.sco_header(context, REQUEST)
+ "<h2>Modification des notes impossible pour %s</h2>" % authusername + "<h2>Modification des notes impossible pour %s</h2>" % authusername
+ """<p>(vérifiez que le semestre n'est pas verrouillé et que vous + """<p>(vérifiez que le semestre n'est pas verrouillé et que vous
avez l'autorisation d'effectuer cette opération)</p> avez l'autorisation d'effectuer cette opération)</p>
<p><a href="moduleimpl_status?moduleimpl_id=%s">Continuer</a></p> <p><a href="moduleimpl_status?moduleimpl_id=%s">Continuer</a></p>
""" """
% E["moduleimpl_id"] % E["moduleimpl_id"]
+ context.sco_footer(REQUEST) + html_sco_header.sco_footer(context, REQUEST)
) )
if E["description"]: if E["description"]:
@ -627,7 +627,7 @@ def saisie_notes_tableur(context, evaluation_id, group_ids=[], REQUEST=None):
) )
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, REQUEST,
page_title=page_title, page_title=page_title,
javascripts=sco_groups_view.JAVASCRIPTS, javascripts=sco_groups_view.JAVASCRIPTS,
@ -762,7 +762,7 @@ def saisie_notes_tableur(context, evaluation_id, group_ids=[], REQUEST=None):
</ol> </ol>
""" """
) )
H.append(context.sco_footer(REQUEST)) H.append(html_sco_header.sco_footer(context, REQUEST))
return "\n".join(H) return "\n".join(H)
@ -881,14 +881,14 @@ def saisie_notes(context, evaluation_id, group_ids=[], REQUEST=None):
# (admin, respformation, and responsable_id) # (admin, respformation, and responsable_id)
if not can_edit_notes(context, authuser, E["moduleimpl_id"]): if not can_edit_notes(context, authuser, E["moduleimpl_id"]):
return ( return (
context.sco_header(REQUEST) html_sco_header.sco_header(context, REQUEST)
+ "<h2>Modification des notes impossible pour %s</h2>" % authusername + "<h2>Modification des notes impossible pour %s</h2>" % authusername
+ """<p>(vérifiez que le semestre n'est pas verrouillé et que vous + """<p>(vérifiez que le semestre n'est pas verrouillé et que vous
avez l'autorisation d'effectuer cette opération)</p> avez l'autorisation d'effectuer cette opération)</p>
<p><a href="moduleimpl_status?moduleimpl_id=%s">Continuer</a></p> <p><a href="moduleimpl_status?moduleimpl_id=%s">Continuer</a></p>
""" """
% E["moduleimpl_id"] % E["moduleimpl_id"]
+ context.sco_footer(REQUEST) + html_sco_header.sco_footer(context, REQUEST)
) )
# Informations sur les groupes à afficher: # Informations sur les groupes à afficher:
@ -908,7 +908,7 @@ def saisie_notes(context, evaluation_id, group_ids=[], REQUEST=None):
# HTML page: # HTML page:
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, REQUEST,
page_title=page_title, page_title=page_title,
javascripts=sco_groups_view.JAVASCRIPTS + ["js/saisie_notes.js"], javascripts=sco_groups_view.JAVASCRIPTS + ["js/saisie_notes.js"],
@ -977,7 +977,7 @@ def saisie_notes(context, evaluation_id, group_ids=[], REQUEST=None):
</div>""" </div>"""
) )
H.append(context.sco_footer(REQUEST)) H.append(html_sco_header.sco_footer(context, REQUEST))
return "\n".join(H) return "\n".join(H)

View File

@ -466,7 +466,7 @@ def semset_page(context, format="html", REQUEST=None):
page_title = "Ensembles de semestres" page_title = "Ensembles de semestres"
H = [ H = [
context.sco_header( html_sco_header.sco_header(context,
REQUEST, REQUEST,
page_title=page_title, page_title=page_title,
init_qtip=True, init_qtip=True,
@ -526,4 +526,4 @@ def semset_page(context, format="html", REQUEST=None):
""" """
) )
return "\n".join(H) + context.sco_footer(REQUEST) return "\n".join(H) + html_sco_header.sco_footer(context, REQUEST)

View File

@ -105,8 +105,8 @@ def formsemestre_synchro_etuds(
""" """
% sem % sem
) )
header = context.sco_header(REQUEST, page_title="Synchronisation étudiants") header = html_sco_header.sco_header(context, REQUEST, page_title="Synchronisation étudiants")
footer = context.sco_footer(REQUEST) footer = html_sco_header.sco_footer(context, REQUEST)
base_url = "%s?formsemestre_id=%s" % (REQUEST.URL0, formsemestre_id) base_url = "%s?formsemestre_id=%s" % (REQUEST.URL0, formsemestre_id)
if anneeapogee: if anneeapogee:
base_url += "&anneeapogee=%s" % anneeapogee base_url += "&anneeapogee=%s" % anneeapogee

View File

@ -95,11 +95,11 @@ def trombino(
return _listeappel_photos_pdf(context, groups_infos, REQUEST) return _listeappel_photos_pdf(context, groups_infos, REQUEST)
else: else:
raise Exception("invalid format") raise Exception("invalid format")
# return _trombino_html_header(context, REQUEST) + trombino_html(context, group, members, REQUEST=REQUEST) + context.sco_footer(REQUEST) # return _trombino_html_header(context, REQUEST) + trombino_html(context, group, members, REQUEST=REQUEST) + html_sco_header.sco_footer(context, REQUEST)
def _trombino_html_header(context, REQUEST): def _trombino_html_header(context, REQUEST):
return context.sco_header(REQUEST, javascripts=["js/trombino.js"]) return html_sco_header.sco_header(context, REQUEST, javascripts=["js/trombino.js"])
def trombino_html(context, groups_infos, REQUEST=None): def trombino_html(context, groups_infos, REQUEST=None):
@ -242,8 +242,8 @@ def trombino_copy_photos(context, group_ids=[], REQUEST=None, dialog_confirmed=F
back_url = "groups_view?%s&curtab=tab-photos" % groups_infos.groups_query_args back_url = "groups_view?%s&curtab=tab-photos" % groups_infos.groups_query_args
portal_url = sco_portal_apogee.get_portal_url(context) portal_url = sco_portal_apogee.get_portal_url(context)
header = context.sco_header(REQUEST, page_title="Chargement des photos") header = html_sco_header.sco_header(context, REQUEST, page_title="Chargement des photos")
footer = context.sco_footer(REQUEST) footer = html_sco_header.sco_footer(context, REQUEST)
if not portal_url: if not portal_url:
return ( return (
header header
@ -490,7 +490,7 @@ def photos_import_files_form(context, group_ids=[], REQUEST=None):
back_url = "groups_view?%s&curtab=tab-photos" % groups_infos.groups_query_args back_url = "groups_view?%s&curtab=tab-photos" % groups_infos.groups_query_args
H = [ H = [
context.sco_header(REQUEST, page_title="Import des photos des étudiants"), html_sco_header.sco_header(context, REQUEST, page_title="Import des photos des étudiants"),
"""<h2 class="formsemestre">Téléchargement des photos des étudiants</h2> """<h2 class="formsemestre">Téléchargement des photos des étudiants</h2>
<p><b>Vous pouvez aussi charger les photos individuellement via la fiche de chaque étudiant (menu "Etudiant" / "Changer la photo").</b></p> <p><b>Vous pouvez aussi charger les photos individuellement via la fiche de chaque étudiant (menu "Etudiant" / "Changer la photo").</b></p>
<p class="help">Cette page permet de charger en une seule fois les photos de plusieurs étudiants.<br/> <p class="help">Cette page permet de charger en une seule fois les photos de plusieurs étudiants.<br/>
@ -508,7 +508,7 @@ def photos_import_files_form(context, group_ids=[], REQUEST=None):
""" """
% groups_infos.groups_query_args, % groups_infos.groups_query_args,
] ]
F = context.sco_footer(REQUEST) F = html_sco_header.sco_footer(context, REQUEST)
REQUEST.form["group_ids"] = groups_infos.group_ids REQUEST.form["group_ids"] = groups_infos.group_ids
tf = TrivialFormulator( tf = TrivialFormulator(
REQUEST.URL0, REQUEST.URL0,

View File

@ -219,7 +219,7 @@ def external_ue_create_form(context, formsemestre_id, etudid, REQUEST=None):
existing_external_ue = get_existing_external_ue(context, formation_id) existing_external_ue = get_existing_external_ue(context, formation_id)
H = [ H = [
context.html_sem_header( html_sco_header.html_sem_header(context,
REQUEST, REQUEST,
"Ajout d'une UE externe pour %(nomprenom)s" % etud, "Ajout d'une UE externe pour %(nomprenom)s" % etud,
sem, sem,
@ -233,7 +233,7 @@ def external_ue_create_form(context, formsemestre_id, etudid, REQUEST=None):
</p> </p>
""", """,
] ]
html_footer = context.sco_footer(REQUEST) html_footer = html_sco_header.sco_footer(context, REQUEST)
Fo = context.formation_list(args={"formation_id": sem["formation_id"]})[0] Fo = context.formation_list(args={"formation_id": sem["formation_id"]})[0]
parcours = sco_codes_parcours.get_parcours_from_code(Fo["type_parcours"]) parcours = sco_codes_parcours.get_parcours_from_code(Fo["type_parcours"])
ue_types = parcours.ALLOWED_UE_TYPES ue_types = parcours.ALLOWED_UE_TYPES

View File

@ -936,6 +936,6 @@ def confirm_dialog(
if helpmsg: if helpmsg:
H.append('<p class="help">' + helpmsg + "</p>") H.append('<p class="help">' + helpmsg + "</p>")
if add_headers and REQUEST: if add_headers and REQUEST:
return context.sco_header(REQUEST) + "\n".join(H) + context.sco_footer(REQUEST) return html_sco_header.sco_header(context, REQUEST) + "\n".join(H) + html_sco_header.sco_footer(context, REQUEST)
else: else:
return "\n".join(H) return "\n".join(H)

View File

@ -29,6 +29,7 @@
""" """
import time import time
import mail
import sco_utils as scu import sco_utils as scu
from sco_utils import SCO_ENCODING from sco_utils import SCO_ENCODING
from sco_exceptions import ScoGenError, ScoValueError from sco_exceptions import ScoGenError, ScoValueError
@ -455,7 +456,7 @@ def notify_etud_change(context, email_addr, etud, before, after, subject):
msg["To"] = email_addr msg["To"] = email_addr
mime_txt = MIMEText(txt, "plain", SCO_ENCODING) mime_txt = MIMEText(txt, "plain", SCO_ENCODING)
msg.attach(mime_txt) msg.attach(mime_txt)
context.sendEmail(msg) mails.sendEmail(context, msg)
return txt return txt

View File

@ -704,7 +704,9 @@ def SignaleAbsenceGrHebdo(
) )
if not groups_infos.members: if not groups_infos.members:
return ( return (
context.sco_header(page_title="Saisie des absences", REQUEST=REQUEST) html_sco_header.sco_header(
context, page_title="Saisie des absences", REQUEST=REQUEST
)
+ "<h3>Aucun étudiant !</h3>" + "<h3>Aucun étudiant !</h3>"
+ context.sco_footer(REQUEST) + context.sco_footer(REQUEST)
) )
@ -758,7 +760,8 @@ def SignaleAbsenceGrHebdo(
gr_tit = p + ' <span class="fontred">' + groups_infos.groups_titles + "</span>" gr_tit = p + ' <span class="fontred">' + groups_infos.groups_titles + "</span>"
H = [ H = [
context.sco_header( html_sco_header.sco_header(
context,
page_title="Saisie hebdomadaire des absences", page_title="Saisie hebdomadaire des absences",
init_qtip=True, init_qtip=True,
javascripts=html_sco_header.BOOTSTRAP_MULTISELECT_JS javascripts=html_sco_header.BOOTSTRAP_MULTISELECT_JS
@ -870,7 +873,9 @@ def SignaleAbsenceGrSemestre(
) )
if not groups_infos.members: if not groups_infos.members:
return ( return (
context.sco_header(page_title="Saisie des absences", REQUEST=REQUEST) html_sco_header.sco_header(
context, page_title="Saisie des absences", REQUEST=REQUEST
)
+ "<h3>Aucun étudiant !</h3>" + "<h3>Aucun étudiant !</h3>"
+ context.sco_footer(REQUEST) + context.sco_footer(REQUEST)
) )
@ -961,7 +966,8 @@ def SignaleAbsenceGrSemestre(
gr_tit = p + '<span class="fontred">' + groups_infos.groups_titles + "</span>" gr_tit = p + '<span class="fontred">' + groups_infos.groups_titles + "</span>"
H = [ H = [
context.sco_header( html_sco_header.sco_header(
context,
page_title="Saisie des absences", page_title="Saisie des absences",
init_qtip=True, init_qtip=True,
javascripts=["js/etud_info.js", "js/abs_ajax.js"], javascripts=["js/etud_info.js", "js/abs_ajax.js"],
@ -1450,7 +1456,8 @@ def EtatAbsencesGr(
}, },
html_sortable=True, html_sortable=True,
html_class="table_leftalign", html_class="table_leftalign",
html_header=context.sco_header( html_header=html_sco_header.sco_header(
context,
REQUEST, REQUEST,
page_title=title, page_title=title,
init_qtip=True, init_qtip=True,
@ -1500,7 +1507,11 @@ def EtatAbsencesDate(
groups_infos = sco_groups_view.DisplayedGroupsInfos( groups_infos = sco_groups_view.DisplayedGroupsInfos(
context, group_ids, REQUEST=REQUEST context, group_ids, REQUEST=REQUEST
) )
H = [context.sco_header(page_title="Etat des absences", REQUEST=REQUEST)] H = [
html_sco_header.sco_header(
context, page_title="Etat des absences", REQUEST=REQUEST
)
]
if date: if date:
dateiso = notesdb.DateDMYtoISO(date) dateiso = notesdb.DateDMYtoISO(date)
nbetud = 0 nbetud = 0
@ -1641,8 +1652,8 @@ def AddBilletAbsenceForm(context, etudid, REQUEST=None):
""" """
etud = context.getEtudInfo(etudid=etudid, filled=1, REQUEST=REQUEST)[0] etud = context.getEtudInfo(etudid=etudid, filled=1, REQUEST=REQUEST)[0]
H = [ H = [
context.sco_header( html_sco_header.sco_header(
REQUEST, page_title="Billet d'absence de %s" % etud["nomprenom"] context, REQUEST, page_title="Billet d'absence de %s" % etud["nomprenom"]
) )
] ]
tf = TrivialFormulator( tf = TrivialFormulator(
@ -1780,7 +1791,9 @@ def listeBillets(context, REQUEST=None):
tab = context._tableBillets(billets) tab = context._tableBillets(billets)
T = tab.html() T = tab.html()
H = [ H = [
context.sco_header(REQUEST, page_title="Billet d'absence non traités"), html_sco_header.sco_header(
context, REQUEST, page_title="Billet d'absence non traités"
),
"<h2>Billets d'absence en attente de traitement (%d)</h2>" % len(billets), "<h2>Billets d'absence en attente de traitement (%d)</h2>" % len(billets),
] ]
@ -1890,7 +1903,8 @@ def ProcessBilletAbsenceForm(context, billet_id, REQUEST=None):
etud = context.getEtudInfo(etudid=etudid, filled=1, REQUEST=REQUEST)[0] etud = context.getEtudInfo(etudid=etudid, filled=1, REQUEST=REQUEST)[0]
H = [ H = [
context.sco_header( html_sco_header.sco_header(
context,
REQUEST, REQUEST,
page_title="Traitement billet d'absence de %s" % etud["nomprenom"], page_title="Traitement billet d'absence de %s" % etud["nomprenom"],
), ),

View File

@ -76,57 +76,57 @@ from app.scodoc.sco_permissions import Permission, ScoImplement
from app.scodoc.TrivialFormulator import TrivialFormulator from app.scodoc.TrivialFormulator import TrivialFormulator
from app.scodoc import htmlutils from app.scodoc import htmlutils
from app.scodoc import sco_excel from app.scodoc import notes_table
from app.scodoc import pe_view
from app.scodoc import sco_apogee_compare
from app.scodoc import sco_apogee_csv
from app.scodoc import sco_archives
from app.scodoc import sco_bulletins
from app.scodoc import sco_bulletins_pdf
from app.scodoc import sco_cache from app.scodoc import sco_cache
from app.scodoc import scolars from app.scodoc import sco_codes_parcours
from app.scodoc import sco_news from app.scodoc import sco_compute_moy
from app.scodoc import sco_formsemestre from app.scodoc import sco_cost_formation
from app.scodoc import sco_formsemestre_edit from app.scodoc import sco_debouche
from app.scodoc import sco_formsemestre_status
from app.scodoc import sco_formsemestre_inscriptions
from app.scodoc import sco_formsemestre_custommenu
from app.scodoc import sco_moduleimpl
from app.scodoc import sco_moduleimpl_status
from app.scodoc import sco_moduleimpl_inscriptions
from app.scodoc import sco_evaluations
from app.scodoc import sco_groups
from app.scodoc import sco_edit_ue
from app.scodoc import sco_edit_formation from app.scodoc import sco_edit_formation
from app.scodoc import sco_edit_matiere from app.scodoc import sco_edit_matiere
from app.scodoc import sco_edit_module from app.scodoc import sco_edit_module
from app.scodoc import sco_tag_module from app.scodoc import sco_edit_ue
from app.scodoc import sco_bulletins from app.scodoc import sco_etape_apogee_view
from app.scodoc import sco_bulletins_pdf from app.scodoc import sco_evaluations
from app.scodoc import sco_compute_moy from app.scodoc import sco_excel
from app.scodoc import sco_recapcomplet from app.scodoc import sco_export_results
from app.scodoc import sco_liste_notes
from app.scodoc import sco_saisie_notes
from app.scodoc import sco_placement
from app.scodoc import sco_undo_notes
from app.scodoc import sco_formations from app.scodoc import sco_formations
from app.scodoc import sco_report from app.scodoc import sco_formsemestre
from app.scodoc import sco_lycee from app.scodoc import sco_formsemestre_custommenu
from app.scodoc import sco_poursuite_dut from app.scodoc import sco_formsemestre_edit
from app.scodoc import pe_view from app.scodoc import sco_formsemestre_exterieurs
from app.scodoc import sco_debouche from app.scodoc import sco_formsemestre_inscriptions
from app.scodoc import sco_ue_external from app.scodoc import sco_formsemestre_status
from app.scodoc import sco_cost_formation
from app.scodoc import sco_formsemestre_validation from app.scodoc import sco_formsemestre_validation
from app.scodoc import sco_groups
from app.scodoc import sco_inscr_passage
from app.scodoc import sco_liste_notes
from app.scodoc import sco_lycee
from app.scodoc import sco_moduleimpl
from app.scodoc import sco_moduleimpl_inscriptions
from app.scodoc import sco_moduleimpl_status
from app.scodoc import sco_news
from app.scodoc import sco_parcours_dut from app.scodoc import sco_parcours_dut
from app.scodoc import sco_codes_parcours from app.scodoc import sco_placement
from app.scodoc import sco_poursuite_dut
from app.scodoc import sco_prepajury
from app.scodoc import sco_pvjury from app.scodoc import sco_pvjury
from app.scodoc import sco_pvpdf from app.scodoc import sco_pvpdf
from app.scodoc import sco_prepajury from app.scodoc import sco_recapcomplet
from app.scodoc import sco_inscr_passage from app.scodoc import sco_report
from app.scodoc import sco_synchro_etuds from app.scodoc import sco_saisie_notes
from app.scodoc import sco_archives
from app.scodoc import sco_apogee_csv
from app.scodoc import sco_etape_apogee_view
from app.scodoc import sco_apogee_compare
from app.scodoc import sco_semset from app.scodoc import sco_semset
from app.scodoc import sco_export_results from app.scodoc import sco_synchro_etuds
from app.scodoc import sco_formsemestre_exterieurs from app.scodoc import sco_tag_module
from app.scodoc import notes_table from app.scodoc import sco_ue_external
from app.scodoc import sco_undo_notes
from app.scodoc import scolars
context = ScoDoc7Context(globals()) context = ScoDoc7Context(globals())
@ -410,7 +410,9 @@ def index_html(context, REQUEST=None):
) )
H = [ H = [
context.sco_header(REQUEST, page_title="Programmes formations"), html_sco_header.sco_header(
context, REQUEST, page_title="Programmes formations"
),
"""<h2>Programmes pédagogiques</h2> """<h2>Programmes pédagogiques</h2>
""", """,
] ]
@ -438,34 +440,11 @@ def index_html(context, REQUEST=None):
# --- Formations # --- Formations
sco_publish(
@bp.route("/do_formation_create") "/do_formation_create",
@permission_required(Permission.ScoChangeFormation) sco_edit_formation.do_formation_create,
@scodoc7func(context) Permission.ScoChangeFormation,
def do_formation_create(context, args, REQUEST):
"create a formation"
cnx = context.GetDBConnexion()
# check unique acronyme/titre/version
a = args.copy()
if a.has_key("formation_id"):
del a["formation_id"]
F = context.formation_list(args=a)
if len(F) > 0:
log("do_formation_create: error: %d formations matching args=%s" % (len(F), a))
raise ScoValueError("Formation non unique (%s) !" % str(a))
# Si pas de formation_code, l'enleve (default SQL)
if args.has_key("formation_code") and not args["formation_code"]:
del args["formation_code"]
#
r = _formationEditor.create(cnx, args)
sco_news.add(
context,
REQUEST,
typ=NEWS_FORM,
text="Création de la formation %(titre)s (%(acronyme)s)" % args,
) )
return r
@bp.route("/do_formation_delete") @bp.route("/do_formation_delete")
@ -543,7 +522,9 @@ def formation_import_xml(context, file, REQUEST):
def formation_import_xml_form(context, REQUEST): def formation_import_xml_form(context, REQUEST):
"form import d'une formation en XML" "form import d'une formation en XML"
H = [ H = [
context.sco_header(page_title="Import d'une formation", REQUEST=REQUEST), html_sco_header.sco_header(
context, page_title="Import d'une formation", REQUEST=REQUEST
),
"""<h2>Import d'une formation</h2> """<h2>Import d'une formation</h2>
<p>Création d'une formation (avec UE, matières, modules) <p>Création d'une formation (avec UE, matières, modules)
à partir un fichier XML (réservé aux utilisateurs avertis)</p> à partir un fichier XML (réservé aux utilisateurs avertis)</p>
@ -664,7 +645,7 @@ def _do_ue_delete(context, ue_id, delete_validations=False, REQUEST=None, force=
if not ue: if not ue:
raise ScoValueError("UE inexistante !") raise ScoValueError("UE inexistante !")
ue = ue[0] ue = ue[0]
if context.ue_is_locked(ue["ue_id"]): if sco_edit_ue.ue_is_locked(context, ue["ue_id"]):
raise ScoLockedFormError() raise ScoLockedFormError()
# Il y a-t-il des etudiants ayant validé cette UE ? # Il y a-t-il des etudiants ayant validé cette UE ?
# si oui, propose de supprimer les validations # si oui, propose de supprimer les validations
@ -775,7 +756,7 @@ def do_matiere_delete(context, oid, REQUEST):
# check # check
mat = context.do_matiere_list({"matiere_id": oid})[0] mat = context.do_matiere_list({"matiere_id": oid})[0]
ue = context.do_ue_list({"ue_id": mat["ue_id"]})[0] ue = context.do_ue_list({"ue_id": mat["ue_id"]})[0]
locked = context.matiere_is_locked(mat["matiere_id"]) locked = sco_edit_matiere.matiere_is_locked(context, mat["matiere_id"])
if locked: if locked:
log("do_matiere_delete: mat=%s" % mat) log("do_matiere_delete: mat=%s" % mat)
log("do_matiere_delete: ue=%s" % ue) log("do_matiere_delete: ue=%s" % ue)
@ -816,7 +797,7 @@ def do_matiere_edit(context, *args, **kw):
cnx = context.GetDBConnexion() cnx = context.GetDBConnexion()
# check # check
mat = context.do_matiere_list({"matiere_id": args[0]["matiere_id"]})[0] mat = context.do_matiere_list({"matiere_id": args[0]["matiere_id"]})[0]
if context.matiere_is_locked(mat["matiere_id"]): if sco_edit_matiere.matiere_is_locked(context, mat["matiere_id"]):
raise ScoLockedFormError() raise ScoLockedFormError()
# edit # edit
context._matiereEditor.edit(cnx, *args, **kw) context._matiereEditor.edit(cnx, *args, **kw)
@ -900,7 +881,7 @@ def do_module_create(context, args, REQUEST):
def do_module_delete(context, oid, REQUEST): def do_module_delete(context, oid, REQUEST):
"delete module" "delete module"
mod = context.do_module_list({"module_id": oid})[0] mod = context.do_module_list({"module_id": oid})[0]
if context.module_is_locked(mod["module_id"]): if sco_edit_module.module_is_locked(context, mod["module_id"]):
raise ScoLockedFormError() raise ScoLockedFormError()
# S'il y a des moduleimpls, on ne peut pas detruire le module ! # S'il y a des moduleimpls, on ne peut pas detruire le module !
@ -946,7 +927,7 @@ def do_module_edit(context, val):
"edit a module" "edit a module"
# check # check
mod = context.do_module_list({"module_id": val["module_id"]})[0] mod = context.do_module_list({"module_id": val["module_id"]})[0]
if context.module_is_locked(mod["module_id"]): if sco_edit_module.module_is_locked(context, mod["module_id"]):
# formation verrouillée: empeche de modifier certains champs: # formation verrouillée: empeche de modifier certains champs:
protected_fields = ("coefficient", "ue_id", "matiere_id", "semestre_id") protected_fields = ("coefficient", "ue_id", "matiere_id", "semestre_id")
for f in protected_fields: for f in protected_fields:
@ -988,68 +969,17 @@ def formation_count_sems(context, formation_id):
return len(sems) return len(sems)
@bp.route("/module_count_moduleimpls") sco_publish(
@permission_required(Permission.ScoView) "/module_count_moduleimpls",
@scodoc7func(context) sco_edit_module.module_count_moduleimpls,
def module_count_moduleimpls(context, module_id): Permission.ScoView,
"Number of moduleimpls using this module"
mods = sco_moduleimpl.do_moduleimpl_list(context, module_id=module_id)
return len(mods)
@bp.route("/module_is_locked")
@permission_required(Permission.ScoView)
@scodoc7func(context)
def module_is_locked(context, module_id):
"""True if UE should not be modified
(used in a locked formsemestre)
"""
r = ndb.SimpleDictFetch(
context,
"""SELECT mi.* from notes_modules mod, notes_formsemestre sem, notes_moduleimpl mi
WHERE mi.module_id = mod.module_id AND mi.formsemestre_id = sem.formsemestre_id
AND mi.module_id = %(module_id)s AND sem.etat = 0
""",
{"module_id": module_id},
) )
return len(r) > 0
sco_publish("/module_is_locked", sco_edit_module.module_is_locked, Permission.ScoView)
@bp.route("/matiere_is_locked") sco_publish(
@permission_required(Permission.ScoView) "/matiere_is_locked", sco_edit_matiere.matiere_is_locked, Permission.ScoView
@scodoc7func(context)
def matiere_is_locked(context, matiere_id):
"""True if matiere should not be modified
(contains modules used in a locked formsemestre)
"""
r = ndb.SimpleDictFetch(
context,
"""SELECT ma.* from notes_matieres ma, notes_modules mod, notes_formsemestre sem, notes_moduleimpl mi
WHERE ma.matiere_id = mod.matiere_id AND mi.module_id = mod.module_id AND mi.formsemestre_id = sem.formsemestre_id
AND ma.matiere_id = %(matiere_id)s AND sem.etat = 0
""",
{"matiere_id": matiere_id},
) )
return len(r) > 0
@bp.route("/ue_is_locked")
@permission_required(Permission.ScoView)
@scodoc7func(context)
def ue_is_locked(context, ue_id):
"""True if module should not be modified
(contains modules used in a locked formsemestre)
"""
r = ndb.SimpleDictFetch(
context,
"""SELECT ue.* FROM notes_ue ue, notes_modules mod, notes_formsemestre sem, notes_moduleimpl mi
WHERE ue.ue_id = mod.ue_id
AND mi.module_id = mod.module_id AND mi.formsemestre_id = sem.formsemestre_id
AND ue.ue_id = %(ue_id)s AND sem.etat = 0
""",
{"ue_id": ue_id},
)
return len(r) > 0
@bp.route("/module_move") @bp.route("/module_move")
@ -1248,7 +1178,9 @@ def _check_access_diretud(
""" """
authuser = REQUEST.AUTHENTICATED_USER authuser = REQUEST.AUTHENTICATED_USER
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
header = context.sco_header(page_title="Accès interdit", REQUEST=REQUEST) header = html_sco_header.sco_header(
context, page_title="Accès interdit", REQUEST=REQUEST
)
footer = context.sco_footer(REQUEST) footer = context.sco_footer(REQUEST)
if (str(authuser) not in sem["responsables"]) and not authuser.has_permission( if (str(authuser) not in sem["responsables"]) and not authuser.has_permission(
required_permission, context required_permission, context
@ -1286,32 +1218,6 @@ sco_publish(
Permission.ScoView, Permission.ScoView,
) )
@bp.route("/html_sem_header")
@permission_required(Permission.ScoView)
@scodoc7func(context)
def html_sem_header(
context,
REQUEST,
title,
sem=None,
with_page_header=True,
with_h2=True,
page_title=None,
**args
):
"Titre d'une page semestre avec lien vers tableau de bord"
# sem now unused and thus optional...
if with_page_header:
h = context.sco_header(REQUEST, page_title="%s" % (page_title or title), **args)
else:
h = ""
if with_h2:
return h + """<h2 class="formsemestre">%s</h2>""" % (title)
else:
return h
# --- dialogue modif enseignants/moduleimpl # --- dialogue modif enseignants/moduleimpl
@bp.route("/edit_enseignants_form") @bp.route("/edit_enseignants_form")
@permission_required(Permission.ScoView) @permission_required(Permission.ScoView)
@ -1320,7 +1226,8 @@ def edit_enseignants_form(context, REQUEST, moduleimpl_id):
"modif liste enseignants/moduleimpl" "modif liste enseignants/moduleimpl"
M, sem = sco_moduleimpl.can_change_ens(context, REQUEST, moduleimpl_id) M, sem = sco_moduleimpl.can_change_ens(context, REQUEST, moduleimpl_id)
# -- # --
header = context.html_sem_header( header = html_sco_header.html_sem_header(
context,
REQUEST, REQUEST,
'Enseignants du <a href="moduleimpl_status?moduleimpl_id=%s">module %s</a>' 'Enseignants du <a href="moduleimpl_status?moduleimpl_id=%s">module %s</a>'
% (moduleimpl_id, M["module"]["titre"]), % (moduleimpl_id, M["module"]["titre"]),
@ -1430,7 +1337,8 @@ def edit_moduleimpl_resp(context, REQUEST, moduleimpl_id):
""" """
M, sem = sco_moduleimpl.can_change_module_resp(context, REQUEST, moduleimpl_id) M, sem = sco_moduleimpl.can_change_module_resp(context, REQUEST, moduleimpl_id)
H = [ H = [
context.html_sem_header( html_sco_header.html_sem_header(
context,
REQUEST, REQUEST,
'Modification du responsable du <a href="moduleimpl_status?moduleimpl_id=%s">module %s</a>' 'Modification du responsable du <a href="moduleimpl_status?moduleimpl_id=%s">module %s</a>'
% (moduleimpl_id, M["module"]["titre"]), % (moduleimpl_id, M["module"]["titre"]),
@ -1539,7 +1447,8 @@ def edit_moduleimpl_expr(context, REQUEST, moduleimpl_id):
""" """
M, sem = sco_moduleimpl.can_change_ens(context, REQUEST, moduleimpl_id) M, sem = sco_moduleimpl.can_change_ens(context, REQUEST, moduleimpl_id)
H = [ H = [
context.html_sem_header( html_sco_header.html_sem_header(
context,
REQUEST, REQUEST,
'Modification règle de calcul du <a href="moduleimpl_status?moduleimpl_id=%s">module %s</a>' 'Modification règle de calcul du <a href="moduleimpl_status?moduleimpl_id=%s">module %s</a>'
% (moduleimpl_id, M["module"]["titre"]), % (moduleimpl_id, M["module"]["titre"]),
@ -1636,7 +1545,8 @@ def view_module_abs(context, REQUEST, moduleimpl_id, format="html"):
) )
H = [ H = [
context.html_sem_header( html_sco_header.html_sem_header(
context,
REQUEST, REQUEST,
'Absences du <a href="moduleimpl_status?moduleimpl_id=%s">module %s</a>' 'Absences du <a href="moduleimpl_status?moduleimpl_id=%s">module %s</a>'
% (moduleimpl_id, M["module"]["titre"]), % (moduleimpl_id, M["module"]["titre"]),
@ -1686,7 +1596,8 @@ def edit_ue_expr(context, REQUEST, formsemestre_id, ue_id):
# #
ue = context.do_ue_list({"ue_id": ue_id})[0] ue = context.do_ue_list({"ue_id": ue_id})[0]
H = [ H = [
context.html_sem_header( html_sco_header.html_sem_header(
context,
REQUEST, REQUEST,
"Modification règle de calcul de l'UE %s (%s)" "Modification règle de calcul de l'UE %s (%s)"
% (ue["acronyme"], ue["titre"]), % (ue["acronyme"], ue["titre"]),
@ -1816,8 +1727,8 @@ def formsemestre_enseignants_list(context, REQUEST, formsemestre_id, format="htm
html_sortable=True, html_sortable=True,
html_class="table_leftalign", html_class="table_leftalign",
filename=scu.make_filename("Enseignants-" + sem["titreannee"]), filename=scu.make_filename("Enseignants-" + sem["titreannee"]),
html_title=context.html_sem_header( html_title=html_sco_header.html_sem_header(
REQUEST, "Enseignants du semestre", sem, with_page_header=False context, REQUEST, "Enseignants du semestre", sem, with_page_header=False
), ),
base_url="%s?formsemestre_id=%s" % (REQUEST.URL0, formsemestre_id), base_url="%s?formsemestre_id=%s" % (REQUEST.URL0, formsemestre_id),
caption="Tous les enseignants (responsables ou associés aux modules de ce semestre) apparaissent. Le nombre de saisies d'absences est le nombre d'opérations d'ajout effectuées sur ce semestre, sans tenir compte des annulations ou double saisies.", caption="Tous les enseignants (responsables ou associés aux modules de ce semestre) apparaissent. Le nombre de saisies d'absences est le nombre d'opérations d'ajout effectuées sur ce semestre, sans tenir compte des annulations ou double saisies.",
@ -2036,7 +1947,7 @@ def formsemestre_desinscription(
context.do_formsemestre_desinscription(etudid, formsemestre_id, REQUEST=REQUEST) context.do_formsemestre_desinscription(etudid, formsemestre_id, REQUEST=REQUEST)
return ( return (
context.sco_header(REQUEST) html_sco_header.sco_header(context, REQUEST)
+ '<p>Etudiant désinscrit !</p><p><a class="stdlink" href="%s/ficheEtud?etudid=%s">retour à la fiche</a>' + '<p>Etudiant désinscrit !</p><p><a class="stdlink" href="%s/ficheEtud?etudid=%s">retour à la fiche</a>'
% (context.ScoURL(), etudid) % (context.ScoURL(), etudid)
+ context.sco_footer(REQUEST) + context.sco_footer(REQUEST)
@ -2396,7 +2307,7 @@ def evaluation_delete(context, REQUEST, evaluation_id):
tit = "Suppression de l'évaluation %(description)s (%(jour)s)" % E tit = "Suppression de l'évaluation %(description)s (%(jour)s)" % E
etat = sco_evaluations.do_evaluation_etat(context, evaluation_id) etat = sco_evaluations.do_evaluation_etat(context, evaluation_id)
H = [ H = [
context.html_sem_header(REQUEST, tit, with_h2=False), html_sco_header.html_sem_header(context, REQUEST, tit, with_h2=False),
"""<h2 class="formsemestre">Module <tt>%(code)s</tt> %(titre)s</h2>""" % Mod, """<h2 class="formsemestre">Module <tt>%(code)s</tt> %(titre)s</h2>""" % Mod,
"""<h3>%s</h3>""" % tit, """<h3>%s</h3>""" % tit,
"""<p class="help">Opération <span class="redboldtext">irréversible</span>. Si vous supprimez l'évaluation, vous ne pourrez pas retrouver les notes associées.</p>""", """<p class="help">Opération <span class="redboldtext">irréversible</span>. Si vous supprimez l'évaluation, vous ne pourrez pas retrouver les notes associées.</p>""",
@ -2571,7 +2482,8 @@ def evaluation_create(context, moduleimpl_id, REQUEST):
def evaluation_listenotes(context, REQUEST=None): def evaluation_listenotes(context, REQUEST=None):
"""Affichage des notes d'une évaluation""" """Affichage des notes d'une évaluation"""
if REQUEST.form.get("format", "html") == "html": if REQUEST.form.get("format", "html") == "html":
H = context.sco_header( H = html_sco_header.sco_header(
context,
REQUEST, REQUEST,
cssstyles=["css/verticalhisto.css"], cssstyles=["css/verticalhisto.css"],
javascripts=["js/etud_info.js"], javascripts=["js/etud_info.js"],
@ -2777,7 +2689,7 @@ def formsemestre_bulletins_mailetuds(
nb_send += 1 nb_send += 1
# #
return ( return (
context.sco_header(REQUEST) html_sco_header.sco_header(context, REQUEST)
+ '<p>%d bulletins sur %d envoyés par mail !</p><p><a class="stdlink" href="formsemestre_status?formsemestre_id=%s">continuer</a></p>' + '<p>%d bulletins sur %d envoyés par mail !</p><p><a class="stdlink" href="formsemestre_status?formsemestre_id=%s">continuer</a></p>'
% (nb_send, len(etudids), formsemestre_id) % (nb_send, len(etudids), formsemestre_id)
+ context.sco_footer(REQUEST) + context.sco_footer(REQUEST)
@ -2841,7 +2753,7 @@ def appreciation_add_form(
else: else:
a = "Ajout" a = "Ajout"
H = [ H = [
context.sco_header(REQUEST) html_sco_header.sco_header(context, REQUEST)
+ "<h2>%s d'une appréciation sur %s</h2>" % (a, etud["nomprenom"]) + "<h2>%s d'une appréciation sur %s</h2>" % (a, etud["nomprenom"])
] ]
F = context.sco_footer(REQUEST) F = context.sco_footer(REQUEST)
@ -3401,7 +3313,7 @@ def check_sem_integrity(context, formsemestre_id, REQUEST):
modimpl["mod"] = mod modimpl["mod"] = mod
return ( return (
context.sco_header(REQUEST=REQUEST) html_sco_header.sco_header(context, REQUEST=REQUEST)
+ "<p>formation_id=%s" % sem["formation_id"] + "<p>formation_id=%s" % sem["formation_id"]
+ "<h2>Inconsistent UE/MOD:</h2>" + "<h2>Inconsistent UE/MOD:</h2>"
+ "<br/>".join([str(x) for x in bad_ue]) + "<br/>".join([str(x) for x in bad_ue])
@ -3445,7 +3357,11 @@ def check_form_integrity(context, formation_id, fix=False, REQUEST=None):
else: else:
txth = "OK" txth = "OK"
log("ok") log("ok")
return context.sco_header(REQUEST=REQUEST) + txth + context.sco_footer(REQUEST) return (
html_sco_header.sco_header(context, REQUEST=REQUEST)
+ txth
+ context.sco_footer(REQUEST)
)
@bp.route("/check_formsemestre_integrity") @bp.route("/check_formsemestre_integrity")
@ -3494,7 +3410,7 @@ def check_formsemestre_integrity(context, formsemestre_id, REQUEST=None):
diag = ["OK"] diag = ["OK"]
log("ok") log("ok")
return ( return (
context.sco_header(REQUEST=REQUEST) html_sco_header.sco_header(context, REQUEST=REQUEST)
+ "<br/>".join(diag) + "<br/>".join(diag)
+ context.sco_footer(REQUEST) + context.sco_footer(REQUEST)
) )
@ -3512,7 +3428,7 @@ def check_integrity_all(context, REQUEST=None):
for sem in sco_formsemestre.do_formsemestre_list(context): for sem in sco_formsemestre.do_formsemestre_list(context):
context.check_formsemestre_integrity(sem["formsemestre_id"], REQUEST=REQUEST) context.check_formsemestre_integrity(sem["formsemestre_id"], REQUEST=REQUEST)
return ( return (
context.sco_header(REQUEST=REQUEST) html_sco_header.sco_header(context, REQUEST=REQUEST)
+ "<p>empty page: see logs and mails</p>" + "<p>empty page: see logs and mails</p>"
+ context.sco_footer(REQUEST) + context.sco_footer(REQUEST)
) )

View File

@ -177,9 +177,6 @@ def DeptId():
# Permission.ScoView, # Permission.ScoView,
# ) # )
sco_publish("/sco_header", html_sco_header.sco_header, Permission.ScoView)
sco_publish("/sco_footer", html_sco_header.sco_footer, Permission.ScoView)
@bp.route("/about") @bp.route("/about")
@permission_required(Permission.ScoView) @permission_required(Permission.ScoView)
@ -203,7 +200,12 @@ def about(context, REQUEST):
+ " <em>Au pays des aveugles...</em></div>" + " <em>Au pays des aveugles...</em></div>"
) )
d = "" d = ""
return context.sco_header(REQUEST) + "\n".join(H) + d + context.sco_footer(REQUEST) return (
html_sco_header.sco_header(context, REQUEST)
+ "\n".join(H)
+ d
+ context.sco_footer(REQUEST)
)
# -------------------------------------------------------------------- # --------------------------------------------------------------------
@ -255,10 +257,6 @@ def doc_preferences(context, REQUEST):
# #
# -------------------------------------------------------------------- # --------------------------------------------------------------------
# ----------------- BANDEAUX -------------------
sco_publish("/sidebar", html_sidebar.sidebar, Permission.ScoView)
sco_publish("/sidebar_dept", html_sidebar.sidebar_dept, Permission.ScoView)
@bp.route("/showEtudLog") @bp.route("/showEtudLog")
@permission_required(Permission.ScoView) @permission_required(Permission.ScoView)
@ -613,8 +611,8 @@ def formChangeCoordonnees(context, etudid, REQUEST):
'<h2><font color="#FF0000">Changement des coordonnées de </font> %(nomprenom)s</h2><p>' '<h2><font color="#FF0000">Changement des coordonnées de </font> %(nomprenom)s</h2><p>'
% etud % etud
] ]
header = context.sco_header( header = html_sco_header.sco_header(
REQUEST, page_title="Changement adresse de %(nomprenom)s" % etud context, REQUEST, page_title="Changement adresse de %(nomprenom)s" % etud
) )
tf = TrivialFormulator( tf = TrivialFormulator(
@ -723,7 +721,7 @@ def etud_photo_orig_page(context, etudid=None, REQUEST=None):
"Page with photo in orig. size" "Page with photo in orig. size"
etud = context.getEtudInfo(etudid=etudid, filled=1, REQUEST=REQUEST)[0] etud = context.getEtudInfo(etudid=etudid, filled=1, REQUEST=REQUEST)[0]
H = [ H = [
context.sco_header(REQUEST, page_title=etud["nomprenom"]), html_sco_header.sco_header(context, REQUEST, page_title=etud["nomprenom"]),
"<h2>%s</h2>" % etud["nomprenom"], "<h2>%s</h2>" % etud["nomprenom"],
'<div><a href="ficheEtud?etudid=%s">' % etudid, '<div><a href="ficheEtud?etudid=%s">' % etudid,
sco_photos.etud_photo_orig_html(context, etud), sco_photos.etud_photo_orig_html(context, etud),
@ -744,7 +742,7 @@ def formChangePhoto(context, etudid=None, REQUEST=None):
else: else:
etud["photoloc"] = "externe" etud["photoloc"] = "externe"
H = [ H = [
context.sco_header(REQUEST, page_title="Changement de photo"), html_sco_header.sco_header(context, REQUEST, page_title="Changement de photo"),
"""<h2>Changement de la photo de %(nomprenom)s</h2> """<h2>Changement de la photo de %(nomprenom)s</h2>
<p>Photo actuelle (%(photoloc)s): <p>Photo actuelle (%(photoloc)s):
""" """
@ -861,7 +859,8 @@ def _formDem_of_Def(
etud["nowdmy"] = time.strftime("%d/%m/%Y") etud["nowdmy"] = time.strftime("%d/%m/%Y")
etud["operation_name"] = operation_name etud["operation_name"] = operation_name
# #
header = context.sco_header( header = html_sco_header.sco_header(
context,
REQUEST, REQUEST,
page_title="%(operation_name)s de %(nomprenom)s (du semestre %(semtitre)s)" page_title="%(operation_name)s de %(nomprenom)s (du semestre %(semtitre)s)"
% etud, % etud,
@ -1084,7 +1083,7 @@ def etudident_edit_form(context, REQUEST=None):
def _etudident_create_or_edit_form(context, REQUEST, edit): def _etudident_create_or_edit_form(context, REQUEST, edit):
"Le formulaire HTML" "Le formulaire HTML"
H = [context.sco_header(REQUEST, init_jquery_ui=True)] H = [html_sco_header.sco_header(context, REQUEST, init_jquery_ui=True)]
F = context.sco_footer(REQUEST) F = context.sco_footer(REQUEST)
etudid = REQUEST.form.get("etudid", None) etudid = REQUEST.form.get("etudid", None)
cnx = context.GetDBConnexion() cnx = context.GetDBConnexion()
@ -1701,7 +1700,7 @@ def form_students_import_excel(context, REQUEST, formsemestre_id=None):
if sem and sem["etat"] != "1": if sem and sem["etat"] != "1":
raise ScoValueError("Modification impossible: semestre verrouille") raise ScoValueError("Modification impossible: semestre verrouille")
H = [ H = [
context.sco_header(REQUEST, page_title="Import etudiants"), html_sco_header.sco_header(context, REQUEST, page_title="Import etudiants"),
"""<h2 class="formsemestre">Téléchargement d\'une nouvelle liste d\'etudiants</h2> """<h2 class="formsemestre">Téléchargement d\'une nouvelle liste d\'etudiants</h2>
<div style="color: red"> <div style="color: red">
<p>A utiliser pour importer de <b>nouveaux</b> étudiants (typiquement au <p>A utiliser pour importer de <b>nouveaux</b> étudiants (typiquement au
@ -1873,7 +1872,8 @@ def form_students_import_infos_admissions(context, REQUEST, formsemestre_id=None
if not authuser.has_permission(Permission.ScoEtudInscrit, context): if not authuser.has_permission(Permission.ScoEtudInscrit, context):
# autorise juste l'export # autorise juste l'export
H = [ H = [
context.sco_header( html_sco_header.sco_header(
context,
REQUEST, REQUEST,
page_title="Export données admissions (Parcoursup ou autre)", page_title="Export données admissions (Parcoursup ou autre)",
), ),
@ -1889,7 +1889,9 @@ def form_students_import_infos_admissions(context, REQUEST, formsemestre_id=None
# On a le droit d'importer: # On a le droit d'importer:
H = [ H = [
context.sco_header(REQUEST, page_title="Import données admissions Parcoursup"), html_sco_header.sco_header(
context, REQUEST, page_title="Import données admissions Parcoursup"
),
"""<h2 class="formsemestre">Téléchargement des informations sur l'admission des étudiants depuis feuilles import Parcoursup</h2> """<h2 class="formsemestre">Téléchargement des informations sur l'admission des étudiants depuis feuilles import Parcoursup</h2>
<div style="color: red"> <div style="color: red">
<p>A utiliser pour renseigner les informations sur l'origine des étudiants (lycées, bac, etc). Ces informations sont facultatives mais souvent utiles pour mieux connaitre les étudiants et aussi pour effectuer des statistiques (résultats suivant le type de bac...). Les données sont affichées sur les fiches individuelles des étudiants.</p> <p>A utiliser pour renseigner les informations sur l'origine des étudiants (lycées, bac, etc). Ces informations sont facultatives mais souvent utiles pour mieux connaitre les étudiants et aussi pour effectuer des statistiques (résultats suivant le type de bac...). Les données sont affichées sur les fiches individuelles des étudiants.</p>
@ -1981,7 +1983,11 @@ def _students_import_admission(
type_admission=type_admission, type_admission=type_admission,
) )
if REQUEST: if REQUEST:
H = [context.sco_header(REQUEST, page_title="Import données admissions")] H = [
html_sco_header.sco_header(
context, REQUEST, page_title="Import données admissions"
)
]
H.append("<p>Import terminé !</p>") H.append("<p>Import terminé !</p>")
H.append( H.append(
'<p><a class="stdlink" href="%s">Continuer</a></p>' '<p><a class="stdlink" href="%s">Continuer</a></p>'

View File

@ -1,8 +1,18 @@
#!/usr/bin/env python
# -*- coding: UTF-8 -* # -*- coding: UTF-8 -*
"""Outil pour migration ScoDoc 7 => ScoDoc 8 """Outil pour migration ScoDoc 7 => ScoDoc 8
- Liste des appels de la forme context.xxx
./refactor.py showcontextcalls app/scodoc/*.p
- remplace context.xxx par module.xxx
./refactor.py refactor method module app/scodoc/*.py
Pour chaque module dans views: Pour chaque module dans views:
- construire la liste des fonctions définies dans ce module: - construire la liste des fonctions définies dans ce module:
get_module_functions get_module_functions
@ -116,15 +126,8 @@ def list_context_calls(sourcefilename):
return sorted(set(exp.findall(source))) return sorted(set(exp.findall(source)))
@click.group() def get_context_calls(src_filenames):
def cli(): """returns { method_name : [ list of module names in which it is called ] }"""
pass
@cli.command()
@click.argument("src_filenames", nargs=-1)
def showcontextcalls(src_filenames):
click.echo("Initialized the database")
S = {} S = {}
for sourcefilename in src_filenames: for sourcefilename in src_filenames:
l = list_context_calls(sourcefilename) l = list_context_calls(sourcefilename)
@ -134,25 +137,52 @@ def showcontextcalls(src_filenames):
S[m].append(module_name) S[m].append(module_name)
else: else:
S[m] = [module_name] S[m] = [module_name]
return S
@click.group()
def cli():
pass
@cli.command()
@click.argument("src_filenames", nargs=-1)
def showcontextcalls(src_filenames):
click.echo("Appels de méthodes sur l'object context")
S = get_context_calls(src_filenames)
# #
for method in sorted(S.keys()): for method in sorted(S.keys()):
print(method + ":\t" + ", ".join(S[method])) print(method + ":\t" + ", ".join(S[method]))
@cli.command() @cli.command()
@click.argument("method", nargs=1) @click.argument("modulemethod", nargs=1)
@click.argument("module", nargs=1)
@click.argument("src_filenames", nargs=-1) @click.argument("src_filenames", nargs=-1)
def refactor(method, module, src_filenames): def refactor(modulemethod, src_filenames):
"""Replace call context.method """Replace call context.method(...)
by module.method by module.method(context, ...)
in all given source filenames in all given source filenames
""" """
modulemethod = str(modulemethod) # avoid unicode in Python2
frags = modulemethod.split(".")
if len(frags) < 2:
raise click.BadParameter("must be module.method", param_hint="modulemethod")
module = ".".join(frags[:-1])
method = frags[-1]
backup = tempfile.mkdtemp(dir="/tmp") backup = tempfile.mkdtemp(dir="/tmp")
for sourcefilename in src_filenames: for sourcefilename in src_filenames:
print("reading %s" % sourcefilename) source_module_name = os.path.splitext(os.path.split(sourcefilename)[1])[0]
is_local = source_module_name == module
source = open(sourcefilename).read() source = open(sourcefilename).read()
source2 = source.replace("context." + method, module + "." + method) if not is_local:
source2 = source.replace(
"context." + method + "(", module + "." + method + "(context, "
)
else:
# call in the same module:
source2 = source.replace("context." + method + "(", method + "(context, ")
if source2 != source:
print("changed %s" % sourcefilename)
shutil.move(sourcefilename, backup) shutil.move(sourcefilename, backup)
open(sourcefilename, "w").write(source2) open(sourcefilename, "w").write(source2)
print("Done.\noriginal files saved in %s\n" % backup) print("Done.\noriginal files saved in %s\n" % backup)