diff --git a/requirements.in b/requirements.in index 6bbeab56..ed928e99 100644 --- a/requirements.in +++ b/requirements.in @@ -32,3 +32,4 @@ Pillow redis requests sentry-sdk +beautifulsoup4 \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 447680f1..f8343aff 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ # This file is autogenerated by pip-compile with python 3.10 # To update, run: # -# pip-compile --output-file=requirements.txt requirements.in +# pip-compile # arrow==1.2.2 # via ics @@ -17,7 +17,9 @@ attrs==21.4.0 backcall==0.2.0 # via ipython beautifulsoup4==4.11.1 - # via django-bootstrap4 + # via + # -r requirements.in + # django-bootstrap4 bleach[css]==5.0.1 # via wiki build==0.8.0 diff --git a/wiki/forms.py b/wiki/forms.py index 5a1ce81a..682edeb5 100644 --- a/wiki/forms.py +++ b/wiki/forms.py @@ -1,14 +1,22 @@ -from django.forms import ModelForm, Textarea - +from django import forms from .models import Article -class ArticleForm(ModelForm): +class ArticleForm(forms.ModelForm): class Meta: model = Article exclude = ['creator', 'last_modifier'] widgets = { - 'content': Textarea(attrs={'rows': 20}), - 'commit': Textarea(attrs={'rows': 3}), + 'content': forms.Textarea(attrs={'rows': 20}), + 'commit': forms.Textarea(attrs={'rows': 3}), } + + +class DiffForm(forms.Form): + base_commit = forms.ModelChoiceField(queryset=Article.history.model.objects.all(), required=True, label="Version de base") + comp_commit = forms.ModelChoiceField(queryset=Article.history.model.objects.all(), required=True, label="Version à comparer") + + # def __init__(self, *args, **kwargs): + # if 'article' in kwargs: + # article = kwargs.pop('article') diff --git a/wiki/models.py b/wiki/models.py index e17d083e..e5844738 100644 --- a/wiki/models.py +++ b/wiki/models.py @@ -32,7 +32,7 @@ class Meta: verbose_name = "Article" def __str__(self): - return self.title + return f"{self.title} ({self.commit})" def get_absolute_url(self): return reverse('view_article', args=[self.pk]) diff --git a/wiki/templates/article_detail.html b/wiki/templates/article_detail.html index b6fb2e40..1e5d3a73 100644 --- a/wiki/templates/article_detail.html +++ b/wiki/templates/article_detail.html @@ -78,7 +78,14 @@

{{article.title}}

{% endfor %} - {% endif %} +
+ {% csrf_token %} +
+ {{ diff_form.as_p }} +
+ +
+ {% endif %} diff --git a/wiki/templates/diff_article.html b/wiki/templates/diff_article.html new file mode 100644 index 00000000..40d0e3e5 --- /dev/null +++ b/wiki/templates/diff_article.html @@ -0,0 +1,83 @@ +{% extends "base.html" %} +{% load bootstrap4 %} +{% load static %} + +{% block title %} +Formulaire article +{% endblock %} + +{% block head %} + {{ form.media }} + + + + +{% endblock %} + +{% block content %} +

Différences:

+ +
+
+
+

{{ old_article.commit }}

+
+
+
+

{{ article.commit }}

+
+
+ + {{ delta | safe }} + +
+
+
+ + Voir cette version + +
+
+
+ + Voir cette version + +
+
+ +

Légende:

+ + + + + + + + + + + + + + + + + + + + + +
CouleurSignification
(t)opSupprimé
(f)irst changeAjouté
(n)ext changeModifié
+{% endblock %} diff --git a/wiki/urls.py b/wiki/urls.py index 6e2f6af7..2f6ac17d 100644 --- a/wiki/urls.py +++ b/wiki/urls.py @@ -1,12 +1,12 @@ from django.urls import path -from .views import ( - wiki_home, ArticleDetailView, ArticleAddView, ArticleEditView, ArticleOldDetailView) +from wiki import views urlpatterns = [ - path('', wiki_home, name='wiki_home'), - path('add', ArticleAddView.as_view(), name='add_article'), - path('edit/', ArticleEditView.as_view(), name='edit_article'), - path('', ArticleDetailView.as_view(), name='view_article'), - path('/old/', ArticleOldDetailView.as_view(), name='view_old_version') + path('', views.wiki_home, name='wiki_home'), + path('diff', views.diff_article, name='diff_article'), + path('add', views.ArticleAddView.as_view(), name='add_article'), + path('edit/', views.ArticleEditView.as_view(), name='edit_article'), + path('', views.ArticleDetailView.as_view(), name='view_article'), + path('/old/', views.ArticleOldDetailView.as_view(), name='view_old_version') ] diff --git a/wiki/views.py b/wiki/views.py index 88d46bb9..ebd40b3e 100644 --- a/wiki/views.py +++ b/wiki/views.py @@ -1,12 +1,14 @@ +from difflib import HtmlDiff from django.shortcuts import render from django.views.generic.detail import DetailView from django.views.generic import CreateView, UpdateView from django.contrib.auth.mixins import LoginRequiredMixin from django.utils import timezone from actstream import action +from bs4 import BeautifulSoup from .models import Article -from .forms import ArticleForm +from .forms import ArticleForm, DiffForm def wiki_home(request): @@ -21,6 +23,38 @@ def wiki_home(request): }) +def diff_article(request): + """Compares two versions of an article.""" + form = DiffForm() + + if request.method == 'POST': + form_post = DiffForm(request.POST) + if form_post.is_valid(): + old_article = form_post.cleaned_data['base_commit'] + article = form_post.cleaned_data['comp_commit'] + + # Calculating the delta + delta = HtmlDiff(wrapcolumn=75).make_table( + old_article.content.split("\n"), + article.content.split("\n") + ) + # Making the table pretty + table = BeautifulSoup(delta, features="html.parser") + table.table['class'] = table.table.get('class', []) + ["table table-stripped"] + + return render(request, "diff_article.html", { + "delta": table.prettify(), + "initial_article": article.history_object, + "article": article, + "old_article": old_article, + "form": form, + }) + + return render(request, "diff_article.html", { + "form": form, + }) + + class ArticleAddView(LoginRequiredMixin, CreateView): form_class = ArticleForm template_name = 'add_article.html' @@ -57,6 +91,11 @@ class ArticleDetailView(DetailView): template_name = 'article_detail.html' context_object_name = 'article' + def get_context_data(self, **kwargs): + context = super(ArticleDetailView, self).get_context_data(**kwargs) + context['diff_form'] = DiffForm + + return context class ArticleOldDetailView(DetailView): model = Article.history.model