first commit

This commit is contained in:
jc
2025-09-22 21:07:30 +08:00
commit d409882c64
114 changed files with 47381 additions and 0 deletions

30
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,30 @@
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "cmake",
"request": "launch",
"name": "CMake: 配置项目",
"cmakeDebugType": "configure",
"clean": false,
"configureAll": false
},
{
"name": "Python 调试程序: 当前文件",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/src/main.py",
"console": "integratedTerminal"
},
{
"name": "test_main_create_block",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/src/main_test.py",
"console": "integratedTerminal"
}
]
}

88
data/dialog_result.json Normal file
View File

@@ -0,0 +1,88 @@
{
"dependency": [
],
"flow": [
{
"name": "0_基本配置",
"memo": null,
"kind": "visual",
"blocks": [
{
"id": "b60be60e-d970-4e4f-9564-6a66b138d08a",
"name": "dialog.show_custom_dialog",
"isEnabled": true,
"inputs": {
"settings": {
"value": "10:{\"dialogTitle\":null,\"height\":0,\"width\":0,\"timeout\":0,\"autoCloseButton\":null,\"use_wait_timeout\":false,\"canRememberContent\":false,\"settings\":{\"editors\":[],\"buttons\":[{\"type\":\"Button\",\"label\":\"确定\",\"theme\":\"white\",\"hotKey\":\"Return\",\"uuid\":\"e49138d8-6857-4ef3-9550-4d098e95e7ce\"},{\"type\":\"Button\",\"label\":\"取消\",\"theme\":\"white\",\"hotKey\":\"Escape\",\"uuid\":\"5b7bd90e-50c1-4583-9e8a-d59ea1c1efc9\"}]}}"
},
"dialog_title": {
"value": "10:"
},
"default_btn": {
"value": "10:确定",
"display": "确定"
},
"is_auto_click": {
"value": "13:False"
},
"timeout": {
"value": null
},
"globals": {
"value": "13:globals()"
},
"locals": {
"value": "13:locals()"
},
"storage_key": {
"value": "13:`block_id`"
}
},
"outputs": {
"dialog_result": {
"name": "dialog_result",
"isEnable": true
}
}
},
{
"id": "6e80cd80-7109-427c-87e8-22ffd91ef176",
"name": "workflow.if",
"isEnabled": true,
"foldState": "UnFold",
"inputs": {
"operand1": {
"value": "11:dialog_result.pressed_button"
},
"operator": {
"value": "10:!=",
"display": "不等于"
},
"operand2": {
"value": "10:确定"
},
"operator_options": {
"value": "10:{}"
}
},
"outputs": {}
},
{
"id": "2a389cae-75f6-43f1-a365-b2e47c1d4e18",
"name": "process.exit",
"isEnabled": true,
"inputs": {},
"outputs": {}
},
{
"id": "2091634e-7ee7-4c1f-b3a8-cb3f00dc4770",
"name": "workflow.endif",
"isEnabled": true,
"inputs": {},
"outputs": {}
}
],
"parameters": []
}
]
}

292
data/superbrowser.json Normal file
View File

@@ -0,0 +1,292 @@
{
"dependency": [
"super_browser==25.9.3",
"activity_f4d5de04==23.11.1"
],
"flow": [
{
"name": "main",
"memo": "我的自动化应用",
"kind": "visual",
"blocks": [
{
"id": "48a2e4c6-3b44-4e55-a581-0ed0d56323cc",
"name": "process.run",
"isEnabled": true,
"comment": "执行流程%process%,无返回结果",
"inputs": {
"process": {
"value": "10:setting_process",
"display": "0_基本配置"
},
"package": {
"value": "11:__name__"
},
"inputs": {
"value": "16:[]"
},
"outputs": {
"value": "10:[]"
}
},
"outputs": {
"process_result": {
"name": "process_result",
"isEnable": false
}
}
},
{
"id": "ed930e1f-722d-43b9-9b84-0a0a175944ce",
"name": "process.run",
"isEnabled": true,
"comment": "执行流程%process%并传入参数%inputs:WyLotKblj7flgLzkuLol6LSm5Y+3Je+8jCIsIuWvhueggeWAvOS4uiXlr4bnoIEl77yMIiwi5LyB5Lia5ZCN56ew5YC85Li6JeS8geS4muWQjeensCXvvIwiXQ==%无返回结果",
"inputs": {
"process": {
"value": "10:login_process",
"display": "1_登录"
},
"package": {
"value": "11:__name__"
},
"inputs": {
"value": "16:[{\"账号\":\"10:\"},{\"密码\":\"10:\"},{\"企业名称\":\"10:\"}]"
},
"outputs": {
"value": "10:[]"
}
},
"outputs": {
"process_result": {
"name": "process_result2",
"isEnable": false
}
}
},
{
"id": "80850dab-a050-435e-b6b4-09f2aa2455f8",
"name": "process.run",
"isEnabled": true,
"comment": "执行流程%process%并传入参数%inputs:WyLlupfpk7rlkI3np7DlgLzkuLol5bqX6ZO65ZCN56ewJe+8jCJd%无返回结果",
"inputs": {
"process": {
"value": "10:func_process",
"display": "2_功能模块"
},
"package": {
"value": "11:__name__"
},
"inputs": {
"value": "16:[{\"店铺名称\":\"10:\"}]"
},
"outputs": {
"value": "10:[]"
}
},
"outputs": {
"process_result": {
"name": "process_result3",
"isEnable": false
}
}
}
],
"parameters": []
},
{
"name": "0_基本配置",
"memo": "setting_process",
"kind": "visual",
"blocks": [
{
"id": "b60be60e-d970-4e4f-9564-6a66b138d08a",
"name": "dialog.show_custom_dialog",
"isEnabled": true,
"inputs": {
"settings": {
"value": "10:{\"dialogTitle\":null,\"height\":0,\"width\":0,\"timeout\":0,\"autoCloseButton\":null,\"use_wait_timeout\":false,\"canRememberContent\":false,\"settings\":{\"editors\":[],\"buttons\":[{\"type\":\"Button\",\"label\":\"确定\",\"theme\":\"white\",\"hotKey\":\"Return\",\"uuid\":\"e49138d8-6857-4ef3-9550-4d098e95e7ce\"},{\"type\":\"Button\",\"label\":\"取消\",\"theme\":\"white\",\"hotKey\":\"Escape\",\"uuid\":\"5b7bd90e-50c1-4583-9e8a-d59ea1c1efc9\"}]}}"
},
"dialog_title": {
"value": "10:"
},
"default_btn": {
"value": "10:确定",
"display": "确定"
},
"is_auto_click": {
"value": "13:False"
},
"timeout": {
"value": null
},
"globals": {
"value": "13:globals()"
},
"locals": {
"value": "13:locals()"
},
"storage_key": {
"value": "13:`block_id`"
}
},
"outputs": {
"dialog_result": {
"name": "dialog_result",
"isEnable": true
}
}
},
{
"id": "6e80cd80-7109-427c-87e8-22ffd91ef176",
"name": "workflow.if",
"isEnabled": true,
"foldState": "UnFold",
"inputs": {
"operand1": {
"value": "11:dialog_result.pressed_button"
},
"operator": {
"value": "10:!=",
"display": "不等于"
},
"operand2": {
"value": "10:确定"
},
"operator_options": {
"value": "10:{}"
}
},
"outputs": {}
},
{
"id": "2a389cae-75f6-43f1-a365-b2e47c1d4e18",
"name": "process.exit",
"isEnabled": true,
"inputs": {},
"outputs": {}
},
{
"id": "2091634e-7ee7-4c1f-b3a8-cb3f00dc4770",
"name": "workflow.endif",
"isEnabled": true,
"inputs": {},
"outputs": {}
}
],
"parameters": []
},
{
"name": "1_登录",
"memo": "login_process",
"kind": "visual",
"blocks": [
{
"id": "81b42701-4cb6-4603-b262-75f793c92d58",
"name": "xbot_extensions.super_browser.A4 紫鸟登录",
"isEnabled": true,
"inputs": {
"紫鸟版本": {
"value": "10:V5",
"display": "V5"
},
"企业名称": {
"value": "11:企业名称"
},
"企业用户名": {
"value": "11:账号"
},
"密码": {
"value": "11:密码"
},
"是否填写账号密码": {
"value": "13:False"
},
"是否退出登录": {
"value": "13:False"
}
},
"outputs": {},
"block_title": "紫鸟控制台操作/紫鸟登录"
}
],
"parameters": [
{
"name": "账号",
"direction": "In",
"type": "str",
"value": "",
"description": "",
"kind": "Text"
},
{
"name": "密码",
"direction": "In",
"type": "str",
"value": "",
"description": "",
"kind": "Text"
},
{
"name": "企业名称",
"direction": "In",
"type": "str",
"value": "",
"description": "",
"kind": "Text"
}
]
},
{
"name": "2_功能模块",
"memo": "func_process",
"kind": "visual",
"blocks": [
{
"id": "a1d0e848-2023-4bb9-abbf-25214bb93ef5",
"name": "xbot_extensions.super_browser.A2 打开店铺",
"isEnabled": true,
"inputs": {
"店铺名称": {
"value": "11:店铺名称"
},
"匹配类型": {
"value": "10:相等",
"display": "相等"
},
"打开账号": {
"value": "10:点击",
"display": "点击"
},
"隐私模式": {
"value": "13:False"
},
"超时时间": {
"value": "13:50"
}
},
"outputs": {
"完整店铺名称": {
"name": "完整店铺名称",
"isEnable": true
},
"web_page": {
"name": "web_page",
"isEnable": true
}
},
"block_title": "紫鸟控制台操作/打开店铺"
}
],
"parameters": [
{
"name": "店铺名称",
"direction": "In",
"type": "str",
"value": "",
"description": "",
"kind": "Text"
}
]
}
]
}

167
data/templete1.json Normal file
View File

@@ -0,0 +1,167 @@
{
"name": "main",
"memo": "测试_jc",
"kind": "visual",
"blocks": [
{
"id": "51db7333-6ae1-4429-ac86-354bd60e86d3",
"name": "excel.launch",
"isEnabled": true,
"inputs": {
"launch_way": {
"value": "10:open",
"display": "打开已有的Excel"
},
"driver_way": {
"value": "10:auto_check",
"display": "自动检测"
},
"open_filename": {
"value": "10:D:\\env_text\\京东商智商家版\\16839740_成交订单_2025-07-01~2025-07-31.xlsx"
},
"save_filename": {
"value": "10:"
},
"isvisible": {
"value": "13:False"
},
"ignoreformula": {
"value": "13:False"
},
"password": {
"value": null
},
"write_password": {
"value": null
},
"update_links": {
"value": "13:False"
}
},
"outputs": {
"excel_instance": {
"name": "excel_instance",
"variableLabel": "打开的Excel对象",
"isEnable": true
}
}
},
{
"id": "1ed06cd6-2b02-4ef9-a714-7a010f4e3e19",
"name": "excel.read_data_from_workbook",
"isEnabled": true,
"comment": "从Excel对象%workbook%中读取已使用的矩形区域内容,将数据保存到%excel_data%",
"inputs": {
"workbook": {
"value": "11:excel_instance",
"display": "excel_instance"
},
"read_way": {
"value": "10:used_range",
"display": "已使用区域内容"
},
"range": {
"value": null
},
"cell_row_num": {
"value": null
},
"cell_column_name": {
"value": null
},
"area_begin_row_num": {
"value": null
},
"area_begin_column_name": {
"value": null
},
"area_end_row_num": {
"value": null
},
"area_end_column_name": {
"value": null
},
"row_row_num": {
"value": null
},
"get_display_text": {
"value": "13:False"
},
"has_header_row": {
"value": "13:False"
},
"column_column_name": {
"value": null
},
"sheet_name": {
"value": "10:"
},
"using_text": {
"value": "13:False"
},
"text_cols": {
"value": "10:"
},
"clear_space": {
"value": "13:False"
}
},
"outputs": {
"excel_data": {
"name": "excel_data",
"variableLabel": "Excel已使用区域内容",
"type": "list<list<any>>",
"isEnable": true
}
}
},
{
"id": "6da8c5eb-fcf5-4199-80f5-df5fd529a375",
"name": "excel.close",
"isEnabled": true,
"inputs": {
"operation": {
"value": "10:close_specified",
"display": "关闭指定Excel文件"
},
"excel_instance": {
"value": "11:excel_instance"
},
"close_way": {
"value": "10:save",
"display": "保存"
},
"filename": {
"value": null
},
"overwrite_file": {
"value": "13:True"
},
"close_process": {
"value": "10:office",
"display": "office"
},
"task_kill": {
"value": "13:True"
}
},
"outputs": {}
},
{
"id": "ee73d8ec-1441-45b2-8bec-4d4d10b4153a",
"name": "programing.log",
"isEnabled": true,
"inputs": {
"type": {
"value": "10:info",
"display": "信息"
},
"text": {
"value": "11:excel_data"
}
},
"outputs": {}
}
],
"parameters": []
}

3058
data/test.json Normal file

File diff suppressed because it is too large Load Diff

0
readme.md Normal file
View File

Binary file not shown.

36
src/Converter/utils.py Normal file
View File

@@ -0,0 +1,36 @@
import random
import re
import time
def clear_quote(s):
if s.startswith("'") and s.endswith("'"):
return s[1:-1]
elif s.startswith('"') and s.endswith('"'):
return s[1:-1]
else:
return s
def convert_self_to_glv(python_code: str) -> str:
if 'self' not in python_code:
return python_code
# 第一步:替换属性访问 self.xxx → glv['xxx'] or self.xxx -> glv["xxx"]
# NOTE(huifu.zc) 这里无法完全避免 rf'glv['abc']' 这样的问题, 只能尽力避免
if python_code.find('"') > 0:
python_code = re.sub(r'\bself\.([a-zA-Z_][a-zA-Z0-9_]*)', r"glv['\1']", python_code)
else:
python_code = re.sub(r'\bself\.([a-zA-Z_][a-zA-Z0-9_]*)', r'glv["\1"]', python_code)
# 第二步替换函数参数中的self → glv
# 增强的正则表达式,处理赋值情况 (project=self)
python_code = re.sub(r'([(,=]\s*)\bself\b(?!\.)', r'\1glv', python_code)
return python_code
def gen_random_var(var_base: str):
time_in_ns = str(int(time.time_ns()/100))
random.seed(time.time_ns())
return f"{var_base}_{time_in_ns[-6:]}_{random.randint(100, 200)}"

View File

@@ -0,0 +1,193 @@
import json
import os
import sys
from typing import Dict, Any, Optional, List
import logging
import glob
from .BlockPrototype import BlockPrototype, FieldPrototype
from .Variable import VariablePrototype
class BlockManager:
"""块定义管理器"""
_instance = None
_component_configs: Dict[str, Dict] = {} # 存储每个组件的配置,键为组件名称
_block_prototypes: Dict[str, BlockPrototype] = {} # 缓存已加载的块原型
def __new__(cls):
if cls._instance is None:
cls._instance = super(BlockManager, cls).__new__(cls)
cls._instance._load_block_configs()
return cls._instance
def _get_resource_path(self, relative_path):
"""获取资源文件的路径,支持普通运行和打包环境"""
# 检查是否在PyInstaller环境中运行
if hasattr(sys, '_MEIPASS'):
# PyInstaller创建的临时文件夹
base_path = sys._MEIPASS
else:
# 普通Python环境
base_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
return os.path.join(base_path, relative_path)
def _load_block_configs(self):
"""加载所有块定义配置文件"""
try:
# 获取块配置文件目录
config_dir = self._get_resource_path("assert/block_settings")
if not os.path.exists(config_dir):
logging.warning(f"找不到块配置目录: {config_dir}")
# 在打包环境中尝试其他可能的路径
if hasattr(sys, '_MEIPASS'):
alt_paths = [
os.path.join(sys._MEIPASS, "block_settings"),
os.path.join(sys._MEIPASS, "assert", "block_settings"),
]
for alt_path in alt_paths:
if os.path.exists(alt_path):
config_dir = alt_path
logging.info(f"找到替代块配置目录: {config_dir}")
break
else:
# 输出更详细的诊断信息
logging.error(f"无法找到块配置目录,已尝试以下路径:")
for path in [config_dir] + alt_paths:
logging.error(f" - {path}")
if hasattr(sys, '_MEIPASS'):
logging.error(f"PyInstaller临时目录内容: {os.listdir(sys._MEIPASS)}")
return
else:
return
# 查找所有 .blocks.json 文件
config_files = glob.glob(os.path.join(config_dir, "*.blocks.json"))
if not config_files:
logging.warning(f"未找到块配置文件: {config_dir}")
# 列出目录内容以进行诊断
if os.path.exists(config_dir):
logging.warning(f"目录内容: {os.listdir(config_dir)}")
return
# 加载每个文件
for config_file in config_files:
try:
with open(config_file, 'r', encoding='utf-8-sig') as f:
config_data = json.load(f)
# 从文件名获取组件名称
component_name = os.path.basename(config_file).split('.')[0]
self._component_configs[component_name] = config_data
# 预加载所有块原型
for block_data in config_data.get('blocks', []):
block_name = block_data.get('name')
if block_name:
prototype = BlockPrototype.from_dict(block_data)
self._block_prototypes[block_name] = prototype
logging.info(f"已加载组件 {component_name} 的块定义")
except Exception as e:
logging.error(f"加载块配置文件失败 {config_file}: {e}")
logging.exception(e)
logging.info(f"总共加载了 {len(self._component_configs)} 个组件的块定义")
logging.info(f"总共加载了 {len(self._block_prototypes)} 个块原型")
except Exception as e:
logging.error(f"加载块配置失败: {e}")
logging.exception(e)
def get_block_prototype(self, block_name: str) -> Optional[BlockPrototype]:
"""获取块原型定义
Args:
block_name: 块名称 (如 'programing.log')
Returns:
Optional[BlockPrototype]: 块原型定义如果不存在则返回None
"""
if block_name is None:
raise ValueError("block_name 不能为空")
# 首先从缓存中查找
if block_name in self._block_prototypes:
return self._block_prototypes[block_name]
# 解析命名空间和块名
if '.' in block_name:
namespace, block_short_name = block_name.split('.', 1)
else:
# 在转换失败情况下,会添加一个无效的 block此时不需要警告
if 'EnumWidget_' in block_name:
return None
print(f"不规范的块名称格式: {block_name},应为'namespace.name'格式.....")
return None
# 查找对应的组件配置
component_config = self._component_configs.get(namespace)
if not component_config:
# if 'xbot_extensions' in namespace:
# return None
print(f"找不到组件配置: {namespace}")
return None
# 在该组件的块列表中查找指定名称的块
blocks = component_config.get('blocks', [])
for block_data in blocks:
if block_data.get('name') == block_name:
# 创建并缓存块原型
prototype = BlockPrototype.from_dict(block_data)
self._block_prototypes[block_name] = prototype
return prototype
print(f"在组件 {namespace} 中找不到块定义: {block_short_name}")
return None
def get_input_definitions(self, block_name: str) -> Dict[str, FieldPrototype]:
"""获取块的输入字段定义
Args:
block_name: 块名称
Returns:
Dict[str, FieldPrototype]: 字段名到定义的映射
"""
prototype = self.get_block_prototype(block_name)
if not prototype:
return {}
# 将输入字段定义转换为字段名到定义的映射
return {input_def.name: input_def for input_def in prototype.inputs}
def get_output_definitions(self, block_name: str) -> Dict[str, VariablePrototype]:
"""获取块的输出变量定义
Args:
block_name: 块名称
Returns:
Dict[str, VariablePrototype]: 变量名到定义的映射
"""
prototype = self.get_block_prototype(block_name)
if not prototype:
return {}
# 将输出变量定义转换为变量名到定义的映射
return {output_def.name: output_def for output_def in prototype.outputs}
def get_required_inputs(self, block_name: str) -> List[str]:
"""获取块的必填输入字段名称
Args:
block_name: 块名称
Returns:
List[str]: 必填字段名列表
"""
prototype = self.get_block_prototype(block_name)
if not prototype:
return []
return prototype.get_required_inputs()

View File

@@ -0,0 +1,196 @@
from dataclasses import dataclass, field
from typing import List, Dict, Any, Optional
from .Variable import VariablePrototype # 导入自 Variable 模块
@dataclass
class FieldPrototype:
name: str
label: str
type: str = "str"
required: bool = False
tips: str = ""
default: Optional[Any] = None
defaultDisplay: Optional[str] = None
editor: Dict[str, Any] = field(default_factory=dict)
category: str = "normal"
def to_dict(self) -> Dict[str, Any]:
"""转换为字典表示"""
result = {
"name": self.name,
"label": self.label,
"type": self.type,
"required": self.required,
"tips": self.tips,
"category": self.category
}
# 添加可选字段
if self.default is not None:
result["default"] = self.default
if self.defaultDisplay:
result["defaultDisplay"] = self.defaultDisplay
if self.editor:
result["editor"] = self.editor
return result
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> 'FieldPrototype':
"""从字典创建字段原型"""
return cls(
name=data.get("name"),
label=data.get("label", ""),
type=data.get("type"),
required=data.get("required", False),
tips=data.get("tips", ""),
default=data.get("default", None),
defaultDisplay=data.get("defaultDisplay"),
editor=data.get("editor", {}),
category=data.get("category", "normal")
)
@dataclass
class VariablePrototype:
name: str
id: str
type: str
label: str = ""
variableLabel: Optional[str] = None
tips: str = ""
def to_dict(self) -> Dict[str, Any]:
"""转换为字典表示"""
result = {
"name": self.name,
"type": self.type,
}
if self.label:
result["label"] = self.label
if self.variableLabel:
result["variableLabel"] = self.variableLabel
if self.tips:
result["tips"] = self.tips
return result
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> 'VariablePrototype':
"""从字典创建变量原型"""
return cls(
name=data.get("name"),
type=data.get("type"),
id=data.get("id"),
label=data.get("label", ""),
variableLabel=data.get("variableLabel", ""),
tips=data.get("tips", "")
)
@dataclass
class BlockPrototype:
"""块原型定义"""
name: str
title: str
description: str = ""
comment: str = ""
icon: str = ""
function: str = ""
helpUrl: str = ""
extension: str = ""
hidden: bool = False
canDebug: bool = True
isCondition: bool = False
isLoop: bool = False
isPseudo: bool = False
statement: bool = False
keywords: List[str] = field(default_factory=list)
inputs: List[FieldPrototype] = field(default_factory=list)
outputs: List[VariablePrototype] = field(default_factory=list) # 更新为 VariablePrototype
exceptionHandling: Optional[str] = None
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> 'BlockPrototype':
"""从字典创建块原型"""
# 处理输入字段
inputs = []
for input_data in data.get("inputs", []):
inputs.append(FieldPrototype.from_dict(input_data))
# 处理输出变量
outputs = []
for output_data in data.get("outputs", []):
outputs.append(VariablePrototype.from_dict(output_data)) # 使用 VariablePrototype
# 处理关键词
keywords = []
keywords_str = data.get("keywords", "")
if keywords_str:
keywords = keywords_str.split(";")
return cls(
name=data.get("name", ""),
title=data.get("title", ""),
description=data.get("description", ""),
comment=data.get("comment", ""),
icon=data.get("icon", ""),
function=data.get("function", ""),
helpUrl=data.get("helpUrl", ""),
extension=data.get("extension", ""),
hidden=data.get("hidden", False),
canDebug=data.get("canDebug", True),
isCondition=data.get("isCondition", False),
isLoop=data.get("isLoop", False),
isPseudo=data.get("isPseudo", False),
statement=data.get("statement", False),
keywords=keywords,
inputs=inputs,
outputs=outputs,
exceptionHandling=data.get("exception_handling")
)
def to_dict(self) -> Dict[str, Any]:
"""转换为字典表示"""
result = {
"name": self.name,
"statement": self.statement,
"title": self.title,
"keywords": ";".join(self.keywords) if self.keywords else None,
"description": self.description,
"comment": self.comment,
"icon": self.icon,
"function": self.function,
"helpUrl": self.helpUrl,
"extension": self.extension,
"hidden": self.hidden,
"canDebug": self.canDebug,
"isCondition": self.isCondition,
"isLoop": self.isLoop,
"isPseudo": self.isPseudo,
"inputs": [input.to_dict() for input in self.inputs],
"outputs": [output.to_dict() for output in self.outputs]
}
if self.exceptionHandling:
result["exception_handling"] = self.exceptionHandling
return result
def get_input_by_name(self, name: str) -> Optional[FieldPrototype]:
"""通过名称获取输入字段定义"""
for input_def in self.inputs:
if input_def.name == name:
return input_def
return None
def get_output_by_name(self, name: str) -> Optional[VariablePrototype]:
"""通过名称获取输出变量定义"""
for output_def in self.outputs:
if output_def.name == name:
return output_def
return None
def get_required_inputs(self) -> List[str]:
"""获取所有必填输入字段名称"""
return [input_def.name for input_def in self.inputs if input_def.required]

111
src/Xbot/Blockly/Field.py Normal file
View File

@@ -0,0 +1,111 @@
from dataclasses import dataclass
from typing import Dict, Any, Optional, Union, List
from enum import Enum
from .BlockPrototype import FieldPrototype
from .FieldValue import FieldValue, FieldValueKind, FieldValueFactory
@dataclass
class Field:
"""块的输入字段定义"""
label: str
displayValue: str
prototype: FieldPrototype = None
value: Optional["FieldValue"] = None # 引用 FieldValue 类型
def __post_init__(self):
"""初始化后处理"""
# 如果没有设置值,但有原型,则从原型创建默认值
if self.value is None and self.prototype is not None:
if self.prototype.default:
self.value = FieldValueFactory.create(self.prototype.default)
def reset_value(self):
self.value = None
if self.prototype.default:
self.value = FieldValueFactory.create(self.prototype.default)
def set_text_value(self, content):
self.value = FieldValue(FieldValueKind.TEXT, content)
def set_image_value(self, content):
self.value = FieldValue(FieldValueKind.IMAGE, content)
def no_inputbox_text_value(self, content):
self.value = FieldValue(FieldValueKind.TEXT, content)
for item in self.prototype.editor["options"]:
if item["value"].lower() == content.lower():
self.displayValue = item["display"]
return
def set_display_value(self, display_value):
self.displayValue = display_value
def set_group_array_value(self, value):
self.value = FieldValue(FieldValueKind.GROUPARRAY, value)
def set_expression_value(self, content):
from Converter.utils import convert_self_to_glv
if content is not None and "self" in content:
content = convert_self_to_glv(content)
self.value = FieldValue(FieldValueKind.EXPRESSION, content)
def set_global_var(self, global_var_name):
self.value = FieldValue(FieldValueKind.VARIABLE, f"glv['{global_var_name}']")
def set_flow_arg(self, flow_var_name):
self.value = FieldValue(FieldValueKind.VARIABLE, flow_var_name)
def set_flow_var(self, local_var_name):
self.value = FieldValue(FieldValueKind.VARIABLE, local_var_name)
def to_dict(self) -> Dict[str, Any]:
"""转换为字典表示"""
result = {}
if self.value:
result["value"] = str(self.value)
else:
result["value"] = None
if self.displayValue:
result["display"] = self.displayValue
# if self.label:
# result["label"] = self.label
# 如果 result 是一个空字典,则返回 None
if not result:
return None
return result
def not_inputbox_filed(self):
return (
self.prototype.editor["kind"] != "textbox"
and self.prototype.editor["kind"].lower() != "memoedit"
and self.prototype.editor["kind"] != "select"
)
@classmethod
def from_prototype(cls, prototype: FieldPrototype) -> "Field":
"""从字段原型创建Field实例"""
field = cls(
label=prototype.label,
displayValue=prototype.defaultDisplay or "",
prototype=prototype,
)
return field
@classmethod
def from_value_string(cls, label: str, value_string: str) -> "Field":
"""从值字符串创建Field实例"""
field = cls(label=label, displayValue="")
return field

View File

@@ -0,0 +1,191 @@
from typing import List, Dict, Any, Optional, Union
import json
from enum import Enum
class FieldValueKind(str, Enum):
"""字段值类型枚举"""
TEXT = "10" # Text = 10
VARIABLE = "11" # Variable = 11
SELECTOR = "12" # Selector = 12
EXPRESSION = "13" # Expression = 13
IMAGE = "14" # Image = 14
ARRAY = "15" # Array = 15
GROUPARRAY = "16" # GroupArray = 16
OPERATOR = "17" # Operator = 17
APEXPR = "18" # APExpr = 18
class FieldValue:
"""字段值基类"""
def __init__(self, kind: FieldValueKind, content: str):
"""初始化字段值
Args:
kind: 字段值类型
content: 字段内容
"""
self.kind = kind
self._content = content or ""
@property
def content(self) -> str:
"""获取字段内容"""
return self._content
@content.setter
def content(self, value: str):
"""设置字段内容"""
self._content = value or ""
def __str__(self) -> str:
"""转换为字符串表示"""
if self._content:
return f"{self.kind.value}:{self._content}"
else:
return f"{self.kind.value}:"
class FieldValueArray(FieldValue):
"""数组类型字段值"""
def __init__(self, content: str = ""):
"""初始化数组字段值"""
super().__init__(FieldValueKind.ARRAY, content)
self._items: List[str] = []
# 解析初始内容
self._parse_content()
def _parse_content(self):
"""解析内容字符串为数组项"""
if not self._content:
self._items = []
return
try:
self._items = json.loads(self._content)
if not isinstance(self._items, list):
self._items = []
except json.JSONDecodeError:
self._items = []
@property
def items(self) -> List[str]:
"""获取数组项列表"""
return self._items
@items.setter
def items(self, values: List[str]):
"""设置数组项列表"""
self._items = values or []
self._content = json.dumps(self._items)
@property
def content(self) -> str:
"""获取字段内容确保是JSON格式"""
return self._content
@content.setter
def content(self, value: str):
"""设置字段内容并解析"""
self._content = value or ""
self._parse_content()
class FieldValueGroupArray(FieldValue):
"""分组数组类型字段值"""
def __init__(self, content: str = ""):
"""初始化分组数组字段值"""
super().__init__(FieldValueKind.GROUPARRAY, content)
self._groups: List[Dict[str, Any]] = []
# 解析初始内容
self._parse_content()
def _parse_content(self):
"""解析内容字符串为分组项"""
if not self._content:
self._groups = []
return
try:
self._groups = json.loads(self._content)
if not isinstance(self._groups, list):
self._groups = []
except json.JSONDecodeError:
self._groups = []
@property
def groups(self) -> List[Dict[str, Any]]:
"""获取分组列表"""
return self._groups
@groups.setter
def groups(self, values: List[Dict[str, Any]]):
"""设置分组列表"""
self._groups = values or []
self._content = json.dumps(self._groups)
@property
def content(self) -> str:
"""获取字段内容确保是JSON格式"""
return self._content
@content.setter
def content(self, value: str):
"""设置字段内容并解析"""
self._content = value or ""
self._parse_content()
def __str__(self) -> str:
"""转换为字符串表示"""
def __str__(self) -> str:
"""转换为字符串表示"""
result = {}
for name, value in self._groups.items():
result[name] = [str(item) for item in value]
return f"{self.kind.value}:{json.dumps(result)}"
class FieldValueFactory:
"""字段值工厂类,用于创建和解析字段值"""
@staticmethod
def create(value_string: str) -> FieldValue:
"""从值字符串创建字段值实例
Args:
value_string: 格式为 "kind:content" 的字符串
Returns:
FieldValue: 字段值实例
"""
# 解析值字符串
parts = value_string.split(':', 1)
if len(parts) != 2:
# 格式不正确,默认为文本类型
return FieldValue(FieldValueKind.TEXT, value_string)
kind_str, content = parts
try:
kind = FieldValueKind(kind_str)
except ValueError:
# 无效的类型,默认为文本
return FieldValue(FieldValueKind.TEXT, value_string)
return FieldValueFactory.create_by_kind(kind, content)
@staticmethod
def create_by_kind(kind: FieldValueKind, content: str = "") -> FieldValue:
"""根据类型和内容创建字段值实例
Args:
kind: 字段值类型
content: 字段内容
Returns:
FieldValue: 字段值实例
"""
if kind == FieldValueKind.ARRAY:
return FieldValueArray(content)
elif kind == FieldValueKind.GROUPARRAY:
return FieldValueGroupArray(content)
else:
return FieldValue(kind, content)

View File

@@ -0,0 +1,93 @@
from dataclasses import dataclass
from typing import Dict, Any, Optional
from Xbot.Blockly.FieldValue import FieldValueKind
@dataclass
class VariablePrototype:
"""变量原型定义"""
name: str
type: str = "any"
id: Optional[str] = None
label: Optional[str] = None
variableLabel: Optional[str] = None
tips: Optional[str] = None
def to_dict(self) -> Dict[str, Any]:
"""转换为字典表示"""
result = {
"name": self.name,
"type": self.type,
}
# 添加可选字段
if self.id:
result["id"] = self.id
if self.label:
result["label"] = self.label
if self.variableLabel:
result["variableLabel"] = self.variableLabel
if self.tips:
result["tips"] = self.tips
return result
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> 'VariablePrototype':
"""从字典创建变量原型"""
return cls(
name=data.get("name"),
type=data.get("type"),
id=data.get("id", None),
label=data.get("label", None),
variableLabel=data.get("variableLabel", None),
tips=data.get("tips", None)
)
@dataclass
class Variable:
"""块的输出变量定义"""
name: str
isEnable: bool = True
variableLabel: Optional[str] = None
type: Optional[str] = None
defaultValue: Optional[Any] = None
prototype: Optional[VariablePrototype] = None
id: Optional[str] = None
def to_dict(self) -> Dict[str, Any]:
"""转换为字典表示"""
result = {
"name": self.name,
"isEnable": self.isEnable
}
# if self.variableLabel:
# result["variableLabel"] = self.variableLabel
# if self.type:
# result["type"] = self.type
# if self.defaultValue:
# result["defaultValue"] = self.defaultValue
return result
def set_name(self, name):
self.name = name
def set_type(self, field_type:FieldValueKind):
self.type = field_type.value.lower()
@classmethod
def from_prototype(cls, prototype: VariablePrototype) -> 'Variable':
"""从变量原型创建Variable实例"""
return cls(
name=prototype.name,
isEnable=True,
variableLabel=prototype.variableLabel,
type=prototype.type,
defaultValue=None,
prototype=prototype,
id=prototype.id
)

View File

@@ -0,0 +1,198 @@
import enum
from dataclasses import dataclass, field
from typing import Optional, Dict, Any, List
import uuid
import logging
from .Field import Field, FieldValueKind
from .Variable import Variable
from .BlockManager import BlockManager
from .BlockPrototype import BlockPrototype, FieldPrototype
from .FieldValue import FieldValueFactory
# 创建全局单例
_block_manager = BlockManager()
class XbotExceptionKind(str, enum.Enum):
Default = "default"
Abort = "exit"
Contine = "continue"
Retry = "retry"
@dataclass
class XbotBlock:
"""Xbot流程块定义"""
id: str
name: str # 块类型名称
fields: Dict[str, Field] = field(default_factory=dict)
variables: Dict[str, Variable] = field(default_factory=dict)
isEnabled: bool = True
block_title: Optional[str] = None
comment: Optional[str] = None
fold_state: Optional[str] = None
block_prototype: BlockPrototype = None
_exception_mode: Optional[XbotExceptionKind] = XbotExceptionKind.Default
def __post_init__(self):
"""初始化后处理"""
if not self.fields:
self.fields = {}
# 如果没有提供ID则自动生成
if not self.id:
self.id = str(uuid.uuid4())
if not self.fields:
self.fields = {}
if not self.variables:
self.variables = {}
self.prepareDefaultInputOutput()
if not self.block_prototype:
# if 'xbot_extensions' in self.name:
# return
print(f"未找到块定义: {self.name}")
return
if not self.comment:
self.comment = self.block_prototype.comment
def set_exception_mode_continue(self):
self._exception_mode = XbotExceptionKind.Contine
def prepareDefaultInputOutput(self):
"""加载块定义并创建默认输入输出"""
self.block_prototype = _block_manager.get_block_prototype(self.name)
if not self.block_prototype:
return
# 为每个输入字段创建对应的 Field 实例
for field_prototype in self.block_prototype.inputs:
# 如果该字段已经存在,则跳过
print(f"输入字段: {field_prototype.name}")
print(self.fields)
if field_prototype.name in self.fields:
continue
field = Field.from_prototype(field_prototype)
self.fields[field_prototype.name] = field
for var_prototype in self.block_prototype.outputs:
if var_prototype.name in self.variables:
continue
variable = Variable.from_prototype(var_prototype)
self.variables[var_prototype.id] = variable
@property
def local_variables(self) -> List[str]:
"""获取块定义的局部变量列表"""
return [name for name, var in self.variables.items() if var.isEnable]
@property
def component_namespace(self) -> str:
"""获取组件命名空间"""
return self.name.split('.')[0] if '.' in self.name else ''
@property
def component_name(self) -> str:
"""获取组件基础名称"""
return self.name.split('.')[-1] if '.' in self.name else self.name
def validate(self) -> List[str]:
"""验证块配置
Returns:
List[str]: 错误信息列表,如果没有错误则为空列表
"""
errors = []
# 验证必填字段
required_fields = _block_manager.get_required_fields(self.name)
for field_name in required_fields:
if field_name not in self.fields:
errors.append(f"缺少必填字段: {field_name}")
elif not self.fields[field_name].value:
errors.append(f"必填字段值为空: {field_name}")
return errors
def to_dict(self) -> Dict[str, Any]:
"""转换为字典格式"""
result = {
"id": self.id,
"name": self.name,
"isEnabled": self.isEnabled,
"inputs": {},
"outputs": {}
}
# 添加可选字段
if self.comment:
result["comment"] = self.comment
if self.fold_state:
result["foldState"] = self.fold_state
if self.block_title:
result["block_title"] = self.block_title
# 处理输入字段
print(f"输入字段: {self.fields}")
for name, field in self.fields.items():
result["inputs"][name] = field.to_dict()
# 处理输出变量
for name, variable in self.variables.items():
result["outputs"][name] = variable.to_dict()
# 错误处理 - 部分模式没有支持, 需要的时候再支持
if self._exception_mode == XbotExceptionKind.Contine:
result["exception_handling"] = {
"logging": True,
"mode": "continue",
"retryTime": 1,
"retryInterval": 1
}
return result
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> 'XbotBlock':
"""从字典创建Block实例"""
block = cls(
id=data.get('id', str(uuid.uuid4())),
name=data.get('name', ''),
isEnabled=data.get('isEnabled', True),
comment=data.get('comment'),
fold_state=data.get('foldState')
)
if 'block_title' in data:
block.block_title = data['block_title']
# 处理输入字段
for name, input_data in data.get('inputs', {}).items():
if "value" in input_data:
# 使用 Field.from_value_string 方法创建字段
field = Field.from_value_string(
label=input_data.get("label", name),
value_string=input_data["value"]
)
field.displayValue = input_data.get("display", "")
block.fields[name] = field
# 处理输出变量
for name, output_data in data.get('outputs', {}).items():
variable = Variable(
name=name,
isEnable=output_data.get("isEnable", True),
variableLabel=output_data.get("variableLabel"),
type=output_data.get("type", "any")
)
block.variables[name] = variable
return block

View File

@@ -0,0 +1,4 @@
from .BlockManager import BlockManager
from .XbotBlock import XbotBlock
from .Field import Field, FieldValueKind
from .Variable import Variable

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

93
src/Xbot/CodeFlow.py Normal file
View File

@@ -0,0 +1,93 @@
from dataclasses import dataclass
from typing import Dict, Any, Optional
import json
import os.path
from .XbotFlow import XbotFlow, FlowKind
from .FlowParameter import FlowParameter, FieldValueKind
DEFAULT_CODE_TEMPLATE = '''# 使用提醒:
# 1. xbot包提供软件自动化、数据表格、Excel、日志、AI等功能
# 2. package包提供访问当前应用数据的功能如获取元素、访问全局变量、获取资源文件等功能
# 3. 当此模块作为流程独立运行时执行main函数
# 4. 可视化流程中可以通过"调用模块"的指令使用此模块
import xbot
from xbot import print, sleep
from .import package
from .package import variables as glv
def main(args):
pass
'''
@dataclass
class CodeFlow(XbotFlow):
"""代码类型流程"""
code: str = ""
def load_flow_json(self, project_dir: str) -> None:
"""从flow.json文件加载流程定义"""
dev_dir = os.path.join(project_dir, ".dev")
flow_path = os.path.join(dev_dir, f"{self.filename}.flow.json")
if not os.path.exists(flow_path):
print(f"警告: 流程文件不存在: {flow_path}")
return
with open(flow_path, 'r', encoding='utf-8') as f:
data = json.load(f)
# 加载parameters
self.parameters = []
for param_data in data.get('parameters', []):
param = FlowParameter(
name=param_data.get('name', ''),
direction=param_data.get('direction', 'In'),
type=param_data.get('type', 'any'),
value=param_data.get('value', ''),
description=param_data.get('description', ''),
kind=FieldValueKind(param_data.get('kind', 'Expression'))
)
self.parameters.append(param)
# 从Python文件加载代码内容
code_path = os.path.join(project_dir, f"{self.filename}.py")
if os.path.exists(code_path):
with open(code_path, 'r', encoding='utf-8') as code_file:
self.code = code_file.read()
else:
print(f"警告: 代码文件不存在: {code_path}, 使用默认模板")
self.code = DEFAULT_CODE_TEMPLATE
def to_disk(self) -> Dict[str, Any]:
"""将流程转换为字典格式 (flow.json内容)"""
return {
'name': self.name,
'kind': self.kind.lower(),
'parameters': [param.to_dict() for param in self.parameters]
}
def save_flow_json(self, project_dir: str) -> None:
"""保存流程定义到flow.json和Python文件
Args:
project_dir: 项目根目录
"""
# 先调用父类方法保存flow.json
super().save_flow_json(project_dir)
# 然后保存Python代码文件
code_path = os.path.join(project_dir, f"{self.filename}.py")
print(f"保存代码文件: {code_path}")
with open(code_path, 'w', encoding='utf-8') as f:
f.write(self.code or DEFAULT_CODE_TEMPLATE)
def set_code(self, code: str):
"""设置代码内容"""
self.code = code
def get_code(self) -> str:
"""获取代码内容"""
return self.code

89
src/Xbot/FlowParameter.py Normal file
View File

@@ -0,0 +1,89 @@
from dataclasses import dataclass
import enum
from typing import Dict, Any
class DirectionKind(str, enum.Enum):
IN = "In"
OUT = "Out"
class FieldValueKind(str, enum.Enum):
"""字段值类型枚举
对应关系:
10: 文本值 (TEXT)
11: 变量引用 (VARIABLE)
12: 选择器 (SELECTOR)
13: 表达式 (EXPRESSION)
14: 图片 (IMAGE)
15: 数组 (ARRAY)
16: 分组数组 (GROUPARRAY)
17: 运算符 (OPERATOR)
18: AI表达式 (APEXPR)
"""
TEXT = "10" # Text = 10
VARIABLE = "11" # Variable = 11
SELECTOR = "12" # Selector = 12
EXPRESSION = "13" # Expression = 13
IMAGE = "14" # Image = 14
ARRAY = "15" # Array = 15
GROUPARRAY = "16" # GroupArray = 16
OPERATOR = "17" # Operator = 17
APEXPR = "18" # APExpr = 18
@classmethod
def from_string(cls, value: str) -> 'FieldValueKind':
"""从字符串创建枚举值
支持字符串名称 (如 "TEXT") 和实际值 (如 "10")
"""
# 尝试将输入当作枚举成员名称处理
name_map = {
"TEXT": cls.TEXT,
"VARIABLE": cls.VARIABLE,
"SELECTOR": cls.SELECTOR,
"EXPRESSION": cls.EXPRESSION,
"IMAGE": cls.IMAGE,
"ARRAY": cls.ARRAY,
"GROUPARRAY": cls.GROUPARRAY,
"OPERATOR": cls.OPERATOR,
"APEXPR": cls.APEXPR,
}
# 处理忽略大小写的情况
if value.upper() in name_map:
return name_map[value.upper()]
# 尝试直接用值创建
try:
return cls(value)
except ValueError:
# 如果都失败,返回默认值
return cls.TEXT
@dataclass
class FlowParameter:
"""流程参数定义"""
name: str = ""
direction: DirectionKind = DirectionKind.IN
value: str = ""
type: str = ""
description: str = ""
kind: FieldValueKind = FieldValueKind.TEXT
def __post_init__(self):
self._name = self.name
self._direction = self.direction
self._value = self.value
self._description = self.description
self._kind = self.kind
def to_dict(self) -> Dict[str, Any]:
"""转换为字典表示"""
return {
"name": self.name,
"direction": self.direction.value,
"value": self.value,
"type": self.type,
"description": self.description,
"kind": self.kind.value
}

View File

@@ -0,0 +1,32 @@
import os
import glob
class ShadowBotPaths:
@staticmethod
def get_shadowbot_root():
"""获取ShadowBot安装根目录"""
return os.path.join(os.environ["LOCALAPPDATA"], "ShadowBot")
@staticmethod
def get_first_user_dir():
"""获取第一个用户目录"""
users_dir = os.path.join(ShadowBotPaths.get_shadowbot_root(), "users")
user_dirs = glob.glob(os.path.join(users_dir, "*"))
if not user_dirs:
raise FileNotFoundError("未找到ShadowBot用户目录")
# NOTE(huifu.zc) 为多账户的用户方便指定账号
env_defined_id = os.environ.get("__XBOT_YSQ_CONV_USR_ID__", "")
if env_defined_id is not None and len(env_defined_id) > 0:
for user_dir in user_dirs:
user_id = os.path.basename(user_dir)
if user_id == env_defined_id:
return user_dir
return user_dirs[0]
@staticmethod
def get_apps_dir():
"""获取应用目录"""
return os.path.join(ShadowBotPaths.get_first_user_dir(), "apps")

75
src/Xbot/VisualFlow.py Normal file
View File

@@ -0,0 +1,75 @@
from dataclasses import dataclass, field
from typing import Optional, List, Dict, Any
import json
import os.path
from .XbotFlow import XbotFlow, FlowKind
from .Blockly import XbotBlock
from .FlowParameter import FlowParameter, DirectionKind, FieldValueKind
@dataclass
class VisualFlow(XbotFlow):
"""可视化流程"""
blocks: List[XbotBlock] = field(default_factory=list)
connections: List[Dict[str, str]] = field(default_factory=list)
def load_flow_json(self, project_dir: str) -> None:
"""从flow.json文件加载流程定义"""
dev_dir = os.path.join(project_dir, ".dev")
flow_path = os.path.join(dev_dir, f"{self.filename}.flow.json")
if not os.path.exists(flow_path):
print(f"警告: 流程文件不存在: {flow_path}")
return
with open(flow_path, 'r', encoding='utf-8') as f:
data = json.load(f)
self.memo = data.get('memo', '')
# 加载blocks
self.blocks = []
for block_data in data.get('blocks', []):
block = XbotBlock.from_dict(block_data)
self.blocks.append(block)
# 加载parameters
self.parameters = []
for param_data in data.get('parameters', []):
param = FlowParameter(
name=param_data.get('name', ''),
direction=param_data.get('direction', 'In'),
type=param_data.get('type', 'any'),
value=param_data.get('value', ''),
description=param_data.get('description', ''),
kind=FieldValueKind(param_data.get('kind', 'Expression'))
)
self.parameters.append(param)
# 加载connections (如果有)
self.connections = data.get('connections', [])
def to_disk(self) -> Dict[str, Any]:
"""将流程转换为字典格式"""
return {
'name': self.name,
'memo': self.memo,
'kind': self.kind.lower(),
'blocks': [block.to_dict() for block in self.blocks],
'parameters': [param.to_dict() for param in self.parameters],
}
def create_new_block(self, block_id: str, block_name: str,
inputs: Dict[str, Dict[str, Any]] = None,
outputs: Dict[str, Any] = None,
is_enabled: bool = True,
block_title: Optional[str] = None) -> XbotBlock:
"""添加新的代码块"""
block = XbotBlock(
id=block_id,
name=block_name,
inputs=inputs or {},
outputs=outputs or {},
isEnabled=is_enabled,
block_title=block_title
)
self.blocks.append(block)
return block

47
src/Xbot/XBotHelper.py Normal file
View File

@@ -0,0 +1,47 @@
from Xbot import XbotProject, XbotBlock
class XBotGlobalVariable(object):
@classmethod
def build_glv_var(cls, var_name: str):
assert isinstance(var_name, str)
return f"glv['{var_name}']"
class XBotVariableUtil(object):
self_prefix_string = "self."
@classmethod
def is_self_var(cls, var_name: str):
return var_name.startswith(cls.self_prefix_string)
@classmethod
def trim_self(cls, var_name):
return var_name[len(cls.self_prefix_string):]
@classmethod
def create_comment_block(cls, comment):
comment_block = XbotBlock(id="", name="programing.comment")
comment_block.fields["content"].set_text_value(comment)
return comment_block
@classmethod
def create_var_block(cls, project: XbotProject, var_name: str, var_value: str):
set_var_block = XbotBlock(id="", name="programing.variable")
# 绑定的变量 = ret_name (any)
set_var_block.fields["value_type"].set_text_value("any")
if cls.is_self_var(var_name):
var_value_without_self = cls.trim_self(var_name)
cls.add_global_if_not_existed(project, var_value_without_self)
set_var_block.variables["variable"].set_name(var_value_without_self)
else:
set_var_block.variables["variable"].set_name(var_name)
set_var_block.fields["value"].set_expression_value(var_value)
return set_var_block
@classmethod
def add_global_if_not_existed(cls, project: XbotProject, var_name: str) -> None:
if not project.global_variable_exist(var_name):
project.add_global_variable(var_name, value=None)

46
src/Xbot/XbotApp.py Normal file
View File

@@ -0,0 +1,46 @@
import json
import os
import shutil
import uuid
from Xbot.XbotProject import XbotProject
from Xbot.XbotFlow import XbotFlow
class XbotApp:
def __init__(self, app_root: str, app_id: str, app_name: str):
self.project = XbotProject(app_root, app_id, app_name)
self.main_flow = XbotFlow(self.project.dev_dir)
self.main_flow.project = self.project
def create(self):
"""创建完整的Xbot应用程序结构"""
if not os.path.exists(self.project.template_dir):
raise FileNotFoundError(f"模板目录不存在: {self.project.template_dir}")
self.project.create_project_structure()
self.main_flow.create_flow()
self._create_python_modules()
self._update_package_json()
def _create_python_modules(self):
"""创建Python模块文件"""
with open(os.path.join(self.project.robot_dir, "main.py"), "w", encoding="utf-8") as f:
f.write("# main.py implementation\n")
def _update_package_json(self):
"""更新package.json文件"""
package_file = os.path.join(self.project.robot_dir, "package.json")
with open(package_file, 'r', encoding="utf-8") as f:
package_data = json.load(f)
package_data.update({
"uuid": self.project.app_id,
"name": self.project.app_name,
"flows": [XbotFlow.get_flow_config("main")]
})
with open(package_file, 'w', encoding="utf-8") as f:
json.dump(package_data, f, indent=2, ensure_ascii=False)

317
src/Xbot/XbotAppCreator.py Normal file
View File

@@ -0,0 +1,317 @@
import os
import shutil
import sys
import uuid
from .ShadowBotPaths import ShadowBotPaths
from .XbotProject import XbotProject
from Xbot.Blockly import Variable, Field
import json
# 添加项目根目录到Python路径
project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if project_root not in sys.path:
sys.path.append(project_root)
from .bot_import import insert_new_app
def _get_template_dir():
"""获取模板目录适用于普通运行和PyInstaller打包的情况"""
# 检查是否在PyInstaller环境中运行
if hasattr(sys, '_MEIPASS'):
# PyInstaller创建的临时文件夹
base_path = sys._MEIPASS
else:
# 普通Python环境
base_path = os.path.dirname(os.path.abspath(__file__))
template_path = os.path.join(base_path, "Xbot", "XbotAppTemplate", "xbot_robot")
# 如果路径不存在,尝试其他可能的路径
if not os.path.exists(template_path):
template_path = os.path.join(base_path, "XbotAppTemplate", "xbot_robot")
return template_path
class XbotAppCreator:
def __init__(self, app_root: str, app_id: str, app_name: str):
"""初始化应用创建器
Args:
app_root: 应用根目录
app_id: 应用唯一标识
app_name: 应用名称
"""
self.app_root = app_root
self.app_id = app_id
self.app_name = app_name
self.app_dir = os.path.join(app_root, app_id)
self.robot_dir = os.path.join(self.app_dir, "xbot_robot")
self.template_dir = _get_template_dir() # 使用辅助函数获取模板目录
def create(self) -> XbotProject:
"""创建新的Xbot应用
Returns:
XbotProject: 创建的项目实例
"""
# 验证模板目录
if not os.path.exists(self.template_dir):
# 输出更多诊断信息
print(f"模板目录不存在: {self.template_dir}")
print(f"当前工作目录: {os.getcwd()}")
print(f"Python路径: {sys.path}")
if hasattr(sys, '_MEIPASS'):
print(f"PyInstaller临时目录: {sys._MEIPASS}")
print(f"临时目录内容: {os.listdir(sys._MEIPASS)}")
if os.path.exists(os.path.join(sys._MEIPASS, 'Xbot')):
print(f"Xbot目录内容: {os.listdir(os.path.join(sys._MEIPASS, 'Xbot'))}")
raise FileNotFoundError(f"模板目录不存在: {self.template_dir}")
# 创建应用目录
os.makedirs(self.app_dir, exist_ok=True)
# 复制机器人模板
self._copy_robot_template()
# 加载并更新项目
return self._init_project()
def _copy_robot_template(self):
"""从模板目录复制xbot_robot内容到目标目录"""
if os.path.exists(self.robot_dir):
shutil.rmtree(self.robot_dir)
print(f"正在从模板创建机器人: {self.template_dir} -> {self.robot_dir}")
shutil.copytree(self.template_dir, self.robot_dir)
def _init_project(self) -> XbotProject:
"""初始化项目配置"""
# 加载项目
project = XbotProject.load(self.robot_dir)
# 更新基本信息
project.uuid = self.app_id
project.name = self.app_name
# 保存更新后的配置和流程
project.save_all(self.robot_dir)
print(f"已初始化项目:")
print(f"- 名称: {project.name}")
print(f"- UUID: {project.uuid}")
print(f"- 位置: {self.robot_dir}")
return project
def create_and_import_app(app_name: str, temp_path: str) -> tuple[str, str]:
"""创建并导入新的Xbot应用
Returns:
tuple[str, str]: (app_id, app_path)
"""
try:
output_dir = ShadowBotPaths.get_apps_dir()
app_id = str(uuid.uuid4())
# 创建应用
creator = XbotAppCreator(output_dir, app_id, app_name)
project = creator.create()
# 加载扩展
project.add_internal_dependency('super_browser==25.9.3')
project.add_internal_dependency('activity_f4d5de04==23.11.1')
# code = project.create_code_flow('module1', '')
code = project.create_new_flow('module1', '')
code.add_input_parameter('参数一', 'str', '参数1的默认值', '参数1的描述', 'TEXT')
code.add_output_parameter('结果', 'str', '结果的默认值', '结果的描述', 'TEXT')
# project.add_global_variable('全局变量1', 'str', '全局变量1的默认值', '全局变量1的描述', 'TEXT')
# project.add_global_variable('全局变量2', 'any', '0', '全局变量2的描述', 'Expression')
main = project.main
main.add_input_parameter('参数一', 'str', '参数1的默认值', '参数1的描述', 'TEXT')
main.add_output_parameter('结果', 'str', '结果的默认值', '结果的描述', 'TEXT')
block = main.add_block('dialog.show_custom_dialog')
block.fields['dialog_title'].set_text_value('Hello, World!')
block.variables['dialog_result'].set_name('1111')
# block = main.add_block('programing.log')
# 创建脚手架
# # 打开excel
# block = main.add_block('excel.launch')
# file_path = r"D:\env_text\万相台\批量报表下载.xlsx"
# block.fields['open_filename'].set_text_value(file_path)
# block.fields['save_filename'].set_text_value("excel_instance")
# block.fields['driver_way'].set_text_value("office")
# # 关闭excel
# block = main.add_block('excel.close')
# block.fields['operation'].set_text_value("close_specified")
# block.fields['excel_instance'].set_text_value("excel_instance")
# block.fields['close_way'].set_text_value("save")
# 打开紫鸟登录
block = main.add_block('xbot_extensions.super_browser.A2 打开店铺')
# block.fields['紫鸟版本'].set_text_value("V5")
project.save_all(creator.robot_dir)
app_path = os.path.join(output_dir, app_id)
# 导入应用到数据库
print("\n=== 开始导入数据库 ===")
user_dir = ShadowBotPaths.get_first_user_dir()
user_id = os.path.basename(user_dir)
insert_new_app(app_id, user_id, app_name)
return app_id, app_path
except Exception as e:
print(f"\n错误: 创建或导入失败")
print(f"详细信息: {str(e)}")
raise
def create_and_import_app_test(app_name: str, temp_path: str) -> tuple[str, str]:
"""
根据json配置文件创建并导入新的Xbot应用脚手架
"""
try:
output_dir = ShadowBotPaths.get_apps_dir()
app_id = str(uuid.uuid4())
# 1. 创建应用基本结构
creator = XbotAppCreator(output_dir, app_id, app_name)
project = creator.create()
print(f"正在从配置文件创建脚手架: {temp_path}")
with open(temp_path, 'r', encoding='utf-8') as f:
config = json.load(f)
# 3. 添加依赖
if 'dependency' in config:
for dep in config['dependency']:
print(f"添加依赖: {dep}")
project.add_internal_dependency(dep)
# 4. 创建和配置流程
if 'flow' in config:
for flow_data in config['flow']:
flow_name = flow_data['name']
if flow_name == 'main':
flow = project.main
print("配置主流程 (main)...")
else:
if flow_data.get('kind') == 'visual':
flow = project.create_new_flow(flow_name, flow_data.get('memo'))
print(f"创建新可视化流程: {flow_name}")
else:
flow = project.create_code_flow(flow_name, flow_data.get('memo', ''))
print(f"创建新代码流程: {flow_name}")
if 'parameters' in flow_data:
for param in flow_data['parameters']:
if param.get('direction') == 'In':
flow.add_input_parameter(param['name'], param.get('type', 'str'), param.get('value', ''), param.get('description', ''), param.get('kind', 'Text'))
if 'blocks' in flow_data:
for block_data in flow_data['blocks']:
print(f" -> 添加积木块: {block_data['name']}")
block = flow.add_block(block_data['name'])
if 'inputs' in block_data:
for input_name, input_info in block_data['inputs'].items():
value = input_info.get('value')
display = input_info.get('display', '')
if value is None:
continue
value_str = str(value)
if value_str.startswith('10:'):
block.fields[input_name].set_text_value(value_str[3:])
elif value_str.startswith('11:'):
block.fields[input_name].set_expression_value(value_str[3:])
elif value_str.startswith('13:'):
block.fields[input_name].set_text_value(value_str[3:])
elif value_str.startswith('16:'):
block.fields[input_name].set_text_value(value_str[3:])
else:
block.fields[input_name].set_text_value(value_str)
if display:
block.fields[input_name].set_display_value(display)
# **错误修复逻辑**
if 'outputs' in block_data:
for output_name, output_info in block_data['outputs'].items():
if output_info.get('isEnable'):
var_name = output_info.get('name')
if var_name:
# 检查指定的 output_name 是否存在
if output_name in block.fields:
block.variables[output_name].set_name(var_name)
# 如果不存在,并且只有一个输出,尝试使用通用的 'output' 字段
elif len(block_data['outputs']) == 1 and 'output' in block.fields:
print(f" [警告] 字段 '{output_name}' 未找到. 尝试使用通用字段 'output'.")
block.variables['output'].set_name(var_name)
else:
# 如果还是找不到,则打印一个更明确的错误信息
print(f" [错误] 无法为积木块 '{block_data['name']}' 设置输出变量 '{var_name}'. "
f"字段 '{output_name}' 或备用字段 'output' 均不存在。 "
f"可用字段: {list(block.fields.keys())}")
# 5. 保存所有更改
print("\n保存项目所有更改...")
project.save_all(creator.robot_dir)
# 6. 导入应用到数据库
app_path = os.path.join(output_dir, app_id)
print("\n=== 开始导入数据库 ===")
user_dir = ShadowBotPaths.get_first_user_dir()
user_id = os.path.basename(user_dir)
insert_new_app(app_id, user_id, app_name)
return app_id, app_path
except Exception as e:
import traceback
print(f"\n错误: 创建或导入失败")
print(f"详细信息: {str(e)}")
traceback.print_exc()
raise
def create_and_import_app_for_convert(app_name: str) -> tuple[str, str]:
"""创建并导入新的Xbot应用
Returns:
tuple[str, str]: (app_id, app_path)
"""
try:
output_dir = ShadowBotPaths.get_apps_dir()
app_id = str(uuid.uuid4())
# 创建应用
creator = XbotAppCreator(output_dir, app_id, app_name)
project = creator.create()
project.save_all(creator.robot_dir)
app_path = os.path.join(output_dir, app_id)
# 导入应用到数据库
print("\n=== 开始导入数据库 ===")
user_dir = ShadowBotPaths.get_first_user_dir()
user_id = os.path.basename(user_dir)
insert_new_app(app_id, user_id, app_name)
return app_id, app_path
except Exception as e:
print(f"\n错误: 创建或导入失败")
print(f"详细信息: {str(e)}")
raise

View File

@@ -0,0 +1,8 @@
{
"name": "main",
"memo": "测试_jc",
"kind": "visual",
"blocks": [
],
"parameters": []
}

View File

@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<repository xmlns:x="rpa://imageselector/core">
</repository>

View File

@@ -0,0 +1,7 @@
import xbot
import xbot_visual
from . import package
import time
def main(args):
pass

View File

@@ -0,0 +1,13 @@
{
"version": "1",
"name": "浦发-新应用测试11",
"package_version": 2,
"startup": "main",
"flows": [{
"name": "main",
"filename": "main",
"kind": "visual"
}],
"variables": [],
"external_dependencies": []
}

View File

@@ -0,0 +1,49 @@
"""
提供访问应用数据的功能,如获取元素、访问全局变量、获取资源文件等功能
```python
# 获取名称为Button的选择器
package.selector('Button')
# 获取名称为Img的图像选择器
package.image_selector('Img')
# 以文本形式获取名称为names.txt的资源文件
package.resources.get_text('names.txt')
# 以二进制形式获取名称为users.xlsx的资源文件
package.resources.get_bytes('users.xlsx')
# 设置全局变量
package.variables['g_var1'] = 123
# 获取全局变量
package.variables['g_var1']
```
"""
from xbot.selector import SelectorStore, ImageSelectorStore
from xbot.primitives import VariableDict, ResourceReader, _sdmodules
import os
_path = os.path.dirname(__file__)
_sdmodules[_path] = globals()
_selector_store = SelectorStore(_path)
_image_selector_store = ImageSelectorStore(_path)
def selector(name):
"""
从元素库中获取指定名称的选择器
* @param name, 元素名称
* @return `Selector`、`TableSelector`, 返回选择器对象
"""
return _selector_store(name)
def image_selector(name):
"""
从图像库中获取指定名称的图像选择器
* @param name, 元素名称
* @return `ImageSelector`, 返回图像选择器对象
"""
return _image_selector_store(name)
resources = ResourceReader(__loader__, _path)
variables = VariableDict()

View File

@@ -0,0 +1,22 @@
# 如果配置中必填项有一个为空, 以流程代码传递的参数为准
# 如果Config目录下有此配置文件, aocc模块流程参数以配置文件为准
# 流程编号(必填)
Processid: "87df5e45-1a63-4d1a-97b5-baffeab20851"
# 流程名称(必填)
ProcessName: "test - jianxin"
#管理端类型(必填) AA或i-search,默认为 yingdao
Software: "yingdao"
#管理端地址(必填)
CR: "21.64.212.172"
# 机器人名称为空则自动获取用户和机器名拼接机器人名称
RobotName: "uat_test6@yd"
#机器人ip为空则自动获取本机IP地址
Robotip: ""
# AOCC接口开关(必填): 为True表示与AOCC通信,为False表示流程不与AOCC交互,默认为True
Switch: True
#AOCC通信超时重试次数(必填--超时重试):当AOCC接口调用超时,尝试重发多少次,默认为3次
TimeoutRetry: 3
#AOCC通信失败重试次数 (必填--失败重试):当AOCC接口不通时,尝试重发多少次,默认为3次
failedRetry: 3

View File

@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<repository xmlns:x="rpa://selector/core" xmlns:regex="rpa://selector/operator/regex" xmlns:wildcard="rpa://selector/operator/wildcard">
</repository>

248
src/Xbot/XbotFlow.py Normal file
View File

@@ -0,0 +1,248 @@
from abc import abstractmethod
from dataclasses import dataclass, field
from typing import Optional, List, Dict, Any, Union, Literal
import json
import os.path
import re
import enum
import uuid
from Xbot.Blockly.Field import Field
from Xbot.FlowParameter import FieldValueKind, DirectionKind
from Xbot.Blockly import Variable, XbotBlock
class FlowKind(enum.Enum):
VISUAL = "Visual"
CODE = "Code"
class ParameterDirection(str, enum.Enum):
IN = "In"
OUT = "Out"
class ParameterKind(str, enum.Enum):
TEXT = "Text"
EXPRESSION = "Expression"
@dataclass
class FlowParameter:
name: str
direction: str # "In" 或 "Out"
type: str # 数据类型,如 "str", "int", "bool" 等
value: str = "" # 默认值
description: str = ""
kind: str = "Text" # "Text" 或 "Expression"
def to_dict(self) -> Dict[str, Any]:
"""转换为字典表示"""
return {
"name": self.name,
"direction": self.direction,
"type": self.type,
"value": self.value,
"description": self.description,
"kind": self.kind
}
@dataclass
class XbotFlow:
name: str
filename: str
kind: str = "Visual"
opened: bool = False
groupName: Optional[str] = None
memo: Optional[str] = None
blocks: List[XbotBlock] = field(default_factory=list)
parameters: List[FlowParameter] = field(default_factory=list)
dev_dir: Optional[str] = None
local_vars: list[str] = field(default_factory=list)
project = None
block_imports: list[str] = field(default_factory=list)
def load_flow_json(self, project_dir: str) -> None:
"""从flow.json文件加载流程定义
Args:
project_dir: 项目根目录
"""
# 在.dev目录下查找flow.json
dev_dir = os.path.join(project_dir, ".dev")
flow_path = os.path.join(dev_dir, f"{self.filename}.flow.json")
if not os.path.exists(flow_path):
print(f"警告: 流程文件不存在: {flow_path}")
return
with open(flow_path, 'r', encoding='utf-8') as f:
data = json.load(f)
self.memo = data.get('memo', '')
# 加载blocks
self.blocks = []
for block_data in data.get('blocks', []):
block = XbotBlock.from_dict(block_data)
self.blocks.append(block)
# 加载parameters
self.parameters = []
for param_data in data.get('parameters', []):
param = FlowParameter(
name=param_data.get('name', ''),
direction=param_data.get('direction', 'In'),
type=param_data.get('type', 'str'),
value=param_data.get('value', ''),
description=param_data.get('description', ''),
kind=param_data.get('kind', 'Text')
)
self.parameters.append(param)
def add_block(self, block_name: str,
inputs: Dict[str, Field] = None,
outputs: Dict[str, Variable]= None,
is_enabled: bool = True,
block_title: Optional[str] = None) -> XbotBlock:
"""添加新的代码块"""
block = XbotBlock(
id=str(uuid.uuid4()),
name=block_name,
fields=inputs,
variables=outputs,
isEnabled=is_enabled,
block_title=block_title
)
self.blocks.append(block)
return block
def add_parameter(self, name: str, param_type: str = "str",
direction: str = "In", value: str = "",
description: str = "", kind: str = "Text") -> FlowParameter:
"""添加流程参数
Args:
name: 参数名称
param_type: 参数类型,如 "str", "int", "bool"
direction: 参数方向,"In"表示输入参数,"Out"表示输出参数
value: 参数默认值
description: 参数描述
kind: 参数种类,"Text""Expression"
Returns:
FlowParameter: 新添加的参数
"""
param = FlowParameter(
name=name,
direction=DirectionKind(direction),
type=param_type,
value=value,
description=description,
kind=kind
)
self.parameters.append(param)
return param
def add_input_parameter(self, name: str, param_type: str = "str",
value: str = "", description: str = "",
kind: str = "Text") -> FlowParameter:
"""添加输入参数(便捷方法)"""
return self.add_parameter(name, param_type, "In", value, description, kind)
def add_output_parameter(self, name: str, param_type: str = "str",
value: str = "", description: str = "",
kind: str = "Text") -> FlowParameter:
"""添加输出参数(便捷方法)"""
return self.add_parameter(name, param_type, "Out", value, description, kind)
def get_parameter_by_name(self, name: str) -> Optional[FlowParameter]:
"""通过名称获取参数
Args:
name: 参数名称
Returns:
Optional[FlowParameter]: 找到的参数如果不存在则返回None
"""
for param in self.parameters:
if param.name == name:
return param
return None
def add_block_import(self, import_content: str):
for import_line in import_content.split('\n'):
import_line = import_line.strip("\r")
if import_line is not None and len(import_line) > 0:
self.block_imports.append(import_line)
def get_block_import(self) -> list[str]:
return self.block_imports
def get_input_parameters(self) -> List[FlowParameter]:
"""获取所有输入参数"""
return [param for param in self.parameters if param.direction == "In"]
def get_output_parameters(self) -> List[FlowParameter]:
"""获取所有输出参数"""
return [param for param in self.parameters if param.direction == "Out"]
def get_block_by_id(self, block_id: str) -> Optional[XbotBlock]:
"""通过ID获取代码块
Args:
block_id: 块ID
Returns:
Optional[Block]: 找到的代码块如果不存在则返回None
"""
for block in self.blocks:
if block.id == block_id:
return block
return None
def to_dict(self) -> Dict[str, Any]:
"""将流程转换为字典格式"""
return {
'name': self.name,
'filename': self.filename,
'memo': self.memo,
'kind': self.kind.lower(),
'groupName': self.groupName,
}
@abstractmethod
def to_disk(self) -> Dict[str, Any]:
"""转换为保存到磁盘的字典格式"""
pass
def save_flow_json(self, project_dir: str) -> None:
"""保存流程定义到flow.json文件
Args:
project_dir: 项目根目录
"""
dev_dir = os.path.join(project_dir, ".dev")
if not os.path.exists(dev_dir):
os.makedirs(dev_dir, exist_ok=True)
flow_path = os.path.join(dev_dir, f"{self.filename}.flow.json")
print(f"保存流程: {flow_path}")
with open(flow_path, 'w', encoding='utf-8') as f:
json.dump(self.to_disk(), f, indent=2, ensure_ascii=False)
def create_flow(self):
"""创建流程文件"""
if not self.dev_dir:
raise ValueError("dev_dir不能为空")
template = self.to_dict()
flow_file = os.path.join(self.dev_dir, f"{self.filename}.flow.json")
with open(flow_file, "w", encoding="utf-8") as f:
json.dump(template, f, indent=2, ensure_ascii=False)
@classmethod
def create(cls, name: str, filename: str, kind: str, **kwargs):
"""创建合适类型的流程对象"""
if kind.lower() == FlowKind.CODE.value.lower():
from .CodeFlow import CodeFlow
return CodeFlow(name=name, filename=filename, kind=FlowKind.CODE.value, **kwargs)
else:
from .VisualFlow import VisualFlow
return VisualFlow(name=name, filename=filename, kind=FlowKind.VISUAL.value, **kwargs)

405
src/Xbot/XbotProject.py Normal file
View File

@@ -0,0 +1,405 @@
from dataclasses import dataclass, field
from typing import List, Optional, Dict, Any
from enum import Enum
import json
import uuid
import os.path
from .XbotFlow import XbotFlow
from .XbotFlow import FlowKind
class FlowKind(Enum):
VISUAL = "Visual"
CODE = "Code"
@dataclass
class FlowGroup:
name: str
@dataclass
class CustomItems:
gifUrl: Optional[str] = None
videoUrl: str = ""
imageUrl: str = ""
imageName: str = ""
@dataclass
class XbotProject:
name: str
uuid: str = field(default_factory=lambda: str(uuid.uuid4()))
icon: Optional[str] = None
version: str = "1"
tags: str = ""
software: Optional[str] = None
software_title: Optional[str] = None
package_version: int = 2
description: Optional[str] = None
instruction: str = ""
use_latest_pip: bool = False
videoName: str = ""
startup: str = "main"
robot_type: str = "app"
activity_code: Optional[str] = None
main: Optional[XbotFlow] = None # 添加main流程属性
flows: List[XbotFlow] = field(default_factory=list)
flow_groups: List[FlowGroup] = field(default_factory=list) # 修复这行
variables: List[Any] = field(default_factory=list)
external_dependencies: List[str] = field(default_factory=list)
internaldependencies: List[Any] = field(default_factory=list)
selectordependencies: List[Any] = field(default_factory=list)
internalautodependencies: List[Any] = field(default_factory=list)
databook_columns: List[Any] = field(default_factory=list)
authority: str = "use"
internalautoupgrade: bool = False
isbrief: bool = False
uia_type: str = "PC"
persist_databook: bool = False
customItems: CustomItems = field(default_factory=CustomItems)
_project_dir: Optional[str] = None
images: Dict[str, Any] = field(default_factory=dict)
def _post_init(self):
"""初始化后处理"""
if self.main:
self.main.project = self
for flow in self.flows:
flow.project = self
def create_new_flow(
self,
name: str,
filename: str,
kind: str = FlowKind.VISUAL.value,
groupName: Optional[str] = None,
) -> XbotFlow:
"""添加新的流程"""
flow = XbotFlow.create(
name=name, filename=filename, kind=kind, groupName=groupName
)
flow.project = self
if name == "main":
self.main = flow
else:
self.flows.append(flow)
return flow
def add_exist_flow(self, flow: XbotFlow) -> XbotFlow:
"""添加已存在的流程"""
if flow.name == "main":
self.main = flow
else:
self.flows.append(flow)
flow.project = self
return flow
def create_code_flow(
self, name: str, code: str = "", groupName: Optional[str] = None
) -> XbotFlow:
"""创建代码类型流程(便捷方法)"""
flow = self.create_new_flow(
name=name, filename=name, kind=FlowKind.CODE.value, groupName=groupName
)
flow.set_code(code)
return flow
def add_flow_group(self, name: str) -> None:
"""添加新的流程组"""
group = FlowGroup(name=name)
self.flow_groups.append(group)
def add_global_variable(
self,
name: str,
type="any",
value: str = "",
desc: str = "any",
kind: str = "Expression",
) -> None:
"""添加全局变量"""
self.variables.append(
{"name": name, "value": value, "kind": kind, "type": type, "desc": desc}
)
def global_variable_exist(self, name: str) -> bool:
for i in self.variables:
if i['name'] == name:
return True
return False
def add_external_dependency(self, dependency: str) -> None:
"""添加外部依赖"""
if dependency not in self.external_dependencies:
self.external_dependencies.append(dependency)
def add_internal_dependency(self, dependency: str) -> None:
"""添加内部组件依赖
Args:
dependency: 依赖标识符,格式如 'activity_f4d5de04==23.11.1'
"""
if dependency not in self.internaldependencies:
self.internaldependencies.append(dependency)
# 添加自动更新依赖
component_name = dependency.split("==")[0]
if component_name not in self.internalautodependencies:
self.internalautodependencies.append(component_name)
def remove_internal_dependency(self, component_name: str) -> None:
"""移除内部组件依赖
Args:
component_name: 组件名称,如 'activity_f4d5de04'
"""
# 移除指定版本的依赖
self.internaldependencies = [
dep
for dep in self.internaldependencies
if not dep.startswith(component_name + "==")
]
# 移除自动更新依赖
if component_name in self.internalautodependencies:
self.internalautodependencies.remove(component_name)
def get_internal_dependencies(self) -> Dict[str, str]:
"""获取内部组件依赖的版本映射
Returns:
Dict[str, str]: 组件名称到版本号的映射
"""
result = {}
for dep in self.internaldependencies:
if "==" in dep:
name, version = dep.split("==")
result[name] = version
return result
def add_image(self, image_name: str, image_file: str) -> None:
self.images[image_file] = {
"filepath" : fr'resources\images\{image_file}',
"similarity": "85",
"scalingfactor": "1.0",
"adaptive": "True",
"graying": "False",
"sourcetype": "screenshot",
"name": image_name,
'filename': image_file
}
def get_images(self) -> dict[Any]:
return self.images
def project_dir(self) -> str:
return self._project_dir
def to_dict(self) -> dict:
"""将项目配置转换为字典格式"""
flows_data = []
if self.main:
flows_data.append(self.main.to_dict())
flows_data.extend([flow.to_dict() for flow in self.flows])
return {
"uuid": self.uuid,
"name": self.name,
"icon": self.icon,
"version": self.version,
"tags": self.tags,
"software": self.software,
"software_title": self.software_title,
"package_version": self.package_version,
"description": self.description,
"instruction": self.instruction,
"use_latest_pip": self.use_latest_pip,
"videoName": self.videoName,
"startup": self.startup,
"robot_type": self.robot_type,
"activity_code": self.activity_code,
"flows": flows_data,
"flow_groups": [vars(group) for group in self.flow_groups],
"variables": self.variables,
"external_dependencies": self.external_dependencies,
"internaldependencies": self.internaldependencies,
"selectordependencies": self.selectordependencies,
"internalautodependencies": self.internalautodependencies,
"databook_columns": self.databook_columns,
"authority": self.authority,
"internalautoupgrade": self.internalautoupgrade,
"isbrief": self.isbrief,
"uia_type": self.uia_type,
"persist_databook": self.persist_databook,
"customItems": vars(self.customItems),
}
def save(self, filepath: str) -> None:
"""保存项目配置到package.json"""
with open(filepath, "w", encoding="utf-8") as f:
json.dump(self.to_dict(), f, indent=2, ensure_ascii=False)
def save_all(self, project_dir: str) -> None:
"""保存项目所有内容,包括配置文件和所有流程
Args:
project_dir: 项目根目录
"""
# 保存package.json
package_json = os.path.join(project_dir, "package.json")
self.save(package_json)
# 保存所有流程
if self.main:
self.main.save_flow_json(project_dir)
for flow in self.flows:
flow.save_flow_json(project_dir)
# 为全局变量生成初始化代码并保存到package.py
self._save_variables_init_code(project_dir)
self._save_image_v2_file()
def _save_variables_init_code(self, project_dir: str) -> None:
"""生成全局变量初始化代码并保存到package.py文件末尾
Args:
project_dir: 项目根目录
Raises:
FileNotFoundError: 当package.py文件不存在时抛出异常
"""
package_py = os.path.join(project_dir, "package.py")
# 检查package.py文件是否存在
if not os.path.exists(package_py):
raise FileNotFoundError(f"package.py文件不存在: {package_py}")
# 生成变量初始化代码
var_init_lines = []
for var in self.variables:
var_name = var.get("name", "")
var_value = var.get("value", "")
# 根据变量类型格式化值
var_type = var.get("type", "any").lower()
if var_type in ["string", "str"] and not (
var_value.startswith("'") or var_value.startswith('"')
):
# 字符串类型需要加引号
var_value = f"'{var_value}'"
var_init_lines.append(f"variables['{var_name}'] = {var_value}")
# 读取现有文件内容
with open(package_py, "r", encoding="utf-8") as f:
content = f.read()
# 添加变量初始化代码
if var_init_lines:
# 在文件末尾添加变量初始化代码
content += "\n\n# 全局变量初始化\n"
for line in var_init_lines:
content += f"{line}\n"
# 写回文件
with open(package_py, "w", encoding="utf-8") as f:
f.write(content)
print(f"已将 {len(var_init_lines)} 个全局变量的初始化代码添加到 package.py")
@classmethod
def load(cls, project_dir: str) -> "XbotProject":
"""从项目目录加载 XBot 项目配置"""
package_json = os.path.join(project_dir, "package.json")
if not os.path.exists(package_json):
raise FileNotFoundError(f"项目配置文件不存在: {package_json}")
try:
with open(package_json, "r", encoding="utf-8") as f:
data = json.load(f)
# 确保必需的字段存在
if "name" not in data:
raise ValueError("项目配置缺少必需的name字段")
# 修改流程加载逻辑
flows = []
main_flow = None
for flow_data in data.pop("flows", []):
kind = flow_data.get("kind", FlowKind.VISUAL.value)
flow = XbotFlow.create(**flow_data)
flow.load_flow_json(project_dir)
if flow.name == "main":
main_flow = flow
else:
flows.append(flow)
flow_groups = [
FlowGroup(**group) for group in data.pop("flow_groups", [])
]
custom_items = CustomItems(**data.pop("customItems", {}))
# 创建项目实例
project = cls(
name=data.pop("name"),
flows=flows,
main=main_flow, # 设置main流程
flow_groups=flow_groups,
customItems=custom_items,
**data,
)
project._project_dir = project_dir
print(f"已加载项目 '{project.name}' (UUID: {project.uuid})")
print(f"包含主流程: {project.main.name if project.main else 'None'}")
print(f"包含 {len(project.flows)} 个子流程:")
for flow in project.flows:
print(
f" - {flow.name} ({flow.kind})"
+ (f" [组: {flow.groupName}]" if flow.groupName else "")
)
return project
except json.JSONDecodeError as e:
raise ValueError(f"项目配置文件格式错误: {e}")
except Exception as e:
raise RuntimeError(f"加载项目失败: {e}")
def _save_image_v2_file(self):
image_v2_path = os.path.join(self._project_dir, "imagesV2.xml")
image_content = []
image_content.append('<?xml version="1.0" encoding="utf-8"?>')
image_content.append('<repository xmlns:x="rpa://imageselector/core">')
image_content.append(' <group name="默认分组">')
for image in self.images.values():
image_name = image["name"]
image_path = image["filepath"]
image_similarity = image["similarity"]
image_content.append(f' <imageelement name="{image_name}" sourcetype="screenshot" filepath="{image_path}" similarity="{image_similarity}" scalingfactor="2.25" adaptive="True" graying="False" />')
image_content.append(' </group>')
image_content.append('</repository>')
with open(image_v2_path, 'w', encoding='utf-8') as f:
f.write("\n".join(image_content))
pass
def get_image_name(self, image_file_name: str) -> str:
if image_file_name in self.images:
return self.images[image_file_name]['name']
return ""
def set_image_fuzzy(self, image_file_name: str, fuzzy: str) -> None:
'''设置相似度'''
try:
if image_file_name in self.images:
self.images[image_file_name]['similarity'] = int(float(fuzzy) * 100)
except Exception as e:
pass

5
src/Xbot/__init__.py Normal file
View File

@@ -0,0 +1,5 @@
from .XbotProject import XbotProject
from .XbotFlow import XbotFlow
from .Blockly.XbotBlock import XbotBlock
__all__ = ['XbotProject', 'XbotFlow', 'XbotBlock', 'ValueRef', 'BlockInput']

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

33
src/Xbot/bot_import.py Normal file
View File

@@ -0,0 +1,33 @@
import os
import sqlite3
import uuid
#TODO(huifu): 演示的用用户ID
USER_ID = "757424674936492032"
def get_xbot_user_app_dir(user_id):
local_app_data = os.environ.get('LOCALAPPDATA')
return os.path.join(local_app_data, "ShadowBot", "users", user_id)
def insert_new_app(app_id, user_id, app_name):
user_db_file = get_xbot_db_file(user_id)
conn = sqlite3.connect(user_db_file)
cursor = conn.cursor()
cursor.execute('INSERT INTO developmentsync_apps_v2 (uuid, name, robotType, isSynchronized) VALUES (?,?,?,?)', (app_id, app_name, "app", 0))
conn.commit()
conn.close()
def get_xbot_db_file(user_id):
user_db_file = os.path.join(get_xbot_user_app_dir(user_id), "user.db3")
if not os.path.exists(user_db_file):
raise RuntimeError(f"can not file shadow bot db file: {user_db_file}")
return user_db_file
if __name__ == "__main__":
uuid_str = str(uuid.uuid4())
print(f"start insert app : {uuid_str}")
insert_new_app(str(uuid.uuid4()), USER_ID, f"test-{uuid_str}")

View File

@@ -0,0 +1,77 @@
{
"types": [],
"blocks": [
{
"name": "asset.get_asset",
"title": "获取资产",
"icon": "BlockIcons/36-1.png",
"comment": "获取%asset_name%的资产值",
"description": "获取资产信息",
"function": "xbot_visual.asset.get_asset",
"settingsControl": "ShadowBot.Shell.Console.BlockSettings.Controls.Asset.GetAssetControl, ShadowBot.Shell.Console",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/获取资产.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Asset.GetAssetHandler"
}
],
"inputs": [
{
"name": "asset_name",
"label": "资产名称",
"required": true,
"tips": "",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "asset_type",
"label": "资产类型",
"required": true,
"tips": "",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "encrypt_flag",
"label": "资产值加密标志",
"tips": "",
"type": "str",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "value",
"label": "保存普通资产值至",
"variableLabel": "资产值",
"tips": "输入一个变量用来保存普通资产的资产值",
"name": "value",
"type": "str"
},
{
"id": "user_name",
"label": "保存凭证资产用户名至",
"variableLabel": "凭证用户名",
"tips": "输入一个变量用来保存凭证资产的用户名",
"name": "user_name",
"type": "str"
},
{
"id": "password",
"label": "保存凭证资产密码至",
"variableLabel": "凭证密码",
"tips": "输入一个变量用来保存凭证资产的密码,获取的凭证资产密码为加密文本,会在使用填写密码框指令时被自动解密",
"name": "password",
"type": "str"
}
]
}
]
}

View File

@@ -0,0 +1,101 @@
{
"types": [],
"blocks": [
{
"name": "base64.encode",
"function": "xbot_visual.base64.encode",
"title": "Base64编码",
"description": "Base64编码",
"comment": "Base64编码%source%,将编码结果保存到%base64_encode_result%",
"icon": "BlockIcons/15-1.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/base64编解码/base64编码.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Base64.EncodeHandler"
}
],
"inputs": [
{
"name": "source",
"label": "内容",
"required": true,
"tips": "输入待编码的内容",
"type": "any",
"editor": {
"kind": "memoedit"
}
},
{
"name": "output_string",
"label": "",
"required": true,
"tips": "输出字符串",
"type": "bool",
"default": "13:True",
"editor": {
"label": "输出字符串",
"kind": "checkbox"
}
}
],
"outputs": [
{
"id": "base64_encode_result",
"label": "保存编码结果至",
"variableLabel": "Base64编码结果",
"tips": "输入一个名字用来保存Base64编码结果",
"type": "any",
"name": "base64_encode_result"
}
]
},
{
"name": "base64.decode",
"function": "xbot_visual.base64.decode",
"title": "Base64解码",
"description": "Base64解码",
"comment": "Base64解码%source%,将解码结果保存到%base64_decode_result%",
"icon": "BlockIcons/15-2.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/base64编解码/base64解码.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Base64.DecodeHandler"
}
],
"inputs": [
{
"name": "source",
"label": "待解码内容",
"required": true,
"tips": "输入待解码的内容",
"type": "any",
"editor": {
"kind": "memoedit"
}
},
{
"name": "output_string",
"label": "",
"required": true,
"tips": "输出字符串",
"type": "bool",
"default": "13:True",
"editor": {
"label": "输出字符串",
"kind": "checkbox"
}
}
],
"outputs": [
{
"id": "base64_decode_result",
"label": "保存解码结果至",
"variableLabel": "base64解码结果",
"tips": "输入一个名字用来保存base64解码结果",
"type": "any",
"name": "base64_decode_result"
}
]
}
]
}

View File

@@ -0,0 +1,142 @@
[
{
"name": "any",
"localName": "任意类型",
"group_order": "6"
},
{
"name": "int",
"localName": "整数",
"pythonName": "int",
"group": "Common",
"group_order": "2",
"methods": [
{
"display": "转字符串",
"function": "str($0)",
"type": "str"
}
]
},
{
"name": "float",
"localName": "小数",
"pythonName": "float",
"group_order": "7",
"methods": [
{
"display": "转字符串",
"function": "str($0)",
"type": "str"
},
{
"display": "取整数部分",
"function": "int($0)",
"type": "int"
}
]
},
{
"name": "bool",
"localName": "布尔值",
"pythonName": "bool",
"group": "Common",
"group_order": "3"
},
{
"name": "str",
"localName": "字符串",
"pythonName": "str",
"group": "Common",
"group_order": "1",
"methods": [
{
"display": "删除两端空格",
"function": "$0.strip()",
"type": "str"
},
{
"display": "转数字(整数)",
"function": "int($0)",
"type": "int"
},
{
"display": "转数字(小数)",
"function": "float($0)",
"type": "float"
}
]
},
{
"name": "list",
"localName": "列表",
"pythonName": "list,set,tuple",
"group": "Common",
"group_order": "4",
"methods": [
{
"display": "列表第$1项",
"function": "$0[--$1]",
"type": "any",
"params": [
{
"name": "$1",
"default": "1"
}
],
"editor": "spin"
},
{
"display": "列表倒数第$1项",
"function": "$0[-$1]",
"type": "any",
"params": [
{
"name": "$1",
"default": "1"
}
],
"editor": "spin"
},
{
"display": "列表长度",
"function": "len($0)",
"type": "int"
}
]
},
{
"name": "dict",
"localName": "字典",
"group": "Common",
"pythonName": "dict",
"group_order": "5"
},
{
"name": "file",
"localName": "文件路径",
"pythonName": "str"
},
{
"name": "directory",
"localName": "文件夹路径",
"pythonName": "str"
},
{
"name": "bytes",
"localName": "二进制数据",
"pythonName": "bytes",
"methods": [
{
"display": "转字符串",
"function": "str($0)",
"type": "str"
}
]
},
{
"name": "datetime",
"localName": "日期时间",
"pythonName": "datetime.datetime"
}
]

View File

@@ -0,0 +1,212 @@
{
"types": [],
"blocks": [
{
"name": "chatgpt.completions",
"icon": "BlockIcons/23-8.png",
"description": "可通过自然语言对话让AI完成原创写作、检查纠错、客服对话、翻译等任务",
"comment": "通过%ai_engine%GPT引擎提问内容%question%,将结果保存到%chatgpt_result%",
"title": "影刀GPT",
"keywords": "Chat",
"function": "xbot_visual.chatgpt.completions",
"helpUrl": "yddoc/language/zh-cn/指令文档/人工智能ai/chatgpt.html",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.ChatGPT.ChatGPTControl, ShadowBot.Shell.Development",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.ChatGPT.ChatGPTHandler"
}
],
"inputs": [
{
"name": "ai_engine",
"label": "AI引擎",
"required": true,
"tips": "选择AI引擎类型",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "影刀",
"value": "shadowbot"
}
]
}
},
{
"name": "model",
"label": "模型",
"required": false,
"tips": "调用的AI模型版本请仔细确认价格后切换",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "影刀GPT-3.5",
"value": "gpt35_turbo"
},
{
"display": "影刀GPT-4.0",
"value": "gpt-4"
}
]
}
},
{
"name": "use_knowledge",
"label": "扩展能力",
"required": false,
"tips": "选择知识库让GPT生成更懂业务的回答",
"type": "bool",
"default": "13:False",
"editor": {
"kind": "checkbox",
"label": "知识库"
}
},
{
"name": "knowledge",
"label": "知识库",
"required": false,
"tips": "选择知识库让GPT生成更懂业务的回答",
"type": "str",
"editor": {
"kind": "select"
}
},
{
"name": "prompt",
"label": "角色定义",
"tips": "定义GPT的角色和回答要求。如扮演影刀客服回答要专业",
"type": "str",
"required": false,
"editor": {
"kind": "textbox",
"placeholder": "选填,定义角色与回答要求"
}
},
{
"name": "question",
"label": "提问",
"tips": "最多可输入1600字请勿包含敏感词",
"type": "str",
"required": true,
"editor": {
"kind": "textbox",
"placeholder": "最多可输入1600字请勿包含敏感词"
}
},
{
"name": "maxWords",
"label": "最大回答字数",
"required": false,
"category": "advanced",
"tips": "默认值为 -1代表不限制",
"type": "int",
"editor": {
"kind": "textbox",
"placeholder": "选填,默认不限制"
}
},
{
"name": "temperature",
"label": "创意性参数",
"required": false,
"category": "advanced",
"tips": "在0-2之间值越高越有创意性",
"type": "int",
"editor": {
"kind": "textbox",
"placeholder": "选填范围0-2默认为1值越高越有创意性"
}
}
],
"outputs": [
{
"id": "chatgpt_result",
"label": "返回结果保存至",
"variableLabel": "gpt文本",
"tips": "指定一个变量,该变量用于保存返回的文本",
"type": "str",
"name": "gpt_result"
}
]
},
{
"name": "dynamic.magic",
"icon": "Png/Magic/icon_magicaction2.png",
"statement": "programing.empty",
"description": "通过文字描述生成处理类指令,包括列表、文本、时间日期、逻辑等",
"comment": "",
"title": "魔法指令",
"function": "",
"helpUrl": "yddoc/language/zh-cn/指令文档/魔法指令/魔法指令说明.html",
"inputs": [],
"outputs": [],
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Magic.MagicHandler"
}
]
},
{
"name": "ai.power",
"statement": "ai.power",
"icon": "BlockIcons/ai_power.png",
"description": "在影刀中调用并执行AI Power应用增强AI自动化的场景与能力",
"comment": "执行AI应用%flowId%,将结果保存到%ai_power_result%",
"title": "AI应用",
"keywords": "",
"function": "xbot_visual.chatgpt.ai_power",
"helpUrl": "yddoc/language/zh-cn/指令文档/人工智能AI/AI应用.html",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.AIPower.AIPowerControl, ShadowBot.Shell.Development",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.AIPower.AIPowerBlockHandler"
}
],
"inputs": [
{
"name": "flowId",
"label": "选择应用",
"required": true,
"tips": "从“我的AI应用”列表中选择一个应用",
"type": "str",
"editor": {
"kind": "select"
}
},
{
"name": "inputs",
"label": "输入参数",
"required": false,
"tips": "输入参数列表",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "outputs",
"label": "输出参数",
"required": false,
"tips": "输出参数列表",
"type": "str",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "ai_power_result",
"label": "输出结果保存至",
"tips": "",
"name": "ai_power_result",
"type": "dict"
}
]
}
]
}

View File

@@ -0,0 +1,83 @@
{
"types": [],
"blocks": [
{
"name": "clipboard.get_text",
"function": "xbot_visual.win32.clipboard_get_text",
"title": "获取剪切板文本",
"keywords": "剪贴板",
"description": "这个指令用来获取剪切板文本内容",
"comment": "获取剪切板中的文本内容,将结果保存到%clipboard_text%",
"icon": "BlockIcons/24-2.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/剪切板/获取剪切板内容.html",
"outputs": [
{
"id": "clipboard_text",
"label": "保存剪切板文本至",
"variableLabel": "剪切板文本",
"tips": "获取剪切板中文本内容",
"type": "str",
"name": "clipboard_text"
}
]
},
{
"name": "clipboard.set_text",
"function": "xbot_visual.win32.clipboard_set_text",
"title": "设置剪切板内容",
"keywords": "剪贴板",
"description": "这个指令用来设置剪切板内容",
"comment": "将内容源%text%设置到剪切板中",
"icon": "BlockIcons/24-1.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/剪切板/设置剪切板内容.html",
"inputs": [
{
"name": "text",
"label": "内容源",
"required": true,
"tips": "请输入要设置到剪切板中的文本内容",
"type": "str",
"editor": {
"kind": "memoedit"
}
}
]
},
{
"name": "clipboard.clear",
"function": "xbot_visual.win32.clipboard_clear",
"title": "清空剪切板",
"keywords": "剪贴板",
"description": "这个指令用来清空剪切板内容",
"comment": "清空当前剪切板中的内容",
"icon": "BlockIcons/24-3.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/剪切板/清空剪切板.html"
},
{
"name": "clipboard.set_file",
"function": "xbot_visual.win32.clipboard_set_file",
"title": "将文件添加到剪切板",
"keywords": "剪贴板",
"description": "这个指令用来将文件添加到剪切板中,可用于文件的快捷发送",
"comment": "将文件%file_path%添加到剪切板中",
"icon": "BlockIcons/24-1.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/剪切板/将文件添加到剪切板.html",
"inputs": [
{
"name": "file_path",
"label": "文件路径",
"required": true,
"tips": "请输入资源文件名或文件名列表",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "OpenFile",
"filter": "所有文件(.*)|*.*"
}
}
}
]
}
]
}

View File

@@ -0,0 +1,13 @@
# 使用提醒:
# 1. xbot包提供软件自动化、数据表格、Excel、日志、AI等功能
# 2. package包提供访问当前应用数据的功能如获取元素、访问全局变量、获取资源文件等功能
# 3. 当此模块作为流程独立运行时执行main函数
# 4. 可视化流程中可以通过"调用模块"的指令使用此模块
import xbot
from xbot import print, sleep
from .import package
from .package import variables as glv
def main(args):
pass

View File

@@ -0,0 +1,176 @@
{
"types": [],
"blocks": [
{
"name": "csv.read",
"function": "xbot_visual.csv.read",
"title": "读取CSV数据",
"description": "读取CSV数据",
"comment": "读取%csv_path%文件,并将读取结果保存到%row_values%",
"icon": "BlockIcons/29-1.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/csv读写/读取csv数据.html",
"inputs": [
{
"name": "csv_path",
"label": "CSV文件路径",
"required": true,
"tips": "输入CSV文件路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "OpenFile",
"filter": "CSV文件 (.csv)|*.csv"
}
}
},
{
"name": "encoding",
"label": "文件编码",
"required": true,
"default": "10:UTF-8",
"defaultDisplay": "UTF-8",
"tips": "选择文本编码格式UTF-8-SIG为带有 BOM 的 UTF-8",
"type": "str",
"editor": {
"kind": "editselect",
"options": [
"ANSI",
"UTF-8",
"UTF-8-SIG"
]
}
},
{
"name": "delimiter",
"label": "内容分隔符",
"required": false,
"tips": "选择内容分隔符,默认为逗号",
"type": "str",
"defaultDisplay": "逗号",
"editor": {
"kind": "select",
"options": [
{
"display": "逗号",
"value": ","
},
{
"display": "分号",
"value": ";"
},
{
"display": "冒号",
"value": ":"
},
{
"display": "空格",
"value": " "
},
{
"display": "Tab键",
"value": "\t"
}
]
}
},
{
"name": "first_row_is_header",
"label": "",
"required": true,
"tips": "CSV文件首行是否是列头",
"type": "bool",
"default": "13:False",
"editor": {
"label": "首行是列头",
"kind": "checkbox"
}
}
],
"outputs": [
{
"id": "row_values",
"label": "保存行数据至",
"variableLabel": "CSV数据",
"tips": "输入一个名字,用来保存读取的行数据",
"type": "list<list<str>>",
"name": "row_values"
}
]
},
{
"name": "csv.write",
"function": "xbot_visual.csv.write",
"title": "数据写入CSV",
"description": "数据写入CSV",
"comment": "将%values%通过%write_way%方式写入到%csv_path%",
"icon": "BlockIcons/29-2.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/csv读写/数据写入csv.html",
"inputs": [
{
"name": "csv_path",
"label": "CSV文件路径",
"required": true,
"tips": "输入CSV文件路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "OpenFile",
"filter": "CSV文件 (.csv)|*.csv"
}
}
},
{
"name": "encoding",
"label": "文件编码",
"required": true,
"default": "10:UTF-8",
"defaultDisplay": "UTF-8",
"tips": "选择文本编码格式",
"type": "str",
"editor": {
"kind": "editselect",
"options": [
"ANSI",
"UTF-8",
"UTF-8-SIG"
]
}
},
{
"name": "write_way",
"label": "写入方式",
"required": true,
"default": "10:overwrite",
"defaultDisplay": "覆盖写入",
"tips": "选择写入方式",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "追加写入",
"value": "append"
},
{
"display": "覆盖写入",
"value": "overwrite"
}
]
}
},
{
"name": "values",
"label": "行数据",
"required": true,
"tips": "输入待写入CSV文件的行数据",
"type": "list<list<any>>",
"editor": {
"kind": "textbox"
}
}
]
}
]
}

View File

@@ -0,0 +1,250 @@
{
"types": [
{
"name": "xbot.database",
"localName": "数据库连接",
"pythonName": "xbot.ado.Database",
"props": []
}
],
"blocks": [
{
"name": "database.connect",
"icon": "BlockIcons/25-1.png",
"description": "使用数据库连接字符串连接到数据库",
"comment": "使用%conn_str%数据库连接字符串创建数据库连接对象,并保存到%database%",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Database.ConnectControl, ShadowBot.Shell.Development",
"title": "连接数据库",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/数据库/连接数据库.html",
"function": "xbot_visual.database.connect",
"inputs": [
{
"name": "conn_str",
"label": "连接字符串",
"required": true,
"tips": "输入数据库连接字符串",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "Custom"
}
}
}
],
"outputs": [
{
"id": "database",
"label": "保存数据库连接对象至",
"variableLabel": "数据库连接",
"tips": "指定一个变量名称,该变量用于存储数据库连接对象",
"type": "xbot.database",
"name": "database"
}
]
},
{
"name": "database.close",
"icon": "BlockIcons/25-3.png",
"description": "关闭数据库",
"comment": "关闭数据库连接%database%",
"title": "关闭数据库",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/数据库/关闭数据库.html",
"function": "xbot_visual.database.close",
"inputs": [
{
"name": "database",
"label": "数据库连接对象",
"required": true,
"tips": "输入数据库连接对象",
"type": "xbot.database",
"editor": {
"kind": "select",
"useVariableOptions": true
}
}
]
},
{
"name": "database.exec",
"icon": "BlockIcons/25-2.png",
"description": "在指定数据库中执行Insert、Update、Delete、Select等SQL语句",
"comment": "在%database%中执行SQL%sql%,结果保存到%recordset%",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Database.ExecControl, ShadowBot.Shell.Development",
"title": "执行SQL语句",
"keywords": "查询;修改;删除;插入;Insert;Update;Delete;Select",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/数据库/查询数据库.html",
"function": "xbot_visual.database.exec",
"inputs": [
{
"name": "connect_way",
"label": "连接方式",
"required": true,
"default": "10:database",
"defaultDisplay": "数据库连接对象",
"tips": "选择一个数据库连接方式",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "数据库连接对象",
"value": "database"
},
{
"display": "数据库连接字符串",
"value": "conn_str"
}
]
}
},
{
"name": "database",
"label": "数据库连接对象",
"required": false,
"tips": "选择数据库连接对象",
"type": "xbot.database",
"editor": {
"kind": "select",
"useVariableOptions": true
}
},
{
"name": "conn_str",
"label": "数据库连接字符串",
"required": false,
"tips": "请输入数据库连接字符串",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "Custom"
}
}
},
{
"name": "sql",
"label": "数据库查询语句",
"required": true,
"tips": "请输入数据库查询语句",
"type": "str",
"editor": {
"kind": "memoedit"
}
},
{
"name": "timeout_seconds",
"label": "超时秒数",
"required": true,
"tips": "请输入数据库查询超时秒数",
"type": "int",
"default": "10:30",
"editor": {
"kind": "textbox"
}
},
{
"name": "result_toString",
"label": "",
"category": "advanced",
"type": "bool",
"tips": "若勾选,查询结果的每一个值会转成文本格式输出,否则保留原格式输出",
"default": "13:True",
"editor": {
"label": "以文本格式输出",
"kind": "checkbox"
}
}
],
"outputs": [
{
"id": "recordset",
"label": "保存查询结果至",
"variableLabel": "数据库查询结果",
"tips": "指定一个变量名称,该变量用于存储数据库查询结果",
"type": "list<list<str>>",
"name": "recordset"
}
]
},
{
"name": "database.batch_insert",
"icon": "BlockIcons/25-4.png",
"description": "将多组数据一次性插入到一张表中,结果为全部正确或全部失败",
"comment": "在%database%中执行批量插入%sql%",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Database.BatchInsertControl, ShadowBot.Shell.Development",
"title": "数据库批量插入数据",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/数据库/数据库批量插入数据.html",
"function": "xbot_visual.database.batch_insert",
"inputs": [
{
"name": "connect_way",
"label": "连接方式",
"required": true,
"default": "10:database",
"defaultDisplay": "数据库连接对象",
"tips": "选择一个数据库连接方式",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "数据库连接对象",
"value": "database"
},
{
"display": "数据库连接字符串",
"value": "conn_str"
}
]
}
},
{
"name": "database",
"label": "数据库连接对象",
"required": false,
"tips": "选择数据库连接对象",
"type": "xbot.database",
"editor": {
"kind": "select",
"useVariableOptions": true
}
},
{
"name": "conn_str",
"label": "数据库连接字符串",
"required": false,
"tips": "请输入数据库连接字符串",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "Custom"
}
}
},
{
"name": "sql",
"label": "数据库插入语句",
"required": true,
"tips": "请输入数据库插入语句",
"type": "str",
"editor": {
"kind": "memoedit",
"placeholder": "例INSERT INTO `test` 或 INSERT INTO `test` (`id`, `name`)"
}
},
{
"name": "data",
"label": "待插入数据",
"required": true,
"tips": "请输入需要批量插入的数据,格式为二维列表",
"type": "str",
"editor": {
"kind": "textbox"
}
}
]
}
]
}

View File

@@ -0,0 +1,583 @@
{
"types": [
{
"name": "xbot_visual.datetime.DateTimeParts",
"localName": "日期时间详情",
"props": [
{
"name": "year",
"type": "int",
"label": "年份"
},
{
"name": "month",
"type": "int",
"label": "月份"
},
{
"name": "day",
"type": "int",
"label": "天数"
},
{
"name": "hour",
"type": "int",
"label": "小时"
},
{
"name": "minute",
"type": "int",
"label": "分钟"
},
{
"name": "second",
"type": "int",
"label": "秒数"
},
{
"name": "weekday",
"type": "int",
"label": "星期"
},
{
"name": "lastday_of_month",
"type": "int",
"label": "当月最后一天"
},
{
"name": "week_of_year",
"type": "int",
"label": "当年第几周"
},
{
"name": "day_of_year",
"type": "int",
"label": "当年第几天"
}
]
}
],
"blocks": [
{
"name": "datetime.now",
"function": "xbot_visual.datetime.now",
"title": "获取当前日期时间",
"description": "获取当前日期时间",
"comment": "获取当前日期时间,将结果保存到%datetime_instance%",
"icon": "BlockIcons/17-4.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/日期时间/获取当前时间.html",
"outputs": [
{
"id": "datetime_instance",
"label": "保存当前日期时间至",
"variableLabel": "当前的日期时间对象",
"tips": "输入一个变量,用来保存当前日期时间",
"type": "datetime",
"name": "current_datetime"
}
]
},
{
"name": "datetime.difference",
"function": "xbot_visual.datetime.difference",
"title": "获取时间间隔",
"description": "获取时间间隔",
"comment": "获取%begin_datetime%到%end_datetime%间隔的%unit%数,将结果保存至%datetime_difference%",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Datetime.DifferenceHandler"
}
],
"icon": "BlockIcons/17-5.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/日期时间/获取时间间隔.html",
"inputs": [
{
"name": "begin_datetime",
"label": "开始时间",
"required": false,
"tips": "输入开始时间。若日期是文本只支持常用格式2020-02-02、2020/02/02 02:02:02、2020年2月2日 2时2分2秒等",
"type": "any",
"editor": {
"kind": "textbox",
"placeholder": "日期时间对象或文本。若空,则为系统的当前时间"
}
},
{
"name": "end_datetime",
"label": "结束时间",
"required": false,
"tips": "输入结束时间。若日期是文本只支持常用格式2020-02-02、2020/02/02 02:02:02、2020年2月2日 2时2分2秒等",
"type": "datetime",
"editor": {
"kind": "textbox",
"placeholder": "日期时间对象或文本。若空,则为系统的当前时间"
}
},
{
"name": "unit",
"label": "时间间隔单位",
"required": true,
"default": "10:second",
"defaultDisplay": "秒",
"tips": "选择时间间隔的时间单位",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "秒",
"value": "second"
},
{
"display": "分钟",
"value": "minute"
},
{
"display": "小时",
"value": "hour"
},
{
"display": "天",
"value": "day"
}
]
}
}
],
"outputs": [
{
"id": "datetime_difference",
"label": "保存时间间隔至",
"variableLabel": "时间间隔",
"tips": "输入一个变量,用来保存时间间隔",
"type": "int",
"name": "datetime_difference"
}
]
},
{
"name": "datetime.add",
"function": "xbot_visual.datetime.add",
"title": "增加/减少时间",
"description": "在指定日期时间上进行时间增加或者减少,支持文本格式的日期",
"comment": "将%datetime%%timeway%%duration%%unit%,将结果保存到%datetime_instance%",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Datetime.AddControl, ShadowBot.Shell.Development",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Datetime.AddHandler"
}
],
"icon": "BlockIcons/17-3.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/日期时间/增加时间.html",
"inputs": [
{
"name": "datetime",
"label": "原日期时间",
"required": false,
"tips": "输入日期时间。若日期是文本,只支持常用格式,如: 2020-02-02、2020/02/02 02:02:02、2020年2月2日 2时2分2秒等",
"type": "any",
"editor": {
"kind": "textbox",
"placeholder": "日期时间对象或文本。若空,为系统的当前时间"
}
},
{
"name": "timeway",
"label": "调整方式",
"required": true,
"default": "10:increase",
"defaultDisplay": "增加",
"tips": "选择增加时间或者减少时间",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "增加",
"value": "increase"
},
{
"display": "减少",
"value": "decrease"
}
]
}
},
{
"name": "duration",
"label": "时间长度",
"required": true,
"tips": "输入时间长度",
"type": "int",
"editor": {
"kind": "textbox"
}
},
{
"name": "unit",
"label": "时间单位",
"required": true,
"default": "10:second",
"defaultDisplay": "秒",
"tips": "选择时间单位",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "秒",
"value": "second"
},
{
"display": "分钟",
"value": "minute"
},
{
"display": "小时",
"value": "hour"
},
{
"display": "天",
"value": "day"
},
{
"display": "月",
"value": "month"
},
{
"display": "年",
"value": "year"
}
]
}
},
{
"name": "output_text",
"label": "",
"required": false,
"default": "13:False",
"tips": "若勾选,指明该指令的输出为新日期的文本格式,否则为日期时间对象",
"type": "bool",
"editor": {
"label": "输出日期时间的文本",
"kind": "checkbox"
}
}
],
"outputs": [
{
"id": "datetime_instance",
"label": "保存新的日期时间至",
"variableLabel": "更改时间后的日期时间对象",
"tips": "输入一个名字,用来保存更改后的日期时间",
"type": "datetime",
"name": "datetime_instance"
},
{
"id": "datetime_text",
"label": "保存新的日期文本至",
"variableLabel": "更改时间后的日期时间文本",
"tips": "输入一个名字,用来保存更改后的日期时间的文本",
"type": "str",
"name": "datetime_text"
}
]
},
{
"name": "datetime.from_string",
"function": "xbot_visual.datetime.from_string",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Datetime.FromStringControl, ShadowBot.Shell.Development",
"title": "转换到日期时间",
"keywords": "文本转换",
"description": "将文本转换成日期时间,默认采用%Y-%m-%d的时间格式",
"comment": "将%text%按%format%格式转换成日期时间,并将结果保存到%datetime_instance%",
"icon": "BlockIcons/17-2.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/日期时间/转换到日期时间.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Datetime.FromStringHandler"
}
],
"inputs": [
{
"name": "text",
"label": "文本",
"required": true,
"tips": "输入待转换到日期时间的文本",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "is_custom_format",
"label": "",
"required": true,
"tips": "是否使用自定义格式",
"type": "bool",
"default": "13:False",
"editor": {
"label": "使用自定义格式",
"kind": "checkbox"
}
},
{
"name": "format",
"label": "时间格式",
"required": false,
"tips": "设置待转换文本的日期时间格式。自定义的时间格式请参考Python日期时间相关文档。",
"type": "str",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "datetime_instance",
"label": "保存日期时间至",
"variableLabel": "文本转换后的日期时间对象",
"tips": "输入一个名字,用来保存转换后的日期时间",
"type": "datetime",
"name": "datetime_instance"
}
]
},
{
"name": "datetime.to_string",
"function": "xbot_visual.datetime.to_string",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Datetime.ToStringControl, ShadowBot.Shell.Development",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Datetime.ToStringHandler"
}
],
"title": "日期时间转换为文本",
"keywords": "星期;格式化",
"description": "将日期时间转换到文本",
"comment": "将%datetime%按%format%格式转换成文本,将结果保存到%text%",
"icon": "BlockIcons/17-1.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/日期时间/时间转换到文本.html",
"inputs": [
{
"name": "datetime",
"label": "日期时间",
"required": false,
"tips": "输入待转换日期。若日期是文本,只支持常用格式,如: 2020-02-02、2020/02/02 02:02:02、2020年2月2日 2时2分2秒等",
"type": "any",
"editor": {
"kind": "textbox",
"placeholder": "日期时间对象或文本。若空,为系统的当前时间"
}
},
{
"name": "format",
"label": "时间格式",
"required": true,
"tips": "设置待转换文本的日期时间格式。自定义的时间格式请参考Python日期时间相关文档。",
"type": "str",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "text",
"label": "保存文本至",
"variableLabel": "日期时间转换后的文本",
"tips": "输入一个名字,用来保存转换后的文本",
"type": "str",
"name": "text"
}
]
},
{
"name": "datetime.get_parts",
"function": "xbot_visual.datetime.get_parts",
"title": "获取时间详细信息",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Datetime.DetailHandler"
}
],
"keywords": "日期时间;年月日时分秒;星期;当月最后一天;当年第几周;当年第几天",
"description": "获取日期时间的年、月、日、时、分、秒、星期、当月最后一天、当年第几周、当年第几天",
"comment": "获取%datetime%的时间详细信息,将结果保存到%datetime_parts%",
"icon": "BlockIcons/17-6.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/日期时间/获取时间详细信息.html",
"inputs": [
{
"name": "datetime",
"label": "日期时间",
"required": false,
"tips": "输入日期时间。若日期是文本,只支持常用格式,如: 2020-02-02、2020/02/02 02:02:02、2020年2月2日 2时2分2秒等",
"type": "any",
"editor": {
"kind": "textbox",
"placeholder": "日期时间对象或文本。若空,为系统的当前时间"
}
}
],
"outputs": [
{
"id": "datetime_parts",
"label": "保存日期时间数据至",
"variableLabel": "时间的详情数据",
"tips": "输入一个名字,用来保存获得的年月日时分秒数据",
"required": true,
"type": "xbot_visual.datetime.DateTimeParts",
"name": "datetime_parts"
}
]
},
{
"name": "datetime.to_timestamp",
"function": "xbot_visual.datetime.to_timestamp",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Datetime.ToTimestampControl, ShadowBot.Shell.Development",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Datetime.ToTimestampHandler"
}
],
"title": "日期时间转换为时间戳",
"keywords": "星期;格式化",
"description": "将日期时间转换为时间戳",
"comment": "将%datetime%转换成%timestamp_level%时间戳,将结果保存到%timestamp%",
"icon": "BlockIcons/17-7.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/日期时间/日期时间转换为时间戳.html",
"inputs": [
{
"name": "datetime",
"label": "日期时间",
"required": false,
"tips": "输入待转换日期。若日期是文本,只支持常用格式,如: 2020-02-02、2020/02/02 02:02:02、2020年2月2日 2时2分2秒等",
"type": "any",
"editor": {
"kind": "textbox",
"placeholder": "日期时间对象或文本。若空,为系统的当前时间"
}
},
{
"name": "timestamp_level",
"label": "时间戳级别",
"required": true,
"default": "10:second",
"defaultDisplay": "秒级",
"tips": "选择时间戳级别,分别为秒级,毫秒级,微秒级",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "秒级",
"value": "second"
},
{
"display": "毫秒级",
"value": "millisecond"
},
{
"display": "微秒级",
"value": "microsecond"
}
]
}
}
],
"outputs": [
{
"id": "timestamp",
"label": "保存时间戳至",
"variableLabel": "日期时间转换后的时间戳",
"tips": "输入一个变量名,用来保存转换后的时间戳",
"type": "str",
"name": "timestamp"
}
]
},
{
"name": "datetime.from_timestamp",
"function": "xbot_visual.datetime.from_timestamp",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Datetime.FromTimestampControl, ShadowBot.Shell.Development",
"title": "时间戳转换为日期时间",
"description": "将时间戳转换为日期时间,默认采用秒级时间戳",
"comment": "将%timestamp%按%timestamp_level%时间戳转换成日期时间,将结果保存到%datetime_instance%",
"icon": "BlockIcons/17-8.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/日期时间/时间戳转换为日期时间.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Datetime.FromTimestampHandler"
}
],
"inputs": [
{
"name": "timestamp",
"label": "时间戳",
"required": true,
"tips": "输入待转换到日期时间的时间戳",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "timestamp_level",
"label": "时间戳级别",
"required": true,
"default": "10:second",
"defaultDisplay": "秒级",
"tips": "选择时间戳级别,分别为秒级,毫秒级,微秒级",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "秒级",
"value": "second"
},
{
"display": "毫秒级",
"value": "millisecond"
},
{
"display": "微秒级",
"value": "microsecond"
}
]
}
},
{
"name": "output_text",
"label": "",
"required": false,
"default": "13:False",
"tips": "若勾选,指明该指令的输出为日期时间文本格式(采用默认格式%Y-%m-%d %H:%M:%S),否则为日期时间对象",
"type": "bool",
"editor": {
"label": "输出日期时间的文本",
"kind": "checkbox"
}
}
],
"outputs": [
{
"id": "datetime_instance",
"label": "保存日期时间至",
"variableLabel": "时间戳转换后的日期时间对象",
"tips": "输入一个变量名,用来保存转换后的日期时间",
"type": "datetime",
"name": "datetime_instance"
},
{
"id": "datetime_text",
"label": "保存日期文本至",
"variableLabel": "时间戳转换后的日期时间文本",
"tips": "输入一个变量名,用来保存转换后的日期时间的文本",
"type": "str",
"name": "datetime_text"
}
]
}
]
}

View File

@@ -0,0 +1,926 @@
{
"types": [],
"blocks": [
{
"name": "dialog.show_alert",
"icon": "BlockIcons/11-1.png",
"description": "打开消息对话框",
"comment": "打开消息对话框%message%",
"title": "打开消息对话框",
"function": "xbot_visual.dialog.show_alert",
"inputs": [
{
"name": "title",
"label": "对话框标题",
"required": true,
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "message",
"label": "对话框内容",
"required": true,
"type": "str",
"editor": {
"kind": "textbox"
}
}
]
},
{
"name": "dialog.show_confirm",
"icon": "BlockIcons/11-2.png",
"description": "打开确认对话框",
"comment": "打开确认对话框%message%",
"title": "打开确认对话框",
"function": "xbot_visual.dialog.show_confirm",
"inputs": [
{
"name": "title",
"label": "对话框标题",
"required": true,
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "message",
"label": "对话框内容",
"required": true,
"type": "str",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "confirm_result",
"label": "确认结果",
"tips": "指定一个变量名称该变量用于保存确认结果bool类型",
"name": "confirm_result",
"type": "bool"
}
]
},
{
"name": "dialog.show_custom_message_box",
"icon": "BlockIcons/11-2.png",
"description": "打开信息对话框",
"comment": "打开信息对话框%message%,将点击按钮名保存到%button_result%",
"title": "打开信息对话框",
"helpUrl": "yddoc/language/zh-cn/指令文档/对话框/打开信息对话框.html",
"video": {
"time": "05:32"
},
"function": "xbot_visual.dialog.show_message_box",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.MessageBox.CustomMessageBox, ShadowBot.Shell.Development",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Dialog.ShowCustomMessageBoxHandler"
}
],
"inputs": [
{
"name": "title",
"label": "对话框标题",
"required": true,
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "message",
"label": "对话框内容",
"required": true,
"type": "str",
"editor": {
"kind": "memoEdit"
}
},
{
"name": "buttons",
"label": "对话框按钮",
"required": true,
"default": "10:确定",
"defaultDisplay": "确定",
"tips": "选择对话框按钮",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "确定",
"value": "确定"
},
{
"display": "是-否",
"value": "是|否"
},
{
"display": "确定-取消",
"value": "确定|取消"
},
{
"display": "是-否-取消",
"value": "是|否|取消"
}
]
}
},
{
"name": "default_button",
"label": "默认选中按钮",
"required": true,
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "use_wait_timeout",
"label": "",
"required": false,
"tips": "当对话框超过设定时间没有点击按钮时,自动点击默认按钮",
"type": "bool",
"default": "13:False",
"editor": {
"label": "超时自动点击默认按钮",
"kind": "checkbox"
}
},
{
"name": "wait_seconds",
"label": "超时秒数",
"required": false,
"tips": "设置对话框在没有用户点击时,自动关闭的超时秒数",
"type": "int",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "button_result",
"label": "按钮名称",
"tips": "指定一个变量名称,该变量用于保存点击的按钮名称",
"variableLabel": "按钮名称",
"name": "pressed_button",
"type": "str"
}
]
},
{
"name": "dialog.show_custom_dialog",
"icon": "BlockIcons/11-3.png",
"description": "打开自定义对话框",
"comment": "打开自定义对话框,将输入结果保存到%dialog_result%",
"title": "打开自定义对话框",
"helpUrl": "yddoc/language/zh-cn/指令文档/对话框/打开自定义对话框.html",
"video": {
"time": "08:39"
},
"function": "xbot_visual.dialog.show_custom_dialog",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Dialog.CustomDialogControl, ShadowBot.Shell.Development",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Dialog.ShowCustomDialogBlockHandler"
}
],
"inputs": [
{
"name": "settings",
"label": "对话框配置",
"required": true,
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "dialog_title",
"label": "对话框标题",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "default_btn",
"label": "默认选中按钮",
"required": true,
"default": "10:确定",
"defaultDisplay": "确定",
"tips": "超时自动点击时默认点击的按钮",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "确定",
"value": "确定"
},
{
"display": "取消",
"value": "取消"
}
]
}
},
{
"name": "is_auto_click",
"label": "",
"required": false,
"tips": "当对话框超过设定时间没有点击按钮时,自动点击默认按钮",
"type": "bool",
"default": "13:False",
"editor": {
"label": "超时自动点击默认按钮",
"kind": "checkbox"
}
},
{
"name": "timeout",
"label": "超时秒数",
"required": false,
"tips": "设置对话框在没有用户点击时,自动关闭的超时秒数",
"type": "int",
"editor": {
"kind": "textbox"
}
},
{
"name": "globals",
"label": "全局变量集合",
"default": "13:globals()",
"type": "dict",
"editor": {
"kind": "textbox"
}
},
{
"name": "locals",
"label": "局部变量集合",
"default": "13:locals()",
"type": "dict",
"editor": {
"kind": "textbox"
}
},
{
"name": "storage_key",
"label": "指令ID",
"default": "13:`block_id`",
"type": "str",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "dialog_result",
"label": "保存用户输入结果至",
"tips": "指定一个变量名称该变量用于保存用户输入结果如果用户取消对话框则返回None否则返回dict对象",
"name": "dialog_result",
"type": "dict"
}
]
},
{
"name": "dialog.show_workbook_dialog",
"icon": "BlockIcons/11-2.png",
"description": "弹出数据表格可对数据表格进行填写或Excel导入操作",
"comment": "打开标题为%title%的数据表格对话框,将输入结果保存到数据表格中,将点击按钮名保存到%button_result%",
"title": "打开数据表格对话框",
"keywords": "Excel导入",
"helpUrl": "yddoc/language/zh-cn/指令文档/对话框/打开数据表格对话框.html",
"video": {
"time": "02:49"
},
"function": "xbot_visual.dialog.show_workbook_dialog",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.MessageBox.DataBookDialog, ShadowBot.Shell.Development",
"inputs": [
{
"name": "title",
"label": "对话框标题",
"tips": "对话框的标题",
"required": true,
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "message",
"label": "提示说明",
"tips": "为数据表格的使用方法进行说明,让使用者更加容易理解",
"type": "str",
"editor": {
"kind": "memoEdit"
}
}
],
"outputs": [
{
"id": "button_result",
"label": "按钮名称",
"tips": "指定一个变量名称,该变量用于保存点击的按钮名称",
"variableLabel": "按钮名称",
"name": "pressed_button",
"type": "str"
}
]
},
{
"name": "dialog.show_input_dialog",
"icon": "BlockIcons/11-4.png",
"description": "打开输入对话框",
"comment": "打开标题为%title%的输入对话框,将输入结果保存到%input_dialog%",
"title": "打开输入对话框",
"helpUrl": "yddoc/language/zh-cn/指令文档/对话框/打开输入对话框.html",
"function": "xbot_visual.dialog.show_input_dialog",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.MessageBox.InputDialog, ShadowBot.Shell.Development",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Dialog.ShowInputDialogBlockHandler"
}
],
"inputs": [
{
"name": "title",
"label": "对话框标题",
"tips": "对话框标题",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "label",
"label": "对话框说明",
"tips": "对话框说明",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "type",
"label": "输入框类型",
"tips": "输入框类型",
"required": true,
"type": "str",
"default": "10:input",
"defaultDisplay": "文本框",
"editor": {
"kind": "select",
"options": [
{
"display": "文本框",
"value": "input"
},
{
"display": "密码框",
"value": "password"
},
{
"display": "多行文本框",
"value": "multiInput"
}
]
}
},
{
"name": "value",
"label": "默认值",
"tips": "默认值",
"type": "str",
"category": "advanced",
"editor": {
"kind": "textbox"
}
},
{
"name": "storage_key",
"label": "指令ID",
"default": "13:`block_id`",
"type": "str",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "input_dialog",
"label": "保存用户输入结果至",
"tips": "指定一个变量名称该变量用于保存用户输入结果如果用户取消对话框则返回None否则返回dict对象",
"name": "input_dialog",
"type": "dict"
}
]
},
{
"name": "dialog.show_datetime_dialog",
"icon": "BlockIcons/11-5.png",
"description": "打开日期时间对话框",
"comment": "打开标题为%title%的日期时间对话框,将输入的日期时间保存到%datetime_dialog%",
"title": "打开日期时间对话框",
"helpUrl": "yddoc/language/zh-cn/指令文档/对话框/打开日期时间对话框.html",
"function": "xbot_visual.dialog.show_datetime_dialog",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.MessageBox.DatetimeDialog, ShadowBot.Shell.Development",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Dialog.ShowDateTimeDialogBlockHandler"
}
],
"inputs": [
{
"name": "title",
"tips": "对话框标题",
"label": "对话框标题",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "label",
"label": "对话框说明",
"tips": "对话框说明",
"type": "str",
"category": "advanced",
"editor": {
"kind": "textbox"
}
},
{
"name": "kind",
"tips": "时间类型",
"label": "时间类型",
"required": true,
"default": "10:date",
"defaultDisplay": "时间",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "时间",
"value": "date"
},
{
"display": "时间段",
"value": "dateRange"
}
]
}
},
{
"name": "format",
"label": "时间格式",
"tips": "时间格式",
"required": true,
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"value": "yyyy-MM-dd",
"display": "年-月-日"
},
{
"value": "yyyy-MM-dd HH:mm:ss",
"display": "年-月-日 时:分:秒"
},
{
"value": "yyyy/MM/dd",
"display": "年/月/日"
},
{
"value": "yyyy/MM/dd HH:mm:ss",
"display": "年/月/日 时:分:秒"
},
{
"value": "MM-dd-yyyy",
"display": "月-日-年"
},
{
"value": "MM-dd-yyyy HH:mm:ss",
"display": "月-日-年 时:分:秒"
},
{
"value": "MM/dd/yyyy",
"display": "月/日/年"
},
{
"value": "MM/dd/yyyy HH:mm:ss",
"display": "月/日/年 时:分:秒"
}
]
}
},
{
"name": "begin_date",
"label": "默认时间",
"tips": "如果输入的数据无法转为时间格式则取当前时间日期",
"type": "datetime",
"editor": {
"kind": "textbox"
}
},
{
"name": "end_date",
"label": "结束时间",
"tips": "如果输入的数据无法转为时间格式则取当前时间日期",
"type": "datetime",
"editor": {
"kind": "textbox"
}
},
{
"name": "storage_key",
"label": "指令ID",
"default": "13:`block_id`",
"type": "str",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "datetime_dialog",
"label": "保存时间设置结果至",
"tips": "指定一个变量名称该变量用于保存时间设置结果如果用户取消对话框则返回None否则返回dict对象",
"name": "datetime_dialog",
"type": "dict"
}
]
},
{
"name": "dialog.show_select_dialog",
"icon": "BlockIcons/11-6.png",
"description": "打开选择对话框",
"comment": "打开标题为%title%的%select_model%对话框,将选择结果保存到%select_dialog%",
"title": "打开选择对话框",
"helpUrl": "yddoc/language/zh-cn/指令文档/对话框/打开选择对话框.html",
"function": "xbot_visual.dialog.show_select_dialog",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.MessageBox.SelectDialog, ShadowBot.Shell.Development",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Dialog.ShowSelectDialogBlockHandler"
}
],
"inputs": [
{
"name": "title",
"label": "对话框标题",
"tips": "对话框标题",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "label",
"label": "对话框说明",
"tips": "对话框说明",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "select_type",
"label": "选择框类型",
"tips": "选择框类型",
"required": true,
"default": "10:combobox",
"defaultDisplay": "下拉框",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "下拉框",
"value": "combobox"
},
{
"display": "列表",
"value": "list"
}
]
}
},
{
"name": "select_model",
"label": "选择模式",
"tips": "选择模式",
"required": true,
"default": "10:single",
"defaultDisplay": "单选",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "单选",
"value": "single"
},
{
"display": "多选",
"value": "multi"
}
]
}
},
{
"name": "values",
"label": "选项列表",
"tips": "选项列表,每行代表一个选项",
"type": "str",
"editor": {
"kind": "memoedit"
}
},
{
"name": "is_selected_first",
"label": "",
"tips": "默认选中第一项",
"required": true,
"default": "13:True",
"type": "bool",
"editor": {
"kind": "checkbox",
"label": "默认选中第一项"
}
},
{
"name": "storage_key",
"label": "指令ID",
"default": "13:`block_id`",
"type": "str",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "select_dialog",
"label": "保存用户选择结果至",
"tips": "指定一个变量名称该变量用于保存用户选择结果如果用户取消对话框则返回None否则返回dict对象",
"name": "select_dialog",
"type": "dict"
}
]
},
{
"name": "dialog.show_select_file_dialog",
"icon": "BlockIcons/11-7.png",
"description": "打开选择文件对话框",
"comment": "打开标题为%title%的选择文件对话框,将文件路径保存到%select_file_dialog%",
"title": "打开选择文件对话框",
"helpUrl": "yddoc/language/zh-cn/指令文档/对话框/打开选择文件对话框.html",
"function": "xbot_visual.dialog.show_select_file_dialog",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Dialog.ShowSelectFileBlockHandler"
}
],
"inputs": [
{
"name": "title",
"label": "对话框标题",
"tips": "对话框标题",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "folder",
"label": "默认文件夹",
"tips": "默认打开的文件夹路径",
"type": "str",
"category": "advanced",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SelectFolder"
}
}
},
{
"name": "filter",
"label": "文件类型",
"tips": "文件类型",
"default": "10:所有文件 (.*)|*.*",
"type": "str",
"editor": {
"kind": "editselect",
"options": [
"所有文件|*.*",
"Excel文件|*.xls;*.xlsx",
"Word文件|*.doc;*.docx",
"文本文件|*.txt",
"图像文件|*.png;*.jpg;*.bmp",
"PPT文件|*.ppt;*.pptx",
"压缩文件|*.zip;*.rar"
]
}
},
{
"name": "is_multi",
"label": "",
"tips": "允许选择多个文件",
"type": "bool",
"default": "13:False",
"editor": {
"kind": "checkbox",
"label": "允许多选"
}
},
{
"name": "is_checked_exists",
"label": "",
"tips": "检查文件是否存在",
"type": "bool",
"default": "13:False",
"editor": {
"kind": "checkbox",
"label": "检查文件是否存在"
}
}
],
"outputs": [
{
"id": "select_file_dialog",
"label": "保存文件选择结果至",
"tips": "指定一个变量名称该变量用于保存文件选择结果如果用户取消对话框则返回None否则返回dict对象",
"name": "select_file_dialog",
"type": "dict"
}
]
},
{
"name": "dialog.show_select_folder_dialog",
"icon": "BlockIcons/11-8.png",
"description": "打开选择文件夹对话框",
"comment": "打开标题为%title%的选择文件夹对话框,将文件夹路径保存到%select_folder_dialog%",
"title": "打开选择文件夹对话框",
"helpUrl": "yddoc/language/zh-cn/指令文档/对话框/打开选择文件夹对话框.html",
"function": "xbot_visual.dialog.show_select_folder_dialog",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Dialog.ShowSelectFolderBlockHandler"
}
],
"inputs": [
{
"name": "title",
"label": "对话框标题",
"tips": "对话框标题",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "folder",
"label": "默认路径",
"tips": "默认打开的文件夹路径",
"type": "str",
"category": "advanced",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SelectFolder"
}
}
}
],
"outputs": [
{
"id": "select_folder_dialog",
"label": "保存文件夹选择结果至",
"tips": "指定一个变量名称该变量用于保存文件夹选择结果如果用户取消对话框则返回None否则返回dict对象",
"name": "select_folder_dialog",
"type": "dict"
}
]
},
{
"name": "dialog.show_notifycation",
"icon": "BlockIcons/11-5.png",
"description": "打开或关闭消息提示框",
"comment": "在屏幕%placement%打开或关闭%level%信息%message%",
"title": "消息通知",
"keywords": "弹框;消息提示",
"helpUrl": "yddoc/language/zh-cn/指令文档/对话框/消息通知.html",
"function": "xbot_visual.dialog.show_notifycation",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Dialog.NotifycationControl, ShadowBot.Shell.Development",
"inputs": [
{
"name": "operation_kind",
"label": "操作",
"default": "10:show",
"defaultDisplay": "打开消息通知",
"tips": "可选择打开消息通知或关闭消息通知",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "打开消息通知",
"value": "show"
},
{
"display": "关闭消息通知",
"value": "close"
}
]
}
},
{
"name": "level",
"label": "消息类型",
"default": "10:info",
"defaultDisplay": "信息",
"tips": "提示框展示的信息的类型,类型有:信息、警告、错误",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "信息",
"value": "info"
},
{
"display": "警告",
"value": "warning"
},
{
"display": "错误",
"value": "error"
}
]
}
},
{
"name": "placement",
"label": "消息位置",
"default": "10:top",
"defaultDisplay": "顶部",
"tips": "提示框展示时再屏幕上的位置,位置有:顶部、底部、右下",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "顶部",
"value": "top"
},
{
"display": "底部",
"value": "bottom"
},
{
"display": "右下角",
"value": "rightBottom"
}
]
}
},
{
"name": "message",
"label": "消息内容",
"tips": "提示框要展示给用户的信息",
"type": "str",
"editor": {
"kind": "memoEdit"
}
},
{
"name": "timeout",
"label": "关闭超时时间(秒)",
"category": "advanced",
"default": "10:3",
"tips": "通知信息展示时长默认展示3秒",
"type": "int",
"editor": {
"kind": "textbox",
"minValue": 1
}
}
]
}
]
}

View File

@@ -0,0 +1,239 @@
{
"types": [],
"blocks": [
{
"name": "dictionary.create",
"function": "xbot_visual.dictionary.create",
"title": "新建字典",
"description": "新建空的字典",
"comment": "新建字典,将字典对象保存到%dict_instance%",
"icon": "BlockIcons/28-1.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/字典操作/新建字典.html",
"outputs": [
{
"id": "dict_instance",
"label": "保存字典对象至",
"variableLabel": " 新建的字典对象",
"tips": "输入一个名字,用来保存新建的字典",
"type": "dict",
"name": "dict_instance"
}
]
},
{
"name": "dictionary.set",
"function": "xbot_visual.dictionary.set",
"title": "设置键值对",
"keywords": "字典",
"description": "这个指令用于在字典中设置一对键值,若键名已存在则修改值",
"comment": "在字典%dict%中设置新的键值对(%key%%value%",
"icon": "BlockIcons/28-2.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/字典操作/设置键值对.html",
"inputs": [
{
"name": "dict",
"label": "字典",
"required": true,
"tips": "输入字典变量",
"type": "dict",
"editor": {
"kind": "textbox"
}
},
{
"name": "key",
"label": "键名",
"required": true,
"tips": "输入键名",
"type": "any",
"editor": {
"kind": "textbox"
}
},
{
"name": "value",
"label": "值",
"required": true,
"tips": "输入键值",
"type": "any",
"editor": {
"kind": "textbox"
}
}
]
},
{
"name": "dictionary.get_value",
"function": "xbot_visual.dictionary.get_value",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Dictionary.GetValueControl, ShadowBot.Shell.Development",
"title": "获取键值",
"keywords": "字典",
"description": "这个指令用于在字典中获取键值",
"comment": "在字典%dict%中获取%key%键的值,将结果保存到%value_instance%",
"icon": "BlockIcons/28-3.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/字典操作/获取键值.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Dictionary.GetValueHandler"
}
],
"inputs": [
{
"name": "dict",
"label": "字典",
"required": true,
"tips": "输入字典变量",
"type": "dict",
"editor": {
"kind": "textbox"
}
},
{
"name": "key",
"label": "键名",
"required": true,
"tips": "输入键名",
"type": "any",
"editor": {
"kind": "textbox"
}
},
{
"name": "key_not_exist_process_way",
"label": "键不存在时",
"required": true,
"default": "10:raise_error",
"defaultDisplay": "报错",
"tips": "当输入的键不存在时,选择一种处理方式",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "报错",
"value": "raise_error"
},
{
"display": "返回默认值",
"value": "return_default_value"
}
]
}
},
{
"name": "default_value",
"label": "默认值",
"required": false,
"tips": "输入默认键值",
"type": "any",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "value_instance",
"label": "保存键值至",
"variableLabel": "字典的键值",
"tips": "输入一个名字,用来保存查找到的键值",
"type": "any",
"name": "value_instance"
}
]
},
{
"name": "dictionary.get_keys",
"function": "xbot_visual.dictionary.get_keys",
"title": "获取字典键名列表",
"description": "这个指令用于在字典中获取键名列表",
"comment": "在字典%dict%中获取键名列表,将结果保存到%key_list%",
"icon": "BlockIcons/28-4.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/字典操作/获取字典键名列表.html",
"inputs": [
{
"name": "dict",
"label": "字典",
"required": true,
"tips": "输入字典变量",
"type": "dict",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "key_list",
"label": "保存键名列表至",
"variableLabel": "字典键名列表",
"tips": "输入一个名字,用来保存查找到的键名列表",
"type": "list<any>",
"name": "key_list"
}
]
},
{
"name": "dictionary.get_values",
"function": "xbot_visual.dictionary.get_values",
"title": "获取字典值列表",
"description": "这个指令用于在字典中获取值列表",
"comment": "在字典%dict%中获取值列表,将结果保存到%value_list%",
"icon": "BlockIcons/28-5.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/字典操作/获取字典值列表.html",
"inputs": [
{
"name": "dict",
"label": "字典",
"required": true,
"tips": "输入字典变量",
"type": "dict",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "value_list",
"label": "保存值列表至",
"variableLabel": "字典键值列表",
"tips": "输入一个名字,用来保存查找到的值列表",
"type": "list<any>",
"name": "value_list"
}
]
},
{
"name": "dictionary.pop",
"function": "xbot_visual.dictionary.pop",
"title": "删除字典键值对",
"description": "这个指令用于在字典中删除键值对",
"comment": "在字典%dict%中删除键名为%key%的键值对",
"icon": "BlockIcons/28-6.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/字典操作/删除字典键值对.html",
"inputs": [
{
"name": "dict",
"label": "字典",
"required": true,
"tips": "输入字典变量",
"type": "dict",
"editor": {
"kind": "textbox"
}
},
{
"name": "key",
"label": "待删除的键名",
"required": true,
"tips": "输入待删除的键名",
"type": "any",
"editor": {
"kind": "textbox"
}
}
]
}
]
}

View File

@@ -0,0 +1,747 @@
{
"types": [],
"blocks": [
{
"name": "dir.if_exist",
"statement": "workflow.if",
"function": "xbot_visual.dir.if_exist",
"title": "IF 文件夹存在",
"description": "判断文件夹是否存在",
"comment": "如果文件夹%path%%expect_exist%,则执行以下操作",
"indent": "1",
"scope": "1",
"isCondition": true,
"icon": "BlockIcons/19-1.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/条件判断/if文件夹存在.html",
"video": {
"time": "00:36"
},
"inputs": [
{
"name": "path",
"label": "文件夹路径",
"required": true,
"tips": "输入或选择文件夹路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SelectFolder"
}
}
},
{
"name": "expect_exist",
"label": "文件夹是否",
"required": true,
"default": "10:exist",
"defaultDisplay": "存在",
"tips": "选择预期的文件夹是否存在",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "存在",
"value": "exist"
},
{
"display": "不存在",
"value": "no_exist"
}
]
}
}
]
},
{
"name": "dir.make",
"function": "xbot_visual.dir.make",
"title": "创建文件夹",
"description": "创建指定路径的文件夹",
"comment": "创建文件夹%path%",
"icon": "BlockIcons/19-2.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/文件夹/创建文件夹.html",
"inputs": [
{
"name": "path",
"label": "路径",
"required": true,
"tips": "输入或选择文件夹路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SelectFolder"
}
}
}
]
},
{
"name": "dir.makedir",
"function": "xbot_visual.dir.makedir",
"title": "创建文件夹",
"description": "创建文件夹",
"comment": "在%parent%下新建文件夹%name%,将新建的文件夹路径保存到%new_folder%",
"icon": "BlockIcons/19-2.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/文件夹/创建文件夹.html",
"inputs": [
{
"name": "parent",
"label": "父文件夹目录",
"required": true,
"tips": "输入或选择要在其中创建新文件夹的文件夹路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SelectFolder"
}
}
},
{
"name": "name",
"label": "新文件夹名称",
"required": true,
"tips": "要创建的文件夹名称",
"type": "str",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "new_folder",
"label": "保存新文件夹路径至",
"variableLabel": "创建的新文件夹路径",
"tips": "输入一个名字,用于保存新建的文件夹路径",
"type": "str",
"name": "new_folder"
}
]
},
{
"name": "dir.remove",
"function": "xbot_visual.dir.remove",
"title": "删除文件夹",
"description": "删除文件夹,包括该文件夹下所有的子文件和文件",
"comment": "删除文件夹%path%",
"icon": "BlockIcons/19-3.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/文件夹/删除文件夹.html",
"inputs": [
{
"name": "path",
"label": "要删除的文件夹",
"required": true,
"tips": "输入或选择要删除的文件夹路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SelectFolder"
}
}
}
]
},
{
"name": "dir.find_files",
"function": "xbot_visual.dir.find_files",
"title": "获取文件列表",
"keywords": "检索文件",
"description": "在文件夹中检索文件",
"comment": "获取文件夹%path%下符合%patterns%命名规则的文件列表,将文件列表保存到%file_paths%",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Dir.FindFilesControl, ShadowBot.Shell.Development",
"icon": "BlockIcons/19-4.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/文件/获取文件列表.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Dir.FindFilesHandler"
}
],
"inputs": [
{
"name": "path",
"label": "文件夹",
"required": true,
"tips": "输入或选择文件夹路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SelectFolder"
}
}
},
{
"name": "patterns",
"label": "文件名匹配规则",
"required": true,
"tips": "输入文件名匹配规则,允许使用通配符,比如“图片*”或“图片?”,多个规则用逗号分割,比如:规则1规则2",
"type": "str",
"default": "10:*.*",
"editor": {
"kind": "textbox"
}
},
{
"name": "find_subdir",
"label": "",
"required": true,
"tips": "是否查找子文件夹下的文件",
"type": "bool",
"default": "13:False",
"editor": {
"label": "查找子文件夹",
"kind": "checkbox"
}
},
{
"name": "skip_hidden_file",
"label": "",
"required": true,
"tips": "是否忽略隐藏的文件",
"type": "bool",
"default": "13:False",
"editor": {
"label": "忽略隐藏的文件",
"kind": "checkbox"
}
},
{
"name": "is_sort",
"label": "",
"required": true,
"tips": "指定文件列表排序规则",
"type": "bool",
"default": "13:False",
"editor": {
"label": "指定文件列表排序规则",
"kind": "checkbox"
}
},
{
"name": "sort_by",
"label": "排序因素",
"required": false,
"default": "10:name",
"defaultDisplay": "文件名称",
"tips": "选择文件列表排序因素",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "文件名称",
"value": "name"
},
{
"display": "文件大小",
"value": "size"
},
{
"display": "文件创建时间",
"value": "create_time"
},
{
"display": "文件最后修改时间",
"value": "last_modify_time"
}
]
}
},
{
"name": "sort_way",
"label": "排序方式",
"required": false,
"default": "10:increase",
"defaultDisplay": "递增",
"tips": "选择文件列表排序方式",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "递增",
"value": "increase"
},
{
"display": "递减",
"value": "decrease"
}
]
}
}
],
"outputs": [
{
"id": "file_paths",
"label": "保存文件列表至",
"variableLabel": "获取的文件列表",
"tips": "输入一个名字,用来保存文件列表",
"type": "list<str>",
"name": "file_paths"
}
]
},
{
"name": "dir.find_subdirs",
"function": "xbot_visual.dir.find_subdirs",
"title": "获取文件夹列表",
"keywords": "子文件夹",
"description": "获取指定路径文件夹下的子文件夹",
"comment": "获取文件夹%path%下的子文件夹,将文件夹列表保存到%dir_paths%",
"icon": "BlockIcons/19-5.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/文件夹/获取文件夹列表.html",
"inputs": [
{
"name": "path",
"label": "文件夹路径",
"required": true,
"tips": "输入或选择文件夹路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SelectFolder"
}
}
},
{
"name": "patterns",
"label": "子文件夹名称匹配规则",
"required": true,
"tips": "输入子文件夹名称匹配规则,允许使用通配符,比如“图片*”或“图片?”,多个规则用逗号分割,比如:规则1规则2",
"type": "str",
"default": "10:*",
"editor": {
"kind": "textbox"
}
},
{
"name": "find_subdir",
"label": "",
"required": true,
"tips": "是否递归查找子文件夹",
"type": "bool",
"default": "13:False",
"editor": {
"label": "递归查找子文件夹",
"kind": "checkbox"
}
}
],
"outputs": [
{
"id": "dir_paths",
"label": "保存文件夹列表至",
"variableLabel": "获取的文件夹列表",
"tips": "输入一个名字,用来保存文件夹列表",
"type": "list<str>",
"name": "dir_paths"
}
]
},
{
"name": "dir.selected_dirs_or_files",
"function": "xbot_visual.dir.selected_dirs_or_files",
"title": "获取选中文件(夹)列表",
"description": "获取当前激活文件资源管理器(若激活桌面则目标为桌面)中选中的文件、文件夹列表",
"comment": "获取当前激活的文件夹中选中的文件和文件夹列表,将结果保存到%dir_or_file_paths%",
"icon": "BlockIcons/19-11.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/文件夹/获取选中文件(夹)列表.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Dir.SelectedDirsOrFilesHandler"
}
],
"inputs": [
{
"name": "file_type",
"label": "获取类型",
"required": true,
"tips": "选择要获取的选中类型,支持获取选中的文件、文件夹或所有选中项",
"type": "str",
"default": "10:all",
"defaultDisplay": "文件和文件夹",
"autoFill": true,
"editor": {
"kind": "select",
"options": [
{
"display": "文件和文件夹",
"value": "all"
},
{
"display": "文件",
"value": "file"
},
{
"display": "文件夹",
"value": "folder"
}
]
}
}
],
"outputs": [
{
"id": "dir_or_file_paths",
"label": "保存文件、文件夹列表至",
"variableLabel": "选中的文件(夹)列表",
"tips": "输入一个名字,用来保存文件、文件夹列表",
"type": "list<str>",
"name": "dir_or_file_paths"
}
]
},
{
"name": "dir.open",
"function": "xbot_visual.dir.open",
"title": "打开文件夹",
"description": "打开文件夹,如果为文件路径,会在打开文件夹后选中文件",
"comment": "打开文件夹并选中文件%folder_file_path%",
"icon": "BlockIcons/19-12.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/文件夹/打开文件夹.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Dir.OpenDirHandler"
}
],
"inputs": [
{
"name": "folder_file_path",
"label": "文件(夹)路径",
"required": true,
"tips": "输入要打开的文件夹路径,如果为文件路径,会打开文件夹并选中文件",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SelectFolder"
}
}
}
]
},
{
"name": "dir.empty",
"function": "xbot_visual.dir.empty",
"title": "清空文件夹",
"description": "删除文件夹下的所有文件和子文件夹,但保留文件夹本身",
"comment": "清空文件夹%path%",
"icon": "BlockIcons/19-6.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/文件夹/清空文件夹.html",
"inputs": [
{
"name": "path",
"label": "要清空的文件夹",
"required": true,
"tips": "输入或选择要清空的文件夹路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SelectFolder"
}
}
}
]
},
{
"name": "dir.copy",
"function": "xbot_visual.dir.copy",
"title": "拷贝文件夹",
"keywords": "复制文件夹",
"description": "将源文件夹拷贝到目标文件夹",
"comment": "将源文件夹%source_dir_path%拷贝到目标文件夹%copyto_dir_path%,将拷贝后的文件夹路径保存到%dir_path%",
"icon": "BlockIcons/19-7.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/文件夹/拷贝文件夹.html",
"inputs": [
{
"name": "source_dir_path",
"label": "要拷贝的文件夹",
"required": true,
"tips": "输入或选择要拷贝的文件夹路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SelectFolder"
}
}
},
{
"name": "copyto_dir_path",
"label": "目标文件夹",
"required": true,
"tips": "输入目标文件夹路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SelectFolder"
}
}
},
{
"name": "copy_way",
"label": "如果文件存在",
"required": true,
"default": "10:overwrite",
"defaultDisplay": "覆盖",
"tips": "对目标文件夹中已存在的文件,选择覆盖还是不执行拷贝",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "覆盖",
"value": "overwrite"
},
{
"display": "不要拷贝",
"value": "not_overwrite"
},
{
"display": "自动添加后缀",
"value": "save_as"
}
]
}
}
],
"outputs": [
{
"id": "dir_path",
"label": "拷贝后的文件夹路径",
"variableLabel": "拷贝后的文件夹路径",
"tips": "输入一个名字,用来保存拷贝后的文件夹路径",
"type": "str",
"name": "dir_path"
}
]
},
{
"name": "dir.move",
"function": "xbot_visual.dir.move",
"title": "移动文件夹",
"description": "将源文件夹移动到目标文件夹下",
"comment": "将源文件夹%source_dir_path%移动到目标文件夹%moveto_dir_path%下,将移动后的文件路径保存到%dir_path%",
"icon": "BlockIcons/19-8.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/文件夹/移动文件夹.html",
"inputs": [
{
"name": "source_dir_path",
"label": "要移动的文件夹",
"required": true,
"tips": "输入或选择要移动的文件夹路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SelectFolder"
}
}
},
{
"name": "moveto_dir_path",
"label": "目标文件夹",
"required": true,
"tips": "输入或选择目标文件夹路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SelectFolder"
}
}
}
],
"outputs": [
{
"id": "dir_path",
"label": "移动后的文件夹路径",
"variableLabel": "移动后的文件夹路径",
"tips": "输入一个名字,用来保存移动后的文件夹路径",
"type": "str",
"name": "dir_path"
}
]
},
{
"name": "dir.get_special_dir",
"function": "xbot_visual.dir.get_special_dir",
"title": "获取系统文件夹路径",
"description": "获取系统文件夹路径",
"comment": "获取系统文件夹%special_dir_name%路径,将系统文件夹路径保存到%dir_path%",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Dir.GetSpecialDirControl, ShadowBot.Shell.Development",
"icon": "BlockIcons/19-9.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/文件夹/获取系统文件夹路径.html",
"inputs": [
{
"name": "special_dir_name",
"label": "系统文件夹名称",
"required": true,
"default": "10:DesktopDirectory",
"defaultDisplay": "文件夹名称",
"tips": "选择系统文件夹名称",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "临时",
"value": "TEMP"
},
{
"display": "桌面",
"value": "DesktopDirectory"
},
{
"display": "应用程序数据",
"value": "ApplicationData"
},
{
"display": "常见应用程序数据",
"value": "CommonApplicationData"
},
{
"display": "本地应用程序数据",
"value": "LocalApplicationData"
},
{
"display": "Cookies",
"value": "Cookies"
},
{
"display": "收藏夹",
"value": "Favorites"
},
{
"display": "历史",
"value": "History"
},
{
"display": "Internet 缓存",
"value": "InternetCache"
},
{
"display": "程序",
"value": "Programs"
},
{
"display": "音乐",
"value": "MyMusic"
},
{
"display": "图片",
"value": "MyPictures"
},
{
"display": "最近",
"value": "Recent"
},
{
"display": "发送到",
"value": "SendTo"
},
{
"display": "开始菜单",
"value": "StartMenu"
},
{
"display": "启动",
"value": "Startup"
},
{
"display": "系统",
"value": "System"
},
{
"display": "模板",
"value": "Templates"
},
{
"display": "个人",
"value": "Personal"
},
{
"display": "程序文件",
"value": "ProgramFiles"
},
{
"display": "常见程序文件",
"value": "CommonProgramFiles"
},
{
"display": "系统",
"value": "Windows"
},
{
"display": "下载",
"value": "Downloads"
}
]
}
}
],
"outputs": [
{
"id": "dir_path",
"label": "系统文件夹路径",
"variableLabel": "系统文件夹路径",
"tips": "输入一个名字,用来保存系统文件夹路径",
"type": "str",
"name": "dir_path"
}
]
},
{
"name": "dir.rename",
"function": "xbot_visual.dir.rename",
"title": "文件夹重命名",
"description": "文件夹重命名",
"comment": "将文件夹%path%重命名为%new_name%,将新的文件夹路径保存到%new_dir_path%",
"icon": "BlockIcons/19-10.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/文件夹/文件夹重命名.html",
"inputs": [
{
"name": "path",
"label": "要重命名的文件夹",
"required": true,
"tips": "输入或选择要重命名的文件夹路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SelectFolder"
}
}
},
{
"name": "new_name",
"label": "新文件夹名称",
"required": true,
"tips": "输入新的文件夹名称",
"type": "str",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "new_dir_path",
"label": "新的文件夹路径",
"variableLabel": "重命名后的文件夹路径",
"tips": "输入一个名字,用来保存新的文件夹路径",
"type": "str",
"name": "new_dir_path"
}
]
}
]
}

View File

@@ -0,0 +1,519 @@
{
"types": [
{
"name": "xbot_visual_email_mailmessage",
"localName": "邮件",
"pythonName": "xbot_visual._core.xbot_visual_email_mailmessage",
"props": [
{
"name": "sender",
"type": "str",
"label": "发件人"
},
{
"name": "receiver",
"type": "str",
"label": "收件人"
},
{
"name": "subject",
"type": "str",
"label": "主题"
},
{
"name": "text_body",
"type": "str",
"label": "正文"
},
{
"name": "html_body",
"type": "str",
"label": "HTML正文"
},
{
"name": "time",
"type": "str",
"label": "时间"
},
{
"name": "attachment",
"type": "str",
"label": "附件路径"
}
]
}
],
"blocks": [
{
"name": "email.send_email",
"icon": "BlockIcons/13-1.png",
"description": "发送邮件",
"comment": "发送邮件到%to%",
"title": "发送邮件",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/邮件/发送邮件.html",
"function": "xbot_visual.email.send_email",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Email.SendEmailControl, ShadowBot.Shell.Development",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Email.SendEmailHandler"
}
],
"inputs": [
{
"name": "sender",
"label": "发件人",
"required": true,
"tips": "邮件发件人",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "sender_display_name",
"label": "发件人名称",
"required": false,
"tips": "邮件发送人名称",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "to",
"label": "收件人",
"required": true,
"tips": "邮件收件人,多个收件人用“;”分隔。",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "cc",
"label": "抄送",
"required": false,
"tips": "邮件抄送,多个抄送用“;”分隔。",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "bcc",
"label": "密送",
"required": false,
"tips": "邮件密送,多个密送用“;”分隔。",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "subject",
"label": "主题",
"required": true,
"tips": "邮件主题",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "body",
"label": "正文",
"required": true,
"tips": "邮件正文",
"type": "str",
"editor": {
"kind": "memoedit"
}
},
{
"name": "body_is_html",
"label": "",
"required": false,
"tips": "正文是HTML格式",
"type": "bool",
"default": "13:False",
"editor": {
"label": "HTML格式",
"kind": "checkbox"
}
},
{
"name": "attachments",
"label": "邮件附件",
"required": false,
"tips": "邮件附件,多个附件用“;”分隔。",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "OpenFile",
"filter": "All Files (*.*)|*.*"
}
}
},
{
"name": "select_smtp_server",
"label": "SMTP服务器",
"required": true,
"category": "advanced",
"default": "10:qq_smtp",
"defaultDisplay": "QQ邮箱",
"tips": "选择一个SMTP服务器",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "QQ邮箱",
"value": "qq_smtp"
},
{
"display": "126邮箱",
"value": "126_smtp"
},
{
"display": "163邮箱",
"value": "163_smtp"
},
{
"display": "Google邮箱",
"value": "gmail_smtp"
},
{
"display": "Outlook邮箱",
"value": "outlook_smtp"
},
{
"display": "iCloud邮箱",
"value": "iCloud_smtp"
},
{
"display": "其他",
"value": "other_smtp"
}
]
}
},
{
"name": "smtp_server",
"label": "指定的SMTP服务器",
"category": "advanced",
"tips": "输入指定的SMTP服务器地址",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "smtp_port",
"label": "指定的SMTP端口",
"default": "10:465",
"category": "advanced",
"tips": "输入指定的SMTP端口",
"type": "int",
"editor": {
"kind": "textbox"
}
},
{
"name": "use_ssl",
"label": "",
"required": true,
"category": "advanced",
"tips": "使用SSL连接SMTP服务器",
"type": "bool",
"default": "13:False",
"editor": {
"label": "使用SSL",
"kind": "checkbox"
}
},
{
"name": "smtp_server_authentication",
"label": "",
"required": false,
"category": "advanced",
"tips": "SMTP服务器需要身份验证",
"type": "bool",
"default": "13:False",
"editor": {
"label": "SMTP服务器需要身份验证",
"kind": "checkbox"
}
},
{
"name": "user_name",
"label": "用户名",
"required": false,
"category": "advanced",
"tips": "SMTP服务器身份验证的用户名",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "password",
"label": "授权码",
"required": false,
"category": "advanced",
"tips": "SMTP服务器验证身份的授权码",
"type": "str",
"editor": {
"kind": "password"
}
}
]
},
{
"name": "email.retrieve_email",
"icon": "BlockIcons/13-2.png",
"description": "从指定的邮箱中获取邮件,收取邮件",
"comment": "获取%mail_kind%%username%中文件夹%folder_name%的前%top%封邮件,将邮件列表保存到%mailmessage_list%",
"title": "获取邮件",
"keywords": "收取邮件;收邮件",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/邮件/获取邮件.html",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Email.RetrieveEmailControl, ShadowBot.Shell.Development",
"function": "xbot_visual.email.retrieve_email",
"inputs": [
{
"name": "mail_kind",
"label": "邮箱类型",
"required": true,
"default": "10:163",
"defaultDisplay": "163邮箱",
"tips": "选择一个邮箱类型",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "163邮箱",
"value": "163"
},
{
"display": "126邮箱",
"value": "126"
},
{
"display": "qq邮箱",
"value": "qq"
},
{
"display": "Google邮箱",
"value": "gmail"
},
{
"display": "Outlook邮箱",
"value": "outlook"
},
{
"display": "iCloud邮箱",
"value": "iCloud"
},
{
"display": "其他",
"value": "other_smtp"
},
{
"display": "自定义邮箱",
"value": "custom"
}
]
}
},
{
"name": "address",
"label": "IMAP服务器",
"tips": "输入指定的IMAP服务器地址",
"type": "str",
"editor": {
"placeholder": "如imap.163.com",
"kind": "textbox"
}
},
{
"name": "port",
"label": "端口号",
"tips": "输入指定的IMAP端口号",
"default": "10:993",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "use_ssl",
"label": "",
"tips": "使用SSL连接IMAP服务器",
"type": "bool",
"default": "13:True",
"editor": {
"label": "使用SSL",
"kind": "checkbox"
}
},
{
"name": "username",
"label": "邮箱账号",
"tips": "IMAP服务器身份验证的用户名通常是邮箱账号以具体邮件服务商的规定为准",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "authcode",
"label": "授权码",
"tips": "IMAP服务器验证身份的授权码一般需要短信认证开通部分邮箱为账号密码以具体邮件服务商的规定为准",
"type": "str",
"editor": {
"kind": "password"
}
},
{
"name": "only_unread",
"label": "",
"tips": "仅获取未读邮件或者获取所有邮件",
"type": "bool",
"default": "13:True",
"editor": {
"label": "仅未读邮件",
"kind": "checkbox"
}
},
{
"name": "top",
"label": "邮件数量",
"tips": "获取前N封邮件",
"default": "10:5",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "save_attachments",
"label": "",
"tips": "是否下载邮件的附件",
"type": "bool",
"default": "13:False",
"editor": {
"label": "保存附件",
"kind": "checkbox"
}
},
{
"name": "attachments_savefolder",
"label": "保存目录",
"tips": "附件的保存目录",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SelectFolder"
}
}
},
{
"name": "folder_name_specifc_mode",
"label": "文件夹指定方式",
"tips": "文件夹指定方式",
"type": "str",
"default": "10:default",
"defaultDisplay": "默认",
"category": "advanced",
"editor": {
"kind": "select",
"options": [
{
"display": "默认",
"value": "default"
},
{
"display": "动态指定",
"value": "dynamic"
}
]
}
},
{
"name": "folder_name",
"label": "文件夹名称",
"tips": "输入指定文件夹的名称",
"category": "advanced",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "mark_as_read",
"label": "",
"tips": "获取邮件后,将邮件标记为已读状态",
"category": "advanced",
"type": "bool",
"default": "13:True",
"editor": {
"label": "标记为已读",
"kind": "checkbox"
}
},
{
"name": "keyword_in_from",
"label": "发件人中包含的内容",
"tips": "发件人中包含的内容",
"category": "advanced",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "keyword_in_to",
"label": "收件人中包含的内容",
"tips": "收件人中包含的内容",
"category": "advanced",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "keyword_in_subject",
"label": "主题中包含的内容",
"tips": "主题中包含的内容",
"category": "advanced",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "keyword_in_textBody",
"label": "正文中包含的内容",
"tips": "正文中包含的内容",
"category": "advanced",
"type": "str",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "mailmessage_list",
"label": "保存邮件列表至",
"variableLabel": "邮件列表",
"tips": "指定一个变量名称,该变量用于存储获取到的邮件列表",
"type": "list<xbot_visual_email_mailmessage>",
"name": "mailmessage_list"
}
]
}
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,651 @@
{
"types": [
{
"name": "xbot_visual.file.FileParts",
"localName": "文件路径信息",
"props": [
{
"name": "drive_name",
"type": "str",
"label": "根目录"
},
{
"name": "directory",
"type": "str",
"label": "父目录"
},
{
"name": "file_name",
"type": "str",
"label": "文件名称"
},
{
"name": "file_name_without_extension",
"type": "str",
"label": "文件名称(不带扩展名)"
},
{
"name": "file_extension",
"type": "str",
"label": "文件扩展名"
}
]
}
],
"blocks": [
{
"name": "file.if_exist",
"statement": "workflow.if",
"function": "xbot_visual.file.if_exist",
"title": "IF 文件存在",
"description": "判断文件是否存在",
"comment": "如果文件%path%%expect_exist%,则执行以下操作",
"indent": "1",
"scope": "1",
"isCondition": true,
"icon": "BlockIcons/18-1.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/条件判断/if文件存在.html",
"video": {
"time": "00:47"
},
"inputs": [
{
"name": "path",
"label": "文件路径",
"required": true,
"tips": "输入或选择文件路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "OpenFile",
"filter": "所有文件 (.*)|*.*"
}
}
},
{
"name": "expect_exist",
"label": "文件是否",
"required": true,
"default": "10:exist",
"defaultDisplay": "存在",
"tips": "选择预期的文件是否存在",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "存在",
"value": "exist"
},
{
"display": "不存在",
"value": "no_exist"
}
]
}
}
]
},
{
"name": "file.remove",
"function": "xbot_visual.file.remove",
"title": "删除文件",
"description": "删除文件Python模式支持多文件删除文本模式只支持单文件删除",
"comment": "删除文件%paths%",
"icon": "BlockIcons/18-2.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/文件/删除文件.html",
"inputs": [
{
"name": "paths",
"label": "要删除的文件",
"required": true,
"tips": "输入要删除的文件的路径若想删除多个文件切换到Python模式比如['文件1路径','文件2路径']",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "OpenFile",
"filter": "所有文件 (.*)|*.*"
}
}
}
]
},
{
"name": "file.read",
"function": "xbot_visual.file.read",
"title": "读取文件",
"description": "读取指定路径文件的内容",
"comment": "读取文件%path%的内容,将内容保存到%file_content%",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.File.ReadFile, ShadowBot.Shell.Development",
"icon": "BlockIcons/18-3.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/文件/读取文件.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.File.ReadHandler"
}
],
"inputs": [
{
"name": "path",
"label": "要读取的文件",
"required": true,
"tips": "输入要读取文件的路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "OpenFile",
"filter": "所有文件 (.*)|*.*"
}
}
},
{
"name": "read_way",
"label": "文件内容保存为",
"required": false,
"default": "10:all_text",
"defaultDisplay": "文本",
"tips": "指定输出的文件内容,可以选择“文本”可以将整个文件保存到一个文本中,选择“列表”按行获取文本内容并存储到列表中,选择“二进制文本”将读取的文本再转为二进制",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "文本",
"value": "all_text"
},
{
"display": "列表(每行保存为列表一项)",
"value": "lines"
},
{
"display": "二进制文本",
"value": "bin"
}
]
}
},
{
"name": "encoding",
"label": "文件编码",
"required": false,
"default": "10:UTF-8",
"defaultDisplay": "UTF-8",
"tips": "选择文本编码",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "默认",
"value": "default"
},
{
"display": "ANSI",
"value": "ANSI"
},
{
"display": "UTF-8",
"value": "UTF-8"
},
{
"display": "UTF-16",
"value": "UTF-16"
},
{
"display": "UTF-16 BE",
"value": "utf-16-be"
}
]
}
}
],
"outputs": [
{
"id": "file_content",
"label": "保存文件内容至",
"variableLabel": "读取的文件内容",
"tips": "输入一个名字,用来保存文件内容",
"type": "any",
"name": "file_content"
}
]
},
{
"name": "file.write",
"function": "xbot_visual.file.write",
"title": "写入文件",
"description": "将文本内容写入到已有文件,若文件不存在,自动创建文件",
"comment": "将内容%content%覆盖写入到文件%path%",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.File.WriteFile, ShadowBot.Shell.Development",
"icon": "BlockIcons/18-4.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/文件/写入文件.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.File.WriteHandler"
}
],
"inputs": [
{
"name": "path",
"label": "要写入的文件",
"required": true,
"tips": "输入文件路径,文件若不存在,会自动创建文件",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "OpenFile",
"filter": "所有文件 (.*)|*.*"
}
}
},
{
"name": "content",
"label": "要写入的内容",
"required": true,
"tips": "待写入文件的内容",
"type": "any",
"editor": {
"kind": "memoedit"
}
},
{
"name": "write_way",
"label": "如果文件存在",
"required": true,
"default": "10:overwrite",
"defaultDisplay": "覆盖写入",
"tips": "指定当要写入的文件存在时要执行的操作",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "覆盖写入",
"value": "overwrite"
},
{
"display": "追加写入",
"value": "append"
}
]
}
},
{
"name": "is_text",
"label": "",
"required": true,
"tips": "文件是文本文件",
"type": "bool",
"default": "13:True",
"editor": {
"label": "文件是文本文件",
"kind": "checkbox"
}
},
{
"name": "new_line",
"label": "",
"required": false,
"tips": "是否要换新行追加,若否,直接在原内容后面追加",
"type": "bool",
"default": "13:False",
"editor": {
"label": "新行追加",
"kind": "checkbox"
}
},
{
"name": "encoding",
"label": "文件编码",
"required": false,
"default": "10:UTF-8",
"defaultDisplay": "UTF-8",
"tips": "选择文本编码",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "默认",
"value": "default"
},
{
"display": "ANSI",
"value": "ANSI"
},
{
"display": "UTF-8",
"value": "UTF-8"
},
{
"display": "UTF-16",
"value": "UTF-16"
},
{
"display": "UTF-16 BE",
"value": "utf-16-be"
}
]
}
}
]
},
{
"name": "file.copy",
"function": "xbot_visual.file.copy",
"title": "拷贝文件",
"keywords": "复制文件",
"description": "拷贝文件Python模式支持多文件拷贝文本模式只支持单文件拷贝",
"comment": "将文件%source_file_paths%拷贝到文件夹%copyto_dir_path%,将拷贝后的文件路径列表保存到%file_list%",
"icon": "BlockIcons/18-5.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/文件/拷贝文件.html",
"inputs": [
{
"name": "source_file_paths",
"label": "要拷贝的文件",
"required": true,
"tips": "输入要拷贝文件的路径若想拷贝多个文件切换到Python模式比如['D:\\测试\\11.txt','D:\\测试\\22.txt']",
"type": "any",
"editor": {
"kind": "textbox",
"dialog": {
"type": "OpenFile",
"filter": "所有文件 (.*)|*.*"
}
}
},
{
"name": "copyto_dir_path",
"label": "目标文件夹",
"required": true,
"tips": "输入目标文件夹路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SelectFolder"
}
}
},
{
"name": "copy_way",
"label": "如果文件存在",
"required": true,
"default": "10:overwrite",
"defaultDisplay": "覆盖",
"tips": "指定当目标文件夹下已存在同名文件时要执行的操作",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "覆盖",
"value": "overwrite"
},
{
"display": "不要拷贝",
"value": "not_copy"
},
{
"display": "自动添加后缀",
"value": "save_as"
}
]
}
}
],
"outputs": [
{
"id": "file_list",
"label": "拷贝后的文件路径列表",
"variableLabel": "拷贝后的文件路径列表",
"tips": "输入一个名字,用来保存拷贝后的文件路径列表",
"type": "list<str>",
"name": "file_list"
}
]
},
{
"name": "file.move",
"function": "xbot_visual.file.move",
"title": "移动文件",
"description": "移动文件Python模式支持多文件移动文本模式只支持单文件移动",
"comment": "将文件%source_file_paths%移动到文件夹%moveto_dir_path%,将移动后的文件路径列表保存到%file_list%",
"icon": "BlockIcons/18-6.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/文件/移动文件.html",
"inputs": [
{
"name": "source_file_paths",
"label": "要移动的文件",
"required": true,
"tips": "输入要移动文件的路径若想移动多个文件切换到Python模式比如['D:\\测试\\11.txt','D:\\测试\\22.txt']",
"type": "any",
"editor": {
"kind": "textbox",
"dialog": {
"type": "OpenFile",
"filter": "所有文件 (.*)|*.*"
}
}
},
{
"name": "moveto_dir_path",
"label": "目标文件夹",
"required": true,
"tips": "输入目标文件夹路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SelectFolder"
}
}
},
{
"name": "move_way",
"label": "如果文件存在",
"required": true,
"default": "10:overwrite",
"defaultDisplay": "覆盖",
"tips": "指定当目标文件夹下已存在同名文件时要执行的操作",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "覆盖",
"value": "overwrite"
},
{
"display": "不要移动",
"value": "not_copy"
}
]
}
}
],
"outputs": [
{
"id": "file_list",
"label": "移动后的文件路径列表",
"variableLabel": "移动后的文件路径列表",
"tips": "输入一个名字,移动后的文件路径列表",
"type": "list<str>",
"name": "file_list"
}
]
},
{
"name": "file.get_file_parts",
"function": "xbot_visual.file.get_file_parts",
"title": "获取文件路径信息",
"description": "获取文件路径的根目录、父目录、文件名、基本文件名和文件扩展名",
"comment": "解析文件%path%信息,将结果保存到%file_parts%",
"icon": "BlockIcons/18-8.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/文件/获取文件路径信息.html",
"inputs": [
{
"name": "path",
"label": "文件路径",
"required": true,
"tips": "输入文件路径",
"type": "any",
"editor": {
"kind": "textbox",
"dialog": {
"type": "OpenFile",
"filter": "所有文件 (.*)|*.*"
}
}
}
],
"outputs": [
{
"id": "file_parts",
"label": "文件路径信息",
"variableLabel": "文件路径信息",
"tips": "输入一个名字,用来保存文件路径信息",
"type": "xbot_visual.file.FileParts",
"name": "file_parts"
}
]
},
{
"name": "file.wait",
"function": "xbot_visual.file.wait",
"title": "等待文件",
"description": "等待文件被创建或者删除",
"comment": "等待文件%path%被%desired_state%,最多等待%timeout%秒",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.File.WaitFileControl, ShadowBot.Shell.Development",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.File.WaitFileHandler"
}
],
"icon": "BlockIcons/18-9.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/等待/等待文件.html",
"video": {
"time": "04:46"
},
"inputs": [
{
"name": "path",
"label": "文件路径",
"required": true,
"tips": "输入文件路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "OpenFile",
"filter": "所有文件 (.*)|*.*"
}
}
},
{
"name": "desired_state",
"label": "等待文件被",
"required": true,
"default": "10:created",
"defaultDisplay": "创建",
"tips": "选择期望的文件状态",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "创建",
"value": "created"
},
{
"display": "删除",
"value": "deleted"
}
]
}
},
{
"name": "is_wait",
"label": "",
"required": true,
"tips": "设置超时时间",
"type": "bool",
"default": "13:True",
"editor": {
"label": "设置超时时间",
"kind": "checkbox"
}
},
{
"name": "timeout_seconds",
"label": "超时时间(秒)",
"required": false,
"default": "10:20",
"tips": "请输入超时时间(秒),",
"type": "int",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "file_wait_result",
"label": "等待结果",
"tips": "如果为True则等待成功,否则等待超时",
"name": "file_wait_result",
"type": "bool"
}
]
},
{
"name": "file.rename",
"function": "xbot_visual.file.rename",
"title": "文件重命名",
"description": "文件重命名",
"comment": "将文件%path%重命名为%new_name%,将新的文件路径保存到%new_file_path%",
"icon": "BlockIcons/18-10.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/文件/文件重命名.html",
"inputs": [
{
"name": "path",
"label": "要重命名的文件",
"required": true,
"tips": "输入或选择要重命名的文件路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "OpenFile",
"filter": "所有文件 (.*)|*.*"
}
}
},
{
"name": "new_name",
"label": "新的文件名称",
"required": true,
"tips": "新的文件名称",
"type": "str",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "new_file_path",
"label": "新的文件路径",
"variableLabel": "重命名后的文件路径",
"tips": "输入一个名字,用来保存新的文件路径",
"type": "str",
"name": "new_file_path"
}
]
}
]
}

View File

@@ -0,0 +1,684 @@
{
"types": [
{
"name": "xbot.ftp.FTPBase",
"localName": "FTP对象"
}
],
"blocks": [
{
"name": "ftp.connection",
"function": "xbot_visual.ftp.connection",
"title": "建立FTP连接",
"description": "创建一个文件服务器连接,并返回连接对象",
"comment": "使用输入密码为用户%user_name%建立%server_kind%%server_ip%:%server_port%)的连接,将连接对象保存到%ftp_instance%",
"icon": "BlockIcons/32-1.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/ftp/建立ftp连接.html",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.FTP.ConnectionControl, ShadowBot.Shell.Development",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.FTP.ConnectionHandler"
}
],
"inputs": [
{
"name": "server_kind",
"label": "服务器类型",
"tips": "要创建的连接对象的服务器类型",
"type": "str",
"required": true,
"default": "10:FTP",
"defaultDisplay": "FTP服务器",
"editor": {
"kind": "select",
"options": [
{
"display": "FTP服务器",
"value": "FTP"
},
{
"display": "SFTP服务器",
"value": "SFTP"
}
]
}
},
{
"name": "server_ip",
"label": "FTP服务器地址",
"required": true,
"tips": "FTP服务器地址",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "server_port",
"label": "FTP服务器端口",
"required": true,
"tips": "FTP服务器端口",
"default": "10:21",
"type": "int",
"editor": {
"kind": "textbox",
"minValue": 0
}
},
{
"name": "is_active",
"label": "",
"default": "13:False",
"tips": "通常更推荐使用ftp被动模式。但如果FTP服务器配置为仅支持主动模式或者服务端网络配置不允许被动模式的数据连接此时客户端就需要使用主动模式。",
"type": "bool",
"editor": {
"kind": "checkbox",
"label": "启用主动模式"
}
},
{
"name": "ispasv",
"label": "",
"default": "13:False",
"tips": "当客户端和服务端之间存在连接安全问题如存在防火墙导致服务端无法主动创建数据传输连接时可以启用主动连接模式",
"type": "bool",
"editor": {
"kind": "checkbox",
"label": "启用主动连接"
}
},
{
"name": "login_kind",
"label": "连接方式",
"tips": "连接远程服务器的方式,默认使用密码连接",
"type": "str",
"required": true,
"default": "10:usePassword",
"defaultDisplay": "密码连接",
"editor": {
"kind": "select",
"options": [
{
"display": "密码连接",
"value": "usePassword"
},
{
"display": "密钥连接",
"value": "usePrivateKey"
}
]
}
},
{
"name": "user_name",
"label": "用户名",
"required": true,
"tips": "用于连接到FTP服务器的用户名称",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "password",
"label": "密码",
"tips": "用于连接到FTP服务器的用户密码",
"type": "str",
"default": "10:",
"editor": {
"kind": "password"
}
},
{
"name": "private_key",
"label": "密钥文件",
"tips": "用于连接到服务器的密钥文件",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "OpenFile",
"filter": "所有文件 (.*)|*.*"
}
}
},
{
"name": "timeout",
"label": "连接超时时间",
"tips": "FTP连接的超时时间,默认超时时间10s,设置为-1表示一直等待,0表示不等待",
"required": true,
"category": "advanced",
"default": "10:10",
"type": "int",
"editor": {
"kind": "textbox",
"minValue": 0
}
}
],
"outputs": [
{
"id": "ftp_instance",
"label": "保存FTP连接对象至",
"tips": "指定一个变量名称,该变量用于保存FTP连接对象",
"name": "ftp_instance",
"type": "xbot.ftp.FTPBase"
}
]
},
{
"name": "ftp.disconnection",
"function": "xbot_visual.ftp.disconnection",
"title": "断开FTP连接",
"description": "断开当前FTP连接",
"comment": "断开当前%ftp%连接",
"icon": "BlockIcons/32-12.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/ftp/断开ftp连接.html",
"inputs": [
{
"name": "ftp",
"label": "FTP连接对象",
"tips": "需要断开连接的FTP对象",
"required": true,
"type": "xbot.ftp.FTPBase",
"editor": {
"useVariableOptions": true,
"kind": "select"
}
}
]
},
{
"name": "ftp.get_ftp_files",
"function": "xbot_visual.ftp.get_ftp_files",
"title": "获取全部文件",
"description": "获取FTP服务端当前路径下的全部文件和子文件夹",
"comment": "获取FTP连接%ftp%中当前工作路径下的全部文件和子文件夹,将结果保存到%files_result%",
"icon": "BlockIcons/32-2.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/ftp/获取全部文件.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.FTP.GetFTPFilesBlockHandler"
}
],
"inputs": [
{
"name": "ftp",
"label": "FTP连接对象",
"tips": "需要获取文件和文件夹信息的FTP连接对象",
"required": true,
"type": "xbot.ftp.FTPBase",
"editor": {
"useVariableOptions": true,
"kind": "select"
}
}
],
"outputs": [
{
"id": "files_result",
"label": "保存返回的文件至",
"tips": "指定一个变量名称,该变量用于保存返回的文件和子文件数据",
"name": "files_result",
"type": "dict"
}
]
},
{
"name": "ftp.change_workspace_path",
"function": "xbot_visual.ftp.change_workspace_path",
"title": "切换工作路径",
"description": "切换FTP连接的工作路径",
"comment": "切换FTP连接%ftp%中的工作路径到%new_remote_path%",
"icon": "BlockIcons/32-3.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/ftp/切换工作路径.html",
"inputs": [
{
"name": "ftp",
"label": "FTP连接对象",
"tips": "需要切换工作路径的ftp连接对象",
"required": true,
"type": "xbot.ftp.FTPBase",
"editor": {
"useVariableOptions": true,
"kind": "select"
}
},
{
"name": "new_remote_path",
"label": "工作路径",
"tips": "需要切换到的新工作路径",
"required": true,
"type": "str",
"editor": {
"kind": "textbox"
}
}
]
},
{
"name": "ftp.download_files",
"function": "xbot_visual.ftp.download_files",
"title": "文件下载(ftp)",
"keywords": "下载文件;FTP下载",
"description": "将FTP远程服务器指定路径下的一个或多个文件下载到本地指定的路径下",
"comment": "将FTP连接%ftp%中的文件%download_files%下载到本地路径%local_path%中,如果本地存在同名文件则%download_mode%",
"icon": "BlockIcons/32-4.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/ftp/文件下载.html",
"inputs": [
{
"name": "ftp",
"label": "FTP连接对象",
"tips": "要下载的文件的ftp连接对象",
"required": true,
"type": "xbot.ftp.FTPBase",
"editor": {
"useVariableOptions": true,
"kind": "select"
}
},
{
"name": "download_files",
"label": "远程文件(文件列表)",
"tips": "需要下载的文件或文件列表",
"type": "any",
"editor": {
"kind": "textbox"
}
},
{
"name": "local_path",
"label": "本地路径",
"tips": "远程文件将要下载到本地的路径",
"required": true,
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SelectFolder"
}
}
},
{
"name": "download_mode",
"label": "下载模式",
"tips": "需要下载的文件在本地文件夹存在时的处理方式",
"type": "str",
"required": true,
"default": "10:overwrite",
"defaultDisplay": "覆盖",
"editor": {
"kind": "select",
"options": [
{
"display": "覆盖",
"value": "overwrite"
},
{
"display": "放弃下载",
"value": "notdownload"
},
{
"display": "自动生成文件名",
"value": "uniquename"
}
]
}
}
]
},
{
"name": "ftp.download_folders",
"function": "xbot_visual.ftp.download_folders",
"title": "文件夹下载(ftp)",
"keywords": "下载文件夹;FTP下载",
"description": "将FTP远程服务器指定路径下的一个或多个文件夹下载到本地指定的路径下",
"comment": "将FTP连接%ftp%中的文件夹%remote_paths%下载到本地路径%local_path%中",
"icon": "BlockIcons/32-5.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/ftp/文件夹下载.html",
"inputs": [
{
"name": "ftp",
"label": "FTP连接对象",
"tips": "要下载的文件夹的ftp连接对象",
"required": true,
"type": "xbot.ftp.FTPBase",
"editor": {
"useVariableOptions": true,
"kind": "select"
}
},
{
"name": "remote_paths",
"label": "远程文件夹(文件夹列表)",
"tips": "下载文件夹的远程路径,不填则默认下载当前工作路径",
"required": true,
"type": "any",
"editor": {
"kind": "textbox"
}
},
{
"name": "local_path",
"label": "本地路径",
"tips": "文件夹下载保存的本地路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SelectFolder"
}
}
},
{
"name": "download_mode",
"label": "子文件存在时",
"tips": "需要下载的文件夹中子文件在本地文件夹存在时的处理方式",
"type": "str",
"required": true,
"default": "10:overwrite",
"defaultDisplay": "覆盖",
"editor": {
"kind": "select",
"options": [
{
"display": "覆盖",
"value": "overwrite"
},
{
"display": "放弃下载",
"value": "notdownload"
},
{
"display": "自动生成文件名",
"value": "uniquename"
}
]
}
}
]
},
{
"name": "ftp.uoload_files",
"function": "xbot_visual.ftp.upload_files",
"title": "文件上传(ftp)",
"keywords": "上传文件;FTP上传",
"description": "将本地一个或多个文件上传到FTP远程服务的指定路径下",
"comment": "将本地文件%local_files%上传到FTP连接%ftp%中指定的路径%remote_path%下,如果远程路径下存在同名文件则%upload_mode%",
"icon": "BlockIcons/32-6.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/ftp/文件上传.html",
"inputs": [
{
"name": "ftp",
"label": "FTP连接对象",
"tips": "文件要上传到的FTP连接对象",
"required": true,
"type": "xbot.ftp.FTPBase",
"editor": {
"useVariableOptions": true,
"kind": "select"
}
},
{
"name": "remote_path",
"label": "远程路径",
"tips": "文件要上传到远程服务器的路径,不填则默认上传到当前工作路径",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "local_files",
"label": "本地文件(文件列表)",
"tips": "要上传的本地文件或文件列表",
"required": true,
"type": "any",
"editor": {
"kind": "textbox",
"dialog": {
"type": "OpenFile",
"filter": "所有文件 (.*)|*.*"
}
}
},
{
"name": "upload_mode",
"label": "上传模式",
"tips": "要上传的文件在远程服务器上存在时的处理方式",
"type": "str",
"required": true,
"default": "10:overwrite",
"defaultDisplay": "覆盖",
"editor": {
"kind": "select",
"options": [
{
"display": "覆盖",
"value": "overwrite"
},
{
"display": "放弃上传",
"value": "notupload"
},
{
"display": "自动生成文件名",
"value": "uniquename"
}
]
}
}
]
},
{
"name": "ftp.upload_folders",
"function": "xbot_visual.ftp.upload_folders",
"title": "文件夹上传(ftp)",
"keywords": "上传文件夹;FTP上传",
"description": "将本地一个或多个文件夹上传到FTP远程服务的指定路径下",
"comment": "将本地文件夹%local_folders%上传到FTP连接%ftp%中",
"icon": "BlockIcons/32-7.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/ftp/文件夹上传.html",
"inputs": [
{
"name": "ftp",
"label": "FTP连接对象",
"tips": "文件夹要上传到的FTP连接对象",
"required": true,
"type": "xbot.ftp.FTPBase",
"editor": {
"useVariableOptions": true,
"kind": "select"
}
},
{
"name": "remote_path",
"label": "远程路径",
"tips": "本地文件夹需要上传到的远程路径,不填则默认上传到当前工作路径",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "local_folders",
"label": "本地文件夹(文件夹列表)",
"tips": "需要上传到远程服务器的本地的一个或多个文件夹",
"required": true,
"type": "any",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SelectFolder"
}
}
},
{
"name": "upload_mode",
"label": "子文件存在时",
"tips": "要上传的文件夹中子文件在远程服务器上存在时的处理方式",
"type": "str",
"required": true,
"default": "10:overwrite",
"defaultDisplay": "覆盖",
"editor": {
"kind": "select",
"options": [
{
"display": "覆盖",
"value": "overwrite"
},
{
"display": "放弃上传",
"value": "notupload"
},
{
"display": "自动生成文件名",
"value": "uniquename"
}
]
}
}
]
},
{
"name": "ftp.delete_files",
"function": "xbot_visual.ftp.delete_files",
"title": "文件删除(ftp)",
"keywords": "删除文件",
"description": "删除远程路径指定的一个或多个文件",
"comment": "删除FTP连接%ftp%中的文件%remote_files%",
"icon": "BlockIcons/32-8.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/ftp/文件删除.html",
"inputs": [
{
"name": "ftp",
"label": "FTP连接对象",
"tips": "需要删除文件的FTP远程连接对象",
"required": true,
"type": "xbot.ftp.FTPBase",
"editor": {
"useVariableOptions": true,
"kind": "select"
}
},
{
"name": "remote_files",
"label": "删除的文件(文件列表)",
"tips": "需要删除的远程文件名称",
"required": true,
"type": "any",
"editor": {
"kind": "textbox"
}
}
]
},
{
"name": "ftp.rename_file",
"function": "xbot_visual.ftp.rename_file",
"title": "文件重命名(ftp)",
"description": "重命名远程服务器的文件",
"comment": "将FTP连接%ftp%中的文件%remote_file%重命名为%new_name%",
"icon": "BlockIcons/32-9.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/ftp/文件重命名.html",
"inputs": [
{
"name": "ftp",
"label": "FTP连接对象",
"tips": "需要重命名文件的FTP远程连接对象",
"required": true,
"type": "xbot.ftp.FTPBase",
"editor": {
"useVariableOptions": true,
"kind": "select"
}
},
{
"name": "remote_file",
"label": "远程文件",
"tips": "需要重命名的远程文件",
"required": true,
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "new_name",
"label": "新名称",
"tips": "远程文件重命名后的名称",
"required": true,
"type": "str",
"editor": {
"kind": "textbox"
}
}
]
},
{
"name": "ftp.creat_directory",
"function": "xbot_visual.ftp.creat_directory",
"title": "创建文件夹(ftp)",
"description": "在远程服务器上创建文件夹",
"comment": "在FTP连接%ftp%中创建文件夹%new_remote_path%",
"icon": "BlockIcons/32-10.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/ftp/创建文件夹.html",
"inputs": [
{
"name": "ftp",
"label": "FTP连接对象",
"tips": "需要创建文件夹的FTP连接对象",
"required": true,
"type": "xbot.ftp.FTPBase",
"editor": {
"useVariableOptions": true,
"kind": "select"
}
},
{
"name": "new_remote_path",
"label": "新文件夹",
"tips": "需要创建的文件夹名称",
"required": true,
"type": "str",
"editor": {
"kind": "textbox"
}
}
]
},
{
"name": "ftp.delete_folder",
"function": "xbot_visual.ftp.delete_folder",
"title": "删除文件夹(ftp)",
"description": "删除远程服务器上的文件夹",
"comment": "删除FTP连接%ftp%中的文件夹%remote_path%",
"icon": "BlockIcons/32-11.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/ftp/删除文件夹.html",
"inputs": [
{
"name": "ftp",
"label": "FTP连接对象",
"tips": "需要删除文件夹的FTP连接对象",
"required": true,
"type": "xbot.ftp.FTPBase",
"editor": {
"useVariableOptions": true,
"kind": "select"
}
},
{
"name": "remote_path",
"label": "远程文件夹",
"tips": "需要删除的文件夹名称,不填则默认删除当前工作路径",
"required": true,
"type": "str",
"editor": {
"kind": "textbox"
}
}
]
}
]
}

View File

@@ -0,0 +1,628 @@
{
"types": [],
"blocks": [
{
"name": "image.wait",
"icon": "BlockIcons/22-3.png",
"description": "等待目标图像出现或消失,再继续执行流程",
"comment": "等待%window_kind%中图像%template_images%出现,最多等待%timeout%秒",
"title": "等待图像",
"keywords": "等待图片",
"function": "xbot_visual.image.wait",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Image.WaitImageControl, ShadowBot.Shell.Development",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Image.WaitImageHandler"
}
],
"helpUrl": "yddoc/language/zh-cn/指令文档/等待/等待图像.html",
"video": {
"time": "06:01"
},
"inputs": [
{
"name": "window_kind",
"label": "搜索范围",
"required": true,
"default": "10:screen",
"defaultDisplay": "整个屏幕",
"tips": "搜索范围",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "整个屏幕",
"value": "screen"
},
{
"display": "窗口对象",
"value": "window"
},
{
"display": "当前激活窗口",
"value": "currentactivatewindow"
}
]
}
},
{
"name": "window",
"label": "窗口对象",
"required": false,
"tips": "请选择窗口对象",
"type": "xbot.win32.window.Win32Window",
"editor": {
"kind": "select",
"useVariableOptions": true
}
},
{
"name": "wait_mode",
"label": "等待方式",
"required": true,
"default": "10:appear",
"defaultDisplay": "等待目标图像出现",
"tips": "",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "等待目标图像出现",
"value": "appear"
},
{
"display": "等待目标图像消失",
"value": "disappear"
}
]
}
},
{
"name": "template_images",
"label": "目标图像",
"tips": "可从图像库选择多张图,其中任一张\"出现/消失\",则继续执行流程",
"required": true,
"type": "str",
"editor": {
"kind": "images"
}
},
{
"name": "is_wait_all_images",
"label": "",
"required": true,
"default": "13:False",
"tips": "等待所有图像或者只等待其中一张",
"type": "bool",
"editor": {
"label": "等待全部图像出现(消失)后再执行",
"kind": "checkbox"
}
},
{
"name": "iswait",
"label": "",
"required": true,
"default": "13:True",
"tips": "设置等待超时时间,超时后流程将自动往下继续执行",
"type": "bool",
"editor": {
"label": "设置超时时间",
"kind": "checkbox"
}
},
{
"name": "timeout",
"label": "超时时间(秒)",
"default": "10:20",
"tips": "设置最大等待时间",
"type": "int",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "wait_result",
"label": "等待结果",
"tips": "如果为True则等待成功,否则等待超时",
"name": "image_wait_result",
"type": "bool"
}
]
},
{
"name": "image.hover",
"icon": "BlockIcons/22-2.png",
"description": "鼠标悬停在图像上",
"comment": "在%window_kind%中搜索图像%template_images%,将鼠标移动到图像%anchor_type%位置",
"title": "鼠标悬停在图像上",
"keywords": "悬浮;图片;图形",
"function": "xbot_visual.image.hover",
"helpUrl": "yddoc/language/zh-cn/指令文档/鼠标键盘/鼠标悬停在图像上.html",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Image.HoverImageControl, ShadowBot.Shell.Development",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Image.HoverImageHandler"
}
],
"inputs": [
{
"name": "window_kind",
"label": "搜索范围",
"required": true,
"default": "10:screen",
"defaultDisplay": "整个屏幕",
"tips": "搜索范围",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "整个屏幕",
"value": "screen"
},
{
"display": "窗口对象",
"value": "window"
},
{
"display": "当前激活窗口",
"value": "currentactivatewindow"
}
]
}
},
{
"name": "window",
"label": "窗口对象",
"required": false,
"tips": "请选择窗口对象",
"type": "xbot.win32.window.Win32Window",
"editor": {
"kind": "select",
"useVariableOptions": true
}
},
{
"name": "template_images",
"label": "目标图像",
"tips": "可从图像库选择多张图,其中任一张\"出现/消失\",则继续执行流程",
"required": true,
"type": "str",
"editor": {
"kind": "images"
}
},
{
"name": "anchor_type",
"label": "锚点",
"required": true,
"tips": "支持点击元素中心位置(元素矩形区域的中心点)、随机位置(自动随机指定元素矩形范围内的点)、自定义位置(手动指定目标点)",
"type": "str",
"default": "10:center",
"defaultDisplay": "中心点",
"autoFill": true,
"editor": {
"kind": "select",
"options": [
{
"display": "中心点",
"value": "center"
},
{
"display": "随机位置",
"value": "random"
},
{
"display": "自定义",
"value": "custom"
}
]
}
},
{
"name": "sudoku_part",
"label": "目标图像的部位",
"default": "10:middleCenter",
"tips": "选择你要将鼠标移动到图像的哪个部位上",
"required": true,
"type": "str",
"editor": {
"kind": "sudoku"
}
},
{
"name": "offset_x",
"label": "横向偏移",
"required": true,
"default": "10:0",
"tips": "输入 5 表示将鼠标向右移动 5px输入负数代表向左移动鼠标",
"type": "int",
"editor": {
"kind": "textbox"
}
},
{
"name": "offset_y",
"label": "纵向偏移",
"required": true,
"default": "10:0",
"tips": "输入 5 表示将鼠标向下移动 5px输入负数代表向上移动鼠标",
"type": "int",
"editor": {
"kind": "textbox"
}
},
{
"name": "timeout",
"label": "超时时间(秒)",
"default": "10:5",
"tips": "设置最大等待时间",
"category": "advanced",
"type": "int",
"editor": {
"kind": "textbox"
}
},
{
"name": "delay_after",
"label": "执行后延迟(秒)",
"required": true,
"category": "advanced",
"default": "10:1",
"tips": "指令执行完成后的等待时间",
"type": "float",
"editor": {
"kind": "spin",
"minValue": 0
}
}
]
},
{
"name": "image.click",
"icon": "BlockIcons/22-1.png",
"description": "点击图像",
"keywords": "点击图片",
"comment": "在%window_kind%中搜索图像%template_images%%button%%clicks%点击%anchor_type%位置",
"title": "点击图像",
"function": "xbot_visual.image.click",
"helpUrl": "yddoc/language/zh-cn/指令文档/鼠标键盘/点击图像.html",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Image.ClickImageControl, ShadowBot.Shell.Development",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Image.ClickImageHandler"
}
],
"inputs": [
{
"name": "window_kind",
"label": "搜索范围",
"required": true,
"default": "10:screen",
"defaultDisplay": "整个屏幕",
"tips": "搜索范围",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "整个屏幕",
"value": "screen"
},
{
"display": "窗口对象",
"value": "window"
},
{
"display": "当前激活窗口",
"value": "currentactivatewindow"
}
]
}
},
{
"name": "window",
"label": "窗口对象",
"required": false,
"tips": "请选择窗口对象",
"type": "xbot.win32.window.Win32Window",
"editor": {
"kind": "select",
"useVariableOptions": true
}
},
{
"name": "template_images",
"label": "目标图像",
"tips": "可从图像库选择多张图,其中任一张\"出现/消失\",则继续执行流程",
"required": true,
"type": "str",
"editor": {
"kind": "images"
}
},
{
"name": "anchor_type",
"label": "目标图像的部位",
"required": true,
"tips": "支持点击元素中心位置(元素矩形区域的中心点)、随机位置(自动随机指定元素矩形范围内的点)、自定义位置(手动指定目标点)",
"type": "str",
"default": "10:center",
"defaultDisplay": "中心点位置",
"autoFill": true,
"editor": {
"kind": "select",
"options": [
{
"display": "中心点",
"value": "center"
},
{
"display": "随机位置",
"value": "random"
},
{
"display": "自定义",
"value": "custom"
}
]
}
},
{
"name": "sudoku_part",
"label": "目标图像的部位",
"default": "10:middleCenter",
"tips": "选择你要将鼠标移动到图像的哪个部位上",
"required": true,
"type": "str",
"editor": {
"kind": "sudoku"
}
},
{
"name": "offset_x",
"label": "横向偏移",
"required": true,
"default": "10:0",
"tips": "输入 5 表示将鼠标向右移动 5px输入负数代表向左移动鼠标",
"type": "int",
"editor": {
"kind": "textbox"
}
},
{
"name": "offset_y",
"label": "纵向偏移",
"required": true,
"default": "10:0",
"tips": "输入 5 表示将鼠标向下移动 5px输入负数代表向上移动鼠标",
"type": "int",
"editor": {
"kind": "textbox"
}
},
{
"name": "clicks",
"label": "点击次数",
"required": true,
"default": "10:click",
"defaultDisplay": "单击",
"tips": "选择点击的方式是单击还是双击",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "单击",
"value": "click"
},
{
"display": "双击",
"value": "dbclick"
}
]
}
},
{
"name": "button",
"label": "鼠标",
"required": true,
"default": "10:left",
"defaultDisplay": "鼠标左键",
"tips": "选择用于触发点击的鼠标按键",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "鼠标左键",
"value": "left"
},
{
"display": "鼠标右键",
"value": "right"
}
]
}
},
{
"name": "keys",
"label": "键盘",
"required": true,
"default": "10:null",
"defaultDisplay": "无",
"category": "advanced",
"tips": "在点击时需要按下的键盘功能键",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "无",
"value": "null"
},
{
"display": "Alt",
"value": "alt"
},
{
"display": "Ctrl",
"value": "ctrl"
},
{
"display": "Shift",
"value": "shift"
},
{
"display": "Win",
"value": "win"
}
]
}
},
{
"name": "move_mouse",
"label": "",
"required": true,
"default": "13:True",
"category": "advanced",
"tips": "是否显示鼠标移动轨迹",
"type": "bool",
"editor": {
"label": "显示鼠标移动轨迹",
"kind": "checkbox"
}
},
{
"name": "timeout",
"label": "超时时间(秒)",
"default": "10:5",
"tips": "设置最大等待时间",
"type": "int",
"editor": {
"kind": "textbox"
}
},
{
"name": "delay_after",
"label": "执行后延迟(秒)",
"required": true,
"category": "advanced",
"default": "10:1",
"tips": "指令执行完成后的等待时间",
"type": "float",
"editor": {
"kind": "spin",
"minValue": 0
}
}
]
},
{
"name": "image.exist",
"statement": "workflow.if",
"icon": "BlockIcons/22-3.png",
"description": "判断目标图像是否存在",
"comment": "在%window_kind%中,是否%exist_mode%目标图像%template_images%",
"title": "IF 图像存在",
"keywords": "图片存在",
"function": "xbot_visual.image.exist",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Image.ExistImageControl, ShadowBot.Shell.Development",
"indent": "1",
"scope": "1",
"isCondition": true,
"helpUrl": "yddoc/language/zh-cn/指令文档/条件判断/if图像存在.html",
"video": {
"time": "02:11"
},
"inputs": [
{
"name": "window_kind",
"label": "搜索范围",
"required": true,
"default": "10:screen",
"defaultDisplay": "整个屏幕",
"tips": "可选择整个屏幕或指定的窗口",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "整个屏幕",
"value": "screen"
},
{
"display": "窗口对象",
"value": "window"
},
{
"display": "当前激活窗口",
"value": "currentactivatewindow"
}
]
}
},
{
"name": "window",
"label": "窗口对象",
"required": false,
"tips": "请选择窗口对象",
"type": "xbot.win32.window.Win32Window",
"editor": {
"kind": "select",
"useVariableOptions": true
}
},
{
"name": "exist_mode",
"label": "查找方式",
"required": true,
"default": "10:exist",
"defaultDisplay": "存在",
"tips": "指定查找范围内指定的图像存在or不存在",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "存在",
"value": "exist"
},
{
"display": "不存在",
"value": "notexist"
}
]
}
},
{
"name": "template_images",
"label": "目标图像",
"tips": "可从图像库选择多张图像",
"required": true,
"type": "str",
"editor": {
"kind": "images"
}
},
{
"name": "is_find_all_images",
"label": "",
"required": true,
"default": "13:False",
"tips": "检测所有图像或者只检测其中一张",
"type": "bool",
"editor": {
"label": "全部图像存在(不存在)后再执行",
"kind": "checkbox"
}
}
]
}
]
}

View File

@@ -0,0 +1,67 @@
{
"types": [],
"blocks": [
{
"name": "json.to_text",
"function": "xbot_visual.json.to_text",
"title": "Json转换成文本",
"description": "将Json对象转换成文本",
"comment": "将Json对象%json_obj%转换成文本,将结果保存到%text_instance%",
"icon": "BlockIcons/16-1.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/json转换/转换成文本.html",
"inputs": [
{
"name": "json_obj",
"label": "Json对象",
"required": true,
"tips": "输入待转换成文本的Json对象",
"type": "any",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "text_instance",
"label": "保存文本至",
"variableLabel": "Json转换后的文本",
"tips": "输入一个名字用来保存Json对象转换成的文本",
"type": "str",
"name": "text_instance"
}
]
},
{
"name": "json.to_json",
"function": "xbot_visual.json.to_json",
"title": "转换成Json对象",
"description": "这个指令用于将输入的文本转换成Json对象",
"comment": "将文本%text%转换成Json对象将对象保存到%json_instance%",
"icon": "BlockIcons/16-2.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/json转换/转换成json对象.html",
"inputs": [
{
"name": "text",
"label": "文本",
"required": true,
"tips": "输入待转换成Json对象的文本",
"type": "str",
"editor": {
"kind": "memoedit"
}
}
],
"outputs": [
{
"id": "json_instance",
"label": "保存Json对象至",
"variableLabel": "文本转换后的Json对象",
"tips": "输入一个名字用来保存转换得到的Json对象",
"type": "any",
"name": "json_instance"
}
]
}
]
}

View File

@@ -0,0 +1,605 @@
{
"types": [],
"blocks": [
{
"name": "list.create",
"function": "xbot_visual.list.create",
"title": "新建列表",
"description": "新建空的列表,列表为多个数据的数组,例如列表:[\"中国\",\"美国\",\"法国\"]",
"comment": "新建列表,将列表对象保存到%list_instance%",
"icon": "BlockIcons/14-1.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/列表操作/新建列表.html",
"outputs": [
{
"id": "list_instance",
"label": "保存列表对象至",
"variableLabel": "新建的列表对象",
"tips": "输入一个名字,用来保存新建的列表",
"type": "list",
"name": "list_instance"
}
]
},
{
"name": "list.clear",
"function": "xbot_visual.list.clear",
"title": "清空列表",
"description": "这个指令用于清空列表",
"comment": "清空列表对象%lst%",
"icon": "BlockIcons/14-2.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/列表操作/清空列表.html",
"inputs": [
{
"name": "lst",
"label": "列表",
"required": true,
"tips": "输入列表变量",
"type": "list",
"editor": {
"kind": "textbox"
}
}
]
},
{
"name": "list.append_or_insert",
"function": "xbot_visual.list.append_or_insert",
"title": "列表插入一项",
"description": "在列表指定位置插入一项",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.List.ListInsertControl, ShadowBot.Shell.Development",
"comment": "在列表对象%lst%中增加新的一项%elem%",
"icon": "BlockIcons/14-3.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/列表操作/列表添加一项.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.List.ListInsertHandler"
}
],
"inputs": [
{
"name": "lst",
"label": "列表",
"required": true,
"tips": "输入列表变量",
"type": "list",
"editor": {
"kind": "textbox"
}
},
{
"name": "insert_way",
"label": "插入方式",
"required": true,
"default": "10:append",
"defaultDisplay": "末尾追加",
"tips": "在列表的末尾或指定位置插入新的一项",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "末尾追加",
"value": "append"
},
{
"display": "指定位置",
"value": "insert"
}
]
}
},
{
"name": "index",
"label": "插入到",
"required": false,
"default": "10:0",
"tips": "输入待插入的位置。正着数第一项填写0第二项填写1以此类推倒着数倒数第一项填写-1倒数第二项填写-2以此类推。插入后原项将后移。",
"type": "int",
"editor": {
"placeholder": "0表示第1项1表示第2项...支持负数,-n表示倒数第n项",
"kind": "textbox"
}
},
{
"name": "elem",
"label": "插入项内容",
"required": true,
"tips": "输入待插入的项内容",
"type": "any",
"editor": {
"kind": "textbox"
}
}
]
},
{
"name": "list.set_elem",
"function": "xbot_visual.list.set_elem",
"title": "修改列表指定位置项的值",
"description": "这个指令用于修改列表指定位置的值",
"comment": "修改列表对象%lst%中第%index%项的值为%elem%",
"icon": "BlockIcons/14-3.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/列表操作/修改列表指定位置的值.html",
"inputs": [
{
"name": "lst",
"label": "列表",
"required": true,
"tips": "输入列表变量",
"type": "list",
"editor": {
"kind": "textbox"
}
},
{
"name": "index",
"label": "项位置",
"required": true,
"tips": "输入项位置。正着数:第一项填写0,第二项填写1,依次类推;倒着数:倒数第一项填写-1;倒数第二项填写-2,依次类推。",
"type": "int",
"editor": {
"kind": "textbox"
}
},
{
"name": "elem",
"label": "修改项",
"required": true,
"tips": "修改列表指定位置项内容",
"type": "any",
"editor": {
"kind": "textbox"
}
}
]
},
{
"name": "list.get_elem",
"function": "xbot_visual.list.get_elem",
"title": "获取列表指定位置项",
"description": "这个指令用于获取列表中指定位置的一项",
"comment": "获取列表对象%lst%中第%index%项的内容,将结果保存到%list_instance%",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.List.UseOutputTypeByInputListItemTypeHandler",
"settings": {
"inputName": "lst",
"outputName": "list_instance"
}
}
],
"icon": "BlockIcons/14-4.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/列表操作/获取列表指定位置项.html",
"inputs": [
{
"name": "lst",
"label": "列表",
"required": true,
"tips": "输入列表变量",
"type": "list",
"editor": {
"kind": "textbox"
}
},
{
"name": "index",
"label": "项位置",
"required": true,
"tips": "输入项位置。正着数:第一项填写0,第二项填写1,依次类推;倒着数:倒数第一项填写-1;倒数第二项填写-2,依次类推。",
"type": "int",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "list_instance",
"label": "保存列表项至",
"variableLabel": "列表项",
"tips": "输入一个名字,用来保存查找到的列表项",
"type": "any",
"name": "element_instance"
}
]
},
{
"name": "list.get_index",
"function": "xbot_visual.list.get_index",
"title": "获取列表指定项的位置",
"description": "获取指定项在列表中的位置列表位置从0开始排序0为第1项1为第2项依次类推",
"comment": "获取列表%lst%中内容为%elem%项的位置,将结果保存到%element_index%",
"icon": "BlockIcons/14-13.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/列表操作/获取列表指定项的位置.html",
"inputs": [
{
"name": "lst",
"label": "列表",
"required": true,
"tips": "输入列表变量",
"type": "list",
"editor": {
"kind": "textbox"
}
},
{
"name": "elem",
"label": "指定项的值",
"required": true,
"tips": "输入列表指定项的值",
"type": "any",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "element_index",
"label": "保存位置至",
"variableLabel": "列表位置",
"tips": "输入一个名字,用来保存查找到的指定项在列表中的位置",
"type": "int",
"name": "element_index"
}
]
},
{
"name": "list.remove",
"function": "xbot_visual.list.remove",
"title": "删除列表一项",
"description": "这个指令用于删除列表中指定的一项",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.List.ListRemove, ShadowBot.Shell.Development",
"comment": "删除列表对象%lst%中第%index%项",
"icon": "BlockIcons/14-5.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/列表操作/删除列表一项.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.List.ListRemoveHandler"
}
],
"inputs": [
{
"name": "lst",
"label": "列表",
"required": true,
"tips": "输入列表变量",
"type": "list",
"editor": {
"kind": "textbox"
}
},
{
"name": "remove_way",
"label": "删除方式",
"required": true,
"default": "10:index",
"defaultDisplay": "按位置删除",
"tips": "在'hellow world'中如果要删除第一个字母'o'选择下表删除需要输入下标4(下标从0开始计数),如果要删除全部的o选择按内容删除则输入字母o'",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "按位置删除",
"value": "index"
},
{
"display": "按内容删除",
"value": "elem"
}
]
}
},
{
"name": "elem",
"label": "待删除的内容",
"required": false,
"tips": "输入待删除的内容",
"type": "any",
"editor": {
"kind": "textbox"
}
},
{
"name": "index",
"label": "待删除的位置",
"required": false,
"tips": "输入删除的位置。正着数:第一项填写0,第二项填写1,依次类推;倒着数:倒数第一项填写-1;倒数第二项填写-2,依次类推。",
"type": "int",
"editor": {
"kind": "textbox"
}
}
]
},
{
"name": "list.sort",
"function": "xbot_visual.list.sort",
"title": "列表排序",
"description": "这个指令用于列表排序",
"comment": "按%sort_way%排序列表对象%lst%",
"icon": "BlockIcons/14-7.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/列表操作/列表排序.html",
"inputs": [
{
"name": "lst",
"label": "列表",
"required": true,
"tips": "输入列表变量",
"type": "list",
"editor": {
"kind": "textbox"
}
},
{
"name": "sort_way",
"label": "排序方式",
"required": true,
"default": "10:descend",
"defaultDisplay": "降序",
"tips": "选择升序或者降序排序列表",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "降序",
"value": "descend"
},
{
"display": "升序",
"value": "ascend"
}
]
}
}
]
},
{
"name": "list.shuffle",
"function": "xbot_visual.list.shuffle",
"title": "列表随机排序",
"description": "这个指令用于列表随机排序",
"comment": "随机排序列表对象%lst%",
"icon": "BlockIcons/14-8.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/列表操作/列表随机排序.html",
"inputs": [
{
"name": "lst",
"label": "列表",
"required": true,
"tips": "输入列表变量",
"type": "list",
"editor": {
"kind": "textbox"
}
}
]
},
{
"name": "list.extend",
"function": "xbot_visual.list.extend",
"title": "合并列表",
"description": "这个指令用于合并列表",
"comment": "合并列表%lst1%和%lst2%到新的列表,将结果保存到%list_instance%",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.List.ExtendBlockHandler",
"settings": {
"inputList1": "lst1",
"inputList2": "lst2",
"outputList": "list_instance"
}
}
],
"icon": "BlockIcons/14-9.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/列表操作/合并列表.html",
"inputs": [
{
"name": "lst1",
"label": "列表1",
"required": true,
"tips": "输入列表变量",
"type": "list",
"editor": {
"kind": "textbox"
}
},
{
"name": "lst2",
"label": "列表2",
"required": true,
"tips": "输入列表变量",
"type": "list",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "list_instance",
"label": "保存列表对象至",
"variableLabel": "合并后的列表对象",
"tips": "输入一个名字,用来保存新建的列表",
"type": "list",
"name": "list_instance"
}
]
},
{
"name": "list.reverse",
"function": "xbot_visual.list.reverse",
"title": "反转列表",
"description": "这个指令用于反转列表",
"comment": "反转列表对象%lst%",
"icon": "BlockIcons/14-10.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/列表操作/反转列表.html",
"inputs": [
{
"name": "lst",
"label": "列表",
"required": true,
"tips": "输入列表变量",
"type": "list",
"editor": {
"kind": "textbox"
}
}
]
},
{
"name": "list.remove_duplicate",
"function": "xbot_visual.list.remove_duplicate",
"title": "列表去重",
"description": "这个指令用于删除列表中重复的项",
"comment": "删除列表对象%lst%中的重复项",
"icon": "BlockIcons/14-11.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/列表操作/列表去重.html",
"inputs": [
{
"name": "lst",
"label": "列表",
"required": true,
"tips": "输入列表变量",
"type": "list",
"editor": {
"kind": "textbox"
}
}
]
},
{
"name": "list.get_duplicate",
"function": "xbot_visual.list.get_duplicate",
"title": "获取两个列表的相同项",
"description": "这个指令用于获取两个列表的相同项",
"comment": "获取列表%lst1%和%lst2%相同的项,将结果保存到%list_instance%",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.List.UseOutputTypeByInputListTypeHandler",
"settings": {
"inputName": "lst1",
"outputName": "list_instance"
}
}
],
"icon": "BlockIcons/14-12.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/列表操作/获取两个列表的相同项.html",
"inputs": [
{
"name": "lst1",
"label": "列表1",
"required": true,
"tips": "输入列表变量",
"type": "list",
"editor": {
"kind": "textbox"
}
},
{
"name": "lst2",
"label": "列表2",
"required": true,
"tips": "输入列表变量",
"type": "list",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "list_instance",
"label": "保存列表对象至",
"variableLabel": "两列表的相同项",
"tips": "输入一个名字,用来保存新建的列表",
"type": "list",
"name": "list_instance"
}
]
},
{
"name": "list.remove_list",
"function": "xbot_visual.list.remove_list",
"title": "过滤列表中的多项",
"description": "这个指令用于过滤列表中的多项",
"comment": "在列表对象%lst1%中过滤列表对象%lst2%所包含的项,将结果保存到新的列表对象%list_instance%",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.List.UseOutputTypeByInputListTypeHandler",
"settings": {
"inputName": "lst1",
"outputName": "list_instance"
}
}
],
"icon": "BlockIcons/14-6.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/列表操作/过滤列表中的多项.html",
"inputs": [
{
"name": "lst1",
"label": "列表1",
"required": true,
"tips": "输入列表变量",
"type": "list",
"editor": {
"kind": "textbox"
}
},
{
"name": "lst2",
"label": "列表2",
"required": true,
"tips": "输入列表变量",
"type": "list",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "list_instance",
"label": "保存列表对象至",
"variableLabel": "过滤后的列表对象",
"tips": "输入一个名字,用来保存新建的列表",
"type": "list",
"name": "list_instance"
}
]
},
{
"name": "list.get_len",
"function": "xbot_visual.list.get_len",
"title": "获取列表长度",
"description": "这个指令用于获取列表长度",
"comment": "获取列表对象%lst%的长度,将结果保存到%list_len%",
"icon": "BlockIcons/14-6.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/列表操作/获取列表长度.html",
"inputs": [
{
"name": "lst",
"label": "列表",
"required": true,
"tips": "输入列表变量",
"type": "list",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "list_len",
"label": "保存列表长度至",
"variableLabel": "列表长度",
"tips": "输入一个名字,用来保存列表长度",
"type": "int",
"name": "list_len"
}
]
}
]
}

View File

@@ -0,0 +1,445 @@
{
"types": [
{
"name": "xbot._mobile.session.DeviceSession",
"localName": "手机连接对象",
"methods": [
{
"display": "udid",
"function": "$0.get_udid()",
"type": "str"
}
]
}
],
"blocks": [
{
"name": "mobile.connect_device",
"title": "连接手机",
"icon": "BlockIcons/27-3.png",
"comment": "连接指定的手机,将连接对象保存到%session%",
"description": "与指定或者所有手机建立连接",
"function": "xbot_visual.mobile.connect_device",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Mobile.ConnectDeviceControl, ShadowBot.Shell.Development",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Mobile.ConnectDeviceHandler"
}
],
"helpUrl": "yddoc/language/zh-cn/指令文档/手机操作自动化/连接手机.html",
"inputs": [
{
"name": "connect_source",
"label": "连接对象",
"required": true,
"tips": "",
"type": "str",
"default": "10:specific",
"defaultDisplay": "指定手机",
"editor": {
"kind": "select",
"options": [
{
"display": "指定手机",
"value": "specific"
},
{
"display": "运行时手动选择",
"value": "runtime_dynamic"
},
{
"display": "运行时连接的一台手机",
"value": "runtime_auto"
},
{
"display": "运行时连接的所有手机",
"value": "all"
}
]
}
},
{
"name": "connect_mode",
"label": "连接模式",
"required": true,
"tips": "Appium某些应用的输入框会无法输入如“闲鱼”需借助 AdbKeyBoard 输入法实现\r\nUiautomator2稳定性高但不支持安卓9及以上版本读写剪贴板需借助 Clipper 剪贴板 APP 实现",
"type": "str",
"default": "10:appium",
"defaultDisplay": "Appium",
"editor": {
"kind": "select",
"options": [
{
"display": "Appium",
"value": "appium"
},
{
"display": "Uiautomator2",
"value": "u2"
}
]
}
},
{
"name": "ingore_failed_device",
"label": "",
"tips": "若勾选,连接失败的手机将添加到连接失败列表中,反之则抛出异常",
"type": "str",
"default": "13:True",
"editor": {
"kind": "checkbox",
"label": "忽略连接失败的手机"
}
},
{
"name": "auto_unlock",
"label": "",
"category": "advanced",
"type": "bool",
"tips": "若勾选,连接时会自动解锁",
"default": "13:False",
"editor": {
"label": "连接时自动解锁",
"kind": "checkbox"
}
},
{
"name": "unlockType",
"label": "锁屏方式",
"category": "advanced",
"type": "str",
"tips": "锁屏方式",
"default": "10:pin",
"editor": {
"kind": "select",
"options": [
{
"display": "数字密码",
"value": "pin"
},
{
"display": "图案密码",
"value": "pattern"
},
{
"display": "复杂密码",
"value": "password"
}
]
}
},
{
"name": "mobile_password",
"label": "",
"category": "advanced",
"type": "str",
"tips": "手机锁屏密码",
"editor": {
"kind": "password"
}
},
{
"name": "custom_name",
"label": "自定义手机名称",
"tips": "请先到设备管理器页面配置手机连接信息",
"type": "str",
"editor": {
"kind": "select",
"options": []
}
}
],
"outputs": [
{
"id": "session",
"label": "保存连接对象至",
"variableLabel": "手机连接对象",
"tips": "该变量保存的是手机连接对象,使用此对象可以对移动手机进行自动化操作",
"name": "device_session",
"type": "xbot._mobile.session.DeviceSession"
},
{
"id": "session_list",
"label": "保存连接对象列表至",
"variableLabel": "手机连接对象列表",
"tips": "该变量保存的是手机连接对象,使用此对象可以对移动手机进行自动化操作",
"name": "device_session_list",
"type": "list<xbot._mobile.session.DeviceSession>"
},
{
"id": "failed_sessions",
"label": "保存连接失败列表至",
"variableLabel": "手机udid",
"tips": "该变量保存的是连接失败手机编号",
"name": "failed_udid_list",
"type": "list<str>"
}
]
},
{
"name": "mobile.connect",
"title": "连接手机",
"icon": "BlockIcons/27-3.png",
"comment": "连接指定的手机,将连接对象保存到%session%",
"description": "与指定手机建立连接",
"function": "xbot_visual.mobile.connect",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Mobile.ConnectControl, ShadowBot.Shell.Development",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Mobile.ConnectHandler"
}
],
"helpUrl": "yddoc/language/zh-cn/指令文档/手机操作自动化/连接手机.html",
"inputs": [
{
"name": "connect_source",
"label": "连接来源",
"required": true,
"tips": "",
"type": "str",
"default": "10:current",
"defaultDisplay": "当前连接的手机",
"editor": {
"kind": "select",
"options": [
{
"display": "当前连接的手机",
"value": "current"
},
{
"display": "指定的手机",
"value": "assign"
}
]
}
},
{
"name": "connect_kind",
"label": "连接类型",
"required": true,
"tips": "",
"type": "str",
"default": "10:local",
"defaultDisplay": "本地连接",
"editor": {
"kind": "select",
"options": [
{
"display": "本地连接",
"value": "local"
},
{
"display": "动态连接",
"value": "dynamic"
}
]
}
},
{
"name": "connect_mode",
"label": "连接模式",
"required": true,
"tips": "Appium某些应用的输入框会无法输入如“闲鱼”需借助 AdbKeyBoard 输入法实现\r\nUiautomator2稳定性高但不支持安卓9及以上版本读写剪贴板需借助 Clipper 剪贴板 APP 实现",
"type": "str",
"default": "10:appium",
"defaultDisplay": "Appium",
"editor": {
"kind": "select",
"options": [
{
"display": "Appium",
"value": "appium"
},
{
"display": "Uiautomator2",
"value": "u2"
}
]
}
},
{
"name": "auto_unlock",
"label": "",
"category": "advanced",
"type": "bool",
"tips": "若勾选,连接时会自动解锁",
"default": "13:False",
"editor": {
"label": "连接时自动解锁",
"kind": "checkbox"
}
},
{
"name": "unlockType",
"label": "锁屏方式",
"category": "advanced",
"type": "str",
"tips": "锁屏方式",
"default": "10:pin",
"editor": {
"kind": "select",
"options": [
{
"display": "数字密码",
"value": "pin"
},
{
"display": "图案密码",
"value": "pattern"
},
{
"display": "复杂密码",
"value": "password"
}
]
}
},
{
"name": "mobile_password",
"label": "",
"category": "advanced",
"type": "str",
"tips": "手机锁屏密码",
"editor": {
"kind": "password"
}
},
{
"name": "custom_name",
"label": "自定义手机名称",
"tips": "请先到设备管理器页面配置手机连接信息",
"type": "str",
"editor": {
"kind": "select",
"options": []
}
}
],
"outputs": [
{
"id": "session",
"label": "保存连接对象至",
"variableLabel": "手机连接对象",
"tips": "该变量保存的是手机连接对象,使用此对象可以对移动手机进行自动化操作",
"name": "device_session",
"type": "xbot._mobile.session.DeviceSession"
}
]
},
{
"name": "mobile.all_connect",
"title": "连接多台手机",
"icon": "BlockIcons/27-26.png",
"comment": "与PC机连接的所有手机建立自动化连接将连接对象保存到%sessions%",
"description": "与PC机连接的所有手机建立自动化连接用于群控场景",
"function": "xbot_visual.mobile.all_connect",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Mobile.MultiConnectHandler"
}
],
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Mobile.MultiConnectControl, ShadowBot.Shell.Development",
"helpUrl": "yddoc/language/zh-cn/指令文档/手机操作自动化/连接多台手机.html?",
"inputs": [
{
"name": "connect_mode",
"label": "连接模式",
"required": true,
"tips": "Appium某些应用的输入框会无法输入如“闲鱼”需借助 AdbKeyBoard 输入法实现\r\nUiautomator2稳定性高但不支持安卓9及以上版本读写剪贴板需借助 Clipper 剪贴板 APP 实现",
"type": "str",
"default": "10:appium",
"defaultDisplay": "Appium",
"editor": {
"kind": "select",
"options": [
{
"display": "Appium",
"value": "appium"
},
{
"display": "Uiautomator2",
"value": "u2"
}
]
}
},
{
"name": "ingore_failed_device",
"label": "",
"tips": "若勾选,连接失败的手机将添加到连接失败列表中,反之则抛出异常",
"type": "str",
"default": "13:True",
"editor": {
"kind": "checkbox",
"label": "忽略连接失败的手机"
}
},
{
"name": "unlockType",
"label": "锁屏方式",
"category": "advanced",
"type": "str",
"tips": "锁屏方式",
"default": "10:pin",
"editor": {
"kind": "select",
"options": [
{
"display": "数字密码",
"value": "pin"
},
{
"display": "图案密码",
"value": "pattern"
},
{
"display": "复杂密码",
"value": "password"
}
]
}
},
{
"name": "auto_unlock",
"label": "",
"category": "advanced",
"type": "bool",
"tips": "若勾选, 连接时会自动解锁",
"default": "13:False",
"editor": {
"label": "连接时自动解锁",
"kind": "checkbox"
}
},
{
"name": "mobile_password",
"label": "",
"category": "advanced",
"type": "str",
"tips": "手机锁屏密码",
"editor": {
"kind": "password"
}
}
],
"outputs": [
{
"id": "sessions",
"label": "保存连接对象列表至",
"variableLabel": "手机连接对象列表",
"tips": "该变量保存的是手机连接对象,使用此对象可以对移动手机进行自动化操作",
"name": "device_session_list",
"type": "list<xbot._mobile.session.DeviceSession>"
},
{
"id": "failed_sessions",
"label": "保存连接失败列表至",
"variableLabel": "手机udid",
"tips": "该变量保存的是连接失败手机编号",
"name": "failed_udid_list",
"type": "list<str>"
}
]
}
]
}

View File

@@ -0,0 +1,405 @@
{
"types": [
{
"name": "xbot_visual_ocr_lexical_words",
"localName": "文本分词",
"python": "xbot_visual._core.xbot_visual_ocr_lexical_words",
"props": [
{
"name": "words",
"type": "list<str>",
"label": "词汇集"
},
{
"name": "raw_data",
"type": "any",
"label": "原始数据"
}
]
},
{
"name": "xbot_visual_ocr_lexical_item",
"localName": "实体属性对象",
"python": "xbot_visual._core.xbot_visual_ocr_lexical_item",
"props": [
{
"name": "word",
"type": "str",
"label": "词汇"
},
{
"name": "type",
"type": "str",
"label": "实体类型"
},
{
"name": "pos",
"type": "str",
"label": "词性"
}
]
},
{
"name": "list<xbot_visual_ocr_lexical_item>",
"localName": "实体属性对象列表",
"base": "list",
"listItemType": "xbot_visual_ocr_lexical_item"
},
{
"name": "xbot_visual_ocr_lexical_detail",
"localName": "实体抽取结果",
"pythonName": "xbot_visual._core.xbot_visual_ocr_lexical_detail",
"props": [
{
"name": "words",
"type": "list<xbot_visual_ocr_lexical_item>",
"label": "属性集"
},
{
"name": "raw_data",
"type": "any",
"label": "原始数据"
}
]
},
{
"name": "xbot_visual_ocr_sentiment",
"localName": "情感分析结果",
"python": "xbot_visual._core.xbot_visual_ocr_sentiment",
"props": [
{
"name": "sentiment",
"type": "str",
"label": "分类结果"
},
{
"name": "positive",
"type": "float",
"label": "积极类别的概率"
},
{
"name": "negative",
"type": "float",
"label": "消极类别的概率"
},
{
"name": "raw_data",
"type": "any",
"label": "原始数据"
}
]
},
{
"name": "xbot_visual_ocr_similarity",
"localName": "相似度分析结果",
"python": "xbot_visual._core.xbot_visual_ocr_similarity",
"props": [
{
"name": "score",
"type": "float",
"label": "相似度"
},
{
"name": "raw_data",
"type": "any",
"label": "原始数据"
}
]
}
],
"blocks": [
{
"name": "nlp.lexical_analysis",
"icon": "BlockIcons/23-6.png",
"description": "将连续的自然语言文本切分成具有语义合理性和完整性的词汇列表",
"comment": "使用%ai_engine%AI引擎对文本%text%进行分词,将分词结果保存到%lexer_result%",
"title": "文本分词",
"function": "xbot_visual.nlp.lexical_analysis",
"helpUrl": "yddoc/language/zh-cn/指令文档/人工智能ai/自然语言处理nlp/文本分词.html",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Nlp.LexicalAnalysisControl, ShadowBot.Shell.Development",
"inputs": [
{
"name": "ai_engine",
"label": "AI引擎",
"default": "10:shadowbot",
"defaultDisplay": "影刀",
"required": true,
"tips": "选择一个AI引擎",
"type": "xbot.ai.AIEngine",
"editor": {
"kind": "select",
"useVariableOptions": true,
"options": [
{
"display": "影刀",
"value": "shadowbot"
}
]
}
},
{
"name": "text",
"label": "文本",
"required": true,
"tips": "输入需要进行分词的文本",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "flag",
"label": "分析模式",
"default": "10:common",
"defaultDisplay": "通用识别",
"tips": "选择一种识别模式",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "通用模式",
"value": "common"
},
{
"display": "高精度模式",
"value": "accurate"
}
]
}
}
],
"outputs": [
{
"id": "lexer_result",
"label": "分词结果保存至",
"variableLabel": "文本分词结果",
"tips": "指定一个变量名称,该变量用于存储文本分词结果",
"type": "xbot_visual_ocr_lexical_words",
"name": "lexer_result"
}
]
},
{
"name": "nlp.lexical_analysis_include_location",
"icon": "BlockIcons/23-6.png",
"description": "从目标文本中,识别出实体词汇,比如人名、地名、机构名等",
"comment": "使用%ai_engine%AI引擎对文本%text%进行实体抽取,将抽取结果保存到%lexer_deatil_result%",
"title": "实体抽取",
"function": "xbot_visual.nlp.lexical_analysis_include_location",
"helpUrl": "yddoc/language/zh-cn/指令文档/人工智能ai/自然语言处理nlp/实体抽取.html",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Nlp.LexicalAnalysisIncludeLocationControl, ShadowBot.Shell.Development",
"inputs": [
{
"name": "ai_engine",
"label": "AI引擎",
"default": "10:shadowbot",
"defaultDisplay": "影刀",
"required": true,
"tips": "选择一个AI引擎",
"type": "xbot.ai.AIEngine",
"editor": {
"kind": "select",
"useVariableOptions": true,
"options": [
{
"display": "影刀",
"value": "shadowbot"
}
]
}
},
{
"name": "text",
"label": "文本",
"required": true,
"tips": "输入需要进行实体抽取的文本",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "flag",
"label": "分析模式",
"default": "10:common",
"defaultDisplay": "通用识别",
"tips": "选择一种识别模式",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "通用模式",
"value": "common"
},
{
"display": "高精度模式",
"value": "accurate"
}
]
}
},
{
"name": "pump_type",
"label": "提取目标",
"default": "10:all",
"defaultDisplay": "全部",
"tips": "选择一种需要提取的实体类型",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "全部",
"value": "all"
},
{
"display": "人名",
"value": "PER"
},
{
"display": "地名",
"value": "LOC"
},
{
"display": "机构团体名",
"value": "ORG"
},
{
"display": "时间",
"value": "TIME"
},
{
"display": "产品名",
"value": "PRODUCTION"
}
]
}
}
],
"outputs": [
{
"id": "lexer_deatil_result",
"label": "实体抽取结果保存至",
"variableLabel": "实体抽取结果",
"tips": "指定一个变量名称,该变量用于存储实体抽取结果",
"type": "xbot_visual_ocr_lexical_detail",
"name": "lexer_deatil_result"
}
]
},
{
"name": "nlp.sentiment_analysis",
"icon": "BlockIcons/23-6.png",
"description": "从文本中识别出用户的情感倾向,是积极还是消极,并且提供各自概率",
"comment": "使用%ai_engine%AI引擎对文本%text%进行情感分析,将分析结果保存到%sentiment_result%",
"title": "情感倾向分析",
"function": "xbot_visual.nlp.sentiment_analysis",
"helpUrl": "yddoc/language/zh-cn/指令文档/人工智能ai/自然语言处理nlp/情感倾向分析.html",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Nlp.SentimentAnalysisControl, ShadowBot.Shell.Development",
"inputs": [
{
"name": "ai_engine",
"label": "AI引擎",
"default": "10:shadowbot",
"defaultDisplay": "影刀",
"required": true,
"tips": "选择一个AI引擎",
"type": "xbot.ai.AIEngine",
"editor": {
"kind": "select",
"useVariableOptions": true,
"options": [
{
"display": "影刀",
"value": "shadowbot"
}
]
}
},
{
"name": "text",
"label": "文本",
"required": true,
"tips": "输入需要进行情感分析的文本",
"type": "str",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "sentiment_result",
"label": "情感分析结果保存至",
"variableLabel": "情感分析结果",
"tips": "指定一个变量名称,该变量用于存储情感分析结果",
"type": "xbot_visual_ocr_sentiment",
"name": "sentiment_result"
}
]
},
{
"name": "nlp.text_similarity",
"icon": "BlockIcons/23-6.png",
"description": "分析两个短文本的相似度相似度结果取值01值越大说明相似度越高",
"comment": "使用%ai_engine%AI引擎比较文本1%src_text%与文本2%target_text%的相似性,将比较结果保存到%similarity_result%",
"title": "文本相似度分析",
"function": "xbot_visual.nlp.text_similarity",
"helpUrl": "yddoc/language/zh-cn/指令文档/人工智能ai/自然语言处理nlp/文本相似度分析.html",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Nlp.TextSimilarityControl, ShadowBot.Shell.Development",
"inputs": [
{
"name": "ai_engine",
"label": "AI引擎",
"default": "10:shadowbot",
"defaultDisplay": "影刀",
"required": true,
"tips": "选择一个AI引擎",
"type": "xbot.ai.AIEngine",
"editor": {
"kind": "select",
"useVariableOptions": true,
"options": [
{
"display": "影刀",
"value": "shadowbot"
}
]
}
},
{
"name": "src_text",
"label": "文本1",
"required": true,
"tips": "需要与目标文本计算相似度的源文本",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "target_text",
"label": "文本2",
"required": true,
"tips": "需要与源文本计算相似度的目标文本",
"type": "str",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "similarity_result",
"label": "相似度结果保存至",
"variableLabel": "文本相似度分析结果",
"tips": "指定一个变量名称,该变量用于存储文本相似度分析结果",
"type": "xbot_visual_ocr_similarity",
"name": "similarity_result"
}
]
}
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,687 @@
{
"types": [],
"blocks": [
{
"name": "pdf.extract_text",
"function": "xbot_visual.pdf.extract_text",
"title": "PDF提取文本",
"description": "这个指令用于从PDF文件中提取文本",
"comment": "从%path%文件中提取%page_scope%的文本,将结果保存到%text%",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Pdf.ExtractTextControl, ShadowBot.Shell.Development",
"icon": "BlockIcons/26-1.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/pdf文件/提取文本.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Pdf.ExtractTextHandler"
}
],
"inputs": [
{
"name": "path",
"label": "文件路径",
"required": true,
"tips": "请输入PDF文件路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "OpenFile",
"filter": "PDF文件 (.pdf)|*.pdf"
}
}
},
{
"name": "page_scope",
"label": "提取范围",
"required": true,
"default": "10:all",
"defaultDisplay": "全部",
"tips": "选择提取页码范围",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "全部",
"value": "all"
},
{
"display": "单页",
"value": "single"
},
{
"display": "部分",
"value": "part"
}
]
}
},
{
"name": "page",
"label": "页码",
"required": false,
"tips": "请输入待提取的单页页码",
"type": "int",
"editor": {
"kind": "textbox"
}
},
{
"name": "from_page",
"label": "起始页码",
"required": false,
"tips": "请输入待提取的起始页码",
"type": "int",
"editor": {
"kind": "textbox"
}
},
{
"name": "to_page",
"label": "终止页码",
"required": false,
"tips": "请输入待提取的终止页码, 输入-1表示最后一页",
"type": "int",
"editor": {
"kind": "textbox"
}
},
{
"name": "use_password",
"label": "",
"required": true,
"category": "advanced",
"tips": "打开文件是否需要输入密码",
"type": "bool",
"default": "13:False",
"editor": {
"label": "使用密码",
"kind": "checkbox"
}
},
{
"name": "password",
"label": "密码",
"required": false,
"category": "advanced",
"tips": "请输入文件密码",
"type": "str",
"editor": {
"kind": "password"
}
}
],
"outputs": [
{
"id": "text",
"label": "保存文本至",
"variableLabel": "PDF中提取的文本",
"tips": "请输入一个名字,用来保存文本",
"type": "str",
"name": "text"
}
]
},
{
"name": "pdf.extract_images",
"function": "xbot_visual.pdf.extract_images",
"title": "PDF提取图片",
"description": "这个指令用于从PDF文件中提取图片",
"comment": "从%path%文件中提取%page_scope%的图片,并以%image_name%为名称前缀保存到%save_to_dir%目录下,将图片路径保存到%image_paths%",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Pdf.ExtractImageControl, ShadowBot.Shell.Development",
"icon": "BlockIcons/26-2.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/pdf文件/提取图片.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Pdf.ExtractImageHandler"
}
],
"inputs": [
{
"name": "path",
"label": "文件路径",
"required": true,
"tips": "请输入PDF文件路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "OpenFile",
"filter": "PDF文件 (.pdf)|*.pdf"
}
}
},
{
"name": "page_scope",
"label": "提取范围",
"required": true,
"default": "10:all",
"defaultDisplay": "全部",
"tips": "选择提取页码范围",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "全部",
"value": "all"
},
{
"display": "单页",
"value": "single"
},
{
"display": "部分",
"value": "part"
}
]
}
},
{
"name": "page",
"label": "页码",
"required": false,
"tips": "请输入待提取的单页页码",
"type": "int",
"editor": {
"kind": "textbox"
}
},
{
"name": "from_page",
"label": "起始页码",
"required": false,
"tips": "请输入待提取的起始页码",
"type": "int",
"editor": {
"kind": "textbox"
}
},
{
"name": "to_page",
"label": "终止页码",
"required": false,
"tips": "请输入待提取的终止页码, 输入-1表示最后一页",
"type": "int",
"editor": {
"kind": "textbox"
}
},
{
"name": "name_prefix",
"label": "图片名称前缀",
"required": true,
"tips": "请输入图片名称前缀",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "save_to_dir",
"label": "保存图片至",
"required": true,
"tips": "请输入保存图片的文件夹路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SelectFolder"
}
}
},
{
"name": "use_password",
"label": "",
"required": true,
"category": "advanced",
"tips": "打开文件是否需要输入密码",
"type": "bool",
"default": "13:False",
"editor": {
"label": "使用密码",
"kind": "checkbox"
}
},
{
"name": "password",
"label": "密码",
"required": false,
"category": "advanced",
"tips": "请输入文件密码",
"type": "str",
"editor": {
"kind": "password"
}
}
],
"outputs": [
{
"id": "image_paths",
"label": "保存图片路径列表至",
"variableLabel": "PDF中提取的图片路径列表",
"tips": "请输入一个名字,用来保存图片路径列表至",
"type": "list<str>",
"name": "image_paths"
}
]
},
{
"name": "pdf.extract_pages",
"function": "xbot_visual.pdf.extract_pages",
"title": "导出新PDF文档",
"description": "这个指令用于从当前PDF文件中导出新的PDF文档",
"comment": "从文件%path%中导出部分页,将内容保存到新文件%file_path%",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Pdf.ExtractPdfControl, ShadowBot.Shell.Development",
"icon": "BlockIcons/26-3.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/pdf文件/导出新的pdf文件.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Pdf.ExtractPdfHandler"
}
],
"inputs": [
{
"name": "path",
"label": "原始文件路径",
"required": true,
"tips": "请输入原始文件路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "OpenFile",
"filter": "PDF文件 (.pdf)|*.pdf"
}
}
},
{
"name": "page_scope",
"label": "提取范围",
"required": true,
"default": "10:single",
"defaultDisplay": "单页",
"tips": "选择提取页码范围",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "单页",
"value": "single"
},
{
"display": "部分",
"value": "part"
}
]
}
},
{
"name": "page",
"label": "页码",
"required": false,
"tips": "请输入待导出的单页页码",
"type": "int",
"editor": {
"kind": "textbox"
}
},
{
"name": "from_page",
"label": "起始页码",
"required": false,
"tips": "请输入待导出的起始页码",
"type": "int",
"editor": {
"kind": "textbox"
}
},
{
"name": "to_page",
"label": "终止页码",
"required": false,
"tips": "请输入待导出的终止页码, 输入-1表示最后一页",
"type": "int",
"editor": {
"kind": "textbox"
}
},
{
"name": "save_to",
"label": "新文件保存到",
"required": true,
"tips": "请输入新文件保存路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SaveFile",
"filter": "PDF 文件|*.pdf"
}
}
},
{
"name": "save_way",
"label": "如果文件存在",
"required": true,
"default": "10:add_sequential_suffix",
"defaultDisplay": "文件名称末尾添加序号",
"tips": "请选择若文件已经存在时,文件保存方式",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "覆盖",
"value": "overwrite"
},
{
"display": "终止导出新文件",
"value": "stop_extract_if_exist"
},
{
"display": "文件名称末尾添加序号",
"value": "add_sequential_suffix"
}
]
}
},
{
"name": "use_password",
"label": "",
"required": true,
"category": "advanced",
"tips": "打开文件是否需要输入密码",
"type": "bool",
"default": "13:False",
"editor": {
"label": "使用密码",
"kind": "checkbox"
}
},
{
"name": "password",
"label": "密码",
"required": false,
"category": "advanced",
"tips": "请输入文件密码",
"type": "str",
"editor": {
"kind": "password"
}
}
],
"outputs": [
{
"id": "file_path",
"label": "保存新文件路径至",
"variableLabel": "导出的PDF文件路径",
"tips": "请输入一个名字,用来保存新文件路径",
"type": "str",
"name": "file_path"
}
]
},
{
"name": "pdf.merge_pdfs",
"function": "xbot_visual.pdf.merge_pdfs",
"title": "合并PDF文档",
"description": "这个指令用于合并PDF文档并保存到指定的新文档",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Pdf.MergePdfControl, ShadowBot.Shell.Development",
"comment": "合并%paths%这些文件,将结果保存到%save_to%",
"icon": "BlockIcons/26-4.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/pdf文件/合并pdf文档.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Pdf.MergePdfHandler"
}
],
"inputs": [
{
"name": "paths",
"label": "待合并的文件列表",
"required": true,
"tips": "可同时选择多个文件。或切换到Python模式下输入列表变量比如 ['文件1路径','文件2路径']",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "OpenFiles",
"filter": "PDF文件 (.pdf)|*.pdf"
}
}
},
{
"name": "save_to",
"label": "合并后保存至",
"required": true,
"tips": "请输入合并后的文件保存路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SaveFile",
"filter": "PDF 文件|*.pdf"
}
}
},
{
"name": "save_way",
"label": "如果文件存在",
"required": true,
"default": "10:add_sequential_suffix",
"defaultDisplay": "文件名称末尾添加序号",
"tips": "请选择若文件已经存在时,文件保存方式",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "覆盖",
"value": "overwrite"
},
{
"display": "终止合并",
"value": "stop_extract_if_exist"
},
{
"display": "文件名称末尾添加序号",
"value": "add_sequential_suffix"
}
]
}
},
{
"name": "use_password",
"label": "",
"required": true,
"category": "advanced",
"tips": "打开文件是否需要输入密码",
"type": "bool",
"default": "13:False",
"editor": {
"label": "使用密码",
"kind": "checkbox"
}
},
{
"name": "passwords",
"label": "密码",
"required": false,
"category": "advanced",
"tips": "请输入文件密码,文件密码和文件路径一一对应",
"type": "str",
"editor": {
"kind": "password"
}
},
{
"name": "delimiter",
"label": "分割符",
"required": false,
"category": "advanced",
"tips": "请输入密码分割符",
"type": "str",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "file_path",
"label": "保存合并的路径至",
"variableLabel": "合并后的PDF文件路径",
"tips": "请输入一个名字,用来保存新文件路径",
"type": "str",
"name": "file_path"
}
]
},
{
"name": "pdf.save_pages_to_images",
"function": "xbot_visual.pdf.save_pages_to_images",
"title": "将PDF指定页另存为图片",
"description": "这个指令用于将指定页另存为图片",
"comment": "将文件%path%的指定页另存为图片,并以%name_prefix%为名称前缀保存到目录%save_to_dir%中,将图片保存路径保存到%page_image_paths%",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Pdf.SavePagesToImageControl, ShadowBot.Shell.Development",
"icon": "BlockIcons/26-2.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/pdf文件/将指定页另存为图片.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Pdf.SavePagesToImagesHandler"
}
],
"inputs": [
{
"name": "path",
"label": "文件路径",
"required": true,
"tips": "请输入PDF文件路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "OpenFile",
"filter": "PDF文件 (.pdf)|*.pdf"
}
}
},
{
"name": "page_scope",
"label": "提取范围",
"required": true,
"default": "10:all",
"defaultDisplay": "全部",
"tips": "选择提取页码范围",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "全部",
"value": "all"
},
{
"display": "单页",
"value": "single"
},
{
"display": "部分",
"value": "part"
}
]
}
},
{
"name": "page",
"label": "页码",
"required": false,
"tips": "请输入待提取的单页页码",
"type": "int",
"editor": {
"kind": "textbox"
}
},
{
"name": "from_page",
"label": "起始页码",
"required": false,
"tips": "请输入待提取的起始页码",
"type": "int",
"editor": {
"kind": "textbox"
}
},
{
"name": "to_page",
"label": "终止页码",
"required": false,
"tips": "请输入待提取的终止页码, 输入-1表示最后一页",
"type": "int",
"editor": {
"kind": "textbox"
}
},
{
"name": "name_prefix",
"label": "图片名称前缀",
"required": true,
"tips": "请输入图片名称前缀",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "save_to_dir",
"label": "保存图片至",
"required": true,
"tips": "请输入保存图片的文件夹路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SelectFolder"
}
}
},
{
"name": "use_password",
"label": "",
"required": true,
"category": "advanced",
"tips": "打开文件是否需要输入密码",
"type": "bool",
"default": "13:False",
"editor": {
"label": "使用密码",
"kind": "checkbox"
}
},
{
"name": "password",
"label": "密码",
"required": false,
"category": "advanced",
"tips": "请输入文件密码",
"type": "str",
"editor": {
"kind": "password"
}
}
],
"outputs": [
{
"id": "page_image_paths",
"label": "保存图片路径列表至",
"variableLabel": "PDF中另存为的图片路径列表",
"tips": "请输入一个名字,用来保存图片路径列表至",
"type": "list<str>",
"name": "page_image_paths"
}
]
}
]
}

View File

@@ -0,0 +1,258 @@
{
"types": [],
"blocks": [
{
"name": "process.run",
"statement": "process.run",
"helpUrl": "yddoc/language/zh-cn/指令文档/流程、应用/调用流程.html",
"icon": "BlockIcons/21-2.png",
"title": "调用流程",
"keywords": "调用子流程",
"description": "执行指定名称的内部流程",
"comment": "执行流程%process%",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.RunProcessControl, ShadowBot.Shell.Development",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.RunProcessHandler"
}
],
"inputs": [
{
"name": "process",
"label": "模块名称",
"required": true,
"tips": "选择要执行的模块名称",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "package",
"label": "当前Python包对象",
"required": true,
"tips": "根据当前Python包对象动态导入指定流程",
"default": "11:__name__",
"type": "any",
"editor": {
"kind": "textbox"
}
},
{
"name": "inputs",
"label": "输入参数列表",
"required": false,
"tips": "输入参数列表",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "outputs",
"label": "输出参数列表",
"required": false,
"tips": "输出参数列表",
"type": "str",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "process_result",
"label": "保存流程输出结果至",
"tips": "指定一个变量名称,该变量用于保存用户输入结果,如果用户取消对话框则返回None否则返回dict对象",
"name": "process_result",
"type": "dict"
}
]
},
{
"name": "process.invoke_module",
"statement": "process.invoke_module",
"helpUrl": "yddoc/language/zh-cn/指令文档/流程、应用/调用模块.html",
"icon": "BlockIcons/21-4.png",
"title": "调用模块",
"keywords": "调用python",
"description": "调用应用内的其他模块",
"comment": "调用模块%module%中的%function%方法",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.InvokeModule, ShadowBot.Shell.Development",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.InvokeModuleHandler"
}
],
"inputs": [
{
"name": "module",
"label": "模块名称",
"required": true,
"tips": "选择要执行的模块名称",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "function",
"label": "方法名称",
"required": true,
"tips": "选择要执行的方法名称",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "params",
"label": "方法参数列表",
"required": false,
"tips": "方法参数列表",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "returnType",
"label": "返回值类型",
"required": false,
"tips": "返回值类型",
"type": "str",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "invoke_result",
"label": "模块调用结果",
"variableLabel": "模块调用结果",
"type": "any",
"name": "invoke_result"
}
]
},
{
"name": "process.return",
"statement": "process.return",
"canDebug": false,
"helpUrl": "yddoc/language/zh-cn/指令文档/流程、应用/退出流程.html",
"icon": "BlockIcons/21-1.png",
"description": "退出当前流程并继续执行其他流程",
"comment": "退出当前流程并继续执行其他流程",
"title": "退出当前流程"
},
{
"name": "process.exit",
"statement": "process.exit",
"canDebug": false,
"helpUrl": "yddoc/language/zh-cn/指令文档/流程、应用/应用/终止应用.html",
"icon": "BlockIcons/21-3.png",
"description": "停止整个应用的运行",
"comment": "停止整个应用的运行",
"keywords": "退出应用;结束应用",
"title": "终止应用"
},
{
"name": "process.get_app_params",
"function": "xbot_visual.process.get_app_params",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Process.GetAppParamsHandler"
}
],
"helpUrl": "yddoc/language/zh-cn/指令文档/流程、应用/应用/获取应用参数.html",
"icon": "BlockIcons/21-2.png",
"title": "获取应用参数",
"description": "获取应用参数",
"comment": "获取应用参数,将结果保存到%param_value%",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.GetAppParams, ShadowBot.Shell.Development",
"inputs": [
{
"name": "param_name",
"label": "参数类型",
"type": "str",
"editor": {
"kind": "select",
"options": []
}
}
],
"outputs": [
{
"id": "param_value",
"label": "保存参数值至",
"variableLabel": "应用参数值",
"type": "str",
"name": "param_value"
}
]
},
{
"name": "process.write_to_storage",
"function": "xbot_visual.process.write_to_storage",
"title": "保存自定义数据",
"description": "可持久保存流程中的用户数据",
"comment": "保存自定义数据%content%到%key%",
"icon": "BlockIcons/12-10.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/流程、应用/应用/保存自定义数据.html",
"inputs": [
{
"name": "key",
"label": "读取Key",
"required": true,
"tips": "数据读取时需要, 读取只限同一用户、同一应用 \r\n相同Key多次保存内容会被覆盖",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "content",
"label": "数据内容",
"required": true,
"tips": "需要保存的数据内容长度不超过20000个字符",
"type": "str",
"editor": {
"kind": "textbox"
}
}
]
},
{
"name": "process.read_from_storage",
"function": "xbot_visual.process.read_from_storage",
"title": "读取自定义数据",
"description": "读取流程中已保存的自定义数据",
"comment": "读取自定义数据%key%,将结果保存到%content%",
"icon": "BlockIcons/12-11.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/流程、应用/应用/读取自定义数据.html",
"inputs": [
{
"name": "key",
"label": "Key",
"required": true,
"tips": "“保存自定义数据”指令中指定的读取Key",
"type": "str",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "content",
"label": "数据内容",
"variableLabel": "自定义数据内容",
"tips": "若根据key未找到返回None",
"type": "str",
"name": "content"
}
]
}
]
}

View File

@@ -0,0 +1,538 @@
{
"types": [],
"blocks": [
{
"name": "programing.log",
"title": "打印日志",
"description": "将变量或者文本打印输出,输出内容可在【运行日志】区查看",
"comment": "打印日志(%type%%text%",
"icon": "BlockIcons/8-1.png",
"function": "xbot_visual.programing.log",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/打印日志.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Programing.LogHandler"
}
],
"inputs": [
{
"name": "type",
"label": "日志类型",
"required": true,
"tips": null,
"type": "str",
"default": "10:info",
"defaultDisplay": "信息",
"editor": {
"kind": "select",
"options": [
{
"display": "调试",
"value": "debug"
},
{
"display": "信息",
"value": "info"
},
{
"display": "警告",
"value": "warning"
},
{
"display": "错误",
"value": "error"
}
]
}
},
{
"name": "text",
"label": "日志内容",
"required": true,
"tips": null,
"type": "any",
"editor": {
"kind": "textbox"
}
}
]
},
{
"name": "programing.undefined",
"function": "xbot_visual.programing.undefined",
"icon": "BlockIcons/8-11.png",
"canDebug": false,
"description": "指令在应用中未找到,可尝试升级客户端或联系作者解决",
"comment": "%message% 指令在指令库中未找到",
"title": "未找到指令",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Programing.BlockUndefinedControl, ShadowBot.Shell.Development",
"helpUrl": "",
"sourceBlock": "",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Programing.UndefinedHandler"
}
],
"inputs": [
{
"name": "message",
"label": "名称",
"required": false,
"tips": "未找到的自定义指令的名称",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "sourceBlock",
"label": "元数据",
"required": false,
"tips": "原指令的元数据,请勿修改",
"type": "str",
"editor": {
"kind": "textbox"
}
}
]
},
{
"name": "programing.exportlog",
"title": "导出日志",
"description": "将日志导出到文件",
"comment": "导出日志至 %custom_folder_path%\\%file_name%",
"icon": "BlockIcons/8-16.png",
"function": "xbot_visual.programing.exportlog",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/导出日志.html",
"inputs": [
{
"name": "custom_folder_path",
"label": "文件夹路径",
"required": true,
"tips": "指定文件夹路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SelectFolder"
}
}
},
{
"name": "file_name",
"label": "文件名称",
"required": true,
"default": "10:日志文件.txt",
"tips": "指定文件名称",
"type": "str",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "file_path",
"label": "文件路径",
"variableLabel": "导出的文件路径",
"tips": "指定一个变量名称, 该变量用于保存导出文件的位置",
"type": "str",
"name": "file_path"
}
]
},
{
"name": "programing.sleep",
"title": "等待",
"description": "让流程等待一段时间",
"comment": "等待%seconds%秒后继续运行",
"icon": "BlockIcons/8-2.png",
"function": "xbot_visual.programing.sleep",
"helpUrl": "yddoc/language/zh-cn/指令文档/等待/等待说明.html",
"keywords": "延迟;延时",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Programing.ProgramingSleep",
"video": {
"time": "05:09"
},
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Programing.ProgramingSleepHandler"
}
],
"inputs": [
{
"name": "random_number",
"label": " ",
"required": true,
"default": "13:False",
"tips": "等待时长是随机数",
"type": "bool",
"editor": {
"label": "等待时长随机",
"kind": "checkbox"
}
},
{
"name": "seconds",
"label": "时长(秒)",
"tips": null,
"type": "float",
"default": "10:1",
"editor": {
"kind": "textbox"
}
},
{
"name": "start_number",
"label": "最小时长(秒)",
"required": true,
"tips": "随机数从开始数字到结束数字这一段区间中产生,包括开始数字和结束数字",
"type": "int",
"default": "10:1",
"editor": {
"kind": "textbox"
}
},
{
"name": "stop_number",
"label": "最大时长(秒)",
"required": true,
"tips": "随机数从开始数字到结束数字这一段区间中产生,包括开始数字和结束数字",
"type": "int",
"default": "10:5",
"editor": {
"kind": "textbox"
}
}
]
},
{
"name": "programing.variable",
"title": "设置变量",
"statement": "programing.variable",
"description": "创建一个新的变量并给它赋值,或对已经存在的变量重新赋值",
"comment": "设置%value_type%变量%variable%=%value%",
"icon": "BlockIcons/8-3.png",
"function": "xbot_visual.programing.variable",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Programing.SetVariableControl, ShadowBot.Shell.Development",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/设置变量.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Programing.SetVariableHandler"
}
],
"inputs": [
{
"name": "value_type",
"label": "变量类型",
"tips": "选择要执行的流程名称",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "value",
"label": "变量值",
"required": false,
"tips": "指定变量中保存的值",
"type": "any",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "variable",
"label": "变量名",
"variableLabel": "变量",
"type": "str",
"tips": "输入一个名称作为变量名,将变量值保存至此变量中",
"name": "variable"
}
]
},
{
"name": "programing.random_int",
"icon": "BlockIcons/8-12.png",
"description": "产生随机数",
"comment": "在最小数%start_number%与最大数%stop_number%之间产生随机数,将随机数保存到%random_number%",
"title": "产生随机数",
"function": "xbot_visual.programing.random_int",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/产生随机数.html",
"inputs": [
{
"name": "start_number",
"label": "最小数",
"required": true,
"tips": "随机数从开始数字到结束数字这一段区间中产生,包括开始数字和结束数字",
"type": "int",
"editor": {
"kind": "textbox"
}
},
{
"name": "stop_number",
"label": "最大数",
"required": true,
"tips": "随机数从开始数字到结束数字这一段区间中产生,包括开始数字和结束数字",
"type": "int",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "random_number",
"label": "随机数保存至",
"variableLabel": "随机数",
"tips": "输入一个名字,用来保存产生的随机数",
"type": "int",
"name": "random_number"
}
]
},
{
"name": "programing.snippet",
"title": "插入代码段(Python)",
"statement": "programing.snippet",
"description": "插入代码段(Python)",
"comment": "执行Python语句%snippet%",
"icon": "BlockIcons/8-4.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/插入代码段python.html",
"inputs": [
{
"name": "snippet",
"label": "Python代码段",
"required": true,
"tips": null,
"type": "str",
"editor": {
"kind": "code",
"language": "python"
}
}
]
},
{
"name": "programing.comment",
"statement": "programing.comment",
"title": "添加备注说明",
"keywords": "注释",
"description": "在流程中插入一条文字说明",
"icon": "BlockIcons/8-5.png",
"comment": "%content%",
"isCommentBlock": true,
"isPseudo": true,
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/添加备注说明.html",
"inputs": [
{
"name": "content",
"label": "备注说明",
"required": true,
"tips": null,
"type": "str",
"editor": {
"kind": "PlainText"
}
}
]
},
{
"name": "programing.region",
"statement": "programing.region",
"title": "折叠开始",
"description": "折叠一组指令,使之更易于阅读,折叠从此处开始",
"comment": "说明:%content%",
"icon": "BlockIcons/8-6.png",
"indent": "1",
"scope": "0",
"isPseudo": true,
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/折叠.html",
"inputs": [
{
"name": "content",
"label": "折叠区域名称",
"required": true,
"tips": null,
"type": "str",
"editor": {
"kind": "PlainText"
}
}
]
},
{
"name": "programing.endregion",
"statement": "programing.endregion",
"title": "折叠结束",
"description": "结束一段指令折叠",
"icon": "BlockIcons/8-7.png",
"indent": "2",
"scope": "0",
"isPseudo": true
},
{
"name": "programing.try",
"statement": "programing.try",
"canDebug": false,
"icon": "BlockIcons/8-8.png",
"indent": "1",
"scope": "1",
"comment": "尝试执行",
"keywords": "异常",
"description": "尝试执行开始标记",
"title": "Try",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/异常处理/try.html"
},
{
"name": "programing.catch",
"statement": "programing.catch",
"icon": "BlockIcons/8-9.png",
"indent": "3",
"scope": "3",
"canDebug": false,
"description": "尝试失败时执行",
"comment": "尝试失败时执行, 将错误信息保存到%exception%",
"title": "Catch",
"keywords": "异常",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/异常处理/catch.html",
"outputs": [
{
"id": "exception",
"label": "错误信息",
"variableLabel": "错误信息",
"type": "str",
"tips": "输入一个名称作为保存错误信息的变量,当指令执行出错的时候错误信息将会保存至此变量中",
"name": "exception"
}
]
},
{
"name": "programing.finally",
"statement": "programing.finally",
"icon": "BlockIcons/8-10.png",
"indent": "3",
"scope": "3",
"canDebug": false,
"description": "无论尝试是否成功始终执行",
"comment": "无论尝试是否成功始终执行以下操作",
"title": "Finally",
"keywords": "异常",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/异常处理/finally.html"
},
{
"name": "programing.endtry",
"statement": "programing.endtry",
"icon": "BlockIcons/8-11.png",
"indent": "2",
"scope": "2",
"isPseudo": true,
"description": "尝试执行结束标记",
"comment": "结束尝试执行",
"title": "End Try",
"keywords": "异常",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/异常处理/endtry.html"
},
{
"name": "programing.raise",
"statement": "programing.raise",
"icon": "BlockIcons/8-13.png",
"description": "抛出异常",
"comment": "抛出异常:%reason%",
"title": "Raise",
"keywords": "异常",
"helpUrl": "yddoc/language/zh-cn/指令文档/其他/异常处理/raise.html",
"inputs": [
{
"name": "reason",
"label": "异常原因",
"required": true,
"tips": "异常产生的原因",
"type": "str",
"editor": {
"kind": "textbox"
}
}
]
},
{
"name": "programing.onDelayRunSwitch",
"title": "开始批量等待",
"description": "一次为多个鼠标操作指令添加等待时间",
"comment": "从此处开始,每条鼠标操作指令运行后等待%seconds%秒",
"icon": "BlockIcons/8-14.png",
"indent": "1",
"scope": "1",
"function": "xbot_visual.programing.on_delay_run_switch",
"helpUrl": "doc/指令文档/03等待/开始批量等待.html",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Programing.OnDelayRunSwitchControl",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Programing.OnDelayRunSwitchHandler"
}
],
"inputs": [
{
"name": "random_number",
"label": " ",
"required": true,
"default": "13:True",
"tips": "每条指令结束后,根据最小、最大等待时长生成随机等待时长",
"type": "bool",
"editor": {
"label": "等待时长随机",
"kind": "checkbox"
}
},
{
"name": "seconds",
"label": "时长(秒)",
"required": false,
"tips": "每条指令结束后,等待的固定时长",
"type": "float",
"default": "10:1",
"editor": {
"kind": "textbox"
}
},
{
"name": "min_number",
"label": "最小时长(秒)",
"required": false,
"tips": "指定最小等待时间",
"type": "int",
"default": "10:1",
"editor": {
"kind": "textbox"
}
},
{
"name": "max_number",
"label": "最大时长(秒)",
"required": false,
"tips": "指定最大等待时间",
"type": "int",
"default": "10:3",
"editor": {
"kind": "textbox"
}
}
]
},
{
"name": "programing.offDelayRunSwitch",
"function": "xbot_visual.programing.off_delay_run_switch",
"icon": "BlockIcons/8-15.png",
"indent": "2",
"scope": "2",
"description": "结束批量等待",
"comment": "结束批量等待",
"title": "结束批量等待",
"helpUrl": "doc/指令文档/03等待/结束批量等待.html"
}
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,78 @@
{
"types": [],
"blocks": [
{
"name": "win32.lock_screen",
"function": "xbot_visual.win32.lock_screen",
"title": "屏幕锁屏",
"description": "这个指令用于屏幕锁屏",
"comment": "屏幕锁屏",
"icon": "BlockIcons/31-1.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/锁屏、解锁/屏幕解锁.html"
},
{
"name": "win32.rdp_lock_screen",
"function": "xbot_visual.win32.rdp_lock_screen",
"title": "屏幕锁屏",
"description": "锁住系统屏幕,确保后续指令能在锁屏状态下正常运行",
"comment": "使用%user_name%账户锁屏",
"icon": "BlockIcons/31-1.png",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Rdp.RDPLockScreenControl, ShadowBot.Shell.Development",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/锁屏、解锁/屏幕锁屏.html",
"inputs": [
{
"name": "user_name",
"label": "用户名",
"required": true,
"tips": "请输入用户名",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "password",
"label": "登录密码",
"required": false,
"tips": "输入登录密码",
"type": "str",
"editor": {
"kind": "password"
}
}
]
},
{
"name": "win32.unlock_screen",
"function": "xbot_visual.win32.unlock_screen",
"title": "屏幕解锁",
"description": "解锁系统屏幕,进入系统屏幕",
"comment": "使用%user_name%账户解锁",
"icon": "BlockIcons/31-2.png",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Rdp.UnlockScreenControl, ShadowBot.Shell.Development",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/锁屏、解锁/屏幕解锁.html",
"inputs": [
{
"name": "user_name",
"label": "用户名",
"required": true,
"tips": "请输入用户名",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "password",
"label": "登录密码",
"required": false,
"tips": "输入登录密码",
"type": "str",
"editor": {
"kind": "password"
}
}
]
}
]
}

View File

@@ -0,0 +1,210 @@
{
"types": [],
"blocks": [
{
"name": "resourcesfile.read",
"function": "xbot_visual.resourcesfile.read",
"title": "读取资源文件内容",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.ResourcesFile.ReadFileControl, ShadowBot.Shell.Development",
"description": "读取资源文件内容",
"icon": "BlockIcons/18-3.png",
"comment": "获取资源文件%file_name%的%read_way%",
"helpUrl": "yddoc/language/zh-cn/指令文档/流程、应用/资源文件/读取资源文件内容.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.ResourcesFile.ReadFileHandler"
}
],
"inputs": [
{
"name": "file_name",
"label": "资源文件名",
"required": true,
"tips": "请选择资源文件",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "read_way",
"label": "读取内容",
"required": true,
"default": "10:text",
"defaultDisplay": "文本内容",
"tips": "选择文件的读取方式",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "文本内容",
"value": "text"
},
{
"display": "二进制内容",
"value": "binary"
}
]
}
},
{
"name": "encoding",
"label": "文件编码",
"default": "10:UTF-8",
"defaultDisplay": "UTF-8",
"tips": "选择文本编码",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "默认",
"value": "default"
},
{
"display": "ANSI",
"value": "ANSI"
},
{
"display": "GB2312",
"value": "GB2312"
},
{
"display": "GBK",
"value": "GBK"
},
{
"display": "UTF-8",
"value": "UTF-8"
}
]
}
}
],
"outputs": [
{
"id": "file_content",
"label": "保存文件内容至",
"variableLabel": "资源文件内容",
"tips": "输入一个名字,用来保存文件内容",
"type": "any",
"name": "file_content"
}
]
},
{
"name": "resourcesfile.copy_to",
"title": "拷贝资源文件",
"keywords": "复制资源文件",
"comment": "将资源文件%file_name%的内容拷贝到%dest_file_name%中",
"description": "将资源文件的内容拷贝到指定文件中",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.ResourcesFile.CopyToControl, ShadowBot.Shell.Development",
"icon": "BlockIcons/18-5.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/流程、应用/资源文件/拷贝资源文件.html",
"function": "xbot_visual.resourcesfile.copy_to",
"inputs": [
{
"name": "file_name",
"label": "资源文件名",
"required": true,
"tips": "请选择资源文件",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "dest_file_name",
"label": "资源文件拷贝至",
"required": true,
"tips": "需要将资源文件拷贝到的文件路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SaveFile",
"filter": "所有文件 (.*)|*.*"
}
}
},
{
"name": "copy_way",
"label": "存在同名文件时",
"required": true,
"default": "10:overwrite",
"defaultDisplay": "覆盖",
"tips": "指定当目标文件夹下已存在同名文件时要执行的操作",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "覆盖",
"value": "overwrite"
},
{
"display": "不要拷贝",
"value": "not_copy"
}
]
}
}
]
},
{
"name": "resourcesfile.get_resourcesfile_path",
"function": "xbot_visual.resourcesfile.get_resourcesfile_path",
"title": "获取资源文件路径",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.ResourcesFile.GetResourcesFilePath, ShadowBot.Shell.Development",
"description": "这个指令用来获取指定资源文件路径, 可用于资源文件的快速获取",
"comment": "获取资源文件%file_name%的路径,将文件路径保存到%file_path%",
"icon": "BlockIcons/18-7.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/流程、应用/资源文件/获取资源文件路径.html",
"inputs": [
{
"name": "file_name",
"label": "资源文件名",
"required": true,
"tips": "输入资源文件名",
"type": "str",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "file_path",
"label": "保存文件路径至",
"variableLabel": "资源文件路径",
"tips": "输入一个名字,用来保存文件路径",
"type": "str",
"name": "file_path"
}
]
},
{
"name": "resourcesfile.copy_to_clipboard",
"function": "xbot_visual.resourcesfile.copy_to_clipboard",
"title": "将资源文件添加到剪切板",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.ResourcesFile.CopyToClipboardControl, ShadowBot.Shell.Development",
"description": "用来将资源文件添加到剪切板中,可用于资源文件的快捷发送",
"comment": "将资源文件%file_name%添加到剪切板中",
"icon": "BlockIcons/18-5.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/流程、应用/资源文件/将资源文件添加到剪切板.html",
"inputs": [
{
"name": "file_name",
"label": "资源文件名",
"required": true,
"tips": "输入资源文件名",
"type": "str",
"editor": {
"kind": "textbox"
}
}
]
}
]
}

View File

@@ -0,0 +1,294 @@
{
"types": [],
"blocks": [
{
"name": "win32.element.expand_tree_and_select_node",
"title": "选中树节点(sap)",
"keywords": "选中目标节点",
"description": "扩展树以显示目标节点,然后选中目标节点",
"comment": "在窗口%window%内,选中树%element%的节点%text_path%",
"icon": "BlockIcons/3-3.png",
"function": "xbot_visual.win32.element.expand_tree_and_select_node",
"helpUrl": "yddoc/language/zh-cn/指令文档/桌面软件自动化/sap/选中树节点sap.html",
"inputs": [
{
"name": "window",
"label": "窗口对象",
"required": true,
"default": "10:0",
"tips": "输入一个窗口对象",
"type": "xbot.win32.window.Win32Window",
"autoFill": false,
"editor": {
"kind": "select",
"useVariableOptions": true,
"options": [
{
"display": "根据操作目标自动匹配",
"value": "0"
}
]
}
},
{
"name": "element",
"label": "操作目标",
"required": true,
"tips": "选择一棵节点树",
"type": "xbot.win32.element.Win32Element",
"editor": {
"kind": "uitarget",
"selectorType": "simple"
}
},
{
"name": "text_path",
"label": "节点路径",
"tips": "填写目标节点的位置路径,如 SAP 菜单/会计核算/控制",
"type": "str",
"editor": {
"placeholder": "目标节点的位置,如 SAP 菜单/会计核算/控制",
"kind": "textbox"
}
},
{
"name": "timeout",
"label": "等待元素存在(s)",
"required": true,
"category": "advanced",
"default": "10:20",
"tips": "等待目标树出现的超时时间",
"type": "int",
"editor": {
"kind": "textbox",
"minValue": 0
}
}
],
"outputs": [
{
"id": "tree_item_element",
"label": "保存选中节点元素至",
"variableLabel": "元素对象",
"tips": "指定一个变量名称, 该变量用于保存选中的sap树节点内的指定元素",
"name": "win_element",
"type": "xbot.win32.element.Win32Element"
}
]
},
{
"name": "win32.element.get_table_row_count",
"title": "获取表格总行数(sap)",
"description": "获取数据表格总行数",
"comment": "获取数据表格%element%的总行数,将结果保存到%row_count%",
"icon": "BlockIcons/3-3.png",
"function": "xbot_visual.win32.element.get_table_row_count",
"helpUrl": "yddoc/language/zh-cn/指令文档/桌面软件自动化/sap/获取表格总行数sap.html",
"inputs": [
{
"name": "window",
"label": "窗口对象",
"required": true,
"default": "10:0",
"tips": "输入一个窗口对象",
"type": "xbot.win32.window.Win32Window",
"autoFill": false,
"editor": {
"kind": "select",
"useVariableOptions": true,
"options": [
{
"display": "根据操作目标自动匹配",
"value": "0"
}
]
}
},
{
"name": "element",
"label": "操作目标",
"required": true,
"tips": "选择数据表格 或者 单元格",
"type": "xbot.win32.element.Win32Element",
"editor": {
"kind": "uitarget",
"selectorType": "simple"
}
},
{
"name": "timeout",
"label": "等待元素存在(s)",
"required": true,
"category": "advanced",
"default": "10:20",
"tips": "等待目标表格出现的超时时间",
"type": "int",
"editor": {
"kind": "textbox",
"minValue": 0
}
}
],
"outputs": [
{
"id": "row_count",
"label": "保存总行数至",
"variableLabel": "总行数",
"tips": "指定一个变量名称, 该变量用于保存获取到的总行数",
"name": "row_count",
"type": "int"
}
]
},
{
"name": "win32.element.get_table_column_count",
"title": "获取表格总列数(sap)",
"description": "获取数据表格总列数",
"comment": "获取数据表格%element%的总列数,将结果保存到%column_count%",
"icon": "BlockIcons/3-3.png",
"function": "xbot_visual.win32.element.get_table_column_count",
"helpUrl": "yddoc/language/zh-cn/指令文档/桌面软件自动化/sap/获取表格总列数sap.html",
"inputs": [
{
"name": "window",
"label": "窗口对象",
"required": true,
"default": "10:0",
"tips": "输入一个窗口对象",
"type": "xbot.win32.window.Win32Window",
"autoFill": false,
"editor": {
"kind": "select",
"useVariableOptions": true,
"options": [
{
"display": "根据操作目标自动匹配",
"value": "0"
}
]
}
},
{
"name": "element",
"label": "操作目标",
"required": true,
"tips": "选择数据表格 或者 单元格",
"type": "xbot.win32.element.Win32Element",
"editor": {
"kind": "uitarget",
"selectorType": "simple"
}
},
{
"name": "timeout",
"label": "等待元素存在(s)",
"required": true,
"category": "advanced",
"default": "10:20",
"tips": "等待目标表格出现的超时时间",
"type": "int",
"editor": {
"kind": "textbox",
"minValue": 0
}
}
],
"outputs": [
{
"id": "column_count",
"label": "保存总列数至",
"variableLabel": "总列数",
"tips": "指定一个变量名称, 该变量用于保存获取到的总列数",
"name": "column_count",
"type": "int"
}
]
},
{
"name": "win32.element.get_table_cell_by_rownum_and_columnnum",
"title": "获取单元格(sap)",
"description": "获取表格指定位置的单元格",
"comment": "获取数据表格%element%位于(第%row_num%行,第%column_num%列)处的单元格对象,将对象保存到%table_cell_element%",
"icon": "BlockIcons/3-3.png",
"function": "xbot_visual.win32.element.get_table_cell_by_rownum_and_columnnum",
"helpUrl": "yddoc/language/zh-cn/指令文档/桌面软件自动化/sap/获取单元格sap.html",
"inputs": [
{
"name": "window",
"label": "窗口对象",
"required": true,
"default": "10:0",
"tips": "输入一个窗口对象",
"type": "xbot.win32.window.Win32Window",
"autoFill": false,
"editor": {
"kind": "select",
"useVariableOptions": true,
"options": [
{
"display": "根据操作目标自动匹配",
"value": "0"
}
]
}
},
{
"name": "element",
"label": "操作目标",
"required": true,
"tips": "选择数据表格 或者 单元格",
"type": "xbot.win32.element.Win32Element",
"editor": {
"kind": "uitarget",
"selectorType": "simple"
}
},
{
"name": "row_num",
"label": "行号",
"required": true,
"tips": "单元格所在行的行号, 从1开始",
"type": "int",
"editor": {
"kind": "textbox",
"placeholder": "单元格所在行的行号, 从1开始"
}
},
{
"name": "column_num",
"label": "列号",
"required": true,
"tips": "单元格所在的列的列号, 从1开始",
"type": "int",
"editor": {
"kind": "textbox",
"placeholder": "单元格所在列的列号, 从1开始"
}
},
{
"name": "timeout",
"label": "等待元素存在(s)",
"required": true,
"category": "advanced",
"default": "10:20",
"tips": "等待目标表格出现的超时时间",
"type": "int",
"editor": {
"kind": "textbox",
"minValue": 0
}
}
],
"outputs": [
{
"id": "table_cell_element",
"label": "保存单元格元素至",
"variableLabel": "单元格元素",
"tips": "指定一个变量名称,该变量用于保存获取到的单元格元素",
"name": "table_cell_element",
"type": "xbot.win32.element.Win32Element"
}
]
}
]
}

View File

@@ -0,0 +1,746 @@
{
"types": [
{
"name": "xbot_visual.system.LaunchResult",
"localName": "应用启动信息",
"props": [
{
"name": "pid",
"type": "int",
"label": "进程唯一标识码"
},
{
"name": "main_window_handle",
"type": "int",
"label": "主窗口句柄"
},
{
"name": "exit_code",
"type": "int",
"label": "退出码"
}
]
}
],
"blocks": [
{
"name": "system.run_application",
"function": "xbot_visual.system.run_application",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.SystemOperation.RunApplicationControl, ShadowBot.Shell.Development",
"title": "启动程序",
"description": "这个指令用于执行一个程序或者打开一个文件",
"comment": "运行应用或者打开文件,路径为%application_path%",
"icon": "BlockIcons/10-1.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/启动程序.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.SystemOperation.RunApplicationHandler"
}
],
"inputs": [
{
"name": "application_path",
"label": "应用路径",
"required": true,
"tips": "打开一个程序或者文件",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "OpenFile"
}
}
},
{
"name": "command_line_arguments",
"label": "命令行参数",
"required": false,
"tips": "程序执行的额外参数",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "working_folder",
"label": "工作目录",
"required": false,
"tips": "进程中命令的工作目录",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SelectFolder"
}
}
},
{
"name": "after_application_launch",
"label": "在应用启动之后",
"required": true,
"default": "10:continue",
"defaultDisplay": "继续执行下一条指令",
"tips": "选择是否继续执行指令,或者等待程序执行结束、文件关闭",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "继续执行下一条指令",
"value": "continue"
},
{
"display": "等待应用执行完成",
"value": "wait_to_complete"
}
]
}
},
{
"name": "is_wait_not_more_than",
"label": "",
"required": false,
"default": "13:False",
"tips": "如果不勾选,表示无限等待",
"type": "bool",
"editor": {
"label": "等待时间不超过",
"kind": "checkbox"
}
},
{
"name": "wait_time",
"label": "等待时间",
"required": false,
"default": "10:10",
"tips": "等待程序执行结束或者文件关闭的最长时间",
"type": "int",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "process_id",
"label": "保存进程id至",
"variableLabel": "进程Id",
"tips": "输入一个名称作为保存进程ID,其类型是整数",
"type": "int",
"name": "process_id"
},
{
"id": "exit_code",
"label": "保存退出码至",
"variableLabel": "退出码",
"tips": "输入一个名称作为保存应用退出码, 其类型是整数,-1表示非正常退出",
"type": "int",
"name": "exit_code"
}
]
},
{
"name": "system.run_dos_command",
"function": "xbot_visual.system.run_dos_command",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.SystemOperation.RunDosCommandControl, ShadowBot.Shell.Development",
"title": "运行DOS命令",
"description": "这个指令用于执行DOS命令并返回结果",
"comment": "运行DOS命令%dos_command%,将执行结果保存到%output_info%,将错误信息保存到%err_info%,将退出代码保存到%exit_code%",
"icon": "BlockIcons/10-2.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/运行dos命令.html",
"inputs": [
{
"name": "dos_command",
"label": "DOS命令",
"required": false,
"tips": "输入DOS命令字符串",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "OpenFile"
}
}
},
{
"name": "working_folder",
"label": "工作目录",
"required": false,
"tips": "进程中命令的工作目录",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SelectFolder"
}
}
},
{
"name": "encoding",
"label": "编码格式",
"required": false,
"tips": "设置命令行的文本格式",
"type": "str",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "output_info",
"label": "保存执行结果至",
"variableLabel": "DOS执行结果",
"tips": "输入一个名称作为保存DOS命令执行结果",
"type": "str",
"name": "output_info"
},
{
"id": "err_info",
"label": "保存错误信息至",
"variableLabel": "DOS错误信息",
"tips": "输入一个名称作为保存错误信息",
"type": "str",
"name": "err_info"
},
{
"id": "exit_code",
"label": "保存退出代码至",
"variableLabel": "DOS退出代码",
"tips": "输入一个名称作为保存退出代码,其类型是整数",
"type": "int",
"name": "exit_code"
}
]
},
{
"name": "system.terminal_process",
"function": "xbot_visual.system.terminal_process",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.SystemOperation.TerminalProcessControl, ShadowBot.Shell.Development",
"title": "终止程序",
"description": "这个指令用于终止一个程序",
"comment": "终止程序",
"icon": "BlockIcons/10-3.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/终止程序.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.SystemOperation.TerminalProcessHandler"
}
],
"inputs": [
{
"name": "terminal_way",
"label": "终止方式",
"required": true,
"default": "10:id",
"defaultDisplay": "进程Id",
"tips": "指定通过进程Id或者进程名称来终止进程",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "进程Id",
"value": "id"
},
{
"display": "进程名称",
"value": "name"
}
]
}
},
{
"name": "process_id",
"label": "进程Id",
"required": false,
"tips": "输入你想要终止的进程的Id号",
"type": "int",
"editor": {
"kind": "textbox"
}
},
{
"name": "process_name",
"label": "进程名称",
"required": false,
"tips": "输入你想要终止的进程的名称,如xxx.exe,如果有多个同名的进程将会全部被关闭",
"type": "str",
"editor": {
"kind": "textbox"
}
}
]
},
{
"name": "system.take_screenshot",
"icon": "BlockIcons/10-4.png",
"description": "对屏幕或者窗口截图,保存到剪切板或者文件",
"comment": "从%image_source%截屏,将图像保存到%save_to%",
"title": "截屏",
"keywords": "截图",
"function": "xbot_visual.system.take_screenshot",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/截屏.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.SystemOperation.TakeScreenshotHandler"
}
],
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.SystemOperation.TakeScreenshotControl, ShadowBot.Shell.Development",
"inputs": [
{
"name": "image_source",
"label": "截屏来源",
"required": true,
"default": "10:screen",
"defaultDisplay": "屏幕",
"tips": "选择一个截屏来源",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "屏幕",
"value": "screen"
},
{
"display": "窗口对象",
"value": "window"
},
{
"display": "当前激活窗口",
"value": "foreground_window"
},
{
"display": "动态选择",
"value": "dynamic_select"
}
]
}
},
{
"name": "window",
"label": "窗口对象",
"required": false,
"tips": "请选择窗口对象",
"type": "xbot.win32.window.Win32Window",
"editor": {
"kind": "select",
"useVariableOptions": true
}
},
{
"name": "image_region",
"label": "提取区域",
"default": "10:all_region",
"defaultDisplay": "提取区域",
"tips": "选择图片提取区域",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "全部",
"value": "all_region"
},
{
"display": "指定部分区域",
"value": "sub_region"
}
]
}
},
{
"name": "region_x1",
"label": "X1",
"tips": "图片左上角X值",
"type": "int",
"default": "10:0",
"editor": {
"kind": "textbox"
}
},
{
"name": "region_y1",
"label": "Y1",
"tips": "图片左上角Y值",
"type": "int",
"default": "10:0",
"editor": {
"kind": "textbox"
}
},
{
"name": "region_x2",
"label": "X2",
"tips": "图片右下角X值",
"type": "int",
"default": "10:0",
"editor": {
"kind": "textbox"
}
},
{
"name": "region_y2",
"label": "Y2",
"tips": "图片右下角Y值",
"type": "int",
"default": "10:0",
"editor": {
"kind": "textbox"
}
},
{
"name": "save_to",
"label": "保存截屏至",
"required": true,
"default": "10:clipboard",
"defaultDisplay": "剪切板",
"tips": "选择一个保存当前截屏的方法",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "剪切板",
"value": "clipboard"
},
{
"display": "文件",
"value": "file"
}
]
}
},
{
"name": "image_path",
"label": "图片路径",
"required": false,
"tips": "请选择图片保存路径",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SaveFile",
"filter": "图片(*.jpg;*.bmp;*.png)|*.jpg;*.bmp;*.png"
}
}
}
],
"outputs": [
{
"id": "is_user_cancel",
"label": "用户是否取消截图",
"variableLabel": "截图操作是否取消",
"tips": "输入一个名称作为保存用户是否取消了截图",
"type": "bool",
"name": "is_user_cancel"
}
]
},
{
"name": "win32.set_ime",
"icon": "BlockIcons/20-6.png",
"description": "设置当前激活窗口的输入法",
"comment": "设置当前激活窗口的输入法为%lang%",
"title": "设置输入法",
"function": "xbot_visual.win32.set_ime",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/输入法/设置输入法.html",
"inputs": [
{
"name": "lang",
"label": "切换到",
"required": true,
"default": "10:english",
"defaultDisplay": "英文输入法",
"tips": "选择一个输入法",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "英文输入法",
"value": "english"
},
{
"display": "中文输入法",
"value": "chinese"
}
]
}
}
]
},
{
"name": "win32.get_ime",
"icon": "BlockIcons/20-7.png",
"description": "获取当前激活窗口的输入法的中英文输入状态",
"comment": "获取当前激活窗口的输入法的中英文输入状态,将结果保存到%lang_name%",
"title": "获取输入法",
"function": "xbot_visual.win32.get_ime",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/输入法/获取输入法.html",
"inputs": [],
"outputs": [
{
"id": "lang_name",
"label": "将输入法名称保存至",
"variableLabel": "输入法名称",
"tips": "输入一个名称用来保存输入法名称",
"type": "str",
"name": "lang_name"
}
]
},
{
"name": "system.open_screen_saver",
"icon": "BlockIcons/actionicon_mask_show.png",
"description": "可在保护屏幕信息不被窥视的状态下执行指令,并可展示自定义的文字提示",
"comment": "唤起屏幕保护,在屏保上显示文字%default_text%",
"title": "唤起屏幕保护",
"keywords": "屏保",
"function": "xbot_visual.system.open_screen_saver",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/屏幕保护/唤起屏幕保护.html",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.SystemOperation.CreateScreenSaverControl, ShadowBot.Shell.Development",
"inputs": [
{
"name": "settings",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "default_text",
"label": "提示文字",
"default": "10:影刀机器人正在工作中,请勿操作此电脑",
"tips": "设置屏保显示文字",
"type": "str",
"editor": {
"kind": "memoedit"
}
}
]
},
{
"name": "system.append_screen_saver_text",
"title": "设置屏保提示",
"icon": "BlockIcons/actionicon_mask_text.png",
"description": "设置显示在屏幕保护上的提示文字",
"comment": "在屏保上显示自定义提示内容%text%",
"function": "xbot_visual.system.append_screen_saver_text",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/屏幕保护/设置屏保提示.html",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.SystemOperation.SetScreenSaverTextControl, ShadowBot.Shell.Development",
"inputs": [
{
"name": "text",
"label": "屏保提示",
"required": true,
"tips": "设置屏保显示文字",
"type": "str",
"editor": {
"kind": "memoedit"
}
},
{
"name": "settings",
"label": "提示内容",
"type": "str",
"editor": {
"kind": "textbox"
}
}
]
},
{
"name": "system.clear_screen_saver_text",
"title": "清空屏保提示",
"icon": "BlockIcons/actionicon_mask_clear.png",
"description": "清空屏保上显示的提示",
"comment": "清空屏保上显示的提示",
"function": "xbot_visual.system.clear_screen_saver_text",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/屏幕保护/清空屏保提示.html"
},
{
"name": "system.close_screen_saver",
"title": "关闭屏幕保护",
"keywords": "屏保",
"icon": "BlockIcons/actionicon_mask_close.png",
"description": "关闭已唤起的屏保",
"comment": "关闭已唤起的屏保",
"function": "xbot_visual.system.close_screen_saver",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/屏幕保护/关闭屏幕保护.html"
},
{
"name": "system.run_or_open",
"function": "xbot_visual.system.run_or_open",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.SystemOperation.RunOrOpenControl, ShadowBot.Shell.Development",
"title": "运行或打开",
"keywords": "启动;运行;执行;程序;软件",
"description": "运行软件、打开文件、打开文件夹、打开网址、执行系统命令等",
"comment": "运行或打开%application_path%,将执行结果保存到%process_info%",
"icon": "BlockIcons/10-1.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/操作系统/运行或打开.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.SystemOperation.RunOrOpenHandler"
}
],
"inputs": [
{
"name": "application_path",
"label": "路径或命令",
"required": true,
"tips": "打开一个程序或者文件",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "OpenFile"
}
}
},
{
"name": "command_line_arguments",
"label": "参数(可选)",
"required": false,
"tips": "程序执行的额外参数",
"category": "advanced",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "working_folder",
"label": "工作目录(可选)",
"required": false,
"tips": "进程中命令的工作目录",
"category": "advanced",
"type": "str",
"editor": {
"kind": "textbox",
"dialog": {
"type": "SelectFolder"
}
}
},
{
"name": "after_application_launch",
"label": "在指令执行之后",
"required": true,
"default": "10:continue",
"defaultDisplay": "继续执行下一条指令",
"tips": "选择是否继续执行指令,或者等待程序执行结束、文件关闭",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "继续执行下一条指令",
"value": "continue"
},
{
"display": "等待主窗口出现",
"value": "wait_to_mainwindow"
},
{
"display": "等待应用执行完成",
"value": "wait_to_complete"
}
]
}
},
{
"name": "is_waitexit_not_more_than",
"label": "",
"default": "13:False",
"tips": "如果不勾选, 表示无限等待",
"type": "bool",
"editor": {
"label": "等待时间不超过",
"kind": "checkbox"
}
},
{
"name": "timeout_for_exit",
"label": "等待时间",
"default": "10:10",
"tips": "等待程序执行结束或者文件关闭的最长时间",
"type": "int",
"editor": {
"kind": "textbox"
}
},
{
"name": "is_waithwnd_not_more_than",
"label": "",
"default": "13:False",
"tips": "如果不勾选, 表示无限等待",
"type": "bool",
"editor": {
"label": "等待时间不超过",
"kind": "checkbox"
}
},
{
"name": "timeout_for_hwnd",
"label": "等待时间",
"default": "10:3",
"tips": "等待主窗口出现的最长时间",
"type": "int",
"editor": {
"kind": "textbox"
}
},
{
"name": "start_as_admin",
"label": "",
"default": "13:False",
"tips": "是否以管理员身份运行",
"category": "advanced",
"type": "bool",
"editor": {
"label": "以管理员身份运行",
"kind": "checkbox"
}
},
{
"name": "window_style",
"label": "窗口风格",
"default": "10:normal",
"defaultDisplay": "普通",
"tips": "指定新窗口应如何显示:普通、最小化、最大化",
"type": "str",
"category": "advanced",
"editor": {
"kind": "select",
"options": [
{
"display": "普通",
"value": "normal"
},
{
"display": "最小化",
"value": "minimized"
},
{
"display": "最大化",
"value": "maximized"
}
]
}
}
],
"outputs": [
{
"id": "process_info",
"label": "保存执行结果至",
"variableLabel": "执行结果",
"tips": "输入一个名称,用于保存执行结果",
"type": "xbot_visual.system.LaunchResult",
"name": "process_info"
}
]
}
]
}

View File

@@ -0,0 +1,976 @@
{
"types": [],
"blocks": [
{
"name": "text.get_text_length",
"function": "xbot_visual.text.get_text_length",
"title": "获取文本长度",
"description": "这个指令用于获取文本字符串的长度",
"comment": "获取文本%text%的长度,将文本长度保存到%text_length%",
"icon": "BlockIcons/12-1.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/文本操作/获取文本长度.html",
"inputs": [
{
"name": "text",
"label": "文本内容",
"required": true,
"tips": "输入文本字符串或者一个变量",
"type": "str",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "text_length",
"label": "保存文本长度至",
"variableLabel": "文本长度",
"tips": "输入一个名字,用来保存文本内容的长度,其返回是一个数字类型",
"type": "int",
"name": "text_length"
}
]
},
{
"name": "text.append_text_in_newline",
"function": "xbot_visual.text.append_text_in_newline",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Text.AppendTextInNewlineControl, ShadowBot.Shell.Development",
"title": "追加新文本",
"keywords": "拼接",
"description": "在原始文本后追加新文本内容,完成文本拼接功能",
"comment": "在原始文本%text%后追加新文本%new_line_text%,将结果保存到%result%",
"icon": "BlockIcons/12-2.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/文本操作/追加新文本.html",
"inputs": [
{
"name": "text",
"label": "原始文本",
"required": true,
"tips": "输入文本字符串或者一个变量",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "new_line",
"label": "",
"required": true,
"tips": "是否换行追加",
"type": "bool",
"default": "13:False",
"editor": {
"label": "换行追加",
"kind": "checkbox"
}
},
{
"name": "new_line_text",
"label": "追加文本",
"required": true,
"tips": "输入文本字符串或者一个变量",
"type": "str",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "result",
"label": "保存结果至",
"variableLabel": "追加后的文本",
"tips": "输入一个名字,用来保存结果。当变量名字与原始文本变量名相同的话,就会发生覆盖。",
"type": "str",
"name": "result"
}
]
},
{
"name": "text.sub_text",
"function": "xbot_visual.text.sub_text",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Text.GetSubTextControl, ShadowBot.Shell.Development",
"title": "截取一段文本",
"description": "这个指令用于截取一段文本",
"comment": "截取文本%text%的子内容,将结果保存到%sub_text%",
"icon": "BlockIcons/12-3.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/文本操作/截取一段文本.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Text.GetSubTextHandler"
}
],
"inputs": [
{
"name": "text",
"label": "文本内容",
"required": true,
"tips": "输入文本字符串或者一个变量",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "start_way",
"label": "起始位置",
"required": true,
"default": "10:begin",
"defaultDisplay": "第一个字符",
"tips": "指定起始字符的位置,如果你想要在文本'Hello中国欢迎你'中提取'中国'两个字',那么起始位置就是5",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "从第一个字符开始截取",
"value": "begin"
},
{
"display": "从指定位置开始截取",
"value": "positon"
},
{
"display": "从指定文本开始截取",
"value": "text"
}
]
}
},
{
"name": "start_index",
"label": "起始字符的位置",
"required": false,
"default": "10:0",
"tips": "如果你想要在文本'Hello中国欢迎你'中提取'中国'两个字',那么起始位置就是5",
"type": "int",
"editor": {
"kind": "textbox",
"placeholder": "位置从0开始计算"
}
},
{
"name": "start_text",
"label": "起始文本",
"required": false,
"tips": "如果你想要在文本“购买订单号1234567890”中提取订单号,那么起始位置就是“:”",
"type": "str",
"editor": {
"kind": "textbox",
"placeholder": "输入需要截取的起始文本内容"
}
},
{
"name": "contaion_start_text",
"label": "",
"default": "13:True",
"tips": "勾选时结果中包含起始文本例如“购买订单号1234567890”起始文本设置为“勾选后结果为“1234567890”不勾选结果为“1234567890”",
"type": "bool",
"editor": {
"label": "结果中包含起始文本",
"kind": "checkbox"
}
},
{
"name": "sub_way",
"label": "截取方式",
"required": true,
"default": "10:end",
"defaultDisplay": "截取到最后一个字符",
"tips": "如果你想要在文本'Hello中国欢迎你'中提取'中国'两个字',那么起始位置就是5,截取长度为2,代表从第6个字符开始要截取两个字符",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "截取到最后一个字符",
"value": "end"
},
{
"display": "截取指定长度",
"value": "length"
}
]
}
},
{
"name": "sub_length",
"label": "截取长度",
"default": "10:0",
"required": false,
"tips": "输入你要截取的字符数量",
"type": "int",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "sub_text",
"label": "保存结果至",
"variableLabel": "截取到的文本内容",
"tips": "输入一个名字,用来保存截取到的文本内容",
"type": "str",
"name": "sub_text"
}
]
},
{
"name": "text.pad_text",
"function": "xbot_visual.text.pad_text",
"title": "补齐文本至指定长度",
"description": "这个指令用于补齐文本至指定长度",
"comment": "在原始文本%text%的%pad_way%文本%pad_text%,直至补齐后的总长度为%total_length%,将结果保存到%result_text%",
"icon": "BlockIcons/12-4.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/文本操作/补齐文本至指定长度.html",
"inputs": [
{
"name": "text",
"label": "原始文本",
"required": true,
"tips": "输入文本字符串或者一个变量",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "pad_way",
"label": "补齐方式",
"required": true,
"default": "10:left",
"defaultDisplay": "左端补齐",
"tips": "在原始文本的左端或者右端添加补齐文本",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "左端补齐",
"value": "left"
},
{
"display": "右端补齐",
"value": "right"
}
]
}
},
{
"name": "pad_text",
"label": "用于补齐的文本",
"required": true,
"tips": "输入文本字符串或者一个变量",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "total_length",
"label": "总长度",
"required": true,
"tips": "如果你要在数字1的左端补齐2个0,那么补齐后的内容就是001,总长度就是3",
"type": "int",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "result_text",
"label": "保存结果至",
"variableLabel": "补齐后的文本",
"tips": "输入一个名字,用来保存补齐后的文本内容",
"type": "str",
"name": "result_text"
}
]
},
{
"name": "text.trim_text",
"function": "xbot_visual.text.trim_text",
"title": "删除文本两端的空格",
"description": "这个指令用于删除文本两端的空格(还包括换行符、回车符、制表符)",
"comment": "删除文本%text%中%trim_way%,将结果保存到%trim_text%",
"icon": "BlockIcons/12-5.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/文本操作/删除文本两端的空格.html",
"inputs": [
{
"name": "text",
"label": "原始文本",
"required": true,
"tips": "输入文本字符串或者一个变量",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "trim_way",
"label": "删除方式",
"required": true,
"default": "10:left",
"defaultDisplay": "左端的空格",
"tips": "选择你要删除文本哪一侧的空格",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "左端的空格",
"value": "left"
},
{
"display": "右端的空格",
"value": "right"
},
{
"display": "两端的空格",
"value": "both"
}
]
}
}
],
"outputs": [
{
"id": "trim_text",
"label": "保存结果至",
"variableLabel": "删除空格后的文本",
"tips": "输入一个名字,用来保存删除空格后的文本内容",
"type": "str",
"name": "trim_text"
}
]
},
{
"name": "text.change_text_case",
"function": "xbot_visual.text.change_text_case",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Text.ChangeTextCaseHandler"
}
],
"title": "改变文本的大小写",
"description": "这个指令用于改变文本的大小写(全部大写、全部小写、词首字母大写)",
"comment": "将文本%text%转换成%case_type%,将结果保存到%text_case%",
"icon": "BlockIcons/12-6.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/文本操作/改变文本的大小写.html",
"inputs": [
{
"name": "text",
"label": "文本内容",
"required": true,
"tips": "输入文本字符串或者一个变量",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "case_type",
"label": "转换成",
"required": true,
"default": "10:upper",
"defaultDisplay": "全部大写",
"tips": "选择一个转换方式",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "全部大写",
"value": "upper"
},
{
"display": "全部小写",
"value": "lower"
},
{
"display": "词首字母大写",
"value": "title"
}
]
}
}
],
"outputs": [
{
"id": "text_case",
"label": "保存结果至",
"variableLabel": "转换大小写后的文本",
"tips": "输入一个名字,用来保存转换大小写后的文本内容",
"type": "str",
"name": "text_case"
}
]
},
{
"name": "text.text_to_number",
"function": "xbot_visual.text.text_to_number",
"title": "文本转数字",
"description": "这个指令用于将文本形式的数字转换成一个包含数字的变量",
"comment": "将文本%text%转换成数字,将结果保存到%text_number%",
"icon": "BlockIcons/12-7.png",
"helpUrl": "",
"inputs": [
{
"name": "text",
"label": "文本内容",
"required": true,
"tips": "输入文本字符串或者一个变量",
"type": "str",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "text_number",
"label": "保存结果至",
"variableLabel": "文本转换成的数字",
"tips": "输入一个变量名字,用来保存数字结果",
"type": "int",
"name": "text_number"
}
]
},
{
"name": "text.number_to_text",
"function": "xbot_visual.text.number_to_text",
"title": "数字转文本",
"description": "这个指令用于将数字转换成指定格式的文本",
"comment": "将数字%num%转换成文本,将结果保存到%formatted_number%",
"icon": "BlockIcons/12-8.png",
"helpUrl": "",
"inputs": [
{
"name": "num",
"label": "待转换的数字",
"required": true,
"tips": "请输入一个数字或者一个变量",
"type": "float",
"editor": {
"kind": "textbox"
}
},
{
"name": "float_places",
"label": "小数位数",
"default": "10:2",
"required": true,
"tips": "请输入一个数字或者一个变量",
"type": "int",
"editor": {
"kind": "textbox"
}
},
{
"name": "use_1000_separator",
"label": "",
"required": true,
"default": "13:False",
"tips": "例如数字 10000 用千分位分割显示的话就是 10,000",
"type": "bool",
"editor": {
"label": "千分位分割",
"kind": "checkbox"
}
}
],
"outputs": [
{
"id": "formatted_number",
"label": "保存结果至",
"variableLabel": "数字转换成的文本",
"tips": "输入一个变量名字,用来保存格式化后的结果",
"type": "str",
"name": "formatted_number"
}
]
},
{
"name": "text.join_list_to_text",
"function": "xbot_visual.text.join_list_to_text",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Text.JoinListToTextControl, ShadowBot.Shell.Development",
"title": "列表聚合成文本",
"keywords": "列表转文本",
"description": "这个指令用于将列表中的每个元素用指定的符号连接起来,最终转换成一个文本字符串",
"comment": "用连接符连接列表%list_to_join%中的每个元素,将文本结果保存到%joined_text%",
"icon": "BlockIcons/12-7.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/文本操作/列表聚合成文本.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Text.JoinListToTextHandler"
}
],
"inputs": [
{
"name": "list_to_join",
"label": "待转换的列表",
"required": true,
"tips": "请输入一个列表",
"type": "list",
"editor": {
"kind": "textbox"
}
},
{
"name": "delimiter_way",
"label": "连接符类型",
"required": true,
"default": "10:no",
"defaultDisplay": "无连接符",
"tips": "选择一种连接符类型",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "无连接符",
"value": "no"
},
{
"display": "标准连接符",
"value": "standard"
},
{
"display": "自定义连接符",
"value": "custom"
}
]
}
},
{
"name": "standard_delimiter",
"label": "标准连接符",
"required": false,
"default": "10:space",
"defaultDisplay": "空格符",
"tips": "选择一种连接符",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "空格符",
"value": "space"
},
{
"display": "制表符",
"value": "tab"
},
{
"display": "换行符",
"value": "new_line"
}
]
}
},
{
"name": "num_standard_delimiter",
"label": "连接符的数量",
"required": false,
"default": "10:1",
"tips": "连接符的重复数量",
"type": "int",
"editor": {
"kind": "textbox"
}
},
{
"name": "custom_delimiter",
"label": "自定义的连接符",
"required": false,
"default": "10:",
"tips": "",
"type": "str",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "joined_text",
"label": "保存结果至",
"variableLabel": "列表转换成的文本",
"tips": "输入一个变量名字,用来保存列表转换后的文本",
"type": "str",
"name": "joined_text"
}
]
},
{
"name": "text.split_text_to_list",
"function": "xbot_visual.text.split_text_to_list",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Text.SplitTextToListControl, ShadowBot.Shell.Development",
"title": "文本分割成列表",
"keywords": "文本转列表",
"description": "这个指令使用指定分隔符号,将目标文本分割成一个列表",
"comment": "用%delimiter_way%分割字符串%text_to_split%,将结果列表保存到%splited_list%",
"icon": "BlockIcons/12-8.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/文本操作/文本分割成列表.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Text.SplitTextToListHandler"
}
],
"inputs": [
{
"name": "text_to_split",
"label": "待转换的文本",
"required": true,
"tips": "请输入文本字符串或者选择一个包含字符串的变量",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "delimiter_way",
"label": "分隔符类型",
"required": true,
"default": "10:standard",
"defaultDisplay": "标准分隔符",
"tips": "选择一种列表的分隔方式",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "标准分隔符",
"value": "standard"
},
{
"display": "自定义分隔符",
"value": "custom"
}
]
}
},
{
"name": "standard_delimiter",
"label": "标准分隔符",
"required": false,
"default": "10:space",
"defaultDisplay": "空格符",
"tips": "选择一种列表的分隔方式",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "空格符",
"value": "space"
},
{
"display": "制表符",
"value": "tab"
},
{
"display": "换行符",
"value": "new_line"
}
]
}
},
{
"name": "num_standard_delimiter",
"label": "分隔符的数量",
"required": false,
"default": "10:1",
"tips": "分隔符的重复数量",
"type": "int",
"editor": {
"kind": "textbox"
}
},
{
"name": "custom_delimiter",
"label": "自定义的分隔符",
"required": false,
"default": "10:",
"tips": "",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "is_regular_expression",
"label": "",
"required": false,
"tips": "是否正则表达式",
"type": "bool",
"default": "13:False",
"editor": {
"label": "正则表达式",
"kind": "checkbox"
}
},
{
"name": "remove_empty",
"label": "",
"required": true,
"tips": "是否过滤空白项",
"type": "bool",
"default": "13:False",
"editor": {
"label": "过滤空白项",
"kind": "checkbox"
}
}
],
"outputs": [
{
"id": "splited_list",
"label": "保存结果至",
"variableLabel": "文本切割后的列表",
"tips": "输入一个变量名字,用来保存文本转换后的列表",
"type": "list<str>",
"name": "splited_list"
}
]
},
{
"name": "text.extract_content_from_text",
"function": "xbot_visual.text.extract_content_from_text",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Text.ExtractContentFromTextControl, ShadowBot.Shell.Development",
"title": "从文本中提取内容",
"keywords": "正则;提取文本;文本提取",
"description": "根据正则表达式从文本中提取指定内容",
"comment": "从文本%text%中%extract_way%,将内容保存到%content%",
"icon": "BlockIcons/12-9.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/文本操作/从文本中提取内容.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Text.ExtractContentFromTextHandler"
}
],
"inputs": [
{
"name": "text",
"label": "文本内容",
"required": true,
"tips": "请输入文本字符串或者选择一个包含字符串的变量",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "extract_way",
"label": "提取方式",
"required": true,
"default": "10:number",
"defaultDisplay": "提取数字",
"tips": "选择一种内容的提取方式",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "提取数字",
"value": "number"
},
{
"display": "提取手机号码",
"value": "mobile_phone"
},
{
"display": "提取Email地址",
"value": "email"
},
{
"display": "提取身份证号",
"value": "id_card"
},
{
"display": "提取自定义内容",
"value": "custom"
}
]
}
},
{
"name": "regular_pattern",
"label": "正则表达式",
"required": true,
"tips": "请输入一段正则表达式",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "just_get_first",
"label": "",
"required": true,
"default": "13:True",
"tips": "例如在文本中找到了两个手机号,你可以只取第一个",
"type": "bool",
"editor": {
"label": "只找第一个匹配项",
"kind": "checkbox"
}
},
{
"name": "ignore_case",
"label": "",
"required": true,
"default": "13:False",
"tips": "在字符串匹配时,是否忽略大小写",
"type": "bool",
"editor": {
"label": "忽略大小写",
"kind": "checkbox"
}
}
],
"outputs": [
{
"id": "content",
"label": "保存结果至",
"variableLabel": "提取到的内容",
"tips": "输入一个变量名字,用来保存提取到的内容",
"type": "str",
"name": "content"
}
]
},
{
"name": "text.replace_content_from_text",
"function": "xbot_visual.text.replace_content_from_text",
"settingsControl": "ShadowBot.Shell.Development.BlockSettings.Controls.Text.ReplaceContentFromText, ShadowBot.Shell.Development",
"title": "文本替换",
"keywords": "正则",
"description": "替换文本中的指定内容",
"comment": "将文本%text%中的内容%replace_text%用%dest_text%替换,将结果保存到%replace_content%",
"icon": "BlockIcons/12-9.png",
"helpUrl": "yddoc/language/zh-cn/指令文档/数据处理/文本操作/文本替换.html",
"handlers": [
{
"name": "ShadowBot.Runtime.Development.Blockly.Handlers.Text.ReplaceContentFromTextHandler"
}
],
"inputs": [
{
"name": "text",
"label": "内容源",
"required": true,
"tips": "请输入文本字符串或者选择一个包含字符串的变量",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "regular_pattern",
"label": "正则表达式",
"tips": "请输入一段正则表达式",
"type": "str",
"editor": {
"kind": "PlainText"
}
},
{
"name": "replace_way",
"label": "替换方式",
"required": true,
"default": "10:content",
"defaultDisplay": "替换内容",
"tips": "选择一种内容的提取方式",
"type": "str",
"editor": {
"kind": "select",
"options": [
{
"display": "替换内容",
"value": "content"
},
{
"display": "替换数字",
"value": "number"
},
{
"display": "替换手机号",
"value": "mobile_phone"
},
{
"display": "替换email",
"value": "email"
},
{
"display": "替换身份证",
"value": "id_card"
},
{
"display": "自定义正则替换",
"value": "custom"
}
]
}
},
{
"name": "replace_text",
"label": "被替换内容",
"tips": "请输入要被替换的内容",
"type": "str",
"editor": {
"kind": "textbox"
}
},
{
"name": "just_get_first",
"label": "",
"required": true,
"default": "13:True",
"tips": "例如在文本中找到了两个手机号,你可以只替换第一个",
"type": "bool",
"editor": {
"label": "只替换第一个匹配项",
"kind": "checkbox"
}
},
{
"name": "ignore_case",
"label": "",
"required": true,
"default": "13:False",
"tips": "在字符串匹配时,是否忽略大小写",
"type": "bool",
"editor": {
"label": "忽略大小写",
"kind": "checkbox"
}
},
{
"name": "dest_text",
"label": "替换为",
"required": false,
"tips": "请输入替换后的值",
"type": "str",
"editor": {
"kind": "textbox"
}
}
],
"outputs": [
{
"id": "replace_content",
"label": "保存结果至",
"variableLabel": "替换后的文本",
"tips": "输入一个变量名字,用来保存替换后的内容",
"type": "str",
"name": "replace_content"
}
]
}
]
}

View File

@@ -0,0 +1,500 @@
<?xml version="1.0" encoding="utf-8" ?>
<root>
<item display="条件判断" icon="VisualTree/conditions.png">
<item block="workflow.if,workflow.endif"></item>
<item block="workflow.multiple_conditions_if,workflow.endif" />
<item block="web.browser.contains_element_or_text,workflow.endif" />
<item block="web.browser.element_display,workflow.endif" />
<item block="win32.window.exists,workflow.endif"/>
<item block="win32.window.contains_element,workflow.endif" />
<item block="image.exist,workflow.endif" />
<item block="ocr.if_text_on_screen,workflow.endif" />
<item block="file.if_exist,workflow.endif" />
<item block="dir.if_exist,workflow.endif" />
<item block="mobile.element.exist_images,workflow.endif"/>
<item block="mobile.session.contains_element,workflow.endif" />
<item block="workflow.elseif" />
<item block="workflow.multiple_conditions_elseif" />
<item block="workflow.else" />
<item block="workflow.endif" />
</item>
<item display="循环" icon="VisualTree/loop.png">
<item block="workflow.for,workflow.endloop" />
<item block="workflow.while,workflow.endloop" />
<item block="workflow.forin,workflow.endloop" />
<item block="workflow.loop_dict,workflow.endloop" />
<item block="workflow.infinite_loop,workflow.endloop" />
<item block="web.element.foreach_element,workflow.endloop" />
<item block="win32.element.foreach_element,workflow.endloop" />
<item block="mobile.element.foreach_element,workflow.endloop" />
<item block="excel.loop_data_from_workbook,workflow.endloop" />
<item block="programing.databook.loop_data_from_workbook,workflow.endloop"/>
<item block="workflow.continue" />
<item block="workflow.break" />
<item block="workflow.endloop" />
</item>
<item display="等待" icon="VisualTree/wait.png">
<item block="programing.sleep" />
<item block="web.element.wait" />
<item block="win32.element.wait" />
<item block="mobile.element.wait" />
<item block="image.wait" />
<item block="mobile.element.wait_images" />
<item block="file.wait" />
<item block="ocr.wait_text_on_screen" />
<item block="win32.window.wait_window" />
<item block="win32.manual_motion_on,win32.manual_motion_off" />
<item block="win32.manual_motion_off" />
</item>
<item display="相似元素操作" icon="VisualTree/similar.png">
<item block="web.element.foreach_element,workflow.endloop" />
<item block="win32.element.foreach_element,workflow.endloop" />
<item block="mobile.element.foreach_element,workflow.endloop" />
<item block="web.element.get_all_elements" />
<item block="win32.element.get_all_elements" />
<item block="mobile.element.get_all_elements" />
</item>
<item display="网页自动化" icon="VisualTree/web.png">
<item block="web.create" />
<item block="web.get" />
<item block="web.element.click" />
<item block="web.element.hover" />
<item block="web.element.input" />
<item block="web.browser.close" />
<item display="元素操作">
<item block="web.element.drag_to" />
<item block="web.element.wait" />
<item block="web.element.input_password" />
<item block="web.element.select" />
<item block="web.element.check" />
<item block="web.element.set_value" />
<item block="web.element.set_attribute" />
<item block="web.element.get_element" />
<item block="web.element.get_associated_elements" />
<item block="web.element.get_all_elements" />
</item>
<item display="网页操作">
<item block="web.browser.navigate" />
<item block="web.browser.wait_load_completed" />
<item block="web.browser.stop_load" />
<item block="web.browser.scroll_to" />
<item block="web.browser.execute_javascript" />
<item block="web.get_all" />
<item block="web.set_cookie" />
<item block="web.remove_cookie" />
</item>
<item display="数据提取">
<item block="web.element.data_scraping" />
<item block="web.element.screenshot" />
<item block="web.element.get_details" />
<!--<item block="web.element.get_bounding" />-->
<item block="web.element.get_select_item" />
<item block="web.browser.get_details" />
<item block="web.browser.get_scroll"/>
<item block="web.browser.get_javascript_dialog_text" />
<item block="web.get_cookies_v2" />
<item block="web.get_cookie" />
<item block="web.browser.start_monitor_network,web.browser.get_responses,web.browser.stop_monitor_network" />
<item block="web.browser.get_responses" />
<item block="web.browser.stop_monitor_network" />
</item>
<item display="对话框处理">
<item block="web.element.upload" />
<item block="web.element.download" />
<item block="web.handle_save_dialog" />
<item block="web.handle_upload_dialog" />
<item block="web.browser.handle_javascript_dialog" />
</item>
</item>
<item display="桌面软件自动化" icon="VisualTree/desktop-software.png">
<item block="win32.window.get_window" />
<item block="win32.window.get_window_list"/>
<item block="win32.element.click" />
<item block="win32.element.hover" />
<item block="win32.element.input" />
<item block="system.run_or_open" />
<item display="元素操作">
<item block="win32.element.drag_to" />
<item block="win32.element.wait" />
<item block="win32.element.input_password" />
<item block="win32.element.select" />
<item block="win32.element.check" />
<item block="win32.element.set_value" />
<item block="win32.element.get_element" />
<item block="win32.element.get_associated_elements" />
<item block="win32.element.get_all_elements" />
</item>
<item display="窗口操作">
<item block="win32.window.get_window" />
<item block="win32.window.get_details" />
<item block="win32.window.activate" />
<item block="win32.window.set_state" />
<item block="win32.window.set_visibility" />
<item block="win32.window.move" />
<item block="win32.window.resize" />
<item block="win32.window.close" />
</item>
<item display="数据提取">
<item block="win32.element.screenshot" />
<item block="win32.element.get_details" />
<!--<item block="win32.element.get_bounding" />-->
<item block="win32.element.get_select_item" />
<item block="win32.window.get_details" />
<item block="win32.get_selected_text" />
</item>
<item display="SAP">
<item block="win32.element.expand_tree_and_select_node" />
<item block="win32.element.get_table_cell_by_rownum_and_columnnum" />
<item block="win32.element.get_table_row_count" />
<item block="win32.element.get_table_column_count" />
</item>
</item>
<item display="鼠标键盘" icon="VisualTree/mouse-keyboard.png">
<item block="win32.send_keys" />
<item block="win32.click_mouse" />
<item block="win32.move_mouse" />
<item block="win32.get_mouse_position" />
<item block="win32.wheel_mouse" />
<item block="image.click" />
<item block="image.hover" />
<item block="ocr.click_text" />
<item block="ocr.hover_on_text" />
<item block="win32.manual_motion_on,win32.manual_motion_off" />
<item block="win32.manual_motion_off" />
</item>
<item display="手机自动化" icon="VisualTree/mobile.png">
<item block="mobile.connect_device" />
<item block="mobile.session.close" />
<item block="mobile.element.click" />
<item block="mobile.session.click" />
<item block="mobile.element.wait" />
<item block="mobile.element.input" />
<item block="mobile.element.find_images" />
<item block="mobile.element.get_element" />
<item display="手机操作">
<item block="mobile.session.press_key" />
<item block="mobile.session.swipe" />
<item block="mobile.session.open_app" />
<item block="mobile.session.close_app" />
<item block="mobile.session.lock_screen" />
<item block="mobile.session.unlock_screen" />
<item block="mobile.element.screenshot" />
<item block="mobile.session.screenshot" />
<item block="mobile.session.setoriention" />
<item block="mobile.session.set_clipboard_text" />
<item block="mobile.session.push_file" />
</item>
<item display="数据获取">
<item block="mobile.element.get_details" />
<item block="mobile.session.get_clipboard_text" />
<item block="mobile.session.getoriention" />
<item block="mobile.session.get_page_source" />
<item block="mobile.session.pull_file" />
<item block="mobile.session.get_session_detail" />
</item>
</item>
<item display="数据表格" icon="VisualTree/data-table.png">
<item block="programing.databook.read_data_from_workbook" />
<item block="programing.databook.write_data_to_workbook" />
<item block="programing.databook.get_row_count" />
<item block="programing.databook.remove_row" />
<item block="programing.databook.remove_column" />
<item block="programing.databook.remove_all_rows" />
<item block="programing.databook.loop_data_from_workbook,workflow.endloop"/>
<item block="programing.databook.import_data" />
<item block="programing.databook.export_data" />
<item block="programing.databook.get_column_info" />
<item block="programing.databook.set_column_info" />
</item>
<item display="Excel / WPS表格" icon="VisualTree/office.png">
<item block="excel.launch,excel.close" />
<item block="excel.get_active_workbook,excel.close" />
<item block="excel.save" />
<item block="excel.close" />
<item block="excel.export_to_pdf"/>
<item block="excel.loop_data_from_workbook,workflow.endloop" />
<item block="excel.read_data_from_workbook" />
<item block="excel.write_data_to_workbook" />
<item display="读写操作">
<item block="excel.get_row_count" />
<item block="excel.copy_range" />
<item block="excel.paste_range_ex" />
<item block="excel.get_first_free_row" />
<item block="excel.get_first_free_row_on_column" />
<item block="excel.get_first_free_column" />
<item block="excel.get_first_free_column_on_row" />
<item block="excel.get_last_column" />
<item block="excel.clear_range" />
<item block="excel.remove_row" />
<item block="excel.remove_duplicate_row" />
<item block="excel.remove_all_rows" />
<item block="excel.remove_column" />
<item block="excel.insert_row"/>
<item block="excel.insert_column"/>
<item block="excel.select_range" />
<item block="excel.get_selected_range" />
<item block="excel.set_hidden" />
</item>
<item display="Sheet页操作">
<item block="excel.create_sheet" />
<item block="excel.active" />
<item block="excel.copy_sheet" />
<item block="excel.delete_sheet" />
<item block="excel.rename_sheet" />
<item block="excel.get_sheet_name" />
</item>
<item display="高级指令">
<item block="excel.execute_macro" />
<item block="excel.refresh_data" />
<item block="excel.set_format"/>
<item block="excel.clear_format"/>
<item block="excel.set_row_height"/>
<item block="excel.set_column_width"/>
<item block="excel.create_pivot_table"/>
<item block="excel.refresh_pivot_table"/>
<item block="excel.filter_pivot_table"/>
<item block="excel.add_validation"/>
<item block="excel.custom_sort"/>
</item>
</item>
<item display="对话框" icon="VisualTree/dialog.png">
<item block="dialog.show_custom_message_box"/>
<item block="dialog.show_input_dialog"/>
<item block="dialog.show_datetime_dialog"/>
<item block="dialog.show_select_dialog"/>
<item block="dialog.show_select_file_dialog"/>
<item block="dialog.show_select_folder_dialog"/>
<item block="dialog.show_workbook_dialog"/>
<item block="dialog.show_custom_dialog"/>
<item block="dialog.show_notifycation"/>
</item>
<item display="数据处理" subtitle="(文本、列表、变量...)" icon="VisualTree/data-dispose.png">
<item block="programing.variable" />
<item block="programing.random_int" />
<item block="asset.get_asset" studio ="Enterprise,Private"/>
<item display="文本操作">
<item block="text.extract_content_from_text" />
<item block="text.get_text_length" />
<item block="text.append_text_in_newline" />
<item block="text.sub_text" />
<item block="text.pad_text" />
<item block="text.trim_text" />
<item block="text.change_text_case" />
<item block="text.join_list_to_text" />
<item block="text.split_text_to_list" />
<item block="text.replace_content_from_text" />
</item>
<item display="列表操作">
<item block="list.create" />
<item block="list.clear" />
<item block="list.append_or_insert" />
<item block="list.set_elem" />
<item block="list.get_elem" />
<item block="list.get_index" />
<item block="list.get_len" />
<item block="list.remove" />
<item block="list.remove_list" />
<item block="list.sort" />
<item block="list.shuffle" />
<item block="list.extend" />
<item block="list.reverse" />
<item block="list.remove_duplicate" />
<item block="list.get_duplicate" />
</item>
<item display="字典操作">
<item block="dictionary.create" />
<item block="dictionary.set" />
<item block="dictionary.get_value" />
<item block="dictionary.get_keys" />
<item block="dictionary.get_values" />
<item block="dictionary.pop" />
</item>
<item display="日期时间">
<item block="datetime.now" />
<item block="datetime.add" />
<item block="datetime.difference" />
<item block="datetime.from_string" />
<item block="datetime.to_string" />
<item block="datetime.get_parts" />
<item block="datetime.to_timestamp" />
<item block="datetime.from_timestamp" />
</item>
<item display="CSV读写">
<item block="csv.read" />
<item block="csv.write" />
</item>
<item display="Json转换">
<item block="json.to_text" />
<item block="json.to_json" />
</item>
<item display="Base64编解码">
<item block="base64.encode" />
<item block="base64.decode" />
</item>
</item>
<item display="操作系统" subtitle="(文件、文件夹、剪贴板...)" icon="VisualTree/system.png">
<item block="system.run_or_open" />
<item block="system.run_dos_command" />
<item block="system.terminal_process" />
<item block="system.take_screenshot" />
<item display="文件">
<item block="dir.find_files" />
<item block="file.copy" />
<item block="file.move" />
<item block="file.rename" />
<item block="file.remove" />
<item block="file.read" />
<item block="file.write" />
<item block="file.get_file_parts" />
<item block="file.wait" />
</item>
<item display="文件夹">
<item block="dir.find_subdirs" />
<item block="dir.selected_dirs_or_files" />
<item block="dir.open" />
<item block="dir.makedir" />
<item block="dir.remove" />
<item block="dir.empty" />
<item block="dir.copy" />
<item block="dir.move" />
<item block="dir.rename" />
<item block="dir.get_special_dir" />
</item>
<item display="剪切板">
<item block="clipboard.set_file"/>
<item block="clipboard.set_text"/>
<item block="clipboard.get_text"/>
<item block="clipboard.clear"/>
</item>
<item display="压缩/解压">
<item block="xzip.zip" />
<item block="xzip.unzip" />
</item>
<item display="锁屏/解锁">
<item block="win32.rdp_lock_screen" />
<item block="win32.unlock_screen" />
</item>
<item display="输入法">
<item block="win32.get_ime" />
<item block="win32.set_ime" />
</item>
<item display="屏幕保护">
<item block="system.open_screen_saver" />
<item block="system.append_screen_saver_text"/>
<item block="system.clear_screen_saver_text"/>
<item block="system.close_screen_saver"/>
</item>
</item>
<item display="流程/应用" icon="VisualTree/process.png">
<item block="process.run" />
<item block="process.invoke_module" />
<item block="process.return" />
<item display="应用">
<item block="process.get_app_params" />
<item block="process.exit" />
<item block="process.write_to_storage"/>
<item block="process.read_from_storage"/>
</item>
<item display="资源文件">
<item block="resourcesfile.read" />
<item block="resourcesfile.get_resourcesfile_path" />
<item block="resourcesfile.copy_to" />
<item block="resourcesfile.copy_to_clipboard" />
</item>
</item>
<item display="人工智能AI" subtitle ="(OCR、NLP)" icon="VisualTree/ai.png">
<item block="ai.power"/>
<item block="chatgpt.completions"/>
<item block="ocr.CreateAIEngine" />
<item display="文字识别OCR">
<item block="ocr.general_text" />
<item block="ocr.general_text_with_location" />
<item block="ocr.table" />
<item block="ocr.id_license_discern" />
<item block="ocr.note_discern" />
<item block="web_service.captcha_paid"/>
</item>
<item display="自然语言处理NLP">
<item block="nlp.lexical_analysis" />
<item block="nlp.lexical_analysis_include_location" />
<item block="nlp.sentiment_analysis" />
<item block="nlp.text_similarity" />
</item>
</item>
<item display="网络" subtitle="(邮件、HTTP、FTP、群通知...)" icon="VisualTree/internet.png">
<item display="邮件">
<item block="email.send_email" />
<item block="email.retrieve_email" />
</item>
<item display="HTTP">
<item block="web_service.rest_request" />
<item block="web_service.download" />
</item>
<item display="FTP">
<item block="ftp.connection,ftp.disconnection"/>
<item block="ftp.get_ftp_files"/>
<item block="ftp.change_workspace_path"/>
<item block="ftp.download_files"/>
<item block="ftp.download_folders"/>
<item block="ftp.uoload_files"/>
<item block="ftp.upload_folders"/>
<item block="ftp.delete_files"/>
<item block="ftp.rename_file"/>
<item block="ftp.creat_directory"/>
<item block="ftp.delete_folder"/>
<item block="ftp.disconnection"/>
</item>
<item display="群通知" subtitle="(钉钉、企微、飞书)">
<item block="web_service.send_wxwork_msg" />
<item block="web_service.send_dingtalk_msg" />
<item block="web_service.send_feishu_msg" />
</item>
</item>
<item display="工作队列" studio ="Enterprise" icon="VisualTree/data-dispose.png">
<item block="workqueue.enqueue"/>
<item block="workqueue.loop_queue,workflow.endloop"/>
<item block="workqueue.update_item"/>
<item block="workqueue.reenqueue"/>
</item>
<item display="其他" subtitle="(数据库、PDF、异常处理...)" icon="VisualTree/ohters.png">
<item block="programing.log" />
<item block="programing.exportlog" />
<item block="programing.snippet" />
<item block="programing.comment" />
<item display="数据库">
<item block="database.connect" />
<item block="database.exec" />
<item block="database.batch_insert" />
<item block="database.close" />
</item>
<item display="PDF文件">
<item block="pdf.extract_text" />
<item block="pdf.extract_images" />
<item block="pdf.extract_pages" />
<item block="pdf.merge_pdfs" />
<item block="pdf.save_pages_to_images" />
</item>
<item display="Word / WPS文字">
<item block="word.launch,word.close" />
<item block="word.export_to_pdf"/>
<item block="word.read_text_from_document" />
<item block="word.write_text_to_document" />
<item block="word.locate_cursor" />
<item block="word.move_cursor" />
<item block="word.replace_text" />
<item block="word.read_table_from_document" />
<item block="word.insert_table" />
<item block="word.insert_picture" />
<item block="word.insert_hyperlink" />
<item block="word.save" />
<item block="word.close" />
</item>
<item display="异常处理">
<item block="programing.try,programing.catch,programing.endtry" />
<item block="programing.catch" />
<item block="programing.finally" />
<item block="programing.endtry" />
<item block="programing.raise" />
</item>
</item>
</root>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More