From 443c95daa0331046f03c595be6c0757dcda0c876 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Mogu=C3=A9rou?= Date: Fri, 19 Apr 2024 16:30:23 +0200 Subject: [PATCH] beaucoup de choses... --- colloscope/: | 204 ------------------ colloscope/admin.py | 15 +- .../0005_etudiant_groupes_groupe_membres.py | 23 ++ ...6_remove_rotation_semaine_rotation_date.py | 24 +++ colloscope/models.py | 83 +++++-- colloscope/pdfexport.py | 16 +- colloscope/templates/base.html | 5 + colloscope/templates/choix_profil.html | 25 +++ colloscope/templates/colloscope.html | 55 +++-- colloscope/urls.py | 1 + colloscope/views.py | 33 ++- scrape_csv.py | 69 ++++++ static/table.css | 29 +++ 13 files changed, 341 insertions(+), 241 deletions(-) delete mode 100644 colloscope/: create mode 100644 colloscope/migrations/0005_etudiant_groupes_groupe_membres.py create mode 100644 colloscope/migrations/0006_remove_rotation_semaine_rotation_date.py create mode 100644 colloscope/templates/choix_profil.html create mode 100644 scrape_csv.py create mode 100644 static/table.css diff --git a/colloscope/: b/colloscope/: deleted file mode 100644 index 7324391..0000000 --- a/colloscope/: +++ /dev/null @@ -1,204 +0,0 @@ -from datetime import date, timedelta - -from colloscope.models import Etudiant, Critere - -from fpdf import FPDF -from fpdf.fonts import FontFace -from fpdf.enums import TableCellFillMode - -calendrier_zoneC = date(2023, 9, 18), [ - ( date(2023, 10, 21), date(2023, 11, 6) ), - ( date(2023, 12, 23), date(2024, 1, 8) ), - ( date(2024, 2, 10), date(2024, 2, 26) ), - ( date(2024, 4, 6), date(2024, 4, 22) ), -] - -def jour_of_sem(n, cal): - sem_1, vac = cal - - jour = sem_1 + (n-1) * timedelta(weeks=1) - - for (debut, fin) in vac: - if jour >= debut: - jour += 2*timedelta(weeks=1) - - return jour - -""" -etudiants = [ - ['Aboujaib', 'Alexandre', 4, 'A', '', ''], - ['Ajan', 'George', 4, 'A', '', ''], - ['Akrad', 'Lina', 1, 'SI', '', ''], - ['Aubert', 'Nicolas', 1, 'SI', '', ''], - ['Badr', 'Roman', 4, 'A', '', ''], - ['Bazire', 'Aurélien', 5, 'A', '', ''], - ['Boit', 'Arthur', 5, 'A', '', ''], - ['Boubker', 'Youssef', 5, 'A', '', ''], - ['Boudjema', 'Dylan', 1, 'SI', '', ''], - ['Chiriac', 'Mihnea', 6, 'A', '', ''], - ['Courier', 'Marine', 6, 'A', '', ''], - ['Daguin', 'Joseph', 6, 'A', '', ''], - ['Dauguen', 'Gabriel', 7, 'A', '', ''], - ['De Weer', 'Matthias', 7, 'A', '', ''], - ['Desbouis', 'Katell', 2, 'SI', '', ''], - ['Dupouy', 'Jérémie', 7, 'A', '', ''], - ['Hariri--Gautier-Picard', 'Grégoire', 8, 'A', '', ''], - ['Juricevic', 'Matteo', 8, 'A', '', ''], - ['Knanoua', 'Anas', 8, 'A', '', ''], - ['Lesenne', 'Pierrick', 9, 'A', '', ''], - ['Lin', 'Hao', 2, 'SI', '', ''], - ['Masbatin', 'Lucas', 2, 'SI', '', ''], - ['Mayuran', 'Mithushan', 9, 'A', '', ''], - ['Messahli', 'Yassine', 9, 'A', '', ''], - ['Moguérou', 'Valentin', 10, 'B', '', ''], - ['Mohellebi', 'Mathéo', 10, 'B', '', ''], - ['Mouisset--Ferrara', 'Maël', 10, 'B', '', ''], - ['Ottavi', 'Corentin', 11, 'B', '', ''], - ['Ponce', 'Alexian', 11, 'B', '', ''], - ['Pujol', 'Raphaël', 11, 'B', '', ''], - ['Pustetto', 'Mathis', 12, 'B', '', ''], - ['Radice', 'Roman', 12, 'B', '', ''], - ['Rat', 'Evelyn', 12, 'B', '', ''], - ['Rousse', 'Louis', 3, 'SI', '', ''], - ['Roux', 'Gaëtan', 3, 'SI', '', ''], - ['Rouyre--Cros', 'Célian', 3, 'SI', '', ''], - ['Sourbé', 'François-Gabriel', 13, 'B', '', ''], - ['Stourbe', 'Simon', 13, 'B', '', ''], - ['Thai', 'Dany', 13, 'B', '', ''], - ['Théodore', 'Jonathan', 14, 'B', '', ''], - ['Vandroux', 'Benoît', 14, 'B', '', ''], - ['Veyssière', 'Thibaud', 14, 'B', '', ''], - ['Vié', 'Adrien', 15, 'B', '', ''], - ['Ye', 'Luan', 15, 'B', '', ''], - ['Zarka', 'Amélie', 15, 'B', '', ''], -] -""" - -creneaux = [ - ["Mathématiques", "vendredi", "17:00", "M. OUBAHA", "C382"], - ["Anglais", "mercredi", "14:00", "Mme LE GOURIELLEC", "C393"], - ["Mathématiques", "mercredi", "15:00", "M. BOULLY", "R004"], - ["Physique", "mardi", "14:00", "Mme CHEVALIER", "R103"], - ["Mathématiques", "mardi", "18:00", "M. RAPIN", "V152"], - ["Anglais", "mardi", "14:00", "Mme BELAGGOUNE", "C4??"], - ["pas de colle", "", "", "", ""], - ["Physique", "mardi", "17:00", "M. COLIN", "C386"], - ["Mathématiques", "mercredi", "13:30", "M. BOUVEROT", "??"], - ["Anglais", "lundi", "13:00", "M. HERBAUT", "V052"], -] - -semaines = list(range(24, 34)) - -rotations = [ - # [semaine, groupe, creneau] - (24, 1, 1), - (24, 2, 2), - (24, 3, 3), - (27, 3, 3), - (28, 3, 3), - (31, 3, 3), -] - -class PDF(FPDF): - def liste_eleves(self, periode): - classe = periode.classe - etudiants = Etudiant.objects.filter(classe=classe) - - with self.table( - align="RIGHT", - col_widths=(4, 3, 1, 1, 1, 1), - width=80, - line_height=3) as table: - header = table.row() - for th in ("Nom", "Prénom", "Grp.", "TD", "LV1", "LV2"): - header.cell(th) - - for etu in etudiants: - row = table.row() - row.cell(etu.nom.upper()) # Nom - row.cell(etu.prenom) # Prénom - row.cell(etu.groupe_de_colle(periode).libelle) # Groupe - row.cell(etu.groupe_du_critere(periode, "TD")) # TD - row.cell("??") # LV1 - row.cell("??") # LV2 - - - def table_colloscope(self, creneaux, semaines, rotations): - with self.table( - align="LEFT", - width=190, - line_height=3, - col_widths=(2, 1, 1, 3, 1, *(1,)*len(semaines)), - num_heading_rows=2) as table: - - header = table.row() - for th in ("Matière", "Jour", "Heure", "Colleur", "Salle"): - header.cell(th, align="CENTER", rowspan=2) - - for sem in semaines: - header.cell(str(sem), align="CENTER") - - header2 = table.row() - for sem in semaines: - header2.cell(jour_of_sem(sem, calendrier_zoneC).strftime("%d/%m/%y"), align="CENTER") - - for i, tr in enumerate(creneaux): - matiere, jour, heure, colleur, salle = tr - - row = table.row() - row.cell(matiere) - row.cell(jour) - row.cell(heure) - row.cell(colleur) - row.cell(salle) - - for s in semaines: - for rot in rotations: - if rot[2] == i and rot[0] == s: - row.cell(str(rot[1]), align="CENTER") - break - else: - row.cell() - - def table_travaux(self): - with self.table( - align="LEFT", - width=190, - line_height=3, - col_widths=(2, 1, 1, 4, *(1,)*len(semaines)), - first_row_as_headings=False) as table: - - row = table.row() - row.cell("TP Physique") - row.cell("lundi") - row.cell("8:30") - row.cell() - - for _ in range(len(semaines)): - row.cell("9 à 15", align="CENTER") - -def generate(periode): - pdf = PDF(orientation="landscape", format="a4") - pdf.set_font("helvetica", size=6) - - pdf.set_title("Colloscope mp2i semestre 5/2") - pdf.set_author("projet colloscope") - pdf.set_author("projet colloscope") - - pdf.add_page() - pdf.cell(text="Colloscope MP2I Semestre 5/2", center=True, border=1, h=5) - base_y = pdf.t_margin + 10 - pdf.set_y(base_y) - pdf.liste_eleves(etudiants) - #pdf.set_y(base_y) - #pdf.table_colloscope(creneaux, semaines, rotations) - #pdf.y += 3 - #pdf.table_travaux() - - pdf.output("test.pdf") - -if __name__ == "__main__": - classe = Classe.get(id=1) - periode = Periode.get(classe=classe, libelle="Semestre 5/2") - - generate(periode) diff --git a/colloscope/admin.py b/colloscope/admin.py index 8c38f3f..d0e2529 100644 --- a/colloscope/admin.py +++ b/colloscope/admin.py @@ -1,3 +1,16 @@ from django.contrib import admin +from colloscope.models import * -# Register your models here. +admin.site.register(Lycee) +admin.site.register(Classe) +admin.site.register(Periode) +admin.site.register(Matiere) +admin.site.register(Critere) +admin.site.register(Groupe) +admin.site.register(Etudiant) +admin.site.register(Appartenance) +admin.site.register(Colleur) +admin.site.register(Creneau) +admin.site.register(Rotation) +admin.site.register(Amendement) +admin.site.register(Utilisateur) diff --git a/colloscope/migrations/0005_etudiant_groupes_groupe_membres.py b/colloscope/migrations/0005_etudiant_groupes_groupe_membres.py new file mode 100644 index 0000000..b03472e --- /dev/null +++ b/colloscope/migrations/0005_etudiant_groupes_groupe_membres.py @@ -0,0 +1,23 @@ +# Generated by Django 5.0.4 on 2024-04-18 23:22 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('colloscope', '0004_matiere_classe'), + ] + + operations = [ + migrations.AddField( + model_name='etudiant', + name='groupes', + field=models.ManyToManyField(through='colloscope.Appartenance', to='colloscope.groupe'), + ), + migrations.AddField( + model_name='groupe', + name='membres', + field=models.ManyToManyField(through='colloscope.Appartenance', to='colloscope.etudiant'), + ), + ] diff --git a/colloscope/migrations/0006_remove_rotation_semaine_rotation_date.py b/colloscope/migrations/0006_remove_rotation_semaine_rotation_date.py new file mode 100644 index 0000000..19598f1 --- /dev/null +++ b/colloscope/migrations/0006_remove_rotation_semaine_rotation_date.py @@ -0,0 +1,24 @@ +# Generated by Django 5.0.4 on 2024-04-19 00:08 + +import datetime +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('colloscope', '0005_etudiant_groupes_groupe_membres'), + ] + + operations = [ + migrations.RemoveField( + model_name='rotation', + name='semaine', + ), + migrations.AddField( + model_name='rotation', + name='date', + field=models.DateField(default=datetime.date(2024, 4, 22)), + preserve_default=False, + ), + ] diff --git a/colloscope/models.py b/colloscope/models.py index 108a534..9df10fd 100644 --- a/colloscope/models.py +++ b/colloscope/models.py @@ -1,4 +1,3 @@ -from math import ceil from datetime import date, datetime, timedelta from django.db import models @@ -10,6 +9,7 @@ calendrier = { ( date(2023, 12, 23), date(2024, 1, 8) ), ( date(2024, 2, 10), date(2024, 2, 26) ), ( date(2024, 4, 6), date(2024, 4, 22) ), + ( date(2024, 5, 6), date(2024, 5, 11) ), # pont un peu gratté ] } @@ -19,6 +19,9 @@ class Lycee(models.Model): libelle = models.CharField(max_length=100) vacances = models.CharField(max_length=1) + def __self__(self): + return self.uai + class Classe(models.Model): lycee = models.ForeignKey(Lycee, on_delete=models.CASCADE) @@ -44,7 +47,7 @@ class Classe(models.Model): n = 1 + ((jour - jour0).days)//7 for debut, fin in vacances: if jour > debut: - n -= 2 + n -= round( ( fin - debut )/timedelta(weeks=1) ) return n def no_aujourdhui(self): @@ -75,9 +78,9 @@ class Classe(models.Model): jour = jour0 + (n-1) * timedelta(weeks=1) - for debut, _ in vacances: + for debut, fin in vacances: if jour >= debut: - jour += 2*timedelta(weeks=1) + jour += round( (fin - debut)/timedelta(weeks=1) )*timedelta(weeks=1) return jour @@ -96,6 +99,9 @@ class Classe(models.Model): """ return Periode.objects.get(classe=self, debut__lte=jour, fin__gte=jour) + def __str__(self): + return f"{self.libelle} ({self.lycee.libelle})" + class Periode(models.Model): classe = models.ForeignKey(Classe, on_delete=models.CASCADE) @@ -117,15 +123,27 @@ class Periode(models.Model): """ return range(self.classe.no_semaine(self.debut), self.classe.no_semaine(self.fin)+1) + def __str__(self): + return self.libelle + + class Matiere(models.Model): classe = models.ForeignKey(Classe, on_delete=models.CASCADE) libelle = models.CharField(max_length=100) code = models.CharField(max_length=20) + def __str__(self): + return self.libelle + + class Critere(models.Model): periode = models.ForeignKey(Periode, on_delete=models.CASCADE) libelle = models.CharField(max_length=100) + def __str__(self): + return self.libelle + + class Groupe(models.Model): #class Meta: # ordering=[F("periode").classe.libelle, F("periode").libelle, "libelle"] @@ -134,8 +152,24 @@ class Groupe(models.Model): critere = models.ForeignKey(Critere, null=True, on_delete=models.CASCADE) libelle = models.CharField(max_length=100) - def membres(self): - return Etudiant.objects.filter(id__in=Appartenance.objects.filter(groupe=self)) + membres = models.ManyToManyField("Etudiant", through="Appartenance") + + def __str__(self): + return self.libelle + + def get_colles(self): + return Rotation.objects.filter(groupes=self).order_by("date") + + def get_colles_par_sem(self): + semaines = ( (s, self.periode.classe.date_debut_sem(s)) for s in self.periode.range_semaines() ) + colles_flat = self.get_colles() + + return [ + (sem, lundi, + colles_flat.filter(date__gte=lundi, date__lt=lundi+timedelta(weeks=1))) + for sem, lundi in semaines + ] + class Etudiant(models.Model): class Meta: @@ -144,14 +178,13 @@ class Etudiant(models.Model): classe = models.ForeignKey(Classe, on_delete=models.CASCADE) prenom = models.CharField(max_length=100) nom = models.CharField(max_length=100) - #lv1 = models.ForeignKey(Matiere, on_delete=models.CASCADE) - #lv2 = models.ForeignKey(Matiere, on_delete=models.CASCADE) + groupes = models.ManyToManyField("Groupe", through="Appartenance") def appartient(self, groupe): """ Renvoie si self appartient au groupe. """ - return Appartenance.objects.filter(etudiant=self, groupe=groupe).exists() + return groupe.membres.contains(self) def groupe_du_critere(self, periode, critere): """ @@ -168,14 +201,29 @@ class Etudiant(models.Model): """ return self.groupe_du_critere(periode, "colle") + def __str__(self): + return f"{self.prenom} {self.nom}" + + class Appartenance(models.Model): etudiant = models.ForeignKey(Etudiant, on_delete=models.CASCADE) groupe = models.ForeignKey(Groupe, on_delete=models.CASCADE) + class Colleur(models.Model): civilite = models.CharField(max_length=1) nom = models.CharField(max_length=100) + def __str__(self): + if self.civilite == "M": + return f"M. {self.nom}" + else: + return f"Mme {self.nom}" + + def get_classes(self): + return (x.periode.classe for x in Creneau.objects.filter(colleur=self).select_related("periode__classe")) + + class Creneau(models.Model): periode = models.ForeignKey(Periode, on_delete=models.CASCADE) jour = models.IntegerField() @@ -187,10 +235,16 @@ class Creneau(models.Model): est_colle = models.BooleanField() capacite = models.IntegerField() + def __str__(self): + jours = ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"] + + return f"Colle {self.matiere} avec {self.colleur} {jours[self.jour]} {self.heure}" + + class Rotation(models.Model): creneau = models.ForeignKey(Creneau, on_delete=models.CASCADE) groupes = models.ManyToManyField(Groupe) - semaine = models.IntegerField() + date = models.DateField() def groupe_initial(self): """ @@ -214,7 +268,7 @@ class Rotation(models.Model): """ Renvoie le nombre d'étudiants inscrits à la colle en tenant compte des amendements. """ - n_base = sum(len(groupe.membres()) for groupe in self.groupes.all()) + n_base = sum(len(groupe.membres.count()) for groupe in self.groupes.all()) n_plus = len(Amendement.objects.filter(est_positif=True, rotation=self)) n_moins = len(Amendement.objects.filter(est_positif=False, rotation=self)) @@ -253,12 +307,17 @@ class Rotation(models.Model): else: amendement = Amendement(rotation=self, etudiant=etudiant, est_positif=est_positif) amendement.save() - + + def __str__(self): + return f"{self.creneau} le {self.date} avec groupes {'+'.join(str(groupe) for groupe in self.groupes.all())}" + + class Amendement(models.Model): est_positif = models.BooleanField() rotation = models.ForeignKey(Rotation, on_delete=models.CASCADE) etudiant = models.ForeignKey(Etudiant, on_delete=models.CASCADE) + class Utilisateur(models.Model): username = models.CharField(max_length=100) password = models.CharField(max_length=300) diff --git a/colloscope/pdfexport.py b/colloscope/pdfexport.py index 9c780c8..1157dbb 100644 --- a/colloscope/pdfexport.py +++ b/colloscope/pdfexport.py @@ -16,7 +16,7 @@ class PDF(FPDF): width=80, line_height=3) as table: header = table.row() - for th in ("Nom", "Prénom", "Grp.", "TD", "LV1", "LV2"): + for th in ("Nom", "Prénom", "Grp.", "TD",): #"LV1", "LV2"): header.cell(th) for etu in etudiants: @@ -24,10 +24,9 @@ class PDF(FPDF): row.cell(etu.nom.upper()) # Nom row.cell(etu.prenom) # Prénom row.cell(etu.groupe_de_colle(periode).libelle) # Groupe - row.cell("??") - #row.cell(etu.groupe_du_critere(periode, "TD")) # TD - row.cell("??") # LV1 - row.cell("??") # LV2 + row.cell(etu.groupe_du_critere(periode, "td").libelle) + #row.cell("??") # LV1 + #row.cell("??") # LV2 def table_colloscope(self, periode, heading=True, est_colle=True): @@ -72,8 +71,10 @@ class PDF(FPDF): row.cell(salle) for s in semaines: - if Rotation.objects.filter(creneau=c, semaine=s).exists(): - r = Rotation.objects.get(creneau=c, semaine=s) + lundi = periode.classe.date_debut_sem(s) + + if Rotation.objects.filter(creneau=c, date__gte=lundi, date__lt=lundi+timedelta(weeks=1)).exists(): + r = Rotation.objects.get(creneau=c, date__gte=lundi, date__lt=lundi+timedelta(weeks=1)) groupes = r.groupes content = ", ".join(g.libelle for g in groupes.all()) @@ -96,6 +97,7 @@ def generate(periode): pdf.add_page() pdf.cell(text=titre, center=True, border=1, h=5) + pdf.set_line_width(0.1) base_y = pdf.t_margin + 10 pdf.set_y(base_y) pdf.liste_eleves(periode) diff --git a/colloscope/templates/base.html b/colloscope/templates/base.html index e4ded3a..c93282b 100644 --- a/colloscope/templates/base.html +++ b/colloscope/templates/base.html @@ -10,6 +10,11 @@
+ {% if request.session.overseer is not None %} +
+ Vous voyez ce site en tant que... Désactiver +
+ {% endif %} {% block header %}{% endblock header %}
diff --git a/colloscope/templates/choix_profil.html b/colloscope/templates/choix_profil.html new file mode 100644 index 0000000..12b734b --- /dev/null +++ b/colloscope/templates/choix_profil.html @@ -0,0 +1,25 @@ +{% extends "base.html" %} + +{% block title %}Sélection du profil{% endblock title %} + +{% block header %} +

Sélection du profil

+{% endblock header %} + +{% block main %} + +{% if user.etudiant is not None and user.colleur is not None %} +Vous êtes connecté. Votre compte correspond à deux profils : + +{% elif user.colleur is not None and user.etudiant is None %} +Connection en tant que {{ user.colleur }}... classes : {{ user.colleur.get_classes }} +{% elif user.etudiant is not None and user.colleur is None %} +Connection en tant que {{ user.etudiant }} : classe {{ user.etudiant.classe }} +{% else %} +Vous êtes connecté, mais votre compte n'est associé à aucun profil. Veuillez contacter le webmestre à l'adresse valentin@mp2i-vms.fr. +{% endif %} + +{% endblock main %} diff --git a/colloscope/templates/colloscope.html b/colloscope/templates/colloscope.html index 394c627..72696b2 100644 --- a/colloscope/templates/colloscope.html +++ b/colloscope/templates/colloscope.html @@ -1,9 +1,13 @@ {% extends "base.html" %} +{% load static %} {% load extras %} {% block title %}Colloscope{% endblock title %} +{% block head %} + +{% endblock head %} {% block header %}

Colloscope

@@ -20,12 +24,28 @@ + + + + + + + + + {% for _ in semaines %} + + {% endfor %} + + + {% for n in semaines %} + + {% endfor %} @@ -40,18 +60,8 @@ - - + + {% for sem, exists, r, est_modifiee, groupes in rs %} {% if exists %} @@ -69,4 +79,25 @@
Matière Jour Heure Colleur Salle{{ n }}
{{ c.matiere.libelle }} {{ jours | getitem:c.jour }} {{ c.heure | strftime:"%H:%M" }} - {% if c.colleur.civilite == "M" %} - M. - {% else %} - Mme - {% endif %} - - {{ c.colleur.nom | upper }} - - {{ c.salle }} - {{ c.colleur }}{{ c.salle }}
+ +

Par groupes

+ + {% for groupe, rot in rotations_par_groupes %} + +

Groupe {{ groupe }}

+ + + + {% endfor %} + {% endblock main %} diff --git a/colloscope/urls.py b/colloscope/urls.py index 6361cc9..24355a6 100644 --- a/colloscope/urls.py +++ b/colloscope/urls.py @@ -4,4 +4,5 @@ from . import views urlpatterns = [ path("", views.colloscope, name="colloscope"), path("export", views.export, name="export"), + path("choix_profil", views.choix_profil, name="choix_profil") ] diff --git a/colloscope/views.py b/colloscope/views.py index 1202d3e..0573fa2 100644 --- a/colloscope/views.py +++ b/colloscope/views.py @@ -1,3 +1,5 @@ +from datetime import timedelta + from django.http import HttpResponse from django.template import loader from colloscope.models import * @@ -7,9 +9,20 @@ from colloscope.pdfexport import main # /!\ temporaire def handler404(request): template = loader.get_template("404.html") - response.status_code = 404 + #response.status_code = 404 context = {} - return HttpResponse(template.render(context, response)) + return HttpResponse(template.render(context)) + + +def choix_profil(request): + template = loader.get_template("choix_profil.html") + + utilisateur = Utilisateur.objects.get(id=1) + + context = { + "user": utilisateur, + } + return HttpResponse(template.render(context)) def colloscope(request): @@ -31,7 +44,9 @@ def colloscope(request): rotations = [ (c, []) for c in creneaux ] for c, l in rotations: for sem in semaines: - rot = Rotation.objects.filter(creneau=c, semaine=sem) + lundi = periode.classe.date_debut_sem(sem) + + rot = Rotation.objects.filter(creneau=c, date__gte=lundi, date__lt=lundi+timedelta(weeks=1)) exists = rot.exists() if exists: @@ -42,14 +57,22 @@ def colloscope(request): r = est_modifiee = groupes = None l.append((sem, exists, r, est_modifiee, groupes)) + + + + rotations_par_groupes = [ ( groupe, groupe.get_colles_par_sem() ) for groupe in Groupe.objects.filter(periode=periode, critere__libelle="colle") ] + + template = loader.get_template("colloscope.html") context = { "periode": periode, - "lundis": [periode.classe.date_debut_sem(n) for n in semaines ], + "semaines": semaines, + "lundis": [periode.classe.date_debut_sem(n) for n in semaines], "jours" : ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"], - "rotations" : rotations + "rotations" : rotations, + "rotations_par_groupes" : rotations_par_groupes, } return HttpResponse(template.render(context, request)) diff --git a/scrape_csv.py b/scrape_csv.py new file mode 100644 index 0000000..71f8346 --- /dev/null +++ b/scrape_csv.py @@ -0,0 +1,69 @@ +import csv +from datetime import date, time, timedelta +from colloscope.models import * + +def scrape(periode, chemin): + with open(chemin, "r") as file: + reader = csv.reader(file) + headers, *colloscope = list(reader) + + for l in colloscope: + print(l) + + for colleur, matiere, jour, heure, *(rotations) in colloscope: + nom_colleur = colleur.lstrip("Mme.").title() + civilite = "M" if colleur.startswith("M.") else "F" + + if not Colleur.objects.filter(nom=nom_colleur, civilite=civilite).exists(): + c = Colleur(civilite=civilite, nom=nom_colleur) + c.save() + else: + c = Colleur.objects.get(nom=nom_colleur, civilite=civilite) + + if not Matiere.objects.filter(classe=periode.classe, libelle=matiere).exists(): + m = Matiere(classe=periode.classe, libelle=matiere, code=matiere.upper()) + m.save() + else: + m = Matiere.objects.get(classe=periode.classe, libelle=matiere) + + jours_dict = {"dimanche": 0, "lundi": 1, "mardi": 2, "mercredi": 3, "jeudi": 4, "vendredi": 5, "samedi": 6} + j = jours_dict[jour] + + h = time(int(heure[:-1]), 0) + + if matiere=="InfoTP": + d = timedelta(hours=2) + c2 = 9 + else: + d = timedelta(hours=1) + c2 = 3 + + print(f"--> Traitement de {c=}, {m=}, {j=}, {h=}, {d=}, {c2=}") + + if not Creneau.objects.filter(periode=periode, jour=j, heure=h, duree=d, matiere=m, colleur=c, est_colle=True, capacite=c2).exists(): + creneau = Creneau(periode=periode, jour=j, heure=h, duree=d, salle="nc", matiere=m, colleur=c, est_colle=True, capacite=c2) + creneau.save() + else: + creneau = Creneau.objects.get(periode=periode, jour=j, heure=h, duree=d, matiere=m, colleur=c, est_colle=True, capacite=c2) + + for i, r in enumerate(rotations): + sem = headers[4+i].split("/") + sem[2] = "20"+sem[2] + sem.reverse() + + s = date.fromisoformat("-".join(sem)) + (j-1) * timedelta(days=1) + + if not Rotation.objects.filter(creneau=creneau, date=s): + rot = Rotation(creneau=creneau, date=s) + rot.save() + else: + rot = Rotation.objects.get(creneau=creneau, date=s) + + rot.groupes.add(Groupe.objects.get(libelle=r)) + +def main(): + periode = Periode.objects.get(id=3) + scrape(periode, "colloscope.csv") + +if __name__ == "__main__": + main() diff --git a/static/table.css b/static/table.css new file mode 100644 index 0000000..f420455 --- /dev/null +++ b/static/table.css @@ -0,0 +1,29 @@ +table { + border: 1px solid #eee; + border-collapse: collapse; +} + +td, th { + border-bottom: 0; + border-top: 0; + border-left: 1px solid #eee; + border-right: 1px solid #eee; + padding: 5px 10px; + margin: 0; +} + +th { + border-bottom: 1px solid #eee; +} + +tr:nth-child(even) { + background-color: #fafafa; +} + +tr:hover, col:hover { + background-color: #f3f3f3; +} + +td:hover { + background-color: gold; +}