THEZYZSTUDIO commited on
Commit
bcd04ea
·
verified ·
1 Parent(s): a52c9b3

Delete app.py

Browse files
Files changed (1) hide show
  1. app.py +0 -413
app.py DELETED
@@ -1,413 +0,0 @@
1
- """
2
- ╔══════════════════════════════════════════════════════════════╗
3
- ║ LINUX SYSTEM SERVER — by BU THE ZYZ STUDIO ║
4
- ║ 🖥️ سيرفر نظام لينكس — يُتحكم فيه عبر السيرفر الأول ║
5
- ╚══════════════════════════════════════════════════════════════╝
6
-
7
- هذا الملف خاص بـ: سيرفر 2 (سيرفر نظام Linux)
8
- This file belongs to: SERVER 2 (Linux System Server)
9
- """
10
-
11
- import os
12
- import subprocess
13
- import json
14
- import threading
15
- import time
16
- import shutil
17
- import signal
18
- from pathlib import Path
19
- from flask import Flask, request, jsonify, Response, stream_with_context
20
- from flask_cors import CORS
21
-
22
- app = Flask(__name__)
23
- CORS(app, resources={r"/api/*": {"origins": "*"}})
24
-
25
- # ══════════════════════════════════════════
26
- # 🔐 Security Token — رمز الأمان
27
- # Set as environment variable: LINUX_API_TOKEN
28
- # عيّن هذا المتغير في إعدادات Hugging Face Space
29
- # ══════════════════════════════════════════
30
- API_TOKEN = os.environ.get("LINUX_API_TOKEN", "zyz-linux-secret-2025")
31
-
32
- # ══════════════════════════════════════════
33
- # 📁 Workspace Directory
34
- # ══════════════════════════════════════════
35
- WORKSPACE = "/workspace"
36
- os.makedirs(WORKSPACE, exist_ok=True)
37
-
38
- # Active processes store (for killing long-running processes)
39
- active_processes = {}
40
- process_lock = threading.Lock()
41
-
42
-
43
- # ══════════════════════════════════════════
44
- # 🔒 Auth Helper
45
- # ══════════════════════════════════════════
46
- def verify_token(req) -> bool:
47
- """التحقق من رمز الأمان في الطلب"""
48
- # Check header first
49
- token_header = req.headers.get("X-API-Token", "")
50
- if token_header == API_TOKEN:
51
- return True
52
- # Check JSON body
53
- if req.is_json:
54
- body = req.get_json(silent=True) or {}
55
- if body.get("token", "") == API_TOKEN:
56
- return True
57
- return False
58
-
59
-
60
- # ══════════════════════════════════════════
61
- # ✅ Status Endpoint
62
- # ══════════════════════════════════════════
63
- @app.route("/")
64
- def root():
65
- return jsonify({
66
- "name": "Linux System Server",
67
- "version": "1.0.0",
68
- "by": "BU THE ZYZ STUDIO",
69
- "status": "online",
70
- "note": "Use /api/status with your token to verify authentication."
71
- })
72
-
73
-
74
- @app.route("/api/status")
75
- def status():
76
- """حالة السيرفر — يعمل بدون توثيق للتحقق من الاتصال"""
77
- try:
78
- uname = subprocess.run("uname -a", shell=True, capture_output=True, text=True, timeout=5)
79
- disk = subprocess.run("df -h /workspace 2>/dev/null || df -h /", shell=True, capture_output=True, text=True, timeout=5)
80
- mem = subprocess.run("free -h", shell=True, capture_output=True, text=True, timeout=5)
81
- python = subprocess.run("python3 --version", shell=True, capture_output=True, text=True, timeout=5)
82
- except Exception:
83
- uname = disk = mem = python = type("R", (), {"stdout": "N/A", "stderr": ""})()
84
-
85
- authenticated = verify_token(request)
86
- return jsonify({
87
- "status": "online",
88
- "authenticated": authenticated,
89
- "system": uname.stdout.strip(),
90
- "disk": disk.stdout.strip(),
91
- "memory": mem.stdout.strip(),
92
- "python": python.stdout.strip(),
93
- "workspace": WORKSPACE,
94
- "timestamp": time.time()
95
- })
96
-
97
-
98
- # ══════════════════════════════════════════
99
- # ⚡ Execute Command — تنفيذ أوامر الترمينال
100
- # ══════════════════════════════════════════
101
- @app.route("/api/execute", methods=["POST"])
102
- def execute_command():
103
- """
104
- تنفيذ أمر ترمينال واحد والحصول على النتيجة كاملة
105
- Execute a single terminal command and get full output
106
- """
107
- if not verify_token(request):
108
- return jsonify({"error": "Unauthorized — Invalid or missing API token"}), 401
109
-
110
- data = request.get_json(silent=True) or {}
111
- command = data.get("command", "").strip()
112
- cwd = data.get("cwd", WORKSPACE)
113
- timeout = min(int(data.get("timeout", 30)), 300) # max 5 minutes
114
-
115
- if not command:
116
- return jsonify({"error": "No command provided"}), 400
117
-
118
- # Validate working directory
119
- if not os.path.exists(cwd):
120
- cwd = WORKSPACE
121
-
122
- try:
123
- result = subprocess.run(
124
- command,
125
- shell=True,
126
- capture_output=True,
127
- text=True,
128
- cwd=cwd,
129
- timeout=timeout,
130
- env={**os.environ, "HOME": "/root", "TERM": "xterm-256color"}
131
- )
132
- return jsonify({
133
- "success": True,
134
- "stdout": result.stdout,
135
- "stderr": result.stderr,
136
- "returncode": result.returncode,
137
- "command": command,
138
- "cwd": cwd
139
- })
140
- except subprocess.TimeoutExpired:
141
- return jsonify({
142
- "success": False,
143
- "error": f"Command timed out after {timeout} seconds",
144
- "returncode": -1
145
- }), 408
146
- except Exception as e:
147
- return jsonify({
148
- "success": False,
149
- "error": str(e),
150
- "returncode": -1
151
- }), 500
152
-
153
-
154
- # ══════════════════════════════════════════
155
- # 📡 Stream Execute — تنفيذ مع بث النتائج
156
- # ══════════════════════════════════════════
157
- @app.route("/api/stream", methods=["POST"])
158
- def stream_execute():
159
- """
160
- تنفيذ أمر مع بث المخرجات سطراً بسطر (مفيد للأوامر الطويلة)
161
- Stream command output line by line (useful for long-running commands)
162
- """
163
- if not verify_token(request):
164
- return jsonify({"error": "Unauthorized"}), 401
165
-
166
- data = request.get_json(silent=True) or {}
167
- command = data.get("command", "").strip()
168
- cwd = data.get("cwd", WORKSPACE)
169
- pid_key = data.get("pid_key", f"proc_{int(time.time())}")
170
-
171
- if not command:
172
- return jsonify({"error": "No command provided"}), 400
173
-
174
- if not os.path.exists(cwd):
175
- cwd = WORKSPACE
176
-
177
- @stream_with_context
178
- def generate():
179
- try:
180
- process = subprocess.Popen(
181
- command,
182
- shell=True,
183
- stdout=subprocess.PIPE,
184
- stderr=subprocess.STDOUT,
185
- text=True,
186
- cwd=cwd,
187
- env={**os.environ, "HOME": "/root", "TERM": "xterm-256color"},
188
- bufsize=1
189
- )
190
- with process_lock:
191
- active_processes[pid_key] = process
192
-
193
- yield f"data: {json.dumps({'type': 'start', 'pid': process.pid, 'command': command})}\n\n"
194
-
195
- for line in iter(process.stdout.readline, ""):
196
- yield f"data: {json.dumps({'type': 'output', 'line': line})}\n\n"
197
-
198
- process.wait()
199
- with process_lock:
200
- active_processes.pop(pid_key, None)
201
-
202
- yield f"data: {json.dumps({'type': 'done', 'returncode': process.returncode})}\n\n"
203
- yield "data: [DONE]\n\n"
204
-
205
- except Exception as e:
206
- yield f"data: {json.dumps({'type': 'error', 'message': str(e)})}\n\n"
207
-
208
- return Response(
209
- generate(),
210
- mimetype="text/event-stream",
211
- headers={"Cache-Control": "no-cache", "X-Accel-Buffering": "no"}
212
- )
213
-
214
-
215
- # ══════════════════════════════════════════
216
- # 🛑 Kill Process — إيقاف عملية جارية
217
- # ══════════════════════════════════════════
218
- @app.route("/api/kill", methods=["POST"])
219
- def kill_process():
220
- if not verify_token(request):
221
- return jsonify({"error": "Unauthorized"}), 401
222
- data = request.get_json(silent=True) or {}
223
- pid_key = data.get("pid_key", "")
224
- with process_lock:
225
- proc = active_processes.get(pid_key)
226
- if proc:
227
- try:
228
- proc.terminate()
229
- time.sleep(0.5)
230
- if proc.poll() is None:
231
- proc.kill()
232
- return jsonify({"success": True, "message": "Process terminated"})
233
- except Exception as e:
234
- return jsonify({"error": str(e)}), 500
235
- return jsonify({"error": "Process not found"}), 404
236
-
237
-
238
- # ══════════════════════════════════════════
239
- # 📁 File System Operations
240
- # ══════════════════════════════════════════
241
- @app.route("/api/files/list", methods=["GET", "POST"])
242
- def list_files():
243
- """قائمة الملفات في مسار معين"""
244
- if not verify_token(request):
245
- return jsonify({"error": "Unauthorized"}), 401
246
-
247
- if request.method == "POST":
248
- data = request.get_json(silent=True) or {}
249
- path = data.get("path", WORKSPACE)
250
- else:
251
- path = request.args.get("path", WORKSPACE)
252
-
253
- try:
254
- items = []
255
- for name in sorted(os.listdir(path)):
256
- full = os.path.join(path, name)
257
- try:
258
- stat = os.stat(full)
259
- items.append({
260
- "name": name,
261
- "path": full,
262
- "is_dir": os.path.isdir(full),
263
- "size": stat.st_size,
264
- "modified": stat.st_mtime
265
- })
266
- except Exception:
267
- pass
268
- return jsonify({"success": True, "path": path, "items": items})
269
- except Exception as e:
270
- return jsonify({"error": str(e)}), 500
271
-
272
-
273
- @app.route("/api/files/read", methods=["POST"])
274
- def read_file():
275
- """قراءة محتوى ملف"""
276
- if not verify_token(request):
277
- return jsonify({"error": "Unauthorized"}), 401
278
- data = request.get_json(silent=True) or {}
279
- path = data.get("path", "").strip()
280
- if not path:
281
- return jsonify({"error": "No path provided"}), 400
282
- try:
283
- with open(path, "r", encoding="utf-8", errors="replace") as f:
284
- content = f.read()
285
- return jsonify({"success": True, "path": path, "content": content, "size": len(content)})
286
- except Exception as e:
287
- return jsonify({"error": str(e)}), 500
288
-
289
-
290
- @app.route("/api/files/write", methods=["POST"])
291
- def write_file():
292
- """كتابة محتوى إلى ملف"""
293
- if not verify_token(request):
294
- return jsonify({"error": "Unauthorized"}), 401
295
- data = request.get_json(silent=True) or {}
296
- path = data.get("path", "").strip()
297
- content = data.get("content", "")
298
- if not path:
299
- return jsonify({"error": "No path provided"}), 400
300
- try:
301
- dir_ = os.path.dirname(path)
302
- if dir_:
303
- os.makedirs(dir_, exist_ok=True)
304
- with open(path, "w", encoding="utf-8") as f:
305
- f.write(content)
306
- return jsonify({"success": True, "path": path, "bytes_written": len(content.encode())})
307
- except Exception as e:
308
- return jsonify({"error": str(e)}), 500
309
-
310
-
311
- @app.route("/api/files/delete", methods=["POST"])
312
- def delete_file():
313
- """حذف ملف أو مجلد"""
314
- if not verify_token(request):
315
- return jsonify({"error": "Unauthorized"}), 401
316
- data = request.get_json(silent=True) or {}
317
- path = data.get("path", "").strip()
318
- if not path:
319
- return jsonify({"error": "No path provided"}), 400
320
- try:
321
- if os.path.isdir(path):
322
- shutil.rmtree(path)
323
- else:
324
- os.remove(path)
325
- return jsonify({"success": True, "deleted": path})
326
- except Exception as e:
327
- return jsonify({"error": str(e)}), 500
328
-
329
-
330
- @app.route("/api/files/mkdir", methods=["POST"])
331
- def make_dir():
332
- """إنشاء مجلد جديد"""
333
- if not verify_token(request):
334
- return jsonify({"error": "Unauthorized"}), 401
335
- data = request.get_json(silent=True) or {}
336
- path = data.get("path", "").strip()
337
- try:
338
- os.makedirs(path, exist_ok=True)
339
- return jsonify({"success": True, "created": path})
340
- except Exception as e:
341
- return jsonify({"error": str(e)}), 500
342
-
343
-
344
- # ══════════════════════════════════════════
345
- # 📦 Package Manager — إدارة الحزم
346
- # ══════════════════════════════════════════
347
- @app.route("/api/packages/install", methods=["POST"])
348
- def install_package():
349
- """تثبيت حزمة Python أو apt"""
350
- if not verify_token(request):
351
- return jsonify({"error": "Unauthorized"}), 401
352
- data = request.get_json(silent=True) or {}
353
- package = data.get("package", "").strip()
354
- manager = data.get("manager", "pip") # "pip" or "apt"
355
- if not package:
356
- return jsonify({"error": "No package name"}), 400
357
- try:
358
- if manager == "apt":
359
- cmd = f"apt-get install -y {package}"
360
- else:
361
- cmd = f"pip install {package}"
362
- result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=120)
363
- return jsonify({
364
- "success": result.returncode == 0,
365
- "stdout": result.stdout,
366
- "stderr": result.stderr
367
- })
368
- except subprocess.TimeoutExpired:
369
- return jsonify({"error": "Installation timed out"}), 408
370
- except Exception as e:
371
- return jsonify({"error": str(e)}), 500
372
-
373
-
374
- # ══════════════════════════════════════════
375
- # 🔧 System Info — معلومات النظام
376
- # ══════════════════════════════════════════
377
- @app.route("/api/sysinfo", methods=["GET", "POST"])
378
- def sysinfo():
379
- """معلومات تفصيلية عن النظام"""
380
- if not verify_token(request):
381
- return jsonify({"error": "Unauthorized"}), 401
382
-
383
- commands = {
384
- "os": "cat /etc/os-release 2>/dev/null | head -5",
385
- "cpu": "lscpu 2>/dev/null | grep -E 'Architecture|CPU\\(s\\)|Model name' | head -5",
386
- "memory": "free -h",
387
- "disk": "df -h",
388
- "network": "ip addr show 2>/dev/null | grep 'inet ' | head -5",
389
- "python": "python3 --version && pip3 list 2>/dev/null | head -20",
390
- "processes":"ps aux --sort=-%cpu 2>/dev/null | head -10",
391
- "uptime": "uptime"
392
- }
393
- info = {}
394
- for key, cmd in commands.items():
395
- try:
396
- r = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=10)
397
- info[key] = r.stdout.strip()
398
- except Exception:
399
- info[key] = "N/A"
400
-
401
- return jsonify({"success": True, "info": info})
402
-
403
-
404
- # ══════════════════════════════════════════
405
- # 🚀 Run — تشغيل السيرفر
406
- # ══════════════════════════════════════════
407
- if __name__ == "__main__":
408
- print("=" * 60)
409
- print(" 🖥️ Linux System Server — BU THE ZYZ STUDIO")
410
- print(" Port: 7860")
411
- print(" Token: Set LINUX_API_TOKEN env variable")
412
- print("=" * 60)
413
- app.run(host="0.0.0.0", port=7860, debug=False, threaded=True)