devtools-hub 2.6.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.
- devtools_hub/__init__.py +1 -0
- devtools_hub/cli.py +150 -0
- devtools_hub/scanner.py +56 -0
- devtools_hub/server.py +41 -0
- devtools_hub-2.6.0.dist-info/METADATA +11 -0
- devtools_hub-2.6.0.dist-info/RECORD +9 -0
- devtools_hub-2.6.0.dist-info/WHEEL +5 -0
- devtools_hub-2.6.0.dist-info/entry_points.txt +2 -0
- devtools_hub-2.6.0.dist-info/top_level.txt +1 -0
devtools_hub/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2.5.0"
|
devtools_hub/cli.py
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
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()
|
devtools_hub/scanner.py
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""端口和服务扫描"""
|
|
2
|
+
import socket
|
|
3
|
+
import subprocess
|
|
4
|
+
|
|
5
|
+
def scan_port(host, port, timeout=1):
|
|
6
|
+
"""扫描单个端口"""
|
|
7
|
+
try:
|
|
8
|
+
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
9
|
+
s.settimeout(timeout)
|
|
10
|
+
result = s.connect_ex((host, port))
|
|
11
|
+
s.close()
|
|
12
|
+
return result == 0
|
|
13
|
+
except:
|
|
14
|
+
return False
|
|
15
|
+
|
|
16
|
+
def scan_common_ports(host="localhost"):
|
|
17
|
+
"""扫描常用端口"""
|
|
18
|
+
common_ports = {
|
|
19
|
+
22: "SSH",
|
|
20
|
+
80: "HTTP",
|
|
21
|
+
443: "HTTPS",
|
|
22
|
+
3000: "Node.js",
|
|
23
|
+
5000: "Flask",
|
|
24
|
+
5001: "DevTools",
|
|
25
|
+
5432: "PostgreSQL",
|
|
26
|
+
6379: "Redis",
|
|
27
|
+
8080: "Tomcat",
|
|
28
|
+
8443: "HTTPS Alt",
|
|
29
|
+
9000: "PHP-FPM",
|
|
30
|
+
27017: "MongoDB"
|
|
31
|
+
}
|
|
32
|
+
results = []
|
|
33
|
+
for port, name in common_ports.items():
|
|
34
|
+
if scan_port(host, port):
|
|
35
|
+
results.append({"port": port, "name": name, "status": "open"})
|
|
36
|
+
return results
|
|
37
|
+
|
|
38
|
+
def get_services():
|
|
39
|
+
"""获取运行中的服务"""
|
|
40
|
+
try:
|
|
41
|
+
result = subprocess.run(
|
|
42
|
+
["launchctl", "list"],
|
|
43
|
+
capture_output=True, text=True
|
|
44
|
+
)
|
|
45
|
+
services = []
|
|
46
|
+
for line in result.stdout.split("\n")[1:20]:
|
|
47
|
+
parts = line.split()
|
|
48
|
+
if len(parts) >= 3:
|
|
49
|
+
services.append({
|
|
50
|
+
"pid": parts[0],
|
|
51
|
+
"status": parts[1],
|
|
52
|
+
"name": parts[2]
|
|
53
|
+
})
|
|
54
|
+
return services
|
|
55
|
+
except:
|
|
56
|
+
return []
|
devtools_hub/server.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""DevTools Hub Server"""
|
|
2
|
+
from flask import Flask, jsonify
|
|
3
|
+
import psutil
|
|
4
|
+
import platform
|
|
5
|
+
|
|
6
|
+
app = Flask(__name__)
|
|
7
|
+
|
|
8
|
+
@app.route("/api/health")
|
|
9
|
+
def health():
|
|
10
|
+
return jsonify({"status": "healthy"})
|
|
11
|
+
|
|
12
|
+
@app.route("/api/system")
|
|
13
|
+
def system():
|
|
14
|
+
return jsonify({
|
|
15
|
+
"cpu_percent": psutil.cpu_percent(),
|
|
16
|
+
"memory_percent": psutil.virtual_memory().percent,
|
|
17
|
+
"cpu_count": psutil.cpu_count()
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
@app.route("/api/processes/top")
|
|
21
|
+
def processes_top():
|
|
22
|
+
procs = []
|
|
23
|
+
for p in psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_percent']):
|
|
24
|
+
try:
|
|
25
|
+
procs.append(p.info)
|
|
26
|
+
except:
|
|
27
|
+
pass
|
|
28
|
+
by_cpu = sorted(procs, key=lambda x: x['cpu_percent'] or 0, reverse=True)[:10]
|
|
29
|
+
by_mem = sorted(procs, key=lambda x: x['memory_percent'] or 0, reverse=True)[:10]
|
|
30
|
+
return jsonify({"by_cpu": by_cpu, "by_memory": by_mem})
|
|
31
|
+
|
|
32
|
+
@app.route("/api/network/bandwidth")
|
|
33
|
+
def network():
|
|
34
|
+
return jsonify({"upload_mbps": 0, "download_mbps": 0})
|
|
35
|
+
|
|
36
|
+
@app.route("/api/benchmark/full")
|
|
37
|
+
def benchmark():
|
|
38
|
+
return jsonify({"cpu_score": 100, "total_score": 100})
|
|
39
|
+
|
|
40
|
+
if __name__ == "__main__":
|
|
41
|
+
app.run(port=5001)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: devtools-hub
|
|
3
|
+
Version: 2.6.0
|
|
4
|
+
Home-page: https://github.com/jingjing737/devtools-hub
|
|
5
|
+
Author: jingjing737
|
|
6
|
+
Requires-Python: >=3.7
|
|
7
|
+
Requires-Dist: flask
|
|
8
|
+
Requires-Dist: psutil
|
|
9
|
+
Requires-Dist: requests
|
|
10
|
+
Dynamic: author
|
|
11
|
+
Dynamic: home-page
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
devtools_hub/__init__.py,sha256=fMbNgIJqxiZEaSBLadLBt4rZpCHqarzb4Okt-aWsp2E,22
|
|
2
|
+
devtools_hub/cli.py,sha256=sN76JIHZgIDlRdtVfpXJ94QvOQgJwv26pjCW0LHwv-I,4151
|
|
3
|
+
devtools_hub/scanner.py,sha256=O4VgB8BTN-wfg0IBNnGSCK48hBNJcZREPHIiY0NNLUU,1472
|
|
4
|
+
devtools_hub/server.py,sha256=LtUvGZjc4jPsGJzfOclJcAzaJNC3f2glv_DYtNwuiU4,1144
|
|
5
|
+
devtools_hub-2.6.0.dist-info/METADATA,sha256=UuEN_EI2SpehfKwqC1FsE7pvBtXP5FLbwsI5s6MwsUw,256
|
|
6
|
+
devtools_hub-2.6.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
7
|
+
devtools_hub-2.6.0.dist-info/entry_points.txt,sha256=fgsOWcmrO0LkMFuBRpaKG5LPeWub8prKpKzL4LhVPI8,51
|
|
8
|
+
devtools_hub-2.6.0.dist-info/top_level.txt,sha256=YIFEk_9ohNME6dUPySvQd0PG52ePtWMR3CsvWZJnm2Q,13
|
|
9
|
+
devtools_hub-2.6.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
devtools_hub
|