X-Git-Url: https://git.mdrn.pl/wolnelektury.git/blobdiff_plain/963c137c837058edfa66e97c49682e2d0f437923..3050ec49d5392fe0120fad4ef02ada55d8b7d04e:/apps/api/handlers.py diff --git a/apps/api/handlers.py b/apps/api/handlers.py index 260384d69..da5c0ed27 100644 --- a/apps/api/handlers.py +++ b/apps/api/handlers.py @@ -12,11 +12,12 @@ from django.core.cache import get_cache from django.core.urlresolvers import reverse from piston.handler import AnonymousBaseHandler, BaseHandler from piston.utils import rc +from sorl.thumbnail import default from api.helpers import timestamp from api.models import Deleted from catalogue.forms import BookImportForm -from catalogue.models import Book, Tag, BookMedia, Fragment +from catalogue.models import Book, Tag, BookMedia, Fragment, Collection from picture.models import Picture from picture.forms import PictureImportForm @@ -93,21 +94,17 @@ class BookMediaHandler(BaseHandler): @classmethod def artist(cls, media): - return media.get_extra_info_value().get('artist_name', '') + return media.extra_info.get('artist_name', '') @classmethod def director(cls, media): - return media.get_extra_info_value().get('director_name', '') + return media.extra_info.get('director_name', '') class BookDetails(object): """Custom fields used for representing Books.""" - @classmethod - def author(cls, book): - return ",".join(t[0] for t in book.related_info()['tags']['author']) - @classmethod def href(cls, book): """ Returns an URI for a Book in the API. """ @@ -134,6 +131,11 @@ class BookDetails(object): def cover(cls, book): return MEDIA_BASE + book.cover.url if book.cover else '' + @classmethod + def cover_thumb(cls, book): + return MEDIA_BASE + default.backend.get_thumbnail( + book.cover, "139x193").url if book.cover else '' + class BookDetailHandler(BaseHandler, BookDetails): @@ -143,7 +145,7 @@ class BookDetailHandler(BaseHandler, BookDetails): """ allowed_methods = ['GET'] fields = ['title', 'parent', 'children'] + Book.formats + [ - 'media', 'url', 'cover'] + [ + 'media', 'url', 'cover', 'cover_thumb'] + [ category_plural[c] for c in book_tag_categories] @piwik_track @@ -162,7 +164,12 @@ class AnonymousBooksHandler(AnonymousBaseHandler, BookDetails): """ allowed_methods = ('GET',) model = Book - fields = ['author', 'href', 'title', 'url', 'cover'] + fields = book_tag_categories + ['href', 'title', 'url', 'cover', 'cover_thumb'] + + @classmethod + def genres(cls, book): + """ Returns all media for a book. """ + return book.tags.filter(category='genre') @piwik_track def read(self, request, tags, top_level=False, @@ -192,9 +199,9 @@ class AnonymousBooksHandler(AnonymousBaseHandler, BookDetails): if top_level: books = books.filter(parent=None) if audiobooks: - books = books.filter(media__type='mp3') + books = books.filter(media__type='mp3').distinct() if daisy: - books = books.filter(media__type='daisy') + books = books.filter(media__type='daisy').distinct() if books.exists(): return books @@ -208,7 +215,7 @@ class AnonymousBooksHandler(AnonymousBaseHandler, BookDetails): class BooksHandler(BookDetailHandler): allowed_methods = ('GET', 'POST') model = Book - fields = ['author', 'href', 'title', 'url'] + fields = book_tag_categories + ['href', 'title', 'url', 'cover', 'cover_thumb'] anonymous = AnonymousBooksHandler def create(self, request, *args, **kwargs): @@ -224,14 +231,24 @@ class BooksHandler(BookDetailHandler): return rc.NOT_FOUND +class EBooksHandler(AnonymousBooksHandler): + fields = ('author', 'href', 'title', 'cover') + tuple(Book.ebook_formats) + + # add categorized tags fields for Book def _tags_getter(category): @classmethod def get_tags(cls, book): return book.tags.filter(category=category) return get_tags +def _tag_getter(category): + @classmethod + def get_tag(cls, book): + return ", ".join(t[0] for t in book.related_info()['tags'].get(category, [])) + return get_tag for plural, singular in category_singular.items(): setattr(BookDetails, plural, _tags_getter(singular)) + setattr(BookDetails, singular, _tag_getter(singular)) # add fields for files in Book def _file_getter(format): @@ -248,6 +265,52 @@ for format in Book.formats: setattr(BookDetails, format, _file_getter(format)) +class CollectionDetails(object): + """Custom Collection fields.""" + + @classmethod + def href(cls, collection): + """ Returns URI in the API for the collection. """ + + return API_BASE + reverse("api_collection", args=[collection.slug]) + + @classmethod + def url(cls, collection): + """ Returns URL on the site. """ + + return WL_BASE + collection.get_absolute_url() + + @classmethod + def books(cls, collection): + return Book.objects.filter(collection.get_query()) + + + +class CollectionDetailHandler(BaseHandler, CollectionDetails): + allowed_methods = ('GET',) + fields = ['url', 'title', 'description', 'books'] + + @piwik_track + def read(self, request, slug): + print slug + """ Returns details of a collection, identified by slug. """ + try: + return Collection.objects.get(slug=slug) + except Collection.DoesNotExist: + return rc.NOT_FOUND + + +class CollectionsHandler(BaseHandler, CollectionDetails): + allowed_methods = ('GET',) + model = Collection + fields = ['url', 'href', 'title'] + + @piwik_track + def read(self, request): + """ Returns all collections. """ + return Collection.objects.all() + + class TagDetails(object): """Custom Tag fields.""" @@ -410,7 +473,7 @@ class CatalogueHandler(BaseHandler): def book_dict(book, fields=None): all_fields = ['url', 'title', 'description', 'gazeta_link', 'wiki_link', - ] + Book.formats + BookMedia.formats + [ + ] + Book.formats + BookMedia.formats.keys() + [ 'parent', 'parent_number', 'tags', 'license', 'license_description', 'source_name', @@ -422,7 +485,7 @@ class CatalogueHandler(BaseHandler): else: fields = all_fields - extra_info = book.get_extra_info_value() + extra_info = book.extra_info obj = {} for field in fields: @@ -437,7 +500,7 @@ class CatalogueHandler(BaseHandler): elif field in BookMedia.formats: media = [] - for m in book.media.filter(type=field): + for m in book.media.filter(type=field).iterator(): media.append({ 'url': m.file.url, 'size': m.file.size, @@ -449,10 +512,10 @@ class CatalogueHandler(BaseHandler): obj[field] = book.get_absolute_url() elif field == 'tags': - obj[field] = [t.id for t in book.tags.exclude(category__in=('book', 'set'))] + obj[field] = [t.id for t in book.tags.exclude(category__in=('book', 'set')).iterator()] elif field == 'author': - obj[field] = ", ".join(t.name for t in book.tags.filter(category='author')) + obj[field] = ", ".join(t.name for t in book.tags.filter(category='author').iterator()) elif field == 'parent': obj[field] = book.parent_id @@ -489,7 +552,7 @@ class CatalogueHandler(BaseHandler): last_change = since for book in Book.objects.filter(changed_at__gte=since, - changed_at__lt=until): + changed_at__lt=until).iterator(): book_d = cls.book_dict(book, fields) updated.append(book_d) if updated: @@ -498,7 +561,7 @@ class CatalogueHandler(BaseHandler): for book in Deleted.objects.filter(content_type=Book, deleted_at__gte=since, deleted_at__lt=until, - created_at__lt=since): + created_at__lt=since).iterator(): deleted.append(book.id) if deleted: changes['deleted'] = deleted @@ -524,7 +587,7 @@ class CatalogueHandler(BaseHandler): obj[field] = tag.get_absolute_url() elif field == 'books': - obj[field] = [b.id for b in Book.tagged_top_level([tag])] + obj[field] = [b.id for b in Book.tagged_top_level([tag]).iterator()] elif field == 'sort_key': obj[field] = tag.sort_key @@ -562,7 +625,7 @@ class CatalogueHandler(BaseHandler): for tag in Tag.objects.filter(category__in=categories, changed_at__gte=since, - changed_at__lt=until): + changed_at__lt=until).iterator(): # only serve non-empty tags if tag.book_count: tag_d = cls.tag_dict(tag, fields) @@ -576,7 +639,7 @@ class CatalogueHandler(BaseHandler): content_type=Tag, deleted_at__gte=since, deleted_at__lt=until, - created_at__lt=since): + created_at__lt=since).iterator(): deleted.append(tag.id) if deleted: changes['deleted'] = deleted