#6: Endpoint do pobierania elementów galerii (wstępna wersja)
authorJan Szejko <j-sz@o2.pl>
Wed, 3 Feb 2016 10:37:47 +0000 (11:37 +0100)
committerJan Szejko <j-sz@o2.pl>
Wed, 3 Feb 2016 10:37:47 +0000 (11:37 +0100)
src/catalogue/urls.py
src/picture/models.py
src/picture/views.py
src/wolnelektury/settings/custom.py
src/wolnelektury/utils.py

index a4627e2..bc9f78d 100644 (file)
@@ -14,6 +14,8 @@ SLUG = r'[a-z0-9-]*'
 
 urlpatterns = patterns(
     'picture.views',
+
+    url(r'^obraz/strona/$', 'picture_page', name='picture_page'),
     # pictures - currently pictures are coupled with catalogue, hence the url is here
     url(r'^obraz/$', 'picture_list_thumb', name='picture_list_thumb'),
     url(r'^obraz/(?P<slug>%s).html$' % SLUG, 'picture_viewer', name='picture_viewer'),
index 8ab5d21..f496726 100644 (file)
@@ -127,6 +127,9 @@ class Picture(models.Model):
     def author_str(self):
         return ", ".join(str(t) for t in self.tags.filter(category='author'))
 
+    def author_unicode(self):
+        return ", ".join(unicode(t) for t in self.tags.filter(category='author'))
+
     @permalink
     def get_absolute_url(self):
         return 'picture.views.picture_detail', [self.slug]
index 4337058..35e9b5f 100644 (file)
@@ -2,6 +2,7 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
+from django.conf import settings
 from django.contrib.auth.decorators import permission_required
 from django.shortcuts import render_to_response, get_object_or_404, render
 from django.template import RequestContext
@@ -26,6 +27,7 @@ from sponsors.models import Sponsor
 #             books_nav.setdefault(tag.sort_key[0], []).append(tag)
 #
 #     return render_to_response(template_name, locals(), context_instance=RequestContext(request))
+from wolnelektury.utils import ajax
 
 
 def picture_list_thumb(request, filter=None, get_filter=None, template_name='picture/picture_list_thumb.html',
@@ -69,6 +71,29 @@ def picture_viewer(request, slug):
     }, context_instance=RequestContext(request))
 
 
+@ajax(method='get')
+def picture_page(request, key=None):
+    pictures = Picture.objects.order_by('-id')
+    if key is not None:
+        pictures = pictures.filter(id__lt=key)
+    pictures = pictures[:settings.PICTURE_PAGE_SIZE]
+    picture_data = [
+        {
+            'id': picture.id,
+            'title': picture.title,
+            'author': picture.author_unicode(),
+            'image_url': picture.image_file.url,
+            'width': picture.width,
+            'height': picture.height,
+        }
+        for picture in pictures
+    ]
+    return {
+        'pictures': picture_data,
+        'count': Picture.objects.count(),
+    }
+
+
 # =========
 # = Admin =
 # =========
index 09cc641..acea28b 100644 (file)
@@ -26,3 +26,5 @@ LATEST_BLOG_POSTS = "http://nowoczesnapolska.org.pl/feed/?cat=-135"
 CATALOGUE_COUNTERS_FILE = os.path.join(VAR_DIR, 'catalogue_counters.p')
 
 CATALOGUE_MIN_INITIALS = 60
+
+PICTURE_PAGE_SIZE = 20
index e8aa7fb..9717070 100644 (file)
@@ -2,8 +2,16 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
+import json
 import os
+from functools import wraps
+
 import pytz
+from inspect import getargspec
+
+from django.http import HttpResponse
+from django.template import RequestContext
+from django.template.loader import render_to_string
 from django.utils import timezone
 from django.conf import settings
 
@@ -23,3 +31,78 @@ def utc_for_js(dt):
 def makedirs(path):
     if not os.path.isdir(path):
         os.makedirs(path)
+
+
+def stringify_keys(dictionary):
+    return dict((keyword.encode('ascii'), value)
+                for keyword, value in dictionary.iteritems())
+
+
+def json_encode(obj, sort_keys=True, ensure_ascii=False):
+    return json.dumps(obj, sort_keys=sort_keys, ensure_ascii=ensure_ascii)
+
+
+def json_decode(obj):
+    return json.loads(obj)
+
+
+def json_decode_fallback(value):
+    try:
+        return json_decode(value)
+    except ValueError:
+        return value
+
+
+class AjaxError(Exception):
+    pass
+
+
+def ajax(login_required=True, method=None, template=None, permission_required=None):
+    def decorator(fun):
+        @wraps(fun)
+        def ajax_view(request):
+            kwargs = {}
+            request_params = None
+            if method == 'post':
+                request_params = request.POST
+            elif method == 'get':
+                request_params = request.GET
+            fun_params, xx, fun_kwargs, defaults = getargspec(fun)
+            if defaults:
+                required_params = fun_params[1:-len(defaults)]
+            else:
+                required_params = fun_params[1:]
+            missing_params = set(required_params) - set(request_params)
+            if missing_params:
+                res = {
+                    'result': 'missing params',
+                    'missing': ', '.join(missing_params),
+                }
+            else:
+                if request_params:
+                    request_params = dict(
+                        (key, json_decode_fallback(value))
+                        for key, value in request_params.iteritems()
+                        if fun_kwargs or key in fun_params)
+                    kwargs.update(stringify_keys(request_params))
+                res = None
+                if login_required and not request.user.is_authenticated():
+                    res = {'result': 'logout'}
+                if (permission_required and
+                        not request.user.has_perm(permission_required)):
+                    res = {'result': 'access denied'}
+            if not res:
+                try:
+                    res = fun(request, **kwargs)
+                    if res and template:
+                        res = {'html': render_to_string(template, res, RequestContext(request))}
+                except AjaxError as e:
+                    res = {'result': e.args[0]}
+            if 'result' not in res:
+                res['result'] = 'ok'
+            return HttpResponse(json_encode(res), content_type='application/json; charset=utf-8',
+                                status=200 if res['result'] == 'ok' else 400)
+
+        return ajax_view
+
+    return decorator