rcoder 1.0.0__py3-none-any.whl

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.
@@ -0,0 +1,373 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Rcoder 服务器安装工具
4
+ 用于自动安装和配置中转服务器和目标服务器
5
+ """
6
+
7
+ import os
8
+ import time
9
+ from typing import Optional, Dict, Any
10
+
11
+ class ServerInstaller:
12
+ """
13
+ 服务器安装器类
14
+ 处理远程服务器的自动安装和配置
15
+ """
16
+
17
+ def __init__(self, remote_host):
18
+ """
19
+ 初始化服务器安装器
20
+
21
+ Args:
22
+ remote_host: 远程主机实例
23
+ """
24
+ self.remote = remote_host
25
+ self.installation_steps = []
26
+ self.verbose = True
27
+
28
+ def install_rcoder_server(self, server_type: str = 'target',
29
+ use_venv: bool = True,
30
+ venv_path: str = '~/.rcoder/venv') -> Dict[str, Any]:
31
+ """
32
+ 在远程服务器上安装Rcoder服务器端
33
+
34
+ Args:
35
+ server_type: 服务器类型 ('target' 或 'proxy')
36
+ use_venv: 是否使用虚拟环境
37
+ venv_path: 虚拟环境路径
38
+
39
+ Returns:
40
+ 安装结果
41
+ """
42
+ print(f"=== 安装 {server_type} 服务器 ===")
43
+
44
+ results = {
45
+ 'success': False,
46
+ 'steps': [],
47
+ 'errors': [],
48
+ 'status': 'pending'
49
+ }
50
+
51
+ try:
52
+ # 步骤1: 系统更新
53
+ self._log(f"1. 更新系统包")
54
+ if self._update_system():
55
+ results['steps'].append('系统更新成功')
56
+ else:
57
+ results['errors'].append('系统更新失败')
58
+
59
+ # 步骤2: 安装必要依赖
60
+ self._log(f"2. 安装必要依赖")
61
+ if self._install_dependencies():
62
+ results['steps'].append('依赖安装成功')
63
+ else:
64
+ results['errors'].append('依赖安装失败')
65
+
66
+ # 步骤3: 安装Python
67
+ self._log(f"3. 安装Python")
68
+ if self._install_python():
69
+ results['steps'].append('Python安装成功')
70
+ else:
71
+ results['errors'].append('Python安装失败')
72
+
73
+ # 步骤4: 安装和配置虚拟环境
74
+ if use_venv:
75
+ self._log(f"4. 安装和配置虚拟环境")
76
+ if self._setup_venv(venv_path):
77
+ results['steps'].append('虚拟环境配置成功')
78
+ else:
79
+ results['errors'].append('虚拟环境配置失败')
80
+ else:
81
+ results['steps'].append('跳过虚拟环境配置')
82
+
83
+ # 步骤5: 安装Rcoder服务器端
84
+ self._log(f"5. 安装Rcoder服务器端")
85
+ if self._install_rcoder_server(use_venv, venv_path):
86
+ results['steps'].append('Rcoder服务器安装成功')
87
+ else:
88
+ results['errors'].append('Rcoder服务器安装失败')
89
+
90
+ # 步骤6: 配置服务器
91
+ self._log(f"6. 配置服务器")
92
+ config_result = self._configure_server(server_type, use_venv, venv_path)
93
+ if config_result:
94
+ results['steps'].append('服务器配置成功')
95
+ results['config'] = config_result
96
+ else:
97
+ results['errors'].append('服务器配置失败')
98
+
99
+ # 步骤7: 启动服务
100
+ self._log(f"7. 启动服务")
101
+ if self._start_services(use_venv, venv_path):
102
+ results['steps'].append('服务启动成功')
103
+ else:
104
+ results['errors'].append('服务启动失败')
105
+
106
+ # 步骤8: 验证安装
107
+ self._log(f"8. 验证安装")
108
+ if self._verify_installation():
109
+ results['steps'].append('安装验证成功')
110
+ results['success'] = True
111
+ results['status'] = 'completed'
112
+ else:
113
+ results['errors'].append('安装验证失败')
114
+ results['status'] = 'failed'
115
+
116
+ except Exception as e:
117
+ error_msg = f"安装过程出错: {str(e)}"
118
+ self._log(error_msg)
119
+ results['errors'].append(error_msg)
120
+ results['status'] = 'failed'
121
+
122
+ print()
123
+ if results['success']:
124
+ print(f"✅ {server_type} 服务器安装成功!")
125
+ else:
126
+ print(f"❌ {server_type} 服务器安装失败!")
127
+ print(f"错误: {results['errors']}")
128
+
129
+ return results
130
+
131
+ def _log(self, message: str):
132
+ """
133
+ 记录日志
134
+
135
+ Args:
136
+ message: 日志消息
137
+ """
138
+ if self.verbose:
139
+ print(f" {message}")
140
+
141
+ def _update_system(self) -> bool:
142
+ """
143
+ 更新系统包
144
+ """
145
+ try:
146
+ # 检测系统类型
147
+ os_info = self.remote.run('cat /etc/os-release | grep -E "^ID=" | cut -d= -f2 | tr -d \"\'"')
148
+ os_info = os_info.strip().lower()
149
+
150
+ if 'ubuntu' in os_info or 'debian' in os_info:
151
+ # Ubuntu/Debian
152
+ self.remote.run('sudo apt update -y')
153
+ self.remote.run('sudo apt upgrade -y')
154
+ elif 'centos' in os_info or 'rhel' in os_info or 'rocky' in os_info:
155
+ # CentOS/RHEL/Rocky
156
+ self.remote.run('sudo yum update -y')
157
+ elif 'alpine' in os_info:
158
+ # Alpine
159
+ self.remote.run('sudo apk update')
160
+ self.remote.run('sudo apk upgrade')
161
+ else:
162
+ # 尝试通用方法
163
+ self._log("未知系统类型,跳过系统更新")
164
+
165
+ return True
166
+ except Exception as e:
167
+ self._log(f"系统更新出错: {e}")
168
+ return False
169
+
170
+ def _install_dependencies(self) -> bool:
171
+ """
172
+ 安装必要依赖
173
+ """
174
+ try:
175
+ # 检测系统类型
176
+ os_info = self.remote.run('cat /etc/os-release | grep -E "^ID=" | cut -d= -f2 | tr -d \"\'"')
177
+ os_info = os_info.strip().lower()
178
+
179
+ if 'ubuntu' in os_info or 'debian' in os_info:
180
+ # Ubuntu/Debian
181
+ self.remote.run('sudo apt install -y build-essential curl wget git openssl libssl-dev')
182
+ elif 'centos' in os_info or 'rhel' in os_info or 'rocky' in os_info:
183
+ # CentOS/RHEL/Rocky
184
+ self.remote.run('sudo yum install -y gcc gcc-c++ curl wget git openssl openssl-devel')
185
+ elif 'alpine' in os_info:
186
+ # Alpine
187
+ self.remote.run('sudo apk add build-base curl wget git openssl openssl-dev')
188
+
189
+ return True
190
+ except Exception as e:
191
+ self._log(f"依赖安装出错: {e}")
192
+ return False
193
+
194
+ def _install_python(self) -> bool:
195
+ """
196
+ 安装Python
197
+ """
198
+ try:
199
+ # 检查Python是否已安装
200
+ python_version = self.remote.run('python3 --version 2>/dev/null || python --version 2>/dev/null')
201
+
202
+ if 'Python 3.' in python_version:
203
+ self._log(f"Python已安装: {python_version}")
204
+ return True
205
+
206
+ # 检测系统类型并安装Python
207
+ os_info = self.remote.run('cat /etc/os-release | grep -E "^ID=" | cut -d= -f2 | tr -d \"\'"')
208
+ os_info = os_info.strip().lower()
209
+
210
+ if 'ubuntu' in os_info or 'debian' in os_info:
211
+ # Ubuntu/Debian
212
+ self.remote.run('sudo apt install -y python3 python3-pip python3-venv')
213
+ elif 'centos' in os_info or 'rhel' in os_info or 'rocky' in os_info:
214
+ # CentOS/RHEL/Rocky
215
+ self.remote.run('sudo yum install -y python3 python3-pip python3-venv')
216
+ elif 'alpine' in os_info:
217
+ # Alpine
218
+ self.remote.run('sudo apk add python3 py3-pip python3-venv')
219
+
220
+ # 验证安装
221
+ new_version = self.remote.run('python3 --version')
222
+ return 'Python 3.' in new_version
223
+ except Exception as e:
224
+ self._log(f"Python安装出错: {e}")
225
+ return False
226
+
227
+ def _setup_venv(self, venv_path: str) -> bool:
228
+ """
229
+ 安装和配置虚拟环境
230
+ """
231
+ try:
232
+ # 扩展路径
233
+ expanded_path = self.remote.run(f'echo {venv_path}')
234
+ expanded_path = expanded_path.strip()
235
+
236
+ # 创建虚拟环境目录
237
+ self.remote.run(f'mkdir -p $(dirname {expanded_path})')
238
+
239
+ # 删除现有虚拟环境
240
+ self.remote.run(f'rm -rf {expanded_path}')
241
+
242
+ # 创建虚拟环境
243
+ self.remote.run(f'python3 -m venv {expanded_path}')
244
+
245
+ # 激活虚拟环境并升级pip
246
+ activate_cmd = f'source {expanded_path}/bin/activate && pip install --upgrade pip'
247
+ self.remote.run(activate_cmd)
248
+
249
+ # 验证虚拟环境
250
+ venv_python = self.remote.run(f'{expanded_path}/bin/python --version')
251
+ return 'Python 3.' in venv_python
252
+ except Exception as e:
253
+ self._log(f"虚拟环境配置出错: {e}")
254
+ return False
255
+
256
+ def _install_rcoder_server(self, use_venv: bool, venv_path: str) -> bool:
257
+ """
258
+ 安装Rcoder服务器端
259
+ """
260
+ try:
261
+ # 克隆Rcoder仓库
262
+ self.remote.run('git clone https://github.com/trae-ai/rcoder-server ~/.rcoder/server')
263
+
264
+ # 安装依赖
265
+ if use_venv:
266
+ expanded_path = self.remote.run(f'echo {venv_path}')
267
+ expanded_path = expanded_path.strip()
268
+ install_cmd = f'source {expanded_path}/bin/activate && pip install -r ~/.rcoder/server/requirements.txt'
269
+ else:
270
+ install_cmd = 'pip install -r ~/.rcoder/server/requirements.txt'
271
+
272
+ self.remote.run(install_cmd)
273
+
274
+ return True
275
+ except Exception as e:
276
+ self._log(f"Rcoder服务器安装出错: {e}")
277
+ return False
278
+
279
+ def _configure_server(self, server_type: str, use_venv: bool, venv_path: str) -> Dict[str, Any]:
280
+ """
281
+ 配置服务器
282
+ """
283
+ try:
284
+ # 创建配置文件
285
+ config = {
286
+ 'server_type': server_type,
287
+ 'port': 443,
288
+ 'use_https': True,
289
+ 'enable_compression': True,
290
+ 'enable_connection_pool': True
291
+ }
292
+
293
+ # 写入配置文件
294
+ config_json = str(config).replace("'", '"')
295
+ self.remote.run(f'echo "{config_json}" > ~/.rcoder/server/config.json')
296
+
297
+ # 创建启动脚本
298
+ if use_venv:
299
+ expanded_path = self.remote.run(f'echo {venv_path}')
300
+ expanded_path = expanded_path.strip()
301
+ start_script = f"#!/bin/bash\nsource {expanded_path}/bin/activate\npython ~/.rcoder/server/server.py"
302
+ else:
303
+ start_script = f"#!/bin/bash\npython ~/.rcoder/server/server.py"
304
+
305
+ self.remote.run(f'echo "{start_script}" > ~/.rcoder/server/start.sh')
306
+ self.remote.run('chmod +x ~/.rcoder/server/start.sh')
307
+
308
+ # 创建systemd服务文件
309
+ service_file = f"[Unit]\nDescription=Rcoder Server\nAfter=network.target\n\n[Service]\nType=simple\nUser=$(whoami)\nExecStart=~/.rcoder/server/start.sh\nRestart=always\n\n[Install]\nWantedBy=multi-user.target"
310
+ self.remote.run(f'echo "{service_file}" | sudo tee /etc/systemd/system/rcoder.service')
311
+
312
+ return config
313
+ except Exception as e:
314
+ self._log(f"服务器配置出错: {e}")
315
+ return {}
316
+
317
+ def _start_services(self, use_venv: bool, venv_path: str) -> bool:
318
+ """
319
+ 启动服务
320
+ """
321
+ try:
322
+ # 重新加载systemd
323
+ self.remote.run('sudo systemctl daemon-reload')
324
+
325
+ # 启用并启动服务
326
+ self.remote.run('sudo systemctl enable rcoder.service')
327
+ self.remote.run('sudo systemctl start rcoder.service')
328
+
329
+ # 等待服务启动
330
+ time.sleep(5)
331
+
332
+ # 检查服务状态
333
+ status = self.remote.run('sudo systemctl status rcoder.service | grep -E "Active:"')
334
+ return 'active (running)' in status
335
+ except Exception as e:
336
+ self._log(f"服务启动出错: {e}")
337
+ return False
338
+
339
+ def _verify_installation(self) -> bool:
340
+ """
341
+ 验证安装
342
+ """
343
+ try:
344
+ # 检查服务状态
345
+ status = self.remote.run('sudo systemctl status rcoder.service | grep -E "Active:"')
346
+ if 'active (running)' not in status:
347
+ return False
348
+
349
+ # 测试连接
350
+ test_result = self.remote.run('curl -s http://localhost:443/health')
351
+ return 'ok' in test_result.lower()
352
+ except Exception as e:
353
+ self._log(f"安装验证出错: {e}")
354
+ return False
355
+
356
+
357
+ def install_server(remote_host, server_type: str = 'target',
358
+ use_venv: bool = True,
359
+ venv_path: str = '~/.rcoder/venv') -> Dict[str, Any]:
360
+ """
361
+ 安装服务器的便捷函数
362
+
363
+ Args:
364
+ remote_host: 远程主机实例
365
+ server_type: 服务器类型
366
+ use_venv: 是否使用虚拟环境
367
+ venv_path: 虚拟环境路径
368
+
369
+ Returns:
370
+ 安装结果
371
+ """
372
+ installer = ServerInstaller(remote_host)
373
+ return installer.install_rcoder_server(server_type, use_venv, venv_path)
rcoder/utils.py ADDED
@@ -0,0 +1,213 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Rcoder 工具模块
4
+ 提供简化使用的工具函数和辅助功能,降低使用门槛
5
+ """
6
+
7
+ import os
8
+ import json
9
+ import platform
10
+ from typing import Optional, Dict, Any
11
+
12
+ class ConfigManager:
13
+ """配置管理类,简化配置过程"""
14
+
15
+ def __init__(self, config_file: str = '~/.rcoder/config.json'):
16
+ """
17
+ 初始化配置管理器
18
+
19
+ Args:
20
+ config_file: 配置文件路径
21
+ """
22
+ self.config_file = os.path.expanduser(config_file)
23
+ self.config = self._load_config()
24
+
25
+ def _load_config(self) -> Dict[str, Any]:
26
+ """加载配置文件"""
27
+ try:
28
+ if os.path.exists(self.config_file):
29
+ with open(self.config_file, 'r', encoding='utf-8') as f:
30
+ return json.load(f)
31
+ except Exception as e:
32
+ print(f"警告: 加载配置文件失败: {e}")
33
+ return self._get_default_config()
34
+
35
+ def _get_default_config(self) -> Dict[str, Any]:
36
+ """获取默认配置"""
37
+ return {
38
+ 'servers': {
39
+ 'local': {
40
+ 'host': '127.0.0.1',
41
+ 'port': 443,
42
+ 'use_https_disguise': True,
43
+ 'proxy_server': None
44
+ }
45
+ },
46
+ 'default_server': 'local',
47
+ 'timeout': 60,
48
+ 'restart_max_wait': 60,
49
+ 'monitoring_interval': 30
50
+ }
51
+
52
+ def save_config(self):
53
+ """保存配置文件"""
54
+ try:
55
+ os.makedirs(os.path.dirname(self.config_file), exist_ok=True)
56
+ with open(self.config_file, 'w', encoding='utf-8') as f:
57
+ json.dump(self.config, f, indent=2, ensure_ascii=False)
58
+ print(f"✅ 配置已保存到: {self.config_file}")
59
+ except Exception as e:
60
+ print(f"❌ 保存配置文件失败: {e}")
61
+
62
+ def add_server(self, name: str, host: str, port: int = 443,
63
+ use_https_disguise: bool = True,
64
+ proxy_server: Optional[tuple] = None):
65
+ """添加服务器配置"""
66
+ self.config['servers'][name] = {
67
+ 'host': host,
68
+ 'port': port,
69
+ 'use_https_disguise': use_https_disguise,
70
+ 'proxy_server': proxy_server
71
+ }
72
+ self.save_config()
73
+
74
+ def get_server(self, name: Optional[str] = None) -> Dict[str, Any]:
75
+ """获取服务器配置"""
76
+ server_name = name or self.config.get('default_server', 'local')
77
+ return self.config['servers'].get(server_name, self.config['servers']['local'])
78
+
79
+
80
+ def quick_setup():
81
+ """快速设置向导,引导用户完成初始配置"""
82
+ print("=== Rcoder 快速设置向导 ===")
83
+ print("帮助您快速配置 rcoder,降低使用门槛")
84
+ print()
85
+
86
+ config = ConfigManager()
87
+
88
+ # 询问是否添加新服务器
89
+ add_server = input("是否添加新服务器? (y/n): ").lower() == 'y'
90
+
91
+ if add_server:
92
+ server_name = input("服务器名称 (例如: my-server): ")
93
+ server_host = input("服务器地址 (IP或域名): ")
94
+ server_port = input("端口号 (默认443): ")
95
+ server_port = int(server_port) if server_port else 443
96
+ use_https = input("启用 HTTPS 伪装? (y/n, 默认y): ").lower() != 'n'
97
+
98
+ # 询问是否使用中转服务器
99
+ use_proxy = input("使用中转服务器? (y/n): ").lower() == 'y'
100
+ proxy_server = None
101
+ if use_proxy:
102
+ proxy_host = input("中转服务器地址: ")
103
+ proxy_port = input("中转服务器端口: ")
104
+ proxy_server = (proxy_host, int(proxy_port))
105
+
106
+ # 添加服务器配置
107
+ config.add_server(
108
+ name=server_name,
109
+ host=server_host,
110
+ port=server_port,
111
+ use_https_disguise=use_https,
112
+ proxy_server=proxy_server
113
+ )
114
+
115
+ # 设置为默认服务器
116
+ config.config['default_server'] = server_name
117
+ config.save_config()
118
+
119
+ print(f"✅ 服务器 '{server_name}' 已添加并设置为默认服务器")
120
+
121
+ print()
122
+ print("=== 设置完成 ===")
123
+ print("现在您可以使用以下命令快速开始:")
124
+ print()
125
+ print("1. 导入并获取远程主机:")
126
+ print(" from rcoder.utils import get_default_remote")
127
+ print(" remote = get_default_remote()")
128
+ print()
129
+ print("2. 执行命令:")
130
+ print(" result = remote.run('ls -la')")
131
+ print()
132
+
133
+
134
+ def get_default_remote():
135
+ """获取默认远程主机实例,无需手动配置"""
136
+ from rcoder.core import get_remote_host
137
+
138
+ config = ConfigManager()
139
+ server_config = config.get_server()
140
+
141
+ return get_remote_host(
142
+ host=server_config['host'],
143
+ port=server_config['port'],
144
+ use_https_disguise=server_config['use_https_disguise'],
145
+ proxy_server=server_config['proxy_server']
146
+ )
147
+
148
+
149
+ def create_alias():
150
+ """创建命令行别名,方便快速访问"""
151
+ shell = platform.system().lower()
152
+
153
+ if shell == 'windows':
154
+ # Windows 系统
155
+ alias_cmd = 'doskey rcoder=python -m rcoder.cli $*'
156
+ print("在 Windows 中创建别名:")
157
+ print(f"请在命令提示符中执行: {alias_cmd}")
158
+ print("或添加到注册表以永久生效")
159
+ else:
160
+ # Linux/macOS 系统
161
+ shell_config = os.path.expanduser('~/.bashrc')
162
+ if os.path.exists(os.path.expanduser('~/.zshrc')):
163
+ shell_config = os.path.expanduser('~/.zshrc')
164
+
165
+ alias_cmd = 'alias rcoder="python -m rcoder.cli"'
166
+ print(f"在 {shell_config} 中添加以下行:")
167
+ print(alias_cmd)
168
+ print("然后执行: source", shell_config)
169
+
170
+ print()
171
+ print("创建别名后,您可以直接在终端中使用 'rcoder' 命令")
172
+
173
+
174
+ def validate_config():
175
+ """验证配置文件的有效性"""
176
+ config = ConfigManager()
177
+ print("=== 配置验证 ===")
178
+ print(f"配置文件: {config.config_file}")
179
+ print(f"默认服务器: {config.config.get('default_server', 'local')}")
180
+ print(f"服务器数量: {len(config.config.get('servers', {}))}")
181
+ print()
182
+ print("服务器配置:")
183
+ for name, server in config.config.get('servers', {}).items():
184
+ print(f" - {name}:")
185
+ print(f" 地址: {server.get('host')}:{server.get('port')}")
186
+ print(f" HTTPS伪装: {'启用' if server.get('use_https_disguise') else '禁用'}")
187
+ if server.get('proxy_server'):
188
+ print(f" 中转服务器: {server.get('proxy_server')[0]}:{server.get('proxy_server')[1]}")
189
+ print()
190
+ print("✅ 配置验证完成")
191
+
192
+
193
+ def export_config():
194
+ """导出配置文件,方便在不同设备间共享"""
195
+ config = ConfigManager()
196
+ export_path = os.path.expanduser('~/.rcoder/config_export.json')
197
+ config.save_config()
198
+ print(f"✅ 配置已导出到: {export_path}")
199
+ print("您可以将此文件复制到其他设备,然后使用 import_config() 导入")
200
+
201
+
202
+ def import_config(config_file: str):
203
+ """导入配置文件"""
204
+ try:
205
+ with open(config_file, 'r', encoding='utf-8') as f:
206
+ imported_config = json.load(f)
207
+
208
+ config = ConfigManager()
209
+ config.config = imported_config
210
+ config.save_config()
211
+ print(f"✅ 配置已从 {config_file} 导入")
212
+ except Exception as e:
213
+ print(f"❌ 导入配置失败: {e}")