xgo-blockly 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- xgo_blockly-1.0.0/MANIFEST.in +35 -0
- xgo_blockly-1.0.0/PKG-INFO +141 -0
- xgo_blockly-1.0.0/README.md +101 -0
- xgo_blockly-1.0.0/pyproject.toml +55 -0
- xgo_blockly-1.0.0/requirements.txt +6 -0
- xgo_blockly-1.0.0/setup.cfg +4 -0
- xgo_blockly-1.0.0/setup.py +65 -0
- xgo_blockly-1.0.0/xgo_blockly/__init__.py +14 -0
- xgo_blockly-1.0.0/xgo_blockly/app.py +86 -0
- xgo_blockly-1.0.0/xgo_blockly/cli.py +64 -0
- xgo_blockly-1.0.0/xgo_blockly/config.py +77 -0
- xgo_blockly-1.0.0/xgo_blockly/dist/assets/index.0823cb3b.js +7826 -0
- xgo_blockly-1.0.0/xgo_blockly/dist/assets/index.f7fdf6e6.css +1 -0
- xgo_blockly-1.0.0/xgo_blockly/dist/assets/logo.e0551a52.png +0 -0
- xgo_blockly-1.0.0/xgo_blockly/dist/favicon.ico +0 -0
- xgo_blockly-1.0.0/xgo_blockly/dist/index.html +59 -0
- xgo_blockly-1.0.0/xgo_blockly/dist/media/1x1.gif +0 -0
- xgo_blockly-1.0.0/xgo_blockly/dist/media/click.mp3 +0 -0
- xgo_blockly-1.0.0/xgo_blockly/dist/media/click.ogg +0 -0
- xgo_blockly-1.0.0/xgo_blockly/dist/media/click.wav +0 -0
- xgo_blockly-1.0.0/xgo_blockly/dist/media/delete-icon.svg +1 -0
- xgo_blockly-1.0.0/xgo_blockly/dist/media/delete.mp3 +0 -0
- xgo_blockly-1.0.0/xgo_blockly/dist/media/delete.ogg +0 -0
- xgo_blockly-1.0.0/xgo_blockly/dist/media/delete.wav +0 -0
- xgo_blockly-1.0.0/xgo_blockly/dist/media/disconnect.mp3 +0 -0
- xgo_blockly-1.0.0/xgo_blockly/dist/media/disconnect.ogg +0 -0
- xgo_blockly-1.0.0/xgo_blockly/dist/media/disconnect.wav +0 -0
- xgo_blockly-1.0.0/xgo_blockly/dist/media/dropdown-arrow.svg +1 -0
- xgo_blockly-1.0.0/xgo_blockly/dist/media/foldout-icon.svg +1 -0
- xgo_blockly-1.0.0/xgo_blockly/dist/media/handclosed.cur +0 -0
- xgo_blockly-1.0.0/xgo_blockly/dist/media/handdelete.cur +0 -0
- xgo_blockly-1.0.0/xgo_blockly/dist/media/handopen.cur +0 -0
- xgo_blockly-1.0.0/xgo_blockly/dist/media/pilcrow.png +0 -0
- xgo_blockly-1.0.0/xgo_blockly/dist/media/quote0.png +0 -0
- xgo_blockly-1.0.0/xgo_blockly/dist/media/quote1.png +0 -0
- xgo_blockly-1.0.0/xgo_blockly/dist/media/resize-handle.svg +3 -0
- xgo_blockly-1.0.0/xgo_blockly/dist/media/sprites.png +0 -0
- xgo_blockly-1.0.0/xgo_blockly/dist/media/sprites.svg +74 -0
- xgo_blockly-1.0.0/xgo_blockly/dist/static/media/luwu.png +0 -0
- xgo_blockly-1.0.0/xgo_blockly/routes/__init__.py +5 -0
- xgo_blockly-1.0.0/xgo_blockly/routes/api.py +286 -0
- xgo_blockly-1.0.0/xgo_blockly/routes/static.py +46 -0
- xgo_blockly-1.0.0/xgo_blockly/services/__init__.py +5 -0
- xgo_blockly-1.0.0/xgo_blockly/services/code_executor.py +476 -0
- xgo_blockly-1.0.0/xgo_blockly/services/edulib.py +1722 -0
- xgo_blockly-1.0.0/xgo_blockly/services/xgo_status.py +201 -0
- xgo_blockly-1.0.0/xgo_blockly/services/xgolib/_init_.py +1100 -0
- xgo_blockly-1.0.0/xgo_blockly.egg-info/PKG-INFO +141 -0
- xgo_blockly-1.0.0/xgo_blockly.egg-info/SOURCES.txt +52 -0
- xgo_blockly-1.0.0/xgo_blockly.egg-info/dependency_links.txt +1 -0
- xgo_blockly-1.0.0/xgo_blockly.egg-info/entry_points.txt +2 -0
- xgo_blockly-1.0.0/xgo_blockly.egg-info/not-zip-safe +1 -0
- xgo_blockly-1.0.0/xgo_blockly.egg-info/requires.txt +7 -0
- xgo_blockly-1.0.0/xgo_blockly.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# 包含项目说明文件
|
|
2
|
+
include README.md
|
|
3
|
+
include requirements.txt
|
|
4
|
+
include pyproject.toml
|
|
5
|
+
|
|
6
|
+
# 包含许可证文件(如果存在)
|
|
7
|
+
include LICENSE*
|
|
8
|
+
include COPYING*
|
|
9
|
+
|
|
10
|
+
# 包含前端构建资源
|
|
11
|
+
recursive-include xgo_blockly/dist *
|
|
12
|
+
recursive-include xgo_blockly/dist/assets *
|
|
13
|
+
|
|
14
|
+
# 包含Python包的所有子包
|
|
15
|
+
recursive-include xgo_blockly *.py
|
|
16
|
+
recursive-include xgo_blockly *.txt
|
|
17
|
+
recursive-include xgo_blockly *.md
|
|
18
|
+
recursive-include xgo_blockly *.json
|
|
19
|
+
recursive-include xgo_blockly *.yaml
|
|
20
|
+
recursive-include xgo_blockly *.yml
|
|
21
|
+
|
|
22
|
+
# 排除不需要的文件
|
|
23
|
+
global-exclude *.pyc
|
|
24
|
+
global-exclude *.pyo
|
|
25
|
+
global-exclude *.pyd
|
|
26
|
+
global-exclude __pycache__
|
|
27
|
+
global-exclude *.so
|
|
28
|
+
global-exclude .DS_Store
|
|
29
|
+
global-exclude Thumbs.db
|
|
30
|
+
global-exclude *.log
|
|
31
|
+
global-exclude .git*
|
|
32
|
+
global-exclude .pytest_cache
|
|
33
|
+
global-exclude *.egg-info
|
|
34
|
+
global-exclude build
|
|
35
|
+
global-exclude dist
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: xgo-blockly
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: XGO Blockly - 图形化编程Web服务器
|
|
5
|
+
Home-page: https://github.com/xgo-robotics/xgo-blockly
|
|
6
|
+
Author: XGO Team
|
|
7
|
+
Author-email: XGO Team <support@xgo.com>
|
|
8
|
+
License: MIT
|
|
9
|
+
Project-URL: Homepage, https://github.com/xgo-robotics/xgo-blockly
|
|
10
|
+
Project-URL: Bug Reports, https://github.com/xgo-robotics/xgo-blockly/issues
|
|
11
|
+
Project-URL: Source, https://github.com/xgo-robotics/xgo-blockly
|
|
12
|
+
Project-URL: Documentation, https://docs.xgo.com/
|
|
13
|
+
Keywords: xgo,robot,blockly,programming,education
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: Intended Audience :: Education
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
25
|
+
Classifier: Topic :: Education
|
|
26
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
27
|
+
Classifier: Framework :: Flask
|
|
28
|
+
Requires-Python: >=3.7
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
Requires-Dist: flask>=2.3.0
|
|
31
|
+
Requires-Dist: flask-cors>=4.0.0
|
|
32
|
+
Requires-Dist: psutil>=5.9.0
|
|
33
|
+
Requires-Dist: xgo-pythonlib
|
|
34
|
+
Requires-Dist: agentscope
|
|
35
|
+
Requires-Dist: mem0ai
|
|
36
|
+
Requires-Dist: pyserial
|
|
37
|
+
Dynamic: author
|
|
38
|
+
Dynamic: home-page
|
|
39
|
+
Dynamic: requires-python
|
|
40
|
+
|
|
41
|
+
# 项目重构说明
|
|
42
|
+
|
|
43
|
+
## 重构概述
|
|
44
|
+
|
|
45
|
+
原来的 `app.py` 文件包含了所有的路由、业务逻辑和配置,不符合标准的Flask项目架构规范。现在已经将代码重构为更规范的项目结构,采用模块化设计和工厂模式。
|
|
46
|
+
|
|
47
|
+
## 新的项目结构
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
xgo-blockly-server/
|
|
51
|
+
├── app.py # 主应用文件(工厂模式)
|
|
52
|
+
├── config.py # 配置管理
|
|
53
|
+
├── requirements.txt # Python依赖
|
|
54
|
+
├── services/ # 业务逻辑层
|
|
55
|
+
│ ├── __init__.py
|
|
56
|
+
│ └── code_executor.py # 代码执行服务
|
|
57
|
+
├── routes/ # 路由处理层
|
|
58
|
+
│ ├── __init__.py
|
|
59
|
+
│ ├── api.py # API路由
|
|
60
|
+
│ └── static.py # 静态文件路由
|
|
61
|
+
└── dist/ # Vue3构建产物
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## 模块说明
|
|
65
|
+
|
|
66
|
+
### 1. `config.py` - 配置管理
|
|
67
|
+
- 统一管理所有配置项
|
|
68
|
+
- 支持不同环境配置(开发/生产/测试)
|
|
69
|
+
- MIME类型配置管理
|
|
70
|
+
|
|
71
|
+
### 2. `services/code_executor.py` - 业务逻辑层
|
|
72
|
+
- `CodeExecutor` 类:负责Python代码执行
|
|
73
|
+
- `ExecutionManager` 类:管理多个执行任务
|
|
74
|
+
- 日志管理和任务调度
|
|
75
|
+
|
|
76
|
+
### 3. `routes/api.py` - API路由处理
|
|
77
|
+
- `/api/run-code` - Python代码执行接口
|
|
78
|
+
- `/api/health` - 健康检查接口
|
|
79
|
+
- 使用Flask Blueprint进行模块化管理
|
|
80
|
+
|
|
81
|
+
### 4. `routes/static.py` - 静态文件路由
|
|
82
|
+
- Vue3应用托管
|
|
83
|
+
- 静态资源服务
|
|
84
|
+
- MIME类型处理
|
|
85
|
+
|
|
86
|
+
### 5. `app.py` - 应用工厂
|
|
87
|
+
- 采用工厂模式创建Flask应用
|
|
88
|
+
- 蓝图注册
|
|
89
|
+
- 全局错误处理
|
|
90
|
+
|
|
91
|
+
## 重构优势
|
|
92
|
+
|
|
93
|
+
### 1. **代码组织更清晰**
|
|
94
|
+
- 按功能模块分离代码
|
|
95
|
+
- 单一职责原则
|
|
96
|
+
- 便于维护和扩展
|
|
97
|
+
|
|
98
|
+
### 2. **更好的可测试性**
|
|
99
|
+
- 业务逻辑与路由分离
|
|
100
|
+
- 依赖注入更容易
|
|
101
|
+
- 单元测试更方便
|
|
102
|
+
|
|
103
|
+
### 3. **配置管理标准化**
|
|
104
|
+
- 环境配置分离
|
|
105
|
+
- 配置项集中管理
|
|
106
|
+
- 支持多环境部署
|
|
107
|
+
|
|
108
|
+
### 4. **扩展性更强**
|
|
109
|
+
- 新增功能只需添加新的蓝图
|
|
110
|
+
- 业务逻辑模块化
|
|
111
|
+
- 支持插件式架构
|
|
112
|
+
|
|
113
|
+
## 兼容性保证
|
|
114
|
+
|
|
115
|
+
**重要:所有原有的接口和功能保持不变**
|
|
116
|
+
|
|
117
|
+
- ✅ `/api/run-code` - Python代码执行(SSE响应)
|
|
118
|
+
- ✅ `/api/health` - 健康检查
|
|
119
|
+
- ✅ `/` - Vue3应用主页
|
|
120
|
+
- ✅ `/<path>` - 静态资源文件
|
|
121
|
+
- ✅ 404错误处理(Vue路由支持)
|
|
122
|
+
- ✅ CORS跨域支持
|
|
123
|
+
- ✅ MIME类型配置
|
|
124
|
+
|
|
125
|
+
## 启动方式
|
|
126
|
+
|
|
127
|
+
启动方式完全保持不变:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
cd xgo-blockly-server
|
|
131
|
+
python app.py
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## 后续开发建议
|
|
135
|
+
|
|
136
|
+
1. **新增API接口**:在 `routes/` 目录下创建新的路由文件
|
|
137
|
+
2. **新增业务逻辑**:在 `services/` 目录下创建新的服务类
|
|
138
|
+
3. **配置修改**:统一在 `config.py` 中管理
|
|
139
|
+
4. **测试开发**:为每个模块编写单独的单元测试
|
|
140
|
+
|
|
141
|
+
这样的架构更符合Flask最佳实践,便于团队开发和项目维护。
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# 项目重构说明
|
|
2
|
+
|
|
3
|
+
## 重构概述
|
|
4
|
+
|
|
5
|
+
原来的 `app.py` 文件包含了所有的路由、业务逻辑和配置,不符合标准的Flask项目架构规范。现在已经将代码重构为更规范的项目结构,采用模块化设计和工厂模式。
|
|
6
|
+
|
|
7
|
+
## 新的项目结构
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
xgo-blockly-server/
|
|
11
|
+
├── app.py # 主应用文件(工厂模式)
|
|
12
|
+
├── config.py # 配置管理
|
|
13
|
+
├── requirements.txt # Python依赖
|
|
14
|
+
├── services/ # 业务逻辑层
|
|
15
|
+
│ ├── __init__.py
|
|
16
|
+
│ └── code_executor.py # 代码执行服务
|
|
17
|
+
├── routes/ # 路由处理层
|
|
18
|
+
│ ├── __init__.py
|
|
19
|
+
│ ├── api.py # API路由
|
|
20
|
+
│ └── static.py # 静态文件路由
|
|
21
|
+
└── dist/ # Vue3构建产物
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## 模块说明
|
|
25
|
+
|
|
26
|
+
### 1. `config.py` - 配置管理
|
|
27
|
+
- 统一管理所有配置项
|
|
28
|
+
- 支持不同环境配置(开发/生产/测试)
|
|
29
|
+
- MIME类型配置管理
|
|
30
|
+
|
|
31
|
+
### 2. `services/code_executor.py` - 业务逻辑层
|
|
32
|
+
- `CodeExecutor` 类:负责Python代码执行
|
|
33
|
+
- `ExecutionManager` 类:管理多个执行任务
|
|
34
|
+
- 日志管理和任务调度
|
|
35
|
+
|
|
36
|
+
### 3. `routes/api.py` - API路由处理
|
|
37
|
+
- `/api/run-code` - Python代码执行接口
|
|
38
|
+
- `/api/health` - 健康检查接口
|
|
39
|
+
- 使用Flask Blueprint进行模块化管理
|
|
40
|
+
|
|
41
|
+
### 4. `routes/static.py` - 静态文件路由
|
|
42
|
+
- Vue3应用托管
|
|
43
|
+
- 静态资源服务
|
|
44
|
+
- MIME类型处理
|
|
45
|
+
|
|
46
|
+
### 5. `app.py` - 应用工厂
|
|
47
|
+
- 采用工厂模式创建Flask应用
|
|
48
|
+
- 蓝图注册
|
|
49
|
+
- 全局错误处理
|
|
50
|
+
|
|
51
|
+
## 重构优势
|
|
52
|
+
|
|
53
|
+
### 1. **代码组织更清晰**
|
|
54
|
+
- 按功能模块分离代码
|
|
55
|
+
- 单一职责原则
|
|
56
|
+
- 便于维护和扩展
|
|
57
|
+
|
|
58
|
+
### 2. **更好的可测试性**
|
|
59
|
+
- 业务逻辑与路由分离
|
|
60
|
+
- 依赖注入更容易
|
|
61
|
+
- 单元测试更方便
|
|
62
|
+
|
|
63
|
+
### 3. **配置管理标准化**
|
|
64
|
+
- 环境配置分离
|
|
65
|
+
- 配置项集中管理
|
|
66
|
+
- 支持多环境部署
|
|
67
|
+
|
|
68
|
+
### 4. **扩展性更强**
|
|
69
|
+
- 新增功能只需添加新的蓝图
|
|
70
|
+
- 业务逻辑模块化
|
|
71
|
+
- 支持插件式架构
|
|
72
|
+
|
|
73
|
+
## 兼容性保证
|
|
74
|
+
|
|
75
|
+
**重要:所有原有的接口和功能保持不变**
|
|
76
|
+
|
|
77
|
+
- ✅ `/api/run-code` - Python代码执行(SSE响应)
|
|
78
|
+
- ✅ `/api/health` - 健康检查
|
|
79
|
+
- ✅ `/` - Vue3应用主页
|
|
80
|
+
- ✅ `/<path>` - 静态资源文件
|
|
81
|
+
- ✅ 404错误处理(Vue路由支持)
|
|
82
|
+
- ✅ CORS跨域支持
|
|
83
|
+
- ✅ MIME类型配置
|
|
84
|
+
|
|
85
|
+
## 启动方式
|
|
86
|
+
|
|
87
|
+
启动方式完全保持不变:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
cd xgo-blockly-server
|
|
91
|
+
python app.py
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## 后续开发建议
|
|
95
|
+
|
|
96
|
+
1. **新增API接口**:在 `routes/` 目录下创建新的路由文件
|
|
97
|
+
2. **新增业务逻辑**:在 `services/` 目录下创建新的服务类
|
|
98
|
+
3. **配置修改**:统一在 `config.py` 中管理
|
|
99
|
+
4. **测试开发**:为每个模块编写单独的单元测试
|
|
100
|
+
|
|
101
|
+
这样的架构更符合Flask最佳实践,便于团队开发和项目维护。
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=45", "wheel", "setuptools-scm[toml]>=6.2"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "xgo-blockly"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "XGO Blockly - 图形化编程Web服务器"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.7"
|
|
11
|
+
license = {text = "MIT"}
|
|
12
|
+
authors = [
|
|
13
|
+
{name = "XGO Team", email = "support@xgo.com"}
|
|
14
|
+
]
|
|
15
|
+
keywords = ["xgo", "robot", "blockly", "programming", "education"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Intended Audience :: Education",
|
|
19
|
+
"Intended Audience :: Developers",
|
|
20
|
+
"License :: OSI Approved :: MIT License",
|
|
21
|
+
"Operating System :: OS Independent",
|
|
22
|
+
"Programming Language :: Python :: 3",
|
|
23
|
+
"Programming Language :: Python :: 3.7",
|
|
24
|
+
"Programming Language :: Python :: 3.8",
|
|
25
|
+
"Programming Language :: Python :: 3.9",
|
|
26
|
+
"Programming Language :: Python :: 3.10",
|
|
27
|
+
"Programming Language :: Python :: 3.11",
|
|
28
|
+
"Topic :: Education",
|
|
29
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
30
|
+
"Framework :: Flask",
|
|
31
|
+
]
|
|
32
|
+
dependencies = [
|
|
33
|
+
"flask>=2.3.0",
|
|
34
|
+
"flask-cors>=4.0.0",
|
|
35
|
+
"psutil>=5.9.0",
|
|
36
|
+
"xgo-pythonlib",
|
|
37
|
+
"agentscope",
|
|
38
|
+
"mem0ai",
|
|
39
|
+
"pyserial",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
[project.urls]
|
|
43
|
+
Homepage = "https://github.com/xgo-robotics/xgo-blockly"
|
|
44
|
+
"Bug Reports" = "https://github.com/xgo-robotics/xgo-blockly/issues"
|
|
45
|
+
"Source" = "https://github.com/xgo-robotics/xgo-blockly"
|
|
46
|
+
"Documentation" = "https://docs.xgo.com/"
|
|
47
|
+
|
|
48
|
+
[project.scripts]
|
|
49
|
+
xgo-blockly = "xgo_blockly.cli:main"
|
|
50
|
+
|
|
51
|
+
[tool.setuptools.packages.find]
|
|
52
|
+
include = ["xgo_blockly*"]
|
|
53
|
+
|
|
54
|
+
[tool.setuptools.package-data]
|
|
55
|
+
xgo_blockly = ["dist/**/*"]
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
from setuptools import setup, find_packages
|
|
5
|
+
import os
|
|
6
|
+
|
|
7
|
+
# 读取README文件
|
|
8
|
+
def read_readme():
|
|
9
|
+
with open("README.md", "r", encoding="utf-8") as fh:
|
|
10
|
+
return fh.read()
|
|
11
|
+
|
|
12
|
+
# 读取requirements文件
|
|
13
|
+
def read_requirements():
|
|
14
|
+
with open("requirements.txt", "r", encoding="utf-8") as fh:
|
|
15
|
+
return [line.strip() for line in fh if line.strip() and not line.startswith("#")]
|
|
16
|
+
|
|
17
|
+
setup(
|
|
18
|
+
name="xgo-blockly",
|
|
19
|
+
version="1.0.0",
|
|
20
|
+
author="XGO Team",
|
|
21
|
+
author_email="support@xgo.com",
|
|
22
|
+
description="XGO Blockly - 图形化编程Web服务器",
|
|
23
|
+
long_description=read_readme(),
|
|
24
|
+
long_description_content_type="text/markdown",
|
|
25
|
+
url="https://github.com/xgo-robotics/xgo-blockly",
|
|
26
|
+
packages=find_packages(),
|
|
27
|
+
classifiers=[
|
|
28
|
+
"Development Status :: 4 - Beta",
|
|
29
|
+
"Intended Audience :: Education",
|
|
30
|
+
"Intended Audience :: Developers",
|
|
31
|
+
"License :: OSI Approved :: MIT License",
|
|
32
|
+
"Operating System :: OS Independent",
|
|
33
|
+
"Programming Language :: Python :: 3",
|
|
34
|
+
"Programming Language :: Python :: 3.7",
|
|
35
|
+
"Programming Language :: Python :: 3.8",
|
|
36
|
+
"Programming Language :: Python :: 3.9",
|
|
37
|
+
"Programming Language :: Python :: 3.10",
|
|
38
|
+
"Programming Language :: Python :: 3.11",
|
|
39
|
+
"Topic :: Education",
|
|
40
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
41
|
+
"Framework :: Flask",
|
|
42
|
+
],
|
|
43
|
+
python_requires=">=3.7",
|
|
44
|
+
install_requires=read_requirements(),
|
|
45
|
+
entry_points={
|
|
46
|
+
"console_scripts": [
|
|
47
|
+
"xgo-blockly=xgo_blockly.cli:main",
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
package_data={
|
|
51
|
+
"xgo_blockly": [
|
|
52
|
+
"dist/**/*",
|
|
53
|
+
"dist/*",
|
|
54
|
+
"dist/assets/*",
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
include_package_data=True,
|
|
58
|
+
zip_safe=False,
|
|
59
|
+
keywords="xgo robot blockly programming education",
|
|
60
|
+
project_urls={
|
|
61
|
+
"Bug Reports": "https://github.com/xgo-robotics/xgo-blockly/issues",
|
|
62
|
+
"Source": "https://github.com/xgo-robotics/xgo-blockly",
|
|
63
|
+
"Documentation": "https://docs.xgo.com/",
|
|
64
|
+
},
|
|
65
|
+
)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
XGO Blockly Package
|
|
5
|
+
一个提供XGO机器人图形化编程的Web服务器包
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
__version__ = "1.0.0"
|
|
9
|
+
__author__ = "XGO Team"
|
|
10
|
+
__description__ = "XGO Blockly - 图形化编程Web服务器"
|
|
11
|
+
|
|
12
|
+
from .app import create_app
|
|
13
|
+
|
|
14
|
+
__all__ = ['create_app']
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
XGO Blockly Server
|
|
5
|
+
Flask服务器,提供Python代码执行和Vue3静态文件托管功能
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
from flask import Flask
|
|
10
|
+
from flask_cors import CORS
|
|
11
|
+
from .config import get_config
|
|
12
|
+
from .routes.api import api_bp
|
|
13
|
+
from .routes.static import static_bp
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def create_app(config_name=None):
|
|
17
|
+
"""应用工厂函数"""
|
|
18
|
+
# 获取配置
|
|
19
|
+
config_class = get_config(config_name)
|
|
20
|
+
|
|
21
|
+
# 创建Flask应用
|
|
22
|
+
config_instance = config_class()
|
|
23
|
+
app = Flask(__name__,
|
|
24
|
+
static_folder=config_instance.STATIC_FOLDER,
|
|
25
|
+
static_url_path=config_class.STATIC_URL_PATH)
|
|
26
|
+
|
|
27
|
+
# 加载配置
|
|
28
|
+
app.config.from_object(config_class)
|
|
29
|
+
|
|
30
|
+
# 初始化MIME类型
|
|
31
|
+
config_class.init_mime_types()
|
|
32
|
+
|
|
33
|
+
# 初始化扩展
|
|
34
|
+
CORS(app) # 允许跨域请求
|
|
35
|
+
|
|
36
|
+
# 注册蓝图
|
|
37
|
+
app.register_blueprint(api_bp)
|
|
38
|
+
app.register_blueprint(static_bp)
|
|
39
|
+
|
|
40
|
+
# 注册全局错误处理器
|
|
41
|
+
@app.errorhandler(404)
|
|
42
|
+
def not_found(error):
|
|
43
|
+
"""404错误处理,返回index.html用于Vue路由"""
|
|
44
|
+
from flask import send_from_directory
|
|
45
|
+
return send_from_directory(app.static_folder, 'index.html')
|
|
46
|
+
|
|
47
|
+
return app
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
if __name__ == '__main__':
|
|
51
|
+
# 检查dist目录是否存在
|
|
52
|
+
dist_path = os.path.join(os.path.dirname(__file__), 'dist')
|
|
53
|
+
if not os.path.exists(dist_path):
|
|
54
|
+
print("警告: dist目录不存在,请先构建Vue3项目")
|
|
55
|
+
print("运行命令: cd ../blockly-vue3 && npm run build")
|
|
56
|
+
print("然后将dist目录复制到当前目录")
|
|
57
|
+
|
|
58
|
+
# 获取配置
|
|
59
|
+
config_class = get_config()
|
|
60
|
+
|
|
61
|
+
print("启动XGO Blockly Server...")
|
|
62
|
+
print("API接口:")
|
|
63
|
+
print(" - POST /api/run-code - 运行Python代码(SSE响应)")
|
|
64
|
+
print(" - GET /api/health - 健康检查")
|
|
65
|
+
print("XGO状态读取接口:")
|
|
66
|
+
print(" - GET /api/xgo/motor - 读取舵机角度")
|
|
67
|
+
print(" - GET /api/xgo/battery - 读取电池电量")
|
|
68
|
+
print(" - GET /api/xgo/roll - 读取Roll姿态角度")
|
|
69
|
+
print(" - GET /api/xgo/pitch - 读取Pitch姿态角度")
|
|
70
|
+
print(" - GET /api/xgo/yaw - 读取Yaw姿态角度")
|
|
71
|
+
print(" - GET /api/xgo/status - 读取所有状态信息")
|
|
72
|
+
print(" - POST /api/xgo/reconnect - 重新连接XGO")
|
|
73
|
+
print("静态文件托管:")
|
|
74
|
+
print(" - / - Vue3应用主页")
|
|
75
|
+
print(" - /<path> - 静态资源文件")
|
|
76
|
+
|
|
77
|
+
# 创建应用实例
|
|
78
|
+
app = create_app()
|
|
79
|
+
|
|
80
|
+
# 启动Flask应用
|
|
81
|
+
app.run(
|
|
82
|
+
host=config_class.HOST,
|
|
83
|
+
port=config_class.PORT,
|
|
84
|
+
debug=config_class.DEBUG,
|
|
85
|
+
threaded=config_class.THREADED
|
|
86
|
+
)
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
XGO Blockly CLI
|
|
5
|
+
命令行入口点,用于启动XGO Blockly服务器
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import sys
|
|
10
|
+
import argparse
|
|
11
|
+
from .app import create_app
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def main():
|
|
15
|
+
"""主函数"""
|
|
16
|
+
parser = argparse.ArgumentParser(description='XGO Blockly Server')
|
|
17
|
+
parser.add_argument('--host', default='0.0.0.0', help='主机地址 (默认: 0.0.0.0)')
|
|
18
|
+
parser.add_argument('--port', type=int, default=8000, help='端口号 (默认: 8000)')
|
|
19
|
+
parser.add_argument('--debug', action='store_true', help='启用调试模式')
|
|
20
|
+
parser.add_argument('--config', choices=['development', 'production', 'testing'],
|
|
21
|
+
default='production', help='配置环境 (默认: production)')
|
|
22
|
+
|
|
23
|
+
args = parser.parse_args()
|
|
24
|
+
|
|
25
|
+
# 设置环境变量
|
|
26
|
+
os.environ['FLASK_ENV'] = args.config
|
|
27
|
+
|
|
28
|
+
# 创建应用
|
|
29
|
+
app = create_app(args.config)
|
|
30
|
+
|
|
31
|
+
print("启动XGO Blockly Server...")
|
|
32
|
+
print("API接口:")
|
|
33
|
+
print(" - POST /api/run-code - 运行Python代码(SSE响应)")
|
|
34
|
+
print(" - GET /api/health - 健康检查")
|
|
35
|
+
print("XGO状态读取接口:")
|
|
36
|
+
print(" - GET /api/xgo/motor - 读取舵机角度")
|
|
37
|
+
print(" - GET /api/xgo/battery - 读取电池电量")
|
|
38
|
+
print(" - GET /api/xgo/roll - 读取Roll姿态角度")
|
|
39
|
+
print(" - GET /api/xgo/pitch - 读取Pitch姿态角度")
|
|
40
|
+
print(" - GET /api/xgo/yaw - 读取Yaw姿态角度")
|
|
41
|
+
print(" - GET /api/xgo/status - 读取所有状态信息")
|
|
42
|
+
print(" - POST /api/xgo/reconnect - 重新连接XGO")
|
|
43
|
+
print("静态文件托管:")
|
|
44
|
+
print(" - / - Vue3应用主页")
|
|
45
|
+
print(" - /<path> - 静态资源文件")
|
|
46
|
+
print(f"服务器地址: http://{args.host}:{args.port}")
|
|
47
|
+
|
|
48
|
+
try:
|
|
49
|
+
# 启动服务器
|
|
50
|
+
app.run(
|
|
51
|
+
host=args.host,
|
|
52
|
+
port=args.port,
|
|
53
|
+
debug=args.debug,
|
|
54
|
+
threaded=True
|
|
55
|
+
)
|
|
56
|
+
except KeyboardInterrupt:
|
|
57
|
+
print("\n服务器已停止")
|
|
58
|
+
except Exception as e:
|
|
59
|
+
print(f"启动服务器时出错: {e}")
|
|
60
|
+
sys.exit(1)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
if __name__ == '__main__':
|
|
64
|
+
main()
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
配置文件
|
|
5
|
+
包含Flask应用的所有配置项
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import mimetypes
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Config:
|
|
13
|
+
"""基础配置类"""
|
|
14
|
+
# Flask基础配置
|
|
15
|
+
SECRET_KEY = 'xgo-blockly-secret-key'
|
|
16
|
+
MAX_CONTENT_LENGTH = 16 * 1024 * 1024 # 16MB max file size
|
|
17
|
+
|
|
18
|
+
# 静态文件配置
|
|
19
|
+
@property
|
|
20
|
+
def STATIC_FOLDER(self):
|
|
21
|
+
"""获取静态文件夹路径"""
|
|
22
|
+
# 直接使用相对路径
|
|
23
|
+
return os.path.join(os.path.dirname(__file__), 'dist')
|
|
24
|
+
|
|
25
|
+
STATIC_URL_PATH = ''
|
|
26
|
+
|
|
27
|
+
# 服务器配置
|
|
28
|
+
HOST = '0.0.0.0'
|
|
29
|
+
PORT = 8000
|
|
30
|
+
DEBUG = False
|
|
31
|
+
THREADED = True
|
|
32
|
+
|
|
33
|
+
# MIME类型配置
|
|
34
|
+
MIME_TYPES = {
|
|
35
|
+
'.js': 'application/javascript',
|
|
36
|
+
'.css': 'text/css',
|
|
37
|
+
'.json': 'application/json',
|
|
38
|
+
'.svg': 'image/svg+xml'
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@staticmethod
|
|
42
|
+
def init_mime_types():
|
|
43
|
+
"""初始化MIME类型"""
|
|
44
|
+
for ext, mime_type in Config.MIME_TYPES.items():
|
|
45
|
+
mimetypes.add_type(mime_type, ext)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class DevelopmentConfig(Config):
|
|
49
|
+
"""开发环境配置"""
|
|
50
|
+
DEBUG = True
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class ProductionConfig(Config):
|
|
54
|
+
"""生产环境配置"""
|
|
55
|
+
DEBUG = False
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class TestingConfig(Config):
|
|
59
|
+
"""测试环境配置"""
|
|
60
|
+
TESTING = True
|
|
61
|
+
DEBUG = True
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
# 配置映射
|
|
65
|
+
config = {
|
|
66
|
+
'development': DevelopmentConfig,
|
|
67
|
+
'production': ProductionConfig,
|
|
68
|
+
'testing': TestingConfig,
|
|
69
|
+
'default': DevelopmentConfig
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def get_config(env=None):
|
|
74
|
+
"""获取配置类"""
|
|
75
|
+
if env is None:
|
|
76
|
+
env = os.environ.get('FLASK_ENV', 'default')
|
|
77
|
+
return config.get(env, config['default'])
|