# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
from datetime import datetime
+import json
import os
import logging
from time import mktime
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
from django.utils.translation import gettext as _
from django.views.decorators.http import require_POST, require_GET
from django.shortcuts import get_object_or_404, render
+from django_gravatar.helpers import get_gravatar_url
from sorl.thumbnail import get_thumbnail
from documents.models import Book, Chunk
import sources.models
from . import nice_diff
+from team.models import Presence
from wiki import forms
from wiki.helpers import (JSONResponse, JSONFormInvalid, JSONServerError,
ajax_require_permission)
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:
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:
@never_cache
-def scans_list(request, pk):
- bs = get_object_or_404(sources.models.BookSource, pk=pk)
+def scans_list(request, pks):
+ pks = pks.split(',')
+ bss = [
+ get_object_or_404(sources.models.BookSource, pk=pk)
+ for pk in pks
+ ]
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()
- ]
+ images = []
+ for bs in bss:
+ images.extend([
+ {
+ "url": map_to_url(f),
+ } for f in bs.get_view_files()
+ ])
return JSONResponse(images)
@never_cache
def revision(request, chunk_id):
+ if not request.session.session_key:
+ return HttpResponseForbidden("Not authorized.")
doc = get_object_or_404(Chunk, pk=chunk_id)
if not doc.book.accessible(request):
return HttpResponseForbidden("Not authorized.")
- Presence = apps.get_model('team', 'Presence')
- Presence.report(request.user, doc, request.GET.get('a') == 'true')
- return http.HttpResponse(str(doc.revision()))
+
+ Presence.report(
+ request.user, request.session.session_key,
+ doc,
+ request.GET.get('a') == 'true'
+ )
+
+ # Temporary compat for unreloaded clients.
+ if not request.GET.get('new'):
+ return http.HttpResponse(str(doc.revision()))
+
+ return JSONResponse({
+ 'rev': doc.revision(),
+ 'people': list([
+ {
+ 'name': (p.user.first_name + ' ' + p.user.last_name) if p.user is not None else '?',
+ 'gravatar': get_gravatar_url(p.user.email if p.user is not None else '-', size=26),
+ 'since': p.since.strftime('%H:%M'),
+ 'active': p.active,
+ }
+ for p in Presence.get_current(request.session.session_key, doc)
+ ]),
+ })
@never_cache