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 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'management') 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) -- 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 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'management') 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) -- 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(-) (limited to 'management') 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 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(-) (limited to 'management') 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 +++------ 2 files changed, 6 insertions(+), 11 deletions(-) (limited to 'management') 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): -- 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(-) (limited to 'management') 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 (limited to 'management') 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 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(-) (limited to 'management') 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(-) (limited to 'management') 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