import re from elasticsearch.exceptions import RequestError, NotFoundError from rest_framework import viewsets, mixins from rest_framework.response import Response from rest_framework import filters from rest_framework import exceptions from . import app_serializers from mgmt import models as mgmt_models from utils.es import es class DataLuceneViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet): _doc_type = "data" serializer_class = app_serializers.DataLuceneSerializer def get_indices(self, input_indices): tables = mgmt_models.Table.objects.all() all_indices = [table.name for table in tables] not_exit_indices = list(set(input_indices) - set(all_indices)) if not_exit_indices: raise exceptions.ParseError(f"{not_exit_indices}不存在") all_perm_name = self.request.user.get_all_permission_names() if "read_all" in all_perm_name or self.request.user.is_staff: if not input_indices: return all_indices return input_indices has_perm_indices = [perm_name.split(".read")[0] for perm_name in all_perm_name if re.match( "^[a-z][a-z-0-9]*\.read", perm_name)] if not input_indices: if not has_perm_indices: raise exceptions.ParseError("您没有任何表读取权限 请联系管理员分配权限") return has_perm_indices no_perm_index = list(set(input_indices) - set(has_perm_indices)) if no_perm_index: raise exceptions.PermissionDenied(f"你没有{no_perm_index}表权限") return input_indices def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) data = serializer.validated_data # indices = data["indices"] if data["indices"] else "_all" indices = self.get_indices(data["indices"]) sort = ",".join(reversed(list(map(lambda i: ":".join(i), data["sort"].items())))) try: res = es.search(index=indices, doc_type=self._doc_type, from_=data["page_size"] * (data["page"]-1), size=data["page_size"], sort=sort, q=data["query"], analyze_wildcard=True) except NotFoundError as exc: return Response({ "hits": [], "max_score": None, "total": 0 }) except RequestError as exc: raise exceptions.ParseError("Search statement error: "+str(exc)) return Response(res["hits"]) class DeletedDataLuceneViewset(DataLuceneViewSet): _doc_type = "deleted-data" serializer_class = app_serializers.DataLuceneSerializer def get_indices(self, input_indices): return [index + ".." for index in super().get_indices(input_indices)] class DataDSLViewSet(DataLuceneViewSet): def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) data = serializer.validated_data # indices = data["indices"] if data["indices"] else "_all" indices = self.get_indices(data["indices"]) sort = ",".join(reversed(list(map(lambda i: ":".join(i), data["sort"].items())))) try: res = es.search(index=indices, doc_type=self._doc_type, from_=data["page_size"] * (data["page"]-1), size=data["page_size"], sort=sort, body=data["body"], analyze_wildcard=True) except NotFoundError as exc: return Response({ "hits": [], "max_score": None, "total": 0 }) except RequestError as exc: raise exceptions.ParseError("Search statement error: "+str(exc)) return Response(res["hits"]) class DeleteDataDSLViewSet(DataDSLViewSet): def get_indices(self, input_indices): return [index + ".." for index in super().get_indices(input_indices)]