X-Git-Url: https://git.mdrn.pl/wolnelektury.git/blobdiff_plain/86f05630842437fb68b7dfa1fe50607a49826c86..8887547a016bbf665ffc4175346f655f0dfa63fb:/src/api/handlers.py diff --git a/src/api/handlers.py b/src/api/handlers.py index 77728208e..830f0a99a 100644 --- a/src/api/handlers.py +++ b/src/api/handlers.py @@ -9,10 +9,12 @@ from django.core.urlresolvers import reverse from django.http.response import HttpResponse from django.utils.functional import lazy from django.db import models +from migdal.models import Entry from piston.handler import AnonymousBaseHandler, BaseHandler from piston.utils import rc from sorl.thumbnail import default +from api.models import BookUserData from catalogue.forms import BookImportForm from catalogue.models import Book, Tag, BookMedia, Fragment, Collection from catalogue.models.tag import prefetch_relations @@ -163,7 +165,8 @@ class BookDetailHandler(BaseHandler, BookDetails): """ allowed_methods = ['GET'] fields = ['title', 'parent', 'children'] + Book.formats + [ - 'media', 'url', 'cover', 'cover_thumb', 'simple_thumb', 'simple_cover', 'fragment_data', 'preview'] + [ + 'media', 'url', 'cover', 'cover_thumb', 'simple_thumb', 'simple_cover', 'fragment_data', 'audio_length', + 'preview'] + [ category_plural[c] for c in book_tag_categories] @piwik_track @@ -182,7 +185,7 @@ class AnonymousBooksHandler(AnonymousBaseHandler, BookDetails): """ allowed_methods = ('GET',) model = Book - fields = book_tag_categories + ['href', 'title', 'url', 'cover', 'cover_thumb', 'slug', 'simple_thumb'] + fields = book_tag_categories + ['href', 'title', 'url', 'cover', 'cover_thumb', 'slug', 'simple_thumb', 'has_audio'] @classmethod def genres(cls, book): @@ -321,7 +324,7 @@ class QuerySetProxy(models.QuerySet): class FilterBooksHandler(AnonymousBooksHandler): fields = book_tag_categories + [ - 'href', 'title', 'url', 'cover', 'cover_thumb', 'simple_thumb', 'slug', 'key'] + 'href', 'title', 'url', 'cover', 'cover_thumb', 'simple_thumb', 'has_audio', 'slug', 'key'] def parse_bool(self, s): if s in ('true', 'false'): @@ -432,6 +435,7 @@ def add_file_getters(): for book_format in Book.formats: setattr(BookDetails, book_format, _file_getter(book_format)) + add_file_getters() @@ -623,7 +627,7 @@ class FragmentsHandler(BaseHandler, FragmentDetails): """ try: - tags, ancestors = read_tags(tags, allowed=self.categories) + tags, ancestors = read_tags(tags, request, allowed=self.categories) except ValueError: return rc.NOT_FOUND fragments = Fragment.tagged.with_all(tags).select_related('book') @@ -649,3 +653,92 @@ class PictureHandler(BaseHandler): return rc.CREATED else: return rc.NOT_FOUND + + +class UserDataHandler(BaseHandler): + model = BookUserData + fields = ('state', 'username') + allowed_methods = ('GET', 'POST') + + def read(self, request, slug=None): + if not request.user.is_authenticated(): + return rc.FORBIDDEN + if slug is None: + return {'username': request.user.username} + try: + book = Book.objects.get(slug=slug) + except Book.DoesNotExist: + return rc.NOT_FOUND + try: + data = BookUserData.objects.get(book=book, user=request.user) + except BookUserData.DoesNotExist: + return {'state': 'not_started'} + return data + + def create(self, request, slug, state): + try: + book = Book.objects.get(slug=slug) + except Book.DoesNotExist: + return rc.NOT_FOUND + if not request.user.is_authenticated(): + return rc.FORBIDDEN + if state not in ('reading', 'complete'): + return rc.NOT_FOUND + data, created = BookUserData.objects.get_or_create(book=book, user=request.user) + data.state = state + data.save() + return data + + +class UserShelfHandler(BookDetailHandler): + fields = book_tag_categories + [ + 'href', 'title', 'url', 'cover', 'cover_thumb', 'simple_thumb', 'slug', 'key'] + + def parse_bool(self, s): + if s in ('true', 'false'): + return s == 'true' + else: + return None + + def read(self, request, state): + if not request.user.is_authenticated(): + return rc.FORBIDDEN + if state not in ('reading', 'complete'): + return rc.NOT_FOUND + after = request.GET.get('after') + count = int(request.GET.get('count', 50)) + ids = BookUserData.objects.filter(user=request.user, complete=state == 'complete')\ + .values_list('book_id', flat=True) + books = Book.objects.filter(id__in=list(ids)).distinct().order_by('slug') + if after: + books = books.filter(slug__gt=after) + if count: + books = books[:count] + return books + + +class BlogEntryHandler(BaseHandler): + model = Entry + fields = ('title', 'lead', 'body', 'place', 'time', 'image_url', 'gallery_urls', 'type', 'key') + + def read(self, request): + after = request.GET.get('after') + count = int(request.GET.get('count', 20)) + entries = Entry.published_objects.filter(in_stream=True).order_by('-first_published_at') + if after: + entries = entries.filter(first_published_at__lt=after) + if count: + entries = entries[:count] + return entries + + @classmethod + def image_url(cls, entry): + return entry.image.url if entry.image else None + + @classmethod + def gallery_urls(cls, entry): + return [photo.url() for photo in entry.photo_set.all()] + + @classmethod + def key(cls, entry): + return entry.first_published_at