from rest_framework.views import APIView from rest_framework.permissions import IsAdminUser from rest_framework.response import Response from rest_framework.serializers import Serializer from rest_framework.decorators import action from apps.am.models import Area from apps.am.tasks import cache_areas_info from apps.develop.serializers import AreaManSerializer, CleanDataSerializer, GenerateVoiceSerializer, SendSmsSerializer, SpeakerSerializer, \ TestTaskSerializer, TestAlgoSerializer from apps.develop.tasks import backup_database, backup_media, reload_web_git, reload_server_git, reload_server_only from rest_framework.exceptions import APIException from apps.ecm.service import check_not_in_place, create_remind, handle_xx_event, loc_change, notify_event, rail_in, snap_and_analyse from apps.ecm.tasks import opl_task, update_count_people from apps.hrm.models import Employee from apps.opm.models import Opl from apps.third.dahua import dhClient from apps.third.speaker import spClient from apps.third.models import TDevice from apps.utils.sms import send_sms from apps.utils.speech import generate_voice from apps.utils.tools import get_info_from_id from apps.utils.viewsets import CustomGenericViewSet from apps.utils.wx import wxClient from apps.wf.models import State, Transition, Workflow from django.db import transaction from apps.utils.snowflake import idWorker from django.core.cache import cache # Create your views here. class ReloadServerGit(APIView): authentication_classes = [] permission_classes = [] def post(self, request): """ 拉取后端代码并重启服务 拉取后端代码并重启服务 """ reload_server_git.delay() return Response() # if completed.returncode == 0: # return Response() # else: # from server.settings import myLogger # myLogger.error(completed) # raise ParseError(completed.stderr) class ReloadClientGit(APIView): authentication_classes = [] permission_classes = [] def post(self, request): """ 拉取前端代码并打包 拉取前端代码并打包 """ reload_web_git.delay() return Response() # completed = reload_web_git() # if completed.returncode == 0: # return Response() # else: # raise APIException(completed.stdout) class ReloadServerOnly(APIView): permission_classes = [IsAdminUser] def post(self, request): """ 仅重启服务 仅重启服务 """ completed = reload_server_only() if completed.returncode == 0: return Response() else: raise APIException(completed.stdout) class BackupDatabase(APIView): permission_classes = [IsAdminUser] def post(self, request): """ 备份数据库到指定位置 备份数据库到指定位置 """ err_str = backup_database() if err_str: raise APIException(err_str) return Response() class BackupMedia(APIView): permission_classes = [IsAdminUser] def post(self, request): """ 备份资源到指定位置 备份资源到指定位置 """ err_str = backup_media() if err_str: raise APIException(err_str) return Response() class TestViewSet(CustomGenericViewSet): authentication_classes = () permission_classes = () @action(methods=['post'], detail=False, serializer_class=SendSmsSerializer) def send_sms(self, request, pk=None): """发送短信测试 发送短信测试 """ serializer = SendSmsSerializer(data=request.data) serializer.is_valid(raise_exception=True) vdata = serializer.validated_data res = send_sms(**vdata) return Response(res) @action(methods=['post'], detail=False, serializer_class=GenerateVoiceSerializer) def generate_voice(self, request, pk=None): """文字转语音测试 文字转语音测试 """ serializer = GenerateVoiceSerializer(data=request.data) serializer.is_valid(raise_exception=True) vdata = serializer.validated_data res = generate_voice(**vdata) return Response(res) @action(methods=['post'], detail=False, serializer_class=TestTaskSerializer) def task(self, request, pk=None): """任务派发测试 任务派发测试 """ serializer = TestTaskSerializer(data=request.data) serializer.is_valid(raise_exception=True) vdata = serializer.validated_data ret = {} task = show.delay(*vdata.get('args', []), **vdata.get('kwargs', {})) ret['task_id'] = task.task_id # from celery.app.control import Control # from server.celery import app # celery_control = Control(app=app) # # 关闭作业监控任务 # res = celery_control.revoke(task.task_id, terminate=True) return Response(ret) @action(methods=['post'], detail=False, serializer_class=Serializer) def remind_event(self, request, pk=None): """测试事件推送 测试事件推送 """ from apps.ecm.models import Event event = Event.objects.get(id='1562718567894487040') create_remind(event, params={'area': '生产车间', 'employee': '访客石非凡', 'event': '未带安全帽'}) return Response() @action(methods=['post'], detail=False, serializer_class=Serializer) def test_snap_only(self, request, pk=None): """通道抓图 通道抓图 """ return Response(dhClient.snap(request.data['code'])) @action(methods=['post'], detail=False, serializer_class=TestAlgoSerializer) def test_algo(self, request, pk=None): """测试算法 测试算法 """ from apps.ai.main import ai_analyse_2 ret = ai_analyse_2(codes=request.data['codes'], face_img=request.data.get('face_img', None), global_img=request.data.get('global_img', None), is_dahua_pic=request.data.get('is_dahua_pic', True)) return Response(ret) @action(methods=['post'], detail=False, serializer_class=Serializer) def test_algo_full(self, request, pk=None): """测试算法2 测试算法2 """ mode = request.data.get('mode', 1) from apps.ecm.service import dispatch_dahua_event data = {'id': None, 'category': 'alarm', 'method': 'alarm.msg', 'info': {'orgName': '河北省', 'alarmPictureSize': '885977', 'nodeCode': '1002182$1$0$0', 'deviceCode': '1002182', 'alarmCode': '{B55A1489-0064-8D42-B6F4-EFF2DE1DA9B1}', 'alarmPicture': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220831/1/dsf_3c4ef3fe-290f-11ed-884a-e4246c7d1635_55425449_56311426.jpg', 'nodeType': 2, 'deviceName': '192.168.10.155', 'alarmDate': '1661942981', 'alarmGrade': 2, 'isSave': True, 'unitType': 1, 'unitSeq': 0, 'extend': {'params': {'ObjectType': 'Human', 'GroupId': 30.0, 'ObjectSubType': ''}, 'objectSubType': ''}, 'alarmType': 964, 'channelSeq': 0, 'orgCode': '001', 'channelName': '192.168.10.155_视频通道_1', 'alarmStat': 1, 'isEvent': True}, 'subsystem': 'admin', 'userIds': None, 'sid': None, 'domainId': None, 'infoArray': None, 'protocol': None} data = {'id': 1662026969203, 'category': 'alarm', 'method': 'alarm.msg', 'info': {'orgName': '曲阳县金隅水泥厂', 'nodeCode': '1000038$1$0$24', 'deviceCode': '1000038', 'alarmCode': '44df73ba-a423-4479-af70-1f930b00a7e0', 'alarmPicture': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220901/1/dsf_80fed821-29c9-11ed-884a-e4246c7d1635_27257520_27264993.jpg', 'nodeType': 2, 'alarmDate': '1662026965', 'alarmGrade': 2, 'isSave': True, 'extend': {'faceImageUrl': ['6ad010cf-ce45-11ec-9715-e4246c7d1635/20220901/1/dsf_80fed821-29c9-11ed-884a-e4246c7d1635_27257520_27264993.jpg'], 'glass': 0, 'beard': 0, 'candidateInfo': [{'birthday': '2022-8-24', 'faceImageUrl': [ '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220901/1/dsf_80fed821-29c9-11ed-884a-e4246c7d1635_27264993_27338395.jpg'], 'groupName': '全体人员', 'similarity': 97, 'sex': 1, 'cardType': 1, 'name': '曹前明', 'devPersonId': '48', 'id': '342422199004040175', 'type': 0}], 'sex': 0, 'occurrenceCount': 0, 'deviceCode': '1000038', 'globalScenePicUrl': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220901/1/dsf_80fed821-29c9-11ed-884a-e4246c7d1635_26915031_27257520.jpg', 'eye': 0, 'alarmType': 1001003, 'perFlag': -1, 'mouth': 0, 'feature': [], 'isHit': True, 'channelSeq': 24, 'szSerialUUID': '', 'channelName': '窑头平台值班室', 'beginTime': 1662026965, 'endTime': 1662026965, 'age': -1, 'mask': 0}, 'unitType': 1, 'alarmType': 1001003, 'channelSeq': 24, 'orgCode': '001001001', 'channelName': '窑头平台值班室', 'alarmStat': 1, 'isEvent': True}, 'subsystem': 'evo-face', 'userIds': None, 'sid': None, 'domainId': None, 'infoArray': None, 'protocol': None} # data = {'id': 1662032288888, 'category': 'alarm', 'method': 'alarm.msg', 'info': {'orgName': '曲阳县金隅水泥厂', 'nodeCode': '1000038$1$0$25', 'deviceCode': '1000038', 'alarmCode': 'c3df59cd-59d0-4f46-a32c-d2bf7778b37d', 'alarmPicture': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220901/1/dsf_80fed821-29c9-11ed-884a-e4246c7d1635_44280859_44288676.jpg', 'nodeType': 2, 'alarmDate': '1662032288', 'alarmGrade': 2, 'isSave': True, 'extend': {'faceImageUrl': ['6ad010cf-ce45-11ec-9715-e4246c7d1635/20220901/1/dsf_80fed821-29c9-11ed-884a-e4246c7d1635_44280859_44288676.jpg'], 'glass': 0, 'beard': 0, 'candidateInfo': [], 'sex': 0, 'occurrenceCount': 0, 'deviceCode': '1000038', 'globalScenePicUrl': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220901/1/dsf_80fed821-29c9-11ed-884a-e4246c7d1635_44127174_44280859.jpg', 'eye': 0, 'alarmType': 1001000, 'perFlag': -1, 'mouth': 0, 'feature': [], 'isHit': True, 'channelSeq': 25, 'szSerialUUID': '', 'channelName': '公司大门口', 'beginTime': 1662032284, 'endTime': 1662032284, 'age': -1, 'mask': 0}, 'unitType': 1, 'alarmType': 1001000, 'channelSeq': 25, 'orgCode': '001001001', 'channelName': '公司大门口', 'alarmStat': 1, 'isEvent': True}, 'subsystem': 'evo-face', 'userIds': None, 'sid': None, 'domainId': None, 'infoArray': None, 'protocol': None} data = {'id': 1662099853937, 'category': 'alarm', 'method': 'alarm.msg', 'info': {'orgName': '曲阳县金隅水泥厂', 'nodeCode': '1000038$1$0$24', 'deviceCode': '1000038', 'alarmCode': 'c520e09f-4b5d-4d04-be7b-005386a9b835', 'alarmPicture': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220902/1/dsf_a880f743-2a7e-11ed-884a-e4246c7d1635_57321861_57329128.jpg', 'nodeType': 2, 'alarmDate': '1662099849', 'alarmGrade': 2, 'isSave': True, 'extend': {'faceImageUrl': ['6ad010cf-ce45-11ec-9715-e4246c7d1635/20220902/1/dsf_a880f743-2a7e-11ed-884a-e4246c7d1635_57321861_57329128.jpg'], 'glass': 0, 'beard': 0, 'candidateInfo': [{'birthday': '2022-8-24', 'faceImageUrl': [ '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220902/1/dsf_a880f743-2a7e-11ed-884a-e4246c7d1635_57329128_57402530.jpg'], 'groupName': '全体人员', 'similarity': 99, 'sex': 1, 'cardType': 1, 'name': '曹前明', 'devPersonId': '48', 'id': '342422199004040175', 'type': 0}], 'sex': 0, 'occurrenceCount': 0, 'deviceCode': '1000038', 'globalScenePicUrl': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220902/1/dsf_a880f743-2a7e-11ed-884a-e4246c7d1635_56995669_57321861.jpg', 'eye': 0, 'alarmType': 1001003, 'perFlag': -1, 'mouth': 0, 'feature': [], 'isHit': True, 'channelSeq': 24, 'szSerialUUID': '', 'channelName': '窑头平台值班室', 'beginTime': 1662099849, 'endTime': 1662099849, 'age': -1, 'mask': 0}, 'unitType': 1, 'alarmType': 1001003, 'channelSeq': 24, 'orgCode': '001001001', 'channelName': '窑头平台值班室', 'alarmStat': 1, 'isEvent': True}, 'subsystem': 'evo-face', 'userIds': None, 'sid': None, 'domainId': None, 'infoArray': None, 'protocol': None} if mode == 1: data = {'id': 1662786479984, 'category': 'alarm', 'method': 'alarm.msg', 'info': {'orgName': '曲阳县金隅水泥厂', 'nodeCode': '1000038$1$0$24', 'deviceCode': '1000038', 'alarmCode': 'b672731c-4807-47e6-a468-c5f85a68e87d', 'alarmPicture': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220910/1/dsf_2c1150b4-309b-11ed-884a-e4246c7d1635_45588364_45596445.jpg', 'nodeType': 2, 'alarmDate': '1662786477', 'alarmGrade': 2, 'isSave': True, 'extend': {'faceImageUrl': ['6ad010cf-ce45-11ec-9715-e4246c7d1635/20220910/1/dsf_2c1150b4-309b-11ed-884a-e4246c7d1635_45588364_45596445.jpg'], 'glass': 0, 'beard': 0, 'candidateInfo': [{'birthday': '2022-8-24', 'faceImageUrl': [ '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220910/1/dsf_2c1150b4-309b-11ed-884a-e4246c7d1635_45596445_45673444.jpg'], 'groupName': '全体人员', 'similarity': 81, 'sex': 2, 'cardType': 1, 'name': '石静', 'devPersonId': '47', 'id': '371324199502156548', 'type': 0}], 'sex': 0, 'occurrenceCount': 0, 'deviceCode': '1000038', 'globalScenePicUrl': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220910/1/dsf_2c1150b4-309b-11ed-884a-e4246c7d1635_45288246_45588364.jpg', 'eye': 0, 'alarmType': 1001003, 'perFlag': -1, 'mouth': 0, 'feature': [], 'isHit': True, 'channelSeq': 24, 'szSerialUUID': '', 'channelName': '窑头平台值班室', 'beginTime': 1662786477, 'endTime': 1662786477, 'age': -1, 'mask': 0}, 'unitType': 1, 'alarmType': 1001003, 'channelSeq': 24, 'orgCode': '001001001', 'channelName': '窑头平台值班室', 'alarmStat': 1, 'isEvent': True}, 'subsystem': 'evo-face', 'userIds': None, 'sid': None, 'domainId': None, 'infoArray': None, 'protocol': None} elif mode == 2: data = {'id': None, 'category': 'alarm', 'method': 'alarm.msg', 'info': {'orgName': '曲阳县金隅水泥厂', 'alarmPictureSize': '592887', 'nodeCode': '1002191$1$0$0', 'deviceCode': '1002191', 'alarmCode': '{DBF64A47-DA5B-F147-B474-E74F54E4B6E9}', 'alarmPicture': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220923/1/dsf_b834ecae-3ad7-11ed-85c0-e4246c7d1635_43351055_43943942.jpg', 'nodeType': 2, 'deviceName': '192.168.10.177', 'alarmDate': '1663897556', 'alarmGrade': 2, 'isSave': True, 'unitType': 1, 'unitSeq': 0, 'extend': {'params': {'ObjectType': 'Unknown', 'nResetID': 0.0, 'HFOV': 0.0, 'stuPTZPosition': {'nPositionX': 0.0, 'nPositionY': 0.0, 'nZoom': 0.0}, 'Objects': [{'stuBoundingBox': {'nTop': 2616.0, 'nBottom': 3288.0, 'nLeft': 4352.0, 'nRight': 4768.0}}], 'nRuleID': 2.0, 'GroupId': 380.0, 'ObjectSubType': '', 'VFOV': 0.0}, 'objectSubType': ''}, 'alarmType': 303, 'channelSeq': 0, 'orgCode': '001001001', 'channelName': '二道门地中衡', 'alarmStat': 1, 'isEvent': True}, 'subsystem': 'admin', 'userIds': None, 'sid': None, 'domainId': None, 'infoArray': None, 'protocol': None} dispatch_dahua_event(data=data) return Response() @action(methods=['post'], detail=False, serializer_class=Serializer) def test_snap(self, request, pk=None): """测试抓图识别 测试抓图识别 """ code = request.data['code'] vc = TDevice.objects.get(code=code) snap_and_analyse(vc, ['fire1', 'helmet'], Opl.objects.get(id='1572195171456651264')) return Response() @action(methods=['post'], detail=False, serializer_class=Serializer) def test_snap_task(self, request, pk=None): """测试抓图识别任务 测试抓图识别任务 """ code = request.data['code'] task = opl_task.delay([code], '1568880208688320512') task_id = task.task_id test_snap_list = cache.get('test_snap_task', []) test_snap_list.append(task_id) cache.set('test_snap_task', test_snap_list) return Response({'test_snap_task': task_id}) @action(methods=['post'], detail=False, serializer_class=Serializer) def close_snap_task(self, request, pk=None): """关闭抓图识别任务 关闭抓图识别任务 """ test_snap_list = cache.get('test_snap_task', []) from celery.app.control import Control from server.celery import app celery_control = Control(app=app) # 关闭作业视频监控任务 for i in test_snap_list: celery_control.revoke(i, terminate=True) cache.set('test_snap_task', []) return Response() @action(methods=['post'], detail=False, serializer_class=Serializer) def test_loc_change(self, request, pk=None): """位置信息改变 位置信息改变 """ data = {'buildId': '204878', 'floorNo': 'Floor1', 'userId': '1918B2001A26', 'timestampMillisecond': 1663749630302, 'xMillimeter': 314364, 'yMillimeter': 362752, 'zMillimeter': 0, 'pointProperties': 0, 'locationType': 1, 'status': 0, 'src': 0, 'longitude': 114.63020038067505, 'latitude': 38.81357371331778} res = loc_change(data=data) return Response(res) @action(methods=['post'], detail=False, serializer_class=Serializer) def test_one_key_alarm(self, request, pk=None): """一键报警事件 一键报警事件 """ data = {'buildId': '204878', 'mac': '1918B20019F5', 'time': 1663067822887, 'event': 'alarm', 'alarmTypeName': '一键报警'} res = handle_xx_event(name='one_key_alarm', data=data) return Response(res) @action(methods=['post'], detail=False, serializer_class=Serializer) def test_rail_in(self, request, pk=None): """测试围栏进入 测试围栏进入 """ data = {'railId': '80fe94bff7b240aa893976965197487c', 'userId': '1918B20019F5', "railName": "二道门", 'time': 1663067822887, "type": 1, "buildId": "204878", "floorNo": "Floor1"} res = rail_in(data=data) return Response(res) @action(methods=['post'], detail=False, serializer_class=AreaManSerializer) def test_area_man(self, request, pk=None): """测试区域超员/缺员事件 测试区域超员/缺员事件 """ res = update_count_people(i=Area.objects.get(id=request.data['area'])) return Response(res) @action(methods=['post'], detail=False, serializer_class=Serializer) def correct_rail(self, request, pk=None): pass @action(methods=['post'], detail=False, serializer_class=SpeakerSerializer) def test_speaker(self, request, pk=None): spClient.speak(path='/media/2022/09/11/349b3451-50b9-4501-aded-c85a76967920.mp3', sns=request.data['sns'], v_num=2) return Response() @action(methods=['post'], detail=False, serializer_class=Serializer) def test_not_in_place(self, request, pk=None): opl = request.data.get('opl') check_not_in_place(opl=Opl.objects.get(id=opl)) return Response() @action(methods=['post'], detail=False, serializer_class=Serializer) def correct_gender(self, request, pk=None): objs = Employee.objects.get_queryset(all=True).all() for i in objs: if i.id_number: ret = get_info_from_id(i.id_number) i.gender = ret['gender'] i.save() return Response() @action(methods=['post'], detail=False, serializer_class=Serializer) def send_wx_msg(self, request, pk=None): """微信模板消息发送测试 微信模板消息发送测试 """ data = { "touser": "ocAnm5vab6QGOnf2dqpuUZGJ0xyw", "template_id": "wczl-hB_bs8CpxwO8_KZuogSTPFXqhBxf8C5HjKl2M4", "url": "http://weixin.qq.com/download", # "miniprogram":{ # "appid":"xiaochengxuappid12345", # "pagepath":"index?foo=bar" # }, "client_msg_id": "MSG_000001", "data": { "first": { "value": "恭喜你购买成功!", "color": "#173177" }, } } # url = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token'+wxClient.token # print(url) # rt = requests.post(url=url, json=data).text res = wxClient.send_tem_msg(data=data) return Response(res) @action(methods=['post'], detail=False, serializer_class=Serializer, permission_classes=[]) @transaction.atomic def correct_data(self, request, pk=None): """修正数据 修正数据 """ for i in Transition.objects.all(): if i.condition_expression: pass else: i.condition_expression = [] i.save() # wf = Workflow.objects.get(id='1544859644185415680') # objs = Workflow.objects.filter(key__istartswith='opl_').exclude(id='1544859644185415680') # for i in objs: # for s in State.objects.filter(workflow=wf): # sta = State() # sta.id = idWorker.get_id() # sta.workflow = i # for f in State._meta.fields: # if f.name not in ['workflow', 'create_time', 'update_time', 'id']: # setattr(sta, f.name, getattr(s, f.name)) # sta.save() # for t in Transition.objects.filter(workflow=wf): # tr = Transition() # tr.id = idWorker.get_id() # tr.workflow = i # for f in Transition._meta.fields: # if f.name not in ['workflow', 'create_time', 'update_time', 'id']: # setattr(tr, f.name, getattr(t, f.name)) # tr.save() return Response() @action(methods=['post'], detail=False, serializer_class=CleanDataSerializer, permission_classes=[]) def clean_data(self, request, pk=None): """清空数据 清空数据 """ datas = request.data['datas'] from apps.wf.models import Ticket from apps.hrm.models import Employee from apps.system.models import User, Dept if 'visit' in datas: # 访客 from apps.vm.models import Visit, Visitor Visit.objects.get_queryset(all=True).delete(soft=False) Visitor.objects.get_queryset(all=True).delete(soft=False) Ticket.objects.get_queryset(all=True).filter(workflow__key='visit').delete(soft=False) Employee.objects.get_queryset(all=True).filter(type='visitor').delete(soft=False) User.objects.get_queryset(all=True).filter(type='visitor').delete(soft=False) if 'rpm' in datas: from apps.rpm.models import Rparty Rparty.objects.get_queryset(all=True).delete(soft=False) Ticket.objects.get_queryset(all=True).filter(workflow__key='rpj').delete(soft=False) Employee.objects.get_queryset(all=True).filter(type='remployee').delete(soft=False) User.objects.get_queryset(all=True).filter(type='remployee').delete(soft=False) Dept.objects.get_queryset(all=True).filter(type='rparty').delete(soft=False) if 'event' in datas: from apps.ecm.models import Event Event.objects.all().delete() if 'opm' in datas: from apps.opm.models import Operation Operation.objects.all().delete() Ticket.objects.get_queryset(all=True).filter(workflow__key__contains='opl_').delete(soft=False) if 'ptask' in datas: from django_celery_results.models import TaskResult TaskResult.objects.filter(task_name__in=['apps.vm.tasks.close_visit_by_leave_time', 'apps.rpm.tasks.close_rpj_by_leave_time']).delete() return Response()