1 import json |
1 import json, uuid, datetime, time |
2 import uuid |
|
3 |
2 |
|
3 from django.db import transaction |
4 from django.contrib.auth import get_user_model |
4 from django.contrib.auth import get_user_model |
5 from django.conf import settings |
5 from django.conf import settings |
6 from renkanmanager.models import Renkan, Workspace, Revision |
6 from renkanmanager.models import Renkan, Workspace, Revision |
7 from rest_framework import serializers |
7 from rest_framework import serializers |
8 |
8 |
9 RENKAN_USER_DISPLAY_FIELD = getattr(settings, "RENKAN_USER_DISPLAY_FIELD", get_user_model().USERNAME_FIELD) |
9 RENKAN_USER_DISPLAY_FIELD = getattr(settings, "RENKAN_USER_DISPLAY_FIELD", get_user_model().USERNAME_FIELD) |
10 |
10 |
11 class RenkanSerializer(serializers.Serializer): |
11 class RenkanSerializer(serializers.Serializer): |
12 id = serializers.ReadOnlyField(source="renkan_guid") |
12 id = serializers.ReadOnlyField(source="renkan_guid") |
13 current_revision_id = serializers.ReadOnlyField(source="current_revision_guid") |
13 current_revision_id = serializers.SlugRelatedField(source="current_revision", slug_field="revision_guid", read_only=True) |
14 workspace_id = serializers.CharField(source="workspace_guid", required=False) |
14 workspace_id = serializers.SlugRelatedField(source="workspace", slug_field="workspace_guid", queryset=Workspace.objects, required=False) |
15 source_revision_id = serializers.CharField(source="source_revision_guid", required=False) |
15 source_revision_id = serializers.SlugRelatedField(source="source_revision", slug_field="revision_guid", queryset=Revision.objects, required=False) |
16 revision_count = serializers.ReadOnlyField() |
16 revision_count = serializers.ReadOnlyField() |
17 created_by = serializers.SlugRelatedField(source="creator", slug_field=RENKAN_USER_DISPLAY_FIELD, read_only=True) |
17 created_by = serializers.SlugRelatedField(source="creator", slug_field=RENKAN_USER_DISPLAY_FIELD, read_only=True) |
18 last_updated_by = serializers.SerializerMethodField("get_current_revision_last_updator") |
18 last_updated_by = serializers.SerializerMethodField("get_current_revision_last_updator") |
19 title = serializers.CharField(required=False) |
19 title = serializers.CharField(required=False) |
20 content = serializers.JSONField(required=False) |
20 content = serializers.JSONField(required=False) |
21 creation_date = serializers.ReadOnlyField() |
21 creation_date = serializers.ReadOnlyField() |
22 modification_date = serializers.SerializerMethodField("get_current_revision_modification_date") |
22 modification_date = serializers.SerializerMethodField("get_current_revision_modification_date") |
23 create_new_revision = serializers.BooleanField(write_only=True, required=False) # only used for updating |
23 create_new_revision = serializers.BooleanField(write_only=True, required=False) # only used for updating |
|
24 validation_timestamp = serializers.CharField(write_only=True, required=False) # only used for updating is a content json is not provided |
24 |
25 |
25 # ADD ERROR HANDLING |
26 # ADD ERROR HANDLING |
26 def get_current_revision_last_updator(self, renkan): |
27 def get_current_revision_last_updator(self, renkan): |
27 current_revision = Revision.objects.get(revision_guid = renkan.current_revision_guid) |
28 return getattr(renkan.current_revision.last_updated_by, RENKAN_USER_DISPLAY_FIELD) |
28 return getattr(current_revision.last_updated_by, RENKAN_USER_DISPLAY_FIELD) |
|
29 |
29 |
30 |
30 |
31 def get_current_revision_modification_date(self, renkan): |
31 def get_current_revision_modification_date(self, renkan): |
32 current_revision = Revision.objects.get(revision_guid = renkan.current_revision_guid) |
32 return renkan.current_revision.modification_date |
33 return current_revision.modification_date |
|
34 |
33 |
|
34 @transaction.atomic |
35 def create(self, validated_data): |
35 def create(self, validated_data): |
36 """ |
36 """ |
37 Method to create a new Renkan (and its first revision) |
37 Method to create a new Renkan (and its first revision) |
38 """ |
38 """ |
39 creator = validated_data.get('creator') |
39 creator = validated_data.get('creator') |
40 initial_revision = Revision.objects.create( |
40 workspace_obj = validated_data.get('workspace', None) |
41 title = validated_data.get('title', 'Untitled renkan'), |
41 source_revision_obj = validated_data.get('source_revision', None) |
42 creator = creator, |
42 try: |
43 last_updated_by = creator |
43 return Renkan.objects.create_renkan( |
44 ) |
44 creator=creator, |
45 renkan = Renkan.objects.create( |
45 title=validated_data.get('title', ''), |
46 current_revision_guid = initial_revision.revision_guid, |
46 content=validated_data.get('content', ''), |
47 workspace_guid = validated_data.get('workspace_guid', ''), |
47 workspace=workspace_obj, |
48 source_revision_guid = validated_data.get('source_revision_guid', ''), |
48 source_revision=source_revision_obj |
49 creator = creator |
49 ) |
50 ) |
50 except ValidationError as ve: |
51 initial_revision.parent_renkan_guid = renkan.renkan_guid |
51 raise serializers.ValidationError(ve.args[0]) |
52 initial_revision.content = validated_data.get('content', json.dumps( |
|
53 { |
|
54 "id": str(renkan.renkan_guid), |
|
55 "title": initial_revision.title, |
|
56 "description": "", |
|
57 "created": str(initial_revision.creation_date), |
|
58 "updated": str(initial_revision.modification_date), |
|
59 "edges": [], |
|
60 "nodes": [], |
|
61 "users": [], |
|
62 "space_id": str(renkan.workspace_guid), |
|
63 "views": [] |
|
64 } |
|
65 )) |
|
66 initial_revision.save() |
|
67 renkan.save() |
|
68 return renkan |
|
69 |
52 |
|
53 @transaction.atomic |
70 def update(self, renkan, validated_data): |
54 def update(self, renkan, validated_data): |
71 """ |
55 """ |
72 Method to update a Renkan object. Creates a new revision if needed |
56 Method to update a Renkan object. Creates a new revision if needed |
73 """ |
57 """ |
74 updator = validated_data.get('updator') |
58 updator = validated_data.get('updator') |
75 current_revision = Revision.objects.get(revision_guid=renkan.current_revision_guid) |
59 create_new_revision = validated_data.get("create_new_revision", False) |
76 if validated_data.get("create_new_revision", False): |
60 title = validated_data.get('title', renkan.current_revision.title) |
77 revision_to_update = Revision.objects.create(creator=updator) |
61 content = validated_data.get('content', '') |
78 revision_to_update.parent_renkan_guid = renkan.renkan_guid |
62 if not content: |
79 renkan.current_revision_guid = revision_to_update.revision_guid |
63 content = renkan.current_revision.content |
|
64 if not 'validation_timestamp' in validated_data: |
|
65 raise serializers.ValidationError("No validation timestamp and no content json to extract it from") |
|
66 validation_timestamp = validated_data.get('validation_timestamp') |
80 else: |
67 else: |
81 revision_to_update = current_revision |
68 validation_timestamp = json.loads(content).get("updated", "") |
82 revision_to_update.title = validated_data.get('title', current_revision.title) |
69 if title != json.loads(content).get("title", ""): |
83 revision_to_update.content = validated_data.get('content', current_revision.content) |
70 content_dict = json.loads(content) |
84 revision_to_update.last_updated_by = updator |
71 content_dict["title"] = title |
85 revision_to_update.save() |
72 content = json.dumps(content_dict) |
86 if not updator.has_perm('view_revision', revision_to_update): |
73 try: |
87 assign_perm('view_revision', updator, revision_to_update) |
74 renkan.save_renkan(updator=updator, timestamp=validation_timestamp, title=title, content=content, create_new_revision=create_new_revision) |
88 assign_perm('delete_revision', updator, revision_to_update) |
75 except ValidationError as ve: |
89 renkan.save() |
76 raise serializers.ValidationError(ve.args[0]) |
90 return renkan |
77 return renkan |
91 |
78 |
92 def validate_workspace_id(self, value): |
79 def validate_workspace_id(self, value): |
93 if self.instance is not None: |
80 if self.instance is not None: |
94 raise serializers.ValidationError("You cannot update workspace_guid") |
81 raise serializers.ValidationError("You cannot update workspace_guid") |
117 return value |
103 return value |
118 |
104 |
119 |
105 |
120 class RevisionSerializer(serializers.Serializer): |
106 class RevisionSerializer(serializers.Serializer): |
121 id = serializers.ReadOnlyField(source="revision_guid") |
107 id = serializers.ReadOnlyField(source="revision_guid") |
122 parent_renkan_id = serializers.ReadOnlyField(source="parent_renkan_guid") |
108 parent_renkan_id = serializers.SlugRelatedField(source="parent_renkan", slug_field='renkan_guid', read_only=True) |
123 workspace_id = serializers.SerializerMethodField("get_related_workspace_guid") |
109 workspace_id = serializers.SerializerMethodField("get_related_workspace_guid") |
124 title = serializers.ReadOnlyField() |
110 title = serializers.ReadOnlyField() |
125 content = serializers.JSONField(read_only=True) |
111 content = serializers.JSONField(read_only=True) |
126 renkan_created_by = serializers.SerializerMethodField("get_related_renkan_creator") |
112 renkan_created_by = serializers.SerializerMethodField("get_related_renkan_creator") |
127 renkan_creation_date = serializers.SerializerMethodField("get_related_renkan_creation_date") |
113 renkan_creation_date = serializers.SerializerMethodField("get_related_renkan_creation_date") |
128 revision_created_by = serializers.SlugRelatedField(source="creator", slug_field=RENKAN_USER_DISPLAY_FIELD, read_only=True) |
114 revision_created_by = serializers.SlugRelatedField(source="creator", slug_field=RENKAN_USER_DISPLAY_FIELD, read_only=True) |
129 revision_last_updated_by = serializers.StringRelatedField(source="last_updated_by") |
115 revision_last_updated_by = serializers.SlugRelatedField(source="last_updated_by", slug_field=RENKAN_USER_DISPLAY_FIELD, read_only=True) |
130 revision_modification_date = serializers.ReadOnlyField(source="modification_date") |
116 revision_modification_date = serializers.ReadOnlyField(source="modification_date") |
131 |
117 |
132 def get_related_workspace_guid(self, revision): |
118 def get_related_workspace_guid(self, revision): |
133 parent_renkan = Renkan.objects.get(renkan_guid = revision.parent_renkan_guid) |
119 if revision.parent_renkan.workspace: |
134 return parent_renkan.workspace_guid |
120 return revision.parent_renkan.workspace.workspace_guid |
|
121 else: |
|
122 return '' |
135 |
123 |
136 def get_related_renkan_creator(self, revision): |
124 def get_related_renkan_creator(self, revision): |
137 parent_renkan = Renkan.objects.get(renkan_guid = revision.parent_renkan_guid) |
125 return getattr(revision.parent_renkan.creator, RENKAN_USER_DISPLAY_FIELD) |
138 return getattr(parent_renkan.creator, RENKAN_USER_DISPLAY_FIELD) |
|
139 |
126 |
140 def get_related_renkan_creation_date(self, revision): |
127 def get_related_renkan_creation_date(self, revision): |
141 parent_renkan = Renkan.objects.get(renkan_guid = revision.parent_renkan_guid) |
128 return revision.parent_renkan.creation_date |
142 return parent_renkan.creation_date |
|
143 |
129 |
144 |
130 |
145 class WorkspaceSerializer(serializers.Serializer): |
131 class WorkspaceSerializer(serializers.Serializer): |
146 id = serializers.ReadOnlyField(source="workspace_guid") |
132 id = serializers.ReadOnlyField(source="workspace_guid") |
147 workspace_created_by = serializers.SlugRelatedField(source="creator", slug_field=RENKAN_USER_DISPLAY_FIELD, read_only=True) |
133 workspace_created_by = serializers.SlugRelatedField(source="creator", slug_field=RENKAN_USER_DISPLAY_FIELD, read_only=True) |