import django_filters from django_filters.rest_framework import FilterSet from guardian.shortcuts import get_objects_for_user from rest_framework import serializers, viewsets from rest_framework.response import Response from rest_framework.views import APIView from nodeodm.models import ProcessingNode class ProcessingNodeSerializer(serializers.ModelSerializer): online = serializers.SerializerMethodField() label = serializers.SerializerMethodField() def get_online(self, obj): return obj.is_online() def get_label(self, obj): return str(obj) class Meta: model = ProcessingNode fields = '__all__' class ProcessingNodeFilter(FilterSet): has_available_options = django_filters.CharFilter(method='filter_has_available_options') # noinspection PyMethodMayBeStatic def filter_has_available_options(self, queryset, name, value): if value.lower() in ['true', '1']: return queryset.exclude(available_options=dict()) else: return queryset.filter(available_options=dict()) class Meta: model = ProcessingNode fields = ['has_available_options', 'id', 'hostname', 'port', 'api_version', 'queue_count', 'max_images', 'label', ] class ProcessingNodeViewSet(viewsets.ModelViewSet): """ Processing node get/add/delete/update Processing nodes are associated with zero or more tasks and take care of processing input images. """ filter_class = ProcessingNodeFilter pagination_class = None serializer_class = ProcessingNodeSerializer queryset = ProcessingNode.objects.all() class ProcessingNodeOptionsView(APIView): """ Display the common options available among all online processing nodes. This is calculated by intersecting the available_options field of all online processing nodes visible to the current user. """ queryset = ProcessingNode.objects.all() def get(self, request): nodes = get_objects_for_user(request.user, 'view_processingnode', ProcessingNode, accept_global_perms=False) common_options = [] for node in nodes: # Skip offline nodes if not node.is_online(): continue # First? Just populate if len(common_options) == 0 and len(node.available_options) > 0: common_options = node.available_options else: # Remove all options that are in common_options, # but that are not in node.available_options for common_option in common_options: found = False for option in node.available_options: if common_option['name'] == option['name']: found = True break # Mark for deletion if not found: common_option['_delete'] = True common_options = [co for co in common_options if not '_delete' in co] return Response(common_options)