|
1 import json |
|
2 import uuid |
|
3 |
|
4 from guardian.shortcuts import assign_perm |
|
5 from renkanmanager.models import Renkan, Workspace, Revision |
|
6 from rest_framework import serializers |
|
7 |
|
8 |
|
9 class RenkanSerializer(serializers.Serializer): |
|
10 id = serializers.ReadOnlyField(source="renkan_guid") |
|
11 current_revision_id = serializers.ReadOnlyField(source="current_revision_guid") |
|
12 workspace_id = serializers.CharField(source="workspace_guid", required=False) |
|
13 source_revision_id = serializers.CharField(source="source_revision_guid", required=False) |
|
14 revision_count = serializers.ReadOnlyField() |
|
15 created_by = serializers.StringRelatedField(source="creator") |
|
16 last_updated_by = serializers.SerializerMethodField("get_current_revision_last_updator") |
|
17 title = serializers.CharField(required=False) |
|
18 content = serializers.JSONField(required=False) |
|
19 creation_date = serializers.ReadOnlyField() |
|
20 modification_date = serializers.SerializerMethodField("get_current_revision_modification_date") |
|
21 create_new_revision = serializers.BooleanField(write_only=True, required=False) # only used for updating |
|
22 |
|
23 # ADD ERROR HANDLING |
|
24 def get_current_revision_last_updator(self, renkan): |
|
25 current_revision = Revision.objects.get(revision_guid = renkan.current_revision_guid) |
|
26 return current_revision.last_updated_by.username |
|
27 |
|
28 |
|
29 def get_current_revision_modification_date(self, renkan): |
|
30 current_revision = Revision.objects.get(revision_guid = renkan.current_revision_guid) |
|
31 return current_revision.modification_date |
|
32 |
|
33 def create(self, validated_data): |
|
34 """ |
|
35 Method to create a new Renkan (and its first revision) |
|
36 """ |
|
37 creator = validated_data.get('creator') |
|
38 renkan = Renkan.objects.create() |
|
39 initial_revision = Revision.objects.create() |
|
40 initial_revision.title = validated_data.get('title', 'Untitled renkan') |
|
41 initial_revision.parent_renkan_guid = renkan.renkan_guid |
|
42 initial_revision.creator = creator |
|
43 initial_revision.last_updated_by = validated_data.get('creator', '') |
|
44 renkan.current_revision_guid = initial_revision.revision_guid |
|
45 renkan.workspace_guid = validated_data.get('workspace_guid', '') |
|
46 renkan.source_revision_guid = validated_data.get('source_revision_guid', '') |
|
47 renkan.creator = creator |
|
48 initial_revision.content = validated_data.get('content', json.dumps( |
|
49 { |
|
50 "id": str(renkan.renkan_guid), |
|
51 "title": initial_revision.title, |
|
52 "description": "", |
|
53 "created": str(initial_revision.creation_date), |
|
54 "updated": str(initial_revision.modification_date), |
|
55 "edges": [], |
|
56 "nodes": [], |
|
57 "users": [], |
|
58 "space_id": str(renkan.workspace_guid), |
|
59 "views": [] |
|
60 } |
|
61 )) |
|
62 initial_revision.save() |
|
63 renkan.save() |
|
64 assign_perm('view_renkan', creator, renkan) |
|
65 assign_perm('change_renkan', creator, renkan) |
|
66 assign_perm('delete_renkan', creator, renkan) |
|
67 assign_perm('view_revision', creator, initial_revision) |
|
68 assign_perm('delete_revision', creator, initial_revision) |
|
69 return renkan |
|
70 |
|
71 def update(self, renkan, validated_data): |
|
72 """ |
|
73 Method to update a Renkan object. Creates a new revision if needed |
|
74 """ |
|
75 updator = validated_data.get('updator') |
|
76 current_revision = Revision.objects.get(revision_guid=renkan.current_revision_guid) |
|
77 if validated_data.get("create_new_revision", False): |
|
78 revision_to_update = Revision.objects.create() |
|
79 revision_to_update.parent_renkan_guid = renkan.renkan_guid |
|
80 revision_to_update.creator = updator |
|
81 renkan.current_revision_guid = revision_to_update.revision_guid |
|
82 else: |
|
83 revision_to_update = current_revision |
|
84 revision_to_update.title = validated_data.get('title', current_revision.title) |
|
85 revision_to_update.content = validated_data.get('content', current_revision.content) |
|
86 revision_to_update.last_updated_by = updator |
|
87 revision_to_update.save() |
|
88 if not updator.has_perm('view_revision', revision_to_update): |
|
89 assign_perm('view_revision', updator, revision_to_update) |
|
90 assign_perm('delete_revision', updator, revision_to_update) |
|
91 renkan.save() |
|
92 return renkan |
|
93 |
|
94 def validate_workspace_id(self, value): |
|
95 if self.instance is not None: |
|
96 raise serializers.ValidationError("You cannot update workspace_guid") |
|
97 return value |
|
98 |
|
99 def validate_source_revision_id(self, value): |
|
100 if self.instance is not None: |
|
101 raise serializers.ValidationError("You cannot update source_revision_guid") |
|
102 return value |
|
103 |
|
104 def validate_content(self, value): |
|
105 |
|
106 try: |
|
107 json.loads(value) |
|
108 except ValueError: |
|
109 raise serializers.ValidationError("Content format is not a JSON-serializable") |
|
110 loaded_json = json.loads(value) |
|
111 |
|
112 if (not "nodes" in loaded_json): |
|
113 raise serializers.ValidationError("Content requires a 'nodes' entry") |
|
114 if (not "edges" in loaded_json): |
|
115 raise serializers.ValidationError("Content requires a 'edges' entry") |
|
116 if (not "views" in loaded_json): |
|
117 raise serializers.ValidationError("Content requires a 'views' entry") |
|
118 |
|
119 return value |
|
120 |
|
121 |
|
122 class RevisionSerializer(serializers.Serializer): |
|
123 id = serializers.ReadOnlyField(source="revision_guid") |
|
124 parent_renkan_id = serializers.ReadOnlyField(source="parent_renkan_guid") |
|
125 workspace_id = serializers.SerializerMethodField("get_related_workspace_guid") |
|
126 title = serializers.ReadOnlyField() |
|
127 content = serializers.JSONField(read_only=True) |
|
128 renkan_created_by = serializers.SerializerMethodField("get_related_project_creator") |
|
129 renkan_creation_date = serializers.SerializerMethodField("get_related_project_creation_date") |
|
130 revision_created_by = serializers.StringRelatedField(source="creator") |
|
131 revision_last_updated_by = serializers.StringRelatedField(source="last_updated_by") |
|
132 revision_modification_date = serializers.ReadOnlyField(source="modification_date") |
|
133 |
|
134 def get_related_workspace_guid(self, revision): |
|
135 parent_renkan = Renkan.objects.get(renkan_guid = revision.parent_renkan_guid) |
|
136 return parent_renkan.workspace_guid |
|
137 |
|
138 def get_related_project_creator(self, revision): |
|
139 parent_project = Renkan.objects.get(renkan_guid = revision.parent_renkan_guid) |
|
140 return parent_project.creator.username |
|
141 |
|
142 def get_related_project_creation_date(self, revision): |
|
143 parent_project = Renkan.objects.get(renkan_guid = revision.parent_renkan_guid) |
|
144 return parent_project.creation_date |
|
145 |
|
146 |
|
147 class WorkspaceSerializer(serializers.Serializer): |
|
148 id = serializers.ReadOnlyField(source="workspace_guid") |
|
149 workspace_created_by = serializers.StringRelatedField(source="creator") |
|
150 creation_date = serializers.ReadOnlyField() |
|
151 renkan_count = serializers.ReadOnlyField() |
|
152 title = serializers.CharField() |
|
153 |
|
154 def create(self, validated_data): |
|
155 creator = validated_data.get('creator') |
|
156 workspace = Workspace.objects.create() |
|
157 workspace.title = validated_data.get('title', '') |
|
158 workspace.creator = creator |
|
159 workspace.save() |
|
160 assign_perm('view_workspace', creator, workspace) |
|
161 assign_perm('change_workspace', creator, workspace) |
|
162 assign_perm('delete_workspace', creator, workspace) |
|
163 return workspace |
|
164 |
|
165 def update(self, workspace, validated_data): |
|
166 workspace.title = validated_data.get('title', '') |
|
167 workspace.save() |
|
168 return workspace |