forked from ScoDoc/ScoDoc
Calendrier évaluations: fix #875
This commit is contained in:
parent
f2ce16f161
commit
ad7b48e110
@ -230,41 +230,41 @@ def next_iso_day(date):
|
|||||||
|
|
||||||
def YearTable(
|
def YearTable(
|
||||||
year,
|
year,
|
||||||
events=[],
|
events_by_day: dict[str, list[dict]],
|
||||||
firstmonth=9,
|
firstmonth=9,
|
||||||
lastmonth=7,
|
lastmonth=7,
|
||||||
halfday=0,
|
|
||||||
dayattributes="",
|
dayattributes="",
|
||||||
pad_width=8,
|
|
||||||
):
|
):
|
||||||
|
# Code simplifié en 2024: utilisé seulement pour calendrier évaluations
|
||||||
"""Generate a calendar table
|
"""Generate a calendar table
|
||||||
events = list of tuples (date, text, color, href [,halfday])
|
events = list of tuples (date, text, color, href [,halfday])
|
||||||
where date is a string in ISO format (yyyy-mm-dd)
|
where date is a string in ISO format (yyyy-mm-dd)
|
||||||
halfday is boolean (true: morning, false: afternoon)
|
halfday is boolean (true: morning, false: afternoon)
|
||||||
text = text to put in calendar (must be short, 1-5 cars) (optional)
|
text = text to put in calendar (must be short, 1-5 cars) (optional)
|
||||||
if halfday, generate 2 cells per day (morning, afternoon)
|
|
||||||
"""
|
"""
|
||||||
T = [
|
T = [
|
||||||
'<table id="maincalendar" class="maincalendar" border="3" cellpadding="1" cellspacing="1" frame="box">'
|
"""<table id="maincalendar" class="maincalendar"
|
||||||
|
border="3" cellpadding="1" cellspacing="1" frame="box">"""
|
||||||
]
|
]
|
||||||
T.append("<tr>")
|
T.append("<tr>")
|
||||||
month = firstmonth
|
month = firstmonth
|
||||||
while 1:
|
while True:
|
||||||
T.append('<td valign="top">')
|
T.append('<td valign="top">')
|
||||||
T.append(MonthTableHead(month))
|
T.append(_month_table_head(month))
|
||||||
T.append(
|
T.append(
|
||||||
MonthTableBody(
|
_month_table_body(
|
||||||
month,
|
month,
|
||||||
year,
|
year,
|
||||||
events,
|
events_by_day,
|
||||||
halfday,
|
|
||||||
dayattributes,
|
dayattributes,
|
||||||
is_work_saturday(),
|
is_work_saturday(),
|
||||||
pad_width=pad_width,
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
T.append(MonthTableTail())
|
T.append(
|
||||||
T.append("</td>")
|
"""
|
||||||
|
</table>
|
||||||
|
</td>"""
|
||||||
|
)
|
||||||
if month == lastmonth:
|
if month == lastmonth:
|
||||||
break
|
break
|
||||||
month = month + 1
|
month = month + 1
|
||||||
@ -322,29 +322,32 @@ WEEKDAYCOLOR = GRAY1
|
|||||||
WEEKENDCOLOR = GREEN3
|
WEEKENDCOLOR = GREEN3
|
||||||
|
|
||||||
|
|
||||||
def MonthTableHead(month):
|
def _month_table_head(month):
|
||||||
color = WHITE
|
color = WHITE
|
||||||
return """<table class="monthcalendar" border="0" cellpadding="0" cellspacing="0" frame="box">
|
return f"""<table class="monthcalendar" border="0" cellpadding="0" cellspacing="0" frame="box">
|
||||||
<tr bgcolor="%s"><td class="calcol" colspan="2" align="center">%s</td></tr>\n""" % (
|
<tr bgcolor="{color}">
|
||||||
color,
|
<td class="calcol" colspan="2" align="center">{MONTHNAMES_ABREV[month - 1]}</td>
|
||||||
MONTHNAMES_ABREV[month - 1],
|
</tr>\n"""
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def MonthTableTail():
|
def _month_table_body(
|
||||||
return "</table>\n"
|
month,
|
||||||
|
year,
|
||||||
|
events_by_day: dict[str, list[dict]],
|
||||||
def MonthTableBody(
|
trattributes="",
|
||||||
month, year, events=[], halfday=0, trattributes="", work_saturday=False, pad_width=8
|
work_saturday=False,
|
||||||
):
|
) -> str:
|
||||||
|
"""
|
||||||
|
events : [event]
|
||||||
|
event = [ yyyy-mm-dd, legend, href, color, descr ] XXX
|
||||||
|
"""
|
||||||
firstday, nbdays = calendar.monthrange(year, month)
|
firstday, nbdays = calendar.monthrange(year, month)
|
||||||
localtime = time.localtime()
|
localtime = time.localtime()
|
||||||
current_weeknum = time.strftime("%U", localtime)
|
current_weeknum = time.strftime("%U", localtime)
|
||||||
current_year = localtime[0]
|
current_year = localtime[0]
|
||||||
T = []
|
rows = []
|
||||||
# cherche date du lundi de la 1ere semaine de ce mois
|
# cherche date du lundi de la 1ere semaine de ce mois
|
||||||
monday = ddmmyyyy("1/%d/%d" % (month, year))
|
monday = ddmmyyyy(f"1/{month}/{year}")
|
||||||
while monday.weekday != 0:
|
while monday.weekday != 0:
|
||||||
monday = monday.prev()
|
monday = monday.prev()
|
||||||
|
|
||||||
@ -353,158 +356,51 @@ def MonthTableBody(
|
|||||||
else:
|
else:
|
||||||
weekend = ("S", "D")
|
weekend = ("S", "D")
|
||||||
|
|
||||||
if not halfday:
|
for d in range(1, nbdays + 1):
|
||||||
for d in range(1, nbdays + 1):
|
weeknum = time.strftime(
|
||||||
weeknum = time.strftime(
|
"%U", time.strptime("%d/%d/%d" % (d, month, year), scu.DATE_FMT)
|
||||||
"%U", time.strptime("%d/%d/%d" % (d, month, year), scu.DATE_FMT)
|
)
|
||||||
)
|
day = DAYNAMES_ABREV[(firstday + d - 1) % 7]
|
||||||
day = DAYNAMES_ABREV[(firstday + d - 1) % 7]
|
if day in weekend:
|
||||||
if day in weekend:
|
bgcolor = WEEKENDCOLOR
|
||||||
bgcolor = WEEKENDCOLOR
|
weekclass = "wkend"
|
||||||
weekclass = "wkend"
|
attrs = ""
|
||||||
attrs = ""
|
else:
|
||||||
else:
|
bgcolor = WEEKDAYCOLOR
|
||||||
bgcolor = WEEKDAYCOLOR
|
weekclass = "wk" + str(monday).replace("/", "_")
|
||||||
weekclass = "wk" + str(monday).replace("/", "_")
|
attrs = trattributes
|
||||||
attrs = trattributes
|
# events this day ?
|
||||||
color = None
|
events = events_by_day.get(f"{year}-{month:02}-{d:02}", [])
|
||||||
legend = ""
|
color = None
|
||||||
href = ""
|
ev_txts = []
|
||||||
descr = ""
|
for ev in events:
|
||||||
# event this day ?
|
color = ev.get("color")
|
||||||
# each event is a tuple (date, text, color, href)
|
href = ev.get("href", "")
|
||||||
# where date is a string in ISO format (yyyy-mm-dd)
|
description = ev.get("description", "")
|
||||||
for ev in events:
|
|
||||||
ev_year = int(ev[0][:4])
|
|
||||||
ev_month = int(ev[0][5:7])
|
|
||||||
ev_day = int(ev[0][8:10])
|
|
||||||
if year == ev_year and month == ev_month and ev_day == d:
|
|
||||||
if ev[1]:
|
|
||||||
legend = ev[1]
|
|
||||||
if ev[2]:
|
|
||||||
color = ev[2]
|
|
||||||
if ev[3]:
|
|
||||||
href = ev[3]
|
|
||||||
if len(ev) > 4 and ev[4]:
|
|
||||||
descr = ev[4]
|
|
||||||
#
|
|
||||||
cc = []
|
|
||||||
if color is not None:
|
|
||||||
cc.append('<td bgcolor="%s" class="calcell">' % color)
|
|
||||||
else:
|
|
||||||
cc.append('<td class="calcell">')
|
|
||||||
|
|
||||||
if href:
|
if href:
|
||||||
href = 'href="%s"' % href
|
href = f'href="{href}"'
|
||||||
if descr:
|
if description:
|
||||||
descr = 'title="%s"' % html.escape(descr, quote=True)
|
description = f"""title="{html.escape(description, quote=True)}" """
|
||||||
if href or descr:
|
if href or description:
|
||||||
cc.append("<a %s %s>" % (href, descr))
|
ev_txts.append(f"""<a {href} {description}>{ev.get("title", "")}</a>""")
|
||||||
|
|
||||||
if legend or d == 1:
|
|
||||||
if pad_width is not None:
|
|
||||||
n = pad_width - len(legend) # pad to 8 cars
|
|
||||||
if n > 0:
|
|
||||||
legend = (
|
|
||||||
" " * (n // 2) + legend + " " * ((n + 1) // 2)
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
legend = " " # empty cell
|
ev_txts.append(ev.get("title", " "))
|
||||||
cc.append(legend)
|
#
|
||||||
if href or descr:
|
cc = []
|
||||||
cc.append("</a>")
|
if color is not None:
|
||||||
cc.append("</td>")
|
cc.append(f'<td bgcolor="{color}" class="calcell">')
|
||||||
cell = "".join(cc)
|
else:
|
||||||
if day == "D":
|
cc.append('<td class="calcell">')
|
||||||
monday = monday.next_day(7)
|
|
||||||
if (
|
|
||||||
weeknum == current_weeknum
|
|
||||||
and current_year == year
|
|
||||||
and weekclass != "wkend"
|
|
||||||
):
|
|
||||||
weekclass += " currentweek"
|
|
||||||
T.append(
|
|
||||||
'<tr bgcolor="%s" class="%s" %s><td class="calday">%d%s</td>%s</tr>'
|
|
||||||
% (bgcolor, weekclass, attrs, d, day, cell)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
# Calendar with 2 cells / day
|
|
||||||
for d in range(1, nbdays + 1):
|
|
||||||
weeknum = time.strftime(
|
|
||||||
"%U", time.strptime("%d/%d/%d" % (d, month, year), scu.DATE_FMT)
|
|
||||||
)
|
|
||||||
day = DAYNAMES_ABREV[(firstday + d - 1) % 7]
|
|
||||||
if day in weekend:
|
|
||||||
bgcolor = WEEKENDCOLOR
|
|
||||||
weekclass = "wkend"
|
|
||||||
attrs = ""
|
|
||||||
else:
|
|
||||||
bgcolor = WEEKDAYCOLOR
|
|
||||||
weekclass = "wk" + str(monday).replace("/", "_")
|
|
||||||
attrs = trattributes
|
|
||||||
if (
|
|
||||||
weeknum == current_weeknum
|
|
||||||
and current_year == year
|
|
||||||
and weekclass != "wkend"
|
|
||||||
):
|
|
||||||
weeknum += " currentweek"
|
|
||||||
|
|
||||||
if day == "D":
|
cc.append(f"{', '.join(ev_txts)}</td>")
|
||||||
monday = monday.next_day(7)
|
cells = "".join(cc)
|
||||||
T.append(
|
if day == "D":
|
||||||
'<tr bgcolor="%s" class="wk%s" %s><td class="calday">%d%s</td>'
|
monday = monday.next_day(7)
|
||||||
% (bgcolor, weekclass, attrs, d, day)
|
if weeknum == current_weeknum and current_year == year and weekclass != "wkend":
|
||||||
)
|
weekclass += " currentweek"
|
||||||
cc = []
|
rows.append(
|
||||||
for morning in (True, False):
|
f"""<tr bgcolor="{bgcolor}" class="{weekclass}" {attrs}>
|
||||||
color = None
|
<td class="calday">{d}{day}</td>{cells}</tr>"""
|
||||||
legend = ""
|
)
|
||||||
href = ""
|
|
||||||
descr = ""
|
return "\n".join(rows)
|
||||||
for ev in events:
|
|
||||||
ev_year = int(ev[0][:4])
|
|
||||||
ev_month = int(ev[0][5:7])
|
|
||||||
ev_day = int(ev[0][8:10])
|
|
||||||
if ev[4] is not None:
|
|
||||||
ev_half = int(ev[4])
|
|
||||||
else:
|
|
||||||
ev_half = 0
|
|
||||||
if (
|
|
||||||
year == ev_year
|
|
||||||
and month == ev_month
|
|
||||||
and ev_day == d
|
|
||||||
and morning == ev_half
|
|
||||||
):
|
|
||||||
if ev[1]:
|
|
||||||
legend = ev[1]
|
|
||||||
if ev[2]:
|
|
||||||
color = ev[2]
|
|
||||||
if ev[3]:
|
|
||||||
href = ev[3]
|
|
||||||
if len(ev) > 5 and ev[5]:
|
|
||||||
descr = ev[5]
|
|
||||||
#
|
|
||||||
if color is not None:
|
|
||||||
cc.append('<td bgcolor="%s" class="calcell">' % (color))
|
|
||||||
else:
|
|
||||||
cc.append('<td class="calcell">')
|
|
||||||
if href:
|
|
||||||
href = 'href="%s"' % href
|
|
||||||
if descr:
|
|
||||||
descr = 'title="%s"' % html.escape(descr, quote=True)
|
|
||||||
if href or descr:
|
|
||||||
cc.append("<a %s %s>" % (href, descr))
|
|
||||||
if legend or d == 1:
|
|
||||||
n = 3 - len(legend) # pad to 3 cars
|
|
||||||
if n > 0:
|
|
||||||
legend = (
|
|
||||||
" " * (n // 2) + legend + " " * ((n + 1) // 2)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
legend = " " # empty cell
|
|
||||||
cc.append(legend)
|
|
||||||
if href or descr:
|
|
||||||
cc.append("</a>")
|
|
||||||
cc.append("</td>\n")
|
|
||||||
T.append("".join(cc) + "</tr>")
|
|
||||||
return "\n".join(T)
|
|
||||||
|
@ -360,6 +360,7 @@ def do_evaluation_etat_in_mod(nt, modimpl: ModuleImpl):
|
|||||||
return etat
|
return etat
|
||||||
|
|
||||||
|
|
||||||
|
# View
|
||||||
def formsemestre_evaluations_cal(formsemestre_id):
|
def formsemestre_evaluations_cal(formsemestre_id):
|
||||||
"""Page avec calendrier de toutes les evaluations de ce semestre"""
|
"""Page avec calendrier de toutes les evaluations de ce semestre"""
|
||||||
formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
|
formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
|
||||||
@ -373,22 +374,17 @@ def formsemestre_evaluations_cal(formsemestre_id):
|
|||||||
color_futur = "#70E0FF"
|
color_futur = "#70E0FF"
|
||||||
|
|
||||||
year = formsemestre.annee_scolaire()
|
year = formsemestre.annee_scolaire()
|
||||||
events = {} # (day, halfday) : event
|
events_by_day = collections.defaultdict(list) # date_iso : event
|
||||||
for e in evaluations:
|
for e in evaluations:
|
||||||
if e.date_debut is None:
|
if e.date_debut is None:
|
||||||
continue # éval. sans date
|
continue # éval. sans date
|
||||||
txt = e.moduleimpl.module.code or e.moduleimpl.module.abbrev or "éval."
|
|
||||||
if e.date_debut == e.date_fin:
|
if e.date_debut == e.date_fin:
|
||||||
heure_debut_txt, heure_fin_txt = "?", "?"
|
heure_debut_txt, heure_fin_txt = "", ""
|
||||||
else:
|
else:
|
||||||
heure_debut_txt = (
|
heure_debut_txt = (
|
||||||
e.date_debut.strftime(scu.TIME_FMT) if e.date_debut else "?"
|
e.date_debut.strftime(scu.TIME_FMT) if e.date_debut else ""
|
||||||
)
|
)
|
||||||
heure_fin_txt = e.date_fin.strftime(scu.TIME_FMT) if e.date_fin else "?"
|
heure_fin_txt = e.date_fin.strftime(scu.TIME_FMT) if e.date_fin else ""
|
||||||
|
|
||||||
description = f"""{
|
|
||||||
e.moduleimpl.module.titre
|
|
||||||
}, de {heure_debut_txt} à {heure_fin_txt}"""
|
|
||||||
|
|
||||||
# Etat (notes completes) de l'évaluation:
|
# Etat (notes completes) de l'évaluation:
|
||||||
modimpl_result = nt.modimpls_results[e.moduleimpl.id]
|
modimpl_result = nt.modimpls_results[e.moduleimpl.id]
|
||||||
@ -398,28 +394,27 @@ def formsemestre_evaluations_cal(formsemestre_id):
|
|||||||
color = color_incomplete
|
color = color_incomplete
|
||||||
if e.date_debut > datetime.datetime.now(scu.TIME_ZONE):
|
if e.date_debut > datetime.datetime.now(scu.TIME_ZONE):
|
||||||
color = color_futur
|
color = color_futur
|
||||||
href = url_for(
|
|
||||||
"notes.moduleimpl_status",
|
|
||||||
scodoc_dept=g.scodoc_dept,
|
|
||||||
moduleimpl_id=e.moduleimpl_id,
|
|
||||||
)
|
|
||||||
day = e.date_debut.date().isoformat() # yyyy-mm-dd
|
day = e.date_debut.date().isoformat() # yyyy-mm-dd
|
||||||
event = events.get(day)
|
event = {
|
||||||
if not event:
|
"color": color,
|
||||||
events[day] = [day, txt, color, href, description, e.moduleimpl]
|
"date_iso": day,
|
||||||
else:
|
"title": e.moduleimpl.module.code or e.moduleimpl.module.abbrev or "éval.",
|
||||||
if event[-1].id != e.moduleimpl.id:
|
"description": f"""{e.description or e.moduleimpl.module.titre_str()}"""
|
||||||
# plusieurs evals de modules differents a la meme date
|
+ (
|
||||||
event[1] += ", " + txt
|
f""" de {heure_debut_txt} à {heure_fin_txt}"""
|
||||||
event[4] += ", " + description
|
if heure_debut_txt
|
||||||
if color == color_incomplete:
|
else ""
|
||||||
event[2] = color_incomplete
|
),
|
||||||
if color == color_futur:
|
"href": url_for(
|
||||||
event[2] = color_futur
|
"notes.moduleimpl_status",
|
||||||
|
scodoc_dept=g.scodoc_dept,
|
||||||
|
moduleimpl_id=e.moduleimpl_id,
|
||||||
|
),
|
||||||
|
"modimpl": e.moduleimpl,
|
||||||
|
}
|
||||||
|
events_by_day[day].append(event)
|
||||||
|
|
||||||
cal_html = sco_cal.YearTable(
|
cal_html = sco_cal.YearTable(year, events_by_day=events_by_day)
|
||||||
year, events=list(events.values()), halfday=False, pad_width=None
|
|
||||||
)
|
|
||||||
|
|
||||||
return f"""
|
return f"""
|
||||||
{
|
{
|
||||||
|
@ -51,8 +51,6 @@ Calendrier de l'assiduité
|
|||||||
|
|
||||||
<div class="dayline">
|
<div class="dayline">
|
||||||
<div class="dayline-title">
|
<div class="dayline-title">
|
||||||
<span>Assiduité du</span>
|
|
||||||
<br>
|
|
||||||
<span>{{jour.get_date()}}</span>
|
<span>{{jour.get_date()}}</span>
|
||||||
{{jour.generate_minitimeline() | safe}}
|
{{jour.generate_minitimeline() | safe}}
|
||||||
</div>
|
</div>
|
||||||
@ -158,7 +156,7 @@ Calendrier de l'assiduité
|
|||||||
|
|
||||||
.calendrier {
|
.calendrier {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: start;
|
justify-content: center;
|
||||||
overflow-x: scroll;
|
overflow-x: scroll;
|
||||||
border: 1px solid #444;
|
border: 1px solid #444;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# -*- mode: python -*-
|
# -*- mode: python -*-
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
SCOVERSION = "9.6.962"
|
SCOVERSION = "9.6.963"
|
||||||
|
|
||||||
SCONAME = "ScoDoc"
|
SCONAME = "ScoDoc"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user