code cleaning

This commit is contained in:
Emmanuel Viennet 2022-09-30 16:01:43 +02:00 committed by iziram
parent c91aabee8d
commit 3314c1738e

View File

@ -1,220 +1,206 @@
# -*- mode: python -*- # -*- mode: python -*-
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
############################################################################## ##############################################################################
# #
# Gestion scolarite IUT # Gestion scolarite IUT
# #
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved. # Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or # the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software # along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# #
# Emmanuel Viennet emmanuel.viennet@viennet.net # Emmanuel Viennet emmanuel.viennet@viennet.net
# #
############################################################################## ##############################################################################
"""Accès aux emplois du temps """Accès aux emplois du temps
XXX usage uniquement experimental pour tests implémentations XXX usage uniquement experimental pour tests implémentations
XXX incompatible avec les ics HyperPlanning Paris 13 (était pour GPU). XXX incompatible avec les ics HyperPlanning Paris 13 (était pour GPU).
""" """
import icalendar import icalendar
import pprint import pprint
import traceback import traceback
import urllib import urllib
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
from app import log from app import log
from app.scodoc import html_sco_header from app.scodoc import html_sco_header
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
from app.scodoc import sco_groups from app.scodoc import sco_groups
from app.scodoc import sco_groups_view from app.scodoc import sco_groups_view
from app.scodoc import sco_preferences from app.scodoc import sco_preferences
def formsemestre_get_ics_url(sem): def formsemestre_get_ics_url(sem):
""" """
edt_sem_ics_url est un template edt_sem_ics_url est un template
utilisé avec .format(sem=sem) utilisé avec .format(sem=sem)
Par exemple: Par exemple:
https://example.fr/agenda/{sem[etapes][0]} https://example.fr/agenda/{sem[etapes][0]}
""" """
ics_url_tmpl = sco_preferences.get_preference( ics_url_tmpl = sco_preferences.get_preference(
"edt_sem_ics_url", sem["formsemestre_id"] "edt_sem_ics_url", sem["formsemestre_id"]
) )
if not ics_url_tmpl: if not ics_url_tmpl:
return None return None
try: try:
ics_url = ics_url_tmpl.format(sem=sem) ics_url = ics_url_tmpl.format(sem=sem)
except: except:
log( log(
"Exception in formsemestre_get_ics_url(formsemestre_id=%s)" f"""Exception in formsemestre_get_ics_url(formsemestre_id={sem["formsemestre_id"]})
% sem["formsemestre_id"] ics_url_tmpl='{ics_url_tmpl}'
) """
log("ics_url_tmpl='%s'" % ics_url_tmpl) )
log(traceback.format_exc()) log(traceback.format_exc())
return None return None
return ics_url return ics_url
def formsemestre_load_ics(sem): def formsemestre_load_ics(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(sem) ics_url = formsemestre_get_ics_url(sem)
if not ics_url: if not ics_url:
ics_data = "" ics_data = ""
else: else:
log("Loading edt from %s" % ics_url) log(f"Loading edt from {ics_url}")
f = urllib.request.urlopen( # 5s TODO: add config parameter, eg for slow networks
ics_url, timeout=5 f = urllib.request.urlopen(ics_url, timeout=5)
) # 5s TODO: add config parameter, eg for slow networks ics_data = f.read()
ics_data = f.read() f.close()
f.close()
cal = icalendar.Calendar.from_ical(ics_data)
cal = icalendar.Calendar.from_ical(ics_data) return cal
return cal
def get_edt_transcodage_groups(formsemestre_id):
# def formsemestre_edt_groups_used(sem): """-> { nom_groupe_edt : nom_groupe_scodoc }"""
# """L'ensemble des groupes EDT utilisés dans l'emploi du temps publié""" # TODO: valider ces données au moment où on enregistre les préférences
# cal = formsemestre_load_ics(sem) edt2sco = {}
# return {e["X-GROUP-ID"].decode("utf8") for e in events} sco2edt = {}
msg = "" # message erreur, '' si ok
txt = sco_preferences.get_preference("edt_groups2scodoc", formsemestre_id)
def get_edt_transcodage_groups(formsemestre_id): if not txt:
"""-> { nom_groupe_edt : nom_groupe_scodoc }""" return edt2sco, sco2edt, msg
# TODO: valider ces données au moment où on enregistre les préférences
edt2sco = {} line_num = 1
sco2edt = {} for line in txt.split("\n"):
msg = "" # message erreur, '' si ok fs = [s.strip() for s in line.split(";")]
txt = sco_preferences.get_preference("edt_groups2scodoc", formsemestre_id) if len(fs) == 1: # groupe 'tous'
if not txt: edt2sco[fs[0]] = None
return edt2sco, sco2edt, msg sco2edt[None] = fs[0]
elif len(fs) == 2:
line_num = 1 edt2sco[fs[0]] = fs[1]
for line in txt.split("\n"): sco2edt[fs[1]] = fs[0]
fs = [s.strip() for s in line.split(";")] else:
if len(fs) == 1: # groupe 'tous' msg = f"ligne {line_num} invalide"
edt2sco[fs[0]] = None line_num += 1
sco2edt[None] = fs[0]
elif len(fs) == 2: log(f"sco2edt={pprint.pformat(sco2edt)}")
edt2sco[fs[0]] = fs[1] return edt2sco, sco2edt, msg
sco2edt[fs[1]] = fs[0]
else:
msg = "ligne %s invalide" % line_num def group_edt_json(group_id, start="", end=""): # actuellement inutilisé
line_num += 1 """EDT complet du semestre, au format JSON
TODO: indiquer un groupe
log("sco2edt=%s" % pprint.pformat(sco2edt)) TODO: utiliser start et end (2 dates au format ISO YYYY-MM-DD)
return edt2sco, sco2edt, msg TODO: cacher
"""
group = sco_groups.get_group(group_id)
def group_edt_json(group_id, start="", end=""): # actuellement inutilisé sem = sco_formsemestre.get_formsemestre(group["formsemestre_id"])
"""EDT complet du semestre, au format JSON edt2sco, sco2edt, msg = get_edt_transcodage_groups(group["formsemestre_id"])
TODO: indiquer un groupe
TODO: utiliser start et end (2 dates au format ISO YYYY-MM-DD) edt_group_name = sco2edt.get(group["group_name"], group["group_name"])
TODO: cacher log("group scodoc=%s : edt=%s" % (group["group_name"], edt_group_name))
"""
group = sco_groups.get_group(group_id) cal = formsemestre_load_ics(sem)
sem = sco_formsemestre.get_formsemestre(group["formsemestre_id"]) events = [e for e in cal.walk() if e.name == "VEVENT"]
edt2sco, sco2edt, msg = get_edt_transcodage_groups(group["formsemestre_id"]) J = []
for e in events:
edt_group_name = sco2edt.get(group["group_name"], group["group_name"]) # if e['X-GROUP-ID'].strip() == edt_group_name:
log("group scodoc=%s : edt=%s" % (group["group_name"], edt_group_name)) if "DESCRIPTION" in e:
d = {
cal = formsemestre_load_ics(sem) "title": e.decoded("DESCRIPTION"), # + '/' + e['X-GROUP-ID'],
events = [e for e in cal.walk() if e.name == "VEVENT"] "start": e.decoded("dtstart").isoformat(),
J = [] "end": e.decoded("dtend").isoformat(),
for e in events: }
# if e['X-GROUP-ID'].strip() == edt_group_name: J.append(d)
if "DESCRIPTION" in e:
d = { return scu.sendJSON(J)
"title": e.decoded("DESCRIPTION"), # + '/' + e['X-GROUP-ID'],
"start": e.decoded("dtstart").isoformat(),
"end": e.decoded("dtend").isoformat(), def experimental_calendar(group_id=None, formsemestre_id=None): # inutilisé
} """experimental page"""
J.append(d) return "\n".join(
[
return scu.sendJSON(J) html_sco_header.sco_header(
javascripts=[
"libjs/purl.js",
"""XXX "libjs/moment.min.js",
for e in events: "libjs/fullcalendar/fullcalendar.min.js",
if 'DESCRIPTION' in e: ],
print e.decoded('DESCRIPTION') cssstyles=[
""" # 'libjs/bootstrap-3.1.1-dist/css/bootstrap.min.css',
# 'libjs/bootstrap-3.1.1-dist/css/bootstrap-theme.min.css',
# 'libjs/bootstrap-multiselect/bootstrap-multiselect.css'
def experimental_calendar(group_id=None, formsemestre_id=None): # inutilisé "libjs/fullcalendar/fullcalendar.css",
"""experimental page""" # media='print' 'libjs/fullcalendar/fullcalendar.print.css'
return "\n".join( ],
[ ),
html_sco_header.sco_header( """<style>
javascripts=[ #loading {
"libjs/purl.js", display: none;
"libjs/moment.min.js", position: absolute;
"libjs/fullcalendar/fullcalendar.min.js", top: 10px;
], right: 10px;
cssstyles=[ }
# 'libjs/bootstrap-3.1.1-dist/css/bootstrap.min.css', </style>
# 'libjs/bootstrap-3.1.1-dist/css/bootstrap-theme.min.css', """,
# 'libjs/bootstrap-multiselect/bootstrap-multiselect.css' """<form id="group_selector" method="get">
"libjs/fullcalendar/fullcalendar.css", <span style="font-weight: bold; font-size:120%">Emplois du temps du groupe</span>""",
# media='print' 'libjs/fullcalendar/fullcalendar.print.css' sco_groups_view.menu_group_choice(
], group_id=group_id, formsemestre_id=formsemestre_id
), ),
"""<style> """</form><div id="loading">loading...</div>
#loading { <div id="calendar"></div>
display: none; """,
position: absolute; html_sco_header.sco_footer(),
top: 10px; """<script>
right: 10px; $(document).ready(function() {
}
</style> var group_id = $.url().param()['group_id'];
""",
"""<form id="group_selector" method="get"> $('#calendar').fullCalendar({
<span style="font-weight: bold; font-size:120%">Emplois du temps du groupe</span>""", events: {
sco_groups_view.menu_group_choice( url: 'group_edt_json?group_id=' + group_id,
group_id=group_id, formsemestre_id=formsemestre_id error: function() {
), $('#script-warning').show();
"""</form><div id="loading">loading...</div> }
<div id="calendar"></div> },
""", timeFormat: 'HH:mm',
html_sco_header.sco_footer(), timezone: 'local', // heure locale du client
"""<script> loading: function(bool) {
$(document).ready(function() { $('#loading').toggle(bool);
}
var group_id = $.url().param()['group_id']; });
});
$('#calendar').fullCalendar({ </script>
events: { """,
url: 'group_edt_json?group_id=' + group_id, ]
error: function() { )
$('#script-warning').show();
}
},
timeFormat: 'HH:mm',
timezone: 'local', // heure locale du client
loading: function(bool) {
$('#loading').toggle(bool);
}
});
});
</script>
""",
]
)