project sell info and initial synchro support
[redakcja.git] / src / wiki / views.py
index 29c389a..e22c028 100644 (file)
@@ -2,6 +2,7 @@
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from datetime import datetime
+import json
 import os
 import logging
 from time import mktime
@@ -11,7 +12,7 @@ from django.apps import apps
 from django.conf import settings
 from django.urls import reverse
 from django import http
-from django.http import Http404, HttpResponseForbidden
+from django.http import Http404, HttpResponse, HttpResponseForbidden, HttpResponseBadRequest
 from django.middleware.gzip import GZipMiddleware
 from django.utils.decorators import decorator_from_middleware
 from django.utils.formats import localize
@@ -21,6 +22,7 @@ from django.shortcuts import get_object_or_404, render
 from sorl.thumbnail import get_thumbnail
 
 from documents.models import Book, Chunk
+import sources.models
 from . import nice_diff
 from wiki import forms
 from wiki.helpers import (JSONResponse, JSONFormInvalid, JSONServerError,
@@ -37,6 +39,10 @@ logger = logging.getLogger("fnp.wiki")
 MAX_LAST_DOCS = 10
 
 
+class HttpResponseLengthRequired(HttpResponse):
+    status_code = 411
+
+
 @never_cache
 def editor(request, slug, chunk=None, template_name='wiki/document_details.html'):
     try:
@@ -128,6 +134,20 @@ def text(request, chunk_id):
         return HttpResponseForbidden("Not authorized.")
 
     if request.method == 'POST':
+        # Check length to reject broken request.
+        try:
+            expected_cl = int(request.META['CONTENT_LENGTH'])
+        except:
+            return HttpResponseLengthRequired(json.dumps(
+                {"__message": _("Content length required.")}
+            ))
+        # 411 if missing
+        cl = len(request.body)
+        if cl != expected_cl:
+            return HttpResponseBadRequest(json.dumps(
+                {"__message": _("Wrong content length, request probably interrupted.")}
+            ))
+
         form = forms.DocumentTextSaveForm(request.POST, user=request.user, prefix="textsave")
         if form.is_valid():
             if request.user.is_authenticated:
@@ -250,6 +270,19 @@ def gallery(request, directory):
         raise http.Http404
 
 
+@never_cache
+def scans_list(request, pk):
+    bs = get_object_or_404(sources.models.BookSource, pk=pk)
+    def map_to_url(filename):
+        return quote(("%s/%s" % (settings.MEDIA_URL, filename)))
+    images = [
+        {
+            "url": map_to_url(f),
+        } for f in bs.get_view_files()
+    ]
+    return JSONResponse(images)
+
+
 @never_cache
 def diff(request, chunk_id):
     revA = int(request.GET.get('from', 0))
@@ -307,7 +340,7 @@ def history(request, chunk_id):
                 "description": change.description,
                 "author": change.author_str(),
                 "date": localize(change.created_at),
-                "publishable": _("Publishable") + "\n" if change.publishable else "",
+                "publishable": change.publishable,
                 "tag": ',\n'.join(str(tag) for tag in change.tags.all()),
                 "published": _("Published") + ": " + \
                     localize(change.publish_log.order_by('-book_record__timestamp')[0].book_record.timestamp) \
@@ -337,6 +370,36 @@ def pubmark(request, chunk_id):
         return JSONFormInvalid(form)
 
 
+@require_POST
+@ajax_require_permission('documents.book_edit')
+def set_gallery(request, chunk_id):
+    doc = get_object_or_404(Chunk, pk=chunk_id)
+    book = doc.book
+    book.gallery = request.POST['gallery']
+    book.save(update_fields=['gallery'])
+    return JSONResponse({})
+
+@require_POST
+@ajax_require_permission('documents.chunk_edit')
+def set_gallery_start(request, chunk_id):
+    doc = get_object_or_404(Chunk, pk=chunk_id)
+    doc.gallery_start = request.POST['start']
+    doc.save(update_fields=['gallery_start'])
+    return JSONResponse({})
+
+@ajax_require_permission('documents.chunk_edit')
+def galleries(request):
+    return JSONResponse(
+        sorted(
+            os.listdir(
+                os.path.join(
+                    settings.MEDIA_ROOT,
+                    settings.IMAGE_DIR,
+                )
+            )
+        )
+    )
+
 def themes(request):
     prefix = request.GET.get('q', '')
     return http.HttpResponse('\n'.join([str(t) for t in Theme.objects.filter(name__istartswith=prefix)]))