v3: User lists
[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 catalogue.models
6 from social import models
7
8
9 class SettingsSerializer(serializers.ModelSerializer):
10     class Meta:
11         model = models.UserProfile
12         fields = ['notifications']
13
14
15 class UserListBooksField(serializers.Field):
16     def to_representation(self, value):
17         return value.userlistitem_set.exclude(deleted=True).exclude(book=None).values_list('book__slug', flat=True)
18
19     def to_internal_value(self, value):
20         return {'books': catalogue.models.Book.objects.filter(slug__in=value)}
21
22
23 class UserListSerializerV2(serializers.ModelSerializer):
24     client_id = serializers.CharField(write_only=True, required=False)
25     books = UserListBooksField(source='*', required=False)
26     timestamp = serializers.IntegerField(required=False)
27
28     class Meta:
29         model = models.UserList
30         fields = [
31             'timestamp',
32             'client_id',
33             'name',
34             'slug',
35             'favorites',
36             'deleted',
37             'books',
38         ]
39         read_only_fields = [
40             'favorites',
41             'slug',
42         ]
43         extra_kwargs = {
44             'slug': {
45                 'required': False
46             }
47         }
48
49     def create(self, validated_data):
50         instance = models.UserList.get_by_name(
51             validated_data['user'],
52             validated_data['name'],
53             create=True
54         )
55         if 'books' in validated_data:
56             instance.userlistitem_set.all().delete()
57             for book in validated_data['books']:
58                 instance.append(book)
59         return instance
60
61     def update(self, instance, validated_data):
62         super().update(instance, validated_data)
63         if 'books' in validated_data:
64             instance.userlistitem_set.all().delete()
65             for book in validated_data['books']:
66                 instance.append(instance)
67         return instance
68
69
70 class UserListBooksSerializer(UserListSerializerV2):
71     class Meta:
72         model = models.UserList
73         fields = ['books']
74
75
76 class UserListItemSerializer(serializers.ModelSerializer):
77     client_id = serializers.CharField(write_only=True, required=False)
78     favorites = serializers.BooleanField(required=False)
79     list_slug = serializers.SlugRelatedField(
80         queryset=models.UserList.objects.all(),
81         source='list',
82         slug_field='slug',
83         required=False,
84     )
85     timestamp = serializers.IntegerField(required=False)
86     book_slug = serializers.SlugRelatedField(
87         queryset=catalogue.models.Book.objects.all(),
88         source='book',
89         slug_field='slug',
90         required=False
91     )
92
93     class Meta:
94         model = models.UserListItem
95         fields = [
96             'client_id',
97             'uuid',
98             'order',
99             'list_slug',
100             'timestamp',
101             'favorites',
102             'deleted',
103
104             'book_slug',
105             'fragment',
106             'quote',
107             'bookmark',
108             'note',
109         ]
110         extra_kwargs = {
111             'order': {
112                 'required': False
113             }
114         }
115
116
117 class UserListSerializerV3(serializers.ModelSerializer):
118     client_id = serializers.CharField(write_only=True, required=False)
119     timestamp = serializers.IntegerField(required=False)
120
121     class Meta:
122         model = models.UserList
123         fields = [
124             'timestamp',
125             'client_id',
126             'name',
127             'slug',
128             'favorites',
129             'deleted',
130         ]
131         read_only_fields = [
132             'favorites',
133             'slug',
134         ]
135         extra_kwargs = {
136             'slug': {
137                 'required': False
138             }
139         }
140
141     def create(self, validated_data):
142         instance = models.UserList.get_by_name(
143             validated_data['user'],
144             validated_data['name'],
145             create=True
146         )
147         return instance
148
149
150 class ProgressSerializer(serializers.ModelSerializer):
151     book = serializers.HyperlinkedRelatedField(
152         read_only=True,
153         view_name='catalogue_api_book',
154         lookup_field='slug'
155     )
156     book_slug = serializers.SlugRelatedField(
157         queryset=catalogue.models.Book.objects.all(),
158         source='book',
159         slug_field='slug')
160     timestamp = serializers.IntegerField(required=False)
161
162     class Meta:
163         model = models.Progress
164         fields = [
165             'timestamp',
166             'book', 'book_slug', 'last_mode', 'text_percent',
167             'text_anchor',
168             'audio_percent',
169             'audio_timestamp',
170             'implicit_text_percent',
171             'implicit_text_anchor',
172             'implicit_audio_percent',
173             'implicit_audio_timestamp',
174         ]
175         extra_kwargs = {
176             'last_mode': {
177                 'required': False,
178                 'default': 'text',
179             }
180         }
181
182
183 class TextProgressSerializer(serializers.ModelSerializer):
184     class Meta:
185         model = models.Progress
186         fields = [
187                 'text_percent',
188                 'text_anchor',
189                 ]
190         read_only_fields = ['text_percent']
191
192 class AudioProgressSerializer(serializers.ModelSerializer):
193     class Meta:
194         model = models.Progress
195         fields = ['audio_percent', 'audio_timestamp']
196         read_only_fields = ['audio_percent']