Présentation du site

This commit is contained in:
Valentin Moguérou 2024-05-12 18:24:32 +02:00
parent 92d4c851a3
commit f381b4dd44
22 changed files with 191 additions and 1298 deletions

View File

@ -383,6 +383,9 @@ class Colle(models.Model):
# func = async_to_sync(swap.notify)
# func()
def week_number(self):
return self.slot.term.cls.week_number(self.datetime.date())
def __str__(self):
return f"Colle {self.slot.subject} ({self.slot.colleur}); {self.datetime} {self.slot.time} {self.slot.room}. Groupe(s) {{{'; '.join(str(groupe) for groupe in self.groups.all())}}}"

View File

@ -13,30 +13,33 @@
Bienvenue {{ student }}. Votre lycée est {{ term.cls.school.description }}, et votre classe est {{ term.cls.description }}.
</p>
<p>Période actuelle : {{ term }}. Votre groupe de colle est {{ group }}. <a href="table.html">Consulter le colloscope</a></p>
<p>Période actuelle : {{ term }}. Votre groupe de colle est {{ group }}. <a href="{% url "colloscope:table" %}">Consulter le colloscope</a></p>
<h2>Mes colles</h2>
<p><a href="{{ calendar_link }}"><i class="fa-regular fa-calendar"></i> Exporter en .ics (ceci est un permalien public)</a></p>
<p><a href="{% url "colloscope.marketplace" %}">Accéder au marketplace</a></p>
<p><a href="{% url "colloscope:marketplace" %}">Accéder au marketplace</a></p>
{% for n, lundi, colles in colles_per_sem %}
{% if colles %}
<h3 class="week">Semaine {{n}} ({{lundi}})</h3>
<h3 class="week" id="week-no-{{ n }}">
<a href="#week-no-{{ n }}">Semaine {{n}} ({{lundi}})</a>
</h3>
<div class="colle-wrapper">
{% for colle in colles %}
<div class="colle">
<span class="summary">{{ colle.slot.subject }} ({{ colle.slot.colleur }})</span>
<ul>
<li><i class="fa-solid fa-clock"></i> Le {{ colle.datetime|date:"l" }} {{ colle.datetime|date:"DATETIME_FORMAT" }}</li>
<li><i class="fa-solid fa-graduation-cap"></i> {{ colle.slot.subject }}</li>
<li><i class="fa-solid fa-person-chalkboard"></i> {{ colle.slot.colleur }}</li>
<li><i class="fa-solid fa-clock"></i> {{ colle.datetime|date:"l"|title }} {{ colle.datetime|date:"DATETIME_FORMAT" }}</li>
<li><i class="fa-solid fa-users"></i> {{ colle.groups.all | print_manager | safe }} ({{ colle.volume }} / {{ colle.slot.capacity }})</li>
<li><i class="fa-solid fa-earth-americas"></i> {{ colle.slot.room }}</li>
<li><i class="fa-solid fa-circle-exclamation"></i>
<form
action="{% url "colloscope.withdraw" %}"
action="{% url "colloscope:withdraw" %}"
method="POST"
onsubmit="return confirm('Êtes-vous sûr de vouloir vous désinscrire de la colle {{ colle }} ');">
{% csrf_token %}

View File

@ -15,13 +15,14 @@
<div class="colle-wrapper">
{% for colle in colles %}
<div class="colle">
<span class="summary">{{ colle.slot.subject }} ({{ colle.slot.colleur }})</span>
<ul>
<li><i class="fa-solid fa-clock"></i> Le {{ colle.datetime|date:"l" }} {{ colle.datetime|date:"DATETIME_FORMAT" }}</li>
<li><i class="fa-solid fa-graduation-cap"></i> {{ colle.slot.subject }}</li>
<li><i class="fa-solid fa-person-chalkboard"></i> {{ colle.slot.colleur }}</li>
<li><i class="fa-solid fa-clock"></i> {{ colle.datetime|date:"l"|title }} {{ colle.datetime|date:"DATETIME_FORMAT" }}</li>
<li><i class="fa-solid fa-users"></i> {{ colle.groups.all | print_manager | safe }} ({{ colle.volume }} / {{ colle.slot.capacity }})</li>
<li><i class="fa-solid fa-earth-americas"></i> {{ colle.slot.room }}</li>
<li><i class="fa-solid fa-circle-exclamation"></i>
<form action="{% url "colloscope.enroll" %}"
<form action="{% url "colloscope:enroll" %}"
method="POST"
onsubmit="return confirm('Êtes-vous sûr de vouloir vous inscrire à la colle {{ colle }} ');">
{% csrf_token %}

View File

@ -13,12 +13,12 @@
<h1>Colloscope</h1>
<p>
Lycée : {{ term.cls.school.description }}. Classe : {{ term.cls.description }}. <a href="dashboard.html">Retour au tableau de bord</a>
Lycée : {{ term.cls.school.description }}. Classe : {{ term.cls.description }}. <a href="{% url "colloscope:table" %}">Retour au tableau de bord</a>
</p>
<h2>Colloscope : {{ term.description }}</h2>
<form method="get" action="{% url "colloscope.table" %}">
<form method="get" action="{% url "colloscope:table" %}">
Changer de période&nbsp;:
<select name="term" id="term">
{% for p in term.cls.term_set.all %}

View File

@ -1,14 +1,15 @@
from django.urls import path
from django.shortcuts import redirect
from . import views
urlpatterns = [
path("", views.home_redirect, name="colloscope.home"),
path("table.html", views.colloscope, name="colloscope.table"),
path("dashboard.html", views.dashboard, name="colloscope.dashboard"),
path("export.pdf", views.export, name="colloscope.export"),
path("export/calendar/<str:key>/calendar.ics", views.icalendar, name="colloscope.calendar.ics"),
path("select_profile", views.select_profile, name="colloscope.select_profile"),
path("marketplace.html", views.marketplace, name="colloscope.marketplace"),
path("action/enroll", views.enroll, name="colloscope.enroll"),
path("action/withdraw", views.withdraw, name="colloscope.withdraw"),
path("", lambda req: redirect("colloscope:dashboard"), name="home"),
path("table", views.colloscope, name="table"),
path("dashboard", views.dashboard, name="dashboard"),
path("export.pdf", views.export, name="export"),
path("export/calendar/<str:key>/calendar.ics", views.icalendar, name="export-ics"),
path("select_profile", views.select_profile, name="select_profile"),
path("marketplace", views.marketplace, name="marketplace"),
path("action/enroll", views.enroll, name="enroll"),
path("action/withdraw", views.withdraw, name="withdraw"),
]

View File

@ -6,6 +6,8 @@ from django.http import HttpResponse, HttpResponseRedirect
from django.template import loader
from django.views.decorators.http import require_POST
from django.contrib.auth.decorators import login_required
from django.views.generic import ListView
from django.utils.translation import gettext_lazy as _
from colloscope.models import *
from colloscope.pdfexport import handle
@ -13,13 +15,8 @@ from colloscope.icalexport import to_calendar
def handler404(request):
template = loader.get_template("404.html")
context = {}
return HttpResponse(template.render(context), status=404)
def home_redirect(request):
return redirect("/colloscope/dashboard.html")
return render(request, '404.html', context, status=404)
@login_required
@ -35,10 +32,10 @@ def select_profile(request):
if profile.student is not None and profile.colleur is None:
session["profile"] = "student"
return redirect("/colloscope/")
return redirect("colloscope:home")
elif profile.colleur is not None and profile.student is None:
session["profile"] = "colleur"
return redirect("/colloscope/")
return redirect("colloscope:home")
else:
if profile.student is not None:
template = loader.get_template("select_profile.html")
@ -51,16 +48,11 @@ def select_profile(request):
return HttpResponse(template.render(context))
def get_lien_calendrier(student, term):
try:
lien = CalendarLink.objects.get(student=student, term=term)
except CalendarLink.DoesNotExist:
key = uuid4().hex
lien = CalendarLink(key=key, student=student, term=term)
lien.save()
return f"calendrier.ics?key={lien.key}"
class ColleListView(ListView):
model = Colle
def get_queryset(self):
pass
@login_required
def dashboard(request):
@ -72,7 +64,7 @@ def dashboard(request):
.prefetch_related("student__cls__term_set"))
)
except ValueError:
return redirect("colloscope.select_profile")
return redirect("colloscope:select_profile")
if not isinstance(student, Student):
return HttpResponse("pas encore supporté")
@ -124,10 +116,10 @@ def marketplace(request):
.prefetch_related("student__cls__term_set"))
)
except ValueError:
return redirect("colloscope.select_profile")
return redirect("colloscope:select_profile")
if not isinstance(student, Student):
return HttpResponse("pas encore supporté")
return HttpResponse(_("Not supported yet."))
term = student.cls.current_term()
colles = term.query_colles_not_full_excluding_student(student)

0
front/__init__.py Normal file
View File

3
front/admin.py Normal file
View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

6
front/apps.py Normal file
View File

@ -0,0 +1,6 @@
from django.apps import AppConfig
class FrontConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'front'

View File

3
front/models.py Normal file
View File

@ -0,0 +1,3 @@
from django.db import models
# Create your models here.

View File

@ -0,0 +1,50 @@
{% extends "base.html" %}
{% load i18n %}
{% block title %}Accueil{% endblock %}
{% block main %}
<h1>{% translate "Your colloscope. Online." %}</h1>
<p>
Certifié le dernier colloscope dont vous aurez besoin. Avec ses fonctionalités de synchronisation, il reste
toujours à jour pour vous permettre d'aborder vos colles sereinement, si vous connaissez votre cours (apprentissage
du cours non fourni).
</p>
<h2>Soyez le premier informé lors d'une modification</h2>
<p>
Lorsqu'une colle est modifiée, le modification se propage à l'ensemble des pages visibles par les utilisateurs.
Aucune excuse pour manquer sa colle.
</p>
<h2>Échangez vos colles en toute confiance</h2>
<p>
Vous ne pouvez pas venir à une colle&nbsp;? Aucun problème&nbsp;: il vous suffit de l'échanger&nbsp;!
Le <em>Marketplace</em> intégré vous donne la possibilité de récupérer des colles disponibles.
</p>
<h2>Un système interopérable</h2>
<p>
Vous pouvez synchroniser vos colles avec votre application de calendrier favorite. Il lui suffit de supporter
les liens iCalendar. C'est le cas de l'application Calendrier sur iOS, de OneCalendar sur Android et de
Mozilla Thunderbird sur GNU/Linux et macOS (et Microsoft Windows).
</p>
<h2>Pensé par un nerd, pour les nerds.</h2>
<p>
Un système complet d'API REST vous permet d'intégrer ce colloscope à vos programmes tiers.
</p>
<h2>Libre, pour toujours.</h2>
<p>
Colloscope est distribué avec la licence GNU Affero GPL. Cette licence garantit vos quatre libertés, à savoir&nbsp;:
</p>
<ol start=0>
<li>Exécutez le code librement&nbsp;;</li>
<li>Modifiez le code librement&nbsp;;</li>
<li>Distribuez le code librement&nbsp;;</li>
<li>Distribuez librement des versions modifiées du code.</li>
</ol>
{% endblock %}

3
front/tests.py Normal file
View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

8
front/urls.py Normal file
View File

@ -0,0 +1,8 @@
from django.urls import path
from django.shortcuts import redirect
from . import views
urlpatterns = [
path("", views.index, name="index"),
]

8
front/views.py Normal file
View File

@ -0,0 +1,8 @@
from django.shortcuts import render
# Create your views here.
def index(request):
context = {}
return render(request, "index.html", context)

View File

@ -52,6 +52,7 @@ INSTALLED_APPS = [
"rest_framework",
'rest_framework_simplejwt',
'colloscope',
"front",
"drf_spectacular",
]
@ -156,8 +157,8 @@ STATICFILES_FINDERS = [
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
LOGIN_URL = "/accounts/login"
LOGIN_REDIRECT_URL = "home"
LOGOUT_REDIRECT_URL = "home"
LOGIN_REDIRECT_URL = "colloscope:dashboard"
LOGOUT_REDIRECT_URL = "front:index"
DISCORD_NOTIFY_WEBHOOK_URL = "https://discord.com/api/webhooks/YOUR_URL"
DISCORD_NOTIFY_WEBHOOK_USERNAME = "Watchdog"

View File

@ -23,9 +23,8 @@ from rest_framework_simplejwt.views import (
TokenObtainPairView,
TokenRefreshView,
)
from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView
from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView
from colloscope.views import home_redirect
from colloscope.viewsets import *
router = routers.SimpleRouter()
@ -43,7 +42,9 @@ router.register("calendarlink", CalendarLinkViewset, basename='calendarlink')
urlpatterns = [
path('', home_redirect, name="home"),
path('', include(("front.urls", "front"), namespace="front")),
path("__debug__/", include("debug_toolbar.urls")),
path('api-auth/', include('rest_framework.urls')),
path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
@ -55,7 +56,7 @@ urlpatterns = [
path("oauth2/", include('oauth2_provider.urls', namespace='oauth2_provider')),
path("favicon.ico", lambda req: vstatic.serve(req, "favicon.ico")),
path('colloscope/', include('colloscope.urls')),
path('colloscope/', include(('colloscope.urls', "colloscope"), namespace="colloscope")),
path('admin/', admin.site.urls),
path('accounts/', include("django.contrib.auth.urls")),
]

File diff suppressed because it is too large Load Diff

View File

@ -1239,3 +1239,13 @@ msgstr ""
#: venv/lib/python3.12/site-packages/django/views/templates/default_urlconf.html:248
msgid "Connect, get help, or contribute"
msgstr ""
#: colloscope/views.py:122
msgid "Not supported yet."
msgstr "Pas encore supporté."
#: front/templates/index.html:7
msgid "Your colloscope. Online."
msgstr "Votre colloscope. En ligne."

View File

@ -7,6 +7,15 @@ body {
margin: 0;
}
a:link, a:visited {
color: blue;
text-decoration: underline;
}
a:link:active, a:visited:active {
color: darkblue;
}
header .bandeau {
display: block;
background-color: #333;
@ -129,7 +138,11 @@ nav.semaine .select, nav.semaine .label {
text-align: center;
}
nav.semaine .select { background-color: dodgerblue; color: white; width: 1em; }
nav.semaine .select {
background-color: dodgerblue;
color: white;
width: 1em;
}
nav.semaine .select:hover { background-color: #0077ea; }
nav.semaine .label:hover {
@ -151,7 +164,19 @@ footer {
.week {
background-color: dodgerblue;
color: white;
padding: 5px;
padding: 5px 10px;
border-radius: 5px;
transition: background-color 200ms;
}
.week a, .week a:hover, .week a:active {
color: white;
text-decoration: none;
}
.week:hover {
background-color: #0077ea;
}
.week.empty {
@ -160,7 +185,7 @@ footer {
.colle-wrapper {
display: grid;
gap: 10px;
gap: 15px;
}
@media screen and (min-width: 400px)
@ -171,8 +196,16 @@ footer {
}
.colle {
border: 1px solid black;
padding: 10px;
padding: 15px;
border-radius: 8px;
box-shadow: 0 3px 6px rgba(0,0,0,0.04),0 3px 6px rgba(0,0,0,0.0575);
transition: transform 200ms, background-color 200ms;
}
.colle:hover {
background-color: #fafafa;
transform: rotate(1deg);
}
.colle span {
@ -181,6 +214,7 @@ footer {
.colle ul {
padding: 0;
margin: 0;
}
.colle li {

@ -1 +1 @@
Subproject commit 9e2427d5ae8e7fafef9fe001394e9566e181f217
Subproject commit 811b224d6a8a644dffd6c34cb54acbbd1a0f4db0

View File

@ -25,27 +25,34 @@
<div class="link"><a href="https://mp2i-vms.fr/pages.html"><i class="fa-solid fa-house"></i> Pages personnelles</a></div>
<div class="link"><a href="https://git.mp2i-vms.fr"><i class="fa-brands fa-git-alt"></i> Git</a></div>
<div class="link"><a href="https://play.mp2i-vms.fr"><i class="fa-solid fa-cubes"></i> Minecraft</a></div>
<div class="link"><a href="{% url "home" %}"><i class="fa-solid fa-book"></i> Colles</a></div>
<div class="link"><a href="{% url "front:index" %}"><i class="fa-solid fa-book"></i> Colles</a></div>
</div>
</div>
</div>
<div class="navbar">
<div class="block">
<a href="{% url "front:index" %}">
<div class="link"><i class="fa-solid fa-home"></i> Accueil</div>
</a>
{% if request.user.is_authenticated %}
<a href="{% url "colloscope.dashboard" %}">
<a href="{% url "colloscope:dashboard" %}">
<div class="link"><i class="fa-solid fa-rocket"></i> Tableau de bord</div>
</a>
<a href="{% url "colloscope.table" %}">
<a href="{% url "colloscope:table" %}">
<div class="link"><i class="fa-solid fa-calendar"></i> Colloscope</div>
</a>
<a href="{% url "colloscope.marketplace" %}">
<a href="{% url "colloscope:marketplace" %}">
<div class="link"><i class="fa-solid fa-shop"></i> Marketplace</div>
</a>
{% endif %}
</div>
<div class="block">
{% if request.user.is_authenticated %}
<div class="link">
<i class="fa-solid fa-user"></i> {{ user.username }} ({{ request.session.profile }})
</div>
<form action="{% url 'logout' %}" method="post">
{% csrf_token %}
<button class="link" type="submit" href="{% url "login" %}">
@ -66,6 +73,6 @@
{% block main %}{% endblock main %}
</main>
<footer>
{% block footer %}&copy; colles.mp2i-vms.fr 2024 - <a href="https://git.mp2i-vms.fr/mp2i-vms/kholles-web" target="_blank">Code source</a> - <a href="https://www.gnu.org/licenses/agpl-3.0.html" target="_blank">Licence GNU AGPL v3 or later</a>{% endblock footer %}
{% block footer %}&copy; colles.mp2i-vms.fr 2024 - <a href="https://git.mp2i-vms.fr/mp2i-vms/colles.mp2i-vms.fr" target="_blank">Code source</a> - <a href="https://www.gnu.org/licenses/agpl-3.0.html" target="_blank">Licence GNU AGPL v3 or later</a>{% endblock footer %}
</footer>
</body>