02a98a15403ac37adf2b092f53e278b36cfb75c5
[wolnelektury.git] / src / catalogue / api / serializers.py
1 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
2 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
3 #
4 from rest_framework import serializers
5 from api.fields import AbsoluteURLField, LegacyMixin, ThumbnailField
6 from catalogue.models import Book, Collection, Tag, BookMedia, Fragment
7 from .fields import BookLiked, EmbargoURLField
8
9
10 class TagSerializer(serializers.ModelSerializer):
11     url = AbsoluteURLField()
12     href = AbsoluteURLField(
13         view_name='catalogue_api_tag',
14         view_args=('category', 'slug')
15     )
16
17     class Meta:
18         model = Tag
19         fields = ['url', 'href', 'name', 'slug']
20
21
22 class TagDetailSerializer(serializers.ModelSerializer):
23     url = AbsoluteURLField()
24
25     class Meta:
26         model = Tag
27         fields = ['name', 'url', 'sort_key', 'description']
28
29
30 class TranslatorSerializer(serializers.Serializer):
31     name = serializers.CharField(source='*')
32
33
34 class BookSerializer(LegacyMixin, serializers.ModelSerializer):
35     author = serializers.CharField(source='author_unicode')
36     kind = serializers.CharField(source='kind_unicode')
37     epoch = serializers.CharField(source='epoch_unicode')
38     genre = serializers.CharField(source='genre_unicode')
39     liked = BookLiked()
40
41     simple_thumb = serializers.FileField(source='cover_api_thumb')
42     href = AbsoluteURLField(view_name='catalogue_api_book', view_args=['slug'])
43     url = AbsoluteURLField()
44     cover_thumb = ThumbnailField('139x193', source='cover')
45
46     class Meta:
47         model = Book
48         fields = [
49             'kind', 'full_sort_key', 'title', 'url', 'cover_color', 'author',
50             'cover', 'epoch', 'href', 'has_audio', 'genre',
51             'simple_thumb', 'slug', 'cover_thumb', 'liked']
52         legacy_non_null_fields = [
53             'kind', 'author', 'epoch', 'genre',
54             'cover', 'simple_thumb', 'cover_thumb']
55
56
57 class BookListSerializer(BookSerializer):
58     cover = serializers.CharField()
59     cover_thumb = serializers.CharField()
60
61     Meta = BookSerializer.Meta
62
63
64 class FilterBookListSerializer(BookListSerializer):
65     key = serializers.CharField()
66
67     class Meta:
68         model = Book
69         fields = BookListSerializer.Meta.fields + ['key']
70         legacy_non_null_fields = BookListSerializer.Meta.legacy_non_null_fields
71
72
73 class MediaSerializer(LegacyMixin, serializers.ModelSerializer):
74     url = EmbargoURLField(source='file_url')
75
76     class Meta:
77         model = BookMedia
78         fields = ['url', 'director', 'type', 'name', 'artist']
79         legacy_non_null_fields = ['director', 'artist']
80
81
82 class BookDetailSerializer(LegacyMixin, serializers.ModelSerializer):
83     url = AbsoluteURLField()
84
85     authors = TagSerializer(many=True)
86     translators = TranslatorSerializer(many=True)
87     epochs = TagSerializer(many=True)
88     genres = TagSerializer(many=True)
89     kinds = TagSerializer(many=True)
90
91     fragment_data = serializers.DictField()
92     parent = BookSerializer()
93     children = BookSerializer(many=True)
94
95     xml = EmbargoURLField(source='xml_url')
96     html = EmbargoURLField(source='html_url')
97     txt = EmbargoURLField(source='txt_url')
98     fb2 = EmbargoURLField(source='fb2_url')
99     epub = EmbargoURLField(source='epub_url')
100     mobi = EmbargoURLField(source='mobi_url')
101     pdf = EmbargoURLField(source='pdf_url')
102     media = MediaSerializer(many=True)
103     cover_thumb = ThumbnailField('139x193', source='cover')
104     simple_thumb = serializers.FileField(source='cover_api_thumb')
105
106     class Meta:
107         model = Book
108         fields = [
109             'title', 'url', 'language',
110             'epochs', 'genres', 'kinds', 'authors', 'translators',
111             'fragment_data', 'children', 'parent', 'preview',
112             'epub', 'mobi', 'pdf', 'html', 'txt', 'fb2', 'xml', 'media', 'audio_length',
113             'cover_color', 'simple_cover', 'cover_thumb', 'cover', 'simple_thumb',
114             'isbn_pdf', 'isbn_epub', 'isbn_mobi',
115         ]
116         legacy_non_null_fields = ['html', 'txt', 'fb2', 'epub', 'mobi', 'pdf',
117                                   'cover', 'simple_cover', 'cover_thumb', 'simple_thumb']
118
119
120 class BookPreviewSerializer(BookDetailSerializer):
121     class Meta:
122         model = Book
123         fields = BookDetailSerializer.Meta.fields + ['slug']
124         legacy_non_null_fields = BookDetailSerializer.Meta.legacy_non_null_fields
125
126
127 class EbookSerializer(BookListSerializer):
128     txt = EmbargoURLField(source='txt_url')
129     fb2 = EmbargoURLField(source='fb2_url')
130     epub = EmbargoURLField(source='epub_url')
131     mobi = EmbargoURLField(source='mobi_url')
132     pdf = EmbargoURLField(source='pdf_url')
133
134     class Meta:
135         model = Book
136         fields = ['author', 'href', 'title', 'cover', 'slug'] + Book.ebook_formats
137         legacy_non_null_fields = ['author', 'cover'] + Book.ebook_formats
138
139
140 class CollectionListSerializer(serializers.ModelSerializer):
141     url = AbsoluteURLField()
142     href = AbsoluteURLField(view_name='collection-detail', view_args=['slug'])
143
144     class Meta:
145         model = Collection
146         fields = ['url', 'href', 'title']
147
148
149 class CollectionSerializer(serializers.ModelSerializer):
150     books = BookSerializer(many=True, source='get_books', read_only=True)
151     authors = TagSerializer(many=True, read_only=True)
152     book_slugs = serializers.CharField(write_only=True, required=False)
153     author_slugs = serializers.CharField(write_only=True, required=False)
154     url = AbsoluteURLField()
155
156     class Meta:
157         model = Collection
158         fields = [
159             'url', 'books', 'description', 'title',
160             'book_slugs', 'authors', 'author_slugs'
161         ]
162
163     def update(self, instance, validated_data):
164         instance = super().update(instance, validated_data)
165         author_slugs = validated_data.get('author_slugs', '').strip().split()
166         if author_slugs:
167             authors = Tag.objects.filter(
168                 category='author',
169                 slug__in=author_slugs
170             )
171         else:
172             authors = []
173         instance.authors.set(authors)
174         return instance
175
176
177 class FragmentSerializer(serializers.ModelSerializer):
178     book = BookSerializer()
179     url = AbsoluteURLField()
180     href = AbsoluteURLField(source='get_api_url')
181
182     class Meta:
183         model = Fragment
184         fields = ['book', 'url', 'anchor', 'href']
185
186
187 class FragmentDetailSerializer(serializers.ModelSerializer):
188     book = BookSerializer()
189     url = AbsoluteURLField()
190     themes = TagSerializer(many=True)
191
192     class Meta:
193         model = Fragment
194         fields = ['book', 'anchor', 'text', 'url', 'themes']