API v4: change book representation when reading bookmarks to full.
[wolnelektury.git] / src / social / 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 import bookmarks.api.views
6 import bookmarks.models
7 import catalogue.api.serializers
8 import catalogue.models
9 from social import models
10
11
12 class SettingsSerializer(serializers.ModelSerializer):
13     class Meta:
14         model = models.UserProfile
15         fields = ['notifications']
16
17
18 class UserListBooksField(serializers.Field):
19     def to_representation(self, value):
20         return list(value.userlistitem_set.exclude(deleted=True).exclude(book=None).values_list('book__slug', flat=True))
21
22     def to_internal_value(self, value):
23         return {'books': catalogue.models.Book.objects.filter(slug__in=value)}
24
25
26 class UserListSerializerV2(serializers.ModelSerializer):
27     client_id = serializers.CharField(write_only=True, required=False)
28     books = UserListBooksField(source='*', required=False)
29     timestamp = serializers.IntegerField(required=False)
30
31     class Meta:
32         model = models.UserList
33         fields = [
34             'timestamp',
35             'client_id',
36             'name',
37             'slug',
38             'favorites',
39             'deleted',
40             'books',
41         ]
42         read_only_fields = [
43             'favorites',
44             'slug',
45         ]
46         extra_kwargs = {
47             'slug': {
48                 'required': False
49             }
50         }
51
52     def create(self, validated_data):
53         instance = models.UserList.get_by_name(
54             validated_data['user'],
55             validated_data['name'],
56             create=True
57         )
58         if 'books' in validated_data:
59             instance.userlistitem_set.all().delete()
60             for book in validated_data['books']:
61                 instance.append(book)
62         return instance
63
64     def update(self, instance, validated_data):
65         super().update(instance, validated_data)
66         if 'books' in validated_data:
67             instance.userlistitem_set.all().delete()
68             for book in validated_data['books']:
69                 instance.append(instance)
70         return instance
71
72
73 class UserListBooksSerializer(UserListSerializerV2):
74     class Meta:
75         model = models.UserList
76         fields = ['books']
77
78
79 class UserListItemSerializer(serializers.ModelSerializer):
80     client_id = serializers.CharField(write_only=True, required=False)
81     favorites = serializers.BooleanField(read_only=True)
82     list_slug = serializers.SlugRelatedField(
83         queryset=models.UserList.objects.all(),
84         source='list',
85         slug_field='slug',
86         required=False,
87     )
88     timestamp = serializers.IntegerField(required=False)
89     book_slug = serializers.SlugRelatedField(
90         queryset=catalogue.models.Book.objects.all(),
91         source='book',
92         slug_field='slug',
93         required=False,
94         allow_null=True
95     )
96     bookmark = serializers.SlugRelatedField(
97         queryset=bookmarks.models.Bookmark.objects.all(),
98         slug_field='uuid',
99         required=False,
100         allow_null=True
101     )
102     quote = serializers.SlugRelatedField(
103         queryset=bookmarks.models.Quote.objects.all(),
104         slug_field='uuid',
105         required=False,
106         allow_null=True
107     )
108
109     class Meta:
110         model = models.UserListItem
111         fields = [
112             'client_id',
113             'uuid',
114             'order',
115             'list_slug',
116             'timestamp',
117             'favorites',
118             'deleted',
119
120             'book_slug',
121             'fragment',
122             'quote',
123             'bookmark',
124             'note',
125         ]
126         extra_kwargs = {
127             'order': {
128                 'required': False
129             }
130         }
131
132
133 class UserListItemReadSerializerV3(UserListItemSerializer):
134     book = catalogue.api.serializers.BookSerializer2()
135     bookmark = bookmarks.api.views.BookmarkSerializerV3()
136     class Meta:
137         model = models.UserListItem
138         fields = [
139             'client_id',
140             'uuid',
141             'order',
142             'list_slug',
143             'timestamp',
144             'favorites',
145             'deleted',
146
147             'book',
148             'fragment',
149             'quote',
150             'bookmark',
151             'note',
152         ]
153
154 class UserListItemReadSerializer(UserListItemSerializer):
155     book = catalogue.api.serializers.BookSerializer2()
156     bookmark = bookmarks.api.views.BookmarkSerializer()
157     class Meta:
158         model = models.UserListItem
159         fields = [
160             'client_id',
161             'uuid',
162             'order',
163             'list_slug',
164             'timestamp',
165             'favorites',
166             'deleted',
167
168             'book',
169             'fragment',
170             'quote',
171             'bookmark',
172             'note',
173         ]
174
175
176 class UserListSerializerV3(serializers.ModelSerializer):
177     client_id = serializers.CharField(write_only=True, required=False)
178     timestamp = serializers.IntegerField(required=False)
179
180     class Meta:
181         model = models.UserList
182         fields = [
183             'timestamp',
184             'client_id',
185             'name',
186             'slug',
187             'favorites',
188             'deleted',
189         ]
190         read_only_fields = [
191             'favorites',
192             'slug',
193         ]
194         extra_kwargs = {
195             'slug': {
196                 'required': False
197             }
198         }
199
200     def create(self, validated_data):
201         instance = models.UserList.get_by_name(
202             validated_data['user'],
203             validated_data['name'],
204             create=True
205         )
206         return instance
207
208
209 class ProgressSerializer(serializers.ModelSerializer):
210     book = serializers.HyperlinkedRelatedField(
211         read_only=True,
212         view_name='catalogue_api_book',
213         lookup_field='slug'
214     )
215     book_slug = serializers.SlugRelatedField(
216         queryset=catalogue.models.Book.objects.all(),
217         source='book',
218         slug_field='slug')
219     timestamp = serializers.IntegerField(required=False)
220
221     class Meta:
222         model = models.Progress
223         fields = [
224             'timestamp',
225             'book', 'book_slug', 'last_mode', 'text_percent',
226             'text_anchor',
227             'audio_percent',
228             'audio_timestamp',
229             'implicit_text_percent',
230             'implicit_text_anchor',
231             'implicit_audio_percent',
232             'implicit_audio_timestamp',
233         ]
234         extra_kwargs = {
235             'last_mode': {
236                 'required': False,
237                 'default': 'text',
238             }
239         }
240
241
242 class TextProgressSerializer(serializers.ModelSerializer):
243     class Meta:
244         model = models.Progress
245         fields = [
246                 'text_percent',
247                 'text_anchor',
248                 ]
249         read_only_fields = ['text_percent']
250
251 class AudioProgressSerializer(serializers.ModelSerializer):
252     class Meta:
253         model = models.Progress
254         fields = ['audio_percent', 'audio_timestamp']
255         read_only_fields = ['audio_percent']