From e9ec8bdb5dfcb5735bec4a00611e69ad768181c0 Mon Sep 17 00:00:00 2001
From: Alban Gruin
Date: Sun, 12 Feb 2017 14:28:14 +0100
Subject: Modification du README
---
README.md | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/README.md b/README.md
index afa2b35..93cee88 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,7 @@ Pour tester celcatsanitizer, il est recommandé d'utiliser SQLite ou PostgreSQL.
Pour la production, il est recommandé d'utiliser PostgreSQL (avec le driver psycopg2) et de mettre le tout dans un environnement virtuel.
-Aucun autre SGBD n'a été testé aujourd'hui. Toute modification visant à faire fonctionner celcatsanitizer avec un autre SGBD sera bien entendu acceptée.
+Aucun autre SGBD n'a été testé. Toute modification visant à faire fonctionner celcatsanitizer avec un autre SGBD sera bien entendu acceptée.
### Installation
Il est préférable d'utiliser un environnement virtuel, mais ce n'est pas obligatoire. Si vous ne souhaitez pas utiliser un environnement virtuel, passez directement à l'installation des dépendances.
@@ -74,8 +74,6 @@ Dans le fichier celcatsanitizer/settings.py, vous devrez renseigner plusieurs in
##### Configuration du serveur mail
[Vous pouvez trouver la documentation concernant l'envoi des mails sur le site de Django.](https://docs.djangoproject.com/fr/1.10/topics/email/)
-Pour l'instant, la désactivation des mails n'est pas encore supporté.
-
##### Configuration des administrateurs
[Vous pouvez retrouver la documentation de la variable ADMIN sur le site de Django.](https://docs.djangoproject.com/fr/1.10/ref/settings/#admins)
--
cgit v1.2.1
From d91081d8539988aaca426022c3f28ad78a024bea Mon Sep 17 00:00:00 2001
From: Alban Gruin
Date: Mon, 13 Feb 2017 12:25:18 +0100
Subject: Ajout d'un mail pour signaler l'absence de cours pendant la semaine
---
management/commands/sendmails.py | 20 +++++++++++---------
templates/mail/mail_noevent.txt | 2 ++
2 files changed, 13 insertions(+), 9 deletions(-)
create mode 100644 templates/mail/mail_noevent.txt
diff --git a/management/commands/sendmails.py b/management/commands/sendmails.py
index 5a2054f..e30bb1b 100644
--- a/management/commands/sendmails.py
+++ b/management/commands/sendmails.py
@@ -38,7 +38,10 @@ class Command(BaseCommand):
subscriptions = Subscription.objects.filter(active=True)
content = {}
mails = []
+
footer = loader.get_template("mail/mail_footer.txt")
+ no_event = loader.get_template("mail/mail_noevent.txt")
+ timetable = loader.get_template("mail/mail_timetable.txt")
print("Generating messages...")
for subscription in subscriptions:
@@ -47,16 +50,15 @@ class Command(BaseCommand):
if len(courses) > 0:
grouped_courses = group_courses(courses)
+ context = Context({"courses": grouped_courses, "week": week})
+ content[subscription.group.id] = timetable.render(context)
+ else:
+ context = Context({"group": subscription.group, "week": week})
+ content[subscription.group.id] = no_event.render(context)
- template = loader.get_template("mail/mail_timetable.txt")
- context = Context({"subscription": subscription, "courses": grouped_courses, "week": week})
- content[subscription.group.id] = template.render(context)
-
- if subscription.group.id in content:
- context = Context({"admins": settings.ADMINS, "token": subscription.token, "domain": settings.DEFAULT_DOMAIN})
- mail_content = content[subscription.group.id] + footer.render(context)
-
- mails.append(("{0} - {1} - Semaine {2}".format(subscription.group.timetable.name, subscription.group.name, week), mail_content, settings.DEFAULT_FROM_EMAIL, [subscription.email],))
+ context = Context({"admins": settings.ADMINS, "token": subscription.token, "domain": settings.DEFAULT_DOMAIN})
+ mail_content = content[subscription.group.id] + footer.render(context)
+ mails.append(("{0} - {1} - Semaine {2}".format(subscription.group.timetable.name, subscription.group.name, week), mail_content, settings.DEFAULT_FROM_EMAIL, [subscription.email],))
print("Sending mails...")
send_mass_mail(mails)
diff --git a/templates/mail/mail_noevent.txt b/templates/mail/mail_noevent.txt
new file mode 100644
index 0000000..dc01189
--- /dev/null
+++ b/templates/mail/mail_noevent.txt
@@ -0,0 +1,2 @@
+Aucun cours pour le groupe {{ group }} pendant la semaine {{ week }}.
+
--
cgit v1.2.1
From de405f2212fa64ad2a6a11f6d18186571021ad8c Mon Sep 17 00:00:00 2001
From: Alban Gruin
Date: Mon, 13 Feb 2017 19:39:41 +0100
Subject: Regroupement des deux mails d'emploi du temps dans une seule
template, c'est plus propre
---
management/commands/sendmails.py | 11 +++--------
templates/mail/mail_noevent.txt | 2 --
templates/mail/mail_timetable.txt | 2 +-
3 files changed, 4 insertions(+), 11 deletions(-)
delete mode 100644 templates/mail/mail_noevent.txt
diff --git a/management/commands/sendmails.py b/management/commands/sendmails.py
index e30bb1b..9a05a9c 100644
--- a/management/commands/sendmails.py
+++ b/management/commands/sendmails.py
@@ -40,7 +40,6 @@ class Command(BaseCommand):
mails = []
footer = loader.get_template("mail/mail_footer.txt")
- no_event = loader.get_template("mail/mail_noevent.txt")
timetable = loader.get_template("mail/mail_timetable.txt")
print("Generating messages...")
@@ -48,13 +47,9 @@ class Command(BaseCommand):
if subscription.group.id not in content:
courses = Course.objects.get_courses_for_group(subscription.group, begin__gte=start, begin__lt=end)
- if len(courses) > 0:
- grouped_courses = group_courses(courses)
- context = Context({"courses": grouped_courses, "week": week})
- content[subscription.group.id] = timetable.render(context)
- else:
- context = Context({"group": subscription.group, "week": week})
- content[subscription.group.id] = no_event.render(context)
+ grouped_courses = group_courses(courses)
+ context = Context({"courses": grouped_courses, "group": subscription.group, "week": week})
+ content[subscription.group.id] = timetable.render(context)
context = Context({"admins": settings.ADMINS, "token": subscription.token, "domain": settings.DEFAULT_DOMAIN})
mail_content = content[subscription.group.id] + footer.render(context)
diff --git a/templates/mail/mail_noevent.txt b/templates/mail/mail_noevent.txt
deleted file mode 100644
index dc01189..0000000
--- a/templates/mail/mail_noevent.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Aucun cours pour le groupe {{ group }} pendant la semaine {{ week }}.
-
diff --git a/templates/mail/mail_timetable.txt b/templates/mail/mail_timetable.txt
index 65b5c01..06a2b1c 100644
--- a/templates/mail/mail_timetable.txt
+++ b/templates/mail/mail_timetable.txt
@@ -2,5 +2,5 @@
{% 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 %}
Salle{% if course.rooms.all|length > 1 %}s{% endif %} {% for room in course.rooms.all %}{{ room }} {% endfor %}{% endif %}
-{% endfor %}
+{% endfor %}{% empty %}Aucun cours pour le groupe {{ group }} pendant la semaine {{ week }}.
{% endfor %}{% endautoescape %}
--
cgit v1.2.1
From cd004bdf1144b27bcb4de1f4ffd750b6eefcb477 Mon Sep 17 00:00:00 2001
From: Alban Gruin
Date: Tue, 21 Feb 2017 09:20:05 +0100
Subject: Ajout d'une ligne vide entre les différents jours
---
templates/mail/mail_timetable.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/templates/mail/mail_timetable.txt b/templates/mail/mail_timetable.txt
index 06a2b1c..a14ce9a 100644
--- a/templates/mail/mail_timetable.txt
+++ b/templates/mail/mail_timetable.txt
@@ -2,5 +2,6 @@
{% 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 %}
Salle{% if course.rooms.all|length > 1 %}s{% endif %} {% for room in course.rooms.all %}{{ room }} {% endfor %}{% endif %}
+
{% endfor %}{% empty %}Aucun cours pour le groupe {{ group }} pendant la semaine {{ week }}.
{% endfor %}{% endautoescape %}
--
cgit v1.2.1
From cc479941c95fc487d1bbe8ed49af825177c55a81 Mon Sep 17 00:00:00 2001
From: Alban Gruin
Date: Sun, 26 Feb 2017 21:38:08 +0100
Subject: Différentes améliorations concernant l'affichage des emplois du temps
- Affichage des remarques concernant les cours sur les emplois du temps et
dans les mails - Meilleur formatage des salles - Meilleure gestion des
retours à la ligne dans les mails
---
templates/mail/mail_timetable.txt | 8 ++++----
templates/timetable.html | 3 ++-
templatetags/rooms.py | 27 +++++++++++++++++++++++++++
3 files changed, 33 insertions(+), 5 deletions(-)
create mode 100644 templatetags/rooms.py
diff --git a/templates/mail/mail_timetable.txt b/templates/mail/mail_timetable.txt
index a14ce9a..f6b8364 100644
--- a/templates/mail/mail_timetable.txt
+++ b/templates/mail/mail_timetable.txt
@@ -1,7 +1,7 @@
-{% 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 %}
- Salle{% if course.rooms.all|length > 1 %}s{% endif %} {% for room in course.rooms.all %}{{ room }} {% endfor %}{% endif %}
+{% 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 %}
+ Remarques : {{ course.notes }}{% endif %}
{% endfor %}{% empty %}Aucun cours pour le groupe {{ group }} pendant la semaine {{ week }}.
{% endfor %}{% endautoescape %}
diff --git a/templates/timetable.html b/templates/timetable.html
index 0d3432c..78dcfed 100644
--- a/templates/timetable.html
+++ b/templates/timetable.html
@@ -1,4 +1,5 @@
{% extends "index.html" %}
+{% load rooms %}
{% block title %}{{ group.timetable.name }} – {{ group.name }} – Semaine {{ week }} – {% endblock %}
@@ -8,7 +9,7 @@
{% 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 %}
Salle{% if course.rooms.all|length > 1 %}s{% endif %} {% for room in course.rooms.all %}{{ room }} {% endfor %}{% endif %} {% endfor %}
+ - {{ 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 %}
Remarques : {{ course.notes }}{% endif %} {% endfor %}
{% endfor %}
S'abonner à cet emploi du temps
{% endblock %}
diff --git a/templatetags/rooms.py b/templatetags/rooms.py
new file mode 100644
index 0000000..d76f0ee
--- /dev/null
+++ b/templatetags/rooms.py
@@ -0,0 +1,27 @@
+# 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 import template
+
+register = template.Library()
+
+@register.filter
+def format_rooms(rooms):
+ joined = ", ".join([str(room) for room in rooms])
+ if len(rooms) > 1:
+ return "Salles {0}".format(joined)
+ else:
+ return "Salle {0}".format(joined)
--
cgit v1.2.1
From 0649ee9c528d7a3957fb65e195a4a56a702e8d48 Mon Sep 17 00:00:00 2001
From: Alban Gruin
Date: Sun, 26 Feb 2017 22:08:08 +0100
Subject: Ajout du paramètre --test à la commande sendmails pour afficher les
mails au lieu de les envoyer
---
management/commands/sendmails.py | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/management/commands/sendmails.py b/management/commands/sendmails.py
index 9a05a9c..b53d6f9 100644
--- a/management/commands/sendmails.py
+++ b/management/commands/sendmails.py
@@ -29,6 +29,9 @@ import datetime
class Command(BaseCommand):
help = "Sends emails to subscribed users"
+ def add_arguments(self, parser):
+ parser.add_argument("--test", help="Print the content of mails instead of sending them", action="store_true")
+
def handle(self, *args, **options):
translation.activate(settings.LANGUAGE_CODE)
@@ -51,10 +54,17 @@ class Command(BaseCommand):
context = Context({"courses": grouped_courses, "group": subscription.group, "week": week})
content[subscription.group.id] = timetable.render(context)
- context = Context({"admins": settings.ADMINS, "token": subscription.token, "domain": settings.DEFAULT_DOMAIN})
- mail_content = content[subscription.group.id] + footer.render(context)
- mails.append(("{0} - {1} - Semaine {2}".format(subscription.group.timetable.name, subscription.group.name, week), mail_content, settings.DEFAULT_FROM_EMAIL, [subscription.email],))
+ if options["test"]:
+ print(subscription.group)
+ print(content[subscription.group.id])
+
+ if not options["test"]:
+ context = Context({"admins": settings.ADMINS, "token": subscription.token, "domain": settings.DEFAULT_DOMAIN})
+ mail_content = content[subscription.group.id] + footer.render(context)
+ mails.append(("{0} - {1} - Semaine {2}".format(subscription.group.timetable.name, subscription.group.name, week), mail_content, settings.DEFAULT_FROM_EMAIL, [subscription.email],))
+
+ if not options["test"]:
+ print("Sending mails...")
+ send_mass_mail(mails)
- print("Sending mails...")
- send_mass_mail(mails)
self.stdout.write(self.style.SUCCESS("Done."))
--
cgit v1.2.1
From 60092220ca3c47a20f50b677a2bb2173ae3f89a3 Mon Sep 17 00:00:00 2001
From: Alban Gruin
Date: Mon, 27 Feb 2017 09:52:08 +0100
Subject: Parsage du nom des groupes basé sur une regex pour éviter les
problèmes liés à l'ancienne méthode
---
models.py | 22 +++++-----------------
utils.py | 15 +++++++++++++++
2 files changed, 20 insertions(+), 17 deletions(-)
diff --git a/models.py b/models.py
index 1e96a88..478b48f 100644
--- a/models.py
+++ b/models.py
@@ -20,6 +20,8 @@ from django.db.models.expressions import RawSQL
from django.db.models.functions import Extract, ExtractYear
from django.utils.text import slugify
+from .utils import parse_group
+
import hashlib
import os
@@ -81,23 +83,9 @@ class Group(models.Model):
return self.name
def save(self, *args, **kwargs):
- try:
- parts = self.celcat_name.split("-")[-2:]
- group = parts[1].strip()[2:]
-
- self.mention = parts[0].strip()
- self.subgroup = group[0]
-
- if len(group) > 1:
- self.td = int(group[1])
- if len(group) > 2:
- self.tp = int(group[2])
- except:
- print("Malformed name: {0}. Ignoring".format(self.celcat_name))
- finally:
- if self.name == "":
- self.name = self.celcat_name
-
+ self.mention, self.subgroup, self.td, self.tp = parse_group(self.celcat_name)
+ if self.name == "":
+ self.name = self.celcat_name
self.slug = slugify(self.name)
super(Group, self).save()
diff --git a/utils.py b/utils.py
index 4ce3a21..090142b 100644
--- a/utils.py
+++ b/utils.py
@@ -17,6 +17,7 @@
from django.utils import timezone
import datetime
+import re
def get_current_week():
return timezone.now().isocalendar()[:2]
@@ -44,3 +45,17 @@ def group_courses(courses):
grouped_courses[-1].append(course)
return grouped_courses
+
+def parse_group(name):
+ group_regex = re.compile("^(.+?)\s*\-\s*(((CM)(\w))|((TD)(\w)(\d))|((TP)(\w)(\d)(\d)))$")
+ search = group_regex.search(name)
+ if search is None:
+ return None, None, None, None
+
+ parts = search.groups(0)
+ if parts[3] == "CM":
+ return parts[0], parts[4], None, None
+ elif parts[6] == "TD":
+ return parts[0], parts[7], parts[8], None
+ elif parts[10] == "TP":
+ return parts[0], parts[11], parts[12], parts[13]
--
cgit v1.2.1
From 1511f5755ff98c15ed3b5a882ae5d24f399a03af Mon Sep 17 00:00:00 2001
From: Alban Gruin
Date: Mon, 27 Feb 2017 10:41:40 +0100
Subject: Modification du README
---
README.md | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/README.md b/README.md
index 93cee88..ece8601 100644
--- a/README.md
+++ b/README.md
@@ -60,13 +60,7 @@ SQLite n'a pas besoin de driver.
> $ git clone https://git.pa1ch.fr/alban/celcatsanitizer.git edt
-Pour la production, il est recommandé d'utiliser une version stable, accessibles à travers les tags git :
-
-> $ cd edt
-
-> $ git checkout v0.4.0
-
-> $ cd ..
+Pour la production, il est recommandé d'utiliser une version stable, accessibles à travers les tags git.
#### Configuration de Django
Dans le fichier celcatsanitizer/settings.py, vous devrez renseigner plusieurs informations.
@@ -104,9 +98,14 @@ Vous avez besoin de générer les migrations de celcatsanitizer, puis appliquez-
> $ ./manage.py migrate
+##### Gestion des fichiers statiques
+Si vous êtes en production, vous devez renseigner l'emplacement de vos fichiers statiques dans la variable [STATIC_ROOT](https://docs.djangoproject.com/fr/1.10/ref/settings/#std:setting-STATIC_ROOT) de la configuration de Django, puis exécuter la commande suivante :
+
+> $ ./manage.py collectstatic
+
### Lancement de celcatsanitizer
Si vous êtes en mode de débuggage, lancez le serveur de cette manière :
> $ ./manage.py runserver
-Si vous êtes en production, il n'est pas recommandé d'utiliser ce serveur. Exécutez Django avec le module mod_wsgi d'Apache, ou avec le serveur gunicorn, derrière un serveur nginx.
+Si vous êtes en production, il n'est pas recommandé d'utiliser ce serveur. Exécutez Django avec le module mod_wsgi d'Apache, ou avec un serveur [gunicorn](http://gunicorn.org/) derrière nginx.
--
cgit v1.2.1
From ba7d2e5c5a78170fa178cd6f9a07a35ec385b63a Mon Sep 17 00:00:00 2001
From: Alban Gruin
Date: Mon, 27 Feb 2017 10:56:54 +0100
Subject: Léger reformatage
---
management/commands/_private.py | 15 +++++++++------
management/commands/timetables.py | 2 +-
2 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/management/commands/_private.py b/management/commands/_private.py
index f14dae6..5b4a7ff 100644
--- a/management/commands/_private.py
+++ b/management/commands/_private.py
@@ -27,7 +27,8 @@ import requests
class Week:
def __init__(self, number, start):
self.number = number
- self.start = timezone.make_aware(datetime.datetime.strptime(start, "%d/%m/%Y"))
+ self.start = timezone.make_aware(
+ datetime.datetime.strptime(start, "%d/%m/%Y"))
def get_day(self, id):
return self.start + datetime.timedelta(id)
@@ -58,7 +59,7 @@ def get_from_db_or_create(cls, timetable=None, **kwargs):
return obj
-def get_events(soup, weeks, year, week, timetable):
+def get_events(timetable, year, week, soup, weeks_in_soup):
for event in soup.find_all("event"):
title = None
type_ = None
@@ -66,11 +67,12 @@ def get_events(soup, weeks, year, week, timetable):
rooms = None
notes = None
- if weeks[event.rawweeks.text].number == week and \
- weeks[event.rawweeks.text].year == year and \
+ if weeks_in_soup[event.rawweeks.text].number == week and \
+ weeks_in_soup[event.rawweeks.text].year == year and \
event.resources.group is not None and \
event.starttime is not None and event.endtime is not None:
- date = weeks[event.rawweeks.text].get_day(int(event.day.text))
+ date = weeks_in_soup[event.rawweeks.text].get_day(int(
+ event.day.text))
begin = add_time(date, datetime.datetime.strptime(
event.starttime.text, "%H:%M"))
@@ -104,7 +106,8 @@ def get_events(soup, weeks, year, week, timetable):
def get_weeks(soup):
weeks = {}
for span in soup.find_all("span"):
- weeks[span.alleventweeks.text] = Week(int(span.title.text), span["date"])
+ weeks[span.alleventweeks.text] = Week(int(span.title.text),
+ span["date"])
return weeks
diff --git a/management/commands/timetables.py b/management/commands/timetables.py
index 88d9008..50256db 100644
--- a/management/commands/timetables.py
+++ b/management/commands/timetables.py
@@ -29,7 +29,7 @@ import requests
@transaction.atomic
def process_timetable_week(timetable, year, week, soup, weeks_in_soup):
delete_courses_in_week(timetable, year, week)
- for name, type_, groups, rooms, notes, begin, end in get_events(soup, weeks_in_soup, year, week, timetable):
+ 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_
--
cgit v1.2.1
From a9f2d9a4c736511235140f362ab33eb7da0cda61 Mon Sep 17 00:00:00 2001
From: Alban Gruin
Date: Mon, 27 Feb 2017 11:14:26 +0100
Subject: Nettoyage des imports
---
management/commands/sendmails.py | 8 +++-----
management/commands/timetables.py | 9 +++------
templatetags/dt_week.py | 2 --
urls.py | 3 +--
views.py | 5 -----
5 files changed, 7 insertions(+), 20 deletions(-)
diff --git a/management/commands/sendmails.py b/management/commands/sendmails.py
index b53d6f9..c7725b7 100644
--- a/management/commands/sendmails.py
+++ b/management/commands/sendmails.py
@@ -14,17 +14,15 @@
# with celcatsanitizer; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import BaseCommand
from django.core.mail import send_mass_mail
-from django.utils import timezone, translation
+from django.utils import translation
from django.template import Context, loader
from django.conf import settings
-from edt.models import Group, Subscription, Course
+from edt.models import Course, Subscription
from edt.utils import get_current_or_next_week, get_week, group_courses
-import datetime
-
class Command(BaseCommand):
help = "Sends emails to subscribed users"
diff --git a/management/commands/timetables.py b/management/commands/timetables.py
index 50256db..d39075d 100644
--- a/management/commands/timetables.py
+++ b/management/commands/timetables.py
@@ -14,17 +14,14 @@
# with celcatsanitizer; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import BaseCommand
from django.db import transaction
from django.utils import timezone
-from edt.models import Timetable, LastUpdate, Group, Room, Course
+from edt.models import Timetable, LastUpdate, Course
-from bs4 import BeautifulSoup
-
-from ._private import delete_courses_in_week, get_events, get_weeks, get_xml, Week
+from ._private import delete_courses_in_week, get_events, get_weeks, get_xml
import datetime
-import requests
@transaction.atomic
def process_timetable_week(timetable, year, week, soup, weeks_in_soup):
diff --git a/templatetags/dt_week.py b/templatetags/dt_week.py
index 97d9b8b..eae5523 100644
--- a/templatetags/dt_week.py
+++ b/templatetags/dt_week.py
@@ -16,8 +16,6 @@
from django import template
-import datetime
-
register = template.Library()
@register.filter
diff --git a/urls.py b/urls.py
index 38c33a0..5557612 100644
--- a/urls.py
+++ b/urls.py
@@ -14,8 +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.conf.urls import url, handler404
-
+from django.conf.urls import url
from . import views
urlpatterns = [
diff --git a/views.py b/views.py
index 651533a..22c08ac 100644
--- a/views.py
+++ b/views.py
@@ -14,10 +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.http import HttpResponse, Http404
-from django.db.models import Count
from django.shortcuts import get_object_or_404, redirect, render
-from django.utils import timezone
from django.core.mail import send_mail
from django.conf import settings
from django.template import Context, loader
@@ -26,8 +23,6 @@ from .forms import SubscribeForm
from .models import Timetable, LastUpdate, Group, Subscription, Course
from .utils import get_current_week, get_week, group_courses
-import datetime
-
def index(request):
timetables = Timetable.objects.all().order_by("name")
groups = Group.objects.filter(tp__isnull=False).order_by("name")
--
cgit v1.2.1
From 990b45c050d287ee86483faaa32db25e392a7605 Mon Sep 17 00:00:00 2001
From: Alban Gruin
Date: Tue, 28 Feb 2017 09:15:00 +0100
Subject: Explication de la regex
---
utils.py | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/utils.py b/utils.py
index 090142b..2de7ef0 100644
--- a/utils.py
+++ b/utils.py
@@ -47,6 +47,18 @@ def group_courses(courses):
return grouped_courses
def parse_group(name):
+ # Explication de la regex
+ #
+ # ^(.+?)\s*\-\s*(((CM)(\w))|((TD)(\w)(\d))|((TP)(\w)(\d)(\d)))$
+ # ^ début de la ligne
+ # (.+?) correspond à au moins un caractère
+ # \s* au moins un espace
+ # \- un tiret
+ # \s* au moins un espace
+ # (((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
+ # $ fin de la ligne
group_regex = re.compile("^(.+?)\s*\-\s*(((CM)(\w))|((TD)(\w)(\d))|((TP)(\w)(\d)(\d)))$")
search = group_regex.search(name)
if search is None:
--
cgit v1.2.1
From 246d7a2e3a22548ce355a551fb19936dc420f695 Mon Sep 17 00:00:00 2001
From: Alban Gruin
Date: Tue, 28 Feb 2017 09:32:01 +0100
Subject: Léger nettoyage
---
management/commands/_private.py | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/management/commands/_private.py b/management/commands/_private.py
index 5b4a7ff..3cd23ca 100644
--- a/management/commands/_private.py
+++ b/management/commands/_private.py
@@ -46,15 +46,12 @@ def delete_courses_in_week(timetable, year, week):
Course.objects.filter(begin__gte=start, begin__lt=end,
timetable=timetable).delete()
-def get_from_db_or_create(cls, timetable=None, **kwargs):
+def get_from_db_or_create(cls, **kwargs):
obj = cls.objects.all().filter(**kwargs)
- if timetable is not None:
- obj = obj.filter(timetable=timetable)
obj = obj.first()
if obj is None:
obj = cls(**kwargs)
- obj.timetable = timetable
obj.save()
return obj
@@ -79,7 +76,7 @@ def get_events(timetable, year, week, soup, weeks_in_soup):
end = add_time(date, datetime.datetime.strptime(
event.endtime.text, "%H:%M"))
- groups = [get_from_db_or_create(Group, timetable,
+ groups = [get_from_db_or_create(Group, timetable=timetable,
celcat_name=item.text)
for item in event.resources.group.find_all("item")]
--
cgit v1.2.1
From 8ca0b621434804100cab3893240f24f7f6d88be9 Mon Sep 17 00:00:00 2001
From: Alban Gruin
Date: Tue, 28 Feb 2017 11:13:59 +0100
Subject: Ajout deux deux commandes d'administration - cleancourses efface
tous les cours, les groupes et les dernières mises à jours par défaut. Il
est possible de supprimer seulement ceux d'un ou plusieurs emploi du temps
en passant leurs ID au paramètre --timetable - listtimetables affiche la
liste des emplois du temps enregistrés dans la base de données, ordonnés
par leur nom. Il est possible de les ordonner par ID avec le paramètre
--order-by-id
---
management/commands/cleancourses.py | 39 +++++++++++++++++++++++++++++++++++
management/commands/listtimetables.py | 39 +++++++++++++++++++++++++++++++++++
2 files changed, 78 insertions(+)
create mode 100644 management/commands/cleancourses.py
create mode 100644 management/commands/listtimetables.py
diff --git a/management/commands/cleancourses.py b/management/commands/cleancourses.py
new file mode 100644
index 0000000..bc14893
--- /dev/null
+++ b/management/commands/cleancourses.py
@@ -0,0 +1,39 @@
+# 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.core.management.base import BaseCommand
+from django.db import transaction
+from edt.models import Course, Group, LastUpdate
+
+
+class Command(BaseCommand):
+ help = "Remove all courses and groups from the database"
+
+ def add_arguments(self, parser):
+ parser.add_argument("--timetable", type=int, nargs="+")
+
+ @transaction.atomic
+ def handle(self, *args, **options):
+ if options["timetable"] is None:
+ Course.objects.all().delete()
+ Group.objects.all().delete()
+ LastUpdate.objects.all().delete()
+ else:
+ Course.objects.filter(timetable__id__in=options["timetable"]).delete()
+ Group.objects.filter(timetable__id__in=options["timetable"]).delete()
+ LastUpdate.objects.filter(timetable__id__in=options["timetable"]).delete()
+
+ self.stdout.write(self.style.SUCCESS("Done."))
diff --git a/management/commands/listtimetables.py b/management/commands/listtimetables.py
new file mode 100644
index 0000000..c5ef41f
--- /dev/null
+++ b/management/commands/listtimetables.py
@@ -0,0 +1,39 @@
+# 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.core.management.base import BaseCommand
+from edt.models import Timetable
+
+
+class Command(BaseCommand):
+ help = "List timetables in the database"
+
+ def add_arguments(self, parser):
+ parser.add_argument("--order-by-id", action="store_true")
+
+ def handle(self, *args, **options):
+ timetables = Timetable.objects.all()
+ if options["order_by_id"]:
+ print("oui")
+ timetables = timetables.order_by("id")
+ else:
+ timetables = timetables.order_by("name")
+
+ for timetable in timetables:
+ self.stdout.write("{0} (id: {1})".format(timetable, timetable.id))
+
+ self.stdout.write("")
+ self.stdout.write(self.style.SUCCESS("Done."))
--
cgit v1.2.1
From 1718988d65a9601a8d2d953da6c1fedc57a6a18c Mon Sep 17 00:00:00 2001
From: Alban Gruin
Date: Tue, 28 Feb 2017 11:53:01 +0100
Subject: Correction de l'explication de la regex
---
utils.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/utils.py b/utils.py
index 2de7ef0..cff4c9c 100644
--- a/utils.py
+++ b/utils.py
@@ -52,9 +52,9 @@ def parse_group(name):
# ^(.+?)\s*\-\s*(((CM)(\w))|((TD)(\w)(\d))|((TP)(\w)(\d)(\d)))$
# ^ début de la ligne
# (.+?) correspond à au moins un caractère
- # \s* au moins un espace
+ # \s* zéro, un ou plusieurs espaces
# \- un tiret
- # \s* au moins un espace
+ # \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
--
cgit v1.2.1
From 2ca125053e753482d13f40da3c602c964b215626 Mon Sep 17 00:00:00 2001
From: Alban Gruin
Date: Tue, 28 Feb 2017 13:21:24 +0100
Subject: Modification de la gestion de la transaction dans la commande
cleancourses
---
management/commands/cleancourses.py | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/management/commands/cleancourses.py b/management/commands/cleancourses.py
index bc14893..8bb1b97 100644
--- a/management/commands/cleancourses.py
+++ b/management/commands/cleancourses.py
@@ -25,15 +25,15 @@ class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument("--timetable", type=int, nargs="+")
- @transaction.atomic
def handle(self, *args, **options):
- if options["timetable"] is None:
- Course.objects.all().delete()
- Group.objects.all().delete()
- LastUpdate.objects.all().delete()
- else:
- Course.objects.filter(timetable__id__in=options["timetable"]).delete()
- Group.objects.filter(timetable__id__in=options["timetable"]).delete()
- LastUpdate.objects.filter(timetable__id__in=options["timetable"]).delete()
+ with transaction.atomic:
+ if options["timetable"] is None:
+ Course.objects.all().delete()
+ Group.objects.all().delete()
+ LastUpdate.objects.all().delete()
+ else:
+ Course.objects.filter(timetable__id__in=options["timetable"]).delete()
+ Group.objects.filter(timetable__id__in=options["timetable"]).delete()
+ LastUpdate.objects.filter(timetable__id__in=options["timetable"]).delete()
self.stdout.write(self.style.SUCCESS("Done."))
--
cgit v1.2.1
From 66be6f2e7a3c642fb3c69e7c2a70cc3f898d77ea Mon Sep 17 00:00:00 2001
From: Alban Gruin
Date: Tue, 28 Feb 2017 13:25:08 +0100
Subject: Avec des parenthèses c'est mieux
---
management/commands/cleancourses.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/management/commands/cleancourses.py b/management/commands/cleancourses.py
index 8bb1b97..5f71861 100644
--- a/management/commands/cleancourses.py
+++ b/management/commands/cleancourses.py
@@ -26,7 +26,7 @@ class Command(BaseCommand):
parser.add_argument("--timetable", type=int, nargs="+")
def handle(self, *args, **options):
- with transaction.atomic:
+ with transaction.atomic():
if options["timetable"] is None:
Course.objects.all().delete()
Group.objects.all().delete()
--
cgit v1.2.1