Minor upgrades and test fixes.
[wolnelektury.git] / src / catalogue / api / serializers.py
1 # This file is part of Wolne Lektury, licensed under GNU Affero GPLv3 or later.
2 # Copyright © Fundacja Wolne Lektury. 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 = [
28             'name', 'url', 'sort_key',
29             'description',
30             'description_pl',
31             'plural', 'genre_epoch_specific',
32             'adjective_feminine_singular', 'adjective_nonmasculine_plural',
33             'genitive', 'collective_noun',
34         ]
35         write_only_fields = [
36             'description_pl',
37             'plural', 'genre_epoch_specific',
38             'adjective_feminine_singular', 'adjective_nonmasculine_plural',
39             'genitive', 'collective_noun',
40         ]
41
42
43 class TranslatorSerializer(serializers.Serializer):
44     name = serializers.CharField(source='*')
45
46
47 class BookSerializer2(serializers.ModelSerializer):
48     url = AbsoluteURLField()
49     href = AbsoluteURLField(view_name='catalogue_api_book', view_args=['slug'])
50     xml = EmbargoURLField(source='xml_url')
51     html = EmbargoURLField(source='html_url')
52     txt = EmbargoURLField(source='txt_url')
53     fb2 = EmbargoURLField(source='fb2_url')
54     epub = EmbargoURLField(source='epub_url')
55     mobi = EmbargoURLField(source='mobi_url')
56     pdf = EmbargoURLField(source='pdf_url')
57
58     class Meta:
59         model = Book
60         fields = [
61             'full_sort_key', 'title',
62             'href', 'url', 'language',
63             #'epochs', 'genres', 'kinds', 'authors', 'translators',
64             #'children',
65             'parent', 'preview',
66             'epub', 'mobi', 'pdf', 'html', 'txt', 'fb2', 'xml',
67             'cover_thumb', 'cover',
68             'isbn_pdf', 'isbn_epub', 'isbn_mobi',
69         ]
70
71 class BookSerializer(LegacyMixin, serializers.ModelSerializer):
72     author = serializers.CharField(source='author_unicode')
73     kind = serializers.CharField(source='kind_unicode')
74     epoch = serializers.CharField(source='epoch_unicode')
75     genre = serializers.CharField(source='genre_unicode')
76     liked = BookLiked()
77
78     simple_thumb = serializers.FileField(source='cover_api_thumb')
79     href = AbsoluteURLField(view_name='catalogue_api_book', view_args=['slug'])
80     url = AbsoluteURLField()
81     cover_thumb = ThumbnailField('139x193', source='cover')
82
83     class Meta:
84         model = Book
85         fields = [
86             'kind', 'full_sort_key', 'title', 'url', 'cover_color', 'author',
87             'cover', 'epoch', 'href', 'has_audio', 'genre',
88             'simple_thumb', 'slug', 'cover_thumb', 'liked']
89         legacy_non_null_fields = [
90             'kind', 'author', 'epoch', 'genre',
91             'cover', 'simple_thumb', 'cover_thumb']
92
93
94 class BookListSerializer(BookSerializer):
95     cover = serializers.CharField()
96     cover_thumb = serializers.CharField()
97
98     Meta = BookSerializer.Meta
99
100
101 class FilterBookListSerializer(BookListSerializer):
102     key = serializers.CharField()
103
104     class Meta:
105         model = Book
106         fields = BookListSerializer.Meta.fields + ['key']
107         legacy_non_null_fields = BookListSerializer.Meta.legacy_non_null_fields
108
109
110 class MediaSerializer(LegacyMixin, serializers.ModelSerializer):
111     url = EmbargoURLField(source='file_url')
112
113     class Meta:
114         model = BookMedia
115         fields = ['url', 'director', 'type', 'name', 'artist']
116         legacy_non_null_fields = ['director', 'artist']
117
118
119 class BookDetailSerializer(LegacyMixin, serializers.ModelSerializer):
120     url = AbsoluteURLField()
121
122     authors = TagSerializer(many=True)
123     translators = TranslatorSerializer(many=True)
124     epochs = TagSerializer(many=True)
125     genres = TagSerializer(many=True)
126     kinds = TagSerializer(many=True)
127
128     fragment_data = serializers.DictField()
129     parent = BookSerializer()
130     children = BookSerializer(many=True)
131
132     xml = EmbargoURLField(source='xml_url')
133     html = EmbargoURLField(source='html_url')
134     txt = EmbargoURLField(source='txt_url')
135     fb2 = EmbargoURLField(source='fb2_url')
136     epub = EmbargoURLField(source='epub_url')
137     mobi = EmbargoURLField(source='mobi_url')
138     pdf = EmbargoURLField(source='pdf_url')
139     media = MediaSerializer(many=True)
140     cover_thumb = ThumbnailField('139x193', source='cover')
141     simple_thumb = serializers.FileField(source='cover_api_thumb')
142
143     class Meta:
144         model = Book
145         fields = [
146             'title', 'url', 'language',
147             'epochs', 'genres', 'kinds', 'authors', 'translators',
148             'fragment_data', 'children', 'parent', 'preview',
149             'epub', 'mobi', 'pdf', 'html', 'txt', 'fb2', 'xml', 'media', 'audio_length',
150             'cover_color', 'simple_cover', 'cover_thumb', 'cover', 'simple_thumb',
151             'isbn_pdf', 'isbn_epub', 'isbn_mobi',
152         ]
153         legacy_non_null_fields = ['html', 'txt', 'fb2', 'epub', 'mobi', 'pdf',
154                                   'cover', 'simple_cover', 'cover_thumb', 'simple_thumb']
155
156
157 class BookPreviewSerializer(BookDetailSerializer):
158     class Meta:
159         model = Book
160         fields = BookDetailSerializer.Meta.fields + ['slug']
161         legacy_non_null_fields = BookDetailSerializer.Meta.legacy_non_null_fields
162
163
164 class EbookSerializer(BookListSerializer):
165     txt = EmbargoURLField(source='txt_url')
166     fb2 = EmbargoURLField(source='fb2_url')
167     epub = EmbargoURLField(source='epub_url')
168     mobi = EmbargoURLField(source='mobi_url')
169     pdf = EmbargoURLField(source='pdf_url')
170
171     class Meta:
172         model = Book
173         fields = ['author', 'href', 'title', 'cover', 'slug'] + Book.ebook_formats
174         legacy_non_null_fields = ['author', 'cover'] + Book.ebook_formats
175
176
177 class CollectionListSerializer(serializers.ModelSerializer):
178     url = AbsoluteURLField()
179     href = AbsoluteURLField(view_name='collection-detail', view_args=['slug'])
180
181     class Meta:
182         model = Collection
183         fields = ['url', 'href', 'title']
184
185
186 class CollectionSerializer(serializers.ModelSerializer):
187     books = BookSerializer(many=True, source='get_books', read_only=True)
188     authors = TagSerializer(many=True, read_only=True)
189     book_slugs = serializers.CharField(write_only=True, required=False)
190     author_slugs = serializers.CharField(write_only=True, required=False)
191     url = AbsoluteURLField()
192
193     class Meta:
194         model = Collection
195         fields = [
196             'url', 'books', 'description', 'title',
197             'book_slugs', 'authors', 'author_slugs'
198         ]
199
200     def update(self, instance, validated_data):
201         instance = super().update(instance, validated_data)
202         author_slugs = validated_data.get('author_slugs', '').strip().split()
203         if author_slugs:
204             authors = Tag.objects.filter(
205                 category='author',
206                 slug__in=author_slugs
207             )
208         else:
209             authors = []
210         instance.authors.set(authors)
211         return instance
212
213
214 class FragmentSerializer(serializers.ModelSerializer):
215     book = BookSerializer()
216     url = AbsoluteURLField()
217     href = AbsoluteURLField(source='get_api_url')
218
219     class Meta:
220         model = Fragment
221         fields = ['book', 'url', 'anchor', 'href']
222
223
224 class FragmentDetailSerializer(serializers.ModelSerializer):
225     book = BookSerializer()
226     url = AbsoluteURLField()
227     themes = TagSerializer(many=True)
228
229     class Meta:
230         model = Fragment
231         fields = ['book', 'anchor', 'text', 'url', 'themes']