From 0f4c06767896ed8e7665cc3602b78d40b3b8eaf8 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Tue, 5 Sep 2017 10:14:52 +0200 Subject: Correction des dépendances nécessaires dans le README --- README.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/README.md b/README.md index d3cbb6c..7acda46 100644 --- a/README.md +++ b/README.md @@ -38,11 +38,7 @@ Notez que cette étape n'est pas obligatoire #### Installation des dépendances -> $ pip install requests - -> $ pip install django - -> $ pip install beautiful4 +> $ pip install requests django beautiful4 Si vous utilisez PostgreSQL, vous allez avoir besoin du driver psycopg2 : -- cgit v1.2.1 From 70405621bf66bc188df5d4ee0624735e2967979c Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Tue, 5 Sep 2017 10:15:55 +0200 Subject: Correction des dépendances nécessaires dans le README, encore --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7acda46..66aa100 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ Notez que cette étape n'est pas obligatoire #### Installation des dépendances -> $ pip install requests django beautiful4 +> $ pip install requests django beautifulsoup4 Si vous utilisez PostgreSQL, vous allez avoir besoin du driver psycopg2 : -- cgit v1.2.1 From 78920718408ab411680b7f5dd003b70c4e458e37 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Tue, 5 Sep 2017 10:38:23 +0200 Subject: Correction de l’affichage des remarques --- templates/mail/mail_timetable.txt | 2 +- templates/timetable.html | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/templates/mail/mail_timetable.txt b/templates/mail/mail_timetable.txt index 7cc6b26..20da575 100644 --- a/templates/mail/mail_timetable.txt +++ b/templates/mail/mail_timetable.txt @@ -1,6 +1,6 @@ {% load rooms %}{% autoescape off %}{% for day in courses %}{% filter title %}{{ day.0.begin|date:"l j F o" }}{% endfilter %} - de {{ day.0.begin|date:"H:i" }} à {% with day|last as last %}{{ last.end|date:"H:i" }}{% endwith %} {% for course in day %} * {{ course.name }} ({{ course.type }}), de {{ course.begin|date:"H:i" }} à {{ course.end|date:"H:i" }}{% if course.rooms.all|length > 0 %} - {{ course.rooms.all|format_rooms }}{% endif %}{% if course.notes is not None %} + {{ course.rooms.all|format_rooms }}{% endif %}{% if course.notes != "" %} Remarques : {{ course.notes }}{% endif %} {% endfor %}{% empty %}Aucun cours pour le groupe {{ group }} pendant la semaine {{ week }}. diff --git a/templates/timetable.html b/templates/timetable.html index 264a25c..ba673ce 100644 --- a/templates/timetable.html +++ b/templates/timetable.html @@ -9,7 +9,11 @@

{% filter title %}{{ day.0.begin|date:"l j F o" }}{% endfilter %} – de {{ day.0.begin|date:"H:i" }} à {% with day|last as last %}{{ last.end|date:"H:i" }}{% endwith %}

{% endfor %}

S’abonner à cet emploi du temps

{% endblock %} -- cgit v1.2.1 From b4ed0a15e5bc11c7c41d4d8308ff900a34486697 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Tue, 5 Sep 2017 10:47:57 +0200 Subject: Suppression de l’import de django.db.connection --- models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models.py b/models.py index 21b08f5..1aeb8e2 100644 --- a/models.py +++ b/models.py @@ -14,7 +14,7 @@ # with celcatsanitizer; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -from django.db import connection, models +from django.db import models from django.db.models import Count, Manager, Q from django.db.models.functions import ExtractWeek, ExtractYear from django.utils.text import slugify -- cgit v1.2.1 From f0158ff8d00119307bc8f8ec59de0b6a6f5be3c6 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Tue, 5 Sep 2017 10:50:12 +0200 Subject: Remplacement du type « REUNION » par « réunion » --- models.py | 1 + 1 file changed, 1 insertion(+) diff --git a/models.py b/models.py index 1aeb8e2..0b0ee63 100644 --- a/models.py +++ b/models.py @@ -163,6 +163,7 @@ class Course(models.Model): def save(self, *args, **kwargs): if self.type is not None: self.type = self.type.replace("COURS", "cours") + self.type = self.type.replace("REUNION", "réunion") if self.name is not None: self.name = self.name.split("(")[0].strip() -- cgit v1.2.1 From 0426214423e7a43c31d62ecd4e7d8f29cb65d251 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Tue, 5 Sep 2017 11:42:45 +0200 Subject: Re-correction de l’affichage des remarques --- templates/mail/mail_timetable.txt | 2 +- templates/timetable.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/mail/mail_timetable.txt b/templates/mail/mail_timetable.txt index 20da575..258db0c 100644 --- a/templates/mail/mail_timetable.txt +++ b/templates/mail/mail_timetable.txt @@ -1,6 +1,6 @@ {% load rooms %}{% autoescape off %}{% for day in courses %}{% filter title %}{{ day.0.begin|date:"l j F o" }}{% endfilter %} - de {{ day.0.begin|date:"H:i" }} à {% with day|last as last %}{{ last.end|date:"H:i" }}{% endwith %} {% for course in day %} * {{ course.name }} ({{ course.type }}), de {{ course.begin|date:"H:i" }} à {{ course.end|date:"H:i" }}{% if course.rooms.all|length > 0 %} - {{ course.rooms.all|format_rooms }}{% endif %}{% if course.notes != "" %} + {{ course.rooms.all|format_rooms }}{% endif %}{% if course.notes != "" and course.notes is not None %} Remarques : {{ course.notes }}{% endif %} {% endfor %}{% empty %}Aucun cours pour le groupe {{ group }} pendant la semaine {{ week }}. diff --git a/templates/timetable.html b/templates/timetable.html index ba673ce..149068d 100644 --- a/templates/timetable.html +++ b/templates/timetable.html @@ -11,7 +11,7 @@ -- cgit v1.2.1 From 3363152e79991c9a6d86da819b758dacab33b16a Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Tue, 5 Sep 2017 19:17:53 +0200 Subject: Squelette de syndication au format ICS --- feeds.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 feeds.py diff --git a/feeds.py b/feeds.py new file mode 100644 index 0000000..913e337 --- /dev/null +++ b/feeds.py @@ -0,0 +1,42 @@ +# Copyright (C) 2017 Alban Gruin +# +# celcatsanitizer 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. +# +# celcatsanitizer 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 celcatsanitizer; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +from django.contrib.syndication.views import Feed +from django.utils.feedgenerator import SyndicationFeed + +from icalendar import Calendar, Event + + +class IcalFeed(SyndicationFeed): + content_type = "text/calendar; charset=utf-8" + __ical_names = {"name": "summary", + "notes": "description", + "rooms": "location", + "begin": "dtbegin", + "end": "dtend"} + + def write(self, outfile, encoding): + calendar = Calendar() + calendar.add("version", "2.0") + + write_events(calendar) + outfile.write(calendar.to_ical()) + + def write_events(self, calendar): + for item in items: + event = Event() + for key, value in item.items(): + event.add(__ical_names[key], value) -- cgit v1.2.1 From e1899a300bca73bce70591ccd9a5386bb5152aa9 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Tue, 5 Sep 2017 19:30:32 +0200 Subject: Ne plante pas si jamais une variable n’a pas d’équivalent icalendar --- feeds.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/feeds.py b/feeds.py index 913e337..f3ccaf3 100644 --- a/feeds.py +++ b/feeds.py @@ -39,4 +39,5 @@ class IcalFeed(SyndicationFeed): for item in items: event = Event() for key, value in item.items(): - event.add(__ical_names[key], value) + if key in __ical_names: + event.add(__ical_names[key], value) -- cgit v1.2.1 From 88197b09b47911d38b7ca372d5d25e0f13d3ea10 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Tue, 5 Sep 2017 19:31:49 +0200 Subject: Ajout de la dépendance à icalendar dans le README --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 66aa100..0b03f56 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ celcatsanitizer est écrit en Python 3. Il dépend des bibliothèques suivantes * Django 1.11 * requests * BeautifulSoup4 + * icalendar Pour installer celcatsanitizer, il est possible d'utiliser git. @@ -38,7 +39,7 @@ Notez que cette étape n'est pas obligatoire #### Installation des dépendances -> $ pip install requests django beautifulsoup4 +> $ pip install requests django beautifulsoup4 icalendar Si vous utilisez PostgreSQL, vous allez avoir besoin du driver psycopg2 : -- cgit v1.2.1 From 492da9dc027a42384b286593c61e6951089bc013 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Tue, 5 Sep 2017 21:40:08 +0200 Subject: Correction de détails --- feeds.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/feeds.py b/feeds.py index f3ccaf3..4b42c47 100644 --- a/feeds.py +++ b/feeds.py @@ -20,7 +20,7 @@ from django.utils.feedgenerator import SyndicationFeed from icalendar import Calendar, Event -class IcalFeed(SyndicationFeed): +class IcalFeedGenerator(SyndicationFeed): content_type = "text/calendar; charset=utf-8" __ical_names = {"name": "summary", "notes": "description", @@ -32,12 +32,14 @@ class IcalFeed(SyndicationFeed): calendar = Calendar() calendar.add("version", "2.0") - write_events(calendar) + self.write_events(calendar) outfile.write(calendar.to_ical()) def write_events(self, calendar): - for item in items: + print(self.items) + for item in self.items: event = Event() - for key, value in item.items(): - if key in __ical_names: - event.add(__ical_names[key], value) + for key, value in self.__ical_names.items(): + if item.get(key) is not None: + event.add(value, item[key]) + calendar.add_component(event) -- cgit v1.2.1 From eea68427e8a84ceae7f41409bd07615af4490d2e Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Tue, 5 Sep 2017 22:48:25 +0200 Subject: Implémentation d’un flux ICS (icalendar) par groupe. Non testé avec un client ICS pour l’instant. --- feeds.py | 45 ++++++++++++++++++++++++++++++++++++++------- urls.py | 3 +++ 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/feeds.py b/feeds.py index 4b42c47..609d422 100644 --- a/feeds.py +++ b/feeds.py @@ -14,19 +14,24 @@ # with celcatsanitizer; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +from django.core.exceptions import ObjectDoesNotExist from django.contrib.syndication.views import Feed from django.utils.feedgenerator import SyndicationFeed from icalendar import Calendar, Event +from .models import Course, Group, Timetable +from .templatetags.rooms import format_rooms + +ICAL_NAMES = {"name": "summary", + "notes": "description", + "rooms": "location", + "begin": "dtbegin", + "end": "dtend"} + class IcalFeedGenerator(SyndicationFeed): content_type = "text/calendar; charset=utf-8" - __ical_names = {"name": "summary", - "notes": "description", - "rooms": "location", - "begin": "dtbegin", - "end": "dtend"} def write(self, outfile, encoding): calendar = Calendar() @@ -36,10 +41,36 @@ class IcalFeedGenerator(SyndicationFeed): outfile.write(calendar.to_ical()) def write_events(self, calendar): - print(self.items) for item in self.items: event = Event() - for key, value in self.__ical_names.items(): + for key, value in ICAL_NAMES.items(): if item.get(key) is not None: event.add(value, item[key]) calendar.add_component(event) + + +class IcalFeed(Feed): + feed_type = IcalFeedGenerator + link = "" + + def get_object(self, request, timetable_slug, group_slug): + try: + timetable = Timetable.objects.get(slug=timetable_slug) + group = Group.objects.get(timetable=timetable, slug=group_slug) + except: + raise ObjectDoesNotExist + else: + return group + + def item_link(self, item): + return "" + + def items(self, obj): + return Course.objects.get_courses_for_group(obj).order_by("begin") + + def item_extra_kwargs(self, item): + return {"begin": item.begin, + "end": item.end, + "name": item.name, + "notes": item.notes, + "rooms": format_rooms(item.rooms.all())} diff --git a/urls.py b/urls.py index 5557612..3faa78d 100644 --- a/urls.py +++ b/urls.py @@ -15,13 +15,16 @@ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. from django.conf.urls import url + from . import views +from .feeds import IcalFeed urlpatterns = [ url(r"^$", views.index, name="index"), url(r"^(?P[-\w]+)/(?P[-\w]+)/$", views.timetable, name="timetable"), url(r"^(?P[-\w]+)/(?P[-\w]+)/(?P[0-9]{4})/(?P[0-4]?[0-9]|5[0-3])/$", views.timetable, name="timetable"), url(r"^(?P[-\w]+)/(?P[-\w]+)/(?P[0-9]{4})/(?P[0-4]?[0-9]|5[0-3])/subscribe$", views.subscribe, name="subscribe"), + url(r"^(?P[-\w]+)/(?P[-\w]+)/calendar.ics$", IcalFeed(), name="ics"), url(r"^subscriptions/confirm/(?P[0-9a-f]{40})$", views.confirm_subscription, name="confirm"), url(r"^subscriptions/cancel/(?P[0-9a-f]{40})$", views.cancel_subscription, name="cancel"), ] -- cgit v1.2.1 From 493bbe8ac06a530ca02452da719258e2ad306c82 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Tue, 5 Sep 2017 22:54:57 +0200 Subject: dtstart, pas dtbegin. Fonctionnalitée testée avec succès sur Lightning. --- feeds.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feeds.py b/feeds.py index 609d422..e97c29a 100644 --- a/feeds.py +++ b/feeds.py @@ -26,7 +26,7 @@ from .templatetags.rooms import format_rooms ICAL_NAMES = {"name": "summary", "notes": "description", "rooms": "location", - "begin": "dtbegin", + "begin": "dtstart", "end": "dtend"} -- cgit v1.2.1 From 36757e937abd7d5aa3434f4c815dfb040e1e3a71 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Wed, 6 Sep 2017 11:46:37 +0200 Subject: Simplification du code icalendar --- feeds.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/feeds.py b/feeds.py index e97c29a..72d7873 100644 --- a/feeds.py +++ b/feeds.py @@ -23,11 +23,7 @@ from icalendar import Calendar, Event from .models import Course, Group, Timetable from .templatetags.rooms import format_rooms -ICAL_NAMES = {"name": "summary", - "notes": "description", - "rooms": "location", - "begin": "dtstart", - "end": "dtend"} +ICAL_NAMES = ["summary", "description", "location", "start", "dtstart", "dtend"] class IcalFeedGenerator(SyndicationFeed): @@ -43,9 +39,9 @@ class IcalFeedGenerator(SyndicationFeed): def write_events(self, calendar): for item in self.items: event = Event() - for key, value in ICAL_NAMES.items(): + for key in ICAL_NAMES: if item.get(key) is not None: - event.add(value, item[key]) + event.add(key, item[key]) calendar.add_component(event) @@ -62,6 +58,9 @@ class IcalFeed(Feed): else: return group + def item_description(self, item): + return item.notes + def item_link(self, item): return "" @@ -69,8 +68,7 @@ class IcalFeed(Feed): return Course.objects.get_courses_for_group(obj).order_by("begin") def item_extra_kwargs(self, item): - return {"begin": item.begin, - "end": item.end, - "name": item.name, - "notes": item.notes, - "rooms": format_rooms(item.rooms.all())} + return {"dtstart": item.begin, + "dtend": item.end, + "summary": item.name, + "location": format_rooms(item.rooms.all())} -- cgit v1.2.1 From 1561cb829a48d49d36242db89fa4490144767065 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Thu, 7 Sep 2017 17:02:27 +0200 Subject: Séparation de l’année et de la mention dans le modèle Timetable --- admin.py | 4 ++-- models.py | 10 ++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/admin.py b/admin.py index 2408623..ca2fed9 100644 --- a/admin.py +++ b/admin.py @@ -20,8 +20,8 @@ from .models import Timetable, LastUpdate, Group, Subscription, Room, Course @admin.register(Timetable) class TimetableAdmin(admin.ModelAdmin): - prepopulated_fields = {"slug": ("name",)} - list_display = ("name", "url",) + prepopulated_fields = {"slug": ("year", "name",)} + list_display = ("full_name", "url",) @admin.register(LastUpdate) diff --git a/models.py b/models.py index 0b0ee63..61e7f6c 100644 --- a/models.py +++ b/models.py @@ -26,15 +26,21 @@ import os class Timetable(models.Model): - name = models.CharField(max_length=64, unique=True, verbose_name="nom") + year = models.CharField(max_length=16, verbose_name="année") + name = models.CharField(max_length=64, verbose_name="nom") url = models.URLField(max_length=255, unique=True, verbose_name="URL") slug = models.SlugField(max_length=64, unique=True, default="") def __str__(self): - return self.name + return self.full_name() + + def full_name(self): + return self.year + " " + self.name + full_name.short_description = "Nom complet" class Meta: + unique_together = ("year", "name",) verbose_name = "emploi du temps" verbose_name_plural = "emplois du temps" -- cgit v1.2.1 From dc272aad09f15273a930345f33943580b2a8a1f3 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Thu, 7 Sep 2017 19:54:03 +0200 Subject: Ajout d’un champ permettant de stocker la date de mise à jour du calendrier celcat dans le modèle LastUpdate, ainsi que de quoi la lire depuis le XML --- management/commands/_private.py | 25 +++++++++++++++++++++++++ models.py | 2 ++ 2 files changed, 27 insertions(+) diff --git a/management/commands/_private.py b/management/commands/_private.py index c31eb34..f7f8435 100644 --- a/management/commands/_private.py +++ b/management/commands/_private.py @@ -21,6 +21,8 @@ from edt.models import Group, Room, Course from edt.utils import get_week import datetime +import re + import requests @@ -122,6 +124,29 @@ def get_events(timetable, year, week, soup, weeks_in_soup): yield title, type_, groups, rooms, notes, begin, end +def get_update_date(soup): + # Explication de la regex + # + # (\d+)/(\d+)/(\d+)\s+(\d+):(\d+):(\d+) + # (\d+) au moins un nombre + # / un slash + # (\d+) au moins un nombre + # / un slash + # (\d+) au moins un nombre + # \s+ au moins un espace + # (\d+) au moins un nombre + # : un deux-points + # (\d+) au moins un nombre + # : un deux-points + # (\d+) au moins un nombre + datetime_regex = re.compile("(\d+)/(\d+)/(\d+)\s+(\d+):(\d+):(\d+)") + search = datetime_regex.search(soup.footer.text) + if search is None: + return None + + day, month, year, hour, minute, second = [int(v) for v in search.groups()] + return datetime.datetime(year, month, day, hour, minute, second) + def get_weeks(soup): weeks = {} for span in soup.find_all("span"): diff --git a/models.py b/models.py index 61e7f6c..01819d6 100644 --- a/models.py +++ b/models.py @@ -51,6 +51,8 @@ class LastUpdate(models.Model): year = models.IntegerField(verbose_name="année") date = models.DateTimeField(verbose_name="date de mise à jour") + updated_at = models.DateTimeField(verbose_name="date de publication", null=True) + def __str__(self): return "{0}, semaine {1} de {2}".format(self.timetable.name, self.week, self.year) -- cgit v1.2.1 From 43abb9e5746803bf2b415904d11c68f5a3d56720 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Thu, 7 Sep 2017 19:55:30 +0200 Subject: Remplacement des trois points (...) par de vrais points de suspension (…) --- utils.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/utils.py b/utils.py index 8630036..26bad17 100644 --- a/utils.py +++ b/utils.py @@ -53,9 +53,9 @@ def parse_group(name): # ^ début de la ligne # ([\w ]+?) correspond à au moins un caractère # (\s* zéro, un ou plusieurs espaces - # (((CM)(\w))| correspond à CM suivi d'une lettre ou... - # ((TD)(\w)(\d))| ... à TD suivi d’une lettre et d'un chiffre ou... - # ((TP)(\w)(\d)(\d))) ... à TP suivi d’une lettre et de deux chiffres + # (((CM)(\w))| correspond à CM suivi d'une lettre ou… + # ((TD)(\w)(\d))| … à TD suivi d’une lettre et d'un chiffre ou… + # ((TP)(\w)(\d)(\d))) … à TP suivi d’une lettre et de deux chiffres # )? groupe optionel # $ fin de la ligne group_regex = re.compile("^([\w ]+?)(\s*(((CM)(\w))|((TD)(\w)(\d))|((TP)(\w)(\d)(\d))))?$") -- cgit v1.2.1 From bd236d267bfa6857d062733899ca6db5231ddd1d Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Thu, 7 Sep 2017 20:04:10 +0200 Subject: On rend la date de MàJ retournée au courant de la tz --- management/commands/_private.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/management/commands/_private.py b/management/commands/_private.py index f7f8435..d54d81b 100644 --- a/management/commands/_private.py +++ b/management/commands/_private.py @@ -145,7 +145,8 @@ def get_update_date(soup): return None day, month, year, hour, minute, second = [int(v) for v in search.groups()] - return datetime.datetime(year, month, day, hour, minute, second) + date = datetime.datetime(year, month, day, hour, minute, second) + return timezone.make_aware(date) def get_weeks(soup): weeks = {} -- cgit v1.2.1 From 1a605b7390fadd1ad65128590aca9d30743a0510 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Thu, 7 Sep 2017 20:22:55 +0200 Subject: On ne parse pas le contenu de l’emploi du temps si la date de mise à jour est égale ou inférieure à celle stockée en base de données. --- management/commands/timetables.py | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/management/commands/timetables.py b/management/commands/timetables.py index d596233..7f33be1 100644 --- a/management/commands/timetables.py +++ b/management/commands/timetables.py @@ -17,16 +17,29 @@ from django.core.management.base import BaseCommand from django.db import transaction from django.utils import timezone -from edt.models import Timetable, LastUpdate, Course -from ._private import delete_courses_in_week, get_events, get_weeks, get_xml +from edt.models import Timetable, LastUpdate, Course +from ._private import delete_courses_in_week, get_events, get_update_date, get_weeks, get_xml import datetime @transaction.atomic def process_timetable_week(timetable, year, week, soup, weeks_in_soup): + last_update_date = None + new_update_date = get_update_date(soup) + try: + last_update = LastUpdate.objects.get(timetable=timetable, year=year, week=week) + last_update_date = last_update.updated_at + except: + last_update = LastUpdate.objects(timetable=timetable, year=year, week=week) + + if last_update_date is not None and new_update_date is not None and \ + last_update_date >= new_update_date: + return + delete_courses_in_week(timetable, year, week) - for name, type_, groups, rooms, notes, begin, end in get_events(timetable, year, week, soup, weeks_in_soup): + for name, type_, groups, rooms, notes, begin, end in \ + get_events(timetable, year, week, soup, weeks_in_soup): course = Course.objects.create(timetable=timetable, begin=begin, end=end) course.name = name course.type = type_ @@ -38,14 +51,9 @@ def process_timetable_week(timetable, year, week, soup, weeks_in_soup): course.save() - date = timezone.make_aware(datetime.datetime.now()) - try: - last_update = LastUpdate.objects.get(timetable=timetable, year=year, week=week) - last_update.date = date - except: - last_update = LastUpdate(timetable=timetable, year=year, week=week, date=date) - finally: - last_update.save() + last_update.date = timezone.make_aware(datetime.datetime.now()) + last_update.updated_at = new_update_date + last_update.save() def process_timetable(timetable, year, weeks): soup = get_xml(timetable.url) -- cgit v1.2.1 From 702ed90e13396bd999079d22f03a40e4daf93a54 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Thu, 7 Sep 2017 20:28:48 +0200 Subject: Correction de la création de l’objet LastUpdate --- management/commands/timetables.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/management/commands/timetables.py b/management/commands/timetables.py index 7f33be1..64dd6f6 100644 --- a/management/commands/timetables.py +++ b/management/commands/timetables.py @@ -31,7 +31,7 @@ def process_timetable_week(timetable, year, week, soup, weeks_in_soup): last_update = LastUpdate.objects.get(timetable=timetable, year=year, week=week) last_update_date = last_update.updated_at except: - last_update = LastUpdate.objects(timetable=timetable, year=year, week=week) + last_update = LastUpdate(timetable=timetable, year=year, week=week) if last_update_date is not None and new_update_date is not None and \ last_update_date >= new_update_date: -- cgit v1.2.1 From a79e87a3ecfd505846c04f7949b1036a102430ed Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Thu, 7 Sep 2017 20:56:22 +0200 Subject: Affichage du champ updated_at dans l’interface d’administration --- admin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin.py b/admin.py index ca2fed9..fba80c6 100644 --- a/admin.py +++ b/admin.py @@ -26,7 +26,7 @@ class TimetableAdmin(admin.ModelAdmin): @admin.register(LastUpdate) class LastUpdateAdmin(admin.ModelAdmin): - list_display = ("timetable", "week", "year", "date",) + list_display = ("timetable", "week", "year", "date", "updated_at",) list_filter = ("timetable__name",) -- cgit v1.2.1 From f18b2cc4f4aa7b2ed2d7801c19ddf75acbb6abc2 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Thu, 7 Sep 2017 22:22:46 +0200 Subject: Remplacement de la page d’acceuil par la liste des années, menant sur une liste de mentions, puis une liste de groupes, etc etc. --- templates/index.html | 18 +++++++++++------- templates/mention_list.html | 14 ++++++++++++++ templates/timetables_list.html | 9 +++++++++ urls.py | 7 +++---- views.py | 11 ++++++++++- 5 files changed, 47 insertions(+), 12 deletions(-) create mode 100644 templates/mention_list.html create mode 100644 templates/timetables_list.html diff --git a/templates/index.html b/templates/index.html index d834884..09bb0f6 100644 --- a/templates/index.html +++ b/templates/index.html @@ -58,13 +58,17 @@ li.course {

celcatsanitizer

-
{% block body %}{% for timetable in timetables %} -
-

{{ timetable.name }}

-
    {% for group in groups %}{% if group.timetable.id == timetable.id %} -
  • {{ group.name }} – {% for week in group.weeks %}{{ week|dt_prettyprint }} {% empty %}aucun cours{% endfor %}
  • {% endif %}{% endfor %} -
-
{% endfor %}{% endblock %} +
+ {% block body %} +

Choisissez votre année

+
    + {% for year in years %} +
  • {{ year.year }} ({{ year.count }})
  • + {% empty %} +

    Aucun emploi du temps à afficher

    + {% endfor %} +
+ {% endblock %}