Separate list item read-only serializer.
[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 UserListItemReadSerializer(UserListItemSerializer):
134     book = catalogue.api.serializers.BookSerializer2()
135     bookmark = bookmarks.api.views.BookmarkSerializer()
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
155 class UserListSerializerV3(serializers.ModelSerializer):
156     client_id = serializers.CharField(write_only=True, required=False)
157     timestamp = serializers.IntegerField(required=False)
158
159     class Meta:
160         model = models.UserList
161         fields = [
162             'timestamp',
163             'client_id',
164             'name',
165             'slug',
166             'favorites',
167             'deleted',
168         ]
169         read_only_fields = [
170             'favorites',
171             'slug',
172         ]
173         extra_kwargs = {
174             'slug': {
175                 'required': False
176             }
177         }
178
179     def create(self, validated_data):
180         instance = models.UserList.get_by_name(
181             validated_data['user'],
182             validated_data['name'],
183             create=True
184         )
185         return instance
186
187
188 class ProgressSerializer(serializers.ModelSerializer):
189     book = serializers.HyperlinkedRelatedField(
190         read_only=True,
191         view_name='catalogue_api_book',
192         lookup_field='slug'
193     )
194     book_slug = serializers.SlugRelatedField(
195         queryset=catalogue.models.Book.objects.all(),
196         source='book',
197         slug_field='slug')
198     timestamp = serializers.IntegerField(required=False)
199
200     class Meta:
201         model = models.Progress
202         fields = [
203             'timestamp',
204             'book', 'book_slug', 'last_mode', 'text_percent',
205             'text_anchor',
206             'audio_percent',
207             'audio_timestamp',
208             'implicit_text_percent',
209             'implicit_text_anchor',
210             'implicit_audio_percent',
211             'implicit_audio_timestamp',
212         ]
213         extra_kwargs = {
214             'last_mode': {
215                 'required': False,
216                 'default': 'text',
217             }
218         }
219
220
221 class TextProgressSerializer(serializers.ModelSerializer):
222     class Meta:
223         model = models.Progress
224         fields = [
225                 'text_percent',
226                 'text_anchor',
227                 ]
228         read_only_fields = ['text_percent']
229
230 class AudioProgressSerializer(serializers.ModelSerializer):
231     class Meta:
232         model = models.Progress
233         fields = ['audio_percent', 'audio_timestamp']
234         read_only_fields = ['audio_percent']