aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--__init__.py2
-rw-r--r--management/commands/_private.py2
-rw-r--r--models.py26
-rw-r--r--tests.py38
-rw-r--r--utils.py26
5 files changed, 63 insertions, 31 deletions
diff --git a/__init__.py b/__init__.py
index 7371b39..1cdb4e3 100644
--- a/__init__.py
+++ b/__init__.py
@@ -13,7 +13,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with celcatsanitizer. If not, see <http://www.gnu.org/licenses/>.
-VERSION = "0.11.1"
+VERSION = "0.11.3"
__version__ = VERSION
default_app_config = "edt.apps.EdtConfig"
diff --git a/management/commands/_private.py b/management/commands/_private.py
index b663454..4dd9262 100644
--- a/management/commands/_private.py
+++ b/management/commands/_private.py
@@ -54,7 +54,7 @@ def get_event(timetable, event, event_week, today):
end = add_time(date, event.endtime.text)
# On ne traite pas le cours si il commence après le moment du traitement
- if begin < today:
+ if today is not None and begin < today:
return
# Création de l’objet cours
diff --git a/models.py b/models.py
index 0804a38..40406e3 100644
--- a/models.py
+++ b/models.py
@@ -16,7 +16,7 @@
from functools import reduce
from django.db import models
-from django.db.models import Count, Manager, Q, Subquery
+from django.db.models import Count, Manager, Q, Subquery, Value
from django.db.models.expressions import OuterRef
from django.db.models.functions import ExtractWeek, ExtractYear
from django.utils import timezone
@@ -57,7 +57,8 @@ class Timetable(SlugModel):
url = models.URLField(max_length=255, verbose_name="URL")
slug = models.SlugField(max_length=64, default="")
- last_update_date = models.DateTimeField(verbose_name="dernière mise à jour Celcat", null=True)
+ last_update_date = models.DateTimeField(verbose_name="dernière mise à jour Celcat",
+ null=True, blank=True)
def __str__(self):
return self.year.name + " " + self.name
@@ -71,18 +72,22 @@ class Timetable(SlugModel):
class GroupManager(Manager):
def get_parents(self, group):
- groups_criteria = Q(subgroup="") | Q(subgroup__startswith=group.subgroup) | \
- reduce(lambda x, y: x | y,
- [Q(subgroup=group.subgroup[:i])
- for i in range(1, len(group.subgroup) + 1)])
+ groups_criteria = Q(subgroup="") | Q(subgroup__startswith=group.subgroup)
+
+ if len(group.subgroup) != 0:
+ groups_criteria |= reduce(lambda x, y: x | y,
+ [Q(subgroup=group.subgroup[:i])
+ for i in range(1, len(group.subgroup) + 1)])
return self.get_queryset().filter(groups_criteria, mention=group.mention,
timetable=group.timetable)
def get_relevant_groups(self, timetable, *args, **criteria):
- sub = self.get_queryset().filter(timetable=timetable, mention=OuterRef("mention"),
- subgroup__startswith=OuterRef("subgroup")) \
- .order_by().values("mention").annotate(c=Count("*")).values("c")
+ sub = self.get_queryset().filter(timetable=timetable,
+ mention__startswith=OuterRef("mention"),
+ subgroup__startswith=OuterRef("subgroup")) \
+ .annotate(v=Value(0)).values("v") \
+ .annotate(c=Count("v")).values("c") # fuck Count()
return self.get_queryset().filter(*args, timetable=timetable, hidden=False, **criteria) \
.annotate(nbsub=Subquery(sub, output_field=models.IntegerField())) \
@@ -112,7 +117,8 @@ class Group(models.Model):
self.subgroup.startswith(subgroup)
return self.timetable.id == timetable_id and \
- self.mention.startswith(mention) and \
+ (self.mention.startswith(mention) or \
+ mention.startswith(self.mention)) and \
subgroup_corresponds
@property
diff --git a/tests.py b/tests.py
index 051c733..a509f38 100644
--- a/tests.py
+++ b/tests.py
@@ -69,6 +69,8 @@ class GroupTestCase(TestCase):
Group.objects.create(celcat_name="L1 info s2 TDB2", timetable=self.timetable)
Group.objects.create(celcat_name="L1 info s2 TPB21", timetable=self.timetable)
+ Group.objects.create(celcat_name="L1 info (toutes sections et semestres confondus)", timetable=self.timetable)
+
def test_corresponds(self):
cma = Group.objects.get(celcat_name="L1 info s2 CMA", timetable=self.timetable)
tda2 = Group.objects.get(celcat_name="L1 info s2 TDA2", timetable=self.timetable)
@@ -78,6 +80,8 @@ class GroupTestCase(TestCase):
tdb2 = Group.objects.get(celcat_name="L1 info s2 TDB2", timetable=self.timetable)
tpb21 = Group.objects.get(celcat_name="L1 info s2 TPB21", timetable=self.timetable)
+ general = Group.objects.get(celcat_name="L1 info (toutes sections et semestres confondus)", timetable=self.timetable)
+
self.assertTrue(cma.corresponds_to(*tda2.group_info)) # CMA corresponds to TDA2
self.assertTrue(cma.corresponds_to(*tpa21.group_info)) # CMA corresponds to TPA21
self.assertTrue(tda2.corresponds_to(*tpa21.group_info)) # TDA2 corresponds to TPA21
@@ -102,6 +106,20 @@ class GroupTestCase(TestCase):
self.assertFalse(tpa21.corresponds_to(*cmb.group_info)) # TPA21 does not corresponds to CMB
self.assertFalse(tpa21.corresponds_to(*tdb2.group_info)) # TPA21 does not corresponds to TDB2
+ self.assertTrue(general.corresponds_to(*cma.group_info))
+ self.assertTrue(general.corresponds_to(*cmb.group_info))
+ self.assertTrue(general.corresponds_to(*tda2.group_info))
+ self.assertTrue(general.corresponds_to(*tdb2.group_info))
+ self.assertTrue(general.corresponds_to(*tpa21.group_info))
+ self.assertTrue(general.corresponds_to(*tpb21.group_info))
+
+ self.assertTrue(cma.corresponds_to(*general.group_info))
+ self.assertTrue(cmb.corresponds_to(*general.group_info))
+ self.assertTrue(tda2.corresponds_to(*general.group_info))
+ self.assertTrue(tdb2.corresponds_to(*general.group_info))
+ self.assertTrue(tpa21.corresponds_to(*general.group_info))
+ self.assertTrue(tpb21.corresponds_to(*general.group_info))
+
def test_get(self):
cma = Group.objects.get(name="L1 info s2 CMA", timetable=self.timetable)
tda2 = Group.objects.get(name="L1 info s2 TDA2", timetable=self.timetable)
@@ -111,6 +129,8 @@ class GroupTestCase(TestCase):
tdb2 = Group.objects.get(name="L1 info s2 TDB2", timetable=self.timetable)
tpb21 = Group.objects.get(name="L1 info s2 TPB21", timetable=self.timetable)
+ general = Group.objects.get(celcat_name="L1 info (toutes sections et semestres confondus)", timetable=self.timetable)
+
self.assertEqual(cma.celcat_name, "L1 info s2 CMA")
self.assertEqual(tda2.celcat_name, "L1 info s2 TDA2")
self.assertEqual(tpa21.celcat_name, "L1 info s2 TPA21")
@@ -119,6 +139,8 @@ class GroupTestCase(TestCase):
self.assertEqual(tdb2.celcat_name, "L1 info s2 TDB2")
self.assertEqual(tpb21.celcat_name, "L1 info s2 TPB21")
+ self.assertEqual(general.celcat_name, "L1 info (toutes sections et semestres confondus)")
+
def test_parse(self):
cma = Group.objects.get(celcat_name="L1 info s2 CMA", timetable=self.timetable)
tda2 = Group.objects.get(celcat_name="L1 info s2 TDA2", timetable=self.timetable)
@@ -128,10 +150,14 @@ class GroupTestCase(TestCase):
tdb2 = Group.objects.get(celcat_name="L1 info s2 TDB2", timetable=self.timetable)
tpb21 = Group.objects.get(celcat_name="L1 info s2 TPB21", timetable=self.timetable)
- self.assertEqual(cma.group_info, (self.timetable.id, "L1 info", "A"))
- self.assertEqual(tda2.group_info, (self.timetable.id, "L1 info", "A2"))
- self.assertEqual(tpa21.group_info, (self.timetable.id, "L1 info", "A21"))
+ general = Group.objects.get(celcat_name="L1 info (toutes sections et semestres confondus)", timetable=self.timetable)
+
+ self.assertEqual(cma.group_info, (self.timetable.id, "L1 info s2 ", "A"))
+ self.assertEqual(tda2.group_info, (self.timetable.id, "L1 info s2 ", "A2"))
+ self.assertEqual(tpa21.group_info, (self.timetable.id, "L1 info s2 ", "A21"))
+
+ self.assertEqual(cmb.group_info, (self.timetable.id, "L1 info s2 ", "B"))
+ self.assertEqual(tdb2.group_info, (self.timetable.id, "L1 info s2 ", "B2"))
+ self.assertEqual(tpb21.group_info, (self.timetable.id, "L1 info s2 ", "B21"))
- self.assertEqual(cmb.group_info, (self.timetable.id, "L1 info", "B"))
- self.assertEqual(tdb2.group_info, (self.timetable.id, "L1 info", "B2"))
- self.assertEqual(tpb21.group_info, (self.timetable.id, "L1 info", "B21"))
+ self.assertEqual(general.group_info, (self.timetable.id, "L1 info ", ""))
diff --git a/utils.py b/utils.py
index 5d55eca..e1b9867 100644
--- a/utils.py
+++ b/utils.py
@@ -48,24 +48,24 @@ def group_courses(courses):
def parse_group(name):
# Explication de la regex
#
- # ^(.+?)\s*(s\d\s+)?((CM|TD|TP|G)(\w\d{0,3}))?(\s+\(.+\))?$
- # ^ début de la ligne
- # (.+?) correspond à au moins un caractère
- # \s* éventuellement un ou plusieurs espaces
- # (s\d\s+)? éventuellement un s suivi d’un nombre et d’un ou plusieurs espaces
- # ((CM|TD|TP|G) « CM » ou « TD » ou « TP » ou « G »
- # (\w\d{0,3}) suivi d’un caractère puis entre 0 et 3 chiffres
- # )? groupe optionnel
- # (\s+ un ou plusieurs espaces
- # \(.+\))? un ou pliseurs caractères entre parenthèses
- # $ fin de la ligne
- group_regex = re.compile(r"^(.+?)\s*(s\d\s+)?((CM|TD|TP|G)(\w\d{0,3}))?(\s+\(.+\))?$")
+ # ^((.+?)\s*(s\d\s+)?)((CM|TD|TP|G)(\w\d{0,3}))?(\s+\(.+\))?$
+ # ^ début de la ligne
+ # ((.+?) correspond à au moins un caractère
+ # \s* éventuellement un ou plusieurs espaces
+ # (s\d\s+)?) éventuellement un s suivi d’un nombre et d’un ou plusieurs espaces
+ # ((CM|TD|TP|G) « CM » ou « TD » ou « TP » ou « G »
+ # (\w\d{0,3}) suivi d’un caractère puis entre 0 et 3 chiffres
+ # )? groupe optionnel
+ # (\s* éventuellement un ou plusieurs espaces
+ # \(.+\))? un ou plusieurs caractères entre parenthèses
+ # $ fin de la ligne
+ group_regex = re.compile(r"^((.+?)\s*(s\d\s+)?)((CM|TD|TP|G)(\w\d{0,3}))?(\s*\(.+\))?$")
search = group_regex.search(name)
if search is None:
return name, None
parts = search.groups()
- return parts[0], parts[4]
+ return parts[0], parts[5]
def tz_now():
"""Retourne la date et l’heure avec le bon fuseau horaire"""