Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Permet les suggestions sur les billets #6666

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ <h3>Éditorialisation</h3>
</li>
{% endif %}

{% if perms.tutorialv2.change_publishablecontent and not content.is_opinion %}
{% if perms.tutorialv2.change_publishablecontent %}
<li>
<a href="#add-suggestion" class="open-modal ico-after more blue">
{% trans "Ajouter une suggestion" %}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Generated by Django 4.2.16 on 2024-10-18 19:39

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
("tutorialv2", "0041_remove_must_reindex"),
]

operations = [
migrations.AlterModelOptions(
name="contentsuggestion",
options={"verbose_name": "Suggestion de publication", "verbose_name_plural": "Suggestions de publication"},
),
migrations.AlterField(
model_name="contentsuggestion",
name="publication",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="publication",
to="tutorialv2.publishablecontent",
verbose_name="Publication",
),
),
]
8 changes: 4 additions & 4 deletions zds/tutorialv2/models/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
from zds.tutorialv2.models.goals import Goal
from zds.tutorialv2.models.labels import Label
from zds.tutorialv2.models.mixins import TemplatableContentModelMixin, OnlineLinkableContentMixin
from zds.tutorialv2.models.versioned import NotAPublicVersion, VersionedContent
from zds.tutorialv2.models.versioned import NotAPublicVersion
from zds.tutorialv2.utils import get_content_from_json, BadManifestError, get_blob
from zds.utils import get_current_user
from zds.utils.models import Category, SubCategory, Licence, Comment, Tag
Expand Down Expand Up @@ -1572,13 +1572,13 @@ def __str__(self):

class ContentSuggestion(models.Model):
class Meta:
verbose_name = "Suggestion de contenu"
verbose_name_plural = "Suggestions de contenu"
verbose_name = "Suggestion de publication"
verbose_name_plural = "Suggestions de publication"

publication = models.ForeignKey(
PublishableContent,
null=False,
verbose_name="Contenu",
verbose_name="Publication",
db_index=True,
on_delete=models.CASCADE,
related_name="publication",
Expand Down
6 changes: 3 additions & 3 deletions zds/tutorialv2/models/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from zds.tutorialv2.views.beta import ManageBetaContent
from zds.tutorialv2.views.canonical import EditCanonicalLinkView
from zds.tutorialv2.views.contributors import AddContributorToContent, RemoveContributorFromContent
from zds.tutorialv2.views.suggestions import AddSuggestion, RemoveSuggestion
from zds.tutorialv2.views.suggestions import AddSuggestionView, RemoveSuggestionView
from zds.tutorialv2.views.tags import EditTags
from zds.tutorialv2.views.goals import EditGoals
from zds.tutorialv2.views.labels import EditLabels
Expand Down Expand Up @@ -164,8 +164,8 @@ def record_event_canonical_link_management(sender, performer, signal, content, *
).save()


@receiver(signals.suggestions_management, sender=AddSuggestion)
@receiver(signals.suggestions_management, sender=RemoveSuggestion)
@receiver(signals.suggestions_management, sender=AddSuggestionView)
@receiver(signals.suggestions_management, sender=RemoveSuggestionView)
def record_event_suggestion_management(sender, performer, signal, content, action, **_):
Event(
performer=performer,
Expand Down
10 changes: 5 additions & 5 deletions zds/tutorialv2/tests/tests_views/tests_addsuggestion.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def test_authenticated_staff_opinion(self):
self.content.type = "OPINION"
self.content.save()
response = self.client.post(self.form_url, self.form_data)
self.assertEqual(response.status_code, 403)
self.assertRedirects(response, self.content_url)


class AddSuggestionWorkflowTests(TutorialTestMixin, TestCase):
Expand All @@ -94,10 +94,10 @@ def setUp(self):

# Get information to be reused in tests
self.form_url = reverse("content:add-suggestion", kwargs={"pk": self.content.pk})
self.success_message_fragment = _("a été ajouté dans les suggestions")
self.error_message_fragment_unpublished = _("un contenu qui n'a pas été publié")
self.error_message_fragment_already_suggested = _("fait déjà partie des suggestions de")
self.error_message_fragment_self = _("en tant que suggestion pour lui-même")
self.success_message_fragment = _("a été ajouté aux suggestions")
self.error_message_fragment_unpublished = _("pas suggérer une publication non publique")
self.error_message_fragment_already_suggested = _("déjà suggéré pour cette publication")
self.error_message_fragment_self = _("la publication pour elle-même")
self.error_messge_fragment_not_picked = _("un billet qui n'a pas été mis en avant")

# Log in with an authorized user to perform the tests
Expand Down
2 changes: 1 addition & 1 deletion zds/tutorialv2/tests/tests_views/tests_removesuggestion.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def test_authenticated_staff_opinion(self):
self.content.type = "OPINION"
self.content.save()
response = self.client.post(self.form_url, self.form_data)
self.assertEqual(response.status_code, 403)
self.assertRedirects(response, self.content_url)


class RemoveSuggestionWorkflowTests(TutorialTestMixin, TestCase):
Expand Down
6 changes: 3 additions & 3 deletions zds/tutorialv2/urls/urls_contents.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
RemoveContributorFromContent,
ContentOfContributors,
)
from zds.tutorialv2.views.suggestions import RemoveSuggestion, AddSuggestion
from zds.tutorialv2.views.suggestions import RemoveSuggestionView, AddSuggestionView
from zds.tutorialv2.views.tags import EditTags

from zds.tutorialv2.views.lists import TagsListView, ContentOfAuthor, ListContentReactions
Expand Down Expand Up @@ -233,8 +233,8 @@ def get_version_pages():
name="inactive-beta",
),
path("stats/<int:pk>/<slug:slug>/", ContentStatisticsView.as_view(), name="stats-content"),
path("ajouter-suggestion/<int:pk>/", AddSuggestion.as_view(), name="add-suggestion"),
path("enlever-suggestion/<int:pk>/", RemoveSuggestion.as_view(), name="remove-suggestion"),
path("ajouter-suggestion/<int:pk>/", AddSuggestionView.as_view(), name="add-suggestion"),
path("enlever-suggestion/<int:pk>/", RemoveSuggestionView.as_view(), name="remove-suggestion"),
# jsfiddle support:
path("activer-js/", ActivateJSFiddleInContent.as_view(), name="activate-jsfiddle"),
# delete:
Expand Down
35 changes: 10 additions & 25 deletions zds/tutorialv2/views/suggestions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.core.exceptions import PermissionDenied
from django.shortcuts import get_object_or_404, redirect
from django.urls import reverse
from django.utils.decorators import method_decorator
Expand All @@ -19,7 +18,7 @@

class SearchSuggestionForm(forms.Form):
suggestion_pk = forms.CharField(
label="Contenu à suggérer",
label="Publication à suggérer",
required=False,
widget=forms.TextInput(),
)
Expand Down Expand Up @@ -64,16 +63,14 @@ def clean_pk_suggestion(self):
return pk_suggestion


class RemoveSuggestion(PermissionRequiredMixin, SingleContentFormViewMixin):
class RemoveSuggestionView(PermissionRequiredMixin, SingleContentFormViewMixin):
form_class = RemoveSuggestionForm
modal_form = True
permission_required = "tutorialv2.change_publishablecontent"

@method_decorator(login_required)
@method_decorator(can_write_and_read_now)
def dispatch(self, *args, **kwargs):
if self.get_object().is_opinion:
raise PermissionDenied
return super().dispatch(*args, **kwargs)

def form_valid(self, form):
Expand All @@ -90,9 +87,8 @@ def form_invalid(self, form):
return super().form_invalid(form)

def get_success_message(self, content_suggestion):
return _('Vous avez enlevé "{}" de la liste des suggestions de {}.').format(
content_suggestion.suggestion.title,
self.describe_type(),
return _('Vous avez enlevé "{}" de la liste des suggestions de cette publication.').format(
content_suggestion.suggestion.title
)

def get_success_url(self):
Expand All @@ -101,48 +97,37 @@ def get_success_url(self):
else:
return self.object.get_absolute_url()

def describe_type(self):
if self.object.is_tutorial:
return _("ce tutoriel")
return _("cet article")


class AddSuggestion(LoggedWithReadWriteHability, PermissionRequiredMixin, SingleContentFormViewMixin):
class AddSuggestionView(LoggedWithReadWriteHability, PermissionRequiredMixin, SingleContentFormViewMixin):
authorized_for_staff = True
permission_required = "tutorialv2.change_publishablecontent"

def post(self, request, *args, **kwargs):
publication = get_object_or_404(PublishableContent, pk=kwargs["pk"])

_type = _("cet article")
if publication.is_tutorial:
_type = _("ce tutoriel")
elif self.object.is_opinion:
raise PermissionDenied

if "options" in request.POST:
options = request.POST.getlist("options")
for option in options:
suggestion = get_object_or_404(PublishableContent, pk=option)
if ContentSuggestion.objects.filter(publication=publication, suggestion=suggestion).exists():
messages.error(
self.request,
_(f'Le contenu "{suggestion.title}" fait déjà partie des suggestions de {_type}.'),
_(f'"{suggestion.title}" est déjà suggéré pour cette publication.'),
)
elif suggestion.pk == publication.pk:
messages.error(
self.request,
_(f"Vous ne pouvez pas ajouter {_type} en tant que suggestion pour lui-même."),
_(f"Vous ne pouvez pas suggérer la publication pour elle-même."),
)
elif suggestion.is_opinion and suggestion.sha_picked != suggestion.sha_public:
messages.error(
self.request,
_(f"Vous ne pouvez pas suggérer pour {_type} un billet qui n'a pas été mis en avant."),
_(f"Vous ne pouvez pas suggérer un billet qui n'a pas été mis en avant."),
)
elif not suggestion.sha_public:
messages.error(
self.request,
_(f"Vous ne pouvez pas suggérer pour {_type} un contenu qui n'a pas été publié."),
_(f"Vous ne pouvez pas suggérer une publication non publique."),
)
else:
obj_suggestion = ContentSuggestion(publication=publication, suggestion=suggestion)
Expand All @@ -155,7 +140,7 @@ def post(self, request, *args, **kwargs):
)
messages.info(
self.request,
_(f'Le contenu "{suggestion.title}" a été ajouté dans les suggestions de {_type}.'),
_(f'"{suggestion.title}" a été ajouté aux suggestions de la publication.'),
)

if self.object.public_version:
Expand Down