diff --git a/apps/playbook/app.json b/apps/playbook/app.json new file mode 100644 index 0000000000000000000000000000000000000000..65c60cfb7ff94b28233c46ae9725418a59d62bbb --- /dev/null +++ b/apps/playbook/app.json @@ -0,0 +1,43 @@ +{ + "identification": "w5soar", + "is_public": true, + "name": "调用剧本", + "version": "0.1", + "description": "调用剧本", + "type": "调用剧本", + "action": [ + { + "name": "执行剧本", + "func": "exec_play_book" + } + ], + "args": { + "exec_play_book": [ + { + "key": "uuid", + "type": "text", + "required": true + }, + { + "key": "app_uuids", + "type": "text", + "required": false + }, + { + "key": "func_num", + "type": "number", + "required": false + }, + { + "key": "datas", + "type": "text", + "required": false + }, + { + "key": "overtime", + "type": "text", + "required": false + } + ] + } +} \ No newline at end of file diff --git a/apps/playbook/icon.png b/apps/playbook/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..8540c7d56e6c5a8ef750ceb82a19a6a24cf7a429 Binary files /dev/null and b/apps/playbook/icon.png differ diff --git a/apps/playbook/linux/__init__.py b/apps/playbook/linux/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a505ad1b754e961e3f69750ada3bf95c32d050c6 --- /dev/null +++ b/apps/playbook/linux/__init__.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python +# _*_ coding: utf-8 _*_ +# @Time : 2021/6/3 11:58 +# @Author : asyu17 +# @File : __init__.py.py +# @Version : 1.0 \ No newline at end of file diff --git a/apps/playbook/linux/run.py b/apps/playbook/linux/run.py new file mode 100644 index 0000000000000000000000000000000000000000..839209dd1af69cd9fd44280b3ced5767af1c28ea --- /dev/null +++ b/apps/playbook/linux/run.py @@ -0,0 +1,144 @@ +#!/usr/bin/env python +# _*_ coding: utf-8 _*_ +# @Time : 2021/6/3 11:58 +# @Author : asyu17 +# @File : run.py +# @Version : 1.0 + + +import platform +import os +import sys +import json +import threading +import asyncio + +from loguru import logger + + +def my_auto_execute(uuid, Auto): + def thread_exec(): + async def run(): + await asyncio.gather(Auto.run(uuid=uuid)) + + try: + asyncio.run(run()) + except RuntimeError: + asyncio.gather(Auto.run(uuid=uuid)) + + t = threading.Thread(target=thread_exec) + t.setDaemon(True) + t.start() + + +async def exec_play_book(uuid, app_uuids='', func_num='', datas='', overtime='10'): + # app_uuids 格式:[app1,app2] + # func_num 是指目标函数为目标app的第几个函数,从0开始计算 + # datas 格式:[[data1]],[data2]] + # overtime 是设置目标剧本执行的超时时间 + + logger.info("[Exec-Play-Book] APP执行参数为: {uuid} ", uuid=uuid) + try: + app_uuids = app_uuids.strip(',[]').split(',') + func_num = func_num.strip(',[]').split(',') + datas = datas[1:-1].strip(',').split(',') + overtime = int(overtime) * 2 + for i in range(len(datas)): + datas[i] = datas[i].strip(',[]').split(',') + if app_uuids[0] == '': + app_uuids = [] + if func_num == '': + func_num = [0] * len(app_uuids) + for i in range(len(func_num)): + func_num[i] = int(func_num[i]) + if datas[0] == '': + datas = [[]] + if len(func_num) != len(app_uuids): + logger.error("[Exec-Play-Book] 函数序号无法与app_uuids匹配!") + return {"status": 1, "result": "函数序号无法与app_uuids匹配!"} + except Exception as e: + logger.error("[Exec-Play-Book] 传入参数格式有误:{e}", e=e) + return {"status": 2, "result": "传入参数格式有误!"} + current_path = sys.path[0] + path = current_path + for i in range(3): + path = os.path.dirname(path) + sys.path[0] = path + # —————————————————————— 导入依赖core模块 —————————————————————— + os.chdir(path) + try: + if platform.system() == 'Windows': + from core.auto.windows.core import Auto + elif platform.system() == 'Linux': + from core.auto.linux.core import Auto + elif platform.system() == "Darwin": + from core.auto.mac.core import Auto + from core.model import Workflow, Logs + from core.utils.times import Time + flow_data = Workflow.select( + 'flow_data', + ).where( + "uuid", uuid + ).first().flow_data + except Exception as e: + logger.error("[Exec-Play-Book] 导入依赖模块失败:{e}", e=e) + return {"status": 2, "result": "导入依赖模块失败!"} + + # —————————————————————— 修改目标剧本执行过程中的参数 —————————————————————— + flow_data = json.loads(flow_data) + for i in range(len(app_uuids)): + args = list(flow_data[app_uuids[i]]["args"].values())[func_num[i]] + for arg in args: + key = arg["key"] + if len(datas) == len(app_uuids): + for data in datas[i]: + flow_data[app_uuids[i]]["data"][key] = data + Workflow.where('uuid', uuid).update({ + 'flow_data': json.dumps(flow_data), + 'update_time': Time.get_date_time() + }) + try: + # —————————————————————— 调用目标剧本 —————————————————————— + auto = Auto() + my_auto_execute(uuid, auto) + except Exception as e: + logger.error("[Exec-Play-Book] 调用 {uuid} 剧本失败:{e}", uuid=uuid, e=e) + return {"status": 2, "result": "调用剧本失败!"} + + try: + # —————————————————————— 判断与解析剧本执行状况 —————————————————————— + only_id = auto.only_id + log = None + + for i in range(overtime): + await asyncio.sleep(0.5) # 要等待auto_execute用线程执行完 + log = Logs.select( + 'app_uuid', + 'app_name', + 'result' + + ).where( + "only_id", only_id + ).where('app_name', '结束').get().to_json()[1:-1] + log = json.loads(log) + + if None != log and '剧本执行结束' == log['result'] and '结束' == log['app_name']: + break + if None == log: + logger.error("[Exec-Play-Book] 调用 {uuid} 剧本超时!", uuid=uuid) + return {"status": 1, "result": "调用剧本超时!"} + dict_log = {} + for app_uuid in app_uuids: + log = Logs.select( + 'result' + ).where( + "only_id", only_id + ).where("app_uuid", app_uuid).get().to_json()[1:-1] + dict_log.update({app_uuid: json.loads(log)}) + result = dict_log + os.chdir(current_path) + logger.info("[Exec-Play-Book] {uuid} 剧本执行结果:{result}", uuid=uuid, result=result) + return {"status": 0, "result": result} + except Exception as e: + logger.error("[Exec-Play-Book] 解析 {uuid} 剧本结果失败:{e}", uuid=uuid, e=e) + return {"status": 2, "result": "解析剧本结果失败!"} diff --git a/apps/playbook/mac/__init__.py b/apps/playbook/mac/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a505ad1b754e961e3f69750ada3bf95c32d050c6 --- /dev/null +++ b/apps/playbook/mac/__init__.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python +# _*_ coding: utf-8 _*_ +# @Time : 2021/6/3 11:58 +# @Author : asyu17 +# @File : __init__.py.py +# @Version : 1.0 \ No newline at end of file diff --git a/apps/playbook/mac/run.py b/apps/playbook/mac/run.py new file mode 100644 index 0000000000000000000000000000000000000000..839209dd1af69cd9fd44280b3ced5767af1c28ea --- /dev/null +++ b/apps/playbook/mac/run.py @@ -0,0 +1,144 @@ +#!/usr/bin/env python +# _*_ coding: utf-8 _*_ +# @Time : 2021/6/3 11:58 +# @Author : asyu17 +# @File : run.py +# @Version : 1.0 + + +import platform +import os +import sys +import json +import threading +import asyncio + +from loguru import logger + + +def my_auto_execute(uuid, Auto): + def thread_exec(): + async def run(): + await asyncio.gather(Auto.run(uuid=uuid)) + + try: + asyncio.run(run()) + except RuntimeError: + asyncio.gather(Auto.run(uuid=uuid)) + + t = threading.Thread(target=thread_exec) + t.setDaemon(True) + t.start() + + +async def exec_play_book(uuid, app_uuids='', func_num='', datas='', overtime='10'): + # app_uuids 格式:[app1,app2] + # func_num 是指目标函数为目标app的第几个函数,从0开始计算 + # datas 格式:[[data1]],[data2]] + # overtime 是设置目标剧本执行的超时时间 + + logger.info("[Exec-Play-Book] APP执行参数为: {uuid} ", uuid=uuid) + try: + app_uuids = app_uuids.strip(',[]').split(',') + func_num = func_num.strip(',[]').split(',') + datas = datas[1:-1].strip(',').split(',') + overtime = int(overtime) * 2 + for i in range(len(datas)): + datas[i] = datas[i].strip(',[]').split(',') + if app_uuids[0] == '': + app_uuids = [] + if func_num == '': + func_num = [0] * len(app_uuids) + for i in range(len(func_num)): + func_num[i] = int(func_num[i]) + if datas[0] == '': + datas = [[]] + if len(func_num) != len(app_uuids): + logger.error("[Exec-Play-Book] 函数序号无法与app_uuids匹配!") + return {"status": 1, "result": "函数序号无法与app_uuids匹配!"} + except Exception as e: + logger.error("[Exec-Play-Book] 传入参数格式有误:{e}", e=e) + return {"status": 2, "result": "传入参数格式有误!"} + current_path = sys.path[0] + path = current_path + for i in range(3): + path = os.path.dirname(path) + sys.path[0] = path + # —————————————————————— 导入依赖core模块 —————————————————————— + os.chdir(path) + try: + if platform.system() == 'Windows': + from core.auto.windows.core import Auto + elif platform.system() == 'Linux': + from core.auto.linux.core import Auto + elif platform.system() == "Darwin": + from core.auto.mac.core import Auto + from core.model import Workflow, Logs + from core.utils.times import Time + flow_data = Workflow.select( + 'flow_data', + ).where( + "uuid", uuid + ).first().flow_data + except Exception as e: + logger.error("[Exec-Play-Book] 导入依赖模块失败:{e}", e=e) + return {"status": 2, "result": "导入依赖模块失败!"} + + # —————————————————————— 修改目标剧本执行过程中的参数 —————————————————————— + flow_data = json.loads(flow_data) + for i in range(len(app_uuids)): + args = list(flow_data[app_uuids[i]]["args"].values())[func_num[i]] + for arg in args: + key = arg["key"] + if len(datas) == len(app_uuids): + for data in datas[i]: + flow_data[app_uuids[i]]["data"][key] = data + Workflow.where('uuid', uuid).update({ + 'flow_data': json.dumps(flow_data), + 'update_time': Time.get_date_time() + }) + try: + # —————————————————————— 调用目标剧本 —————————————————————— + auto = Auto() + my_auto_execute(uuid, auto) + except Exception as e: + logger.error("[Exec-Play-Book] 调用 {uuid} 剧本失败:{e}", uuid=uuid, e=e) + return {"status": 2, "result": "调用剧本失败!"} + + try: + # —————————————————————— 判断与解析剧本执行状况 —————————————————————— + only_id = auto.only_id + log = None + + for i in range(overtime): + await asyncio.sleep(0.5) # 要等待auto_execute用线程执行完 + log = Logs.select( + 'app_uuid', + 'app_name', + 'result' + + ).where( + "only_id", only_id + ).where('app_name', '结束').get().to_json()[1:-1] + log = json.loads(log) + + if None != log and '剧本执行结束' == log['result'] and '结束' == log['app_name']: + break + if None == log: + logger.error("[Exec-Play-Book] 调用 {uuid} 剧本超时!", uuid=uuid) + return {"status": 1, "result": "调用剧本超时!"} + dict_log = {} + for app_uuid in app_uuids: + log = Logs.select( + 'result' + ).where( + "only_id", only_id + ).where("app_uuid", app_uuid).get().to_json()[1:-1] + dict_log.update({app_uuid: json.loads(log)}) + result = dict_log + os.chdir(current_path) + logger.info("[Exec-Play-Book] {uuid} 剧本执行结果:{result}", uuid=uuid, result=result) + return {"status": 0, "result": result} + except Exception as e: + logger.error("[Exec-Play-Book] 解析 {uuid} 剧本结果失败:{e}", uuid=uuid, e=e) + return {"status": 2, "result": "解析剧本结果失败!"} diff --git a/apps/playbook/readme.md b/apps/playbook/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..6638d628d94766ecf2f6497856c6abd1e8507914 --- /dev/null +++ b/apps/playbook/readme.md @@ -0,0 +1,25 @@ +## APP 说明 + +> 剧本调用 + +## 动作列表 + +### 查询信息 + +**参数:** + +| 参数 | 类型 | 必填 | 备注 | +| ---- | ---- | ---- | ---- | +| **uuid** | text | `是` | 要操作的剧本,示例:59c88704-c694-11eb-8ebe-0242ac110003 | +| **app_uuids** | text | `否` | 要操作的应用,示例:[61eaa840-c694-11eb-b241-23cb919a2e29,eff61240-c695-11eb-b241-23cb919a2e29] | +| **func_num** | text | `否` | 要操作的函数序号,示例:[0,0] | +| **datas** | text | `否` | 要操作应用的参数,示例:[[12312345],[123123]] | +| **overtime** | text | `否` | 要操作应用的参数,示例:20 | + +**返回值:** + +``` +{'status': 0, 'result': {'61eaa840-c694-11eb-b241-23cb919a2e29': {'result': '{}'}, 'eff6 +1240-c695-11eb-b241-23cb919a2e29': {'result': ''}}} +``` + diff --git a/apps/playbook/windows/__init__.py b/apps/playbook/windows/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a505ad1b754e961e3f69750ada3bf95c32d050c6 --- /dev/null +++ b/apps/playbook/windows/__init__.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python +# _*_ coding: utf-8 _*_ +# @Time : 2021/6/3 11:58 +# @Author : asyu17 +# @File : __init__.py.py +# @Version : 1.0 \ No newline at end of file diff --git a/apps/playbook/windows/run.py b/apps/playbook/windows/run.py new file mode 100644 index 0000000000000000000000000000000000000000..839209dd1af69cd9fd44280b3ced5767af1c28ea --- /dev/null +++ b/apps/playbook/windows/run.py @@ -0,0 +1,144 @@ +#!/usr/bin/env python +# _*_ coding: utf-8 _*_ +# @Time : 2021/6/3 11:58 +# @Author : asyu17 +# @File : run.py +# @Version : 1.0 + + +import platform +import os +import sys +import json +import threading +import asyncio + +from loguru import logger + + +def my_auto_execute(uuid, Auto): + def thread_exec(): + async def run(): + await asyncio.gather(Auto.run(uuid=uuid)) + + try: + asyncio.run(run()) + except RuntimeError: + asyncio.gather(Auto.run(uuid=uuid)) + + t = threading.Thread(target=thread_exec) + t.setDaemon(True) + t.start() + + +async def exec_play_book(uuid, app_uuids='', func_num='', datas='', overtime='10'): + # app_uuids 格式:[app1,app2] + # func_num 是指目标函数为目标app的第几个函数,从0开始计算 + # datas 格式:[[data1]],[data2]] + # overtime 是设置目标剧本执行的超时时间 + + logger.info("[Exec-Play-Book] APP执行参数为: {uuid} ", uuid=uuid) + try: + app_uuids = app_uuids.strip(',[]').split(',') + func_num = func_num.strip(',[]').split(',') + datas = datas[1:-1].strip(',').split(',') + overtime = int(overtime) * 2 + for i in range(len(datas)): + datas[i] = datas[i].strip(',[]').split(',') + if app_uuids[0] == '': + app_uuids = [] + if func_num == '': + func_num = [0] * len(app_uuids) + for i in range(len(func_num)): + func_num[i] = int(func_num[i]) + if datas[0] == '': + datas = [[]] + if len(func_num) != len(app_uuids): + logger.error("[Exec-Play-Book] 函数序号无法与app_uuids匹配!") + return {"status": 1, "result": "函数序号无法与app_uuids匹配!"} + except Exception as e: + logger.error("[Exec-Play-Book] 传入参数格式有误:{e}", e=e) + return {"status": 2, "result": "传入参数格式有误!"} + current_path = sys.path[0] + path = current_path + for i in range(3): + path = os.path.dirname(path) + sys.path[0] = path + # —————————————————————— 导入依赖core模块 —————————————————————— + os.chdir(path) + try: + if platform.system() == 'Windows': + from core.auto.windows.core import Auto + elif platform.system() == 'Linux': + from core.auto.linux.core import Auto + elif platform.system() == "Darwin": + from core.auto.mac.core import Auto + from core.model import Workflow, Logs + from core.utils.times import Time + flow_data = Workflow.select( + 'flow_data', + ).where( + "uuid", uuid + ).first().flow_data + except Exception as e: + logger.error("[Exec-Play-Book] 导入依赖模块失败:{e}", e=e) + return {"status": 2, "result": "导入依赖模块失败!"} + + # —————————————————————— 修改目标剧本执行过程中的参数 —————————————————————— + flow_data = json.loads(flow_data) + for i in range(len(app_uuids)): + args = list(flow_data[app_uuids[i]]["args"].values())[func_num[i]] + for arg in args: + key = arg["key"] + if len(datas) == len(app_uuids): + for data in datas[i]: + flow_data[app_uuids[i]]["data"][key] = data + Workflow.where('uuid', uuid).update({ + 'flow_data': json.dumps(flow_data), + 'update_time': Time.get_date_time() + }) + try: + # —————————————————————— 调用目标剧本 —————————————————————— + auto = Auto() + my_auto_execute(uuid, auto) + except Exception as e: + logger.error("[Exec-Play-Book] 调用 {uuid} 剧本失败:{e}", uuid=uuid, e=e) + return {"status": 2, "result": "调用剧本失败!"} + + try: + # —————————————————————— 判断与解析剧本执行状况 —————————————————————— + only_id = auto.only_id + log = None + + for i in range(overtime): + await asyncio.sleep(0.5) # 要等待auto_execute用线程执行完 + log = Logs.select( + 'app_uuid', + 'app_name', + 'result' + + ).where( + "only_id", only_id + ).where('app_name', '结束').get().to_json()[1:-1] + log = json.loads(log) + + if None != log and '剧本执行结束' == log['result'] and '结束' == log['app_name']: + break + if None == log: + logger.error("[Exec-Play-Book] 调用 {uuid} 剧本超时!", uuid=uuid) + return {"status": 1, "result": "调用剧本超时!"} + dict_log = {} + for app_uuid in app_uuids: + log = Logs.select( + 'result' + ).where( + "only_id", only_id + ).where("app_uuid", app_uuid).get().to_json()[1:-1] + dict_log.update({app_uuid: json.loads(log)}) + result = dict_log + os.chdir(current_path) + logger.info("[Exec-Play-Book] {uuid} 剧本执行结果:{result}", uuid=uuid, result=result) + return {"status": 0, "result": result} + except Exception as e: + logger.error("[Exec-Play-Book] 解析 {uuid} 剧本结果失败:{e}", uuid=uuid, e=e) + return {"status": 2, "result": "解析剧本结果失败!"}