From: Jan Szejko Date: Wed, 3 Feb 2016 10:37:47 +0000 (+0100) Subject: #6: Endpoint do pobierania elementów galerii (wstępna wersja) X-Git-Url: https://git.mdrn.pl/wolnelektury.git/commitdiff_plain/f29c8cb6c8bb788fe4dcd93f59dee829d1281c69 #6: Endpoint do pobierania elementów galerii (wstępna wersja) --- diff --git a/src/catalogue/urls.py b/src/catalogue/urls.py index a4627e25e..bc9f78d87 100644 --- a/src/catalogue/urls.py +++ b/src/catalogue/urls.py @@ -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%s).html$' % SLUG, 'picture_viewer', name='picture_viewer'), diff --git a/src/picture/models.py b/src/picture/models.py index 8ab5d2111..f496726a3 100644 --- a/src/picture/models.py +++ b/src/picture/models.py @@ -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] diff --git a/src/picture/views.py b/src/picture/views.py index 43370582d..35e9b5f8d 100644 --- a/src/picture/views.py +++ b/src/picture/views.py @@ -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 = # ========= diff --git a/src/wolnelektury/settings/custom.py b/src/wolnelektury/settings/custom.py index 09cc641e6..acea28b9f 100644 --- a/src/wolnelektury/settings/custom.py +++ b/src/wolnelektury/settings/custom.py @@ -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 diff --git a/src/wolnelektury/utils.py b/src/wolnelektury/utils.py index e8aa7fb27..971707030 100644 --- a/src/wolnelektury/utils.py +++ b/src/wolnelektury/utils.py @@ -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