+ """
""".format(
- _("Sujets similaires au vôtre :"), _("Aucun résultat")
+ reverse("search:similar"), _("Sujets similaires au vôtre :"), _("Aucun résultat")
)
),
CommonLayoutEditor(),
diff --git a/zds/forum/tests/tests_utils.py b/zds/forum/tests/tests_utils.py
new file mode 100644
index 0000000000..f0f03bf128
--- /dev/null
+++ b/zds/forum/tests/tests_utils.py
@@ -0,0 +1,31 @@
+from django.contrib.auth.models import Group
+from django.test import TestCase
+
+from zds.forum.tests.factories import create_category_and_forum
+from zds.forum.utils import get_authorized_forums_pk
+from zds.member.tests.factories import ProfileFactory, StaffProfileFactory
+
+
+class GetAuthorizedForumsTests(TestCase):
+ def test_get_authorized_forums_pk(self):
+ user = ProfileFactory().user
+ staff = StaffProfileFactory().user
+
+ # 1. Create a hidden forum belonging to a hidden staff group:
+ group = Group.objects.create(name="Les illuminatis anonymes de ZdS")
+ _, hidden_forum = create_category_and_forum(group)
+
+ staff.groups.add(group)
+ staff.save()
+
+ # 2. Create a public forum:
+ _, public_forum = create_category_and_forum()
+
+ # 3. Regular user can access only the public forum:
+ self.assertEqual(get_authorized_forums_pk(user), [public_forum.pk])
+
+ # 4. Staff user can access all forums:
+ self.assertEqual(sorted(get_authorized_forums_pk(staff)), sorted([hidden_forum.pk, public_forum.pk]))
+
+ # 5. By default, only public forums are available:
+ self.assertEqual(get_authorized_forums_pk(None), [public_forum.pk])
diff --git a/zds/forum/utils.py b/zds/forum/utils.py
index 353910605b..f24dfbd9b5 100644
--- a/zds/forum/utils.py
+++ b/zds/forum/utils.py
@@ -8,7 +8,7 @@
from django.views.generic import CreateView
from django.views.generic.detail import SingleObjectMixin
from django.utils.translation import gettext as _
-from zds.forum.models import Topic, Post
+from zds.forum.models import Forum, Topic, Post
from zds.member.views import get_client_ip
from zds.utils.misc import contains_utf8mb4
from zds.utils.mixins import QuoteMixin
@@ -198,3 +198,20 @@ def post(self, request, *args, **kwargs):
def create_forum(self, form_class, **kwargs):
raise NotImplementedError("`create_forum()` must be implemented.")
+
+
+def get_authorized_forums_pk(user):
+ """
+ Find forums the user is allowed to visit.
+
+ :param user: concerned user.
+ :return: pk of authorized forums
+ """
+ forums_pub = Forum.objects.filter(groups__isnull=True).all()
+ if user and user.is_authenticated:
+ forums_private = Forum.objects.filter(groups__isnull=False, groups__in=user.groups.all()).all()
+ list_forums = list(forums_pub | forums_private)
+ else:
+ list_forums = list(forums_pub)
+
+ return [f.pk for f in list_forums]
diff --git a/zds/mp/forms.py b/zds/mp/forms.py
index 3e6597669d..cf99988c61 100644
--- a/zds/mp/forms.py
+++ b/zds/mp/forms.py
@@ -16,9 +16,8 @@ class PrivateTopicForm(forms.Form, ParticipantsStringValidator, TitleValidator,
label=_("Participants"),
widget=forms.TextInput(
attrs={
- "placeholder": _("Les participants doivent " "être séparés par une virgule."),
+ "placeholder": _("Les participants doivent être séparés par une virgule."),
"required": "required",
- "data-autocomplete": '{ "type": "multiple", "url": "/api/membres/?search=%s" }',
}
),
)
@@ -40,6 +39,12 @@ class PrivateTopicForm(forms.Form, ParticipantsStringValidator, TitleValidator,
def __init__(self, username, *args, **kwargs):
super().__init__(*args, **kwargs)
+
+ self.fields["participants"].widget.attrs.update(
+ {
+ "data-autocomplete": '{ "type": "multiple", "url": "' + reverse("api:member:list") + '?search=%s" }',
+ }
+ )
self.helper = FormHelper()
self.helper.form_class = "content-wrapper"
self.helper.form_method = "post"
diff --git a/zds/searchv2/views.py b/zds/searchv2/views.py
index e78c9f7c43..73beed8d19 100644
--- a/zds/searchv2/views.py
+++ b/zds/searchv2/views.py
@@ -17,7 +17,7 @@
from zds.searchv2.forms import SearchForm
from zds.searchv2.models import ESIndexManager
from zds.utils.paginator import ZdSPagingListView
-from zds.utils.templatetags.authorized_forums import get_authorized_forums
+from zds.forum.utils import get_authorized_forums_pk
from functools import reduce
@@ -38,7 +38,7 @@ def get(self, request, *args, **kwargs):
results = []
if self.index_manager.connected_to_es and self.search_query:
- self.authorized_forums = get_authorized_forums(self.request.user)
+ self.authorized_forums = get_authorized_forums_pk(self.request.user)
search_queryset = Search()
query = (
@@ -90,7 +90,7 @@ def get(self, request, *args, **kwargs):
excluded_content_ids = request.GET.get("excluded", "").split(",")
results = []
if self.index_manager.connected_to_es and self.search_query:
- self.authorized_forums = get_authorized_forums(self.request.user)
+ self.authorized_forums = get_authorized_forums_pk(self.request.user)
search_queryset = Search()
if len(excluded_content_ids) > 0 and excluded_content_ids != [""]:
@@ -174,7 +174,7 @@ def get_queryset(self):
if self.search_query:
# Searches forums the user is allowed to visit
- self.authorized_forums = get_authorized_forums(self.request.user)
+ self.authorized_forums = get_authorized_forums_pk(self.request.user)
search_queryset = Search()
diff --git a/zds/tutorialv2/forms.py b/zds/tutorialv2/forms.py
index a83afa97b0..61479275bf 100644
--- a/zds/tutorialv2/forms.py
+++ b/zds/tutorialv2/forms.py
@@ -320,9 +320,7 @@ class EditContentTagsForm(forms.Form):
label=_("Tags séparés par des virgules (exemple : python,api,web) :"),
max_length=64,
required=False,
- widget=forms.TextInput(
- attrs={"data-autocomplete": '{ "type": "multiple", "fieldname": "title", "url": "/api/tags/?search=%s" }'}
- ),
+ widget=forms.TextInput(),
error_messages={"max_length": _("La liste de tags saisie dépasse la longueur maximale autorisée.")},
)
@@ -331,6 +329,14 @@ def __init__(self, content, db_content, *args, **kwargs):
kwargs["initial"] = {"tags": ", ".join(db_content.tags.values_list("title", flat=True))}
super(forms.Form, self).__init__(*args, **kwargs)
+ self.fields["tags"].widget.attrs.update(
+ {
+ "data-autocomplete": '{ "type": "multiple", "fieldname": "title", "url": "'
+ + reverse("api:utils:tags-list")
+ + '?search=%s" }',
+ }
+ )
+
self.helper = FormHelper()
self.helper.form_class = "content-wrapper"
self.helper.form_method = "post"
@@ -341,7 +347,9 @@ def __init__(self, content, db_content, *args, **kwargs):
HTML(
"""
Les tags permettent de grouper les publications plus finement que les catégories.
Par exemple, vous pouvez indiquer une technologie ou une sous-discipline.
- Consultez la page des tags pour voir des exemples."""
+ Consultez la page des tags pour voir des exemples.""".format(
+ reverse("content:tags")
+ )
),
Field("tags"),
ButtonHolder(StrictButton("Valider", type="submit")),
@@ -1302,21 +1310,23 @@ class SearchSuggestionForm(forms.Form):
suggestion_pk = forms.CharField(
label="Contenu à suggérer",
required=False,
- widget=forms.TextInput(
- attrs={
- "data-autocomplete": '{"type": "multiple_checkbox",'
- '"limit": 10,'
- '"fieldname": "title",'
- '"url": "/rechercher/suggestion-contenu/?q=%s&excluded=%e"}',
- "placeholder": "Rechercher un contenu",
- }
- ),
+ widget=forms.TextInput(),
)
excluded_pk = forms.CharField(required=False, widget=forms.HiddenInput(attrs={"class": "excluded_field"}))
def __init__(self, content, *args, **kwargs):
super().__init__(*args, **kwargs)
+ self.fields["suggestion_pk"].widget.attrs.update(
+ {
+ "data-autocomplete": '{"type": "multiple_checkbox",'
+ '"limit": 10,'
+ '"fieldname": "title",'
+ '"url": "' + reverse("search:suggestion") + '?q=%s&excluded=%e"}',
+ "placeholder": "Rechercher un contenu",
+ }
+ )
+
self.helper = FormHelper()
self.helper.form_action = reverse("content:add-suggestion", kwargs={"pk": content.pk})
self.helper.form_class = "modal modal-large"
@@ -1326,7 +1336,6 @@ def __init__(self, content, *args, **kwargs):
self.helper.layout = Layout(
Field("suggestion_pk"), Field("excluded_pk"), StrictButton(_("Ajouter"), type="submit")
)
- super().__init__(*args, **kwargs)
class RemoveSuggestionForm(forms.Form):
diff --git a/zds/utils/templatetags/authorized_forums.py b/zds/utils/templatetags/authorized_forums.py
deleted file mode 100644
index 8dcc78b39d..0000000000
--- a/zds/utils/templatetags/authorized_forums.py
+++ /dev/null
@@ -1,18 +0,0 @@
-from zds.forum.models import Forum
-
-
-def get_authorized_forums(user):
- """
- Find forums the user is allowed to visit.
-
- :param user: concerned user.
- :return: authorized_forums
- """
- forums_pub = Forum.objects.filter(groups__isnull=True).all()
- if user and user.is_authenticated:
- forums_private = Forum.objects.filter(groups__isnull=False, groups__in=user.groups.all()).all()
- list_forums = list(forums_pub | forums_private)
- else:
- list_forums = list(forums_pub)
-
- return [f.pk for f in list_forums]
diff --git a/zds/utils/templatetags/date.py b/zds/utils/templatetags/date.py
index f3f91e8ef1..91759df4ce 100644
--- a/zds/utils/templatetags/date.py
+++ b/zds/utils/templatetags/date.py
@@ -85,9 +85,10 @@ def tooltip_date(value):
@register.filter
-def humane_time(timestamp):
- """Render time (number of second from epoch) to an human readable string"""
- return format_date(datetime.fromtimestamp(timestamp))
+def date_from_timestamp(timestamp):
+ """Convert a timestamp (number of second from epoch) to a datetime object,
+ another filter should then be used to format the datetime object."""
+ return datetime.fromtimestamp(timestamp)
@register.filter
diff --git a/zds/utils/tests/tests_date.py b/zds/utils/tests/tests_date.py
index 3611395727..bd2fe7e978 100644
--- a/zds/utils/tests/tests_date.py
+++ b/zds/utils/tests/tests_date.py
@@ -76,8 +76,8 @@ def test_tooltip_date(self):
tr = Template("{% load date %}" "{{ NoneVal | tooltip_date }}").render(self.context)
self.assertEqual("None", tr)
- def test_humane_time(self):
+ def test_date_from_timestamp(self):
# Default behaviour
- tr = Template("{% load date %}" "{{ date_epoch | humane_time }}").render(self.context)
+ tr = Template("{% load date %}" "{{ date_epoch | date_from_timestamp | format_date }}").render(self.context)
self.assertEqual(tr, "jeudi 01 janvier 1970 à 01h00")