1 import json, uuid, datetime, time |
1 import json, logging, uuid, datetime, time |
2 |
2 |
3 from django.db import transaction |
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 django.core.exceptions import ValidationError |
|
7 from django.utils import dateparse |
6 from renkanmanager.models import Renkan, Workspace, Revision |
8 from renkanmanager.models import Renkan, Workspace, Revision |
7 from rest_framework import serializers |
9 from rest_framework import serializers |
8 |
10 |
|
11 logger = logging.getLogger(__name__) |
9 RENKAN_USER_DISPLAY_FIELD = getattr(settings, "RENKAN_USER_DISPLAY_FIELD", get_user_model().USERNAME_FIELD) |
12 RENKAN_USER_DISPLAY_FIELD = getattr(settings, "RENKAN_USER_DISPLAY_FIELD", get_user_model().USERNAME_FIELD) |
10 |
13 |
11 class RenkanSerializer(serializers.Serializer): |
14 class RenkanSerializer(serializers.Serializer): |
12 id = serializers.ReadOnlyField(source="renkan_guid") |
15 id = serializers.ReadOnlyField(source="renkan_guid") |
13 current_revision_id = serializers.SlugRelatedField(source="current_revision", slug_field="revision_guid", read_only=True) |
16 current_revision_id = serializers.SlugRelatedField(source="current_revision", slug_field="revision_guid", read_only=True) |
64 if not 'validation_timestamp' in validated_data: |
67 if not 'validation_timestamp' in validated_data: |
65 raise serializers.ValidationError("No validation timestamp and no content json to extract it from") |
68 raise serializers.ValidationError("No validation timestamp and no content json to extract it from") |
66 validation_timestamp = validated_data.get('validation_timestamp') |
69 validation_timestamp = validated_data.get('validation_timestamp') |
67 else: |
70 else: |
68 validation_timestamp = json.loads(content).get("updated", "") |
71 validation_timestamp = json.loads(content).get("updated", "") |
|
72 if dateparse.parse_datetime(validation_timestamp) < renkan.current_revision.modification_date: |
|
73 raise serializers.ValidationError("Provided timestamp is invalid") |
69 if title != json.loads(content).get("title", ""): |
74 if title != json.loads(content).get("title", ""): |
70 content_dict = json.loads(content) |
75 content_dict = json.loads(content) |
71 content_dict["title"] = title |
76 content_dict["title"] = title |
72 content = json.dumps(content_dict) |
77 content = json.dumps(content_dict) |
73 try: |
78 try: |
74 renkan.save_renkan(updator=updator, timestamp=validation_timestamp, title=title, content=content, create_new_revision=create_new_revision) |
79 renkan.save_renkan(updator=updator, timestamp=validation_timestamp, title=title, content=content, create_new_revision=create_new_revision) |
75 except ValidationError as ve: |
80 except ValidationError as ve: |
76 raise serializers.ValidationError(ve.args[0]) |
81 raise serializers.ValidationError(str(ve.args[0])) |
77 return renkan |
82 return renkan |
78 |
83 |
79 def validate_workspace_id(self, value): |
84 def validate_workspace_id(self, value): |
80 if self.instance is not None: |
85 if self.instance is not None: |
81 raise serializers.ValidationError("You cannot update workspace_guid") |
86 raise serializers.ValidationError("You cannot update workspace_guid") |
86 raise serializers.ValidationError("You cannot update source_revision_guid") |
91 raise serializers.ValidationError("You cannot update source_revision_guid") |
87 return value |
92 return value |
88 |
93 |
89 def validate_content(self, value): |
94 def validate_content(self, value): |
90 try: |
95 try: |
91 json.loads(value) |
96 loaded_json = json.loads(value) |
92 except ValueError: |
97 except ValueError: |
93 raise serializers.ValidationError("Content format is not a JSON-serializable") |
98 raise serializers.ValidationError("Content format is not a JSON-serializable") |
94 loaded_json = json.loads(value) |
|
95 |
|
96 if (not "nodes" in loaded_json): |
99 if (not "nodes" in loaded_json): |
97 raise serializers.ValidationError("Content requires a 'nodes' entry") |
100 raise serializers.ValidationError("Content requires a 'nodes' entry") |
98 if (not "edges" in loaded_json): |
101 if (not "edges" in loaded_json): |
99 raise serializers.ValidationError("Content requires a 'edges' entry") |
102 raise serializers.ValidationError("Content requires a 'edges' entry") |
100 if (not "views" in loaded_json): |
103 if (not "views" in loaded_json): |
101 raise serializers.ValidationError("Content requires a 'views' entry") |
104 raise serializers.ValidationError("Content requires a 'views' entry") |
102 |
|
103 return value |
105 return value |
104 |
106 |
|
107 def validate_validation_timestamp(self, value): |
|
108 logger.debug("%r", value) |
|
109 if self.instance and dateparse.parse_datetime(value) < self.get_current_revision_modification_date(self.instance): |
|
110 raise serializers.ValidationError("Invalid timestamp was provided") |
|
111 return value |
105 |
112 |
106 class RevisionSerializer(serializers.Serializer): |
113 class RevisionSerializer(serializers.Serializer): |
107 id = serializers.ReadOnlyField(source="revision_guid") |
114 id = serializers.ReadOnlyField(source="revision_guid") |
108 parent_renkan_id = serializers.SlugRelatedField(source="parent_renkan", slug_field='renkan_guid', read_only=True) |
115 parent_renkan_id = serializers.SlugRelatedField(source="parent_renkan", slug_field='renkan_guid', read_only=True) |
109 workspace_id = serializers.SerializerMethodField("get_related_workspace_guid") |
116 workspace_id = serializers.SerializerMethodField("get_related_workspace_guid") |