mirror of
https://github.com/ae-utbm/sith.git
synced 2026-10-25 11:49:33 +00:00
Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d7e1cdafde | ||
|
|
93b6238c75 | ||
|
|
91865fe7a1 | ||
|
|
1e189f7b2b |
No files matched your search
@@ -0,0 +1,79 @@
|
|||||||
|
{% extends "core/base.jinja" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% if club.has_rights_in_club(user) %}
|
||||||
|
<a class="btn btn-blue" href="{{ url("com:news_new") }}">
|
||||||
|
<i class="fa fa-plus"></i> {% trans %}Create news{% endtrans %}
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% for semester_code, semester_events in events %}
|
||||||
|
<h3>{{ semester_code }}</h3>
|
||||||
|
{% for event in semester_events %}
|
||||||
|
<details class="accordion">
|
||||||
|
<summary>{{ event.title }}</summary>
|
||||||
|
<div class="accordion-content">
|
||||||
|
|
||||||
|
{# Events that occur weekly from the start to the end of the semester
|
||||||
|
would take a lot of space if shown by default.
|
||||||
|
Thus, if the event has more than one date, those are
|
||||||
|
hidden by a details element.
|
||||||
|
If there is only one date, it is directly displayed. #}
|
||||||
|
{% set dates = event.dates.all()|list %}
|
||||||
|
{% if dates|length == 1 %}
|
||||||
|
<em>
|
||||||
|
<time datetime="{{ dates[0].start_date.isoformat(timespec="seconds") }}">
|
||||||
|
{{ dates[0].start_date|localtime|date(DATETIME_FORMAT) }},
|
||||||
|
{{ dates[0].start_date|localtime|time(DATETIME_FORMAT) }}
|
||||||
|
</time> -
|
||||||
|
<time datetime="{{ dates[0].end_date.isoformat(timespec="seconds") }}">
|
||||||
|
{{ dates[0].end_date|localtime|date(DATETIME_FORMAT) }},
|
||||||
|
{{ dates[0].end_date|localtime|time(DATETIME_FORMAT) }}
|
||||||
|
</time>
|
||||||
|
</em>
|
||||||
|
{% else %}
|
||||||
|
<details>
|
||||||
|
<summary>
|
||||||
|
{% trans trimmed nb_occurrences=dates|length %}
|
||||||
|
Dates ({{ nb_occurrences }} occurrences)
|
||||||
|
{% endtrans %}
|
||||||
|
</summary>
|
||||||
|
<ul>
|
||||||
|
{% for d in dates %}
|
||||||
|
<li>
|
||||||
|
<time datetime="{{ d.start_date.isoformat(timespec="seconds") }}">
|
||||||
|
{{ d.start_date|localtime|date(DATETIME_FORMAT) }},
|
||||||
|
{{ d.start_date|localtime|time(DATETIME_FORMAT) }}
|
||||||
|
</time> -
|
||||||
|
<time datetime="{{ d.end_date.isoformat(timespec="seconds") }}">
|
||||||
|
{{ d.end_date|localtime|date(DATETIME_FORMAT) }},
|
||||||
|
{{ d.end_date|localtime|time(DATETIME_FORMAT) }}
|
||||||
|
</time>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</details>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<h4>{% trans %}Permalink{% endtrans %}</h4>
|
||||||
|
<p>{{ request.build_absolute_uri(event.get_absolute_url())|urlize }}</p>
|
||||||
|
|
||||||
|
<h4>{% trans %}Summary{% endtrans %}</h4>
|
||||||
|
{% if event.summary %}
|
||||||
|
{{ event.summary|markdown }}
|
||||||
|
{% else %}
|
||||||
|
<p><em>{% trans %}No summary{% endtrans %}</em></p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<h4>{% trans %}Description{% endtrans %}</h4>
|
||||||
|
{% if event.content %}
|
||||||
|
{{ event.content|markdown }}
|
||||||
|
{% else %}
|
||||||
|
<p><em>{% trans %}No detailed description{% endtrans %}</em></p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
{% endfor %}
|
||||||
|
<br />
|
||||||
|
{% endfor %}
|
||||||
|
{% endblock %}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
from django.test import RequestFactory, TestCase
|
||||||
|
from django.urls import reverse
|
||||||
|
from django.utils.timezone import get_current_timezone
|
||||||
|
from model_bakery import baker
|
||||||
|
|
||||||
|
from club.models import Club
|
||||||
|
from club.views import ClubNewsView
|
||||||
|
from com.models import News, NewsDate
|
||||||
|
from core.baker_recipes import subscriber_user
|
||||||
|
from core.models import User
|
||||||
|
|
||||||
|
|
||||||
|
class TestClubNews(TestCase):
|
||||||
|
@classmethod
|
||||||
|
def setUpTestData(cls):
|
||||||
|
cls.club = baker.make(Club)
|
||||||
|
cls.news = baker.make(
|
||||||
|
News, club=cls.club, is_published=True, author=baker.make(User), _quantity=5
|
||||||
|
)
|
||||||
|
d = datetime(year=2025, month=10, day=1, tzinfo=get_current_timezone())
|
||||||
|
dates = [
|
||||||
|
baker.prepare(NewsDate, news=cls.news[0], start_date=d),
|
||||||
|
baker.prepare(NewsDate, news=cls.news[0], start_date=d.replace(day=8)),
|
||||||
|
baker.prepare(NewsDate, news=cls.news[0], start_date=d.replace(day=15)),
|
||||||
|
baker.prepare(NewsDate, news=cls.news[1], start_date=d.replace(month=5)),
|
||||||
|
baker.prepare(NewsDate, news=cls.news[2], start_date=d.replace(month=4)),
|
||||||
|
baker.prepare(NewsDate, news=cls.news[3], start_date=d.replace(year=2024)),
|
||||||
|
baker.prepare(NewsDate, news=cls.news[4], start_date=d.replace(year=2020)),
|
||||||
|
]
|
||||||
|
NewsDate.objects.bulk_create(dates)
|
||||||
|
cls.url = reverse("club:news_list", kwargs={"club_id": cls.club.id})
|
||||||
|
|
||||||
|
def test_load_page(self):
|
||||||
|
"""Just test that the page loads."""
|
||||||
|
self.client.force_login(subscriber_user.make())
|
||||||
|
res = self.client.get(self.url)
|
||||||
|
assert res.status_code == 200
|
||||||
|
|
||||||
|
def test_page_data(self):
|
||||||
|
"""Test that we display the good events."""
|
||||||
|
# For this test, the object we want to test
|
||||||
|
# is built with `itertools.groupby`.
|
||||||
|
# However, it is consumed when rendering the template,
|
||||||
|
# making it unusable for later testing purposes,
|
||||||
|
# so we must use lower level django APIs in this test.
|
||||||
|
request = RequestFactory().get(self.url)
|
||||||
|
request.user = subscriber_user.make()
|
||||||
|
response = ClubNewsView.as_view()(request, club_id=self.club.id)
|
||||||
|
events = [
|
||||||
|
(semester_code, list(dates))
|
||||||
|
for semester_code, dates in response.context_data["events"]
|
||||||
|
]
|
||||||
|
assert events == [
|
||||||
|
("A25", [self.news[0]]),
|
||||||
|
("P25", [self.news[1], self.news[2]]),
|
||||||
|
("A24", [self.news[3]]),
|
||||||
|
("A20", [self.news[4]]),
|
||||||
|
]
|
||||||
@@ -31,6 +31,7 @@ from club.views import (
|
|||||||
ClubListView,
|
ClubListView,
|
||||||
ClubMailingView,
|
ClubMailingView,
|
||||||
ClubMembersView,
|
ClubMembersView,
|
||||||
|
ClubNewsView,
|
||||||
ClubOldMembersView,
|
ClubOldMembersView,
|
||||||
ClubPageEditView,
|
ClubPageEditView,
|
||||||
ClubPageHistView,
|
ClubPageHistView,
|
||||||
@@ -136,4 +137,5 @@ urlpatterns = [
|
|||||||
PosterDeleteView.as_view(),
|
PosterDeleteView.as_view(),
|
||||||
name="poster_delete",
|
name="poster_delete",
|
||||||
),
|
),
|
||||||
|
path("<int:club_id>/news/", ClubNewsView.as_view(), name="news_list"),
|
||||||
]
|
]
|
||||||
+35
-1
@@ -37,6 +37,7 @@ from django.contrib.messages.views import SuccessMessageMixin
|
|||||||
from django.core.exceptions import NON_FIELD_ERRORS, PermissionDenied, ValidationError
|
from django.core.exceptions import NON_FIELD_ERRORS, PermissionDenied, ValidationError
|
||||||
from django.core.paginator import InvalidPage, Paginator
|
from django.core.paginator import InvalidPage, Paginator
|
||||||
from django.db.models import F, Prefetch, Q, Sum
|
from django.db.models import F, Prefetch, Q, Sum
|
||||||
|
from django.db.models.expressions import OuterRef, Subquery
|
||||||
from django.db.models.functions import Length
|
from django.db.models.functions import Length
|
||||||
from django.http import Http404, StreamingHttpResponse
|
from django.http import Http404, StreamingHttpResponse
|
||||||
from django.shortcuts import get_object_or_404, redirect
|
from django.shortcuts import get_object_or_404, redirect
|
||||||
@@ -71,7 +72,7 @@ from club.models import (
|
|||||||
MailingSubscription,
|
MailingSubscription,
|
||||||
Membership,
|
Membership,
|
||||||
)
|
)
|
||||||
from com.models import Poster
|
from com.models import NewsDate, Poster
|
||||||
from com.views import (
|
from com.views import (
|
||||||
PosterCreateBaseView,
|
PosterCreateBaseView,
|
||||||
PosterDeleteBaseView,
|
PosterDeleteBaseView,
|
||||||
@@ -80,6 +81,7 @@ from com.views import (
|
|||||||
)
|
)
|
||||||
from core.auth.mixins import CanEditMixin, PermissionOrClubBoardRequiredMixin
|
from core.auth.mixins import CanEditMixin, PermissionOrClubBoardRequiredMixin
|
||||||
from core.models import Page, PageRev
|
from core.models import Page, PageRev
|
||||||
|
from core.utils import get_semester_code
|
||||||
from core.views import BasePageEditView, DetailFormView, UseFragmentsMixin
|
from core.views import BasePageEditView, DetailFormView, UseFragmentsMixin
|
||||||
from core.views.mixins import (
|
from core.views.mixins import (
|
||||||
AllowFragment,
|
AllowFragment,
|
||||||
@@ -134,6 +136,11 @@ class ClubTabsMixin(TabedViewMixin):
|
|||||||
"slug": "history",
|
"slug": "history",
|
||||||
"name": _("History"),
|
"name": _("History"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"url": reverse("club:news_list", kwargs={"club_id": self.object.id}),
|
||||||
|
"slug": "events",
|
||||||
|
"name": _("Events"),
|
||||||
|
},
|
||||||
]
|
]
|
||||||
if self.request.user.can_edit(self.object):
|
if self.request.user.can_edit(self.object):
|
||||||
tab_list.extend(
|
tab_list.extend(
|
||||||
@@ -935,3 +942,30 @@ class PosterDeleteView(ClubTabsMixin, PosterDeleteBaseView):
|
|||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
return reverse_lazy("club:poster_list", kwargs={"club_id": self.club.id})
|
return reverse_lazy("club:poster_list", kwargs={"club_id": self.club.id})
|
||||||
|
|
||||||
|
|
||||||
|
class ClubNewsView(PermissionRequiredMixin, ClubTabsMixin, DetailView):
|
||||||
|
pk_url_kwarg = "club_id"
|
||||||
|
model = Club
|
||||||
|
permission_required = "club.view_club"
|
||||||
|
template_name = "club/club_news_list.jinja"
|
||||||
|
current_tab = "events"
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs: Any):
|
||||||
|
events = list(
|
||||||
|
self.object.news.viewable_by(self.request.user)
|
||||||
|
.annotate(
|
||||||
|
first_date=Subquery(
|
||||||
|
NewsDate.objects.filter(news_id=OuterRef("pk"))
|
||||||
|
.order_by("start_date")
|
||||||
|
.values("start_date")[:1]
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.prefetch_related("dates")
|
||||||
|
.order_by("-first_date")
|
||||||
|
)
|
||||||
|
return super().get_context_data(**kwargs) | {
|
||||||
|
"events": itertools.groupby(
|
||||||
|
events, key=lambda event: get_semester_code(event.first_date.date())
|
||||||
|
),
|
||||||
|
}
|
||||||
+129
-24
@@ -6,7 +6,7 @@
|
|||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2026-10-19 19:45+0200\n"
|
"POT-Creation-Date: 2026-10-25 12:04+0100\n"
|
||||||
"PO-Revision-Date: 2016-07-18\n"
|
"PO-Revision-Date: 2016-07-18\n"
|
||||||
"Last-Translator: Maréchal <thomas.girod@utbm.fr\n"
|
"Last-Translator: Maréchal <thomas.girod@utbm.fr\n"
|
||||||
"Language-Team: AE info <ae.info@utbm.fr>\n"
|
"Language-Team: AE info <ae.info@utbm.fr>\n"
|
||||||
@@ -394,7 +394,8 @@ msgstr ""
|
|||||||
"de la présidence."
|
"de la présidence."
|
||||||
|
|
||||||
#: club/models.py core/models.py counter/models.py eboutic/models.py
|
#: club/models.py core/models.py counter/models.py eboutic/models.py
|
||||||
#: election/models.py pedagogy/models.py sas/models.py trombi/models.py
|
#: election/models.py pedagogy/models.py sas/models.py timetable/models.py
|
||||||
|
#: trombi/models.py
|
||||||
msgid "user"
|
msgid "user"
|
||||||
msgstr "utilisateur"
|
msgstr "utilisateur"
|
||||||
|
|
||||||
@@ -580,6 +581,7 @@ msgid "Role"
|
|||||||
msgstr "Rôle"
|
msgstr "Rôle"
|
||||||
|
|
||||||
#: club/templates/club/club_members.jinja
|
#: club/templates/club/club_members.jinja
|
||||||
|
#: club/templates/club/club_news_list.jinja
|
||||||
#: club/templates/club/club_old_members.jinja
|
#: club/templates/club/club_old_members.jinja
|
||||||
#: core/templates/core/group_list.jinja core/templates/core/user_clubs.jinja
|
#: core/templates/core/group_list.jinja core/templates/core/user_clubs.jinja
|
||||||
msgid "Description"
|
msgid "Description"
|
||||||
@@ -594,6 +596,34 @@ msgstr "Depuis"
|
|||||||
msgid "There are no members in this club."
|
msgid "There are no members in this club."
|
||||||
msgstr "Il n'y a pas de membres dans ce club."
|
msgstr "Il n'y a pas de membres dans ce club."
|
||||||
|
|
||||||
|
#: club/templates/club/club_news_list.jinja
|
||||||
|
#: com/templates/com/news_admin_list.jinja com/templates/com/news_edit.jinja
|
||||||
|
#: com/templates/com/news_list.jinja core/templates/core/user_tools.jinja
|
||||||
|
msgid "Create news"
|
||||||
|
msgstr "Créer une nouvelle"
|
||||||
|
|
||||||
|
#: club/templates/club/club_news_list.jinja
|
||||||
|
#, python-format
|
||||||
|
msgid "Dates (%(nb_occurrences)s occurrences)"
|
||||||
|
msgstr "Dates (%(nb_occurrences)s occurrences)"
|
||||||
|
|
||||||
|
#: club/templates/club/club_news_list.jinja
|
||||||
|
msgid "Permalink"
|
||||||
|
msgstr "Permalien"
|
||||||
|
|
||||||
|
#: club/templates/club/club_news_list.jinja
|
||||||
|
#: com/templates/com/news_admin_list.jinja
|
||||||
|
msgid "Summary"
|
||||||
|
msgstr "Résumé"
|
||||||
|
|
||||||
|
#: club/templates/club/club_news_list.jinja
|
||||||
|
msgid "No summary"
|
||||||
|
msgstr "Pas de Résumé"
|
||||||
|
|
||||||
|
#: club/templates/club/club_news_list.jinja
|
||||||
|
msgid "No detailed description"
|
||||||
|
msgstr "Pas de description détaillée"
|
||||||
|
|
||||||
#: club/templates/club/club_old_members.jinja
|
#: club/templates/club/club_old_members.jinja
|
||||||
msgid "Club old members"
|
msgid "Club old members"
|
||||||
msgstr "Anciens membres du club"
|
msgstr "Anciens membres du club"
|
||||||
@@ -1030,6 +1060,11 @@ msgstr "Anciens membres"
|
|||||||
msgid "History"
|
msgid "History"
|
||||||
msgstr "Historique"
|
msgstr "Historique"
|
||||||
|
|
||||||
|
#: club/views.py com/templates/com/news_admin_list.jinja
|
||||||
|
#: core/templates/core/base/navbar.jinja
|
||||||
|
msgid "Events"
|
||||||
|
msgstr "Événements"
|
||||||
|
|
||||||
#: club/views.py core/templates/core/base/header.jinja core/views/user.py
|
#: club/views.py core/templates/core/base/header.jinja core/views/user.py
|
||||||
#: sas/templates/sas/picture.jinja trombi/views.py
|
#: sas/templates/sas/picture.jinja trombi/views.py
|
||||||
msgid "Tools"
|
msgid "Tools"
|
||||||
@@ -1317,11 +1352,6 @@ msgstr "Administration des nouvelles"
|
|||||||
msgid "News"
|
msgid "News"
|
||||||
msgstr "Nouvelles"
|
msgstr "Nouvelles"
|
||||||
|
|
||||||
#: com/templates/com/news_admin_list.jinja com/templates/com/news_edit.jinja
|
|
||||||
#: com/templates/com/news_list.jinja core/templates/core/user_tools.jinja
|
|
||||||
msgid "Create news"
|
|
||||||
msgstr "Créer une nouvelle"
|
|
||||||
|
|
||||||
#: com/templates/com/news_admin_list.jinja
|
#: com/templates/com/news_admin_list.jinja
|
||||||
msgid "Weeklies"
|
msgid "Weeklies"
|
||||||
msgstr "Événements hebdomadaires"
|
msgstr "Événements hebdomadaires"
|
||||||
@@ -1336,10 +1366,6 @@ msgstr "Événements hebdomadaires affichées"
|
|||||||
msgid "Title"
|
msgid "Title"
|
||||||
msgstr "Titre"
|
msgstr "Titre"
|
||||||
|
|
||||||
#: com/templates/com/news_admin_list.jinja
|
|
||||||
msgid "Summary"
|
|
||||||
msgstr "Résumé"
|
|
||||||
|
|
||||||
#: com/templates/com/news_admin_list.jinja com/templates/com/weekmail.jinja
|
#: com/templates/com/news_admin_list.jinja com/templates/com/weekmail.jinja
|
||||||
#: forum/templates/forum/forum.jinja sas/models.py
|
#: forum/templates/forum/forum.jinja sas/models.py
|
||||||
msgid "Author"
|
msgid "Author"
|
||||||
@@ -1367,11 +1393,6 @@ msgstr "Dépublier"
|
|||||||
msgid "Weeklies to moderate"
|
msgid "Weeklies to moderate"
|
||||||
msgstr "Nouvelles hebdomadaires à modérer"
|
msgstr "Nouvelles hebdomadaires à modérer"
|
||||||
|
|
||||||
#: com/templates/com/news_admin_list.jinja
|
|
||||||
#: core/templates/core/base/navbar.jinja
|
|
||||||
msgid "Events"
|
|
||||||
msgstr "Événements"
|
|
||||||
|
|
||||||
#: com/templates/com/news_admin_list.jinja
|
#: com/templates/com/news_admin_list.jinja
|
||||||
msgid "Displayed events"
|
msgid "Displayed events"
|
||||||
msgstr "Événements affichés"
|
msgstr "Événements affichés"
|
||||||
@@ -1869,7 +1890,7 @@ msgstr "département"
|
|||||||
msgid "dpt option"
|
msgid "dpt option"
|
||||||
msgstr "Filière"
|
msgstr "Filière"
|
||||||
|
|
||||||
#: core/models.py pedagogy/models.py
|
#: core/models.py pedagogy/models.py timetable/models.py
|
||||||
msgid "semester"
|
msgid "semester"
|
||||||
msgstr "semestre"
|
msgstr "semestre"
|
||||||
|
|
||||||
@@ -1994,6 +2015,18 @@ msgstr ""
|
|||||||
"Autorise les cotisants (ou les personnes whitelistées, si votre profil est "
|
"Autorise les cotisants (ou les personnes whitelistées, si votre profil est "
|
||||||
"caché) à accéder aux statistiques de votre compte AE"
|
"caché) à accéder aux statistiques de votre compte AE"
|
||||||
|
|
||||||
|
#: core/models.py
|
||||||
|
msgid "show your timetable to others"
|
||||||
|
msgstr "montrez votre emploi du temps aux autres"
|
||||||
|
|
||||||
|
#: core/models.py
|
||||||
|
msgid ""
|
||||||
|
"Allow subscribers to see your timetable and to compare it to theirs (if you "
|
||||||
|
"have filled it)"
|
||||||
|
msgstr ""
|
||||||
|
"Permet aux cotisants de voir votre emploi du temps et de le comparer au leur "
|
||||||
|
"(si vous l'avez enregistré)"
|
||||||
|
|
||||||
#: core/models.py
|
#: core/models.py
|
||||||
msgid "get a notification for every click"
|
msgid "get a notification for every click"
|
||||||
msgstr "avoir une notification pour chaque click"
|
msgstr "avoir une notification pour chaque click"
|
||||||
@@ -5201,7 +5234,7 @@ msgstr "heures THE"
|
|||||||
msgid "hours TE"
|
msgid "hours TE"
|
||||||
msgstr "heures TE"
|
msgstr "heures TE"
|
||||||
|
|
||||||
#: pedagogy/models.py
|
#: pedagogy/models.py timetable/models.py
|
||||||
msgid "ue"
|
msgid "ue"
|
||||||
msgstr "UE"
|
msgstr "UE"
|
||||||
|
|
||||||
@@ -5999,6 +6032,46 @@ msgstr "Membre existant"
|
|||||||
msgid "the groups that can create subscriptions"
|
msgid "the groups that can create subscriptions"
|
||||||
msgstr "les groupes pouvant créer des cotisations"
|
msgstr "les groupes pouvant créer des cotisations"
|
||||||
|
|
||||||
|
#: timetable/models.py
|
||||||
|
msgid "timetable"
|
||||||
|
msgstr "emploi du temps"
|
||||||
|
|
||||||
|
#: timetable/models.py
|
||||||
|
msgid "timetables"
|
||||||
|
msgstr "emplois du temps"
|
||||||
|
|
||||||
|
#: timetable/models.py
|
||||||
|
msgid "weekday"
|
||||||
|
msgstr "jour de la semaine"
|
||||||
|
|
||||||
|
#: timetable/models.py
|
||||||
|
msgid "start at"
|
||||||
|
msgstr "début"
|
||||||
|
|
||||||
|
#: timetable/models.py
|
||||||
|
msgid "end at"
|
||||||
|
msgstr "fin"
|
||||||
|
|
||||||
|
#: timetable/models.py
|
||||||
|
msgid "course type"
|
||||||
|
msgstr "type de cours"
|
||||||
|
|
||||||
|
#: timetable/models.py
|
||||||
|
msgid "room"
|
||||||
|
msgstr "salle"
|
||||||
|
|
||||||
|
#: timetable/models.py
|
||||||
|
msgid "week group"
|
||||||
|
msgstr "groupe de semaine"
|
||||||
|
|
||||||
|
#: timetable/models.py
|
||||||
|
msgid "timetable slot"
|
||||||
|
msgstr "créneau d'emploi du temps"
|
||||||
|
|
||||||
|
#: timetable/models.py
|
||||||
|
msgid "timetable slots"
|
||||||
|
msgstr "créneaux d'emploi du temps"
|
||||||
|
|
||||||
#: timetable/templates/timetable/generator.jinja
|
#: timetable/templates/timetable/generator.jinja
|
||||||
msgid "Timetable generator"
|
msgid "Timetable generator"
|
||||||
msgstr "Générateur d'emploi du temps"
|
msgstr "Générateur d'emploi du temps"
|
||||||
@@ -6029,8 +6102,44 @@ msgid "Generate"
|
|||||||
msgstr "Générer"
|
msgstr "Générer"
|
||||||
|
|
||||||
#: timetable/templates/timetable/generator.jinja
|
#: timetable/templates/timetable/generator.jinja
|
||||||
msgid "Save to PNG"
|
msgid "Save on your profile"
|
||||||
msgstr "Sauver en PNG"
|
msgstr "Enregistrer sur votre profil"
|
||||||
|
|
||||||
|
#: timetable/templates/timetable/generator.jinja
|
||||||
|
msgid "Make this timetable public"
|
||||||
|
msgstr "Rendre cet emploi du temps publique"
|
||||||
|
|
||||||
|
#: timetable/templates/timetable/generator.jinja
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"You can change this at any time in <a href=\"%(url)s\">your preferences</a>"
|
||||||
|
msgstr ""
|
||||||
|
"Vous pouvez changer ceci n'importe quand dans <a href=\"%(url)s\">vos préférences</a>"
|
||||||
|
|
||||||
|
#: timetable/templates/timetable/generator.jinja
|
||||||
|
msgid "Save timetable"
|
||||||
|
msgstr "Enregistrer l'emploi du temps"
|
||||||
|
|
||||||
|
#: timetable/templates/timetable/generator.jinja
|
||||||
|
#: trombi/templates/trombi/detail.jinja
|
||||||
|
msgid "Export"
|
||||||
|
msgstr "Export"
|
||||||
|
|
||||||
|
#: timetable/templates/timetable/generator.jinja
|
||||||
|
msgid "Export to PNG"
|
||||||
|
msgstr "Exporter en PNG"
|
||||||
|
|
||||||
|
#: timetable/views.py
|
||||||
|
msgid "Timetables"
|
||||||
|
msgstr "Emplois du temps"
|
||||||
|
|
||||||
|
#: timetable/views.py
|
||||||
|
msgid "Generator"
|
||||||
|
msgstr "Générateur"
|
||||||
|
|
||||||
|
#: timetable/views.py
|
||||||
|
msgid "My timetables"
|
||||||
|
msgstr "Mes emplois du temps"
|
||||||
|
|
||||||
#: trombi/models.py
|
#: trombi/models.py
|
||||||
msgid "subscription deadline"
|
msgid "subscription deadline"
|
||||||
@@ -6145,10 +6254,6 @@ msgstr "Fin des inscriptions : "
|
|||||||
msgid "Comment deadline: "
|
msgid "Comment deadline: "
|
||||||
msgstr "Fin des commentaires : "
|
msgstr "Fin des commentaires : "
|
||||||
|
|
||||||
#: trombi/templates/trombi/detail.jinja
|
|
||||||
msgid "Export"
|
|
||||||
msgstr "Exporter"
|
|
||||||
|
|
||||||
#: trombi/templates/trombi/detail.jinja
|
#: trombi/templates/trombi/detail.jinja
|
||||||
msgid "Add user"
|
msgid "Add user"
|
||||||
msgstr "Ajouter une personne"
|
msgstr "Ajouter une personne"
|
||||||
|
|||||||
Reference in new issue
Block a user