mirror of
https://github.com/jumpserver/jumpserver.git
synced 2026-02-21 14:32:45 +00:00
* [Update] 封装JMSCSVRender和JMSCSVParser * [Update] 更改JMSCSVRender,根据请求参数控制导出csv的字段和下载csv模板的字段 * [Update] 导入空数据,提示错误消息 * [Update] 修改用户导入和导出功能代码 * [Update] 修改导入路由为动态反向解析 * [Update] 修改JMSCSVRender和JMSCSVParser以及用户导入导出代码 * [Update] 优化parsers逻辑 * [Update] 优化parsers csv代码结构 * [Update] 优化renders csv代码逻辑 * [Update] 删除parsers csv多余代码 * [Update] 删除parsers csv多余变量 * [Update] 优化renders csv代码结构 * [Update] 优化renders csv代码结构2 * [Update] 优化renders csv获取header逻辑 * [Update] 优化Cache Resources ID View逻辑 * [Update] 优化ViewSet IDCacheFilterMixin逻辑 * [Update] csv: parser render 添加异常捕获逻辑 * [Update] 删除多余代码 * [Update] 优化前端代码 * [Update] 修改小问题 * [Update] 修改前端导出用户的问题 * [Update] 前端 - 优化数据导出逻辑 APIExportData * [Update] 修复批量创建用户时发送created信号的bug * [Update] 优化导入时错误信息展示 * [Update] 优化parser、render时,对于多对多字段的处理 * [Update] 修改前端上传空文件问题 * [Update] 添加IDExportFilter,控制下载模版时的queryset * [Update] 修改判断导出模版时参数变量名 action => template * [Update] 修复导入用户数据时,用户组不生效的bug * [Update] 修改前端导入信息展示 * [Update] 抽象资源导入模版 * [Update] 优化资源导入模版 * [Update] 修改js设置url的params逻辑 * [Update] 修改users序列类控制read_only字段方式 * [Update] 资产列表采用新的导入/导出csv文件逻辑 * [Update] 修改导入资产时设置资产所在节点逻辑 * [Update] 添加用户组导入/导出功能 * [Update] 修改前端变量名 * [Update] 修改下载导入模版,不包含org字段 * [Update] 增加管理用户导入/导出功能 * [Update] 导入模版提供id字段(为了资源备份后导入直接使用); 修复资源导入时联合唯一字段不校验导致创建时报错的bug * [Update] 增加系统用户导入/导出功能 * [Update] 排序资源导入/导出字段 * [Update] 翻译导入/导出的字段和模版 * [Update] 更改csv导出和导出模版数据的控制在render实现 * [Update] 资产添加 更新导入 功能 * [Update] 用户/用户组/管理用户/系统用户/ 添加导入更新 * [Update] 翻译 * [Update] 优化资源序列化中的label * [Update] 去掉资源IDInFilterMixin过滤 * [Update] 翻译
90 lines
2.4 KiB
Python
90 lines
2.4 KiB
Python
# -*- coding: utf-8 -*-
|
|
#
|
|
import os
|
|
import uuid
|
|
|
|
from django.core.cache import cache
|
|
|
|
from rest_framework.views import APIView
|
|
from rest_framework.response import Response
|
|
from rest_framework import generics, serializers
|
|
|
|
from .const import KEY_CACHE_RESOURCES_ID
|
|
|
|
__all__ = [
|
|
'LogTailApi', 'ResourcesIDCacheApi',
|
|
]
|
|
|
|
|
|
class OutputSerializer(serializers.Serializer):
|
|
output = serializers.CharField()
|
|
is_end = serializers.BooleanField()
|
|
mark = serializers.CharField()
|
|
|
|
|
|
class LogTailApi(generics.RetrieveAPIView):
|
|
permission_classes = ()
|
|
buff_size = 1024 * 10
|
|
serializer_class = OutputSerializer
|
|
end = False
|
|
mark = ''
|
|
log_path = ''
|
|
|
|
def is_file_finish_write(self):
|
|
return True
|
|
|
|
def get_log_path(self):
|
|
raise NotImplementedError()
|
|
|
|
def get_no_file_message(self, request):
|
|
return 'Not found the log'
|
|
|
|
def filter_line(self, line):
|
|
"""
|
|
过滤行,可能替换一些信息
|
|
:param line:
|
|
:return:
|
|
"""
|
|
return line
|
|
|
|
def read_from_file(self):
|
|
with open(self.log_path, 'r') as f:
|
|
offset = cache.get(self.mark, 0)
|
|
f.seek(offset)
|
|
data = f.read(self.buff_size).replace('\n', '\r\n')
|
|
|
|
new_mark = str(uuid.uuid4())
|
|
cache.set(new_mark, f.tell(), 5)
|
|
|
|
if data == '' and self.is_file_finish_write():
|
|
self.end = True
|
|
_data = ''
|
|
for line in data.split('\r\n'):
|
|
new_line = self.filter_line(line)
|
|
if line == '':
|
|
continue
|
|
_data += new_line + '\r\n'
|
|
return _data, self.end, new_mark
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
self.mark = request.query_params.get("mark") or str(uuid.uuid4())
|
|
self.log_path = self.get_log_path()
|
|
|
|
if not self.log_path or not os.path.isfile(self.log_path):
|
|
msg = self.get_no_file_message(self.request)
|
|
return Response({"data": msg}, status=200)
|
|
|
|
data, end, new_mark = self.read_from_file()
|
|
return Response({"data": data, 'end': end, 'mark': new_mark})
|
|
|
|
|
|
class ResourcesIDCacheApi(APIView):
|
|
|
|
def post(self, request, *args, **kwargs):
|
|
spm = str(uuid.uuid4())
|
|
resources_id = request.data.get('resources')
|
|
if resources_id:
|
|
cache_key = KEY_CACHE_RESOURCES_ID.format(spm)
|
|
cache.set(cache_key, resources_id, 300)
|
|
return Response({'spm': spm})
|