'''
field serializing and deserializing metacategorization protocols
'''
import json
import logging
from rest_framework import serializers
from notes import constants, settings
from protocols.models import Protocol, ProtocolRevision
from protocols.serializers import ProtocolRevisionSerializer
logger = logging.getLogger(__name__)
class ProtocolField(serializers.Field):
default_error_messages = {
'incorrect_format_str': 'Incorrect format. Expected `'+constants.PROTOCOL_URN_PREFIX+'<ext_id>.<version>`.',
'protocol_unknown': 'Incorrect protocol, protocol {ext_id}, version {version} does not exists.',
'incorrect_format': 'Incorrect format. Expected `'+constants.PROTOCOL_URN_PREFIX+'<ext_id>.<version>` or dict.'
}
def __init__(self, *args, **kwargs):
logger.debug("ProtocolField.__init__ %r || %r", args, kwargs)
super().__init__(*args, **kwargs)
# def get_attribute(self, *args, **kwargs):
# logger.debug("ProtocolField.get_attribute %r || %r", args, kwargs)
# logger.debug("ProtocolField.get_attribute source %r", self.source)
# # We pass the object instance onto `to_representation`,
# # not just the field attribute.
# return kwargs.get('obj')
def to_representation(self, value):
if isinstance(value, str) and value.startswith(constants.PROTOCOL_URN_PREFIX) :
protocol_id, protocol_version = value[len(constants.PROTOCOL_URN_PREFIX):].split('.')
# TODO: treat error case, i.e. protocol is not found
protocol_revision = ProtocolRevision.objects.get(protocol__ext_id=protocol_id, version=protocol_version)
serializer = ProtocolRevisionSerializer(protocol_revision)
return serializer.data
elif isinstance(value, str):
logger.debug("ProtocolField.to_representation value %r" % value)
return json.loads(value)
else:
return value
def to_internal_value(self, data):
if isinstance(data, str) and data.startswith(constants.PROTOCOL_URN_PREFIX):
try:
ext_id, version = data[len(constants.PROTOCOL_URN_PREFIX):].split('.')
except ValueError:
self.fail('incorrect_format_str')
if not ProtocolRevision.objects.filter(protocol__ext_id=ext_id, version=version).exists():
self.fail('protocol_unknown', ext_id=ext_id, version=version)
else:
return data
elif isinstance(data, dict):
return data
else:
self.fail('incorrect_format')