1 # This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later.
2 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
7 logger = logging.getLogger("fnp.wiki_img")
9 from django.urls import reverse
10 from wiki.helpers import (JSONResponse, JSONFormInvalid, JSONServerError,
11 ajax_require_permission)
13 from django.http import Http404, HttpResponse, HttpResponseForbidden
14 from django.shortcuts import get_object_or_404, render
15 from django.views.decorators.http import require_GET, require_POST
16 from django.conf import settings
17 from django.utils.formats import localize
18 from django.utils.translation import gettext as _
20 from documents.models import Image
21 from wiki import forms
22 from wiki import nice_diff
23 from wiki_img.forms import ImageSaveForm
26 # Quick hack around caching problems, TODO: use ETags
28 from django.views.decorators.cache import never_cache
32 def editor(request, slug, template_name='wiki_img/document_details.html'):
33 doc = get_object_or_404(Image, slug=slug)
35 return render(request, template_name, {
38 "text_save": ImageSaveForm(user=request.user, prefix="textsave"),
39 "text_revert": forms.DocumentTextRevertForm(prefix="textrevert"),
40 "pubmark": forms.DocumentPubmarkForm(prefix="pubmark"),
42 'can_pubmark': request.user.has_perm('documents.can_pubmark_image'),
43 'REDMINE_URL': settings.REDMINE_URL,
48 def editor_readonly(request, slug, template_name='wiki_img/document_details_readonly.html'):
49 doc = get_object_or_404(Image, slug=slug)
51 revision = request.GET['revision']
55 return render(request, template_name, {
59 'REDMINE_URL': settings.REDMINE_URL,
64 def text(request, image_id):
65 doc = get_object_or_404(Image, pk=image_id)
66 if request.method == 'POST':
67 form = ImageSaveForm(request.POST, user=request.user, prefix="textsave")
69 if request.user.is_authenticated:
73 text = form.cleaned_data['text']
74 parent_revision = form.cleaned_data['parent_revision']
75 if parent_revision is not None:
76 parent = doc.at_revision(parent_revision)
79 stage = form.cleaned_data['stage_completed']
80 tags = [stage] if stage else []
81 publishable = (form.cleaned_data['publishable'] and
82 request.user.has_perm('documents.can_pubmark_image'))
83 doc.commit(author=author,
86 description=form.cleaned_data['comment'],
88 author_name=form.cleaned_data['author_name'],
89 author_email=form.cleaned_data['author_email'],
90 publishable=publishable,
92 revision = doc.revision()
94 'text': doc.materialize() if parent_revision != revision else None,
99 return JSONFormInvalid(form)
101 revision = request.GET.get("revision", None)
104 revision = int(revision)
105 except (ValueError, TypeError):
106 revision = doc.revision()
108 if revision is not None:
109 text = doc.at_revision(revision).materialize()
113 return JSONResponse({
116 'revision': revision,
121 def history(request, object_id):
123 doc = get_object_or_404(Image, pk=object_id)
124 if not doc.accessible(request):
125 return HttpResponseForbidden("Not authorized.")
128 for change in doc.history().reverse():
130 "version": change.revision,
131 "description": change.description,
132 "author": change.author_str(),
133 "date": localize(change.created_at),
134 "publishable": _("Publishable") + "\n" if change.publishable else "",
135 "tag": ',\n'.join(str(tag) for tag in change.tags.all()),
137 return JSONResponse(changes)
142 def revert(request, object_id):
143 form = forms.DocumentTextRevertForm(request.POST, prefix="textrevert")
145 doc = get_object_or_404(Image, pk=object_id)
146 if not doc.accessible(request):
147 return HttpResponseForbidden("Not authorized.")
149 revision = form.cleaned_data['revision']
151 comment = form.cleaned_data['comment']
152 comment += "\n#revert to %s" % revision
154 if request.user.is_authenticated:
155 author = request.user
159 before = doc.revision()
160 logger.info("Reverting %s to %s", object_id, revision)
161 doc.at_revision(revision).revert(author=author, description=comment)
163 return JSONResponse({
164 'text': doc.materialize() if before != doc.revision() else None,
166 'revision': doc.revision(),
169 return JSONFormInvalid(form)
173 def diff(request, object_id):
174 revA = int(request.GET.get('from', 0))
175 revB = int(request.GET.get('to', 0))
178 revA, revB = revB, revA
183 doc = get_object_or_404(Image, pk=object_id)
184 if not doc.accessible(request):
185 return HttpResponseForbidden("Not authorized.")
187 # allow diff from the beginning
189 docA = doc.at_revision(revA).materialize()
192 docB = doc.at_revision(revB).materialize()
194 return HttpResponse(nice_diff.html_diff_table(docA.splitlines(),
195 docB.splitlines(), context=3))
199 @ajax_require_permission('documents.can_pubmark_image')
200 def pubmark(request, object_id):
201 form = forms.DocumentPubmarkForm(request.POST, prefix="pubmark")
203 doc = get_object_or_404(Image, pk=object_id)
204 if not doc.accessible(request):
205 return HttpResponseForbidden("Not authorized.")
207 revision = form.cleaned_data['revision']
208 publishable = form.cleaned_data['publishable']
209 change = doc.at_revision(revision)
210 if publishable != change.publishable:
211 change.set_publishable(publishable)
212 return JSONResponse({"message": _("Revision marked")})
214 return JSONResponse({"message": _("Nothing changed")})
216 return JSONFormInvalid(form)