mirror of
https://github.com/ae-utbm/sith.git
synced 2025-01-22 06:51:09 +00:00
commit
c555d5c78c
@ -36,6 +36,11 @@
|
|||||||
&:not(:first-of-type) {
|
&:not(:first-of-type) {
|
||||||
margin: 2em 0 1em 0;
|
margin: 2em 0 1em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.feed {
|
||||||
|
float: right;
|
||||||
|
color: #f26522;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: $small-devices) {
|
@media screen and (max-width: $small-devices) {
|
||||||
|
@ -8,6 +8,9 @@
|
|||||||
{% block additional_css %}
|
{% block additional_css %}
|
||||||
<link rel="stylesheet" href="{{ static('com/css/news-list.scss') }}">
|
<link rel="stylesheet" href="{{ static('com/css/news-list.scss') }}">
|
||||||
<link rel="stylesheet" href="{{ static('com/components/ics-calendar.scss') }}">
|
<link rel="stylesheet" href="{{ static('com/components/ics-calendar.scss') }}">
|
||||||
|
|
||||||
|
{# Atom feed discovery, not really css but also goes there #}
|
||||||
|
<link rel="alternate" type="application/rss+xml" title="{% trans %}News feed{% endtrans %}" href="{{ url("com:news_feed") }}">
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block additional_js %}
|
{% block additional_js %}
|
||||||
@ -19,7 +22,10 @@
|
|||||||
<div id="news">
|
<div id="news">
|
||||||
<div id="left_column" class="news_column">
|
<div id="left_column" class="news_column">
|
||||||
{% set events_dates = NewsDate.objects.filter(end_date__gte=timezone.now(), start_date__lte=timezone.now()+timedelta(days=5), news__is_moderated=True).datetimes('start_date', 'day') %}
|
{% set events_dates = NewsDate.objects.filter(end_date__gte=timezone.now(), start_date__lte=timezone.now()+timedelta(days=5), news__is_moderated=True).datetimes('start_date', 'day') %}
|
||||||
<h3>{% trans %}Events today and the next few days{% endtrans %}</h3>
|
<h3>
|
||||||
|
{% trans %}Events today and the next few days{% endtrans %}
|
||||||
|
<a target="#" href="{{ url("com:news_feed") }}"><i class="fa fa-rss feed"></i></a>
|
||||||
|
</h3>
|
||||||
{% if user.is_authenticated and (user.is_com_admin or user.memberships.board().ongoing().exists()) %}
|
{% if user.is_authenticated and (user.is_com_admin or user.memberships.board().ongoing().exists()) %}
|
||||||
<a class="btn btn-blue margin-bottom" href="{{ url("com:news_new") }}">
|
<a class="btn btn-blue margin-bottom" href="{{ url("com:news_new") }}">
|
||||||
<i class="fa fa-plus"></i>
|
<i class="fa fa-plus"></i>
|
||||||
@ -73,7 +79,10 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<h3>{% trans %}All coming events{% endtrans %}</h3>
|
<h3>
|
||||||
|
{% trans %}All coming events{% endtrans %}
|
||||||
|
<a target="#" href="{{ url("com:news_feed") }}"><i class="fa fa-rss feed"></i></a>
|
||||||
|
</h3>
|
||||||
<ics-calendar locale="{{ get_language() }}"></ics-calendar>
|
<ics-calendar locale="{{ get_language() }}"></ics-calendar>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ from unittest.mock import patch
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.contrib.sites.models import Site
|
||||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
@ -24,7 +25,7 @@ from django.utils import html
|
|||||||
from django.utils.timezone import localtime, now
|
from django.utils.timezone import localtime, now
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
from model_bakery import baker
|
from model_bakery import baker
|
||||||
from pytest_django.asserts import assertRedirects
|
from pytest_django.asserts import assertNumQueries, assertRedirects
|
||||||
|
|
||||||
from club.models import Club, Membership
|
from club.models import Club, Membership
|
||||||
from com.models import News, NewsDate, Poster, Sith, Weekmail, WeekmailArticle
|
from com.models import News, NewsDate, Poster, Sith, Weekmail, WeekmailArticle
|
||||||
@ -319,3 +320,15 @@ class TestNewsCreation(TestCase):
|
|||||||
self.valid_payload,
|
self.valid_payload,
|
||||||
)
|
)
|
||||||
mocked.assert_called()
|
mocked.assert_called()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_feed(client):
|
||||||
|
"""Smoke test that checks that the atom feed is working"""
|
||||||
|
Site.objects.clear_cache()
|
||||||
|
with assertNumQueries(2):
|
||||||
|
# get sith domain with Site api: 1 request
|
||||||
|
# get all news and related info: 1 request
|
||||||
|
resp = client.get(reverse("com:news_feed"))
|
||||||
|
assert resp.status_code == 200
|
||||||
|
assert resp.headers["Content-Type"] == "application/rss+xml; charset=utf-8"
|
||||||
|
@ -25,6 +25,7 @@ from com.views import (
|
|||||||
NewsCreateView,
|
NewsCreateView,
|
||||||
NewsDeleteView,
|
NewsDeleteView,
|
||||||
NewsDetailView,
|
NewsDetailView,
|
||||||
|
NewsFeed,
|
||||||
NewsListView,
|
NewsListView,
|
||||||
NewsModerateView,
|
NewsModerateView,
|
||||||
NewsUpdateView,
|
NewsUpdateView,
|
||||||
@ -73,6 +74,7 @@ urlpatterns = [
|
|||||||
name="weekmail_article_edit",
|
name="weekmail_article_edit",
|
||||||
),
|
),
|
||||||
path("news/", NewsListView.as_view(), name="news_list"),
|
path("news/", NewsListView.as_view(), name="news_list"),
|
||||||
|
path("news/feed/", NewsFeed(), name="news_feed"),
|
||||||
path("news/admin/", NewsAdminListView.as_view(), name="news_admin_list"),
|
path("news/admin/", NewsAdminListView.as_view(), name="news_admin_list"),
|
||||||
path("news/create/", NewsCreateView.as_view(), name="news_new"),
|
path("news/create/", NewsCreateView.as_view(), name="news_new"),
|
||||||
path("news/<int:news_id>/edit/", NewsUpdateView.as_view(), name="news_edit"),
|
path("news/<int:news_id>/edit/", NewsUpdateView.as_view(), name="news_edit"),
|
||||||
|
30
com/views.py
30
com/views.py
@ -26,8 +26,10 @@ from datetime import timedelta
|
|||||||
from smtplib import SMTPRecipientsRefused
|
from smtplib import SMTPRecipientsRefused
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
from dateutil.relativedelta import relativedelta
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.mixins import AccessMixin, PermissionRequiredMixin
|
from django.contrib.auth.mixins import AccessMixin, PermissionRequiredMixin
|
||||||
|
from django.contrib.syndication.views import Feed
|
||||||
from django.core.exceptions import PermissionDenied, ValidationError
|
from django.core.exceptions import PermissionDenied, ValidationError
|
||||||
from django.db.models import Max
|
from django.db.models import Max
|
||||||
from django.forms.models import modelform_factory
|
from django.forms.models import modelform_factory
|
||||||
@ -268,6 +270,34 @@ class NewsDetailView(CanViewMixin, DetailView):
|
|||||||
return super().get_context_data(**kwargs) | {"date": self.object.dates.first()}
|
return super().get_context_data(**kwargs) | {"date": self.object.dates.first()}
|
||||||
|
|
||||||
|
|
||||||
|
class NewsFeed(Feed):
|
||||||
|
title = _("News")
|
||||||
|
link = reverse_lazy("com:news_list")
|
||||||
|
description = _("All incoming events")
|
||||||
|
|
||||||
|
def items(self):
|
||||||
|
return (
|
||||||
|
NewsDate.objects.filter(
|
||||||
|
news__is_moderated=True,
|
||||||
|
end_date__gte=timezone.now() - (relativedelta(months=6)),
|
||||||
|
)
|
||||||
|
.select_related("news", "news__author")
|
||||||
|
.order_by("-start_date")
|
||||||
|
)
|
||||||
|
|
||||||
|
def item_title(self, item: NewsDate):
|
||||||
|
return item.news.title
|
||||||
|
|
||||||
|
def item_description(self, item: NewsDate):
|
||||||
|
return item.news.summary
|
||||||
|
|
||||||
|
def item_link(self, item: NewsDate):
|
||||||
|
return item.news.get_absolute_url()
|
||||||
|
|
||||||
|
def item_author_name(self, item: NewsDate):
|
||||||
|
return item.news.author.get_display_name()
|
||||||
|
|
||||||
|
|
||||||
# Weekmail
|
# Weekmail
|
||||||
|
|
||||||
|
|
||||||
|
@ -92,7 +92,12 @@ class Command(BaseCommand):
|
|||||||
raise Exception("Never call this command in prod. Never.")
|
raise Exception("Never call this command in prod. Never.")
|
||||||
|
|
||||||
Sith.objects.create(weekmail_destinations="etudiants@git.an personnel@git.an")
|
Sith.objects.create(weekmail_destinations="etudiants@git.an personnel@git.an")
|
||||||
Site.objects.create(domain=settings.SITH_URL, name=settings.SITH_NAME)
|
|
||||||
|
site = Site.objects.get_current()
|
||||||
|
site.domain = settings.SITH_URL
|
||||||
|
site.name = settings.SITH_NAME
|
||||||
|
site.save()
|
||||||
|
|
||||||
groups = self._create_groups()
|
groups = self._create_groups()
|
||||||
self._create_ban_groups()
|
self._create_ban_groups()
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2025-01-10 14:52+0100\n"
|
"POT-Creation-Date: 2025-01-19 18:12+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"
|
||||||
@ -1447,7 +1447,7 @@ msgid "News admin"
|
|||||||
msgstr "Administration des nouvelles"
|
msgstr "Administration des nouvelles"
|
||||||
|
|
||||||
#: com/templates/com/news_admin_list.jinja com/templates/com/news_detail.jinja
|
#: com/templates/com/news_admin_list.jinja com/templates/com/news_detail.jinja
|
||||||
#: com/templates/com/news_list.jinja
|
#: com/templates/com/news_list.jinja com/views.py
|
||||||
msgid "News"
|
msgid "News"
|
||||||
msgstr "Nouvelles"
|
msgstr "Nouvelles"
|
||||||
|
|
||||||
@ -1525,6 +1525,10 @@ msgstr "Éditer (sera soumise de nouveau à la modération)"
|
|||||||
msgid "Edit news"
|
msgid "Edit news"
|
||||||
msgstr "Éditer la nouvelle"
|
msgstr "Éditer la nouvelle"
|
||||||
|
|
||||||
|
#: com/templates/com/news_list.jinja
|
||||||
|
msgid "News feed"
|
||||||
|
msgstr "Flux d'actualités"
|
||||||
|
|
||||||
#: com/templates/com/news_list.jinja
|
#: com/templates/com/news_list.jinja
|
||||||
msgid "Events today and the next few days"
|
msgid "Events today and the next few days"
|
||||||
msgstr "Événements aujourd'hui et dans les prochains jours"
|
msgstr "Événements aujourd'hui et dans les prochains jours"
|
||||||
@ -1767,6 +1771,10 @@ msgstr "Message d'alerte"
|
|||||||
msgid "Screens list"
|
msgid "Screens list"
|
||||||
msgstr "Liste d'écrans"
|
msgstr "Liste d'écrans"
|
||||||
|
|
||||||
|
#: com/views.py
|
||||||
|
msgid "All incoming events"
|
||||||
|
msgstr "Tous les événements à venir"
|
||||||
|
|
||||||
#: com/views.py
|
#: com/views.py
|
||||||
msgid "Delete and save to regenerate"
|
msgid "Delete and save to regenerate"
|
||||||
msgstr "Supprimer et sauver pour régénérer"
|
msgstr "Supprimer et sauver pour régénérer"
|
||||||
|
Loading…
Reference in New Issue
Block a user