forked from ScoDoc/ScoDoc
blackify and some minor fixes
This commit is contained in:
parent
3c567aeb18
commit
8d74f8feed
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
# SCODOC - gestion de la scolarité
|
# SCODOC - gestion de la scolarité
|
||||||
|
|
||||||
(c) Emmanuel Viennet 1999 - 2020 (voir LICENCE.txt)
|
(c) Emmanuel Viennet 1999 - 2021 (voir LICENCE.txt)
|
||||||
|
|
||||||
|
|
||||||
Installation: voir instructions à jour sur <https://scodoc.org>
|
Installation: voir instructions à jour sur <https://scodoc.org>
|
||||||
|
@ -277,7 +277,7 @@ class ZScoUsers(
|
|||||||
|
|
||||||
def user_info(self, user_name=None, user=None):
|
def user_info(self, user_name=None, user=None):
|
||||||
"""Donne infos sur l'utilisateur (qui peut ne pas etre dans notre base).
|
"""Donne infos sur l'utilisateur (qui peut ne pas etre dans notre base).
|
||||||
Si user_name est specifie, interroge la BD. Sinon, user doit etre un dict.
|
Si user_name est specifie, interroge la BD. Sinon, user doit etre un dict.
|
||||||
"""
|
"""
|
||||||
if user_name:
|
if user_name:
|
||||||
infos = self._user_list(args={"user_name": user_name})
|
infos = self._user_list(args={"user_name": user_name})
|
||||||
@ -919,7 +919,7 @@ class ZScoUsers(
|
|||||||
self, edit, user_name="", nom="", prenom="", email="", roles=[]
|
self, edit, user_name="", nom="", prenom="", email="", roles=[]
|
||||||
):
|
):
|
||||||
"""Vérifie que et utilisateur peut etre crée (edit=0) ou modifié (edit=1)
|
"""Vérifie que et utilisateur peut etre crée (edit=0) ou modifié (edit=1)
|
||||||
Cherche homonymes.
|
Cherche homonymes.
|
||||||
returns (ok, msg)
|
returns (ok, msg)
|
||||||
- ok : si vrai, peut continuer avec ces parametres
|
- ok : si vrai, peut continuer avec ces parametres
|
||||||
(si ok est faux, l'utilisateur peut quand même forcer la creation)
|
(si ok est faux, l'utilisateur peut quand même forcer la creation)
|
||||||
@ -1252,8 +1252,7 @@ class ZScoUsers(
|
|||||||
security.declareProtected(ScoView, "get_user_name_from_nomplogin")
|
security.declareProtected(ScoView, "get_user_name_from_nomplogin")
|
||||||
|
|
||||||
def get_user_name_from_nomplogin(self, nomplogin):
|
def get_user_name_from_nomplogin(self, nomplogin):
|
||||||
"""Returns user_name (login) from nomplogin
|
"""Returns user_name (login) from nomplogin"""
|
||||||
"""
|
|
||||||
m = re.match(r".*\((.*)\)", nomplogin.strip())
|
m = re.match(r".*\((.*)\)", nomplogin.strip())
|
||||||
if m:
|
if m:
|
||||||
return m.group(1)
|
return m.group(1)
|
||||||
|
0
csv2rules.py
Normal file → Executable file
0
csv2rules.py
Normal file → Executable file
22
dutrules.py
22
dutrules.py
@ -4,7 +4,27 @@
|
|||||||
#
|
#
|
||||||
# Command: ./csv2rules.py misc/parcoursDUT.csv
|
# Command: ./csv2rules.py misc/parcoursDUT.csv
|
||||||
#
|
#
|
||||||
from sco_codes_parcours import *
|
from sco_codes_parcours import (
|
||||||
|
DUTRule,
|
||||||
|
ADC,
|
||||||
|
ADJ,
|
||||||
|
ADM,
|
||||||
|
AJ,
|
||||||
|
ALL,
|
||||||
|
ATB,
|
||||||
|
ATJ,
|
||||||
|
ATT,
|
||||||
|
CMP,
|
||||||
|
NAR,
|
||||||
|
NEXT,
|
||||||
|
RA_OR_NEXT,
|
||||||
|
RA_OR_RS,
|
||||||
|
RAT,
|
||||||
|
REO,
|
||||||
|
REDOANNEE,
|
||||||
|
REDOSEM,
|
||||||
|
RS_OR_NEXT,
|
||||||
|
)
|
||||||
|
|
||||||
rules_source_file = "misc/parcoursDUT.csv"
|
rules_source_file = "misc/parcoursDUT.csv"
|
||||||
|
|
||||||
|
@ -45,9 +45,20 @@ from collections import OrderedDict
|
|||||||
|
|
||||||
# XML generation package (apt-get install jaxml)
|
# XML generation package (apt-get install jaxml)
|
||||||
import jaxml
|
import jaxml
|
||||||
|
import json
|
||||||
|
|
||||||
|
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Frame, PageBreak
|
||||||
|
from reportlab.platypus import Table, TableStyle, Image, KeepInFrame
|
||||||
|
from reportlab.lib.colors import Color
|
||||||
|
from reportlab.lib import styles
|
||||||
|
from reportlab.lib.units import inch, cm, mm
|
||||||
|
from reportlab.rl_config import defaultPageSize # pylint: disable=no-name-in-module
|
||||||
|
|
||||||
|
import sco_utils as scu
|
||||||
import sco_excel
|
import sco_excel
|
||||||
from sco_pdf import *
|
import sco_pdf
|
||||||
|
from sco_pdf import SU
|
||||||
|
from notes_log import log
|
||||||
|
|
||||||
|
|
||||||
def mark_paras(L, tags):
|
def mark_paras(L, tags):
|
||||||
@ -280,7 +291,7 @@ class GenTable:
|
|||||||
if not row:
|
if not row:
|
||||||
return "<tr></tr>" # empty row
|
return "<tr></tr>" # empty row
|
||||||
|
|
||||||
if self.html_col_width: # XXXX Obsolete ?
|
if self.html_col_width:
|
||||||
std = ' style="width:%s;"' % self.html_col_width
|
std = ' style="width:%s;"' % self.html_col_width
|
||||||
else:
|
else:
|
||||||
std = ""
|
std = ""
|
||||||
@ -382,10 +393,6 @@ class GenTable:
|
|||||||
else:
|
else:
|
||||||
cls = ""
|
cls = ""
|
||||||
|
|
||||||
if self.html_col_width:
|
|
||||||
std = ' style="width:%s;"' % self.html_col_width
|
|
||||||
else:
|
|
||||||
std = ""
|
|
||||||
H = [self.html_before_table, "<table%s%s>" % (hid, cls)]
|
H = [self.html_before_table, "<table%s%s>" % (hid, cls)]
|
||||||
|
|
||||||
line_num = 0
|
line_num = 0
|
||||||
@ -438,14 +445,14 @@ class GenTable:
|
|||||||
if self.xls_link:
|
if self.xls_link:
|
||||||
H.append(
|
H.append(
|
||||||
' <a href="%s&format=xls">%s</a>'
|
' <a href="%s&format=xls">%s</a>'
|
||||||
% (self.base_url, ICON_XLS)
|
% (self.base_url, scu.ICON_XLS)
|
||||||
)
|
)
|
||||||
if self.xls_link and self.pdf_link:
|
if self.xls_link and self.pdf_link:
|
||||||
H.append(" ")
|
H.append(" ")
|
||||||
if self.pdf_link:
|
if self.pdf_link:
|
||||||
H.append(
|
H.append(
|
||||||
' <a href="%s&format=pdf">%s</a>'
|
' <a href="%s&format=pdf">%s</a>'
|
||||||
% (self.base_url, ICON_PDF)
|
% (self.base_url, scu.ICON_PDF)
|
||||||
)
|
)
|
||||||
H.append("</p>")
|
H.append("</p>")
|
||||||
|
|
||||||
@ -483,10 +490,10 @@ class GenTable:
|
|||||||
"PDF representation: returns a ReportLab's platypus Table instance"
|
"PDF representation: returns a ReportLab's platypus Table instance"
|
||||||
r = []
|
r = []
|
||||||
try:
|
try:
|
||||||
PDFLOCK.acquire()
|
sco_pdf.PDFLOCK.acquire()
|
||||||
r = self._pdf()
|
r = self._pdf()
|
||||||
finally:
|
finally:
|
||||||
PDFLOCK.release()
|
sco_pdf.PDFLOCK.release()
|
||||||
return r
|
return r
|
||||||
|
|
||||||
def _pdf(self):
|
def _pdf(self):
|
||||||
@ -513,7 +520,7 @@ class GenTable:
|
|||||||
CellStyle.leading = 1.0 * self.preferences["SCOLAR_FONT_SIZE"] # vertical space
|
CellStyle.leading = 1.0 * self.preferences["SCOLAR_FONT_SIZE"] # vertical space
|
||||||
LINEWIDTH = 0.5
|
LINEWIDTH = 0.5
|
||||||
#
|
#
|
||||||
titles = ["<para><b>%s</b></para>" % x for x in self.get_titles_list()]
|
# titles = ["<para><b>%s</b></para>" % x for x in self.get_titles_list()]
|
||||||
pdf_style_list = []
|
pdf_style_list = []
|
||||||
Pt = [
|
Pt = [
|
||||||
[Paragraph(SU(str(x)), CellStyle) for x in line]
|
[Paragraph(SU(str(x)), CellStyle) for x in line]
|
||||||
@ -530,10 +537,10 @@ class GenTable:
|
|||||||
# log('len(Pt)=%s' % len(Pt))
|
# log('len(Pt)=%s' % len(Pt))
|
||||||
# log( 'line lens=%s' % [ len(x) for x in Pt ] )
|
# log( 'line lens=%s' % [ len(x) for x in Pt ] )
|
||||||
# log( 'style=\n%s' % pdf_style_list)
|
# log( 'style=\n%s' % pdf_style_list)
|
||||||
col_min = min([x[1][0] for x in pdf_style_list])
|
# col_min = min([x[1][0] for x in pdf_style_list])
|
||||||
col_max = max([x[2][0] for x in pdf_style_list])
|
# col_max = max([x[2][0] for x in pdf_style_list])
|
||||||
lin_min = min([x[1][1] for x in pdf_style_list])
|
# lin_min = min([x[1][1] for x in pdf_style_list])
|
||||||
lin_max = max([x[2][1] for x in pdf_style_list])
|
# lin_max = max([x[2][1] for x in pdf_style_list])
|
||||||
# log('col_min=%s col_max=%s lin_min=%s lin_max=%s' % (col_min, col_max, lin_min, lin_max))
|
# log('col_min=%s col_max=%s lin_min=%s lin_max=%s' % (col_min, col_max, lin_min, lin_max))
|
||||||
T = Table(Pt, repeatRows=1, colWidths=self.pdf_col_widths, style=pdf_style_list)
|
T = Table(Pt, repeatRows=1, colWidths=self.pdf_col_widths, style=pdf_style_list)
|
||||||
|
|
||||||
@ -559,7 +566,7 @@ class GenTable:
|
|||||||
The tag names <table> and <row> can be changed using
|
The tag names <table> and <row> can be changed using
|
||||||
xml_outer_tag and xml_row_tag
|
xml_outer_tag and xml_row_tag
|
||||||
"""
|
"""
|
||||||
doc = jaxml.XML_document(encoding=SCO_ENCODING)
|
doc = jaxml.XML_document(encoding=scu.SCO_ENCODING)
|
||||||
getattr(doc, self.xml_outer_tag)(
|
getattr(doc, self.xml_outer_tag)(
|
||||||
id=self.table_id, origin=self.origin or "", caption=self.caption or ""
|
id=self.table_id, origin=self.origin or "", caption=self.caption or ""
|
||||||
)
|
)
|
||||||
@ -593,7 +600,7 @@ class GenTable:
|
|||||||
v = str(v)
|
v = str(v)
|
||||||
r[cid] = v
|
r[cid] = v
|
||||||
d.append(r)
|
d.append(r)
|
||||||
return json.dumps(d, encoding=SCO_ENCODING)
|
return json.dumps(d, encoding=scu.SCO_ENCODING)
|
||||||
|
|
||||||
def make_page(
|
def make_page(
|
||||||
self,
|
self,
|
||||||
@ -637,11 +644,11 @@ class GenTable:
|
|||||||
return "\n".join(H)
|
return "\n".join(H)
|
||||||
elif format == "pdf":
|
elif format == "pdf":
|
||||||
objects = self.pdf()
|
objects = self.pdf()
|
||||||
doc = pdf_basic_page(
|
doc = sco_pdf.pdf_basic_page(
|
||||||
objects, title=title, preferences=self.preferences, context=context
|
objects, title=title, preferences=self.preferences, context=context
|
||||||
)
|
)
|
||||||
if publish:
|
if publish:
|
||||||
return sendPDFFile(REQUEST, doc, filename + ".pdf")
|
return scu.sendPDFFile(REQUEST, doc, filename + ".pdf")
|
||||||
else:
|
else:
|
||||||
return doc
|
return doc
|
||||||
elif format == "xls":
|
elif format == "xls":
|
||||||
@ -653,16 +660,16 @@ class GenTable:
|
|||||||
elif format == "text":
|
elif format == "text":
|
||||||
return self.text()
|
return self.text()
|
||||||
elif format == "csv":
|
elif format == "csv":
|
||||||
return sendCSVFile(REQUEST, self.text(), filename + ".csv")
|
return scu.sendCSVFile(REQUEST, self.text(), filename + ".csv")
|
||||||
elif format == "xml":
|
elif format == "xml":
|
||||||
xml = self.xml()
|
xml = self.xml()
|
||||||
if REQUEST and publish:
|
if REQUEST and publish:
|
||||||
REQUEST.RESPONSE.setHeader("content-type", XML_MIMETYPE)
|
REQUEST.RESPONSE.setHeader("content-type", scu.XML_MIMETYPE)
|
||||||
return xml
|
return xml
|
||||||
elif format == "json":
|
elif format == "json":
|
||||||
js = self.json()
|
js = self.json()
|
||||||
if REQUEST and publish:
|
if REQUEST and publish:
|
||||||
REQUEST.RESPONSE.setHeader("content-type", JSON_MIMETYPE)
|
REQUEST.RESPONSE.setHeader("content-type", scu.JSON_MIMETYPE)
|
||||||
return js
|
return js
|
||||||
else:
|
else:
|
||||||
log("make_page: format=%s" % format)
|
log("make_page: format=%s" % format)
|
||||||
@ -687,7 +694,7 @@ class SeqGenTable:
|
|||||||
def excel(self):
|
def excel(self):
|
||||||
"""Export des genTables dans un unique fichier excel avec plusieurs feuilles tagguées"""
|
"""Export des genTables dans un unique fichier excel avec plusieurs feuilles tagguées"""
|
||||||
book = sco_excel.Workbook() # Le fichier xls en devenir
|
book = sco_excel.Workbook() # Le fichier xls en devenir
|
||||||
for (name, gt) in self.genTables.items():
|
for (_, gt) in self.genTables.items():
|
||||||
gt.excel(wb=book) # Ecrit dans un fichier excel
|
gt.excel(wb=book) # Ecrit dans un fichier excel
|
||||||
return book.savetostr()
|
return book.savetostr()
|
||||||
|
|
||||||
|
@ -257,6 +257,5 @@ def sco_header(
|
|||||||
|
|
||||||
|
|
||||||
def sco_footer(context, REQUEST=None):
|
def sco_footer(context, REQUEST=None):
|
||||||
"""Main HTMl pages footer
|
"""Main HTMl pages footer"""
|
||||||
"""
|
|
||||||
return """</div><!-- /gtrcontent -->""" + CUSTOM_HTML_FOOTER + """</body></html>"""
|
return """</div><!-- /gtrcontent -->""" + CUSTOM_HTML_FOOTER + """</body></html>"""
|
||||||
|
@ -158,8 +158,7 @@ def sidebar(context, REQUEST=None):
|
|||||||
|
|
||||||
|
|
||||||
def sidebar_dept(context, REQUEST=None):
|
def sidebar_dept(context, REQUEST=None):
|
||||||
"""Partie supérieure de la marge de gauche
|
"""Partie supérieure de la marge de gauche"""
|
||||||
"""
|
|
||||||
infos = {
|
infos = {
|
||||||
"BASE0": REQUEST.BASE0,
|
"BASE0": REQUEST.BASE0,
|
||||||
"DeptIntranetTitle": context.get_preference("DeptIntranetTitle"),
|
"DeptIntranetTitle": context.get_preference("DeptIntranetTitle"),
|
||||||
|
@ -49,7 +49,7 @@ def histogram_notes(notes):
|
|||||||
"HTML code drawing histogram"
|
"HTML code drawing histogram"
|
||||||
if not notes:
|
if not notes:
|
||||||
return ""
|
return ""
|
||||||
bins, H = listhistogram.ListHistogram(notes, 21, minmax=(0, 20))
|
_, H = listhistogram.ListHistogram(notes, 21, minmax=(0, 20))
|
||||||
D = ['<ul id="vhist-q-graph"><li class="vhist-qtr" id="vhist-q1"><ul>']
|
D = ['<ul id="vhist-q-graph"><li class="vhist-qtr" id="vhist-q1"><ul>']
|
||||||
left = 5
|
left = 5
|
||||||
colwidth = 16 # must match #q-graph li.bar width in stylesheet
|
colwidth = 16 # must match #q-graph li.bar width in stylesheet
|
||||||
|
100
intervals.py
100
intervals.py
@ -10,53 +10,53 @@ from itertools import izip
|
|||||||
|
|
||||||
class intervalmap(object):
|
class intervalmap(object):
|
||||||
"""
|
"""
|
||||||
This class maps a set of intervals to a set of values.
|
This class maps a set of intervals to a set of values.
|
||||||
|
|
||||||
>>> i = intervalmap()
|
>>> i = intervalmap()
|
||||||
>>> i[0:5] = '0-5'
|
>>> i[0:5] = '0-5'
|
||||||
>>> i[8:12] = '8-12'
|
>>> i[8:12] = '8-12'
|
||||||
>>> print i[2]
|
>>> print i[2]
|
||||||
0-5
|
0-5
|
||||||
>>> print i[10]
|
>>> print i[10]
|
||||||
8-12
|
8-12
|
||||||
>>> print repr(i[-1])
|
>>> print repr(i[-1])
|
||||||
None
|
None
|
||||||
>>> print repr(i[17])
|
>>> print repr(i[17])
|
||||||
None
|
None
|
||||||
>>> i[4:9] = '4-9'
|
>>> i[4:9] = '4-9'
|
||||||
>>> print [(j,i[j]) for j in range(6)]
|
>>> print [(j,i[j]) for j in range(6)]
|
||||||
[(0, '0-5'), (1, '0-5'), (2, '0-5'), (3, '0-5'), (4, '4-9'), (5, '4-9')]
|
[(0, '0-5'), (1, '0-5'), (2, '0-5'), (3, '0-5'), (4, '4-9'), (5, '4-9')]
|
||||||
>>> print list(i.items())
|
>>> print list(i.items())
|
||||||
[((0, 4), '0-5'), ((4, 9), '4-9'), ((9, 12), '8-12')]
|
[((0, 4), '0-5'), ((4, 9), '4-9'), ((9, 12), '8-12')]
|
||||||
>>> i[:0] = 'less than 0'
|
>>> i[:0] = 'less than 0'
|
||||||
>>> i[-5]
|
>>> i[-5]
|
||||||
'less than 0'
|
'less than 0'
|
||||||
>>> i[0]
|
>>> i[0]
|
||||||
'0-5'
|
'0-5'
|
||||||
>>> print list(i.items())
|
>>> print list(i.items())
|
||||||
[((None, 0), 'less than 0'), ((0, 4), '0-5'), ((4, 9), '4-9'), ((9, 12), '8-12')]
|
[((None, 0), 'less than 0'), ((0, 4), '0-5'), ((4, 9), '4-9'), ((9, 12), '8-12')]
|
||||||
>>> i[21:] = 'more than twenty'
|
>>> i[21:] = 'more than twenty'
|
||||||
>>> i[42]
|
>>> i[42]
|
||||||
'more than twenty'
|
'more than twenty'
|
||||||
>>> i[10.5:15.5] = '10.5-15.5'
|
>>> i[10.5:15.5] = '10.5-15.5'
|
||||||
>>> i[11.5]
|
>>> i[11.5]
|
||||||
'10.5-15.5'
|
'10.5-15.5'
|
||||||
>>> i[0.5]
|
>>> i[0.5]
|
||||||
'0-5'
|
'0-5'
|
||||||
>>> print list(i.items())
|
>>> print list(i.items())
|
||||||
[((None, 0),... ((9, 10.5), '8-12'), ((10.5, 15.5), '10.5-15.5'), ((21, None),...
|
[((None, 0),... ((9, 10.5), '8-12'), ((10.5, 15.5), '10.5-15.5'), ((21, None),...
|
||||||
>>> i = intervalmap()
|
>>> i = intervalmap()
|
||||||
>>> i[0:2] = 1
|
>>> i[0:2] = 1
|
||||||
>>> i[2:8] = 2
|
>>> i[2:8] = 2
|
||||||
>>> i[4:] = 3
|
>>> i[4:] = 3
|
||||||
>>> i[5:6] = 4
|
>>> i[5:6] = 4
|
||||||
>>> i
|
>>> i
|
||||||
{[0, 2] => 1, [2, 4] => 2, [4, 5] => 3, [5, 6] => 4, [6, None] => 3}
|
{[0, 2] => 1, [2, 4] => 2, [4, 5] => 3, [5, 6] => 4, [6, None] => 3}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"""
|
"""
|
||||||
Initializes an empty intervalmap.
|
Initializes an empty intervalmap.
|
||||||
"""
|
"""
|
||||||
self._bounds = []
|
self._bounds = []
|
||||||
self._items = []
|
self._items = []
|
||||||
@ -64,7 +64,7 @@ class intervalmap(object):
|
|||||||
|
|
||||||
def __setitem__(self, _slice, _value):
|
def __setitem__(self, _slice, _value):
|
||||||
"""
|
"""
|
||||||
Sets an interval mapping.
|
Sets an interval mapping.
|
||||||
"""
|
"""
|
||||||
assert isinstance(_slice, slice), "The key must be a slice object"
|
assert isinstance(_slice, slice), "The key must be a slice object"
|
||||||
|
|
||||||
@ -112,7 +112,7 @@ class intervalmap(object):
|
|||||||
|
|
||||||
def __getitem__(self, _point):
|
def __getitem__(self, _point):
|
||||||
"""
|
"""
|
||||||
Gets a value from the mapping.
|
Gets a value from the mapping.
|
||||||
"""
|
"""
|
||||||
assert not isinstance(_point, slice), "The key cannot be a slice object"
|
assert not isinstance(_point, slice), "The key cannot be a slice object"
|
||||||
|
|
||||||
@ -124,9 +124,9 @@ class intervalmap(object):
|
|||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
"""
|
"""
|
||||||
Returns an iterator with each item being
|
Returns an iterator with each item being
|
||||||
((low_bound,high_bound), value). The items are returned
|
((low_bound,high_bound), value). The items are returned
|
||||||
in order.
|
in order.
|
||||||
"""
|
"""
|
||||||
previous_bound = None
|
previous_bound = None
|
||||||
for b, v in izip(self._bounds, self._items):
|
for b, v in izip(self._bounds, self._items):
|
||||||
@ -138,8 +138,8 @@ class intervalmap(object):
|
|||||||
|
|
||||||
def values(self):
|
def values(self):
|
||||||
"""
|
"""
|
||||||
Returns an iterator with each item being a stored value. The items
|
Returns an iterator with each item being a stored value. The items
|
||||||
are returned in order.
|
are returned in order.
|
||||||
"""
|
"""
|
||||||
for v in self._items:
|
for v in self._items:
|
||||||
if v is not None:
|
if v is not None:
|
||||||
|
@ -61,5 +61,5 @@ class CacheFunc:
|
|||||||
|
|
||||||
def inval_cache(self): # >
|
def inval_cache(self): # >
|
||||||
"clear whole cache"
|
"clear whole cache"
|
||||||
log("inval_cache %s(%s)" % (str(self.func), str(args))) # >
|
log("inval_cache %s" % (str(self.func))) # >
|
||||||
self.cache = {}
|
self.cache = {}
|
||||||
|
@ -88,7 +88,7 @@ def retreive_dept():
|
|||||||
return ""
|
return ""
|
||||||
try:
|
try:
|
||||||
url = REQUEST.URL
|
url = REQUEST.URL
|
||||||
m = re.match("^.*ScoDoc/(\w+).*$", url)
|
m = re.match(r"^.*ScoDoc/(\w+).*$", url)
|
||||||
return m.group(1)
|
return m.group(1)
|
||||||
except:
|
except:
|
||||||
return ""
|
return ""
|
||||||
|
@ -51,7 +51,7 @@ BONUS_TWO_ARGS = len(inspect.getargspec(CONFIG.compute_bonus)[0]) == 2
|
|||||||
|
|
||||||
|
|
||||||
def comp_ranks(T):
|
def comp_ranks(T):
|
||||||
"""Calcul rangs à partir d'une liste ordonnée de tuples [ (valeur, ..., etudid) ]
|
"""Calcul rangs à partir d'une liste ordonnée de tuples [ (valeur, ..., etudid) ]
|
||||||
(valeur est une note numérique), en tenant compte des ex-aequos
|
(valeur est une note numérique), en tenant compte des ex-aequos
|
||||||
Le resultat est: { etudid : rang } où rang est une chaine decrivant le rang
|
Le resultat est: { etudid : rang } où rang est une chaine decrivant le rang
|
||||||
"""
|
"""
|
||||||
@ -135,8 +135,8 @@ class NotesTable:
|
|||||||
- inscrlist: étudiants inscrits à ce semestre, par ordre alphabétique (avec demissions)
|
- inscrlist: étudiants inscrits à ce semestre, par ordre alphabétique (avec demissions)
|
||||||
- identdict: { etudid : ident }
|
- identdict: { etudid : ident }
|
||||||
- sem : le formsemestre
|
- sem : le formsemestre
|
||||||
get_table_moyennes_triees: [ (moy_gen, moy_ue1, moy_ue2, ... moy_ues, moy_mod1, ..., moy_modn, etudid) ]
|
get_table_moyennes_triees: [ (moy_gen, moy_ue1, moy_ue2, ... moy_ues, moy_mod1, ..., moy_modn, etudid) ]
|
||||||
(où toutes les valeurs sont soit des nombrs soit des chaines spéciales comme 'NA', 'NI'),
|
(où toutes les valeurs sont soit des nombrs soit des chaines spéciales comme 'NA', 'NI'),
|
||||||
incluant les UE de sport
|
incluant les UE de sport
|
||||||
|
|
||||||
- bonus[etudid] : valeur du bonus "sport".
|
- bonus[etudid] : valeur du bonus "sport".
|
||||||
@ -145,7 +145,7 @@ class NotesTable:
|
|||||||
- _modmoys : { moduleimpl_id : { etudid: note_moyenne_dans_ce_module } }
|
- _modmoys : { moduleimpl_id : { etudid: note_moyenne_dans_ce_module } }
|
||||||
- _ues : liste des UE de ce semestre (hors capitalisees)
|
- _ues : liste des UE de ce semestre (hors capitalisees)
|
||||||
- _matmoys : { matiere_id : { etudid: note moyenne dans cette matiere } }
|
- _matmoys : { matiere_id : { etudid: note moyenne dans cette matiere } }
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, context, formsemestre_id):
|
def __init__(self, context, formsemestre_id):
|
||||||
@ -408,7 +408,7 @@ class NotesTable:
|
|||||||
|
|
||||||
def get_ues(self, filter_sport=False, filter_non_inscrit=False, etudid=None):
|
def get_ues(self, filter_sport=False, filter_non_inscrit=False, etudid=None):
|
||||||
"""liste des ue, ordonnée par numero.
|
"""liste des ue, ordonnée par numero.
|
||||||
Si filter_non_inscrit, retire les UE dans lesquelles l'etudiant n'est
|
Si filter_non_inscrit, retire les UE dans lesquelles l'etudiant n'est
|
||||||
inscrit à aucun module.
|
inscrit à aucun module.
|
||||||
Si filter_sport, retire les UE de type SPORT
|
Si filter_sport, retire les UE de type SPORT
|
||||||
"""
|
"""
|
||||||
@ -580,11 +580,11 @@ class NotesTable:
|
|||||||
return matmoy.get(etudid, "NA")
|
return matmoy.get(etudid, "NA")
|
||||||
|
|
||||||
def comp_etud_moy_ue(self, etudid, ue_id=None, cnx=None):
|
def comp_etud_moy_ue(self, etudid, ue_id=None, cnx=None):
|
||||||
"""Calcule moyenne gen. pour un etudiant dans une UE
|
"""Calcule moyenne gen. pour un etudiant dans une UE
|
||||||
Ne prend en compte que les evaluations où toutes les notes sont entrées
|
Ne prend en compte que les evaluations où toutes les notes sont entrées
|
||||||
Return a dict(moy, nb_notes, nb_missing, sum_coefs)
|
Return a dict(moy, nb_notes, nb_missing, sum_coefs)
|
||||||
Si pas de notes, moy == 'NA' et sum_coefs==0
|
Si pas de notes, moy == 'NA' et sum_coefs==0
|
||||||
Si non inscrit, moy == 'NI' et sum_coefs==0
|
Si non inscrit, moy == 'NI' et sum_coefs==0
|
||||||
"""
|
"""
|
||||||
assert ue_id
|
assert ue_id
|
||||||
modimpls = self.get_modimpls(ue_id)
|
modimpls = self.get_modimpls(ue_id)
|
||||||
@ -608,7 +608,6 @@ class NotesTable:
|
|||||||
est_inscrit = False # inscrit à l'un des modules de cette UE ?
|
est_inscrit = False # inscrit à l'un des modules de cette UE ?
|
||||||
|
|
||||||
for modimpl in modimpls:
|
for modimpl in modimpls:
|
||||||
mod_ue_id = modimpl["ue"]["ue_id"]
|
|
||||||
# module ne faisant pas partie d'une UE capitalisee
|
# module ne faisant pas partie d'une UE capitalisee
|
||||||
val = self._modmoys[modimpl["moduleimpl_id"]].get(etudid, "NI")
|
val = self._modmoys[modimpl["moduleimpl_id"]].get(etudid, "NI")
|
||||||
# si 'NI', etudiant non inscrit a ce module
|
# si 'NI', etudiant non inscrit a ce module
|
||||||
@ -711,7 +710,7 @@ class NotesTable:
|
|||||||
def comp_etud_moy_gen(self, etudid, cnx):
|
def comp_etud_moy_gen(self, etudid, cnx):
|
||||||
"""Calcule moyenne gen. pour un etudiant
|
"""Calcule moyenne gen. pour un etudiant
|
||||||
Return a dict:
|
Return a dict:
|
||||||
moy : moyenne générale
|
moy : moyenne générale
|
||||||
nb_notes, nb_missing, sum_coefs
|
nb_notes, nb_missing, sum_coefs
|
||||||
ects_pot : (float) nb de crédits ECTS qui seraient validés (sous réserve de validation par le jury),
|
ects_pot : (float) nb de crédits ECTS qui seraient validés (sous réserve de validation par le jury),
|
||||||
ects_pot_fond: (float) nb d'ECTS issus d'UE fondamentales (non électives)
|
ects_pot_fond: (float) nb d'ECTS issus d'UE fondamentales (non électives)
|
||||||
@ -721,14 +720,14 @@ class NotesTable:
|
|||||||
'est_inscrit' : True si étudiant inscrit à au moins un module de cette UE
|
'est_inscrit' : True si étudiant inscrit à au moins un module de cette UE
|
||||||
'moy' : moyenne, avec capitalisation eventuelle
|
'moy' : moyenne, avec capitalisation eventuelle
|
||||||
'coef_ue' : coef de l'UE utilisé pour le calcul de la moyenne générale
|
'coef_ue' : coef de l'UE utilisé pour le calcul de la moyenne générale
|
||||||
(la somme des coefs des modules, ou le coef d'UE capitalisée,
|
(la somme des coefs des modules, ou le coef d'UE capitalisée,
|
||||||
ou encore le coef d'UE si l'option use_ue_coefs est active)
|
ou encore le coef d'UE si l'option use_ue_coefs est active)
|
||||||
'cur_moy_ue' : moyenne de l'UE en cours (sans considérer de capitalisation)
|
'cur_moy_ue' : moyenne de l'UE en cours (sans considérer de capitalisation)
|
||||||
'cur_coef_ue': coefficient de l'UE courante
|
'cur_coef_ue': coefficient de l'UE courante
|
||||||
'is_capitalized' : True|False,
|
'is_capitalized' : True|False,
|
||||||
'ects_pot' : (float) nb de crédits ECTS qui seraient validés (sous réserve de validation par le jury),
|
'ects_pot' : (float) nb de crédits ECTS qui seraient validés (sous réserve de validation par le jury),
|
||||||
'ects_pot_fond': 0. si UE non fondamentale, = ects_pot sinon,
|
'ects_pot_fond': 0. si UE non fondamentale, = ects_pot sinon,
|
||||||
'ects_pot_pro' : 0 si UE non pro, = ects_pot sinon,
|
'ects_pot_pro' : 0 si UE non pro, = ects_pot sinon,
|
||||||
'formsemestre_id' : (si capitalisee),
|
'formsemestre_id' : (si capitalisee),
|
||||||
'event_date' : (si capitalisee)
|
'event_date' : (si capitalisee)
|
||||||
}
|
}
|
||||||
@ -760,7 +759,6 @@ class NotesTable:
|
|||||||
sem_ects_pot_pro = 0.0
|
sem_ects_pot_pro = 0.0
|
||||||
|
|
||||||
for ue in self.get_ues():
|
for ue in self.get_ues():
|
||||||
ue_id = ue["ue_id"]
|
|
||||||
# - On calcule la moyenne d'UE courante:
|
# - On calcule la moyenne d'UE courante:
|
||||||
if not block_computation:
|
if not block_computation:
|
||||||
mu = self.comp_etud_moy_ue(etudid, ue_id=ue["ue_id"], cnx=cnx)
|
mu = self.comp_etud_moy_ue(etudid, ue_id=ue["ue_id"], cnx=cnx)
|
||||||
@ -956,10 +954,10 @@ class NotesTable:
|
|||||||
Ne considère que les UE ayant des notes (moyenne calculée).
|
Ne considère que les UE ayant des notes (moyenne calculée).
|
||||||
(les UE sans notes ne sont pas comptées comme sous la barre)
|
(les UE sans notes ne sont pas comptées comme sous la barre)
|
||||||
Prend en compte les éventuelles UE capitalisées.
|
Prend en compte les éventuelles UE capitalisées.
|
||||||
|
|
||||||
Pour les parcours habituels, cela revient à vérifier que
|
Pour les parcours habituels, cela revient à vérifier que
|
||||||
les moyennes d'UE sont toutes > à leur barre (sauf celles sans notes)
|
les moyennes d'UE sont toutes > à leur barre (sauf celles sans notes)
|
||||||
|
|
||||||
Pour les parcours non standards (LP2014), cela peut être plus compliqué.
|
Pour les parcours non standards (LP2014), cela peut être plus compliqué.
|
||||||
|
|
||||||
Return: True|False, message explicatif
|
Return: True|False, message explicatif
|
||||||
@ -1000,8 +998,7 @@ class NotesTable:
|
|||||||
)
|
)
|
||||||
|
|
||||||
def get_table_moyennes_dict(self):
|
def get_table_moyennes_dict(self):
|
||||||
"""{ etudid : (liste des moyennes) } comme get_table_moyennes_triees
|
"""{ etudid : (liste des moyennes) } comme get_table_moyennes_triees"""
|
||||||
"""
|
|
||||||
D = {}
|
D = {}
|
||||||
for t in self.T:
|
for t in self.T:
|
||||||
D[t[-1]] = t
|
D[t[-1]] = t
|
||||||
@ -1209,13 +1206,13 @@ class NotesTable:
|
|||||||
# return sum(c_list)
|
# return sum(c_list)
|
||||||
|
|
||||||
def get_etud_ue_cap_coef(self, etudid, ue, ue_cap, cnx=None):
|
def get_etud_ue_cap_coef(self, etudid, ue, ue_cap, cnx=None):
|
||||||
"""Calcule le coefficient d'une UE capitalisée, pour cet étudiant,
|
"""Calcule le coefficient d'une UE capitalisée, pour cet étudiant,
|
||||||
injectée dans le semestre courant.
|
injectée dans le semestre courant.
|
||||||
|
|
||||||
ue : ue du semestre courant
|
ue : ue du semestre courant
|
||||||
|
|
||||||
ue_cap = resultat de formsemestre_get_etud_capitalisation
|
ue_cap = resultat de formsemestre_get_etud_capitalisation
|
||||||
{ 'ue_id' (dans le semestre source),
|
{ 'ue_id' (dans le semestre source),
|
||||||
'ue_code', 'moy', 'event_date','formsemestre_id' }
|
'ue_code', 'moy', 'event_date','formsemestre_id' }
|
||||||
"""
|
"""
|
||||||
# log("get_etud_ue_cap_coef\nformsemestre_id='%s'\netudid='%s'\nue=%s\nue_cap=%s\n" % (self.formsemestre_id, etudid, ue, ue_cap))
|
# log("get_etud_ue_cap_coef\nformsemestre_id='%s'\netudid='%s'\nue=%s\nue_cap=%s\n" % (self.formsemestre_id, etudid, ue, ue_cap))
|
||||||
@ -1291,8 +1288,7 @@ class NotesTable:
|
|||||||
return len(cursor.fetchall()) > 0
|
return len(cursor.fetchall()) > 0
|
||||||
|
|
||||||
def get_evaluations_etats(self): # evaluation_list_in_sem
|
def get_evaluations_etats(self): # evaluation_list_in_sem
|
||||||
"""[ {...evaluation et son etat...} ]
|
"""[ {...evaluation et son etat...} ]"""
|
||||||
"""
|
|
||||||
if self._evaluations_etats is None:
|
if self._evaluations_etats is None:
|
||||||
self._evaluations_etats = sco_evaluations.do_evaluation_list_in_sem(
|
self._evaluations_etats = sco_evaluations.do_evaluation_list_in_sem(
|
||||||
self.context, self.formsemestre_id
|
self.context, self.formsemestre_id
|
||||||
@ -1301,13 +1297,11 @@ class NotesTable:
|
|||||||
return self._evaluations_etats
|
return self._evaluations_etats
|
||||||
|
|
||||||
def get_sem_evaluation_etat_list(self):
|
def get_sem_evaluation_etat_list(self):
|
||||||
"""Liste des evaluations de ce semestre, avec leur etat
|
"""Liste des evaluations de ce semestre, avec leur etat"""
|
||||||
"""
|
|
||||||
return self.get_evaluations_etats()
|
return self.get_evaluations_etats()
|
||||||
|
|
||||||
def get_mod_evaluation_etat_list(self, moduleimpl_id):
|
def get_mod_evaluation_etat_list(self, moduleimpl_id):
|
||||||
"""Liste des évaluations de ce module
|
"""Liste des évaluations de ce module"""
|
||||||
"""
|
|
||||||
return [
|
return [
|
||||||
e
|
e
|
||||||
for e in self.get_evaluations_etats()
|
for e in self.get_evaluations_etats()
|
||||||
|
@ -50,7 +50,7 @@ DONNEE_MANQUANTE = (
|
|||||||
# ----------------------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------------------
|
||||||
def get_code_latex_from_modele(fichier):
|
def get_code_latex_from_modele(fichier):
|
||||||
"""Lit le code latex à partir d'un modèle. Renvoie une chaine unicode.
|
"""Lit le code latex à partir d'un modèle. Renvoie une chaine unicode.
|
||||||
|
|
||||||
Le fichier doit contenir le chemin relatif
|
Le fichier doit contenir le chemin relatif
|
||||||
vers le modele : attention pas de vérification du format d'encodage
|
vers le modele : attention pas de vérification du format d'encodage
|
||||||
Le fichier doit donc etre enregistré avec le même codage que ScoDoc (utf-8)
|
Le fichier doit donc etre enregistré avec le même codage que ScoDoc (utf-8)
|
||||||
@ -85,7 +85,7 @@ def get_tags_latex(code_latex):
|
|||||||
à la lecture d'un modèle d'avis pe).
|
à la lecture d'un modèle d'avis pe).
|
||||||
Ces tags sont répérés par les balises **, débutant et finissant le tag
|
Ces tags sont répérés par les balises **, débutant et finissant le tag
|
||||||
et sont renvoyés sous la forme d'une liste.
|
et sont renvoyés sous la forme d'une liste.
|
||||||
|
|
||||||
result: liste de chaines unicode
|
result: liste de chaines unicode
|
||||||
"""
|
"""
|
||||||
if code_latex:
|
if code_latex:
|
||||||
@ -144,7 +144,7 @@ def comp_latex_parcourstimeline(etudiant, promo, taille=17):
|
|||||||
|
|
||||||
# ----------------------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------------------
|
||||||
def interprete_tag_latex(tag):
|
def interprete_tag_latex(tag):
|
||||||
"""Découpe les tags latex de la forme S1:groupe:dut:min et renvoie si possible
|
"""Découpe les tags latex de la forme S1:groupe:dut:min et renvoie si possible
|
||||||
le résultat sous la forme d'un quadruplet.
|
le résultat sous la forme d'un quadruplet.
|
||||||
"""
|
"""
|
||||||
infotag = tag.split(":")
|
infotag = tag.split(":")
|
||||||
@ -164,7 +164,7 @@ def get_code_latex_avis_etudiant(
|
|||||||
donnees_etudiant, un_avis_latex, annotationPE, footer_latex, prefs
|
donnees_etudiant, un_avis_latex, annotationPE, footer_latex, prefs
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Renvoie le code latex permettant de générer l'avis d'un étudiant en utilisant ses
|
Renvoie le code latex permettant de générer l'avis d'un étudiant en utilisant ses
|
||||||
donnees_etudiant contenu dans le dictionnaire de synthèse du jury PE et en suivant un
|
donnees_etudiant contenu dans le dictionnaire de synthèse du jury PE et en suivant un
|
||||||
fichier modele donné
|
fichier modele donné
|
||||||
|
|
||||||
@ -228,8 +228,8 @@ def get_code_latex_avis_etudiant(
|
|||||||
|
|
||||||
# ----------------------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------------------
|
||||||
def get_annotation_PE(context, etudid, tag_annotation_pe):
|
def get_annotation_PE(context, etudid, tag_annotation_pe):
|
||||||
"""Renvoie l'annotation PE dans la liste de ces annotations ;
|
"""Renvoie l'annotation PE dans la liste de ces annotations ;
|
||||||
Cette annotation est reconnue par la présence d'un tag **PE**
|
Cette annotation est reconnue par la présence d'un tag **PE**
|
||||||
(cf. context.get_preferences -> pe_tag_annotation_avis_latex).
|
(cf. context.get_preferences -> pe_tag_annotation_avis_latex).
|
||||||
|
|
||||||
Result: chaine unicode
|
Result: chaine unicode
|
||||||
@ -269,8 +269,8 @@ def get_annotation_PE(context, etudid, tag_annotation_pe):
|
|||||||
|
|
||||||
# ----------------------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------------------
|
||||||
def str_from_syntheseJury(donnees_etudiant, aggregat, groupe, tag_scodoc, champ):
|
def str_from_syntheseJury(donnees_etudiant, aggregat, groupe, tag_scodoc, champ):
|
||||||
"""Extrait du dictionnaire de synthèse du juryPE pour un étudiant donnée,
|
"""Extrait du dictionnaire de synthèse du juryPE pour un étudiant donnée,
|
||||||
une valeur indiquée par un champ ;
|
une valeur indiquée par un champ ;
|
||||||
si champ est une liste, renvoie la liste des valeurs extraites.
|
si champ est une liste, renvoie la liste des valeurs extraites.
|
||||||
|
|
||||||
Result: chaine unicode ou liste de chaines unicode
|
Result: chaine unicode ou liste de chaines unicode
|
||||||
@ -322,7 +322,7 @@ def str_from_syntheseJury(donnees_etudiant, aggregat, groupe, tag_scodoc, champ)
|
|||||||
|
|
||||||
# ----------------------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------------------
|
||||||
def get_bilanParTag(donnees_etudiant, groupe="groupe"):
|
def get_bilanParTag(donnees_etudiant, groupe="groupe"):
|
||||||
"""Renvoie le code latex d'un tableau récapitulant, pour tous les tags trouvés dans
|
"""Renvoie le code latex d'un tableau récapitulant, pour tous les tags trouvés dans
|
||||||
les données étudiants, ses résultats.
|
les données étudiants, ses résultats.
|
||||||
result: chaine unicode
|
result: chaine unicode
|
||||||
"""
|
"""
|
||||||
@ -474,8 +474,7 @@ def get_templates_from_distrib(template="avis"):
|
|||||||
|
|
||||||
# ----------------------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------------------
|
||||||
def table_syntheseAnnotationPE(context, syntheseJury, tag_annotation_pe):
|
def table_syntheseAnnotationPE(context, syntheseJury, tag_annotation_pe):
|
||||||
"""Génère un fichier excel synthétisant les annotations PE telles qu'inscrites dans les fiches de chaque étudiant
|
"""Génère un fichier excel synthétisant les annotations PE telles qu'inscrites dans les fiches de chaque étudiant"""
|
||||||
"""
|
|
||||||
sT = SeqGenTable() # le fichier excel à générer
|
sT = SeqGenTable() # le fichier excel à générer
|
||||||
|
|
||||||
# Les etudids des étudiants à afficher, triés par ordre alphabétiques de nom+prénom
|
# Les etudids des étudiants à afficher, triés par ordre alphabétiques de nom+prénom
|
||||||
|
34
pe_jurype.py
34
pe_jurype.py
@ -88,7 +88,7 @@ class JuryPE:
|
|||||||
{'etudid : { 'nom', 'prenom', 'sexe', 'diplome', '', }}
|
{'etudid : { 'nom', 'prenom', 'sexe', 'diplome', '', }}
|
||||||
Rq: il contient à la fois les étudiants qui vont être diplomés à la date prévue
|
Rq: il contient à la fois les étudiants qui vont être diplomés à la date prévue
|
||||||
et ceux qui sont éliminés (abandon, redoublement, ...) pour affichage alternatif
|
et ceux qui sont éliminés (abandon, redoublement, ...) pour affichage alternatif
|
||||||
|
|
||||||
|
|
||||||
Note (EV:): les attributs sont des chaines encodées (utf8), comme dans ScoDoc (pas des unicodes)
|
Note (EV:): les attributs sont des chaines encodées (utf8), comme dans ScoDoc (pas des unicodes)
|
||||||
"""
|
"""
|
||||||
@ -210,8 +210,7 @@ class JuryPE:
|
|||||||
|
|
||||||
# ------------------------------------------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------------------------------------------
|
||||||
def get_zipped_data(self):
|
def get_zipped_data(self):
|
||||||
"""returns zipped data with all generated (CSV) files
|
"""returns zipped data with all generated (CSV) files"""
|
||||||
"""
|
|
||||||
if self.zipfile:
|
if self.zipfile:
|
||||||
self.zipfile.close()
|
self.zipfile.close()
|
||||||
self.zipfile = None
|
self.zipfile = None
|
||||||
@ -366,7 +365,7 @@ class JuryPE:
|
|||||||
|
|
||||||
# ------------------------------------------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------------------------------------------
|
||||||
def add_etudiants(self, etudid):
|
def add_etudiants(self, etudid):
|
||||||
""" Ajoute un étudiant (via son etudid) au dictionnaire de synthèse jurydict.
|
"""Ajoute un étudiant (via son etudid) au dictionnaire de synthèse jurydict.
|
||||||
L'ajout consiste à :
|
L'ajout consiste à :
|
||||||
> insérer une entrée pour l'étudiant en mémorisant ses infos (get_etudInfo),
|
> insérer une entrée pour l'étudiant en mémorisant ses infos (get_etudInfo),
|
||||||
avec son nom, prénom, etc...
|
avec son nom, prénom, etc...
|
||||||
@ -479,7 +478,7 @@ class JuryPE:
|
|||||||
pour autant avoir été indiqué NAR ou DEM ; recherche son dernier semestre validé et regarde s'il
|
pour autant avoir été indiqué NAR ou DEM ; recherche son dernier semestre validé et regarde s'il
|
||||||
n'existe pas parmi les semestres existants dans scodoc un semestre postérieur (en terme de date de
|
n'existe pas parmi les semestres existants dans scodoc un semestre postérieur (en terme de date de
|
||||||
début) de n° au moins égal à celui de son dernier semestre valide dans lequel il aurait pu
|
début) de n° au moins égal à celui de son dernier semestre valide dans lequel il aurait pu
|
||||||
s'inscrire mais ne l'a pas fait. """
|
s'inscrire mais ne l'a pas fait."""
|
||||||
sessems = self.get_semestresDUT_d_un_etudiant(
|
sessems = self.get_semestresDUT_d_un_etudiant(
|
||||||
etudid
|
etudid
|
||||||
) # les semestres de l'étudiant
|
) # les semestres de l'étudiant
|
||||||
@ -868,9 +867,7 @@ class JuryPE:
|
|||||||
return semDeb["annee_debut"]
|
return semDeb["annee_debut"]
|
||||||
|
|
||||||
def get_parcoursIUT(self, etudid):
|
def get_parcoursIUT(self, etudid):
|
||||||
"""Renvoie une liste d'infos sur les semestres du parcours d'un étudiant
|
"""Renvoie une liste d'infos sur les semestres du parcours d'un étudiant"""
|
||||||
|
|
||||||
"""
|
|
||||||
etudinfo = self.ETUDINFO_DICT[etudid]
|
etudinfo = self.ETUDINFO_DICT[etudid]
|
||||||
sems = self.get_semestresDUT_d_un_etudiant(etudid)
|
sems = self.get_semestresDUT_d_un_etudiant(etudid)
|
||||||
|
|
||||||
@ -934,7 +931,7 @@ class JuryPE:
|
|||||||
|
|
||||||
def get_allTagForAggregat(self, nom_aggregat):
|
def get_allTagForAggregat(self, nom_aggregat):
|
||||||
"""Extrait du dictionnaire syntheseJury la liste des tags d'un semestre ou
|
"""Extrait du dictionnaire syntheseJury la liste des tags d'un semestre ou
|
||||||
d'un aggrégat donné par son nom (S1, S2, S3 ou S4, 1A, ...). Renvoie [] si aucun tag."""
|
d'un aggrégat donné par son nom (S1, S2, S3 ou S4, 1A, ...). Renvoie [] si aucun tag."""
|
||||||
taglist = set()
|
taglist = set()
|
||||||
for etudid in self.get_etudids_du_jury():
|
for etudid in self.get_etudids_du_jury():
|
||||||
taglist = taglist.union(
|
taglist = taglist.union(
|
||||||
@ -1127,10 +1124,9 @@ class JuryPE:
|
|||||||
|
|
||||||
# ------------------------------------------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------------------------------------------
|
||||||
def get_cache_notes_d_un_semestre(
|
def get_cache_notes_d_un_semestre(
|
||||||
cls, context, formsemestre_id
|
self, context, formsemestre_id
|
||||||
): # inutile en realité !
|
): # inutile en realité !
|
||||||
"""Charge la table des notes d'un formsemestre
|
"""Charge la table des notes d'un formsemestre"""
|
||||||
"""
|
|
||||||
return context.Notes._getNotesCache().get_NotesTable(
|
return context.Notes._getNotesCache().get_NotesTable(
|
||||||
context.Notes, formsemestre_id
|
context.Notes, formsemestre_id
|
||||||
)
|
)
|
||||||
@ -1196,7 +1192,7 @@ class JuryPE:
|
|||||||
|
|
||||||
# ----------------------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------------------
|
||||||
def get_annee_diplome_semestre(sem):
|
def get_annee_diplome_semestre(sem):
|
||||||
""" Pour un semestre donne, décrit par le biais du dictionnaire sem usuel :
|
"""Pour un semestre donne, décrit par le biais du dictionnaire sem usuel :
|
||||||
sem = {'formestre_id': ..., 'semestre_id': ..., 'annee_debut': ...},
|
sem = {'formestre_id': ..., 'semestre_id': ..., 'annee_debut': ...},
|
||||||
à condition qu'il soit un semestre de formation DUT,
|
à condition qu'il soit un semestre de formation DUT,
|
||||||
predit l'annee à laquelle sera remis le diplome DUT des etudiants scolarisés dans le semestre
|
predit l'annee à laquelle sera remis le diplome DUT des etudiants scolarisés dans le semestre
|
||||||
@ -1230,12 +1226,12 @@ def get_annee_diplome_semestre(sem):
|
|||||||
|
|
||||||
# ----------------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------------
|
||||||
def get_cosemestres_diplomants(context, semBase, avec_meme_formation=False):
|
def get_cosemestres_diplomants(context, semBase, avec_meme_formation=False):
|
||||||
""" Partant d'un semestre de Base = {'formsemestre_id': ..., 'semestre_id': ..., 'annee_debut': ...},
|
"""Partant d'un semestre de Base = {'formsemestre_id': ..., 'semestre_id': ..., 'annee_debut': ...},
|
||||||
renvoie la liste de tous ses co-semestres (lui-meme inclus)
|
renvoie la liste de tous ses co-semestres (lui-meme inclus)
|
||||||
Par co-semestre, s'entend les semestres :
|
Par co-semestre, s'entend les semestres :
|
||||||
> dont l'annee predite pour la remise du diplome DUT est la meme
|
> dont l'annee predite pour la remise du diplome DUT est la meme
|
||||||
> dont la formation est la même (optionnel)
|
> dont la formation est la même (optionnel)
|
||||||
> ne prenant en compte que les etudiants sans redoublement
|
> ne prenant en compte que les etudiants sans redoublement
|
||||||
"""
|
"""
|
||||||
tousLesSems = (
|
tousLesSems = (
|
||||||
context.Notes.formsemestre_list()
|
context.Notes.formsemestre_list()
|
||||||
|
@ -144,8 +144,7 @@ class SetTag(pe_tagtable.TableTag):
|
|||||||
|
|
||||||
# -------------------------------------------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------------------------------------------------
|
||||||
def do_tagdict(self):
|
def do_tagdict(self):
|
||||||
"""Synthétise la liste des modules pris en compte dans le calcul d'un tag (pour analyse des résultats)
|
"""Synthétise la liste des modules pris en compte dans le calcul d'un tag (pour analyse des résultats)"""
|
||||||
"""
|
|
||||||
self.tagdict = {}
|
self.tagdict = {}
|
||||||
for semtag in self.SemTagDict.values():
|
for semtag in self.SemTagDict.values():
|
||||||
for tag in semtag.get_all_tags():
|
for tag in semtag.get_all_tags():
|
||||||
@ -208,8 +207,8 @@ class SetTag(pe_tagtable.TableTag):
|
|||||||
|
|
||||||
class SetTagInterClasse(pe_tagtable.TableTag):
|
class SetTagInterClasse(pe_tagtable.TableTag):
|
||||||
"""Récupère les moyennes de SetTag aggrégant un même parcours (par ex un ['S1', 'S2'] n'ayant pas fini au même S2
|
"""Récupère les moyennes de SetTag aggrégant un même parcours (par ex un ['S1', 'S2'] n'ayant pas fini au même S2
|
||||||
pour fournir un interclassement sur un groupe d'étudiant => seul compte alors la promo
|
pour fournir un interclassement sur un groupe d'étudiant => seul compte alors la promo
|
||||||
nom_combinaison = 'S1' ou '1A'
|
nom_combinaison = 'S1' ou '1A'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# -------------------------------------------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -95,7 +95,7 @@ class TableTag:
|
|||||||
|
|
||||||
# -----------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------
|
||||||
def get_coeff_from_resultats(self, tag, etudid):
|
def get_coeff_from_resultats(self, tag, etudid):
|
||||||
"""Renvoie la somme des coeffs de pondération normalisée utilisés dans le calcul de la moyenne à un tag d'un étudiant
|
"""Renvoie la somme des coeffs de pondération normalisée utilisés dans le calcul de la moyenne à un tag d'un étudiant
|
||||||
au regard du format de self.resultats.
|
au regard du format de self.resultats.
|
||||||
"""
|
"""
|
||||||
return (
|
return (
|
||||||
@ -329,7 +329,7 @@ def moyenne_ponderee_terme_a_terme(notes, coeffs=None, force=False):
|
|||||||
|
|
||||||
# -------------------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------------------------
|
||||||
def conversionDate_StrToDate(date_fin):
|
def conversionDate_StrToDate(date_fin):
|
||||||
""" Conversion d'une date fournie sous la forme d'une chaine de caractère de
|
"""Conversion d'une date fournie sous la forme d'une chaine de caractère de
|
||||||
type 'jj/mm/aaaa' en un objet date du package datetime.
|
type 'jj/mm/aaaa' en un objet date du package datetime.
|
||||||
Fonction servant au tri des semestres par date
|
Fonction servant au tri des semestres par date
|
||||||
"""
|
"""
|
||||||
|
@ -97,7 +97,7 @@ def print_semestres_description(sems, avec_affichage_debug=False):
|
|||||||
|
|
||||||
# ----------------------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------------------
|
||||||
def calcul_age(born):
|
def calcul_age(born):
|
||||||
"""Calcule l'age à partir de la date de naissance sous forme d'une chaine de caractère 'jj/mm/aaaa'.
|
"""Calcule l'age à partir de la date de naissance sous forme d'une chaine de caractère 'jj/mm/aaaa'.
|
||||||
Aucun test de validité sur le format de la date n'est fait.
|
Aucun test de validité sur le format de la date n'est fait.
|
||||||
"""
|
"""
|
||||||
if not isinstance(born, str) or born == "":
|
if not isinstance(born, str) or born == "":
|
||||||
@ -122,8 +122,7 @@ def remove_accents(input_unicode_str):
|
|||||||
|
|
||||||
|
|
||||||
def escape_for_latex(s):
|
def escape_for_latex(s):
|
||||||
"""Protège les caractères pour inclusion dans du source LaTeX
|
"""Protège les caractères pour inclusion dans du source LaTeX"""
|
||||||
"""
|
|
||||||
if not s:
|
if not s:
|
||||||
return ""
|
return ""
|
||||||
conv = {
|
conv = {
|
||||||
@ -162,8 +161,7 @@ def list_directory_filenames(path):
|
|||||||
|
|
||||||
|
|
||||||
def add_local_file_to_zip(zipfile, ziproot, pathname, path_in_zip):
|
def add_local_file_to_zip(zipfile, ziproot, pathname, path_in_zip):
|
||||||
"""Read pathname server file and add content to zip under path_in_zip
|
"""Read pathname server file and add content to zip under path_in_zip"""
|
||||||
"""
|
|
||||||
rooted_path_in_zip = os.path.join(ziproot, path_in_zip)
|
rooted_path_in_zip = os.path.join(ziproot, path_in_zip)
|
||||||
data = open(pathname).read()
|
data = open(pathname).read()
|
||||||
zipfile.writestr(rooted_path_in_zip, data)
|
zipfile.writestr(rooted_path_in_zip, data)
|
||||||
|
@ -89,7 +89,7 @@ def pe_view_sem_recap(
|
|||||||
REQUEST=None,
|
REQUEST=None,
|
||||||
):
|
):
|
||||||
"""Génération des avis de poursuite d'étude
|
"""Génération des avis de poursuite d'étude
|
||||||
|
|
||||||
mode_debug = Pour "squeezer" le calcul du jury pe (long)
|
mode_debug = Pour "squeezer" le calcul du jury pe (long)
|
||||||
et debugger uniquement la partie avis latex
|
et debugger uniquement la partie avis latex
|
||||||
"""
|
"""
|
||||||
|
@ -47,7 +47,7 @@ import sco_formsemestre
|
|||||||
|
|
||||||
def abs_notify(context, etudid, date):
|
def abs_notify(context, etudid, date):
|
||||||
"""Check if notifications are requested and send them
|
"""Check if notifications are requested and send them
|
||||||
Considère le nombre d'absence dans le semestre courant
|
Considère le nombre d'absence dans le semestre courant
|
||||||
(s'il n'y a pas de semestre courant, ne fait rien,
|
(s'il n'y a pas de semestre courant, ne fait rien,
|
||||||
car l'etudiant n'est pas inscrit au moment de l'absence!).
|
car l'etudiant n'est pas inscrit au moment de l'absence!).
|
||||||
"""
|
"""
|
||||||
@ -64,8 +64,7 @@ def abs_notify(context, etudid, date):
|
|||||||
|
|
||||||
|
|
||||||
def do_abs_notify(context, sem, etudid, date, nbabs, nbabsjust):
|
def do_abs_notify(context, sem, etudid, date, nbabs, nbabsjust):
|
||||||
"""Given new counts of absences, check if notifications are requested and send them.
|
"""Given new counts of absences, check if notifications are requested and send them."""
|
||||||
"""
|
|
||||||
# prefs fallback to global pref if sem is None:
|
# prefs fallback to global pref if sem is None:
|
||||||
if sem:
|
if sem:
|
||||||
formsemestre_id = sem["formsemestre_id"]
|
formsemestre_id = sem["formsemestre_id"]
|
||||||
@ -131,8 +130,7 @@ def abs_notify_send(
|
|||||||
|
|
||||||
|
|
||||||
def abs_notify_get_destinations(context, sem, prefs, etudid, date, nbabs, nbabsjust):
|
def abs_notify_get_destinations(context, sem, prefs, etudid, date, nbabs, nbabsjust):
|
||||||
"""Returns set of destination emails to be notified
|
"""Returns set of destination emails to be notified"""
|
||||||
"""
|
|
||||||
formsemestre_id = sem["formsemestre_id"]
|
formsemestre_id = sem["formsemestre_id"]
|
||||||
|
|
||||||
destinations = [] # list of email address to notify
|
destinations = [] # list of email address to notify
|
||||||
@ -176,8 +174,8 @@ def abs_notify_is_above_threshold(context, etudid, nbabs, nbabsjust, formsemestr
|
|||||||
|
|
||||||
nbabs: nombre d'absence (de tous types, unité de compte = demi-journée)
|
nbabs: nombre d'absence (de tous types, unité de compte = demi-journée)
|
||||||
nbabsjust: nombre d'absences justifiées
|
nbabsjust: nombre d'absences justifiées
|
||||||
|
|
||||||
(nbabs > abs_notify_abs_threshold)
|
(nbabs > abs_notify_abs_threshold)
|
||||||
(nbabs - nbabs_last_notified) > abs_notify_abs_increment
|
(nbabs - nbabs_last_notified) > abs_notify_abs_increment
|
||||||
"""
|
"""
|
||||||
abs_notify_abs_threshold = context.get_preference(
|
abs_notify_abs_threshold = context.get_preference(
|
||||||
@ -282,8 +280,7 @@ def retreive_current_formsemestre(context, etudid, cur_date):
|
|||||||
|
|
||||||
|
|
||||||
def mod_with_evals_at_date(context, date_abs, etudid):
|
def mod_with_evals_at_date(context, date_abs, etudid):
|
||||||
"""Liste des moduleimpls avec des evaluations a la date indiquée
|
"""Liste des moduleimpls avec des evaluations a la date indiquée"""
|
||||||
"""
|
|
||||||
req = """SELECT m.* FROM notes_moduleimpl m, notes_evaluation e, notes_moduleimpl_inscription i
|
req = """SELECT m.* FROM notes_moduleimpl m, notes_evaluation e, notes_moduleimpl_inscription i
|
||||||
WHERE m.moduleimpl_id = e.moduleimpl_id AND e.moduleimpl_id = i.moduleimpl_id
|
WHERE m.moduleimpl_id = e.moduleimpl_id AND e.moduleimpl_id = i.moduleimpl_id
|
||||||
AND i.etudid = %(etudid)s AND e.jour = %(date_abs)s"""
|
AND i.etudid = %(etudid)s AND e.jour = %(date_abs)s"""
|
||||||
|
@ -62,8 +62,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"),
|
context.sco_header(REQUEST, page_title="Comparaison de fichiers Apogée"),
|
||||||
"""<h2>Comparaison de fichiers Apogée</h2>
|
"""<h2>Comparaison de fichiers Apogée</h2>
|
||||||
@ -90,8 +89,7 @@ def apo_compare_csv_form(context, REQUEST=None):
|
|||||||
|
|
||||||
|
|
||||||
def apo_compare_csv(context, A_file, B_file, autodetect=True, REQUEST=None):
|
def apo_compare_csv(context, A_file, B_file, autodetect=True, REQUEST=None):
|
||||||
"""Page comparing 2 Apogee CSV files
|
"""Page comparing 2 Apogee CSV files"""
|
||||||
"""
|
|
||||||
A = _load_apo_data(A_file, autodetect=autodetect)
|
A = _load_apo_data(A_file, autodetect=autodetect)
|
||||||
B = _load_apo_data(B_file, autodetect=autodetect)
|
B = _load_apo_data(B_file, autodetect=autodetect)
|
||||||
|
|
||||||
@ -182,7 +180,11 @@ def _apo_compare_csv(context, A, B, REQUEST=None):
|
|||||||
elts_only_B = B_elts - A_elts.intersection(B_elts)
|
elts_only_B = B_elts - A_elts.intersection(B_elts)
|
||||||
L.append(
|
L.append(
|
||||||
'<span class="val_dif">différents (%d en commun, %d seulement dans A, %d seulement dans B)</span>'
|
'<span class="val_dif">différents (%d en commun, %d seulement dans A, %d seulement dans B)</span>'
|
||||||
% (len(elts_communs), len(elts_only_A), len(elts_only_B),)
|
% (
|
||||||
|
len(elts_communs),
|
||||||
|
len(elts_only_A),
|
||||||
|
len(elts_only_B),
|
||||||
|
)
|
||||||
)
|
)
|
||||||
if elts_only_A:
|
if elts_only_A:
|
||||||
L.append(
|
L.append(
|
||||||
@ -244,8 +246,7 @@ def _apo_compare_csv(context, A, B, REQUEST=None):
|
|||||||
|
|
||||||
|
|
||||||
def apo_table_compare_etud_results(context, A, B, REQUEST=None):
|
def apo_table_compare_etud_results(context, A, B, REQUEST=None):
|
||||||
"""
|
""""""
|
||||||
"""
|
|
||||||
D = compare_etuds_res(A, B)
|
D = compare_etuds_res(A, B)
|
||||||
T = GenTable(
|
T = GenTable(
|
||||||
rows=D,
|
rows=D,
|
||||||
|
@ -112,8 +112,7 @@ APO_NEWLINE = "\r\n"
|
|||||||
|
|
||||||
|
|
||||||
def code_scodoc_to_apo(code):
|
def code_scodoc_to_apo(code):
|
||||||
"""Conversion code jury ScoDoc en code Apogée
|
"""Conversion code jury ScoDoc en code Apogée"""
|
||||||
"""
|
|
||||||
return {
|
return {
|
||||||
ATT: "AJAC",
|
ATT: "AJAC",
|
||||||
ATB: "AJAC",
|
ATB: "AJAC",
|
||||||
@ -159,7 +158,7 @@ def fix_data_encoding(
|
|||||||
text, default_source_encoding=APO_INPUT_ENCODING, dest_encoding=APO_INPUT_ENCODING
|
text, default_source_encoding=APO_INPUT_ENCODING, dest_encoding=APO_INPUT_ENCODING
|
||||||
):
|
):
|
||||||
"""Try to ensure that text is using dest_encoding
|
"""Try to ensure that text is using dest_encoding
|
||||||
returns converted text, and a message describing the conversion.
|
returns converted text, and a message describing the conversion.
|
||||||
"""
|
"""
|
||||||
message = ""
|
message = ""
|
||||||
detected_encoding = guess_data_encoding(text)
|
detected_encoding = guess_data_encoding(text)
|
||||||
@ -241,8 +240,7 @@ VOID_APO_RES = dict(N="", B="", J="", R="", M="")
|
|||||||
|
|
||||||
|
|
||||||
class ApoEtud(dict):
|
class ApoEtud(dict):
|
||||||
"""Etudiant Apogee:
|
"""Etudiant Apogee:"""
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
@ -361,7 +359,7 @@ class ApoEtud(dict):
|
|||||||
Autres éléments: résultats du semestre ou de l'année scolaire:
|
Autres éléments: résultats du semestre ou de l'année scolaire:
|
||||||
=> VRTW1: code additionnel au semestre ("code élement semestre", elt_sem_apo)
|
=> VRTW1: code additionnel au semestre ("code élement semestre", elt_sem_apo)
|
||||||
=> VRT1A: le même que le VET: ("code élement annuel", elt_annee_apo)
|
=> VRT1A: le même que le VET: ("code élement annuel", elt_annee_apo)
|
||||||
Attention, si le semestre couvre plusieurs étapes, indiquer les codes des éléments,
|
Attention, si le semestre couvre plusieurs étapes, indiquer les codes des éléments,
|
||||||
séparés par des virgules.
|
séparés par des virgules.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -369,7 +367,7 @@ class ApoEtud(dict):
|
|||||||
sem (dict): semestre dans lequel on cherche l'élément
|
sem (dict): semestre dans lequel on cherche l'élément
|
||||||
cur_sem (dict): semestre "courant" pour résultats annuels (VET)
|
cur_sem (dict): semestre "courant" pour résultats annuels (VET)
|
||||||
autre_sem (dict): autre semestre utilisé pour calculé les résultats annuels (VET)
|
autre_sem (dict): autre semestre utilisé pour calculé les résultats annuels (VET)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dict: with N, B, J, R keys, ou None si elt non trouvé
|
dict: with N, B, J, R keys, ou None si elt non trouvé
|
||||||
"""
|
"""
|
||||||
@ -701,8 +699,7 @@ class ApoData:
|
|||||||
self.periode = periode
|
self.periode = periode
|
||||||
|
|
||||||
def setup(self, context):
|
def setup(self, context):
|
||||||
"""Recherche semestres ScoDoc concernés
|
"""Recherche semestres ScoDoc concernés"""
|
||||||
"""
|
|
||||||
self.context = context
|
self.context = context
|
||||||
self.sems_etape = comp_apo_sems(context, self.etape_apogee, self.annee_scolaire)
|
self.sems_etape = comp_apo_sems(context, self.etape_apogee, self.annee_scolaire)
|
||||||
self.etape_formsemestre_ids = {s["formsemestre_id"] for s in self.sems_etape}
|
self.etape_formsemestre_ids = {s["formsemestre_id"] for s in self.sems_etape}
|
||||||
@ -803,7 +800,7 @@ class ApoData:
|
|||||||
Clé: id apogée, eg 'V1RT', 'V1GE2201', ...
|
Clé: id apogée, eg 'V1RT', 'V1GE2201', ...
|
||||||
Valeur: ApoElt, avec les attributs code, type_objet
|
Valeur: ApoElt, avec les attributs code, type_objet
|
||||||
|
|
||||||
Si les id Apogée ne sont pas uniques (ce n'est pas garanti), garde le premier
|
Si les id Apogée ne sont pas uniques (ce n'est pas garanti), garde le premier
|
||||||
"""
|
"""
|
||||||
elts = collections.OrderedDict()
|
elts = collections.OrderedDict()
|
||||||
for col_id in sorted(cols.keys(), reverse=True):
|
for col_id in sorted(cols.keys(), reverse=True):
|
||||||
@ -849,8 +846,7 @@ class ApoData:
|
|||||||
return L
|
return L
|
||||||
|
|
||||||
def get_etape_apogee(self):
|
def get_etape_apogee(self):
|
||||||
"""Le code etape: 'V1RT', donné par le code de l'élément VET
|
"""Le code etape: 'V1RT', donné par le code de l'élément VET"""
|
||||||
"""
|
|
||||||
for elt in self.apo_elts.values():
|
for elt in self.apo_elts.values():
|
||||||
if elt.type_objet == "VET":
|
if elt.type_objet == "VET":
|
||||||
return elt.code
|
return elt.code
|
||||||
@ -893,8 +889,7 @@ class ApoData:
|
|||||||
f.write(self.column_titles)
|
f.write(self.column_titles)
|
||||||
|
|
||||||
def write_etuds(self, f):
|
def write_etuds(self, f):
|
||||||
"""write apo CSV etuds on f
|
"""write apo CSV etuds on f"""
|
||||||
"""
|
|
||||||
for e in self.etuds:
|
for e in self.etuds:
|
||||||
fs = [] # e['nip'], e['nom'], e['prenom'], e['naissance'] ]
|
fs = [] # e['nip'], e['nom'], e['prenom'], e['naissance'] ]
|
||||||
for col_id in self.col_ids:
|
for col_id in self.col_ids:
|
||||||
@ -983,8 +978,7 @@ class ApoData:
|
|||||||
return codes_by_sem
|
return codes_by_sem
|
||||||
|
|
||||||
def build_cr_table(self):
|
def build_cr_table(self):
|
||||||
"""Table compte rendu des décisions
|
"""Table compte rendu des décisions"""
|
||||||
"""
|
|
||||||
CR = [] # tableau compte rendu des decisions
|
CR = [] # tableau compte rendu des decisions
|
||||||
for e in self.etuds:
|
for e in self.etuds:
|
||||||
cr = {
|
cr = {
|
||||||
@ -1015,14 +1009,14 @@ class ApoData:
|
|||||||
|
|
||||||
|
|
||||||
def _apo_read_cols(f):
|
def _apo_read_cols(f):
|
||||||
"""Lecture colonnes apo :
|
"""Lecture colonnes apo :
|
||||||
Démarre après la balise XX-APO_COLONNES-XX
|
Démarre après la balise XX-APO_COLONNES-XX
|
||||||
et s'arrête après la balise APO_COL_VAL_FIN
|
et s'arrête après la balise APO_COL_VAL_FIN
|
||||||
|
|
||||||
Colonne Apogee: les champs sont données par la ligne
|
Colonne Apogee: les champs sont données par la ligne
|
||||||
apoL_a01_code de la section XX-APO_COLONNES-XX
|
apoL_a01_code de la section XX-APO_COLONNES-XX
|
||||||
col_id est apoL_c0001, apoL_c0002, ...
|
col_id est apoL_c0001, apoL_c0002, ...
|
||||||
|
|
||||||
:return: { col_id : { title : value } }
|
:return: { col_id : { title : value } }
|
||||||
Example: { 'apoL_c0001' : { 'Type Objet' : 'VET', 'Code' : 'V1IN', ... }, ... }
|
Example: { 'apoL_c0001' : { 'Type Objet' : 'VET', 'Code' : 'V1IN', ... }, ... }
|
||||||
"""
|
"""
|
||||||
@ -1116,8 +1110,7 @@ def comp_apo_sems(context, etape_apogee, annee_scolaire):
|
|||||||
|
|
||||||
|
|
||||||
def nar_etuds_table(context, apo_data, NAR_Etuds):
|
def nar_etuds_table(context, apo_data, NAR_Etuds):
|
||||||
"""Liste les NAR -> excel table
|
"""Liste les NAR -> excel table"""
|
||||||
"""
|
|
||||||
code_etape = apo_data.etape_apogee
|
code_etape = apo_data.etape_apogee
|
||||||
today = datetime.datetime.today().strftime("%d/%m/%y")
|
today = datetime.datetime.today().strftime("%d/%m/%y")
|
||||||
L = []
|
L = []
|
||||||
@ -1186,7 +1179,7 @@ def export_csv_to_apogee(
|
|||||||
export_res_rat=True,
|
export_res_rat=True,
|
||||||
REQUEST=None,
|
REQUEST=None,
|
||||||
):
|
):
|
||||||
"""Genere un fichier CSV Apogée
|
"""Genere un fichier CSV Apogée
|
||||||
à partir d'un fichier CSV Apogée vide (ou partiellement rempli)
|
à partir d'un fichier CSV Apogée vide (ou partiellement rempli)
|
||||||
et des résultats ScoDoc.
|
et des résultats ScoDoc.
|
||||||
Si dest_zip, ajoute les fichiers générés à ce zip
|
Si dest_zip, ajoute les fichiers générés à ce zip
|
||||||
|
@ -49,14 +49,12 @@ EtudsArchive = EtudsArchiver()
|
|||||||
|
|
||||||
|
|
||||||
def can_edit_etud_archive(context, authuser):
|
def can_edit_etud_archive(context, authuser):
|
||||||
"""True si l'utilisateur peut modifier les archives etudiantes
|
"""True si l'utilisateur peut modifier les archives etudiantes"""
|
||||||
"""
|
|
||||||
return authuser.has_permission(ScoEtudAddAnnotations, context)
|
return authuser.has_permission(ScoEtudAddAnnotations, context)
|
||||||
|
|
||||||
|
|
||||||
def etud_list_archives_html(context, REQUEST, etudid):
|
def etud_list_archives_html(context, REQUEST, etudid):
|
||||||
"""HTML snippet listing archives
|
"""HTML snippet listing archives"""
|
||||||
"""
|
|
||||||
can_edit = can_edit_etud_archive(context, REQUEST.AUTHENTICATED_USER)
|
can_edit = can_edit_etud_archive(context, REQUEST.AUTHENTICATED_USER)
|
||||||
L = []
|
L = []
|
||||||
for archive_id in EtudsArchive.list_obj_archives(context, etudid):
|
for archive_id in EtudsArchive.list_obj_archives(context, etudid):
|
||||||
@ -122,8 +120,7 @@ def add_archives_info_to_etud_list(context, etuds):
|
|||||||
|
|
||||||
|
|
||||||
def etud_upload_file_form(context, REQUEST, etudid):
|
def etud_upload_file_form(context, REQUEST, etudid):
|
||||||
"""Page with a form to choose and upload a file, with a description.
|
"""Page with a form to choose and upload a file, with a description."""
|
||||||
"""
|
|
||||||
# check permission
|
# check permission
|
||||||
if not can_edit_etud_archive(context, REQUEST.AUTHENTICATED_USER):
|
if not can_edit_etud_archive(context, REQUEST.AUTHENTICATED_USER):
|
||||||
raise AccessDenied(
|
raise AccessDenied(
|
||||||
@ -178,8 +175,7 @@ def etud_upload_file_form(context, REQUEST, etudid):
|
|||||||
def _store_etud_file_to_new_archive(
|
def _store_etud_file_to_new_archive(
|
||||||
context, REQUEST, etudid, data, filename, description=""
|
context, REQUEST, etudid, data, filename, description=""
|
||||||
):
|
):
|
||||||
"""Store data to new archive.
|
"""Store data to new archive."""
|
||||||
"""
|
|
||||||
filesize = len(data)
|
filesize = len(data)
|
||||||
if filesize < 10 or filesize > CONFIG.ETUD_MAX_FILE_SIZE:
|
if filesize < 10 or filesize > CONFIG.ETUD_MAX_FILE_SIZE:
|
||||||
return 0, "Fichier image de taille invalide ! (%d)" % filesize
|
return 0, "Fichier image de taille invalide ! (%d)" % filesize
|
||||||
@ -188,8 +184,7 @@ def _store_etud_file_to_new_archive(
|
|||||||
|
|
||||||
|
|
||||||
def etud_delete_archive(context, REQUEST, etudid, archive_name, dialog_confirmed=False):
|
def etud_delete_archive(context, REQUEST, etudid, archive_name, dialog_confirmed=False):
|
||||||
"""Delete an archive
|
"""Delete an archive"""
|
||||||
"""
|
|
||||||
# check permission
|
# check permission
|
||||||
if not can_edit_etud_archive(context, REQUEST.AUTHENTICATED_USER):
|
if not can_edit_etud_archive(context, REQUEST.AUTHENTICATED_USER):
|
||||||
raise AccessDenied(
|
raise AccessDenied(
|
||||||
@ -218,8 +213,7 @@ def etud_delete_archive(context, REQUEST, etudid, archive_name, dialog_confirmed
|
|||||||
|
|
||||||
|
|
||||||
def etud_get_archived_file(context, REQUEST, etudid, archive_name, filename):
|
def etud_get_archived_file(context, REQUEST, etudid, archive_name, filename):
|
||||||
"""Send file to client.
|
"""Send file to client."""
|
||||||
"""
|
|
||||||
return EtudsArchive.get_archived_file(
|
return EtudsArchive.get_archived_file(
|
||||||
context, REQUEST, etudid, archive_name, filename
|
context, REQUEST, etudid, archive_name, filename
|
||||||
)
|
)
|
||||||
@ -227,8 +221,7 @@ def etud_get_archived_file(context, REQUEST, etudid, archive_name, filename):
|
|||||||
|
|
||||||
# --- Upload d'un ensemble de fichiers (pour un groupe d'étudiants)
|
# --- Upload d'un ensemble de fichiers (pour un groupe d'étudiants)
|
||||||
def etudarchive_generate_excel_sample(context, group_id=None, REQUEST=None):
|
def etudarchive_generate_excel_sample(context, group_id=None, REQUEST=None):
|
||||||
"""Feuille excel pour import fichiers etudiants (utilisé pour admissions)
|
"""Feuille excel pour import fichiers etudiants (utilisé pour admissions)"""
|
||||||
"""
|
|
||||||
fmt = ImportScolars.sco_import_format()
|
fmt = ImportScolars.sco_import_format()
|
||||||
data = ImportScolars.sco_import_generate_excel_sample(
|
data = ImportScolars.sco_import_generate_excel_sample(
|
||||||
fmt,
|
fmt,
|
||||||
@ -249,8 +242,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(
|
context.sco_header(
|
||||||
REQUEST, page_title="Import de fichiers associés aux étudiants"
|
REQUEST, page_title="Import de fichiers associés aux étudiants"
|
||||||
|
@ -162,4 +162,4 @@ class Baccalaureat:
|
|||||||
return self.type() == "G"
|
return self.type() == "G"
|
||||||
|
|
||||||
def is_techno(self):
|
def is_techno(self):
|
||||||
return selt.type() == "T"
|
return self.type() == "T"
|
||||||
|
@ -80,8 +80,7 @@ class BulletinGeneratorLegacy(sco_bulletins_generator.BulletinGenerator):
|
|||||||
return [self.buildTableObject(P, pdfTableStyle, colWidths)]
|
return [self.buildTableObject(P, pdfTableStyle, colWidths)]
|
||||||
|
|
||||||
def bul_table_html(self):
|
def bul_table_html(self):
|
||||||
"""Génère la table centrale du bulletin de notes: chaine HTML
|
"""Génère la table centrale du bulletin de notes: chaine HTML"""
|
||||||
"""
|
|
||||||
format = "html"
|
format = "html"
|
||||||
I = self.infos
|
I = self.infos
|
||||||
authuser = self.authuser
|
authuser = self.authuser
|
||||||
@ -130,13 +129,10 @@ class BulletinGeneratorLegacy(sco_bulletins_generator.BulletinGenerator):
|
|||||||
continue # saute les modules où on n'est pas inscrit
|
continue # saute les modules où on n'est pas inscrit
|
||||||
H.append('<tr class="notes_bulletin_row_mod%s">' % rowstyle)
|
H.append('<tr class="notes_bulletin_row_mod%s">' % rowstyle)
|
||||||
if context.get_preference("bul_show_minmax_mod", formsemestre_id):
|
if context.get_preference("bul_show_minmax_mod", formsemestre_id):
|
||||||
rang_minmax = (
|
rang_minmax = '%s <span class="bul_minmax" title="[min, max] UE">[%s, %s]</span>' % (
|
||||||
'%s <span class="bul_minmax" title="[min, max] UE">[%s, %s]</span>'
|
mod["mod_rang_txt"],
|
||||||
% (
|
fmt_note(mod["stats"]["min"]),
|
||||||
mod["mod_rang_txt"],
|
fmt_note(mod["stats"]["max"]),
|
||||||
fmt_note(mod["stats"]["min"]),
|
|
||||||
fmt_note(mod["stats"]["max"]),
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
rang_minmax = mod["mod_rang_txt"] # vide si pas option rang
|
rang_minmax = mod["mod_rang_txt"] # vide si pas option rang
|
||||||
@ -386,8 +382,7 @@ sco_bulletins_generator.register_bulletin_class(BulletinGeneratorLegacy)
|
|||||||
|
|
||||||
|
|
||||||
class BulTableStyle:
|
class BulTableStyle:
|
||||||
"""Construction du style de tables reportlab platypus pour les bulletins "classiques"
|
"""Construction du style de tables reportlab platypus pour les bulletins "classiques" """
|
||||||
"""
|
|
||||||
|
|
||||||
LINEWIDTH = 0.5
|
LINEWIDTH = 0.5
|
||||||
LINECOLOR = Color(0, 0, 0)
|
LINECOLOR = Color(0, 0, 0)
|
||||||
|
@ -57,8 +57,7 @@ import os
|
|||||||
|
|
||||||
|
|
||||||
def form_change_bul_sig(context, side, formsemestre_id=None, REQUEST=None):
|
def form_change_bul_sig(context, side, formsemestre_id=None, REQUEST=None):
|
||||||
"""Change pdf signature
|
"""Change pdf signature"""
|
||||||
"""
|
|
||||||
filename = _get_sig_existing_filename(
|
filename = _get_sig_existing_filename(
|
||||||
context, side, formsemestre_id=formsemestre_id
|
context, side, formsemestre_id=formsemestre_id
|
||||||
)
|
)
|
||||||
|
@ -305,5 +305,4 @@ sco_bulletins_generator.register_bulletin_class(BulletinGeneratorUCAC)
|
|||||||
|
|
||||||
|
|
||||||
def bulletin_table_ucac(context, I, version=None):
|
def bulletin_table_ucac(context, I, version=None):
|
||||||
"""
|
""""""
|
||||||
"""
|
|
||||||
|
@ -35,6 +35,7 @@ import thread, time
|
|||||||
# Cache data
|
# Cache data
|
||||||
class simpleCache:
|
class simpleCache:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
self.cache = {}
|
||||||
self.inval_cache() # >
|
self.inval_cache() # >
|
||||||
|
|
||||||
def inval_cache(self, key=None): # >
|
def inval_cache(self, key=None): # >
|
||||||
@ -56,7 +57,7 @@ class simpleCache:
|
|||||||
class expiringCache(simpleCache):
|
class expiringCache(simpleCache):
|
||||||
"""A simple cache wich cache data for a most "duration" seconds.
|
"""A simple cache wich cache data for a most "duration" seconds.
|
||||||
|
|
||||||
This is used for users (which may be updated from external
|
This is used for users (which may be updated from external
|
||||||
information systems)
|
information systems)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -64,8 +64,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 = [context.sco_header(REQUEST, page_title="Assistance technique")]
|
||||||
# get currect (dept) DB name:
|
# get currect (dept) DB name:
|
||||||
cursor = SimpleQuery(context, "SELECT current_database()", {})
|
cursor = SimpleQuery(context, "SELECT current_database()", {})
|
||||||
@ -150,8 +149,7 @@ def _duplicate_db(db_name, ano_db_name):
|
|||||||
|
|
||||||
|
|
||||||
def _anonymize_db(ano_db_name):
|
def _anonymize_db(ano_db_name):
|
||||||
"""Anonymize a departement database
|
"""Anonymize a departement database"""
|
||||||
"""
|
|
||||||
cmd = os.path.join(SCO_CONFIG_DIR, "anonymize_db.py")
|
cmd = os.path.join(SCO_CONFIG_DIR, "anonymize_db.py")
|
||||||
log("_anonymize_db: {}".format(cmd))
|
log("_anonymize_db: {}".format(cmd))
|
||||||
try:
|
try:
|
||||||
@ -171,8 +169,7 @@ def _get_scodoc_serial(context):
|
|||||||
|
|
||||||
|
|
||||||
def _send_db(context, REQUEST, ano_db_name):
|
def _send_db(context, REQUEST, ano_db_name):
|
||||||
"""Dump this (anonymized) database and send it to tech support
|
"""Dump this (anonymized) database and send it to tech support"""
|
||||||
"""
|
|
||||||
log("dumping anonymized database {}".format(ano_db_name))
|
log("dumping anonymized database {}".format(ano_db_name))
|
||||||
try:
|
try:
|
||||||
data = subprocess.check_output("pg_dump {} | gzip".format(ano_db_name), shell=1)
|
data = subprocess.check_output("pg_dump {} | gzip".format(ano_db_name), shell=1)
|
||||||
|
@ -37,8 +37,7 @@ import sco_formsemestre
|
|||||||
|
|
||||||
|
|
||||||
def formation_delete(context, formation_id=None, dialog_confirmed=False, REQUEST=None):
|
def formation_delete(context, formation_id=None, dialog_confirmed=False, REQUEST=None):
|
||||||
"""Delete a formation
|
"""Delete a formation"""
|
||||||
"""
|
|
||||||
F = context.formation_list(args={"formation_id": formation_id})
|
F = context.formation_list(args={"formation_id": formation_id})
|
||||||
if not F:
|
if not F:
|
||||||
raise ScoValueError("formation inexistante !")
|
raise ScoValueError("formation inexistante !")
|
||||||
@ -89,14 +88,12 @@ def formation_delete(context, formation_id=None, dialog_confirmed=False, REQUEST
|
|||||||
|
|
||||||
|
|
||||||
def formation_create(context, REQUEST=None):
|
def formation_create(context, REQUEST=None):
|
||||||
"""Creation d'une formation
|
"""Creation d'une formation"""
|
||||||
"""
|
|
||||||
return formation_edit(context, create=True, REQUEST=REQUEST)
|
return formation_edit(context, create=True, REQUEST=REQUEST)
|
||||||
|
|
||||||
|
|
||||||
def formation_edit(context, formation_id=None, create=False, REQUEST=None):
|
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"),
|
context.sco_header(REQUEST, page_title="Création d'une formation"),
|
||||||
|
@ -36,8 +36,7 @@ import sco_formsemestre
|
|||||||
|
|
||||||
|
|
||||||
def matiere_create(context, ue_id=None, REQUEST=None):
|
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"),
|
context.sco_header(REQUEST, page_title="Création d'une matière"),
|
||||||
|
@ -55,8 +55,7 @@ saisir et modifier les notes de ce module.
|
|||||||
|
|
||||||
|
|
||||||
def module_create(context, matiere_id=None, REQUEST=None):
|
def module_create(context, matiere_id=None, REQUEST=None):
|
||||||
"""Creation d'un module
|
"""Creation d'un module"""
|
||||||
"""
|
|
||||||
if not matiere_id:
|
if not matiere_id:
|
||||||
raise ScoValueError("invalid matiere !")
|
raise ScoValueError("invalid matiere !")
|
||||||
M = context.do_matiere_list(args={"matiere_id": matiere_id})[0]
|
M = context.do_matiere_list(args={"matiere_id": matiere_id})[0]
|
||||||
@ -436,8 +435,7 @@ def module_list(context, formation_id, REQUEST=None):
|
|||||||
|
|
||||||
|
|
||||||
def formation_add_malus_modules(context, formation_id, titre=None, REQUEST=None):
|
def formation_add_malus_modules(context, formation_id, titre=None, REQUEST=None):
|
||||||
"""Création d'un module de "malus" dans chaque UE d'une formation
|
"""Création d'un module de "malus" dans chaque UE d'une formation"""
|
||||||
"""
|
|
||||||
ue_list = context.do_ue_list(args={"formation_id": formation_id})
|
ue_list = context.do_ue_list(args={"formation_id": formation_id})
|
||||||
|
|
||||||
for ue in ue_list:
|
for ue in ue_list:
|
||||||
@ -457,8 +455,7 @@ def formation_add_malus_modules(context, formation_id, titre=None, REQUEST=None)
|
|||||||
|
|
||||||
|
|
||||||
def ue_add_malus_module(context, ue_id, titre=None, code=None, REQUEST=None):
|
def ue_add_malus_module(context, ue_id, titre=None, code=None, REQUEST=None):
|
||||||
"""Add a malus module in this ue
|
"""Add a malus module in this ue"""
|
||||||
"""
|
|
||||||
ue = context.do_ue_list(args={"ue_id": ue_id})[0]
|
ue = context.do_ue_list(args={"ue_id": ue_id})[0]
|
||||||
|
|
||||||
if titre is None:
|
if titre is None:
|
||||||
|
@ -41,14 +41,12 @@ import sco_tag_module
|
|||||||
|
|
||||||
|
|
||||||
def ue_create(context, formation_id=None, REQUEST=None):
|
def ue_create(context, formation_id=None, REQUEST=None):
|
||||||
"""Creation d'une UE
|
"""Creation d'une UE"""
|
||||||
"""
|
|
||||||
return ue_edit(context, create=True, formation_id=formation_id, REQUEST=REQUEST)
|
return ue_edit(context, create=True, formation_id=formation_id, REQUEST=REQUEST)
|
||||||
|
|
||||||
|
|
||||||
def ue_edit(context, ue_id=None, create=False, formation_id=None, REQUEST=None):
|
def ue_edit(context, ue_id=None, create=False, formation_id=None, REQUEST=None):
|
||||||
"""Modification ou creation d'une UE
|
"""Modification ou creation d'une UE"""
|
||||||
"""
|
|
||||||
create = int(create)
|
create = int(create)
|
||||||
if not create:
|
if not create:
|
||||||
U = context.do_ue_list(args={"ue_id": ue_id})
|
U = context.do_ue_list(args={"ue_id": ue_id})
|
||||||
@ -227,7 +225,7 @@ def ue_edit(context, ue_id=None, create=False, formation_id=None, REQUEST=None):
|
|||||||
|
|
||||||
def _add_ue_semestre_id(context, ue_list):
|
def _add_ue_semestre_id(context, ue_list):
|
||||||
"""ajoute semestre_id dans les ue, en regardant le premier module de chacune.
|
"""ajoute semestre_id dans les ue, en regardant le premier module de chacune.
|
||||||
Les UE sans modules se voient attribuer le numero UE_SEM_DEFAULT (1000000),
|
Les UE sans modules se voient attribuer le numero UE_SEM_DEFAULT (1000000),
|
||||||
qui les place à la fin de la liste.
|
qui les place à la fin de la liste.
|
||||||
"""
|
"""
|
||||||
for ue in ue_list:
|
for ue in ue_list:
|
||||||
@ -281,7 +279,7 @@ def ue_delete(
|
|||||||
|
|
||||||
|
|
||||||
def ue_list(context, formation_id=None, msg="", REQUEST=None):
|
def ue_list(context, formation_id=None, msg="", REQUEST=None):
|
||||||
"""Liste des matières et modules d'une formation, avec liens pour
|
"""Liste des matières et modules d'une formation, avec liens pour
|
||||||
editer (si non verrouillée).
|
editer (si non verrouillée).
|
||||||
"""
|
"""
|
||||||
authuser = REQUEST.AUTHENTICATED_USER
|
authuser = REQUEST.AUTHENTICATED_USER
|
||||||
@ -781,8 +779,7 @@ def edit_ue_set_code_apogee(context, id=None, value=None, REQUEST=None):
|
|||||||
|
|
||||||
# ---- 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):
|
||||||
"""
|
""""""
|
||||||
"""
|
|
||||||
F = context.formation_list(args={"formation_id": formation_id})
|
F = context.formation_list(args={"formation_id": formation_id})
|
||||||
if not F:
|
if not F:
|
||||||
raise ScoValueError("invalid formation_id")
|
raise ScoValueError("invalid formation_id")
|
||||||
|
@ -67,8 +67,7 @@ def formsemestre_get_ics_url(context, sem):
|
|||||||
|
|
||||||
|
|
||||||
def formsemestre_load_ics(context, sem):
|
def formsemestre_load_ics(context, sem):
|
||||||
"""Load ics data, from our cache or, when necessary, from external provider
|
"""Load ics data, from our cache or, when necessary, from external provider"""
|
||||||
"""
|
|
||||||
# TODO: cacher le résultat
|
# TODO: cacher le résultat
|
||||||
ics_url = formsemestre_get_ics_url(context, sem)
|
ics_url = formsemestre_get_ics_url(context, sem)
|
||||||
if not ics_url:
|
if not ics_url:
|
||||||
@ -86,15 +85,13 @@ def formsemestre_load_ics(context, sem):
|
|||||||
|
|
||||||
|
|
||||||
def formsemestre_edt_groups_used(context, sem):
|
def formsemestre_edt_groups_used(context, sem):
|
||||||
"""L'ensemble des groupes EDT utilisés dans l'emplois du temps publié
|
"""L'ensemble des groupes EDT utilisés dans l'emplois du temps publié"""
|
||||||
"""
|
|
||||||
cal = formsemestre_load_ics(context, sem)
|
cal = formsemestre_load_ics(context, sem)
|
||||||
return {e["X-GROUP-ID"].decode("utf8") for e in events}
|
return {e["X-GROUP-ID"].decode("utf8") for e in events}
|
||||||
|
|
||||||
|
|
||||||
def get_edt_transcodage_groups(context, formsemestre_id):
|
def get_edt_transcodage_groups(context, formsemestre_id):
|
||||||
""" -> { nom_groupe_edt : nom_groupe_scodoc }
|
"""-> { nom_groupe_edt : nom_groupe_scodoc }"""
|
||||||
"""
|
|
||||||
# TODO: valider ces données au moment où on enregistre les préférences
|
# TODO: valider ces données au moment où on enregistre les préférences
|
||||||
edt2sco = {}
|
edt2sco = {}
|
||||||
sco2edt = {}
|
sco2edt = {}
|
||||||
@ -161,8 +158,7 @@ for e in events:
|
|||||||
|
|
||||||
|
|
||||||
def experimental_calendar(context, group_id=None, formsemestre_id=None, REQUEST=None):
|
def experimental_calendar(context, group_id=None, formsemestre_id=None, REQUEST=None):
|
||||||
"""experimental page
|
"""experimental page"""
|
||||||
"""
|
|
||||||
return "\n".join(
|
return "\n".join(
|
||||||
[
|
[
|
||||||
context.sco_header(
|
context.sco_header(
|
||||||
|
@ -190,8 +190,7 @@ def apo_csv_list_stored_etapes(context, annee_scolaire, sem_id=None, etapes=None
|
|||||||
|
|
||||||
|
|
||||||
def apo_csv_delete(context, archive_id):
|
def apo_csv_delete(context, archive_id):
|
||||||
"""Delete archived CSV
|
"""Delete archived CSV"""
|
||||||
"""
|
|
||||||
ApoCSVArchive.delete_archive(archive_id)
|
ApoCSVArchive.delete_archive(archive_id)
|
||||||
|
|
||||||
|
|
||||||
@ -224,19 +223,18 @@ def apo_csv_get(context, etape_apo="", annee_scolaire="", sem_id=""):
|
|||||||
|
|
||||||
|
|
||||||
def apo_get_sem_etapes(context, sem):
|
def apo_get_sem_etapes(context, sem):
|
||||||
"""Etapes de ce semestre: pour l'instant, celles déclarées
|
"""Etapes de ce semestre: pour l'instant, celles déclarées
|
||||||
Dans une future version, on pourrait aussi utiliser les étapes
|
Dans une future version, on pourrait aussi utiliser les étapes
|
||||||
d'inscription des étudiants, recupérées via le portail,
|
d'inscription des étudiants, recupérées via le portail,
|
||||||
voir check_paiement_etuds().
|
voir check_paiement_etuds().
|
||||||
|
|
||||||
:return: list of etape_apo (ApoEtapeVDI instances)
|
:return: list of etape_apo (ApoEtapeVDI instances)
|
||||||
"""
|
"""
|
||||||
return sem["etapes"]
|
return sem["etapes"]
|
||||||
|
|
||||||
|
|
||||||
def apo_csv_check_etape(context, semset, set_nips, etape_apo):
|
def apo_csv_check_etape(context, semset, set_nips, etape_apo):
|
||||||
"""Check etape vs set of sems
|
"""Check etape vs set of sems"""
|
||||||
"""
|
|
||||||
# Etudiants dans la maquette CSV:
|
# Etudiants dans la maquette CSV:
|
||||||
csv_data = apo_csv_get(
|
csv_data = apo_csv_get(
|
||||||
context, etape_apo, semset["annee_scolaire"], semset["sem_id"]
|
context, etape_apo, semset["annee_scolaire"], semset["sem_id"]
|
||||||
@ -254,7 +252,10 @@ def apo_csv_check_etape(context, semset, set_nips, etape_apo):
|
|||||||
|
|
||||||
return nips_ok, apo_nips, nips_no_apo, nips_no_sco, maq_elems, sem_elems
|
return nips_ok, apo_nips, nips_no_apo, nips_no_sco, maq_elems, sem_elems
|
||||||
|
|
||||||
def apo_csv_semset_check(context, semset, allow_missing_apo=False, allow_missing_csv=False): # was apo_csv_check
|
|
||||||
|
def apo_csv_semset_check(
|
||||||
|
context, semset, allow_missing_apo=False, allow_missing_csv=False
|
||||||
|
): # was apo_csv_check
|
||||||
"""
|
"""
|
||||||
check students in stored maqs vs students in semset
|
check students in stored maqs vs students in semset
|
||||||
Cas à détecter:
|
Cas à détecter:
|
||||||
|
@ -58,9 +58,7 @@ def apo_semset_maq_status(
|
|||||||
block_export_res_sdj=True,
|
block_export_res_sdj=True,
|
||||||
REQUEST=None,
|
REQUEST=None,
|
||||||
):
|
):
|
||||||
"""Page statut / tableau de bord
|
"""Page statut / tableau de bord"""
|
||||||
|
|
||||||
"""
|
|
||||||
if not semset_id:
|
if not semset_id:
|
||||||
raise ValueError("invalid null semset_id")
|
raise ValueError("invalid null semset_id")
|
||||||
semset = sco_semset.SemSet(context, semset_id=semset_id)
|
semset = sco_semset.SemSet(context, semset_id=semset_id)
|
||||||
@ -91,7 +89,9 @@ def apo_semset_maq_status(
|
|||||||
apo_dups,
|
apo_dups,
|
||||||
maq_elems,
|
maq_elems,
|
||||||
sem_elems,
|
sem_elems,
|
||||||
) = sco_etape_apogee.apo_csv_semset_check(context, semset, allow_missing_apo, allow_missing_csv)
|
) = sco_etape_apogee.apo_csv_semset_check(
|
||||||
|
context, semset, allow_missing_apo, allow_missing_csv
|
||||||
|
)
|
||||||
|
|
||||||
if not allow_missing_decisions:
|
if not allow_missing_decisions:
|
||||||
ok_for_export &= semset["jury_ok"]
|
ok_for_export &= semset["jury_ok"]
|
||||||
@ -265,9 +265,7 @@ def apo_semset_maq_status(
|
|||||||
)
|
)
|
||||||
if allow_missing_csv:
|
if allow_missing_csv:
|
||||||
H.append("checked")
|
H.append("checked")
|
||||||
H.append(
|
H.append(""" >autoriser export même si étapes sans maquettes</input></div>""")
|
||||||
""" >autoriser export même si étapes sans maquettes</input></div>"""
|
|
||||||
)
|
|
||||||
H.append("""</form>""")
|
H.append("""</form>""")
|
||||||
|
|
||||||
if semset and ok_for_export:
|
if semset and ok_for_export:
|
||||||
@ -295,7 +293,9 @@ def apo_semset_maq_status(
|
|||||||
H.append(
|
H.append(
|
||||||
"""<div><label><input type="checkbox" name="block_export_res_etape" value="1" %s %s>%s</input></label></div>"""
|
"""<div><label><input type="checkbox" name="block_export_res_etape" value="1" %s %s>%s</input></label></div>"""
|
||||||
% checked(
|
% checked(
|
||||||
block_export_res_etape, "export_res_etape", "résultat de l'étape (VET), sauf si diplôme"
|
block_export_res_etape,
|
||||||
|
"export_res_etape",
|
||||||
|
"résultat de l'étape (VET), sauf si diplôme",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
H.append(
|
H.append(
|
||||||
@ -424,8 +424,7 @@ def apo_semset_maq_status(
|
|||||||
|
|
||||||
|
|
||||||
def table_apo_csv_list(context, semset, REQUEST=None):
|
def table_apo_csv_list(context, semset, REQUEST=None):
|
||||||
"""Table des archives (triée par date d'archivage)
|
"""Table des archives (triée par date d'archivage)"""
|
||||||
"""
|
|
||||||
annee_scolaire = semset["annee_scolaire"]
|
annee_scolaire = semset["annee_scolaire"]
|
||||||
sem_id = semset["sem_id"]
|
sem_id = semset["sem_id"]
|
||||||
|
|
||||||
@ -481,8 +480,7 @@ def table_apo_csv_list(context, semset, REQUEST=None):
|
|||||||
|
|
||||||
|
|
||||||
def view_apo_etuds(context, semset_id, title="", nips=[], format="html", REQUEST=None):
|
def view_apo_etuds(context, semset_id, title="", nips=[], format="html", REQUEST=None):
|
||||||
"""Table des étudiants Apogée par nips
|
"""Table des étudiants Apogée par nips"""
|
||||||
"""
|
|
||||||
if not semset_id:
|
if not semset_id:
|
||||||
raise ValueError("invalid null semset_id")
|
raise ValueError("invalid null semset_id")
|
||||||
semset = sco_semset.SemSet(context, semset_id=semset_id)
|
semset = sco_semset.SemSet(context, semset_id=semset_id)
|
||||||
@ -520,8 +518,7 @@ def view_apo_etuds(context, semset_id, title="", nips=[], format="html", REQUEST
|
|||||||
def view_scodoc_etuds(
|
def view_scodoc_etuds(
|
||||||
context, semset_id, title="", etudids=None, nips=None, format="html", REQUEST=None
|
context, semset_id, title="", etudids=None, nips=None, format="html", REQUEST=None
|
||||||
):
|
):
|
||||||
"""Table des étudiants ScoDoc par nips ou etudids
|
"""Table des étudiants ScoDoc par nips ou etudids"""
|
||||||
"""
|
|
||||||
if etudids is not None:
|
if etudids is not None:
|
||||||
if type(etudids) != type([]):
|
if type(etudids) != type([]):
|
||||||
etudids = [etudids]
|
etudids = [etudids]
|
||||||
@ -636,8 +633,7 @@ def view_apo_csv_store(
|
|||||||
|
|
||||||
|
|
||||||
def view_apo_csv_download_and_store(context, etape_apo="", semset_id="", REQUEST=None):
|
def view_apo_csv_download_and_store(context, etape_apo="", semset_id="", REQUEST=None):
|
||||||
"""Download maquette and store it
|
"""Download maquette and store it"""
|
||||||
"""
|
|
||||||
if not semset_id:
|
if not semset_id:
|
||||||
raise ValueError("invalid null semset_id")
|
raise ValueError("invalid null semset_id")
|
||||||
semset = sco_semset.SemSet(context, semset_id=semset_id)
|
semset = sco_semset.SemSet(context, semset_id=semset_id)
|
||||||
@ -656,8 +652,7 @@ def view_apo_csv_download_and_store(context, etape_apo="", semset_id="", REQUEST
|
|||||||
def view_apo_csv_delete(
|
def view_apo_csv_delete(
|
||||||
context, etape_apo="", semset_id="", dialog_confirmed=False, REQUEST=None
|
context, etape_apo="", semset_id="", dialog_confirmed=False, REQUEST=None
|
||||||
):
|
):
|
||||||
"""Delete CSV file
|
"""Delete CSV file"""
|
||||||
"""
|
|
||||||
if not semset_id:
|
if not semset_id:
|
||||||
raise ValueError("invalid null semset_id")
|
raise ValueError("invalid null semset_id")
|
||||||
semset = sco_semset.SemSet(context, semset_id=semset_id)
|
semset = sco_semset.SemSet(context, semset_id=semset_id)
|
||||||
|
@ -237,8 +237,7 @@ class ScoExcelSheet:
|
|||||||
|
|
||||||
|
|
||||||
def Excel_SimpleTable(titles=[], lines=[[]], SheetName="feuille", titlesStyles=[]):
|
def Excel_SimpleTable(titles=[], lines=[[]], SheetName="feuille", titlesStyles=[]):
|
||||||
"""Export simple type 'CSV': 1ere ligne en gras, le reste tel quel
|
"""Export simple type 'CSV': 1ere ligne en gras, le reste tel quel"""
|
||||||
"""
|
|
||||||
# XXX devrait maintenant utiliser ScoExcelSheet
|
# XXX devrait maintenant utiliser ScoExcelSheet
|
||||||
wb = Workbook()
|
wb = Workbook()
|
||||||
ws0 = wb.add_sheet(SheetName.decode(SCO_ENCODING))
|
ws0 = wb.add_sheet(SheetName.decode(SCO_ENCODING))
|
||||||
|
@ -201,8 +201,7 @@ def _build_results_list(context, dpv_by_sem, etuds_infos):
|
|||||||
|
|
||||||
|
|
||||||
def get_set_formsemestre_id_dates(context, start_date, end_date):
|
def get_set_formsemestre_id_dates(context, start_date, end_date):
|
||||||
"""Ensemble des formsemestre_id entre ces dates
|
"""Ensemble des formsemestre_id entre ces dates"""
|
||||||
"""
|
|
||||||
s = SimpleDictFetch(
|
s = SimpleDictFetch(
|
||||||
context,
|
context,
|
||||||
"SELECT formsemestre_id FROM notes_formsemestre WHERE date_debut >= %(start_date)s AND date_fin <= %(end_date)s",
|
"SELECT formsemestre_id FROM notes_formsemestre WHERE date_debut >= %(start_date)s AND date_fin <= %(end_date)s",
|
||||||
@ -216,7 +215,7 @@ def scodoc_table_results(
|
|||||||
):
|
):
|
||||||
"""Page affichant la table des résultats
|
"""Page affichant la table des résultats
|
||||||
Les dates sont en dd/mm/yyyy (datepicker javascript)
|
Les dates sont en dd/mm/yyyy (datepicker javascript)
|
||||||
types_parcours est la liste des types de parcours à afficher
|
types_parcours est la liste des types de parcours à afficher
|
||||||
(liste de chaines, eg ['100', '210'] )
|
(liste de chaines, eg ['100', '210'] )
|
||||||
"""
|
"""
|
||||||
log("scodoc_table_results: start_date=%s" % (start_date,)) # XXX
|
log("scodoc_table_results: start_date=%s" % (start_date,)) # XXX
|
||||||
|
@ -216,7 +216,7 @@ def search_etud_in_dept(
|
|||||||
# Was chercheEtudsInfo()
|
# Was chercheEtudsInfo()
|
||||||
def search_etuds_infos(context, expnom=None, code_nip=None, REQUEST=None):
|
def search_etuds_infos(context, expnom=None, code_nip=None, REQUEST=None):
|
||||||
"""recherche les étudiants correspondants à expnom ou au code_nip
|
"""recherche les étudiants correspondants à expnom ou au code_nip
|
||||||
et ramene liste de mappings utilisables en DTML.
|
et ramene liste de mappings utilisables en DTML.
|
||||||
"""
|
"""
|
||||||
may_be_nip = is_valid_code_nip(expnom)
|
may_be_nip = is_valid_code_nip(expnom)
|
||||||
cnx = context.GetDBConnexion()
|
cnx = context.GetDBConnexion()
|
||||||
@ -286,8 +286,7 @@ def search_etud_by_name(context, term, REQUEST=None):
|
|||||||
|
|
||||||
|
|
||||||
def form_search_etud_in_accessible_depts(context, REQUEST):
|
def form_search_etud_in_accessible_depts(context, REQUEST):
|
||||||
"""Form recherche etudiants pour page accueil ScoDoc
|
"""Form recherche etudiants pour page accueil ScoDoc"""
|
||||||
"""
|
|
||||||
authuser = REQUEST.AUTHENTICATED_USER
|
authuser = REQUEST.AUTHENTICATED_USER
|
||||||
# present form only to authenticated users
|
# present form only to authenticated users
|
||||||
if not authuser.has_role("Authenticated"):
|
if not authuser.has_role("Authenticated"):
|
||||||
|
@ -480,7 +480,7 @@ def formsemestre_recap_parcours_table(
|
|||||||
show_details=False,
|
show_details=False,
|
||||||
):
|
):
|
||||||
"""Tableau HTML recap parcours
|
"""Tableau HTML recap parcours
|
||||||
Si with_links, ajoute liens pour modifier decisions (colonne de droite)
|
Si with_links, ajoute liens pour modifier decisions (colonne de droite)
|
||||||
sem_info = { formsemestre_id : txt } permet d'ajouter des informations associées à chaque semestre
|
sem_info = { formsemestre_id : txt } permet d'ajouter des informations associées à chaque semestre
|
||||||
with_all_columns: si faux, pas de colonne "assiduité".
|
with_all_columns: si faux, pas de colonne "assiduité".
|
||||||
"""
|
"""
|
||||||
@ -690,8 +690,7 @@ def formsemestre_recap_parcours_table(
|
|||||||
def form_decision_manuelle(
|
def form_decision_manuelle(
|
||||||
context, Se, formsemestre_id, etudid, desturl="", sortcol=None
|
context, Se, formsemestre_id, etudid, desturl="", sortcol=None
|
||||||
):
|
):
|
||||||
"""Formulaire pour saisie décision manuelle
|
"""Formulaire pour saisie décision manuelle"""
|
||||||
"""
|
|
||||||
H = [
|
H = [
|
||||||
"""
|
"""
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
@ -1033,8 +1032,7 @@ def formsemestre_fix_validation_ues(context, formsemestre_id, REQUEST=None):
|
|||||||
|
|
||||||
|
|
||||||
def formsemestre_validation_suppress_etud(context, formsemestre_id, etudid):
|
def formsemestre_validation_suppress_etud(context, formsemestre_id, etudid):
|
||||||
"""Suppression des decisions de jury pour un etudiant.
|
"""Suppression des decisions de jury pour un etudiant."""
|
||||||
"""
|
|
||||||
log("formsemestre_validation_suppress_etud( %s, %s)" % (formsemestre_id, etudid))
|
log("formsemestre_validation_suppress_etud( %s, %s)" % (formsemestre_id, etudid))
|
||||||
cnx = context.GetDBConnexion(autocommit=False)
|
cnx = context.GetDBConnexion(autocommit=False)
|
||||||
cursor = cnx.cursor(cursor_factory=ScoDocCursor)
|
cursor = cnx.cursor(cursor_factory=ScoDocCursor)
|
||||||
@ -1064,7 +1062,7 @@ def formsemestre_validation_suppress_etud(context, formsemestre_id, etudid):
|
|||||||
|
|
||||||
|
|
||||||
def formsemestre_validate_previous_ue(context, formsemestre_id, etudid, REQUEST=None):
|
def formsemestre_validate_previous_ue(context, formsemestre_id, etudid, REQUEST=None):
|
||||||
"""Form. saisie UE validée hors ScoDoc
|
"""Form. saisie UE validée hors ScoDoc
|
||||||
(pour étudiants arrivant avec un UE antérieurement validée).
|
(pour étudiants arrivant avec un UE antérieurement validée).
|
||||||
"""
|
"""
|
||||||
etud = context.getEtudInfo(etudid=etudid, filled=True)[0]
|
etud = context.getEtudInfo(etudid=etudid, filled=True)[0]
|
||||||
@ -1205,7 +1203,7 @@ def do_formsemestre_validate_previous_ue(
|
|||||||
REQUEST=None,
|
REQUEST=None,
|
||||||
):
|
):
|
||||||
"""Enregistre (ou modifie) validation d'UE (obtenue hors ScoDoc).
|
"""Enregistre (ou modifie) validation d'UE (obtenue hors ScoDoc).
|
||||||
Si le coefficient est spécifié, modifie le coefficient de
|
Si le coefficient est spécifié, modifie le coefficient de
|
||||||
cette UE (utile seulement pour les semestres extérieurs).
|
cette UE (utile seulement pour les semestres extérieurs).
|
||||||
"""
|
"""
|
||||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||||
@ -1265,8 +1263,7 @@ def _invalidate_etud_formation_caches(context, etudid, formation_id):
|
|||||||
|
|
||||||
|
|
||||||
def get_etud_ue_cap_html(context, etudid, formsemestre_id, ue_id, REQUEST=None):
|
def get_etud_ue_cap_html(context, etudid, formsemestre_id, ue_id, REQUEST=None):
|
||||||
"""Ramene bout de HTML pour pouvoir supprimer une validation de cette UE
|
"""Ramene bout de HTML pour pouvoir supprimer une validation de cette UE"""
|
||||||
"""
|
|
||||||
valids = SimpleDictFetch(
|
valids = SimpleDictFetch(
|
||||||
context,
|
context,
|
||||||
"""SELECT SFV.* FROM scolar_formsemestre_validation SFV
|
"""SELECT SFV.* FROM scolar_formsemestre_validation SFV
|
||||||
|
@ -39,8 +39,7 @@ TITLES = ("user_name", "nom", "prenom", "email", "roles", "dept")
|
|||||||
|
|
||||||
|
|
||||||
def generate_excel_sample():
|
def generate_excel_sample():
|
||||||
"""generates an excel document suitable to import users
|
"""generates an excel document suitable to import users"""
|
||||||
"""
|
|
||||||
style = sco_excel.Excel_MakeStyle(bold=True)
|
style = sco_excel.Excel_MakeStyle(bold=True)
|
||||||
titles = TITLES
|
titles = TITLES
|
||||||
titlesStyles = [style] * len(titles)
|
titlesStyles = [style] * len(titles)
|
||||||
@ -105,7 +104,7 @@ def import_users(U, auth_dept="", context=None):
|
|||||||
- créer utilisateur et mettre le mot de passe
|
- créer utilisateur et mettre le mot de passe
|
||||||
- envoyer mot de passe par mail
|
- envoyer mot de passe par mail
|
||||||
|
|
||||||
En cas d'erreur: supprimer tous les utilisateurs que l'on vient de créer.
|
En cas d'erreur: supprimer tous les utilisateurs que l'on vient de créer.
|
||||||
"""
|
"""
|
||||||
created = [] # liste de uid créés
|
created = [] # liste de uid créés
|
||||||
try:
|
try:
|
||||||
|
@ -45,8 +45,7 @@ import sco_formsemestre
|
|||||||
def formsemestre_table_etuds_lycees(
|
def formsemestre_table_etuds_lycees(
|
||||||
context, formsemestre_id, group_lycees=True, only_primo=False
|
context, formsemestre_id, group_lycees=True, only_primo=False
|
||||||
):
|
):
|
||||||
"""Récupère liste d'etudiants avec etat et decision.
|
"""Récupère liste d'etudiants avec etat et decision."""
|
||||||
"""
|
|
||||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||||
etuds = sco_report.tsp_etud_list(context, formsemestre_id, only_primo=only_primo)[0]
|
etuds = sco_report.tsp_etud_list(context, formsemestre_id, only_primo=only_primo)[0]
|
||||||
if only_primo:
|
if only_primo:
|
||||||
@ -60,8 +59,7 @@ def formsemestre_table_etuds_lycees(
|
|||||||
|
|
||||||
|
|
||||||
def scodoc_table_etuds_lycees(context, format="html", REQUEST=None):
|
def scodoc_table_etuds_lycees(context, format="html", REQUEST=None):
|
||||||
"""Table avec _tous_ les étudiants des semestres non verrouillés de _tous_ les départements.
|
"""Table avec _tous_ les étudiants des semestres non verrouillés de _tous_ les départements."""
|
||||||
"""
|
|
||||||
semdepts = sco_formsemestre.scodoc_get_all_unlocked_sems(context)
|
semdepts = sco_formsemestre.scodoc_get_all_unlocked_sems(context)
|
||||||
etuds = []
|
etuds = []
|
||||||
for (sem, deptcontext) in semdepts:
|
for (sem, deptcontext) in semdepts:
|
||||||
|
@ -41,8 +41,7 @@ import sco_codes_parcours
|
|||||||
|
|
||||||
|
|
||||||
def list_formsemestres_modalites(context, sems):
|
def list_formsemestres_modalites(context, sems):
|
||||||
"""Liste ordonnée des modalités présentes dans ces formsemestres
|
"""Liste ordonnée des modalités présentes dans ces formsemestres"""
|
||||||
"""
|
|
||||||
modalites = {}
|
modalites = {}
|
||||||
for sem in sems:
|
for sem in sems:
|
||||||
if sem["modalite"] not in modalites:
|
if sem["modalite"] not in modalites:
|
||||||
@ -86,8 +85,7 @@ _modaliteEditor = EditableTable(
|
|||||||
|
|
||||||
|
|
||||||
def do_modalite_list(context, *args, **kw):
|
def do_modalite_list(context, *args, **kw):
|
||||||
"""Liste des modalites
|
"""Liste des modalites"""
|
||||||
"""
|
|
||||||
cnx = context.GetDBConnexion()
|
cnx = context.GetDBConnexion()
|
||||||
return _modaliteEditor.list(cnx, *args, **kw)
|
return _modaliteEditor.list(cnx, *args, **kw)
|
||||||
|
|
||||||
|
@ -273,18 +273,17 @@ def ficheEtud(context, etudid=None, REQUEST=None):
|
|||||||
if not context.canSuppressAnnotation(a["id"], REQUEST):
|
if not context.canSuppressAnnotation(a["id"], REQUEST):
|
||||||
a["dellink"] = ""
|
a["dellink"] = ""
|
||||||
else:
|
else:
|
||||||
a["dellink"] = (
|
a[
|
||||||
'<td class="annodel"><a href="doSuppressAnnotation?etudid=%s&annotation_id=%s">%s</a></td>'
|
"dellink"
|
||||||
% (
|
] = '<td class="annodel"><a href="doSuppressAnnotation?etudid=%s&annotation_id=%s">%s</a></td>' % (
|
||||||
etudid,
|
etudid,
|
||||||
a["id"],
|
a["id"],
|
||||||
icontag(
|
icontag(
|
||||||
"delete_img",
|
"delete_img",
|
||||||
border="0",
|
border="0",
|
||||||
alt="suppress",
|
alt="suppress",
|
||||||
title="Supprimer cette annotation",
|
title="Supprimer cette annotation",
|
||||||
),
|
),
|
||||||
)
|
|
||||||
)
|
)
|
||||||
alist.append(
|
alist.append(
|
||||||
'<tr><td><span class="annodate">Le %(date)s par %(zope_authenticated_user)s : </span><span class="annoc">%(comment)s</span></td>%(dellink)s</tr>'
|
'<tr><td><span class="annodate">Le %(date)s par %(zope_authenticated_user)s : </span><span class="annoc">%(comment)s</span></td>%(dellink)s</tr>'
|
||||||
@ -486,8 +485,7 @@ def ficheEtud(context, etudid=None, REQUEST=None):
|
|||||||
|
|
||||||
|
|
||||||
def menus_etud(context, REQUEST=None):
|
def menus_etud(context, REQUEST=None):
|
||||||
"""Menu etudiant (operations sur l'etudiant)
|
"""Menu etudiant (operations sur l'etudiant)"""
|
||||||
"""
|
|
||||||
if not REQUEST.form.has_key("etudid"):
|
if not REQUEST.form.has_key("etudid"):
|
||||||
return ""
|
return ""
|
||||||
authuser = REQUEST.AUTHENTICATED_USER
|
authuser = REQUEST.AUTHENTICATED_USER
|
||||||
|
@ -41,7 +41,7 @@ from reportlab.platypus import Table, TableStyle, Image, KeepInFrame
|
|||||||
from reportlab.platypus.flowables import Flowable
|
from reportlab.platypus.flowables import Flowable
|
||||||
from reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate
|
from reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate
|
||||||
from reportlab.lib.styles import getSampleStyleSheet
|
from reportlab.lib.styles import getSampleStyleSheet
|
||||||
from reportlab.rl_config import defaultPageSize
|
from reportlab.rl_config import defaultPageSize # pylint: disable=no-name-in-module
|
||||||
from reportlab.lib.units import inch, cm, mm
|
from reportlab.lib.units import inch, cm, mm
|
||||||
from reportlab.lib.colors import pink, black, red, blue, green, magenta, red
|
from reportlab.lib.colors import pink, black, red, blue, green, magenta, red
|
||||||
from reportlab.lib.colors import Color
|
from reportlab.lib.colors import Color
|
||||||
|
@ -197,16 +197,18 @@ def do_placement_selectetuds(context, REQUEST):
|
|||||||
numbering = tf[2]["numbering"]
|
numbering = tf[2]["numbering"]
|
||||||
if columns in ("3", "4", "5", "6", "7", "8"):
|
if columns in ("3", "4", "5", "6", "7", "8"):
|
||||||
gs = [("group_ids%3Alist=" + urllib.quote_plus(x)) for x in group_ids]
|
gs = [("group_ids%3Alist=" + urllib.quote_plus(x)) for x in group_ids]
|
||||||
query = "evaluation_id=%s&placement_method=%s&teachers=%s&building=%s&room=%s&columns=%s&numbering=%s&" % (
|
query = (
|
||||||
evaluation_id,
|
"evaluation_id=%s&placement_method=%s&teachers=%s&building=%s&room=%s&columns=%s&numbering=%s&"
|
||||||
placement_method,
|
% (
|
||||||
teachers,
|
evaluation_id,
|
||||||
building,
|
placement_method,
|
||||||
room,
|
teachers,
|
||||||
columns,
|
building,
|
||||||
numbering,
|
room,
|
||||||
) + "&".join(
|
columns,
|
||||||
gs
|
numbering,
|
||||||
|
)
|
||||||
|
+ "&".join(gs)
|
||||||
)
|
)
|
||||||
return REQUEST.RESPONSE.redirect(REQUEST.URL1 + "/do_placement?" + query)
|
return REQUEST.RESPONSE.redirect(REQUEST.URL1 + "/do_placement?" + query)
|
||||||
else:
|
else:
|
||||||
@ -385,8 +387,7 @@ def do_placement(context, REQUEST):
|
|||||||
|
|
||||||
|
|
||||||
def placement_eval_selectetuds(context, evaluation_id, REQUEST=None):
|
def placement_eval_selectetuds(context, evaluation_id, REQUEST=None):
|
||||||
"""Dialogue placement etudiants: choix methode et localisation
|
"""Dialogue placement etudiants: choix methode et localisation"""
|
||||||
"""
|
|
||||||
evals = context.do_evaluation_list({"evaluation_id": evaluation_id})
|
evals = context.do_evaluation_list({"evaluation_id": evaluation_id})
|
||||||
if not evals:
|
if not evals:
|
||||||
raise ScoValueError("invalid evaluation_id")
|
raise ScoValueError("invalid evaluation_id")
|
||||||
|
@ -41,8 +41,7 @@ from sco_codes_parcours import code_semestre_validant, code_semestre_attente
|
|||||||
|
|
||||||
|
|
||||||
def etud_get_poursuite_info(context, sem, etud):
|
def etud_get_poursuite_info(context, sem, etud):
|
||||||
"""{ 'nom' : ..., 'semlist' : [ { 'semestre_id': , 'moy' : ... }, {}, ...] }
|
"""{ 'nom' : ..., 'semlist' : [ { 'semestre_id': , 'moy' : ... }, {}, ...] }"""
|
||||||
"""
|
|
||||||
I = {}
|
I = {}
|
||||||
I.update(etud) # copie nom, prenom, sexe, ...
|
I.update(etud) # copie nom, prenom, sexe, ...
|
||||||
|
|
||||||
@ -153,8 +152,7 @@ def _flatten_info(info):
|
|||||||
def formsemestre_poursuite_report(
|
def formsemestre_poursuite_report(
|
||||||
context, formsemestre_id, format="html", REQUEST=None
|
context, formsemestre_id, format="html", REQUEST=None
|
||||||
):
|
):
|
||||||
"""Table avec informations "poursuite"
|
"""Table avec informations "poursuite" """
|
||||||
"""
|
|
||||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||||
nt = context._getNotesCache().get_NotesTable(context, formsemestre_id)
|
nt = context._getNotesCache().get_NotesTable(context, formsemestre_id)
|
||||||
etuds = context.getEtudInfoGroupes(
|
etuds = context.getEtudInfoGroupes(
|
||||||
|
@ -270,8 +270,7 @@ def do_evaluation_upload_xls(context, REQUEST):
|
|||||||
def do_evaluation_set_missing(
|
def do_evaluation_set_missing(
|
||||||
context, evaluation_id, value, REQUEST=None, dialog_confirmed=False
|
context, evaluation_id, value, REQUEST=None, dialog_confirmed=False
|
||||||
):
|
):
|
||||||
"""Initialisation des notes manquantes
|
"""Initialisation des notes manquantes"""
|
||||||
"""
|
|
||||||
authuser = REQUEST.AUTHENTICATED_USER
|
authuser = REQUEST.AUTHENTICATED_USER
|
||||||
evaluation_id = REQUEST.form["evaluation_id"]
|
evaluation_id = REQUEST.form["evaluation_id"]
|
||||||
E = context.do_evaluation_list({"evaluation_id": evaluation_id})[0]
|
E = context.do_evaluation_list({"evaluation_id": evaluation_id})[0]
|
||||||
@ -547,9 +546,9 @@ def _notes_add(context, uid, evaluation_id, notes, comment=None, do_it=True):
|
|||||||
|
|
||||||
|
|
||||||
def saisie_notes_tableur(context, evaluation_id, group_ids=[], REQUEST=None):
|
def saisie_notes_tableur(context, evaluation_id, group_ids=[], REQUEST=None):
|
||||||
"""Saisie des notes via un fichier Excel
|
"""Saisie des notes via un fichier Excel"""
|
||||||
"""
|
|
||||||
authuser = REQUEST.AUTHENTICATED_USER
|
authuser = REQUEST.AUTHENTICATED_USER
|
||||||
|
authusername = str(authuser)
|
||||||
evals = context.do_evaluation_list({"evaluation_id": evaluation_id})
|
evals = context.do_evaluation_list({"evaluation_id": evaluation_id})
|
||||||
if not evals:
|
if not evals:
|
||||||
raise ScoValueError("invalid evaluation_id")
|
raise ScoValueError("invalid evaluation_id")
|
||||||
@ -724,8 +723,7 @@ def saisie_notes_tableur(context, evaluation_id, group_ids=[], REQUEST=None):
|
|||||||
|
|
||||||
|
|
||||||
def feuille_saisie_notes(context, evaluation_id, group_ids=[], REQUEST=None):
|
def feuille_saisie_notes(context, evaluation_id, group_ids=[], REQUEST=None):
|
||||||
"""Document Excel pour saisie notes dans l'évaluation et les groupes indiqués
|
"""Document Excel pour saisie notes dans l'évaluation et les groupes indiqués"""
|
||||||
"""
|
|
||||||
evals = context.do_evaluation_list({"evaluation_id": evaluation_id})
|
evals = context.do_evaluation_list({"evaluation_id": evaluation_id})
|
||||||
if not evals:
|
if not evals:
|
||||||
raise ScoValueError("invalid evaluation_id")
|
raise ScoValueError("invalid evaluation_id")
|
||||||
@ -825,8 +823,7 @@ def has_existing_decision(context, M, E, etudid):
|
|||||||
|
|
||||||
|
|
||||||
def saisie_notes(context, evaluation_id, group_ids=[], REQUEST=None):
|
def saisie_notes(context, evaluation_id, group_ids=[], REQUEST=None):
|
||||||
"""Formulaire saisie notes d'une évaluation pour un groupe
|
"""Formulaire saisie notes d'une évaluation pour un groupe"""
|
||||||
"""
|
|
||||||
authuser = REQUEST.AUTHENTICATED_USER
|
authuser = REQUEST.AUTHENTICATED_USER
|
||||||
authusername = str(authuser)
|
authusername = str(authuser)
|
||||||
|
|
||||||
@ -1182,8 +1179,7 @@ def _form_saisie_notes(context, E, M, group_ids, REQUEST=None):
|
|||||||
def save_note(
|
def save_note(
|
||||||
context, etudid=None, evaluation_id=None, value=None, comment="", REQUEST=None
|
context, etudid=None, evaluation_id=None, value=None, comment="", REQUEST=None
|
||||||
):
|
):
|
||||||
"""Enregistre une note (ajax)
|
"""Enregistre une note (ajax)"""
|
||||||
"""
|
|
||||||
authuser = REQUEST.AUTHENTICATED_USER
|
authuser = REQUEST.AUTHENTICATED_USER
|
||||||
log(
|
log(
|
||||||
"save_note: evaluation_id=%s etudid=%s uid=%s value=%s"
|
"save_note: evaluation_id=%s etudid=%s uid=%s value=%s"
|
||||||
|
@ -63,8 +63,7 @@ semset_delete = _semset_editor.delete
|
|||||||
|
|
||||||
class SemSet(dict):
|
class SemSet(dict):
|
||||||
def __init__(self, context, semset_id=None, title="", annee_scolaire="", sem_id=""):
|
def __init__(self, context, semset_id=None, title="", annee_scolaire="", sem_id=""):
|
||||||
"""Load and init, or, if semset_id is not specified, create
|
"""Load and init, or, if semset_id is not specified, create"""
|
||||||
"""
|
|
||||||
if not annee_scolaire and not semset_id:
|
if not annee_scolaire and not semset_id:
|
||||||
# on autorise annee_scolaire null si sem_id pour pouvoir lire les anciens semsets
|
# on autorise annee_scolaire null si sem_id pour pouvoir lire les anciens semsets
|
||||||
# mal construits...
|
# mal construits...
|
||||||
@ -201,8 +200,7 @@ class SemSet(dict):
|
|||||||
return etapes
|
return etapes
|
||||||
|
|
||||||
def list_possible_sems(self):
|
def list_possible_sems(self):
|
||||||
"""List sems that can be added to this set
|
"""List sems that can be added to this set"""
|
||||||
"""
|
|
||||||
sems = sco_formsemestre.do_formsemestre_list(self.context)
|
sems = sco_formsemestre.do_formsemestre_list(self.context)
|
||||||
# remove sems already here:
|
# remove sems already here:
|
||||||
sems = [
|
sems = [
|
||||||
@ -243,8 +241,7 @@ class SemSet(dict):
|
|||||||
self["jury_ok"] &= sem["jury_ok"]
|
self["jury_ok"] &= sem["jury_ok"]
|
||||||
|
|
||||||
def html_descr(self):
|
def html_descr(self):
|
||||||
"""Short HTML description
|
"""Short HTML description"""
|
||||||
"""
|
|
||||||
H = [
|
H = [
|
||||||
"""<span class="box_title">Ensemble de semestres %(title)s</span>""" % self
|
"""<span class="box_title">Ensemble de semestres %(title)s</span>""" % self
|
||||||
]
|
]
|
||||||
@ -354,7 +351,7 @@ def do_semset_create(context, title="", annee_scolaire=None, sem_id=None, REQUES
|
|||||||
"do_semset_create(title=%s, annee_scolaire=%s, sem_id=%s)"
|
"do_semset_create(title=%s, annee_scolaire=%s, sem_id=%s)"
|
||||||
% (title, annee_scolaire, sem_id)
|
% (title, annee_scolaire, sem_id)
|
||||||
)
|
)
|
||||||
s = SemSet(context, title=title, annee_scolaire=annee_scolaire, sem_id=sem_id)
|
SemSet(context, title=title, annee_scolaire=annee_scolaire, sem_id=sem_id)
|
||||||
return REQUEST.RESPONSE.redirect("semset_page")
|
return REQUEST.RESPONSE.redirect("semset_page")
|
||||||
|
|
||||||
|
|
||||||
@ -376,12 +373,11 @@ def do_semset_delete(context, semset_id, dialog_confirmed=False, REQUEST=None):
|
|||||||
|
|
||||||
|
|
||||||
def edit_semset_set_title(context, id=None, value=None, REQUEST=None):
|
def edit_semset_set_title(context, id=None, value=None, REQUEST=None):
|
||||||
"""Change title of semset
|
"""Change title of semset"""
|
||||||
"""
|
|
||||||
title = value.strip()
|
title = value.strip()
|
||||||
if not id:
|
if not id:
|
||||||
raise ScoValueError("empty semset_id")
|
raise ScoValueError("empty semset_id")
|
||||||
s = SemSet(context, semset_id=id)
|
SemSet(context, semset_id=id)
|
||||||
cnx = context.GetDBConnexion()
|
cnx = context.GetDBConnexion()
|
||||||
semset_edit(cnx, {"semset_id": id, "title": title})
|
semset_edit(cnx, {"semset_id": id, "title": title})
|
||||||
return title
|
return title
|
||||||
@ -393,7 +389,7 @@ def do_semset_add_sem(context, semset_id, formsemestre_id, REQUEST=None):
|
|||||||
raise ScoValueError("empty semset_id")
|
raise ScoValueError("empty semset_id")
|
||||||
s = SemSet(context, semset_id=semset_id)
|
s = SemSet(context, semset_id=semset_id)
|
||||||
# check for valid formsemestre_id
|
# check for valid formsemestre_id
|
||||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) # raise exc
|
_ = sco_formsemestre.get_formsemestre(context, formsemestre_id) # raise exc
|
||||||
|
|
||||||
s.add(formsemestre_id)
|
s.add(formsemestre_id)
|
||||||
|
|
||||||
@ -431,9 +427,10 @@ def semset_page(context, format="html", REQUEST=None):
|
|||||||
# (remplacé par n liens vers chacun des semestres)
|
# (remplacé par n liens vers chacun des semestres)
|
||||||
# s['_semtitles_str_target'] = s['_export_link_target']
|
# s['_semtitles_str_target'] = s['_export_link_target']
|
||||||
# Experimental:
|
# Experimental:
|
||||||
s["_title_td_attrs"] = (
|
s[
|
||||||
'class="inplace_edit" data-url="edit_semset_set_title" id="%s"'
|
"_title_td_attrs"
|
||||||
% (s["semset_id"])
|
] = 'class="inplace_edit" data-url="edit_semset_set_title" id="%s"' % (
|
||||||
|
s["semset_id"]
|
||||||
)
|
)
|
||||||
|
|
||||||
tab = GenTable(
|
tab = GenTable(
|
||||||
|
@ -53,8 +53,7 @@ from notes_log import log
|
|||||||
|
|
||||||
|
|
||||||
class ScoTag:
|
class ScoTag:
|
||||||
"""Generic tags for ScoDoc
|
"""Generic tags for ScoDoc"""
|
||||||
"""
|
|
||||||
|
|
||||||
# must be overloaded:
|
# must be overloaded:
|
||||||
tag_table = None # table (tag_id, title)
|
tag_table = None # table (tag_id, title)
|
||||||
@ -62,8 +61,7 @@ class ScoTag:
|
|||||||
obj_colname = None # column name for object_id in assoc_table
|
obj_colname = None # column name for object_id in assoc_table
|
||||||
|
|
||||||
def __init__(self, context, title, object_id=""):
|
def __init__(self, context, title, object_id=""):
|
||||||
"""Load tag, or create if does not exist
|
"""Load tag, or create if does not exist"""
|
||||||
"""
|
|
||||||
self.context = context
|
self.context = context
|
||||||
self.title = title.strip()
|
self.title = title.strip()
|
||||||
if not self.title:
|
if not self.title:
|
||||||
@ -153,16 +151,14 @@ class ScoTag:
|
|||||||
|
|
||||||
|
|
||||||
class ModuleTag(ScoTag):
|
class ModuleTag(ScoTag):
|
||||||
"""Tags sur les modules dans les programmes pédagogiques
|
"""Tags sur les modules dans les programmes pédagogiques"""
|
||||||
"""
|
|
||||||
|
|
||||||
tag_table = "notes_tags" # table (tag_id, title)
|
tag_table = "notes_tags" # table (tag_id, title)
|
||||||
assoc_table = "notes_modules_tags" # table (tag_id, object_id)
|
assoc_table = "notes_modules_tags" # table (tag_id, object_id)
|
||||||
obj_colname = "module_id" # column name for object_id in assoc_table
|
obj_colname = "module_id" # column name for object_id in assoc_table
|
||||||
|
|
||||||
def list_modules(self, formation_code=""):
|
def list_modules(self, formation_code=""):
|
||||||
"""Liste des modules des formations de code donné (formation_code) avec ce tag
|
"""Liste des modules des formations de code donné (formation_code) avec ce tag"""
|
||||||
"""
|
|
||||||
args = {"tag_id": self.tag_id}
|
args = {"tag_id": self.tag_id}
|
||||||
if not formation_code:
|
if not formation_code:
|
||||||
# tous les modules de toutes les formations !
|
# tous les modules de toutes les formations !
|
||||||
@ -212,8 +208,7 @@ def module_tag_search(context, term, REQUEST=None):
|
|||||||
|
|
||||||
|
|
||||||
def module_tag_list(context, module_id=""):
|
def module_tag_list(context, module_id=""):
|
||||||
"""les noms de tags associés à ce module
|
"""les noms de tags associés à ce module"""
|
||||||
"""
|
|
||||||
r = SimpleDictFetch(
|
r = SimpleDictFetch(
|
||||||
context,
|
context,
|
||||||
"""SELECT t.title
|
"""SELECT t.title
|
||||||
@ -267,7 +262,7 @@ def module_tag_set(context, module_id="", taglist=[], REQUEST=None):
|
|||||||
def get_etud_tagged_modules(context, etudid, tagname):
|
def get_etud_tagged_modules(context, etudid, tagname):
|
||||||
"""Liste d'infos sur les modules de ce semestre avec ce tag.
|
"""Liste d'infos sur les modules de ce semestre avec ce tag.
|
||||||
Cherche dans tous les semestres dans lesquel l'étudiant est ou a été inscrit.
|
Cherche dans tous les semestres dans lesquel l'étudiant est ou a été inscrit.
|
||||||
Construit la liste des modules avec le tag donné par tagname
|
Construit la liste des modules avec le tag donné par tagname
|
||||||
"""
|
"""
|
||||||
etud = context.getEtudInfo(etudid=etudid, filled=True)[0]
|
etud = context.getEtudInfo(etudid=etudid, filled=True)[0]
|
||||||
R = []
|
R = []
|
||||||
@ -292,7 +287,7 @@ def get_etud_tagged_modules(context, etudid, tagname):
|
|||||||
|
|
||||||
|
|
||||||
def split_tagname_coeff(tag, separateur=":"):
|
def split_tagname_coeff(tag, separateur=":"):
|
||||||
"""Découpe un tag saisi par un utilisateur pour en extraire un tagname
|
"""Découpe un tag saisi par un utilisateur pour en extraire un tagname
|
||||||
(chaine de caractère correspondant au tag)
|
(chaine de caractère correspondant au tag)
|
||||||
et un éventuel coefficient de pondération, avec le séparateur fourni (par défaut ":").
|
et un éventuel coefficient de pondération, avec le séparateur fourni (par défaut ":").
|
||||||
Renvoie le résultat sous la forme d'une liste [tagname, pond] où pond est un float
|
Renvoie le résultat sous la forme d'une liste [tagname, pond] où pond est un float
|
||||||
|
@ -66,8 +66,7 @@ def pdf_trombino_tours(
|
|||||||
formsemestre_id=None, # utilisé si pas de groupes selectionné
|
formsemestre_id=None, # utilisé si pas de groupes selectionné
|
||||||
REQUEST=None,
|
REQUEST=None,
|
||||||
):
|
):
|
||||||
"""Generation du trombinoscope en fichier PDF
|
"""Generation du trombinoscope en fichier PDF"""
|
||||||
"""
|
|
||||||
# Informations sur les groupes à afficher:
|
# Informations sur les groupes à afficher:
|
||||||
groups_infos = sco_groups_view.DisplayedGroupsInfos(
|
groups_infos = sco_groups_view.DisplayedGroupsInfos(
|
||||||
context, group_ids, formsemestre_id=formsemestre_id, REQUEST=REQUEST
|
context, group_ids, formsemestre_id=formsemestre_id, REQUEST=REQUEST
|
||||||
@ -294,8 +293,7 @@ def pdf_feuille_releve_absences(
|
|||||||
formsemestre_id=None, # utilisé si pas de groupes selectionné
|
formsemestre_id=None, # utilisé si pas de groupes selectionné
|
||||||
REQUEST=None,
|
REQUEST=None,
|
||||||
):
|
):
|
||||||
"""Generation de la feuille d'absence en fichier PDF, avec photos
|
"""Generation de la feuille d'absence en fichier PDF, avec photos"""
|
||||||
"""
|
|
||||||
|
|
||||||
NB_CELL_AM = context.get_preference("feuille_releve_abs_AM")
|
NB_CELL_AM = context.get_preference("feuille_releve_abs_AM")
|
||||||
NB_CELL_PM = context.get_preference("feuille_releve_abs_PM")
|
NB_CELL_PM = context.get_preference("feuille_releve_abs_PM")
|
||||||
|
@ -72,8 +72,7 @@ def external_ue_create(
|
|||||||
ects=0.0,
|
ects=0.0,
|
||||||
REQUEST=None,
|
REQUEST=None,
|
||||||
):
|
):
|
||||||
"""Crée UE/matiere/module/evaluation puis saisie les notes
|
"""Crée UE/matiere/module/evaluation puis saisie les notes"""
|
||||||
"""
|
|
||||||
log("external_ue_create( formsemestre_id=%s, titre=%s )" % (formsemestre_id, titre))
|
log("external_ue_create( formsemestre_id=%s, titre=%s )" % (formsemestre_id, titre))
|
||||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||||
# Contrôle d'accès:
|
# Contrôle d'accès:
|
||||||
@ -196,13 +195,14 @@ def get_external_moduleimpl_id(context, formsemestre_id, ue_id):
|
|||||||
# Web function
|
# Web function
|
||||||
def external_ue_create_form(context, formsemestre_id, etudid, REQUEST=None):
|
def external_ue_create_form(context, formsemestre_id, etudid, REQUEST=None):
|
||||||
"""Formulaire création UE externe + inscription étudiant et saisie note
|
"""Formulaire création UE externe + inscription étudiant et saisie note
|
||||||
- Demande UE: peut-être existante (liste les UE externes de cette formation),
|
- Demande UE: peut-être existante (liste les UE externes de cette formation),
|
||||||
ou sinon spécifier titre, acronyme, type, ECTS
|
ou sinon spécifier titre, acronyme, type, ECTS
|
||||||
- Demande note à enregistrer.
|
- Demande note à enregistrer.
|
||||||
|
|
||||||
Note: pour l'édition éventuelle de ces informations, on utilisera les
|
Note: pour l'édition éventuelle de ces informations, on utilisera les
|
||||||
fonctions standards sur les UE/modules/notes
|
fonctions standards sur les UE/modules/notes
|
||||||
"""
|
"""
|
||||||
|
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||||
# Contrôle d'accès:
|
# Contrôle d'accès:
|
||||||
authuser = REQUEST.AUTHENTICATED_USER
|
authuser = REQUEST.AUTHENTICATED_USER
|
||||||
if not authuser.has_permission(ScoImplement, context):
|
if not authuser.has_permission(ScoImplement, context):
|
||||||
@ -210,9 +210,7 @@ def external_ue_create_form(context, formsemestre_id, etudid, REQUEST=None):
|
|||||||
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")
|
||||||
|
|
||||||
etud = context.getEtudInfo(etudid=etudid, filled=1, REQUEST=REQUEST)[0]
|
etud = context.getEtudInfo(etudid=etudid, filled=1, REQUEST=REQUEST)[0]
|
||||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
|
||||||
formation_id = sem["formation_id"]
|
formation_id = sem["formation_id"]
|
||||||
F = context.formation_list(args={"formation_id": formation_id})[0]
|
|
||||||
existing_external_ue = get_existing_external_ue(context, formation_id)
|
existing_external_ue = get_existing_external_ue(context, formation_id)
|
||||||
|
|
||||||
H = [
|
H = [
|
||||||
|
@ -123,8 +123,7 @@ def is_up_to_date(context):
|
|||||||
|
|
||||||
|
|
||||||
def html_up_to_date_box(context):
|
def html_up_to_date_box(context):
|
||||||
"""
|
""""""
|
||||||
"""
|
|
||||||
status, msg = is_up_to_date(context)
|
status, msg = is_up_to_date(context)
|
||||||
if status:
|
if status:
|
||||||
return ""
|
return ""
|
||||||
|
@ -57,8 +57,7 @@ def logdb(REQUEST=None, cnx=None, method=None, etudid=None, msg=None, commit=Tru
|
|||||||
|
|
||||||
|
|
||||||
def loglist(cnx, method=None, authenticated_user=None):
|
def loglist(cnx, method=None, authenticated_user=None):
|
||||||
"""List of events logged for these method and user
|
"""List of events logged for these method and user"""
|
||||||
"""
|
|
||||||
cursor = cnx.cursor(cursor_factory=ScoDocCursor)
|
cursor = cnx.cursor(cursor_factory=ScoDocCursor)
|
||||||
cursor.execute(
|
cursor.execute(
|
||||||
"select * from scolog where method=%(method)s and authenticated_user=%(authenticated_user)s",
|
"select * from scolog where method=%(method)s and authenticated_user=%(authenticated_user)s",
|
||||||
|
Loading…
Reference in New Issue
Block a user