2014-07-08 16:37:38 +00:00
|
|
|
from rest_framework import serializers
|
|
|
|
|
|
|
|
from orchestra.api import router
|
2014-07-09 16:17:43 +00:00
|
|
|
from orchestra.utils import running_syncdb
|
2014-07-08 16:37:38 +00:00
|
|
|
|
2014-07-09 16:17:43 +00:00
|
|
|
from .models import Resource, ResourceData
|
2014-07-08 16:37:38 +00:00
|
|
|
|
|
|
|
|
|
|
|
class ResourceSerializer(serializers.ModelSerializer):
|
|
|
|
name = serializers.SerializerMethodField('get_name')
|
|
|
|
|
|
|
|
class Meta:
|
2014-07-09 16:17:43 +00:00
|
|
|
model = ResourceData
|
|
|
|
fields = ('name', 'used', 'allocated')
|
|
|
|
read_only_fields = ('used',)
|
2014-07-08 16:37:38 +00:00
|
|
|
|
|
|
|
def get_name(self, instance):
|
|
|
|
return instance.resource.name
|
2014-07-10 17:34:23 +00:00
|
|
|
|
|
|
|
def get_identity(self, data):
|
|
|
|
return data.get('name')
|
|
|
|
|
2014-07-08 16:37:38 +00:00
|
|
|
|
2014-07-10 17:34:23 +00:00
|
|
|
# Monkey-patching section
|
2014-07-08 16:37:38 +00:00
|
|
|
|
2014-07-09 16:17:43 +00:00
|
|
|
if not running_syncdb():
|
2014-07-11 14:48:46 +00:00
|
|
|
# TODO why this is even loaded during syncdb?
|
2014-07-28 17:28:00 +00:00
|
|
|
# Create nested serializers on target models
|
2014-07-25 15:17:50 +00:00
|
|
|
for ct, resources in Resource.objects.group_by('content_type'):
|
|
|
|
model = ct.model_class()
|
2014-07-21 15:43:36 +00:00
|
|
|
try:
|
2014-07-28 17:28:00 +00:00
|
|
|
router.insert(model, 'resources', ResourceSerializer, required=False, many=True, source='resource_set')
|
2014-07-21 15:43:36 +00:00
|
|
|
except KeyError:
|
|
|
|
continue
|
2014-07-10 17:34:23 +00:00
|
|
|
|
|
|
|
def validate_resources(self, attrs, source, _resources=resources):
|
|
|
|
""" Creates missing resources """
|
|
|
|
posted = attrs.get(source, [])
|
|
|
|
result = []
|
|
|
|
resources = list(_resources)
|
|
|
|
for data in posted:
|
|
|
|
resource = data.resource
|
|
|
|
if resource not in resources:
|
|
|
|
msg = "Unknown or duplicated resource '%s'." % resource
|
|
|
|
raise serializers.ValidationError(msg)
|
|
|
|
resources.remove(resource)
|
|
|
|
if not resource.ondemand and not data.allocated:
|
|
|
|
data.allocated = resource.default_allocation
|
|
|
|
result.append(data)
|
|
|
|
for resource in resources:
|
|
|
|
data = ResourceData(resource=resource)
|
|
|
|
if not resource.ondemand:
|
|
|
|
data.allocated = resource.default_allocation
|
|
|
|
result.append(data)
|
|
|
|
attrs[source] = result
|
|
|
|
return attrs
|
|
|
|
viewset = router.get_viewset(model)
|
|
|
|
viewset.serializer_class.validate_resources = validate_resources
|
|
|
|
|
|
|
|
old_metadata = viewset.metadata
|
|
|
|
def metadata(self, request, resources=resources):
|
2014-07-11 14:48:46 +00:00
|
|
|
""" Provides available resources description """
|
2014-07-10 17:34:23 +00:00
|
|
|
ret = old_metadata(self, request)
|
2014-07-10 17:53:26 +00:00
|
|
|
ret['available_resources'] = [
|
2014-07-10 17:34:23 +00:00
|
|
|
{
|
|
|
|
'name': resource.name,
|
|
|
|
'ondemand': resource.ondemand,
|
|
|
|
'default_allocation': resource.default_allocation
|
|
|
|
} for resource in resources
|
|
|
|
]
|
|
|
|
return ret
|
|
|
|
viewset.metadata = metadata
|