devtools-hub 2.6.0__tar.gz → 2.7.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devtools-hub
3
- Version: 2.6.0
3
+ Version: 2.7.0
4
4
  Home-page: https://github.com/jingjing737/devtools-hub
5
5
  Author: jingjing737
6
6
  Requires-Python: >=3.7
@@ -7,18 +7,18 @@
7
7
 
8
8
  ## 📦 Installation | 安装
9
9
 
10
+ ### Homebrew (macOS)
10
11
  ```bash
11
- pip install devtools-hub
12
+ brew tap jingjing737/tap
13
+ brew install devtools-hub
12
14
  ```
13
15
 
14
- Or from source:
16
+ ### pip
15
17
  ```bash
16
- git clone https://github.com/jingjing737/devtools-hub.git
17
- cd devtools-hub
18
- pip install -e .
18
+ pip install devtools-hub
19
19
  ```
20
20
 
21
- 或从源码安装:
21
+ ### 从源码安装
22
22
  ```bash
23
23
  git clone https://github.com/jingjing737/devtools-hub.git
24
24
  cd devtools-hub
@@ -162,5 +162,6 @@ MIT License
162
162
  ---
163
163
 
164
164
  **GitHub**: https://github.com/jingjing737/devtools-hub
165
+ **Homebrew**: https://github.com/jingjing737/homebrew-tap
165
166
  **PyPI**: https://pypi.org/project/devtools-hub/
166
167
  **Version**: v2.6.0
@@ -0,0 +1,527 @@
1
+ #!/usr/bin/env python3
2
+ """DevTools Hub CLI v2.7.0 - 开发者工具集"""
3
+ import sys
4
+ import subprocess
5
+ import json
6
+ import time
7
+ import platform
8
+ import os
9
+ import hashlib
10
+ import base64
11
+ import socket
12
+ import re
13
+ import urllib.request
14
+ import urllib.error
15
+
16
+ PORT = 5001
17
+ URL = f"http://localhost:{PORT}"
18
+
19
+ def check():
20
+ try:
21
+ import requests
22
+ r = requests.get(f"{URL}/api/health", timeout=1)
23
+ return r.ok
24
+ except:
25
+ return False
26
+
27
+ def main():
28
+ if len(sys.argv) < 2:
29
+ print("""
30
+ 🔧 DevTools Hub v2.7.0 - 开发者工具集
31
+
32
+ 用法: devtools <命令>
33
+
34
+ 系统监控:
35
+ status 系统状态
36
+ cpu CPU 信息
37
+ cpu-usage CPU 使用率趋势
38
+ mem 内存信息
39
+ disk 磁盘信息
40
+ battery 电池状态
41
+ temp 温度监控
42
+ uptime 运行时间
43
+ load 系统负载
44
+
45
+ 网络工具:
46
+ ip 本机 IP
47
+ publicip 公网 IP
48
+ ping Ping 测试
49
+ dns DNS 查询
50
+ speed 网速测试
51
+ wifi WiFi 信息
52
+ tracert 路由追踪
53
+
54
+ 进程管理:
55
+ top 高占用进程
56
+ ps 进程列表
57
+ kill 结束进程
58
+ zombie 僵尸进程
59
+
60
+ 文件工具:
61
+ du 磁盘使用
62
+ find 查找文件
63
+ hash 计算哈希
64
+ json JSON 工具
65
+ base64 Base64 编解码
66
+ env 环境变量
67
+
68
+ 开发工具:
69
+ ports 端口扫描
70
+ services 系统服务
71
+ git Git 状态
72
+ node Node.js 信息
73
+ python Python 版本
74
+
75
+ 系统:
76
+ info 系统信息
77
+ bench 性能测试
78
+ clean 清理缓存
79
+ update 检查更新
80
+ start 启动服务
81
+ stop 停止服务
82
+ """)
83
+ return
84
+
85
+ cmd = sys.argv[1]
86
+ args = sys.argv[2:]
87
+
88
+ # ========== 系统监控 ==========
89
+ if cmd == "status":
90
+ if check():
91
+ import requests
92
+ r = requests.get(f"{URL}/api/health")
93
+ print(json.dumps(r.json(), indent=2))
94
+ else:
95
+ print("❌ 服务未运行,请先 devtools start")
96
+
97
+ elif cmd == "cpu":
98
+ import psutil
99
+ print(f"CPU: {psutil.cpu_percent()}% 核心: {psutil.cpu_count()} 物理核心: {psutil.cpu_count(logical=False)}")
100
+
101
+ elif cmd == "cpu-usage":
102
+ import psutil
103
+ print("📊 CPU 使用率(5秒采样)...")
104
+ for i in range(5):
105
+ print(f" {psutil.cpu_percent(interval=1)}%", end=" ", flush=True)
106
+ print()
107
+
108
+ elif cmd == "mem":
109
+ import psutil
110
+ m = psutil.virtual_memory()
111
+ print(f"内存: {m.percent}% 已用: {m.used/1024**3:.1f}GB 可用: {m.available/1024**3:.1f}GB 总计: {m.total/1024**3:.1f}GB")
112
+ # Swap
113
+ s = psutil.swap_memory()
114
+ print(f"Swap: {s.percent}% 已用: {s.used/1024**3:.1f}GB")
115
+
116
+ elif cmd == "disk":
117
+ import psutil
118
+ for p in [('/', '/System/Volumes/Data', '/Users')]:
119
+ try:
120
+ d = psutil.disk_usage(p)
121
+ print(f"{p}: {d.percent}% 已用: {d.used/1024**3:.1f}GB 可用: {d.free/1024**3:.1f}GB")
122
+ except:
123
+ pass
124
+
125
+ elif cmd == "battery":
126
+ import psutil
127
+ try:
128
+ b = psutil.sensors_battery()
129
+ if b:
130
+ print(f"电池: {b.percent}% {'🔌 充电中' if b.power_plugged else '🔋 使用电池'}")
131
+ if b.secsleft and b.secsleft > 0:
132
+ h = b.secsleft // 3600
133
+ m = (b.secsleft % 3600) // 60
134
+ print(f"剩余时间: {h}h {m}m")
135
+ else:
136
+ print("❌ 无电池(台式机)")
137
+ except:
138
+ print("❌ 电池信息不可用")
139
+
140
+ elif cmd == "temp":
141
+ import psutil
142
+ temps = getattr(psutil, 'sensors_temperatures', lambda: {})()
143
+ if temps:
144
+ for name, entries in temps.items():
145
+ for entry in entries:
146
+ label = entry.label or name
147
+ current = entry.current
148
+ high = entry.high or "N/A"
149
+ print(f"🌡️ {label}: {current:.1f}°C 最高: {high}°C")
150
+ else:
151
+ print("❌ 温度信息不可用(虚拟机或权限不足)")
152
+
153
+ elif cmd == "uptime":
154
+ import psutil
155
+ boot = psutil.boot_time()
156
+ import datetime
157
+ now = datetime.datetime.now()
158
+ boot_time = datetime.datetime.fromtimestamp(boot)
159
+ delta = now - boot_time
160
+ print(f"系统运行: {delta.days}天 {delta.seconds//3600}小时 {(delta.seconds%3600)//60}分钟")
161
+ print(f"启动时间: {boot_time.strftime('%Y-%m-%d %H:%M:%S')}")
162
+
163
+ elif cmd == "load":
164
+ import os
165
+ load = os.getloadavg() if hasattr(os, 'getloadavg') else (0, 0, 0)
166
+ print(f"负载: {load[0]:.2f} {load[1]:.2f} {load[2]:.2f} (1/5/15分钟)")
167
+
168
+ # ========== 网络工具 ==========
169
+ elif cmd == "ip":
170
+ import socket
171
+ try:
172
+ hostname = socket.gethostname()
173
+ ip = socket.gethostbyname(hostname)
174
+ print(f"主机: {hostname}")
175
+ print(f"IP: {ip}")
176
+ except:
177
+ print(f"IP: {socket.gethostbyname(socket.gethostname())}")
178
+
179
+ elif cmd == "publicip":
180
+ try:
181
+ ip = urllib.request.urlopen('https://api.ipify.org', timeout=5).read().decode()
182
+ print(f"🌐 公网IP: {ip}")
183
+ # 获取位置
184
+ try:
185
+ data = urllib.request.urlopen(f'https://ipapi.co/{ip}/json/', timeout=5).read().decode()
186
+ loc = json.loads(data)
187
+ print(f"📍 位置: {loc.get('city', '')}, {loc.get('country_name', '')}")
188
+ print(f"🏢 运营商: {loc.get('org', '')}")
189
+ except:
190
+ pass
191
+ except Exception as e:
192
+ print(f"❌ 获取失败: {e}")
193
+
194
+ elif cmd == "ping":
195
+ if not args:
196
+ args = ['8.8.8.8']
197
+ host = args[0]
198
+ print(f"📡 Ping {host}...")
199
+ result = subprocess.run(['ping', '-c', '4', host], capture_output=True, text=True)
200
+ lines = result.stdout.split('\n')
201
+ for line in lines[-5:]:
202
+ if line.strip():
203
+ print(line)
204
+ if result.returncode != 0:
205
+ print("❌ Ping 失败")
206
+
207
+ elif cmd == "dns":
208
+ if not args:
209
+ print("用法: devtools dns <域名>")
210
+ return
211
+ domain = args[0]
212
+ print(f"🔍 DNS 查询: {domain}")
213
+ try:
214
+ ip = socket.gethostbyname(domain)
215
+ print(f"✅ 解析: {ip}")
216
+ except Exception as e:
217
+ print(f"❌ 解析失败: {e}")
218
+
219
+ elif cmd == "speed":
220
+ print("📊 测速中(下载测试)...")
221
+ try:
222
+ start = time.time()
223
+ urllib.request.urlopen('https://speed.cloudflare.com/__down?bytes=10000000', timeout=30)
224
+ elapsed = time.time() - start
225
+ speed = 10 / elapsed # MB/s
226
+ print(f"⚡ 网速: {speed:.1f} MB/s ({(speed*8):.1f} Mbps)")
227
+ except Exception as e:
228
+ print(f"❌ 测速失败: {e}")
229
+
230
+ elif cmd == "wifi":
231
+ try:
232
+ result = subprocess.run(['networksetup', '-listallhardwareports'], capture_output=True, text=True)
233
+ print(result.stdout)
234
+ except:
235
+ print("❌ WiFi 信息不可用")
236
+
237
+ elif cmd == "tracert":
238
+ if not args:
239
+ args = ['8.8.8.8']
240
+ host = args[0]
241
+ print(f"🛤️ 路由追踪: {host}")
242
+ result = subprocess.run(['traceroute', '-m', '15', host], capture_output=True, text=True)
243
+ print(result.stdout[:2000])
244
+
245
+ # ========== 进程管理 ==========
246
+ elif cmd == "top":
247
+ import psutil
248
+ procs = []
249
+ for p in psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_percent', 'username']):
250
+ try:
251
+ procs.append(p.info)
252
+ except:
253
+ pass
254
+ by_cpu = sorted(procs, key=lambda x: x['cpu_percent'] or 0, reverse=True)[:8]
255
+ by_mem = sorted(procs, key=lambda x: x['memory_percent'] or 0, reverse=True)[:5]
256
+ print("🔥 CPU 高占用:")
257
+ for p in by_cpu:
258
+ print(f" PID {p['pid']:>6} | {p['name'][:25]:<25} | {p['cpu_percent']:>5}% | {p.get('username', '')[:15]}")
259
+ print("\n💾 内存高占用:")
260
+ for p in by_mem:
261
+ print(f" PID {p['pid']:>6} | {p['name'][:25]:<25} | {p['memory_percent']:>5}%")
262
+
263
+ elif cmd == "ps":
264
+ import psutil
265
+ procs = []
266
+ for p in psutil.process_iter(['pid', 'name', 'status', 'cpu_percent']):
267
+ try:
268
+ procs.append(p.info)
269
+ except:
270
+ pass
271
+ print(f"📋 总进程数: {len(procs)}")
272
+ running = sum(1 for p in procs if p.get('status') == 'running')
273
+ sleeping = sum(1 for p in procs if p.get('status') == 'sleeping')
274
+ print(f" 运行中: {running} 睡眠中: {sleeping}")
275
+
276
+ elif cmd == "kill":
277
+ if not args:
278
+ print("用法: devtools kill <进程名或PID>")
279
+ return
280
+ target = args[0]
281
+ try:
282
+ pid = int(target)
283
+ p = psutil.Process(pid)
284
+ name = p.name()
285
+ p.kill()
286
+ print(f"✅ 已结束进程: {name} (PID: {pid})")
287
+ except ValueError:
288
+ # 按名称结束
289
+ killed = 0
290
+ for p in psutil.process_iter(['pid', 'name']):
291
+ try:
292
+ if target.lower() in p.info['name'].lower():
293
+ p.kill()
294
+ killed += 1
295
+ except:
296
+ pass
297
+ print(f"✅ 已结束 {killed} 个进程: {target}")
298
+ except Exception as e:
299
+ print(f"❌ 结束进程失败: {e}")
300
+
301
+ elif cmd == "zombie":
302
+ import psutil
303
+ zombies = []
304
+ for p in psutil.process_iter(['pid', 'name', 'status']):
305
+ try:
306
+ if p.info['status'] == 'zombie':
307
+ zombies.append(p.info)
308
+ except:
309
+ pass
310
+ if zombies:
311
+ print(f"🧟 僵尸进程 ({len(zombies)}):")
312
+ for z in zombies:
313
+ print(f" PID {z['pid']}: {z['name']}")
314
+ else:
315
+ print("✅ 无僵尸进程")
316
+
317
+ # ========== 文件工具 ==========
318
+ elif cmd == "du":
319
+ if not args:
320
+ path = os.path.expanduser('~')
321
+ else:
322
+ path = args[0]
323
+ print(f"📁 磁盘使用: {path}")
324
+ import subprocess
325
+ result = subprocess.run(['du', '-sh', path], capture_output=True, text=True)
326
+ print(result.stdout.strip())
327
+
328
+ elif cmd == "find":
329
+ print("🔍 查找大文件...")
330
+ import psutil
331
+ import os
332
+ home = os.path.expanduser('~')
333
+ files = []
334
+ for root, dirs, filenames in os.walk(home):
335
+ # 跳过隐藏目录
336
+ dirs[:] = [d for d in dirs if not d.startswith('.')]
337
+ for f in filenames:
338
+ fp = os.path.join(root, f)
339
+ try:
340
+ size = os.path.getsize(fp)
341
+ if size > 100 * 1024 * 1024: # > 100MB
342
+ files.append((size, fp))
343
+ except:
344
+ pass
345
+ files.sort(reverse=True)
346
+ print(f"找到 {len(files)} 个大文件 (>100MB):")
347
+ for size, fp in files[:20]:
348
+ print(f" {size/1024**3:.2f}GB {fp[:80]}")
349
+
350
+ elif cmd == "hash":
351
+ if not args:
352
+ print("用法: devtools hash <文件路径>")
353
+ return
354
+ filepath = os.path.expanduser(args[0])
355
+ if not os.path.exists(filepath):
356
+ print(f"❌ 文件不存在: {filepath}")
357
+ return
358
+ print(f"🔐 计算哈希: {filepath}")
359
+ with open(filepath, 'rb') as f:
360
+ md5 = hashlib.md5(f.read()).hexdigest()
361
+ with open(filepath, 'rb') as f:
362
+ sha1 = hashlib.sha1(f.read()).hexdigest()
363
+ with open(filepath, 'rb') as f:
364
+ sha256 = hashlib.sha256(f.read()).hexdigest()
365
+ print(f"MD5: {md5}")
366
+ print(f"SHA1: {sha1}")
367
+ print(f"SHA256: {sha256}")
368
+
369
+ elif cmd == "json":
370
+ if not args:
371
+ print("用法: devtools json <JSON字符串或文件路径>")
372
+ return
373
+ text = args[0]
374
+ if os.path.exists(os.path.expanduser(text)):
375
+ with open(os.path.expanduser(text)) as f:
376
+ text = f.read()
377
+ try:
378
+ obj = json.loads(text)
379
+ print(json.dumps(obj, indent=2, ensure_ascii=False))
380
+ except json.JSONDecodeError as e:
381
+ print(f"❌ JSON 解析错误: {e}")
382
+
383
+ elif cmd == "base64":
384
+ if len(args) < 2:
385
+ print("用法: devtools base64 <encode|decode> <文本或文件路径>")
386
+ return
387
+ mode = args[0]
388
+ text = args[1]
389
+ if os.path.exists(os.path.expanduser(text)):
390
+ with open(os.path.expanduser(text), 'rb') as f:
391
+ text = f.read()
392
+ if mode == 'encode':
393
+ print(base64.b64encode(text).decode())
394
+ elif mode == 'decode':
395
+ print(base64.b64decode(text).decode(errors='ignore'))
396
+ else:
397
+ text = text.encode()
398
+ if mode == 'encode':
399
+ print(base64.b64encode(text).decode())
400
+ elif mode == 'decode':
401
+ try:
402
+ print(base64.b64decode(text).decode(errors='ignore'))
403
+ except:
404
+ print("❌ 解码失败")
405
+
406
+ elif cmd == "env":
407
+ if args:
408
+ key = args[0]
409
+ print(f"{key}={os.environ.get(key, '❌ 未设置')}")
410
+ else:
411
+ print("🔧 环境变量:")
412
+ for k, v in sorted(os.environ.items()):
413
+ if args and args[0].lower() in k.lower():
414
+ print(f" {k}={v}")
415
+
416
+ # ========== 开发工具 ==========
417
+ elif cmd == "ports":
418
+ from devtools_hub.scanner import scan_common_ports
419
+ print("🔍 扫描常用端口...")
420
+ ports = scan_common_ports()
421
+ if ports:
422
+ for p in ports:
423
+ print(f" ✅ {p['port']} ({p['name']}) - 开放")
424
+ else:
425
+ print(" 未发现开放端口")
426
+
427
+ elif cmd == "services":
428
+ from devtools_hub.scanner import get_services
429
+ print("📋 系统服务:")
430
+ services = get_services()
431
+ for s in services[:20]:
432
+ pid_str = str(s['pid']) if s['pid'] else '-'
433
+ print(f" [{pid_str:>6}] {s['name']}")
434
+
435
+ elif cmd == "git":
436
+ try:
437
+ result = subprocess.run(['git', 'status'], capture_output=True, text=True, cwd=os.path.dirname(os.path.dirname(__file__)))
438
+ print(result.stdout)
439
+ if result.returncode != 0:
440
+ print(result.stderr)
441
+ except FileNotFoundError:
442
+ print("❌ Git 未安装")
443
+
444
+ elif cmd == "node":
445
+ try:
446
+ v = subprocess.run(['node', '--version'], capture_output=True, text=True)
447
+ npm = subprocess.run(['npm', '--version'], capture_output=True, text=True)
448
+ print(f"Node.js: {v.stdout.strip()}")
449
+ print(f"npm: {npm.stdout.strip()}")
450
+ except FileNotFoundError:
451
+ print("❌ Node.js 未安装")
452
+
453
+ elif cmd == "python":
454
+ v = sys.version_info
455
+ print(f"Python: {v.major}.{v.minor}.{v.micro}")
456
+ try:
457
+ import pip
458
+ print(f"pip: {pip.__version__}")
459
+ except:
460
+ pass
461
+
462
+ # ========== 系统 ==========
463
+ elif cmd == "info":
464
+ print(f"""
465
+ 🖥️ 系统信息:
466
+ 系统: {platform.system()} {platform.release()} {platform.machine()}
467
+ 主机: {platform.node()}
468
+ 处理器: {platform.processor()}
469
+ Python: {platform.python_version()}
470
+ macOS: {platform.mac_ver()[0]}
471
+ """)
472
+
473
+ elif cmd == "bench":
474
+ if check():
475
+ import requests
476
+ r = requests.get(f"{URL}/api/benchmark/full")
477
+ print(json.dumps(r.json(), indent=2))
478
+ else:
479
+ print("❌ 服务未运行,请先 devtools start")
480
+ print("💡 或直接运行: devtools cpu")
481
+
482
+ elif cmd == "clean":
483
+ print("🧹 清理缓存...")
484
+ dirs = [
485
+ '~/Library/Caches/com.apple.nsurlsessiond',
486
+ '~/.cache',
487
+ ]
488
+ cleaned = 0
489
+ for d in dirs:
490
+ path = os.path.expanduser(d)
491
+ if os.path.exists(path):
492
+ size = sum(os.path.getsize(os.path.join(r, f)) for r, _, fs in os.walk(path) for f in fs)
493
+ cleaned += size
494
+ print(f" 清理: {d} ({size/1024**2:.1f}MB)")
495
+ print(f"✅ 可释放: {cleaned/1024**2:.1f}MB(手动清理更彻底)")
496
+ print("💡 提示: 使用 'sudo periodic daily weekly monthly' 清理系统缓存")
497
+
498
+ elif cmd == "update":
499
+ print("🔄 检查更新...")
500
+ try:
501
+ latest = urllib.request.urlopen('https://pypi.org/pypi/devtools-hub/json', timeout=5)
502
+ data = json.loads(latest.read())
503
+ version = data['info']['version']
504
+ print(f"PyPI 最新版本: {version}")
505
+ if version != '2.7.0':
506
+ print(f"📦 可更新,运行: pip install --upgrade devtools-hub")
507
+ else:
508
+ print("✅ 已是最新版本")
509
+ except Exception as e:
510
+ print(f"❌ 检查失败: {e}")
511
+
512
+ elif cmd == "start":
513
+ print("🚀 启动服务...")
514
+ subprocess.Popen([sys.executable, "-m", "devtools_hub.server"],
515
+ stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
516
+ time.sleep(2)
517
+ print(f"✅ 已启动: {URL}")
518
+
519
+ elif cmd == "stop":
520
+ subprocess.run(["pkill", "-f", "devtools_hub.server"])
521
+ print("✅ 已停止")
522
+
523
+ else:
524
+ print(f"❌ 未知命令: {cmd}")
525
+
526
+ if __name__ == "__main__":
527
+ main()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devtools-hub
3
- Version: 2.6.0
3
+ Version: 2.7.0
4
4
  Home-page: https://github.com/jingjing737/devtools-hub
5
5
  Author: jingjing737
6
6
  Requires-Python: >=3.7
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "devtools-hub"
7
- version = "2.6.0"
7
+ version = "2.7.0"
8
8
  dependencies = ["flask", "psutil", "requests"]
9
9
  requires-python = ">=3.7"
10
10
 
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="devtools-hub",
5
- version="2.5.0",
5
+ version="2.7.0",
6
6
  packages=find_packages(),
7
7
  install_requires=["flask", "psutil", "requests"],
8
8
  entry_points={
@@ -1,150 +0,0 @@
1
- #!/usr/bin/env python3
2
- """DevTools Hub CLI"""
3
- import sys
4
- import subprocess
5
- import json
6
- import time
7
- import platform
8
-
9
- PORT = 5001
10
- URL = f"http://localhost:{PORT}"
11
-
12
- def check():
13
- try:
14
- import requests
15
- r = requests.get(f"{URL}/api/health", timeout=1)
16
- return r.ok
17
- except:
18
- return False
19
-
20
- def main():
21
- if len(sys.argv) < 2:
22
- print("""
23
- 🔧 DevTools Hub - 开发者工具集
24
-
25
- 用法: devtools <命令>
26
-
27
- 命令:
28
- start 启动服务
29
- stop 停止服务
30
- status 系统状态
31
- cpu CPU 信息
32
- mem 内存信息
33
- disk 磁盘信息
34
- net 网络速度
35
- top 高占用进程
36
- ports 端口扫描
37
- services 系统服务
38
- info 系统信息
39
- ip IP 地址
40
- bench 性能测试
41
- """)
42
- return
43
-
44
- cmd = sys.argv[1]
45
-
46
- if cmd == "start":
47
- print("🚀 启动服务...")
48
- subprocess.Popen([sys.executable, "-m", "devtools_hub.server"],
49
- stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
50
- time.sleep(2)
51
- print(f"✅ 已启动: {URL}")
52
-
53
- elif cmd == "stop":
54
- subprocess.run(["pkill", "-f", "devtools_hub.server"])
55
- print("✅ 已停止")
56
-
57
- elif cmd == "status":
58
- if check():
59
- import requests
60
- r = requests.get(f"{URL}/api/health")
61
- print(json.dumps(r.json(), indent=2))
62
- else:
63
- print("❌ 服务未运行,请先 devtools start")
64
-
65
- elif cmd == "cpu":
66
- import psutil
67
- print(f"CPU: {psutil.cpu_percent()}% 核心: {psutil.cpu_count()}")
68
-
69
- elif cmd == "mem":
70
- import psutil
71
- m = psutil.virtual_memory()
72
- print(f"内存: {m.percent}% 可用: {m.available/1024**3:.1f}GB")
73
-
74
- elif cmd == "disk":
75
- import psutil
76
- d = psutil.disk_usage('/')
77
- print(f"磁盘: {d.percent}% 可用: {d.free/1024**3:.1f}GB")
78
-
79
- elif cmd == "net":
80
- if check():
81
- import requests
82
- r = requests.get(f"{URL}/api/network/bandwidth")
83
- d = r.json()
84
- print(f"↑{d.get('upload_mbps', 0)} Mbps ↓{d.get('download_mbps', 0)} Mbps")
85
- else:
86
- print("❌ 服务未运行")
87
-
88
- elif cmd == "top":
89
- import psutil
90
- procs = []
91
- for p in psutil.process_iter(['name', 'cpu_percent', 'memory_percent']):
92
- try:
93
- procs.append(p.info)
94
- except:
95
- pass
96
- by_cpu = sorted(procs, key=lambda x: x['cpu_percent'] or 0, reverse=True)[:5]
97
- by_mem = sorted(procs, key=lambda x: x['memory_percent'] or 0, reverse=True)[:5]
98
- print("🔥 CPU:")
99
- for p in by_cpu:
100
- print(f" {p['name']}: {p['cpu_percent']}%")
101
- print("💾 内存:")
102
- for p in by_mem:
103
- print(f" {p['name']}: {p['memory_percent']}%")
104
-
105
- elif cmd == "ports":
106
- from devtools_hub.scanner import scan_common_ports
107
- print("🔍 扫描常用端口...")
108
- ports = scan_common_ports()
109
- if ports:
110
- for p in ports:
111
- print(f" ✅ {p['port']} ({p['name']}) - 开放")
112
- else:
113
- print(" 未发现开放端口")
114
-
115
- elif cmd == "services":
116
- from devtools_hub.scanner import get_services
117
- print("📋 系统服务:")
118
- services = get_services()
119
- for s in services[:10]:
120
- print(f" [{s['pid']}] {s['name']}")
121
-
122
- elif cmd == "info":
123
- print(f"""
124
- 系统信息:
125
- 系统: {platform.system()} {platform.release()}
126
- 主机: {platform.node()}
127
- 处理器: {platform.processor()}
128
- Python: {platform.python_version()}
129
- """)
130
-
131
- elif cmd == "ip":
132
- import socket
133
- hostname = socket.gethostname()
134
- ip = socket.gethostbyname(hostname)
135
- print(f"主机: {hostname}")
136
- print(f"IP: {ip}")
137
-
138
- elif cmd == "bench":
139
- if check():
140
- import requests
141
- r = requests.get(f"{URL}/api/benchmark/full")
142
- print(json.dumps(r.json(), indent=2))
143
- else:
144
- print("❌ 服务未运行")
145
-
146
- else:
147
- print(f"❌ 未知命令: {cmd}")
148
-
149
- if __name__ == "__main__":
150
- main()
File without changes