ScoDoc/app/scodoc/sco_edt_cal.py

207 lines
6.4 KiB
Python
Raw Permalink Normal View History

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