diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..8bf4d45
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,6 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..ba520cc
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+db.sqlite3
\ No newline at end of file
diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml
new file mode 100644
index 0000000..f1ffd8d
--- /dev/null
+++ b/.idea/dataSources.xml
@@ -0,0 +1,12 @@
+
+
+
+
+ sqlite.xerial
+ true
+ org.sqlite.JDBC
+ jdbc:sqlite:$PROJECT_DIR$/db.sqlite3
+ $ProjectFileDir$
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/colloscope/__init__.py b/colloscope/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/colloscope/admin.py b/colloscope/admin.py
new file mode 100644
index 0000000..8c38f3f
--- /dev/null
+++ b/colloscope/admin.py
@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.
diff --git a/colloscope/apps.py b/colloscope/apps.py
new file mode 100644
index 0000000..2c5cbed
--- /dev/null
+++ b/colloscope/apps.py
@@ -0,0 +1,6 @@
+from django.apps import AppConfig
+
+
+class ColloscopeConfig(AppConfig):
+ default_auto_field = 'django.db.models.BigAutoField'
+ name = 'colloscope'
diff --git a/colloscope/migrations/0001_initial.py b/colloscope/migrations/0001_initial.py
new file mode 100644
index 0000000..1e6583e
--- /dev/null
+++ b/colloscope/migrations/0001_initial.py
@@ -0,0 +1,40 @@
+# Generated by Django 5.0.4 on 2024-04-12 22:38
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Colleur',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('nom', models.CharField(max_length=100)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Etudiant',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('prenom', models.CharField(max_length=100)),
+ ('nom', models.CharField(max_length=100)),
+ ('groupe', models.IntegerField()),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Colle',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('groupe', models.IntegerField()),
+ ('date', models.DateTimeField()),
+ ('colleur', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='colloscope.colleur')),
+ ],
+ ),
+ ]
diff --git a/colloscope/migrations/__init__.py b/colloscope/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/colloscope/models.py b/colloscope/models.py
new file mode 100644
index 0000000..3c2c89f
--- /dev/null
+++ b/colloscope/models.py
@@ -0,0 +1,15 @@
+from django.db import models
+
+
+class Colleur(models.Model):
+ nom=models.CharField(max_length=100)
+
+class Etudiant(models.Model):
+ prenom=models.CharField(max_length=100)
+ nom=models.CharField(max_length=100)
+ groupe=models.IntegerField()
+
+class Colle(models.Model):
+ colleur=models.ForeignKey(Colleur, on_delete=models.CASCADE)
+ groupe=models.IntegerField()
+ date=models.DateTimeField()
diff --git a/colloscope/pdfexport.py b/colloscope/pdfexport.py
new file mode 100644
index 0000000..33a4c78
--- /dev/null
+++ b/colloscope/pdfexport.py
@@ -0,0 +1,172 @@
+from datetime import date, timedelta
+
+from fpdf import FPDF
+from fpdf.fonts import FontFace
+from fpdf.enums import TableCellFillMode
+
+sem_1 = date(2023, 9, 18)
+
+vacances_zoneA = [
+ ( 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, vac):
+ jour = sem_1 + (n-1) * timedelta(weeks=1)
+
+ for (debut, fin) in vac:
+ if jour >= debut:
+ jour += 2*timedelta(weeks=1)
+
+ return jour
+
+def generate():
+ pdf = FPDF(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")
+
+ etudiants = [
+ ["Aboujaib", "Alexandre", 4, "A", "Angl.", "All."],
+ ["Ajan", "George", 4, "A", "Angl.", ""],
+ ["Akrad", "Lina", 1, "SI", "Angl.", ""],
+ ["Aubert", "Nicolas", 1, "SI", "Angl.", ""],
+ ["Badr", "Roman", 4, "A", "Angl.", ""],
+ ["Bazire", "Aurélien", 5, "A", "Angl.", ""],
+ ["Boit", "Arthur", 1, "SI", "Angl.", ""],
+ ["Boubker", "Youssef", 1, "SI", "Angl.", ""],
+ ["Boudjema", "Dylan", 1, "SI", "Angl.", ""],
+ ["Chiriac", "Mihnea", 1, "SI", "Angl.", ""],
+ ["Courier", "Marine", 1, "SI", "Angl.", ""],
+ ["Daguin", "Joseph", 1, "SI", "Angl.", ""],
+ ["De Weer", "Matthias", 1, "SI", "Angl.", ""],
+ ["Desbouis", "Katell", 1, "SI", "Angl.", ""],
+ ["Dupouy", "Jérémie", 1, "SI", "Angl.", ""],
+ ["Hariri--Gautier-Picard", "Grégoire", 1, "SI", "Angl.", ""],
+ ["Juricevic", "Matteo", 1, "SI", "Angl.", ""],
+ ["Knanoua", "Anas", 1, "SI", "Angl.", ""],
+ ["Lesenne", "Pierrick", 1, "SI", "Angl.", ""],
+ ["Lin", "Hao", 1, "SI", "Angl.", ""],
+ ["Masbatin", "Lucas", 1, "SI", "Angl.", ""],
+ ["Mayuran", "Mithushan", 1, "SI", "Angl.", ""],
+ ["Messahli", "Yassine", 1, "SI", "Angl.", ""],
+ ["Moguérou", "Valentin", 10, "B", "Angl.", "All."],
+ ["Mohellebi", "Mathéo", 10, "B", "Angl.", "All."],
+ ["Mouisset--Ferrara", "Maël", 10, "B", "Angl.", "All."],
+ ["Ottavi", "Corentin", 10, "B", "Angl.", "All."],
+ ["Ponce", "Alexian", 10, "B", "Angl.", "All."],
+ ["Pujol", "Raphaël", 10, "B", "Angl.", "All."],
+ ["Pustetto", "Mathis", 10, "B", "Angl.", "All."],
+ ["Radice", "Roman", 10, "B", "Angl.", "All."],
+ ["Rat", "Evelyn", 10, "B", "Angl.", "All."],
+ ["Rousse", "Louis", 10, "B", "Angl.", "All."],
+ ["Roux", "Gaëtan", 10, "B", "Angl.", "All."],
+ ["Rouyre--Cros", "Célian", 10, "B", "Angl.", "All."],
+ ["Sourbé", "François-Gabriel", 10, "B", "Angl.", "All."],
+ ["Stourbe", "Simon", 10, "B", "Angl.", "All."],
+ ["Thai", "Dany", 10, "B", "Angl.", "All."],
+ ["Théodore", "Jonathan", 10, "B", "Angl.", "All."],
+ ["Vandroux", "Benoît", 10, "B", "Angl.", "All."],
+ ["Veyssière", "Thibaud", 10, "B", "Angl.", "All."],
+ ["Vié", "Adrien", 10, "B", "Angl.", "All."],
+ ["Ye", "Luan", 10, "B", "Angl.", "All."],
+ ["Zarka", "Amélie", 10, "B", "Angl.", "All."],
+ ]
+
+ 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),
+ ]
+
+ 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)
+
+ with pdf.table(
+ align="RIGHT",
+ col_widths=(50, 35, 12, 12, 12, 12),
+ 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[0].upper()) # Nom
+ row.cell(etu[1]) # Prénom
+ row.cell(str(etu[2])) # Groupe
+ row.cell(etu[3]) # TD
+ row.cell(etu[4]) # LV1
+ row.cell(etu[5]) # LV2
+
+ pdf.set_y(base_y)
+
+ with pdf.table(
+ align="LEFT",
+ width=190,
+ line_height=3,
+ col_widths=(25, 12, 10, 25, 12, *(10,)*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, vacances_zoneA).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()
+
+ pdf.output("test.pdf")
+
+if __name__ == "__main__":
+ generate()
diff --git a/colloscope/templates/colloscope.html b/colloscope/templates/colloscope.html
new file mode 100644
index 0000000..e768a2e
--- /dev/null
+++ b/colloscope/templates/colloscope.html
@@ -0,0 +1,52 @@
+{% load static %}
+
+
+
+
+
+ Colloscope
+
+
+
+
+ Universal Kholloscope Systems™
+
+
+
+
+
+
+
+ Programme de colles
+
+ Mathématiques : Dimension finie et matrices
+
+
+ Physique : Mécanique du solide
+
+
+
+ Colles cette semaine
+
+
+
+ - Groupe 1 : Physique dimanche 23h Newton
+ - Groupe 2 : Maths dimanche 23h Euler
+ - Groupe 3 : Anglais dimanche 23h Shakespeare
+ - Groupe 4 : Informatique dimanche 23h Turing
+ - Groupe 5 : Histoire dimanche 23h Tite-Live
+ - Groupe 6 : Philosophie dimanche 23h Descartes
+ - Groupe 7 : EPS dimanche 23h Bolt
+
+
+
+
+
+
+
diff --git a/colloscope/test.pdf b/colloscope/test.pdf
new file mode 100644
index 0000000..a3a217c
Binary files /dev/null and b/colloscope/test.pdf differ
diff --git a/colloscope/tests.py b/colloscope/tests.py
new file mode 100644
index 0000000..7ce503c
--- /dev/null
+++ b/colloscope/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/colloscope/urls.py b/colloscope/urls.py
new file mode 100644
index 0000000..344f355
--- /dev/null
+++ b/colloscope/urls.py
@@ -0,0 +1,6 @@
+from django.urls import path
+from . import views
+
+urlpatterns = [
+ path("colloscope/", views.colloscope, name="colloscope"),
+]
diff --git a/colloscope/views.py b/colloscope/views.py
new file mode 100644
index 0000000..ca03278
--- /dev/null
+++ b/colloscope/views.py
@@ -0,0 +1,6 @@
+from django.http import HttpResponse
+from django.template import loader
+
+def colloscope(request):
+ template = loader.get_template("colloscope.html")
+ return HttpResponse(template.render())
diff --git a/kholles_web/__init__.py b/kholles_web/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/kholles_web/asgi.py b/kholles_web/asgi.py
new file mode 100644
index 0000000..f3e3745
--- /dev/null
+++ b/kholles_web/asgi.py
@@ -0,0 +1,16 @@
+"""
+ASGI config for kholles_web project.
+
+It exposes the ASGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/
+"""
+
+import os
+
+from django.core.asgi import get_asgi_application
+
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'kholles_web.settings')
+
+application = get_asgi_application()
diff --git a/kholles_web/urls.py b/kholles_web/urls.py
new file mode 100644
index 0000000..0b2d6a4
--- /dev/null
+++ b/kholles_web/urls.py
@@ -0,0 +1,23 @@
+"""
+URL configuration for kholles_web project.
+
+The `urlpatterns` list routes URLs to views. For more information please see:
+ https://docs.djangoproject.com/en/5.0/topics/http/urls/
+Examples:
+Function views
+ 1. Add an import: from my_app import views
+ 2. Add a URL to urlpatterns: path('', views.home, name='home')
+Class-based views
+ 1. Add an import: from other_app.views import Home
+ 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
+Including another URLconf
+ 1. Import the include() function: from django.urls import include, path
+ 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
+"""
+from django.contrib import admin
+from django.urls import include, path
+
+urlpatterns = [
+ path('', include('colloscope.urls')),
+ path('admin/', admin.site.urls),
+]
diff --git a/kholles_web/wsgi.py b/kholles_web/wsgi.py
new file mode 100644
index 0000000..6815e91
--- /dev/null
+++ b/kholles_web/wsgi.py
@@ -0,0 +1,16 @@
+"""
+WSGI config for kholles_web project.
+
+It exposes the WSGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/
+"""
+
+import os
+
+from django.core.wsgi import get_wsgi_application
+
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'kholles_web.settings')
+
+application = get_wsgi_application()
diff --git a/manage.py b/manage.py
new file mode 100755
index 0000000..844f791
--- /dev/null
+++ b/manage.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+"""Django's command-line utility for administrative tasks."""
+import os
+import sys
+
+
+def main():
+ """Run administrative tasks."""
+ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'kholles_web.settings')
+ try:
+ from django.core.management import execute_from_command_line
+ except ImportError as exc:
+ raise ImportError(
+ "Couldn't import Django. Are you sure it's installed and "
+ "available on your PYTHONPATH environment variable? Did you "
+ "forget to activate a virtual environment?"
+ ) from exc
+ execute_from_command_line(sys.argv)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/static/main.css b/static/main.css
new file mode 100644
index 0000000..309f005
--- /dev/null
+++ b/static/main.css
@@ -0,0 +1,41 @@
+body {
+ font-family: sans-serif;
+ margin: 0;
+}
+
+main {
+ margin: 5px;
+}
+
+h1 {
+ text-align: center;
+}
+
+nav.semaine {
+ width: 100%;
+ display: flex;
+ background-color: #ddd;
+ justify-content: center;
+}
+
+nav.semaine .select, nav.semaine .label {
+ padding: 5px;
+ text-align: center;
+}
+
+nav.semaine .select { background-color: dodgerblue; color: white; width: 1em; }
+nav.semaine .select:hover { background-color: #0077ea; }
+
+nav.semaine .label:hover {
+ background-color: #ccc;
+}
+
+p.programme {
+ border-left: 5px solid gold;
+ padding: 10px;
+ background-color: #ffffdd;
+}
+
+footer {
+ text-align: center;
+}