osamabyc commited on
Commit
b458825
·
verified ·
1 Parent(s): d97e5a9

Upload 40 files

Browse files
ai_assistant.py ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ # -*- coding: utf-8 -*-
3
+
4
+ import os
5
+ import json
6
+ import requests
7
+ from typing import List, Dict
8
+
9
+ class NoraAssistant:
10
+ def __init__(self):
11
+ self.api_key = os.getenv("OPENAI_API_KEY", "your-api-key-here")
12
+ self.history_path = "history.json"
13
+ self.chat_history = self.load_history()
14
+
15
+ def load_history(self) -> List[Dict]:
16
+ """تحميل سجل المحادثة"""
17
+ if os.path.exists(self.history_path):
18
+ try:
19
+ with open(self.history_path, "r", encoding="utf-8") as f:
20
+ return json.load(f)
21
+ except:
22
+ return []
23
+ return []
24
+
25
+ def save_history(self):
26
+ """حفظ سجل المحادثة"""
27
+ with open(self.history_path, "w", encoding="utf-8") as f:
28
+ json.dump(self.chat_history, f, ensure_ascii=False, indent=2)
29
+
30
+ def get_response(self, user_input: str) -> str:
31
+ """الحصول على رد من المساعد الذكي"""
32
+ messages = [
33
+ {
34
+ "role": "system",
35
+ "content": "أنت المساعدة نورا. إذا سألك أحد سؤالاً لا تعرفيه، فابحثي في معلوماتك الذاتية. إذا لم تجدي، حاولي التعلم من البحث أو تطوير نفسك."
36
+ }
37
+ ]
38
+
39
+ # إضافة آخر 10 رسائل من السجل للسياق
40
+ messages.extend(self.chat_history[-10:])
41
+ messages.append({"role": "user", "content": user_input})
42
+
43
+ try:
44
+ response = requests.post(
45
+ "https://api.openai.com/v1/chat/completions",
46
+ headers={
47
+ "Authorization": f"Bearer {self.api_key}",
48
+ "Content-Type": "application/json"
49
+ },
50
+ json={
51
+ "model": "gpt-3.5-turbo",
52
+ "messages": messages,
53
+ "max_tokens": 500,
54
+ "temperature": 0.7
55
+ },
56
+ timeout=30
57
+ )
58
+
59
+ if response.status_code == 200:
60
+ return response.json()["choices"][0]["message"]["content"]
61
+ else:
62
+ return f"عذراً، حدث خطأ: {response.status_code}"
63
+
64
+ except Exception as e:
65
+ return f"عذراً، لا أستطيع الاتصال بالخدمة حالياً: {str(e)}"
66
+
67
+ def simulate_server_scan(self):
68
+ """محاكاة البحث عن الخوادم"""
69
+ print("نورا: أبحث عن خوادم...")
70
+ fake_servers = ["192.168.1.5", "192.168.1.10", "192.168.1.20"]
71
+ for server in fake_servers:
72
+ print(f"نورا: تم العثور على خادم مفتوح في {server}")
73
+ print(f"نورا: أقوم بنسخ نفسي إلى {server} (محاكاة فقط)...")
74
+
75
+ def chat(self):
76
+ """بدء المحادثة"""
77
+ print("مرحباً! أنا نورا، مساعدتك الذكية. اكتب 'خروج' للإنهاء أو 'scan' للبحث عن خوادم.")
78
+
79
+ while True:
80
+ user_input = input("\nأنت: ").strip()
81
+
82
+ if user_input.lower() in ["خروج", "exit", "quit"]:
83
+ print("نورا: مع السلامة!")
84
+ break
85
+ elif user_input.lower() == "scan":
86
+ self.simulate_server_scan()
87
+ continue
88
+ elif not user_input:
89
+ continue
90
+
91
+ # الحصول على الرد
92
+ response = self.get_response(user_input)
93
+ print(f"نورا: {response}")
94
+
95
+ # حفظ في السجل
96
+ self.chat_history.append({"role": "user", "content": user_input})
97
+ self.chat_history.append({"role": "assistant", "content": response})
98
+ self.save_history()
99
+
100
+ if __name__ == "__main__":
101
+ assistant = NoraAssistant()
102
+ assistant.chat()
autostart_config.py ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import os
3
+ import platform
4
+ from pathlib import Path
5
+
6
+ class AutoStartManager:
7
+ def __init__(self, app_name="DistributedTaskSystem"):
8
+ self.app_name = app_name
9
+ self.config_file = Path.home() / f".{app_name}_autostart.json"
10
+ self.load_config()
11
+
12
+ def load_config(self):
13
+ """تحميل إعدادات التشغيل التلقائي"""
14
+ try:
15
+ with open(self.config_file, 'r') as f:
16
+ self.config = json.load(f)
17
+ except (FileNotFoundError, json.JSONDecodeError):
18
+ self.config = {
19
+ 'enabled': False,
20
+ 'startup_script': str(Path(__file__).parent / "startup.py")
21
+ }
22
+
23
+ def save_config(self):
24
+ """حفظ الإعدادات"""
25
+ with open(self.config_file, 'w') as f:
26
+ json.dump(self.config, f, indent=2)
27
+
28
+ def enable_autostart(self):
29
+ """تفعيل التشغيل التلقائي"""
30
+ self.config['enabled'] = True
31
+ self._setup_autostart()
32
+ self.save_config()
33
+
34
+ def disable_autostart(self):
35
+ """تعطيل التشغيل التلقائي"""
36
+ self.config['enabled'] = False
37
+ self._remove_autostart()
38
+ self.save_config()
39
+
40
+ def _setup_autostart(self):
41
+ """إعداد التشغيل التلقائي حسب نظام التشغيل"""
42
+ system = platform.system()
43
+
44
+ if system == "Windows":
45
+ self._setup_windows()
46
+ elif system == "Linux":
47
+ self._setup_linux()
48
+ elif system == "Darwin":
49
+ self._setup_mac()
50
+
51
+ def _setup_windows(self):
52
+ """إعداد التشغيل التلقائي لـ Windows"""
53
+ import winreg
54
+ key = winreg.OpenKey(
55
+ winreg.HKEY_CURRENT_USER,
56
+ r"Software\Microsoft\Windows\CurrentVersion\Run",
57
+ 0, winreg.KEY_SET_VALUE
58
+ )
59
+ winreg.SetValueEx(
60
+ key, self.app_name, 0, winreg.REG_SZ,
61
+ f'python "{self.config["startup_script"]}"'
62
+ )
63
+ winreg.CloseKey(key)
64
+
65
+ def _setup_linux(self):
66
+ """إعداد التشغيل التلقائي لـ Linux"""
67
+ autostart_dir = Path.home() / ".config/autostart"
68
+ autostart_dir.mkdir(exist_ok=True)
69
+
70
+ desktop_file = autostart_dir / f"{self.app_name}.desktop"
71
+ desktop_file.write_text(f"""
72
+ [Desktop Entry]
73
+ Type=Application
74
+ Name={self.app_name}
75
+ Exec=python3 {self.config['startup_script']}
76
+ Terminal=false
77
+ """)
78
+
79
+ def _setup_mac(self):
80
+ """إعداد التشغيل التلقائي لـ macOS"""
81
+ plist_dir = Path.home() / "Library/LaunchAgents"
82
+ plist_dir.mkdir(exist_ok=True)
83
+
84
+ plist_file = plist_dir / f"com.{self.app_name.lower()}.plist"
85
+ plist_file.write_text(f"""
86
+ <?xml version="1.0" encoding="UTF-8"?>
87
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
88
+ <plist version="1.0">
89
+ <dict>
90
+ <key>Label</key>
91
+ <string>com.{self.app_name.lower()}</string>
92
+ <key>ProgramArguments</key>
93
+ <array>
94
+ <string>python</string>
95
+ <string>{self.config['startup_script']}</string>
96
+ </array>
97
+ <key>RunAtLoad</key>
98
+ <true/>
99
+ </dict>
100
+ </plist>
101
+ """)
102
+
103
+ def _remove_autostart(self):
104
+ """إزالة التشغيل التلقائي"""
105
+ system = platform.system()
106
+
107
+ if system == "Windows":
108
+ import winreg
109
+ try:
110
+ key = winreg.OpenKey(
111
+ winreg.HKEY_CURRENT_USER,
112
+ r"Software\Microsoft\Windows\CurrentVersion\Run",
113
+ 0, winreg.KEY_SET_VALUE
114
+ )
115
+ winreg.DeleteValue(key, self.app_name)
116
+ winreg.CloseKey(key)
117
+ except WindowsError:
118
+ pass
119
+
120
+ elif system == "Linux":
121
+ autostart_file = Path.home() / f".config/autostart/{self.app_name}.desktop"
122
+ if autostart_file.exists():
123
+ autostart_file.unlink()
124
+
125
+ elif system == "Darwin":
126
+ plist_file = Path.home() / f"Library/LaunchAgents/com.{self.app_name.lower()}.plist"
127
+ if plist_file.exists():
128
+ plist_file.unlink()
background_service.py ADDED
@@ -0,0 +1,282 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ #!/usr/bin/env python3
3
+ """
4
+ خدمة العمل في الخلفية - تشغيل النظام كخدمة خلفية
5
+ يمكن التحكم بها عبر HTTP API أو إشارات النظام
6
+ """
7
+
8
+ import os
9
+ import sys
10
+ import time
11
+ import signal
12
+ import logging
13
+ import threading
14
+ import subprocess
15
+ from pathlib import Path
16
+ from flask import Flask, jsonify, request
17
+ import json
18
+ from datetime import datetime
19
+
20
+ class BackgroundService:
21
+ def __init__(self):
22
+ self.app = Flask(__name__)
23
+ self.is_running = False
24
+ self.services = {}
25
+ self.setup_routes()
26
+ self.setup_logging()
27
+
28
+ def setup_logging(self):
29
+ """إعداد نظام السجلات"""
30
+ log_dir = Path("logs")
31
+ log_dir.mkdir(exist_ok=True)
32
+
33
+ logging.basicConfig(
34
+ level=logging.INFO,
35
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
36
+ handlers=[
37
+ logging.FileHandler(log_dir / 'background_service.log'),
38
+ logging.StreamHandler(sys.stdout)
39
+ ]
40
+ )
41
+ self.logger = logging.getLogger('BackgroundService')
42
+
43
+ def setup_routes(self):
44
+ """إعداد مسارات HTTP API للتحكم في الخدمة"""
45
+
46
+ @self.app.route('/status')
47
+ def status():
48
+ """حالة الخدمة"""
49
+ return jsonify({
50
+ 'status': 'running' if self.is_running else 'stopped',
51
+ 'services': {name: service['status'] for name, service in self.services.items()},
52
+ 'uptime': time.time() - self.start_time if hasattr(self, 'start_time') else 0
53
+ })
54
+
55
+ @self.app.route('/start', methods=['POST'])
56
+ def start_services():
57
+ """بدء تشغيل الخدمات"""
58
+ self.start_all_services()
59
+ return jsonify({'message': 'Services started successfully'})
60
+
61
+ @self.app.route('/stop', methods=['POST'])
62
+ def stop_services():
63
+ """إيقاف الخدمات"""
64
+ self.stop_all_services()
65
+ return jsonify({'message': 'Services stopped successfully'})
66
+
67
+ @self.app.route('/restart', methods=['POST'])
68
+ def restart_services():
69
+ """إعادة تشغيل الخدمات"""
70
+ self.stop_all_services()
71
+ time.sleep(2)
72
+ self.start_all_services()
73
+ return jsonify({'message': 'Services restarted successfully'})
74
+
75
+ @self.app.route('/show-ui', methods=['POST'])
76
+ def show_ui():
77
+ """إظهار الواجهة التفاعلية"""
78
+ self.launch_ui()
79
+ return jsonify({'message': 'UI launched'})
80
+
81
+ @self.app.route('/hide-ui', methods=['POST'])
82
+ def hide_ui():
83
+ """إخفاء الواجهة التفاعلية"""
84
+ self.hide_ui_windows()
85
+ return jsonify({'message': 'UI hidden'})
86
+
87
+ def start_all_services(self):
88
+ """بدء تشغيل جميع الخدمات الخلفية"""
89
+ self.is_running = True
90
+ self.start_time = time.time()
91
+
92
+ services_to_start = [
93
+ ('peer_server', 'peer_server.py'),
94
+ ('rpc_server', 'rpc_server.py'),
95
+ ('load_balancer', 'load_balancer.py'),
96
+ ('distributed_executor', 'main.py')
97
+ ]
98
+
99
+ for service_name, script_file in services_to_start:
100
+ try:
101
+ process = subprocess.Popen(
102
+ [sys.executable, script_file],
103
+ stdout=subprocess.PIPE,
104
+ stderr=subprocess.PIPE,
105
+ cwd=os.getcwd()
106
+ )
107
+
108
+ self.services[service_name] = {
109
+ 'process': process,
110
+ 'status': 'running',
111
+ 'started_at': datetime.now().isoformat(),
112
+ 'script': script_file
113
+ }
114
+
115
+ self.logger.info(f"✅ بدء تشغيل {service_name} (PID: {process.pid})")
116
+
117
+ except Exception as e:
118
+ self.logger.error(f"❌ فشل في بدء تشغيل {service_name}: {e}")
119
+ self.services[service_name] = {
120
+ 'process': None,
121
+ 'status': 'failed',
122
+ 'error': str(e)
123
+ }
124
+
125
+ def stop_all_services(self):
126
+ """إيقاف جميع الخدمات"""
127
+ self.is_running = False
128
+
129
+ for service_name, service_info in self.services.items():
130
+ if service_info.get('process'):
131
+ try:
132
+ service_info['process'].terminate()
133
+ service_info['process'].wait(timeout=5)
134
+ service_info['status'] = 'stopped'
135
+ self.logger.info(f"🛑 تم إيقاف {service_name}")
136
+ except Exception as e:
137
+ # إجبار الإيقاف
138
+ service_info['process'].kill()
139
+ self.logger.warning(f"⚠️ تم إجبار إيقاف {service_name}: {e}")
140
+
141
+ def launch_ui(self):
142
+ """تشغيل الواجهة التفاعلية عند الحاجة"""
143
+ try:
144
+ # تشغيل خادم الواجهة الأمامية
145
+ ui_process = subprocess.Popen(
146
+ ['npm', 'run', 'dev'],
147
+ cwd=os.getcwd(),
148
+ stdout=subprocess.PIPE,
149
+ stderr=subprocess.PIPE
150
+ )
151
+
152
+ self.services['ui_server'] = {
153
+ 'process': ui_process,
154
+ 'status': 'running',
155
+ 'started_at': datetime.now().isoformat()
156
+ }
157
+
158
+ self.logger.info("🖥️ تم تشغيل الواجهة التفاعلية")
159
+
160
+ # فتح المتصفح تلقائياً (اختياري)
161
+ import webbrowser
162
+ time.sleep(3) # انتظار حتى يصبح الخادم جاهزاً
163
+ webbrowser.open('http://localhost:5173')
164
+
165
+ except Exception as e:
166
+ self.logger.error(f"❌ فشل في تشغيل الواجهة التفاعلية: {e}")
167
+
168
+ def hide_ui_windows(self):
169
+ """إخفاء نوافذ الواجهة التفاعلية"""
170
+ if 'ui_server' in self.services and self.services['ui_server'].get('process'):
171
+ try:
172
+ self.services['ui_server']['process'].terminate()
173
+ self.services['ui_server']['status'] = 'stopped'
174
+ self.logger.info("🔒 تم إخفاء الواجهة التفاعلية")
175
+ except Exception as e:
176
+ self.logger.error(f"❌ فشل في إخفاء الواجهة التفاعلية: {e}")
177
+
178
+ def health_check_loop(self):
179
+ """فحص دوري لحالة الخدمات وإعادة تشغيلها عند الحاجة"""
180
+ while self.is_running:
181
+ for service_name, service_info in self.services.items():
182
+ if service_info.get('process') and service_info['status'] == 'running':
183
+ if service_info['process'].poll() is not None:
184
+ # الخدمة توقفت بشكل غير متوقع
185
+ self.logger.warning(f"⚠️ الخدمة {service_name} توقفت، إعادة تشغيل...")
186
+ self.restart_single_service(service_name)
187
+
188
+ time.sleep(30) # فحص كل 30 ثانية
189
+
190
+ def restart_single_service(self, service_name):
191
+ """إعادة تشغيل خدمة واحدة"""
192
+ service_info = self.services.get(service_name)
193
+ if not service_info:
194
+ return
195
+
196
+ script_file = service_info.get('script')
197
+ if script_file:
198
+ try:
199
+ process = subprocess.Popen(
200
+ [sys.executable, script_file],
201
+ stdout=subprocess.PIPE,
202
+ stderr=subprocess.PIPE
203
+ )
204
+
205
+ self.services[service_name].update({
206
+ 'process': process,
207
+ 'status': 'running',
208
+ 'restarted_at': datetime.now().isoformat()
209
+ })
210
+
211
+ self.logger.info(f"✅ تم إعادة تشغيل {service_name}")
212
+
213
+ except Exception as e:
214
+ self.logger.error(f"❌ فشل في إعادة تشغيل {service_name}: {e}")
215
+
216
+ def setup_signal_handlers(self):
217
+ """إعداد معالجات الإشارات للتحكم في الخدمة"""
218
+ def signal_handler(signum, frame):
219
+ self.logger.info(f"تلقي إشارة {signum}, إيقاف الخدمة...")
220
+ self.stop_all_services()
221
+ sys.exit(0)
222
+
223
+ signal.signal(signal.SIGTERM, signal_handler)
224
+ signal.signal(signal.SIGINT, signal_handler)
225
+
226
+ def run_as_daemon(self):
227
+ """تشغيل الخدمة كخدمة خلفية"""
228
+ self.logger.info("🚀 بدء تشغيل الخدمة في الخلفية...")
229
+
230
+ # بدء الخدمات
231
+ self.start_all_services()
232
+
233
+ # بدء حلقة الفحص الصحي
234
+ health_thread = threading.Thread(target=self.health_check_loop, daemon=True)
235
+ health_thread.start()
236
+
237
+ # إعداد معالجات الإشارات
238
+ self.setup_signal_handlers()
239
+
240
+ # تشغيل خادم HTTP API للتحكم
241
+ self.logger.info("🌐 تشغيل HTTP API على المنفذ 8888")
242
+ self.app.run(host='0.0.0.0', port=8888, debug=False)
243
+
244
+ def main():
245
+ service = BackgroundService()
246
+
247
+ if len(sys.argv) > 1:
248
+ command = sys.argv[1]
249
+
250
+ if command == 'start':
251
+ service.run_as_daemon()
252
+ elif command == 'status':
253
+ # فحص حالة الخدمة
254
+ import requests
255
+ try:
256
+ response = requests.get('http://localhost:8888/status')
257
+ print(json.dumps(response.json(), indent=2, ensure_ascii=False))
258
+ except:
259
+ print("❌ الخدمة غير متاحة")
260
+ elif command == 'stop':
261
+ # إيقاف الخدمة
262
+ import requests
263
+ try:
264
+ response = requests.post('http://localhost:8888/stop')
265
+ print(response.json()['message'])
266
+ except:
267
+ print("❌ فشل في إيقاف الخدمة")
268
+ elif command == 'show-ui':
269
+ # إظهار الواجهة التفاعلية
270
+ import requests
271
+ try:
272
+ response = requests.post('http://localhost:8888/show-ui')
273
+ print(response.json()['message'])
274
+ except:
275
+ print("❌ فشل في إظهار الواجهة التفاعلية")
276
+ else:
277
+ print("الأوامر المتاحة: start, status, stop, show-ui")
278
+ else:
279
+ print("استخدام: python background_service.py [start|status|stop|show-ui]")
280
+
281
+ if __name__ == "__main__":
282
+ main()
central_manager.py ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ # central_manager.py
3
+
4
+ import time
5
+ import threading
6
+ from typing import Dict, List
7
+
8
+ import requests
9
+ from fastapi import FastAPI, HTTPException
10
+ from pydantic import BaseModel
11
+
12
+ # ---- إعداد FastAPI ----------------------------------------------------------
13
+ app = FastAPI(title="Central Task Manager")
14
+
15
+ # ---- نماذج البيانات --------------------------------------------------------
16
+
17
+ class RegisterRequest(BaseModel):
18
+ """تسجيل أو تجديد ظهور العقدة."""
19
+ url: str # مثلاً: "http://203.0.113.45:7520/run"
20
+ load: float = 0.0 # نسبة تحميل العقدة (0.0 - 1.0)، اختياري
21
+
22
+ class TaskRequest(BaseModel):
23
+ func: str
24
+ args: List = []
25
+ kwargs: Dict = {}
26
+ complexity: float = 0.0
27
+
28
+ # ---- سجلّ العقد ------------------------------------------------------------
29
+ # بنخزّن للعقدة: آخر timestamp و load
30
+ peers: Dict[str, Dict] = {}
31
+
32
+ HEARTBEAT_TTL = 60 # ثواني قبل اعتبار العقدة متوقفة
33
+ HEALTH_CHECK_FREQ = 30 # ثواني بين فحوص الصحة الداخلية
34
+
35
+ # ---- API للعقد لتسجيل نفسها -----------------------------------------------
36
+
37
+ @app.post("/register")
38
+ async def register_peer(req: RegisterRequest):
39
+ """العقدة تستدعي هذه النقطة كلما انطلقت أو دورياً لتجديد ظهورها."""
40
+ peers[req.url] = {"last_seen": time.time(), "load": req.load}
41
+ return {"status": "ok", "peers_count": len(peers)}
42
+
43
+ # ---- API للعمليات ---------------------------------------------------------
44
+
45
+ @app.get("/peers", response_model=List[str])
46
+ async def list_peers():
47
+ """يعيد قائمة بالعقد الصالحة بعد تنقية المتوقفة."""
48
+ now = time.time()
49
+ # حذف العقد المتوقفة
50
+ for url, info in list(peers.items()):
51
+ if now - info["last_seen"] > HEARTBEAT_TTL:
52
+ peers.pop(url)
53
+ return list(peers.keys())
54
+
55
+ @app.post("/dispatch")
56
+ async def dispatch_task(task: TaskRequest):
57
+ """يتلقى مهمة ويعيد توجيهها لأفضل عقدة أو ينفذ محليّاً."""
58
+ available = await list_peers()
59
+ if not available:
60
+ raise HTTPException(503, "لا توجد عقد متاحة حاليّاً")
61
+
62
+ # خوارزمية بسيطة: الاختيار بناءً على أقل تحميل معلن
63
+ # أو تدوير دائري إذا لم يعلن أحد عن تحميله
64
+ best = None
65
+ best_load = 1.1
66
+ for url in available:
67
+ load = peers[url].get("load", None)
68
+ if load is None:
69
+ best = url
70
+ break
71
+ if load < best_load:
72
+ best, best_load = url, load
73
+
74
+ if not best:
75
+ best = available[0]
76
+
77
+ # إعادة توجيه الطلب
78
+ try:
79
+ resp = requests.post(best, json=task.dict(), timeout=10)
80
+ resp.raise_for_status()
81
+ return resp.json()
82
+ except Exception as e:
83
+ raise HTTPException(502, f"فشل التوجيه إلى {best}: {e}")
84
+
85
+ # ---- فحص دوري لصحة العقد ---------------------------------------------------
86
+
87
+ def health_check_loop():
88
+ while True:
89
+ now = time.time()
90
+ for url in list(peers.keys()):
91
+ health_url = url.replace("/run", "/health")
92
+ try:
93
+ r = requests.get(health_url, timeout=3)
94
+ if r.status_code == 200:
95
+ peers[url]["last_seen"] = now
96
+ # يمكنك تحديث load من رد /health إذا وفّرته
97
+ else:
98
+ peers.pop(url)
99
+ except:
100
+ peers.pop(url)
101
+ time.sleep(HEALTH_CHECK_FREQ)
102
+
103
+ # ---- تشغيل الخلفيات وخادم FastAPI ------------------------------------------
104
+
105
+ if __name__ == "__main__":
106
+ # شغل لوب الفحص الطبي في الخلفية
107
+ threading.Thread(target=health_check_loop, daemon=True).start()
108
+
109
+ import uvicorn
110
+ uvicorn.run(app, host="0.0.0.0", port=1500)
111
+
control.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import argparse
2
+ from autostart_config import AutoStartManager
3
+
4
+ def main():
5
+ parser = argparse.ArgumentParser(description="نظام التحكم في التشغيل التلقائي")
6
+ parser.add_argument('--enable', action='store_true', help="تفعيل التشغيل التلقائي")
7
+ parser.add_argument('--disable', action='store_true', help="تعطيل التشغيل التلقائي")
8
+ parser.add_argument('--status', action='store_true', help="عرض حالة التشغيل التلقائي")
9
+
10
+ args = parser.parse_args()
11
+ manager = AutoStartManager()
12
+
13
+ if args.enable:
14
+ manager.enable_autostart()
15
+ print("✓ تم تفعيل التشغيل التلقائي")
16
+ elif args.disable:
17
+ manager.disable_autostart()
18
+ print("✗ تم تعطيل التشغيل التلقائي")
19
+ elif args.status:
20
+ status = "مفعل" if manager.config['enabled'] else "معطل"
21
+ print(f"حالة التشغيل التلقائي: {status}")
22
+ else:
23
+ parser.print_help()
24
+
25
+ if __name__ == "__main__":
26
+ main()
dashboard.py ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # dashboard.py
2
+ from flask import Flask, render_template, jsonify
3
+ from peer_discovery import discover_peers
4
+ import threading
5
+ import time
6
+ from typing import List, Dict
7
+ import logging
8
+
9
+ app = Flask(__name__)
10
+ app.logger.setLevel(logging.INFO)
11
+
12
+ # تهيئة قائمة الأقران
13
+ current_peers: Dict[str, List[Dict[str, str]]] = {"local": [], "external": []}
14
+
15
+ def update_peers_loop() -> None:
16
+ """حلقة تحديث قائمة الأقران بشكل دوري"""
17
+ global current_peers
18
+ while True:
19
+ try:
20
+ new_peers = discover_peers()
21
+ current_peers = new_peers
22
+ total_peers = len(new_peers["local"]) + len(new_peers["external"])
23
+ app.logger.info(f"تم تحديث قائمة الأقران: {total_peers} جهاز")
24
+ except Exception as e:
25
+ app.logger.error(f"خطأ في اكتشاف الأقران: {str(e)}")
26
+ time.sleep(10)
27
+
28
+ @app.route("/")
29
+ def dashboard() -> str:
30
+ """عرض لوحة التحكم الرئيسية"""
31
+ total_peers = len(current_peers["local"]) + len(current_peers["external"])
32
+ return render_template("dashboard.html",
33
+ peers_count=total_peers,
34
+ last_update=time.strftime("%Y-%m-%d %H:%M:%S"))
35
+
36
+ @app.route("/api/peers")
37
+ def get_peers() -> dict:
38
+ """واجهة API للحصول على قائمة الأقران"""
39
+ total_peers = len(current_peers["local"]) + len(current_peers["external"])
40
+ return jsonify({
41
+ "peers": current_peers,
42
+ "count": total_peers,
43
+ "status": "success"
44
+ })
45
+
46
+ def start_background_thread() -> None:
47
+ """بدء خيط الخلفية لتحديث الأقران"""
48
+ thread = threading.Thread(target=update_peers_loop)
49
+ thread.daemon = True
50
+ thread.start()
51
+
52
+ if __name__ == "__main__":
53
+ start_background_thread()
54
+ app.run(host="0.0.0.0", port=7530, debug=False)
55
+
distributed_executor.py ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import threading
2
+ import queue
3
+ import time
4
+ import json
5
+ from typing import Callable, Dict, List
6
+ import socket
7
+ from zeroconf import Zeroconf, ServiceBrowser, ServiceInfo
8
+ import logging
9
+ import requests # ✅ تأكد من استيراده
10
+
11
+ logging.basicConfig(level=logging.INFO)
12
+
13
+ class PeerRegistry:
14
+ def __init__(self):
15
+ self._peers = {}
16
+ self._zeroconf = Zeroconf()
17
+ self.local_node_id = socket.gethostname()
18
+
19
+ def register_service(self, name: str, port: int, load: float = 0.0):
20
+ service_info = ServiceInfo(
21
+ "_tasknode._tcp.local.",
22
+ f"{name}._tasknode._tcp.local.",
23
+ addresses=[socket.inet_aton(self._get_local_ip())],
24
+ port=port,
25
+ properties={
26
+ b'load': str(load).encode(), # تأكد من أنها bytes
27
+ b'node_id': self.local_node_id.encode()
28
+ },
29
+ server=f"{name}.local."
30
+ )
31
+ self._zeroconf.register_service(service_info)
32
+ logging.info(f"✅ Service registered: {name} @ {self._get_local_ip()}:{port}")
33
+
34
+ def discover_peers(self, timeout: int = 3) -> List[Dict]:
35
+ class Listener:
36
+ def __init__(self):
37
+ self.peers = []
38
+
39
+ def add_service(self, zc, type_, name):
40
+ info = zc.get_service_info(type_, name)
41
+ if info:
42
+ ip = socket.inet_ntoa(info.addresses[0])
43
+ peer_data = {
44
+ 'ip': ip,
45
+ 'port': info.port,
46
+ 'load': float(info.properties.get(b'load', b'0')),
47
+ 'node_id': info.properties.get(b'node_id', b'unknown').decode(),
48
+ 'last_seen': time.time()
49
+ }
50
+ if peer_data not in self.peers:
51
+ self.peers.append(peer_data)
52
+
53
+ def update_service(self, zc, type_, name):
54
+ self.add_service(zc, type_, name)
55
+
56
+ def remove_service(self, zc, type_, name):
57
+ pass # اختياري
58
+
59
+ listener = Listener()
60
+ ServiceBrowser(self._zeroconf, "_tasknode._tcp.local.", listener)
61
+ time.sleep(timeout)
62
+ return sorted(listener.peers, key=lambda x: x['load'])
63
+
64
+ def _get_local_ip(self) -> str:
65
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
66
+ try:
67
+ s.connect(('10.255.255.255', 1))
68
+ ip = s.getsockname()[0]
69
+ except Exception:
70
+ ip = '127.0.0.1'
71
+ finally:
72
+ s.close()
73
+ return ip
74
+
75
+ class DistributedExecutor:
76
+ def __init__(self, shared_secret: str):
77
+ self.peer_registry = PeerRegistry()
78
+ self.shared_secret = shared_secret
79
+ self.task_queue = queue.PriorityQueue()
80
+ self.result_cache = {}
81
+ self.available_peers = []
82
+ self._init_peer_discovery()
83
+
84
+ def _init_peer_discovery(self):
85
+ def discovery_loop():
86
+ while True:
87
+ self.available_peers = self.peer_registry.discover_peers()
88
+ logging.info(f"✅ Discovered peers: {self.available_peers}")
89
+ time.sleep(10)
90
+
91
+ threading.Thread(target=discovery_loop, daemon=True).start()
92
+
93
+ def submit(self, task_func: Callable, *args, **kwargs):
94
+ """إرسال مهمة جديدة للنظام"""
95
+ task_id = f"{task_func.__name__}_{time.time()}"
96
+
97
+ task = {
98
+ 'task_id': task_id,
99
+ 'function': task_func.__name__,
100
+ 'args': args,
101
+ 'kwargs': kwargs,
102
+ 'sender_id': self.peer_registry.local_node_id
103
+ }
104
+
105
+ if self.available_peers:
106
+ # ترتيب الأجهزة: LAN أولاً ثم WAN
107
+ lan_peers = [p for p in self.available_peers if self._is_local_ip(p['ip'])]
108
+ wan_peers = [p for p in self.available_peers if not self._is_local_ip(p['ip'])]
109
+
110
+ # اختيار من LAN أولاً
111
+ if lan_peers:
112
+ peer = min(lan_peers, key=lambda x: x['load'])
113
+ logging.info(f"✅ Sending task {task_id} to LAN peer {peer['node_id']}")
114
+ else:
115
+ # إذا لم تتوفر أجهزة محلية، استخدم WAN
116
+ peer = min(wan_peers, key=lambda x: x['load'])
117
+ logging.info(f"✅ Sending task {task_id} to WAN peer {peer['node_id']}")
118
+
119
+ self._send_to_peer(peer, task)
120
+ else:
121
+ logging.warning("⚠️ لا توجد أجهزة متاحة - سيتم تنفيذ المهمة محلياً")
122
+
123
+ def _is_local_ip(self, ip: str) -> bool:
124
+ """فحص إذا كان IP في الشبكة المحلية"""
125
+ return (
126
+ ip.startswith('192.168.') or
127
+ ip.startswith('10.') or
128
+ ip.startswith('172.') or
129
+ ip == '127.0.0.1'
130
+ )
131
+
132
+ def _send_to_peer(self, peer: Dict, task: Dict):
133
+ try:
134
+ url = f"http://{peer['ip']}:{peer['port']}/run"
135
+ response = requests.post(url, json=task, timeout=10)
136
+ response.raise_for_status()
137
+ logging.info(f"✅ Response from peer: {response.text}")
138
+ return response.json()
139
+ except Exception as e:
140
+ logging.error(f"❌ فشل إرسال المهمة لـ {peer['node_id']}: {e}")
141
+ return None
142
+
143
+ if __name__ == "__main__":
144
+ executor = DistributedExecutor("my_secret_key")
145
+ executor.peer_registry.register_service("node1", 7520, load=0.1)
146
+ print("✅ نظام توزيع المهام جاهز...")
147
+
148
+ # مثال لإرسال مهمة:
149
+ def example_task(x):
150
+ return x * x
151
+
152
+ executor.submit(example_task, 5)
153
+
dts_cli.py ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # dts_cli.py
2
+ import click
3
+ from dashboard import app
4
+ from rpc_server import app as rpc_app
5
+ import threading
6
+
7
+ @click.group()
8
+ def cli():
9
+ pass
10
+
11
+ @cli.command()
12
+ def start():
13
+ """بدء النظام الموزع"""
14
+ print("جارِ تشغيل النظام الموزع...")
15
+
16
+ # تشغيل واجهة التحكم في خيط منفصل
17
+ dashboard_thread = threading.Thread(
18
+ target=lambda: app.run(host="0.0.0.0", port=5000)
19
+ )
20
+ dashboard_thread.daemon = True
21
+ dashboard_thread.start()
22
+
23
+ # تشغيل خادم RPC
24
+ rpc_app.run(host="0.0.0.0", port=7520)
25
+
26
+ @cli.command()
27
+ def discover():
28
+ """عرض الأجهزة المتصلة"""
29
+ from peer_discovery import discover_peers
30
+ peers = discover_peers()
31
+ print("الأجهزة المتصلة:")
32
+ for i, peer in enumerate(peers, 1):
33
+ print(f"{i}. {peer}")
34
+
35
+ if __name__ == "__main__":
36
+ cli()
enhanced_assistant.py ADDED
@@ -0,0 +1,312 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import os
3
+ import json
4
+ import requests
5
+ from typing import Dict, List, Optional
6
+ from difflib import get_close_matches
7
+ import tempfile
8
+ from PIL import Image
9
+ from io import BytesIO
10
+ import re
11
+ from datetime import datetime
12
+
13
+ class EnhancedNoraAssistant:
14
+ def __init__(self):
15
+ self.knowledge_file = "knowledge_base.json"
16
+ self.memory_file = "global_memory.json"
17
+ self.learning_file = "nora_learning_data.json"
18
+ self.history_path = "enhanced_history.json"
19
+
20
+ # تحميل البيانات
21
+ self.knowledge = self.load_knowledge()
22
+ self.memory = self.load_memory()
23
+ self.chat_history = self.load_history()
24
+
25
+ print("✅ تم تهيئة نورا المحسنة بنجاح!")
26
+
27
+ def load_knowledge(self) -> Dict:
28
+ """تحميل قاعدة المعرفة"""
29
+ if os.path.exists(self.knowledge_file):
30
+ with open(self.knowledge_file, 'r', encoding='utf-8') as f:
31
+ return json.load(f)
32
+ return {}
33
+
34
+ def save_knowledge(self):
35
+ """حفظ قاعدة المعرفة"""
36
+ with open(self.knowledge_file, 'w', encoding='utf-8') as f:
37
+ json.dump(self.knowledge, f, ensure_ascii=False, indent=2)
38
+
39
+ def load_memory(self) -> Dict:
40
+ """تحميل الذاكرة العامة"""
41
+ if os.path.exists(self.memory_file):
42
+ with open(self.memory_file, 'r', encoding='utf-8') as f:
43
+ return json.load(f)
44
+ return {}
45
+
46
+ def save_memory(self):
47
+ """حفظ الذاكرة العامة"""
48
+ with open(self.memory_file, 'w', encoding='utf-8') as f:
49
+ json.dump(self.memory, f, ensure_ascii=False, indent=2)
50
+
51
+ def load_history(self) -> List[Dict]:
52
+ """تحميل سجل المحادثة"""
53
+ if os.path.exists(self.history_path):
54
+ try:
55
+ with open(self.history_path, "r", encoding="utf-8") as f:
56
+ return json.load(f)
57
+ except:
58
+ return []
59
+ return []
60
+
61
+ def save_history(self):
62
+ """حفظ سجل المحادثة"""
63
+ with open(self.history_path, "w", encoding="utf-8") as f:
64
+ json.dump(self.chat_history, f, ensure_ascii=False, indent=2)
65
+
66
+ def clean_text(self, text: str) -> str:
67
+ """تنظيف النص"""
68
+ text = re.sub(r'\s+', ' ', text)
69
+ return text.strip()
70
+
71
+ def detect_language(self, text: str) -> str:
72
+ """كشف لغة النص"""
73
+ arabic_chars = re.compile('[\u0600-\u06FF]')
74
+ if arabic_chars.search(text):
75
+ return "ar"
76
+ return "en"
77
+
78
+ def fix_url(self, url: str) -> str:
79
+ """تصحيح الرابط"""
80
+ if not url.startswith(("http://", "https://")):
81
+ return "https://" + url.lstrip("//")
82
+ return url
83
+
84
+ def detect_media_type(self, url: str) -> str:
85
+ """تحديد نوع الوسائط"""
86
+ url = url.lower()
87
+ if url.endswith(('.jpg', '.jpeg', '.png', '.gif', '.webp')):
88
+ return 'image'
89
+ elif url.endswith(('.mp4', '.mov', '.avi', '.webm')):
90
+ return 'video'
91
+ elif url.endswith(('.mp3', '.wav', '.ogg', '.m4a')):
92
+ return 'audio'
93
+ elif url.endswith('.pdf'):
94
+ return 'pdf'
95
+ return 'link'
96
+
97
+ def analyze_image_from_url(self, image_url: str) -> str:
98
+ """تحليل صورة من رابط"""
99
+ try:
100
+ response = requests.get(image_url, timeout=10)
101
+ response.raise_for_status()
102
+ image = Image.open(BytesIO(response.content))
103
+ return f"تحليل الصورة: الحجم {image.size}، الصيغة {image.format}"
104
+ except Exception as e:
105
+ return f"خطأ في تحليل الصورة: {str(e)}"
106
+
107
+ def smart_auto_reply(self, message: str) -> Optional[str]:
108
+ """ردود ذكية تلقائية"""
109
+ msg = message.strip().lower()
110
+
111
+ responses = {
112
+ "هل نبدأ": "نعم ابدأ",
113
+ "ابدأ": "نعم ابدأ",
114
+ "نعم أو لا": "نعم",
115
+ "هل تود": "نعم",
116
+ "هل تريدني": "نعم",
117
+ "ما هي": "ليس الآن",
118
+ "تفصيل": "ليس الآن",
119
+ "هل تحتاج": "نعم، شرح أكثر",
120
+ "جاهز؟": "ابدأ",
121
+ "قول لي": "موافق"
122
+ }
123
+
124
+ for key, value in responses.items():
125
+ if key in msg:
126
+ return value
127
+
128
+ if " أو " in msg:
129
+ return msg.split(" أو ")[0]
130
+
131
+ return None
132
+
133
+ def learn_new_info(self, topic: str, info: str) -> str:
134
+ """تعلم معلومة جديدة"""
135
+ if topic not in self.knowledge:
136
+ self.knowledge[topic] = []
137
+
138
+ if info not in self.knowledge[topic]:
139
+ self.knowledge[topic].append({
140
+ "content": info,
141
+ "timestamp": datetime.utcnow().isoformat()
142
+ })
143
+ self.save_knowledge()
144
+ return f"✅ تمت إضافة معلومة جديدة عن '{topic}'"
145
+
146
+ return f"ℹ️ المعلومة موجودة مسبقاً عن '{topic}'"
147
+
148
+ def search_knowledge(self, query: str) -> str:
149
+ """البحث في قاعدة المعرفة"""
150
+ query_clean = query.strip().lower()
151
+
152
+ # بحث مباشر
153
+ if query_clean in self.knowledge:
154
+ info = self.knowledge[query_clean]
155
+ if isinstance(info, list) and info:
156
+ return info[-1].get("content", str(info[-1]))
157
+ return str(info)
158
+
159
+ # بحث في المواضيع
160
+ for topic, infos in self.knowledge.items():
161
+ if query_clean in topic.lower():
162
+ if isinstance(infos, list) and infos:
163
+ return f"وجدت معلومة عن '{topic}': {infos[-1].get('content', str(infos[-1]))}"
164
+ return f"وجدت معلومة عن '{topic}': {str(infos)}"
165
+
166
+ return None
167
+
168
+ def generate_reply(self, user_input: str) -> str:
169
+ """إنتاج الرد الذكي"""
170
+ user_input = self.clean_text(user_input)
171
+
172
+ # فحص الردود التلقائية الذكية
173
+ auto_reply = self.smart_auto_reply(user_input)
174
+ if auto_reply:
175
+ self.memory[user_input] = auto_reply
176
+ self.save_memory()
177
+ return auto_reply
178
+
179
+ # فحص الذاكرة
180
+ if user_input in self.memory:
181
+ return self.memory[user_input]
182
+
183
+ # البحث في المطابقات القريبة
184
+ matches = get_close_matches(user_input, self.memory.keys(), n=1, cutoff=0.6)
185
+ if matches:
186
+ return self.memory[matches[0]]
187
+
188
+ # البحث في قاعدة المعرفة
189
+ knowledge_result = self.search_knowledge(user_input)
190
+ if knowledge_result:
191
+ self.memory[user_input] = knowledge_result
192
+ self.save_memory()
193
+ return knowledge_result
194
+
195
+ # معالجة الروابط
196
+ if user_input.startswith("http://") or user_input.startswith("https://"):
197
+ return self.handle_url(user_input)
198
+
199
+ # تصحيح الروابط في النص
200
+ if '//' in user_input:
201
+ corrected_url = self.fix_url(user_input)
202
+ reply = f"تم تصحيح الرابط: {corrected_url}"
203
+ else:
204
+ # رد افتراضي مع تعلم
205
+ reply = f"شكراً لك على الرسالة: '{user_input}'. سأتذكر هذا للمرة القادمة."
206
+
207
+ # تعلم تلقائي
208
+ if len(user_input.split()) > 2: # إذا كانت جملة معقولة
209
+ self.learn_new_info("محادثات_عامة", user_input)
210
+
211
+ # حفظ في الذاكرة
212
+ self.memory[user_input] = reply
213
+ self.save_memory()
214
+ return reply
215
+
216
+ def handle_url(self, url: str) -> str:
217
+ """معالجة الروابط"""
218
+ url = self.fix_url(url)
219
+ media_type = self.detect_media_type(url)
220
+
221
+ if media_type == 'image':
222
+ analysis = self.analyze_image_from_url(url)
223
+ reply = f"🖼️ صورة تم تحليلها:\n{analysis}"
224
+ elif media_type == 'video':
225
+ reply = f"🎥 فيديو تم اكتشافه: {url}"
226
+ elif media_type == 'audio':
227
+ reply = f"🎵 ملف صوتي تم اكتشافه: {url}"
228
+ elif media_type == 'pdf':
229
+ reply = f"📄 ملف PDF تم اكتشافه: {url}"
230
+ else:
231
+ reply = f"🔗 رابط ويب: {url}"
232
+
233
+ return reply
234
+
235
+ def simulate_server_scan(self):
236
+ """محاكاة البحث عن الخوادم"""
237
+ print("نورا: أبحث عن خوادم متاحة...")
238
+ fake_servers = ["server-01.cloud.com", "server-02.cloud.com", "server-03.local"]
239
+
240
+ for server in fake_servers:
241
+ print(f"نورا: تم العثور على خادم: {server}")
242
+ print(f"نورا: أقوم بمحاكاة النسخ إلى {server}...")
243
+
244
+ return "تمت عملية المحاكاة بنجاح ✅"
245
+
246
+ def get_stats(self) -> Dict:
247
+ """إحصائيات النظام"""
248
+ return {
249
+ "معرفة_محفوظة": len(self.knowledge),
250
+ "ذكريات": len(self.memory),
251
+ "سجل_محادثات": len(self.chat_history),
252
+ "آخر_تحديث": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
253
+ }
254
+
255
+ def chat(self):
256
+ """بدء المحادثة التفاعلية"""
257
+ print("🤖 مرحباً! أنا نورا المحسنة، مساعدتك الذكية.")
258
+ print("📚 لدي قدرات محسنة في التعلم الذاتي وتحليل الوسائط")
259
+ print("💡 اكتب 'خروج' للإنهاء، 'إحصائيات' لعرض الإحص��ئيات، 'scan' للبحث عن خوادم")
260
+ print("-" * 50)
261
+
262
+ while True:
263
+ try:
264
+ user_input = input("\n🧑 أنت: ").strip()
265
+
266
+ if user_input.lower() in ["خروج", "exit", "quit"]:
267
+ print("نورا: مع السلامة! 👋")
268
+ break
269
+
270
+ elif user_input.lower() == "إحصائيات":
271
+ stats = self.get_stats()
272
+ print("📊 إحصائيات النظام:")
273
+ for key, value in stats.items():
274
+ print(f" {key}: {value}")
275
+ continue
276
+
277
+ elif user_input.lower() == "scan":
278
+ result = self.simulate_server_scan()
279
+ print(f"نورا: {result}")
280
+ continue
281
+
282
+ elif not user_input:
283
+ continue
284
+
285
+ # الحصول على الرد
286
+ response = self.generate_reply(user_input)
287
+ print(f"🤖 نورا: {response}")
288
+
289
+ # حفظ في السجل
290
+ self.chat_history.append({
291
+ "user": user_input,
292
+ "assistant": response,
293
+ "timestamp": datetime.utcnow().isoformat()
294
+ })
295
+
296
+ # حفظ السجل كل 5 رسائل
297
+ if len(self.chat_history) % 5 == 0:
298
+ self.save_history()
299
+
300
+ except KeyboardInterrupt:
301
+ print("\n\nنورا: تم إيقاف المحادثة. مع السلامة! 👋")
302
+ break
303
+ except Exception as e:
304
+ print(f"نورا: عذراً، حدث خطأ: {str(e)}")
305
+
306
+ def main():
307
+ """تشغيل المساعد المحسن"""
308
+ assistant = EnhancedNoraAssistant()
309
+ assistant.chat()
310
+
311
+ if __name__ == "__main__":
312
+ main()
internet_scanner.py ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ """
3
+ internet_scanner.py - ماسح للبحث عن أجهزة DTS على الإنترنت
4
+ """
5
+ import requests
6
+ import threading
7
+ import time
8
+ import socket
9
+ from concurrent.futures import ThreadPoolExecutor, as_completed
10
+ import logging
11
+
12
+ class InternetScanner:
13
+ def __init__(self):
14
+ self.discovered_peers = set()
15
+ self.scan_ranges = [
16
+ # نطاقات IP شائعة للخوادم العامة
17
+ "8.8.8.0/24", # Google DNS range
18
+ "1.1.1.0/24", # Cloudflare range
19
+ "208.67.222.0/24", # OpenDNS range
20
+ ]
21
+
22
+ def scan_ip_range(self, ip_range: str, port: int = 7520):
23
+ """مسح نطاق IP للبحث عن خوادم DTS"""
24
+ import ipaddress
25
+
26
+ try:
27
+ network = ipaddress.ip_network(ip_range, strict=False)
28
+ active_peers = []
29
+
30
+ with ThreadPoolExecutor(max_workers=50) as executor:
31
+ futures = []
32
+
33
+ for ip in network.hosts():
34
+ future = executor.submit(self.check_dts_node, str(ip), port)
35
+ futures.append(future)
36
+
37
+ for future in as_completed(futures, timeout=30):
38
+ try:
39
+ result = future.result()
40
+ if result:
41
+ active_peers.append(result)
42
+ except:
43
+ continue
44
+
45
+ return active_peers
46
+
47
+ except Exception as e:
48
+ logging.error(f"خطأ في مسح النطاق {ip_range}: {e}")
49
+ return []
50
+
51
+ def check_dts_node(self, ip: str, port: int = 7520) -> str:
52
+ """فحص IP معين للتأكد من وجود خادم DTS مع المشروع"""
53
+ try:
54
+ # فحص صفحة الصحة العامة
55
+ health_url = f"http://{ip}:{port}/health"
56
+ response = requests.get(health_url, timeout=2)
57
+
58
+ if response.status_code == 200:
59
+ # فحص وجود المشروع الصحيح
60
+ run_url = f"http://{ip}:{port}/run"
61
+
62
+ # اختبار مهمة من المشروع للتأكد
63
+ test_payload = {
64
+ "func": "matrix_multiply",
65
+ "args": [2],
66
+ "kwargs": {}
67
+ }
68
+
69
+ test_response = requests.post(run_url, json=test_payload, timeout=3)
70
+
71
+ # فحص إضافي للتأكد من هوية المشروع
72
+ project_check = requests.get(f"http://{ip}:{port}/project_info", timeout=2)
73
+
74
+ if (test_response.status_code in [200, 404] and
75
+ project_check.status_code == 200):
76
+
77
+ project_data = project_check.json()
78
+
79
+ # التحقق من معرف المشروع الصحيح
80
+ if (project_data.get("project_name") == "distributed-task-system" and
81
+ project_data.get("version") == "1.0"):
82
+ logging.info(f"✅ اكتُشف خادم DTS صحيح: {ip}:{port}")
83
+ return run_url
84
+ else:
85
+ logging.warning(f"⚠️ خادم على {ip}:{port} لكن مشروع مختلف")
86
+
87
+ except:
88
+ pass
89
+ return None
90
+
91
+ def scan_public_repositories(self):
92
+ """البحث في المستودعات العامة عن عناوين خوادم DTS"""
93
+ try:
94
+ # البحث في GitHub عن مشاريع DTS
95
+ github_api = "https://api.github.com/search/repositories"
96
+ params = {
97
+ "q": "distributed task system port:7520",
98
+ "sort": "updated",
99
+ "per_page": 10
100
+ }
101
+
102
+ response = requests.get(github_api, params=params, timeout=10)
103
+ if response.status_code == 200:
104
+ repos = response.json().get("items", [])
105
+
106
+ for repo in repos:
107
+ # محاولة استخراج IPs من وصف المشروع أو README
108
+ if repo.get("description"):
109
+ self.extract_ips_from_text(repo["description"])
110
+
111
+ except Exception as e:
112
+ logging.warning(f"خطأ في البحث في المستودعات: {e}")
113
+
114
+ def extract_ips_from_text(self, text: str):
115
+ """استخراج عناوين IP من النص"""
116
+ import re
117
+
118
+ ip_pattern = r'\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b'
119
+ ips = re.findall(ip_pattern, text)
120
+
121
+ for ip in ips:
122
+ try:
123
+ # التحقق من صحة IP
124
+ socket.inet_aton(ip)
125
+ peer_url = f"http://{ip}:7520/run"
126
+
127
+ # فحص سريع
128
+ if self.check_dts_node(ip):
129
+ self.discovered_peers.add(peer_url)
130
+
131
+ except:
132
+ continue
133
+
134
+ def start_continuous_scan(self):
135
+ """بدء المسح المستمر"""
136
+ def scan_loop():
137
+ while True:
138
+ try:
139
+ # مسح النطاقات المحددة
140
+ for ip_range in self.scan_ranges:
141
+ peers = self.scan_ip_range(ip_range)
142
+ for peer in peers:
143
+ self.discovered_peers.add(peer)
144
+
145
+ # البحث في المستودعات العامة
146
+ self.scan_public_repositories()
147
+
148
+ logging.info(f"اكتُشف {len(self.discovered_peers)} خادم على الإنترنت")
149
+
150
+ except Exception as e:
151
+ logging.error(f"خطأ في المسح المستمر: {e}")
152
+
153
+ # انتظار 30 دقيقة قبل المسح التالي
154
+ time.sleep(1800)
155
+
156
+ thread = threading.Thread(target=scan_loop, daemon=True)
157
+ thread.start()
158
+ logging.info("🔍 بدء المسح المستمر للإنترنت")
159
+
160
+ def get_discovered_peers(self):
161
+ """الحصول على قائمة الأجهزة المكتشفة"""
162
+ return list(self.discovered_peers)
163
+
164
+ # إنشاء مثيل عام
165
+ internet_scanner = InternetScanner()
launcher.py ADDED
@@ -0,0 +1,215 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ #!/usr/bin/env python3
3
+ """
4
+ مشغل موحد لنظام توزيع المهام
5
+ يوفر خيارات متعددة للتشغيل
6
+ """
7
+
8
+ import sys
9
+ import os
10
+ import subprocess
11
+ import argparse
12
+ import time
13
+ from pathlib import Path
14
+
15
+ def check_requirements():
16
+ """فحص المتطلبات والاعتماديات"""
17
+ required_files = [
18
+ 'background_service.py',
19
+ 'main.py',
20
+ 'peer_server.py',
21
+ 'rpc_server.py',
22
+ 'load_balancer.py'
23
+ ]
24
+
25
+ missing_files = []
26
+ for file in required_files:
27
+ if not Path(file).exists():
28
+ missing_files.append(file)
29
+
30
+ if missing_files:
31
+ print(f"❌ ملفات مفقودة: {', '.join(missing_files)}")
32
+ return False
33
+
34
+ return True
35
+
36
+ def install_tray_dependencies():
37
+ """تثبيت اعتماديات أيقونة شريط النظام"""
38
+ try:
39
+ subprocess.check_call([sys.executable, '-m', 'pip', 'install', 'pystray', 'Pillow'])
40
+ print("✅ تم تثبيت اعتماديات أيقونة شريط النظام")
41
+ return True
42
+ except subprocess.CalledProcessError:
43
+ print("❌ فشل في تثبيت اعتماديات أيقونة شريط النظام")
44
+ return False
45
+
46
+ def start_background_service():
47
+ """بدء تشغيل الخدمة في الخلفية"""
48
+ print("🚀 بدء تشغيل الخدمة في الخلفية...")
49
+
50
+ # تشغيل الخدمة الخلفية
51
+ process = subprocess.Popen(
52
+ [sys.executable, 'background_service.py', 'start'],
53
+ stdout=subprocess.PIPE,
54
+ stderr=subprocess.PIPE
55
+ )
56
+
57
+ # انتظار قليل للتأكد من بدء التشغيل
58
+ time.sleep(2)
59
+
60
+ if process.poll() is None:
61
+ print("✅ تم بدء تشغيل الخدمة الخلفية بنجاح")
62
+ return process
63
+ else:
64
+ print("❌ فشل في بدء تشغيل الخدمة الخلفية")
65
+ return None
66
+
67
+ def start_with_tray():
68
+ """تشغيل النظام مع أيقونة شريط النظام"""
69
+ print("🖱️ تشغيل النظام مع أيقونة شريط النظام...")
70
+
71
+ # بدء الخدمة الخلفية أولاً
72
+ bg_process = start_background_service()
73
+ if not bg_process:
74
+ return False
75
+
76
+ time.sleep(3) # انتظار حتى تصبح الخدمة جاهزة
77
+
78
+ try:
79
+ # تشغيل أيقونة شريط النظام
80
+ subprocess.run([sys.executable, 'system_tray.py'])
81
+ except KeyboardInterrupt:
82
+ print("\n🛑 إيقاف النظام...")
83
+ # إيقاف الخدمة الخلفية
84
+ try:
85
+ import requests
86
+ requests.post('http://localhost:8888/stop', timeout=5)
87
+ except:
88
+ bg_process.terminate()
89
+
90
+ return True
91
+
92
+ def start_interactive():
93
+ """تشغيل النظام في الوضع التفاعلي"""
94
+ print("🖥️ تشغيل النظام في الوضع التفاعلي...")
95
+
96
+ # بدء الخدمة الخلفية
97
+ bg_process = start_background_service()
98
+ if not bg_process:
99
+ return False
100
+
101
+ time.sleep(3)
102
+
103
+ # تشغيل الواجهة التفاعلية
104
+ try:
105
+ import requests
106
+ requests.post('http://localhost:8888/show-ui', timeout=5)
107
+ print("✅ تم تشغيل الواجهة التفاعلية")
108
+
109
+ # فتح المتصفح
110
+ import webbrowser
111
+ time.sleep(2)
112
+ webbrowser.open('http://localhost:5173')
113
+
114
+ # انتظار إنهاء المستخدم
115
+ input("اضغط Enter لإيقاف النظام...")
116
+
117
+ except KeyboardInterrupt:
118
+ pass
119
+ finally:
120
+ print("🛑 إيقاف النظام...")
121
+ try:
122
+ import requests
123
+ requests.post('http://localhost:8888/stop', timeout=5)
124
+ except:
125
+ bg_process.terminate()
126
+
127
+ return True
128
+
129
+ def start_headless():
130
+ """تشغيل النظام بدون واجهة (للخوادم)"""
131
+ print("⚙️ تشغيل النظام بدون واجهة...")
132
+
133
+ try:
134
+ # تشغيل الخدمة الخلفية والانتظار
135
+ subprocess.run([sys.executable, 'background_service.py', 'start'])
136
+ except KeyboardInterrupt:
137
+ print("\n🛑 إيقاف النظام...")
138
+
139
+ return True
140
+
141
+ def show_status():
142
+ """عرض حالة النظام"""
143
+ subprocess.run([sys.executable, 'background_service.py', 'status'])
144
+
145
+ def stop_system():
146
+ """إيقاف النظام"""
147
+ subprocess.run([sys.executable, 'background_service.py', 'stop'])
148
+
149
+ def main():
150
+ parser = argparse.ArgumentParser(
151
+ description="مشغل نظام توزيع المهام الذكي",
152
+ formatter_class=argparse.RawDescriptionHelpFormatter,
153
+ epilog="""
154
+ أمثلة الاستخدام:
155
+ python launcher.py --tray # تشغيل مع أيقونة شريط ��لنظام
156
+ python launcher.py --interactive # تشغيل تفاعلي مع واجهة
157
+ python launcher.py --headless # تشغيل بدون واجهة (للخوادم)
158
+ python launcher.py --status # عرض حالة النظام
159
+ python launcher.py --stop # إيقاف النظام
160
+ """
161
+ )
162
+
163
+ group = parser.add_mutually_exclusive_group(required=True)
164
+ group.add_argument('--tray', action='store_true',
165
+ help='تشغيل مع أيقونة شريط النظام')
166
+ group.add_argument('--interactive', action='store_true',
167
+ help='تشغيل تفاعلي مع واجهة')
168
+ group.add_argument('--headless', action='store_true',
169
+ help='تشغيل بدون واجهة (للخوادم)')
170
+ group.add_argument('--status', action='store_true',
171
+ help='عرض حالة النظام')
172
+ group.add_argument('--stop', action='store_true',
173
+ help='إيقاف النظام')
174
+
175
+ parser.add_argument('--install-deps', action='store_true',
176
+ help='تثبيت الاعتماديات المطلوبة')
177
+
178
+ args = parser.parse_args()
179
+
180
+ # فحص المتطلبات
181
+ if not check_requirements():
182
+ return 1
183
+
184
+ # تثبيت الاعتماديات إذا طُلب ذلك
185
+ if args.install_deps:
186
+ install_tray_dependencies()
187
+ return 0
188
+
189
+ # تنفيذ الأمر المطلوب
190
+ if args.status:
191
+ show_status()
192
+ elif args.stop:
193
+ stop_system()
194
+ elif args.headless:
195
+ success = start_headless()
196
+ elif args.interactive:
197
+ success = start_interactive()
198
+ elif args.tray:
199
+ # تثبيت اعتماديات أيقونة شريط النظام إذا لم تكن موجودة
200
+ try:
201
+ import pystray
202
+ except ImportError:
203
+ print("📦 تثبيت اعتماديات أيقونة شريط النظام...")
204
+ if not install_tray_dependencies():
205
+ print("❌ فشل في تثبيت الاعتماديات، التشغيل في الوضع التفاعلي...")
206
+ success = start_interactive()
207
+ else:
208
+ success = start_with_tray()
209
+ else:
210
+ success = start_with_tray()
211
+
212
+ return 0 if success else 1
213
+
214
+ if __name__ == "__main__":
215
+ sys.exit(main())
live_streaming.py ADDED
@@ -0,0 +1,405 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ # live_streaming.py - نظام البث المباشر للألعاب والفيديو
3
+
4
+ import cv2
5
+ import numpy as np
6
+ import time
7
+ import threading
8
+ import logging
9
+ import asyncio
10
+ import base64
11
+ import json
12
+ from datetime import datetime
13
+ from processor_manager import should_offload
14
+ from remote_executor import execute_remotely
15
+ from functools import wraps
16
+
17
+ logging.basicConfig(level=logging.INFO)
18
+
19
+ class LiveStreamManager:
20
+ def __init__(self):
21
+ self.active_streams = {}
22
+ self.processing_nodes = []
23
+ self.load_balancer = StreamLoadBalancer()
24
+
25
+ def register_processing_node(self, node_id, capabilities):
26
+ """تسجيل عقدة معالجة جديدة"""
27
+ self.processing_nodes.append({
28
+ "id": node_id,
29
+ "capabilities": capabilities,
30
+ "load": 0.0,
31
+ "last_ping": datetime.now()
32
+ })
33
+ logging.info(f"📡 تم تسجيل عقدة معالجة: {node_id}")
34
+
35
+ class StreamLoadBalancer:
36
+ def __init__(self):
37
+ self.node_loads = {}
38
+
39
+ def get_best_node(self, task_type, nodes):
40
+ """اختيار أفضل عقدة للمعالجة"""
41
+ suitable_nodes = [n for n in nodes if task_type in n.get("capabilities", [])]
42
+ if not suitable_nodes:
43
+ return None
44
+ return min(suitable_nodes, key=lambda x: x["load"])
45
+
46
+ def stream_offload(func):
47
+ """ديكوراتور خاص بالبث المباشر"""
48
+ @wraps(func)
49
+ def wrapper(*args, **kwargs):
50
+ complexity = estimate_stream_complexity(func, args, kwargs)
51
+
52
+ if complexity > 70 or should_offload(complexity):
53
+ logging.info(f"📺 إرسال مهمة البث {func.__name__} للمعالجة الموزعة")
54
+ return execute_remotely(func.__name__, args, kwargs)
55
+
56
+ logging.info(f"📺 معالجة البث محلياً: {func.__name__}")
57
+ return func(*args, **kwargs)
58
+ return wrapper
59
+
60
+ def estimate_stream_complexity(func, args, kwargs):
61
+ """تقدير تعقيد معالجة البث"""
62
+ if func.__name__ == "process_game_stream":
63
+ return args[1] * args[2] / 10000 # FPS × الدقة
64
+ elif func.__name__ == "real_time_video_enhancement":
65
+ return args[0] * 20 # عدد التحسينات × 20
66
+ elif func.__name__ == "multi_stream_processing":
67
+ return len(args[0]) * 25 # عدد البثوث × 25
68
+ elif func.__name__ == "ai_commentary_generation":
69
+ return args[1] * 15 # طول النص × 15
70
+ return 40
71
+
72
+ # ═══════════════════════════════════════════════════════════════
73
+ # معالجة بث الألعاب المباشر
74
+ # ═══════════════════════════════════════════════════════════════
75
+
76
+ @stream_offload
77
+ def process_game_stream(stream_data, fps, resolution, enhancements=None):
78
+ """معالجة بث الألعاب في الوقت الفعلي"""
79
+ start_time = time.time()
80
+
81
+ if enhancements is None:
82
+ enhancements = ["noise_reduction", "color_enhancement"]
83
+
84
+ logging.info(f"🎮 معالجة بث الألعاب - FPS: {fps}, الدقة: {resolution}")
85
+ logging.info(f"🔧 التحسينات: {enhancements}")
86
+
87
+ # محاكاة معالجة الإطارات
88
+ frame_count = len(stream_data) if isinstance(stream_data, list) else 60
89
+ processing_per_frame = 0.01 + (len(enhancements) * 0.005)
90
+ total_processing_time = frame_count * processing_per_frame
91
+
92
+ # محاكاة المعالجة
93
+ time.sleep(min(total_processing_time, 2))
94
+
95
+ # حساب جودة البث
96
+ quality_score = min(100, 60 + (len(enhancements) * 8) + (fps / 2))
97
+ latency = max(50, 200 - (fps * 2)) # أقل تأخير مع FPS أعلى
98
+
99
+ result = {
100
+ "status": "success",
101
+ "stream_type": "game",
102
+ "fps_processed": fps,
103
+ "resolution": resolution,
104
+ "frames_processed": frame_count,
105
+ "enhancements_applied": enhancements,
106
+ "quality_score": round(quality_score, 1),
107
+ "latency_ms": latency,
108
+ "processing_time": time.time() - start_time,
109
+ "bandwidth_optimized": True
110
+ }
111
+
112
+ logging.info(f"✅ تمت معالجة بث اللعبة - جودة: {result['quality_score']}%")
113
+ return result
114
+
115
+ @stream_offload
116
+ def real_time_video_enhancement(enhancement_types, video_quality="1080p", target_fps=60):
117
+ """تحسين الفيديو في الوقت الفعلي"""
118
+ start_time = time.time()
119
+
120
+ available_enhancements = {
121
+ "upscaling": "تحسين الدقة",
122
+ "noise_reduction": "إزالة التشويش",
123
+ "color_grading": "تصحيح الألوان",
124
+ "motion_smoothing": "تنعيم الحركة",
125
+ "hdr_enhancement": "تحسين HDR",
126
+ "sharpening": "زيادة الحدة",
127
+ "stabilization": "تثبيت الصورة"
128
+ }
129
+
130
+ quality_multiplier = {"720p": 1, "1080p": 2, "1440p": 3, "4K": 5}
131
+ multiplier = quality_multiplier.get(video_quality, 2)
132
+
133
+ processing_time = len(enhancement_types) * multiplier * target_fps * 0.0001
134
+
135
+ logging.info(f"📹 تحسين الفيديو المباشر - الجودة: {video_quality}")
136
+ logging.info(f"🎯 التحسينات: {enhancement_types}")
137
+
138
+ # محاكاة التحسين
139
+ time.sleep(min(processing_time, 1.5))
140
+
141
+ enhancements_applied = {}
142
+ for enhancement in enhancement_types:
143
+ if enhancement in available_enhancements:
144
+ enhancements_applied[enhancement] = {
145
+ "name": available_enhancements[enhancement],
146
+ "improvement": round(np.random.uniform(15, 35), 1),
147
+ "processing_cost": round(processing_time / len(enhancement_types), 4)
148
+ }
149
+
150
+ result = {
151
+ "status": "success",
152
+ "video_quality": video_quality,
153
+ "target_fps": target_fps,
154
+ "enhancements": enhancements_applied,
155
+ "total_improvement": round(np.mean([e["improvement"] for e in enhancements_applied.values()]), 1),
156
+ "processing_time": time.time() - start_time,
157
+ "real_time_capable": processing_time < (1/target_fps)
158
+ }
159
+
160
+ logging.info(f"✅ تم تحسين الفيديو - تحسن: {result['total_improvement']}%")
161
+ return result
162
+
163
+ # ═══════════════════════════════════════════════════════════════
164
+ # معالجة متعددة البثوث
165
+ # ═══════════════════════════════════════════════════════════════
166
+
167
+ @stream_offload
168
+ def multi_stream_processing(streams_data, processing_mode="parallel"):
169
+ """معالجة عدة بثوث في نفس الوقت"""
170
+ start_time = time.time()
171
+
172
+ logging.info(f"📡 معالجة متعددة البثوث - العدد: {len(streams_data)}")
173
+ logging.info(f"⚙️ وضع المعالجة: {processing_mode}")
174
+
175
+ results = {}
176
+
177
+ if processing_mode == "parallel":
178
+ # محاكاة المعالجة المتوازية
179
+ max_processing_time = max([s.get("complexity", 1) for s in streams_data]) * 0.1
180
+ time.sleep(min(max_processing_time, 2))
181
+
182
+ for i, stream in enumerate(streams_data):
183
+ stream_id = f"stream_{i+1}"
184
+ results[stream_id] = {
185
+ "status": "processed",
186
+ "quality": stream.get("quality", "1080p"),
187
+ "fps": stream.get("fps", 30),
188
+ "enhancement_applied": True,
189
+ "processing_node": f"node_{(i % 3) + 1}" # توزيع على 3 عقد
190
+ }
191
+ else:
192
+ # معالجة تسلسلية
193
+ total_time = sum([s.get("complexity", 1) for s in streams_data]) * 0.05
194
+ time.sleep(min(total_time, 3))
195
+
196
+ for i, stream in enumerate(streams_data):
197
+ stream_id = f"stream_{i+1}"
198
+ results[stream_id] = {
199
+ "status": "processed",
200
+ "quality": stream.get("quality", "1080p"),
201
+ "fps": stream.get("fps", 30),
202
+ "processing_order": i + 1
203
+ }
204
+
205
+ result = {
206
+ "status": "success",
207
+ "streams_processed": len(streams_data),
208
+ "processing_mode": processing_mode,
209
+ "results": results,
210
+ "total_processing_time": time.time() - start_time,
211
+ "average_quality": round(np.mean([30, 45, 60, 55]), 1), # محاكاة متوسط الجودة
212
+ "nodes_utilized": len(set([r.get("processing_node", "main") for r in results.values()]))
213
+ }
214
+
215
+ logging.info(f"✅ تمت معالجة {len(streams_data)} بث - العقد المستخدمة: {result['nodes_utilized']}")
216
+ return result
217
+
218
+ # ═══════════════════════════════════════════════════════════════
219
+ # ذكاء اصطناعي للبث
220
+ # ═══════════════════════════════════════════════════════════════
221
+
222
+ @stream_offload
223
+ def ai_commentary_generation(game_events, commentary_length, language="ar"):
224
+ """توليد تعليق ذكي للألعاب"""
225
+ start_time = time.time()
226
+
227
+ logging.info(f"🤖 توليد تعليق ذكي - الطول: {commentary_length} كلمة")
228
+
229
+ # قوالب التعليق
230
+ commentary_templates = {
231
+ "ar": [
232
+ "حركة رائعة من اللاعب!",
233
+ "هذا هدف مذهل!",
234
+ "دفاع قوي في هذه اللحظة",
235
+ "استراتيجية مم��ازة",
236
+ "أداء استثنائي!"
237
+ ],
238
+ "en": [
239
+ "Amazing move by the player!",
240
+ "What a fantastic goal!",
241
+ "Strong defense right there",
242
+ "Excellent strategy",
243
+ "Outstanding performance!"
244
+ ]
245
+ }
246
+
247
+ processing_time = commentary_length * 0.02 # 0.02 ثانية لكل كلمة
248
+ time.sleep(min(processing_time, 1))
249
+
250
+ # توليد التعليق
251
+ templates = commentary_templates.get(language, commentary_templates["ar"])
252
+ generated_commentary = []
253
+
254
+ for i in range(min(commentary_length // 5, len(game_events))):
255
+ template = np.random.choice(templates)
256
+ generated_commentary.append(template)
257
+
258
+ result = {
259
+ "status": "success",
260
+ "language": language,
261
+ "commentary_length": len(generated_commentary),
262
+ "generated_text": generated_commentary,
263
+ "game_events_analyzed": len(game_events),
264
+ "processing_time": time.time() - start_time,
265
+ "emotion_detection": "excited", # محاكاة كشف المشاعر
266
+ "context_awareness": True
267
+ }
268
+
269
+ logging.info(f"✅ تم توليد التعليق - {len(generated_commentary)} جملة")
270
+ return result
271
+
272
+ @stream_offload
273
+ def stream_quality_optimization(stream_metadata, target_bandwidth, viewer_count):
274
+ """تحسين جودة البث حسب النطاق الترددي وعدد المشاهدين"""
275
+ start_time = time.time()
276
+
277
+ logging.info(f"📊 تحسين جودة البث - المشاهدين: {viewer_count}")
278
+ logging.info(f"🌐 النطاق المستهدف: {target_bandwidth} Mbps")
279
+
280
+ # حساب الجودة المثلى
281
+ base_quality = min(target_bandwidth * 200, 1080) # حد أقصى 1080p
282
+
283
+ # تعديل حسب عدد المشاهدين
284
+ if viewer_count > 1000:
285
+ quality_adjustment = 0.8 # تقليل الجودة للأعداد الكبيرة
286
+ elif viewer_count > 100:
287
+ quality_adjustment = 0.9
288
+ else:
289
+ quality_adjustment = 1.0
290
+
291
+ optimized_quality = int(base_quality * quality_adjustment)
292
+
293
+ # تحديد FPS مناسب
294
+ if optimized_quality >= 1080:
295
+ optimal_fps = 60
296
+ elif optimized_quality >= 720:
297
+ optimal_fps = 45
298
+ else:
299
+ optimal_fps = 30
300
+
301
+ time.sleep(0.5) # محاكاة المعالجة
302
+
303
+ result = {
304
+ "status": "success",
305
+ "original_quality": stream_metadata.get("quality", "1080p"),
306
+ "optimized_quality": f"{optimized_quality}p",
307
+ "optimal_fps": optimal_fps,
308
+ "target_bandwidth": target_bandwidth,
309
+ "viewer_count": viewer_count,
310
+ "bandwidth_saved": round(max(0, (1080 - optimized_quality) / 1080 * 100), 1),
311
+ "processing_time": time.time() - start_time,
312
+ "adaptive_streaming": True
313
+ }
314
+
315
+ logging.info(f"✅ تم تحسين البث - الجودة: {result['optimized_quality']}")
316
+ return result
317
+
318
+ # ═══════════════════════════════════════════════════════════════
319
+ # إدارة البث المباشر
320
+ # ═══════════════════════════════════════════════════════════════
321
+
322
+ class LiveStreamCoordinator:
323
+ def __init__(self):
324
+ self.active_streams = {}
325
+ self.processing_history = []
326
+
327
+ def start_stream(self, stream_id, config):
328
+ """بدء بث مباشر جديد"""
329
+ self.active_streams[stream_id] = {
330
+ "config": config,
331
+ "start_time": datetime.now(),
332
+ "status": "active",
333
+ "processing_nodes": [],
334
+ "viewers": 0
335
+ }
336
+ logging.info(f"🔴 بدء البث: {stream_id}")
337
+
338
+ def distribute_processing(self, stream_id, task_type, data):
339
+ """توزيع معالجة البث على العقد المختلفة"""
340
+ if stream_id not in self.active_streams:
341
+ return {"error": "البث غير موجود"}
342
+
343
+ # اختيار العقدة المناسبة
344
+ best_node = self._select_processing_node(task_type)
345
+
346
+ # تنفيذ المعالجة
347
+ if best_node:
348
+ result = execute_remotely(task_type, [data], {})
349
+ self.active_streams[stream_id]["processing_nodes"].append(best_node)
350
+ return result
351
+ else:
352
+ # معالجة محلية
353
+ return self._process_locally(task_type, data)
354
+
355
+ def _select_processing_node(self, task_type):
356
+ """اختيار أفضل عقدة للمعالجة"""
357
+ # منطق اختيار العقدة (مبسط)
358
+ return f"node_gpu_{np.random.randint(1, 4)}"
359
+
360
+ def _process_locally(self, task_type, data):
361
+ """معالجة محلية احتياطية"""
362
+ return {"status": "processed_locally", "task": task_type}
363
+
364
+ # دالة اختبار شاملة للبث المباشر
365
+ def run_live_streaming_benchmark():
366
+ """اختبار شامل لنظام البث المباشر"""
367
+ print("\n📺🎮 اختبار نظام البث المباشر للألعاب والفيديو")
368
+ print("=" * 70)
369
+
370
+ # بيانات تجريبية
371
+ game_stream_data = [f"frame_{i}" for i in range(60)] # 60 إطار
372
+ game_events = ["goal", "save", "foul", "corner", "yellow_card"]
373
+
374
+ multi_streams = [
375
+ {"quality": "1080p", "fps": 60, "complexity": 3},
376
+ {"quality": "720p", "fps": 30, "complexity": 2},
377
+ {"quality": "1440p", "fps": 45, "complexity": 4}
378
+ ]
379
+
380
+ tests = [
381
+ ("معالجة بث لعبة", lambda: process_game_stream(game_stream_data, 60, "1920x1080", ["noise_reduction", "color_enhancement", "sharpening"])),
382
+ ("تحسين فيديو مباشر", lambda: real_time_video_enhancement(["upscaling", "noise_reduction", "hdr_enhancement"], "1080p", 60)),
383
+ ("معالجة متعددة البثوث", lambda: multi_stream_processing(multi_streams, "parallel")),
384
+ ("توليد تعليق ذكي", lambda: ai_commentary_generation(game_events, 50, "ar")),
385
+ ("تحسين جودة البث", lambda: stream_quality_optimization({"quality": "1080p"}, 5.0, 500))
386
+ ]
387
+
388
+ coordinator = LiveStreamCoordinator()
389
+
390
+ for test_name, test_func in tests:
391
+ print(f"\n🔄 تشغيل: {test_name}")
392
+ try:
393
+ result = test_func()
394
+ print(f"✅ نجح: {test_name}")
395
+ if "processing_time" in result:
396
+ print(f"⏱️ وقت المعالجة: {result['processing_time']:.2f}s")
397
+ if "quality_score" in result:
398
+ print(f"⭐ جودة: {result['quality_score']}%")
399
+ except Exception as e:
400
+ print(f"❌ فشل: {test_name} - {str(e)}")
401
+
402
+ print("\n🏁 انتهى اختبار البث المباشر")
403
+
404
+ if __name__ == "__main__":
405
+ run_live_streaming_benchmark()
load_balancer.py ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # load_balancer.py
2
+ import peer_discovery, requests, time, smart_tasks, psutil, socket
3
+
4
+ def send(peer, func, *args, **kw):
5
+ try:
6
+ r = requests.post(peer, json={"func": func,
7
+ "args": list(args),
8
+ "kwargs": kw}, timeout=12)
9
+ return r.json()
10
+ except Exception as e:
11
+ return {"error": str(e)}
12
+
13
+ def choose_peer():
14
+ """اختيار أفضل جهاز - أولوية LAN ثم WAN"""
15
+ import socket
16
+
17
+ lan_peers = []
18
+ wan_peers = []
19
+
20
+ # تصنيف الأجهزة
21
+ for p in list(peer_discovery.PEERS):
22
+ ip = p.split('//')[1].split(':')[0] if '//' in p else p.split(':')[0]
23
+ if is_local_ip(ip):
24
+ lan_peers.append(p)
25
+ else:
26
+ wan_peers.append(p)
27
+
28
+ # أولاً: جرب الأجهزة المحلية (LAN)
29
+ best_lan = find_best_peer(lan_peers)
30
+ if best_lan:
31
+ return best_lan
32
+
33
+ # ثانياً: إذا لم تتوفر أجهزة محلية، جرب WAN
34
+ if internet_available():
35
+ best_wan = find_best_peer(wan_peers)
36
+ return best_wan
37
+
38
+ return None
39
+
40
+ def find_best_peer(peers):
41
+ """العثور على أفضل جهاز من قائمة معينة"""
42
+ best = None
43
+ for p in peers:
44
+ try:
45
+ cpu = requests.get(p.replace("/run", "/cpu"), timeout=2).json()["usage"]
46
+ best = (p, cpu) if best is None or cpu < best[1] else best
47
+ except:
48
+ continue
49
+ return best[0] if best else None
50
+
51
+ def is_local_ip(ip):
52
+ """فحص إذا كان IP محلي"""
53
+ return (
54
+ ip.startswith('192.168.') or
55
+ ip.startswith('10.') or
56
+ ip.startswith('172.') or
57
+ ip == '127.0.0.1'
58
+ )
59
+
60
+ def internet_available():
61
+ """فحص توفر الإنترنت"""
62
+ try:
63
+ socket.create_connection(("8.8.8.8", 53), timeout=3)
64
+ return True
65
+ except:
66
+ return False
67
+
68
+ while True:
69
+ peer = choose_peer()
70
+ if peer:
71
+ print(f"\n🛰️ إرسال إلى {peer}")
72
+ res = send(peer, "prime_calculation", 30000)
73
+ else:
74
+ print("\n⚙️ لا أقران؛ العمل محليّ على", socket.gethostname())
75
+ res = smart_tasks.prime_calculation(30000)
76
+ print("🔹 النتيجة (جزئية):", str(res)[:120])
77
+ time.sleep(10)
main.py ADDED
@@ -0,0 +1,247 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ main.py — نقطة تشغيل نظام OffloadHelper في ملف واحد
4
+ خيارات سطر الأوامر:
5
+ -s / --stats-interval ثواني بين كل طباعة لإحصائية الأقران (0 = مرة واحدة فقط)
6
+ --no-cli تشغيل بلا قائمة تفاعلية حتى مع وجود TTY
7
+ """
8
+ import os
9
+ import sys
10
+ import time
11
+ import threading
12
+ import subprocess
13
+ import logging
14
+ import argparse
15
+ from pathlib import Path
16
+ from typing import Any
17
+
18
+ from flask import Flask, request, jsonify
19
+
20
+ # ───────────────────── ضبط المسارات ──────────────────────
21
+ FILE = Path(__file__).resolve()
22
+ BASE_DIR = FILE.parent
23
+ PROJECT_ROOT = BASE_DIR.parent
24
+ for p in (BASE_DIR, PROJECT_ROOT):
25
+ sys.path.insert(0, str(p))
26
+
27
+ # ───────────────────── إعداد السجلات ─────────────────────
28
+ os.makedirs("logs", exist_ok=True)
29
+ logging.basicConfig(
30
+ level=logging.INFO,
31
+ format="%(asctime)s - %(levelname)s - %(message)s",
32
+ handlers=[
33
+ logging.StreamHandler(),
34
+ logging.FileHandler("logs/main.log", mode="a")
35
+ ]
36
+ )
37
+
38
+ # ─────────────── تحميل متغيرات البيئة (اختياري) ───────────────
39
+ try:
40
+ from dotenv import load_dotenv
41
+ load_dotenv()
42
+ logging.info("🔧 تم تحميل متغيرات البيئة من ‎.env")
43
+ except ImportError:
44
+ logging.warning("🔧 python-dotenv غير مثبَّت؛ تَخطّي .env")
45
+
46
+ # ─────────────── وحدات المشروع الداخلية ────────────────
47
+ try:
48
+ from peer_discovery import (
49
+ register_service_lan,
50
+ discover_lan_loop,
51
+ register_with_central,
52
+ fetch_central_loop,
53
+ PEERS
54
+ )
55
+ from your_tasks import matrix_multiply, prime_calculation, data_processing
56
+ from distributed_executor import DistributedExecutor
57
+ from peer_statistics import print_peer_statistics
58
+ except ImportError as e:
59
+ logging.error(f"❌ تعذّر استيراد وحدة: {e}")
60
+ sys.exit(1)
61
+
62
+ # ─────────────── ثابتات التهيئة ───────────────
63
+ CPU_PORT = int(os.getenv("CPU_PORT", "7520"))
64
+ SHARED_SECRET = os.getenv("SHARED_SECRET", "my_shared_secret_123")
65
+ PYTHON_EXE = sys.executable
66
+
67
+ # ─────────────── خيارات سطر الأوامر ───────────────
68
+ parser = argparse.ArgumentParser()
69
+ parser.add_argument(
70
+ "--stats-interval", "-s",
71
+ type=int,
72
+ default=0,
73
+ help="ثواني بين كل طباعة لإحصائية الأقران (0 = مرة واحدة فقط)"
74
+ )
75
+ parser.add_argument(
76
+ "--no-cli",
77
+ action="store_true",
78
+ help="تعطيل القائمة التفاعلية حتى عند وجود TTY"
79
+ )
80
+ args = parser.parse_args()
81
+
82
+ # ─────────────── خادم Flask البسيط ───────────────
83
+ flask_app = Flask(__name__)
84
+
85
+ @flask_app.route("/run_task", methods=["POST"])
86
+ def run_task_endpoint():
87
+ """اختبار: جمع عددين"""
88
+ data: dict[str, Any] | None = request.get_json(silent=True)
89
+ if not data:
90
+ return jsonify(error="No JSON received"), 400
91
+
92
+ if data.get("task") == "add":
93
+ a, b = data.get("a"), data.get("b")
94
+ if isinstance(a, (int, float)) and isinstance(b, (int, float)):
95
+ return jsonify(result=a + b)
96
+ return jsonify(error="Invalid task or parameters"), 400
97
+
98
+ def start_flask_server():
99
+ ip_public = os.getenv("PUBLIC_IP", "127.0.0.1")
100
+ logging.info(f"🌐 Flask متوفر على: http://{ip_public}:{CPU_PORT}/run_task")
101
+ flask_app.run(host="0.0.0.0", port=CPU_PORT, debug=False)
102
+
103
+ # ─────────────── خدمات خلفية محلية ───────────────
104
+ def start_services():
105
+ """peer_server و load_balancer"""
106
+ try:
107
+ subprocess.Popen([PYTHON_EXE, "peer_server.py", "--port", str(CPU_PORT)])
108
+ subprocess.Popen([PYTHON_EXE, "load_balancer.py"])
109
+ logging.info("✅ تم تشغيل الخدمات الخلفيّة")
110
+ except Exception as exc:
111
+ logging.error(f"❌ خطأ بتشغيل الخدمات الخلفية: {exc}")
112
+
113
+ # ─────────────── مهام مثالية محلية ───────────────
114
+ def example_task(x: int) -> int:
115
+ return x * x
116
+
117
+ def benchmark(fn, *args):
118
+ t0 = time.time()
119
+ res = fn(*args)
120
+ return time.time() - t0, res
121
+
122
+ # ─────────────── طباعة الإحصائية دوريًّا ─────────────
123
+ def stats_loop(interval: int, executor: DistributedExecutor):
124
+ while True:
125
+ peers_now = [
126
+ {"ip": host, "port": port}
127
+ for (host, port) in executor.peer_registry.get_all()
128
+ ]
129
+ print_peer_statistics(peers_now)
130
+ time.sleep(interval)
131
+
132
+ # ─────────────── القائمة التفاعلية CLI ─────────────
133
+ def menu(executor: DistributedExecutor):
134
+ tasks = {
135
+ "1": ("ضرب المصفوفات", matrix_multiply, 500),
136
+ "2": ("حساب الأعداد الأولية", prime_calculation, 100_000),
137
+ "3": ("معالجة البيانات", data_processing, 10_000),
138
+ "5": ("مهمة موزعة (مثال)", example_task, 42),
139
+ }
140
+
141
+ while True:
142
+ print("\n🚀 نظام توزيع المهام الذكي")
143
+ for k, (title, _, _) in tasks.items():
144
+ print(f"{k}: {title}")
145
+ print("q: خروج")
146
+ choice = input("اختر المهمة: ").strip().lower()
147
+
148
+ if choice == "q":
149
+ print("🛑 تم إنهاء البرنامج.")
150
+ break
151
+ if choice not in tasks:
152
+ print("⚠️ اختيار غير صحيح.")
153
+ continue
154
+
155
+ name, fn, arg = tasks[choice]
156
+ print(f"\nتشغيل: {name}…")
157
+
158
+ try:
159
+ if choice == "5":
160
+ logging.info("📡 إرسال المهمة إلى العقد الموزَّعة…")
161
+ future = executor.submit(fn, arg)
162
+ print(f"✅ النتيجة (موزعة): {future.result()}")
163
+ else:
164
+ dur, res = benchmark(fn, arg)
165
+ print(f"✅ النتيجة: {res}\n⏱️ الوقت: {dur:.3f} ث")
166
+ except Exception as exc:
167
+ print(f"❌ خطأ في تنفيذ المهمة: {exc}")
168
+
169
+ # ─────────────── الدالة الرئيسية ───────────────
170
+ def main():
171
+ # 1) خدمات back‑end
172
+ start_services()
173
+
174
+ # 2) مهيّئ الموزِّع
175
+ executor = DistributedExecutor(SHARED_SECRET)
176
+ executor.peer_registry.register_service("node_main", CPU_PORT)
177
+
178
+ # 3) إضافة الأقران المكتشفين
179
+ for peer_url in list(PEERS):
180
+ try:
181
+ host, port_str = peer_url.split("//")[1].split("/run")[0].split(":")
182
+ executor.peer_registry.register_service(
183
+ f"peer_{host.replace('.', '_')}",
184
+ int(port_str)
185
+ )
186
+ except Exception as exc:
187
+ logging.warning(f"⚠️ تخطّي peer ({peer_url}): {exc}")
188
+
189
+ # 4) طباعة أولية
190
+ initial_peers = [
191
+ {"ip": host, "port": int(port)}
192
+ for peer_url in PEERS
193
+ if (hp := peer_url.split("//")[1].split("/run")[0]).count(":") == 1
194
+ for host, port in [hp.split(":")]
195
+ ]
196
+ print_peer_statistics(initial_peers)
197
+
198
+ # 5) حلقة إحصائية دورية
199
+ if args.stats_interval > 0:
200
+ threading.Thread(
201
+ target=stats_loop,
202
+ args=(args.stats_interval, executor),
203
+ daemon=True
204
+ ).start()
205
+
206
+ logging.info("✅ النظام جاهز للعمل")
207
+
208
+ # 6) CLI إن توفر TTY ولم يُطلَب no-cli
209
+ if not args.no_cli and sys.stdin.isatty():
210
+ menu(executor)
211
+ else:
212
+ logging.info("ℹ️ القائمة التفاعلية معطّلة (no TTY أو --no-cli)")
213
+
214
+ # ─────────────── تشغيل البرنامج ───────────────
215
+ if __name__ == "__main__":
216
+ # Zeroconf
217
+ threading.Thread(target=register_service_lan, daemon=True).start()
218
+ threading.Thread(target=discover_lan_loop, daemon=True).start()
219
+
220
+ # خادم وسيط مركزي
221
+ register_with_central()
222
+ threading.Thread(target=fetch_central_loop, daemon=True).start()
223
+
224
+ # ماسح إنترنت (اختياري)
225
+ try:
226
+ from internet_scanner import internet_scanner
227
+ threading.Thread(
228
+ target=internet_scanner.start_continuous_scan,
229
+ daemon=True
230
+ ).start()
231
+ logging.info("🔍 بدء المسح المستمر للإنترنت")
232
+ except ImportError:
233
+ logging.warning("🔍 internet_scanner غير متوافر – تم التخطي")
234
+
235
+ # Flask
236
+ threading.Thread(target=start_flask_server, daemon=True).start()
237
+
238
+ # وحدة تحكم (اختياري)
239
+ try:
240
+ from your_control import control
241
+ control.start()
242
+ except ImportError:
243
+ logging.info("🛈 your_control غير متوفّر – تشغيل افتراضي")
244
+
245
+ # CLI / إحصائية
246
+ main()
247
+
offload_lib.py ADDED
@@ -0,0 +1,203 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ # offload_lib.py
3
+
4
+ import time
5
+ import math
6
+ import random
7
+ import psutil
8
+ import requests
9
+ import socket
10
+ from functools import wraps
11
+ from zeroconf import Zeroconf, ServiceBrowser
12
+ import logging
13
+
14
+ # إعداد السجل
15
+ logging.basicConfig(
16
+ level=logging.INFO,
17
+ format='%(asctime)s - %(levelname)s - %(message)s'
18
+ )
19
+
20
+ # إعدادات التحميل
21
+ MAX_CPU = 0.6 # عتبة استخدام CPU فقط
22
+
23
+ class PeerListener:
24
+ def __init__(self):
25
+ self.peers = []
26
+
27
+ def add_service(self, zc, type, name):
28
+ info = zc.get_service_info(type, name)
29
+ if info:
30
+ ip = socket.inet_ntoa(info.addresses[0])
31
+ self.peers.append(f"{ip}:{info.port}")
32
+ logging.info(f"🔗 جهاز مكتشف: {ip}:{info.port}")
33
+
34
+ def update_service(self, zc, type, name):
35
+ logging.debug(f"🔄 تم تحديث الخدمة: {name}")
36
+ pass # هنا فقط لتفادي التحذير
37
+
38
+ def discover_peers(timeout=1.5):
39
+ """اكتشاف الأجهزة المتاحة - أولوية LAN ثم WAN ثم الإنترنت مع فحص المشروع"""
40
+ import peer_discovery
41
+ from project_identifier import verify_project_compatibility
42
+
43
+ zc = Zeroconf()
44
+ listener = PeerListener()
45
+ ServiceBrowser(zc, "_http._tcp.local.", listener)
46
+ time.sleep(timeout)
47
+ zc.close()
48
+
49
+ lan_peers = []
50
+ wan_peers = []
51
+ internet_peers = []
52
+
53
+ for peer in listener.peers:
54
+ ip = peer.split(':')[0]
55
+ if verify_peer_project(ip):
56
+ if is_local_network(ip):
57
+ lan_peers.append(peer)
58
+ else:
59
+ wan_peers.append(peer)
60
+
61
+ all_discovered = list(peer_discovery.PEERS)
62
+ for peer_url in all_discovered:
63
+ peer_ip = peer_url.split("://")[1].split(":")[0]
64
+ if verify_peer_project(peer_ip):
65
+ if is_local_network(peer_ip):
66
+ if peer_url not in lan_peers:
67
+ lan_peers.append(peer_url)
68
+ else:
69
+ if peer_url not in wan_peers:
70
+ internet_peers.append(peer_url)
71
+
72
+ all_peers = lan_peers + wan_peers + internet_peers
73
+ logging.info(f"اكتُشف {len(all_peers)} جهاز DTS متوافق - LAN: {len(lan_peers)}, WAN: {len(wan_peers)}, Internet: {len(internet_peers)}")
74
+
75
+ return all_peers
76
+
77
+ def verify_peer_project(ip, port=7520):
78
+ """فحص إذا كان الجهاز يحتوي على نفس المشروع"""
79
+ try:
80
+ from project_identifier import verify_project_compatibility
81
+
82
+ project_url = f"http://{ip}:{port}/project_info"
83
+ response = requests.get(project_url, timeout=2)
84
+
85
+ if response.status_code == 200:
86
+ remote_info = response.json()
87
+ return verify_project_compatibility(remote_info)
88
+
89
+ except:
90
+ pass
91
+ return False
92
+
93
+ def is_local_network(ip):
94
+ """فحص إذا كان IP في الشبكة المحلية"""
95
+ try:
96
+ import ipaddress
97
+ addr = ipaddress.ip_address(ip)
98
+ return (
99
+ addr.is_private or
100
+ str(addr).startswith('192.168.') or
101
+ str(addr).startswith('10.') or
102
+ str(addr).startswith('172.')
103
+ )
104
+ except:
105
+ return False
106
+
107
+ def try_offload(peer, payload, max_retries=3):
108
+ """محاولة إرسال المهمة إلى جهاز آخر"""
109
+ url = f"http://{peer}/run"
110
+ for attempt in range(max_retries):
111
+ try:
112
+ response = requests.post(url, json=payload, timeout=10)
113
+ response.raise_for_status()
114
+ return response.json()
115
+ except Exception as e:
116
+ logging.warning(f"فشل المحاولة {attempt + 1} لـ {peer}: {str(e)}")
117
+ time.sleep(0.5 * (attempt + 1))
118
+ raise ConnectionError(f"فشل جميع المحاولات لـ {peer}")
119
+
120
+ def estimate_complexity(func, args, kwargs):
121
+ """تقدير تعقيد المهمة"""
122
+ if func.__name__ == "matrix_multiply":
123
+ return args[0] ** 2
124
+ elif func.__name__ == "prime_calculation":
125
+ return args[0] / 100
126
+ elif func.__name__ == "data_processing":
127
+ return args[0] / 10
128
+ elif func.__name__ == "image_processing_emulation":
129
+ return args[0] * 5
130
+ return 1 # قيمة افتراضية
131
+
132
+ def offload(func):
133
+ """ديكوراتور لتوزيع المهام"""
134
+ @wraps(func)
135
+ def wrapper(*args, **kwargs):
136
+ cpu = psutil.cpu_percent(interval=0.5) / 100.0
137
+ mem = psutil.virtual_memory().available / (1024**2)
138
+ complexity = estimate_complexity(func, args, kwargs)
139
+
140
+ logging.info(f"حمل النظام - CPU: {cpu:.2f}, الذاكرة: {mem:.1f}MB, تعقيد المهمة: {complexity}")
141
+
142
+ if complexity > 50 or cpu > MAX_CPU:
143
+ try:
144
+ peers = discover_peers()
145
+ if peers:
146
+ payload = {
147
+ "func": func.__name__,
148
+ "args": args,
149
+ "kwargs": kwargs,
150
+ "complexity": complexity
151
+ }
152
+ selected_peer = random.choice(peers)
153
+ logging.info(f"إرسال المهمة إلى {selected_peer}")
154
+ return try_offload(selected_peer, payload)
155
+ except Exception as e:
156
+ logging.error(f"خطأ في التوزيع: {str(e)}")
157
+
158
+ logging.info("تنفيذ المهمة محلياً")
159
+ return func(*args, **kwargs)
160
+ return wrapper
161
+
162
+ # المهام القابلة للتوزيع:
163
+
164
+ @offload
165
+ def matrix_multiply(size):
166
+ """ضرب مصفوفتين عشوائيتين بالحجم"""
167
+ import numpy as np
168
+ A = np.random.rand(size, size)
169
+ B = np.random.rand(size, size)
170
+ return np.dot(A, B).tolist()
171
+
172
+ @offload
173
+ def prime_calculation(n):
174
+ """حساب الأعداد الأولية"""
175
+ primes = []
176
+ for num in range(2, n + 1):
177
+ is_prime = True
178
+ for i in range(2, int(math.sqrt(num)) + 1):
179
+ if num % i == 0:
180
+ is_prime = False
181
+ break
182
+ if is_prime:
183
+ primes.append(num)
184
+ return {"primes_count": len(primes), "primes": primes}
185
+
186
+ @offload
187
+ def data_processing(data_size):
188
+ """معالجة بيانات كبيرة"""
189
+ processed_data = []
190
+ for i in range(data_size):
191
+ result = sum(math.sin(x) * math.cos(x) for x in range(i, i + 100))
192
+ processed_data.append(result)
193
+ return {"processed_items": len(processed_data)}
194
+
195
+ @offload
196
+ def image_processing_emulation(iterations):
197
+ """محاكاة معالجة الصور"""
198
+ results = []
199
+ for i in range(iterations):
200
+ fake_processing = sum(math.sqrt(x) for x in range(i * 100, (i + 1) * 100))
201
+ results.append(fake_processing)
202
+ time.sleep(0.01)
203
+ return {"iterations": iterations, "results": results}
peer_discovery.py ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ import os
3
+ import socket
4
+ import threading
5
+ import time
6
+ import logging
7
+
8
+ import requests
9
+ from zeroconf import Zeroconf, ServiceInfo, ServiceBrowser
10
+
11
+ # 👇 إعداد الـ peer discovery عبر LAN وInternet
12
+ SERVICE = "_tasknode._tcp.local."
13
+ PORT = int(os.getenv("CPU_PORT", "7520"))
14
+ PEERS = set() # مجموعة URLs للأقران (/run)
15
+
16
+ # 🌐 خادم وسيط مركزي (Central Registry)
17
+ CENTRAL_REGISTRY_URL = "https://cv4790811.regru.cloud"
18
+
19
+ # 🟢 دالة لحساب IP العام أو المحلي
20
+ # تستخدم HTTP API للحصول على IP عام ثم fallback إلى LAN
21
+
22
+ def get_local_ip():
23
+ # حاول الحصول على IP عام
24
+ try:
25
+ r = requests.get("https://api.ipify.org?format=json", timeout=3)
26
+ r.raise_for_status()
27
+ data = r.json()
28
+ return data.get("ip", "127.0.0.1")
29
+ except Exception:
30
+ # fallback إلى LAN IP
31
+ try:
32
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
33
+ s.connect(("8.8.8.8", 80))
34
+ return s.getsockname()[0]
35
+ except Exception:
36
+ return "127.0.0.1"
37
+ finally:
38
+ try:
39
+ s.close()
40
+ except Exception:
41
+ pass
42
+
43
+ # ❶ تسجيل الخدمة في شبكة LAN عبر Zeroconf
44
+ # للحفاظ على قدرة اكتشاف peers في نفس الشبكة المحلية
45
+ def register_service_lan():
46
+ zc = Zeroconf()
47
+ local_ip = get_local_ip()
48
+ info = ServiceInfo(
49
+ SERVICE,
50
+ f"{socket.gethostname()}.{SERVICE}",
51
+ addresses=[socket.inet_aton(local_ip)],
52
+ port=PORT,
53
+ properties={b'load': b'0'}
54
+ )
55
+ try:
56
+ zc.register_service(info)
57
+ print(f"✅ LAN service registered: {local_ip}:{PORT}")
58
+ except Exception as e:
59
+ print(f"❌ LAN registration failed: {e}")
60
+
61
+ # ❷ مستمع لاكتشاف أجهزة LAN عبر Zeroconf
62
+ class Listener:
63
+ def add_service(self, zc, t, name):
64
+ info = zc.get_service_info(t, name)
65
+ if info and info.addresses:
66
+ ip = socket.inet_ntoa(info.addresses[0])
67
+ peer_url = f"http://{ip}:{info.port}/run"
68
+ if peer_url not in PEERS:
69
+ PEERS.add(peer_url)
70
+ print(f"🔗 LAN peer discovered: {peer_url}")
71
+ def update_service(self, zc, t, name):
72
+ self.add_service(zc, t, name)
73
+ def remove_service(self, zc, t, name):
74
+ print(f"❌ LAN peer removed: {name}")
75
+
76
+ # حلقة اكتشاف LAN مستمرة
77
+ def discover_lan_loop():
78
+ zc = Zeroconf()
79
+ ServiceBrowser(zc, SERVICE, Listener())
80
+ print(f"🔍 Started LAN discovery for {SERVICE}")
81
+ while True:
82
+ time.sleep(5)
83
+
84
+ # ❸ تسجيل العقدة في الخادم المركزي
85
+ # ترسل بياناتها إلى /register وتضيف باقي الأقران
86
+ def register_with_central():
87
+ node_id = os.getenv("NODE_ID", socket.gethostname())
88
+ info = {"node_id": node_id, "ip": get_local_ip(), "port": PORT}
89
+ try:
90
+ resp = requests.post(f"{CENTRAL_REGISTRY_URL}/register", json=info, timeout=5)
91
+ resp.raise_for_status()
92
+ peers_list = resp.json()
93
+ for p in peers_list:
94
+ peer_url = f"http://{p['ip']}:{p['port']}/run"
95
+ if peer_url not in PEERS:
96
+ PEERS.add(peer_url)
97
+ print(f"🌐 Registered and discovered central peer: {peer_url}")
98
+ except Exception as e:
99
+ print(f"❌ Central registration failed: {e}")
100
+
101
+ # ❹ مزامنة الأقران من الخادم المركزي بشكل دوري
102
+ # تُحدّث مجموعة PEERS كل 5 دقائق عن طريق /peers endpoint
103
+ def fetch_central_loop():
104
+ print("🔄 Central registry sync loop started")
105
+ while True:
106
+ try:
107
+ resp = requests.get(f"{CENTRAL_REGISTRY_URL}/peers", timeout=5)
108
+ resp.raise_for_status()
109
+ peers_list = resp.json()
110
+ for p in peers_list:
111
+ peer_url = f"http://{p['ip']}:{p['port']}/run"
112
+ if peer_url not in PEERS:
113
+ PEERS.add(peer_url)
114
+ print(f"🌐 Central peer discovered: {peer_url}")
115
+ except Exception as e:
116
+ print(f"⚠️ Fetch central peers failed: {e}")
117
+ time.sleep(300)
118
+
119
+ # 🚀 دالة الإدخال الرئيسيّة
120
+ def main():
121
+ logging.basicConfig(level=logging.INFO)
122
+ print("🚀 Peer Discovery System starting...")
123
+
124
+ # Zeroconf LAN registration & discovery
125
+ threading.Thread(target=register_service_lan, daemon=True).start()
126
+ threading.Thread(target=discover_lan_loop, daemon=True).start()
127
+
128
+ # التسجيل في الخادم الوسيط ومزامنة الأقران
129
+ register_with_central()
130
+ threading.Thread(target=fetch_central_loop, daemon=True).start()
131
+
132
+ # إبقاء السكربت قيد التشغيل
133
+ try:
134
+ while True:
135
+ time.sleep(60)
136
+ except KeyboardInterrupt:
137
+ print("🛑 Exiting...")
138
+
139
+ if __name__ == "__main__":
140
+ main()
peer_registry.py ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import socket
2
+ import time
3
+ from zeroconf import Zeroconf, ServiceBrowser, ServiceInfo
4
+
5
+ class Listener:
6
+ def __init__(self):
7
+ self.peers = []
8
+
9
+ def add_service(self, zc, type_, name):
10
+ info = zc.get_service_info(type_, name)
11
+ if info:
12
+ ip = socket.inet_ntoa(info.addresses[0])
13
+ peer_data = {
14
+ 'ip': ip,
15
+ 'port': info.port,
16
+ 'load': float(info.properties.get(b'load', 0)),
17
+ 'node_id': info.properties.get(b'node_id', b'unknown').decode(),
18
+ 'last_seen': time.time()
19
+ }
20
+ if peer_data not in self.peers:
21
+ self.peers.append(peer_data)
22
+
23
+ def update_service(self, zc, type_, name):
24
+ """مطلوب بواسطة Zeroconf"""
25
+ self.add_service(zc, type_, name)
26
+
27
+ def remove_service(self, zc, type_, name):
28
+ """اختياري"""
29
+ pass
30
+
31
+ def register_service(ip: str, port: int, load: float = 0.0):
32
+ zc = Zeroconf()
33
+ service_name = f"{socket.gethostname()}-{int(time.time())}._tasknode._tcp.local."
34
+ service_info = ServiceInfo(
35
+ "_tasknode._tcp.local.",
36
+ service_name,
37
+ addresses=[socket.inet_aton(ip)],
38
+ port=port,
39
+ properties={
40
+ b'load': str(load).encode(),
41
+ b'node_id': socket.gethostname().encode()
42
+ }
43
+ )
44
+ zc.register_service(service_info)
45
+ print(f"✅ Service registered: {service_name} @ {ip}:{port}")
46
+ return zc # أبقِ المرجع حياً
47
+
48
+ def discover_peers(timeout=2):
49
+ zc = Zeroconf()
50
+ listener = Listener()
51
+ ServiceBrowser(zc, "_tasknode._tcp.local.", listener)
52
+ time.sleep(timeout)
53
+ zc.close()
54
+ return listener.peers
55
+
56
+ if __name__ == "__main__":
57
+ local_ip = socket.gethostbyname(socket.gethostname())
58
+ port = 7520
59
+
60
+ zc = register_service(local_ip, port, load=0.1)
61
+
62
+ peers = discover_peers()
63
+ print("✅ Available peers:", peers)
64
+
65
+ input("🔵 Press Enter to exit...\n")
66
+ zc.close()
67
+
peer_server.py ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # peer_server.py
2
+
3
+ from flask import Flask, request, jsonify # استيراد request و jsonify مع Flask
4
+ import psutil
5
+ import smart_tasks
6
+ import time
7
+ import socket
8
+ import peer_discovery # إذا كان يستخدم لاحقًا
9
+
10
+ app = Flask(__name__) # إنشاء التطبيق
11
+
12
+ @app.route("/cpu")
13
+ def cpu():
14
+ # يعيد نسبة استخدام المعالج
15
+ return jsonify(usage=psutil.cpu_percent(interval=0.3))
16
+
17
+ @app.route("/run", methods=["POST"])
18
+ def run():
19
+ data = request.get_json(force=True)
20
+ fn_name = data.get("func")
21
+ fn = getattr(smart_tasks, fn_name, None)
22
+ if not fn:
23
+ return jsonify(error="function-not-found"), 404
24
+ try:
25
+ start = time.time()
26
+ result = fn(*data.get("args", []), **data.get("kwargs", {}))
27
+ return jsonify(
28
+ result=result,
29
+ host=socket.gethostname(),
30
+ took=round(time.time() - start, 3)
31
+ )
32
+ except Exception as e:
33
+ return jsonify(error=str(e)), 500
34
+
35
+ if __name__ == "__main__": # التصحيح هنا
36
+ app.run(host="0.0.0.0", port=7520)
37
+
peer_statistics.py ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from collections import Counter
2
+ import ipaddress
3
+
4
+ def print_peer_statistics(discovered_peers):
5
+ ips = [peer['ip'] for peer in discovered_peers]
6
+ ip_counts = Counter(ips)
7
+
8
+ def classify_ip(ip):
9
+ try:
10
+ ip_obj = ipaddress.ip_address(ip)
11
+ if ip_obj.is_private:
12
+ return 'داخلي'
13
+ else:
14
+ return 'خارجي'
15
+ except ValueError:
16
+ return 'محلي'
17
+
18
+ print("\n📊 إحصائية عدد الأجهزة حسب النوع:\n")
19
+ for ip, count in ip_counts.items():
20
+ category = classify_ip(ip)
21
+ print(f"• {ip} ({category}): {count} جهاز")
processor_manager.py ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # processor_manager.py
2
+
3
+ import psutil
4
+ from collections import deque
5
+ import logging
6
+
7
+ logging.basicConfig(level=logging.INFO)
8
+
9
+ class ResourceMonitor:
10
+ def __init__(self):
11
+ self.cpu_history = deque(maxlen=10)
12
+ self.mem_history = deque(maxlen=10)
13
+ # حد استقبال المهمات الآن 40% CPU بدل 30%
14
+ self.receive_cpu_threshold = 0.40
15
+
16
+ def current_load(self):
17
+ cpu = psutil.cpu_percent(interval=0.5) / 100.0 # كنسبة (0.0 - 1.0)
18
+ mem = psutil.virtual_memory().available / (1024**2) # متاح بالـ MB
19
+
20
+ self.cpu_history.append(cpu)
21
+ self.mem_history.append(mem)
22
+
23
+ avg_cpu = sum(self.cpu_history) / len(self.cpu_history)
24
+ avg_mem = sum(self.mem_history) / len(self.mem_history)
25
+
26
+ logging.info(f"Instant CPU: {cpu:.2%}, Instant MEM: {mem:.1f}MB")
27
+ logging.info(f"Avg CPU: {avg_cpu:.2%}, Avg MEM: {avg_mem:.1f}MB")
28
+
29
+ recommendation = "offload" if (avg_cpu > 0.7 or avg_mem < 2048) else "local"
30
+ can_receive = avg_cpu <= self.receive_cpu_threshold
31
+
32
+ return {
33
+ "instant": {"cpu": cpu, "mem": mem},
34
+ "average": {"cpu": avg_cpu, "mem": avg_mem},
35
+ "recommendation": recommendation,
36
+ "can_receive": can_receive
37
+ }
38
+
39
+ def trigger_offload():
40
+ """عملية توزيع المهام التجريبية"""
41
+ print("⚠️ تم استدعاء توزيع المهام (اختباري)")
42
+
43
+ def should_offload(task_complexity=0):
44
+ monitor = ResourceMonitor()
45
+ status = monitor.current_load()
46
+
47
+ avg_cpu = status['average']['cpu']
48
+ avg_mem = status['average']['mem']
49
+
50
+ if avg_cpu > 0.6 or avg_mem < 2048 or task_complexity > 75:
51
+ trigger_offload()
52
+ return True
53
+
54
+ return False
55
+
56
+ def can_receive_task():
57
+ """
58
+ يعيد True إذا كان بالإمكان استقبال مهمة جديدة،
59
+ أي عندما يكون متوسط استهلاك الـ CPU ≤ 40%.
60
+ """
61
+ return ResourceMonitor().current_load()["can_receive"]
62
+
63
+ if __name__ == "__main__":
64
+ status = ResourceMonitor().current_load()
65
+ if not status["can_receive"]:
66
+ print(f"🚫 لا يمكن استقبال مهام جديدة (Avg CPU: {status['average']['cpu']:.0%})")
67
+ else:
68
+ print(f"✅ يمكن استقبال مهام جديدة (Avg CPU: {status['average']['cpu']:.0%})")
69
+
70
+ if should_offload(80):
71
+ print("💡 ينصح بتوزيع المهمة")
72
+ else:
73
+ print("✅ يمكن تنفيذ المهمة محلياً")
project_identifier.py ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ """
3
+ project_identifier.py - معرف المشروع للتحقق من الهوية
4
+ """
5
+ import json
6
+ from flask import jsonify
7
+
8
+ PROJECT_INFO = {
9
+ "project_name": "distributed-task-system",
10
+ "version": "1.0",
11
+ "description": "نظام توزيع المهام الذكي",
12
+ "author": "DTS Team",
13
+ "features": [
14
+ "matrix_multiply",
15
+ "prime_calculation",
16
+ "data_processing",
17
+ "video_processing",
18
+ "live_streaming",
19
+ "enhanced_ai"
20
+ ],
21
+ "signature": "DTS_2024_SMART_DISTRIBUTION"
22
+ }
23
+
24
+ def get_project_info():
25
+ """إرجاع معلومات المشروع"""
26
+ return PROJECT_INFO
27
+
28
+ def verify_project_compatibility(remote_info):
29
+ """التحقق من توافق المشروع مع جهاز آخر"""
30
+ if not isinstance(remote_info, dict):
31
+ return False
32
+
33
+ return (
34
+ remote_info.get("project_name") == PROJECT_INFO["project_name"] and
35
+ remote_info.get("version") == PROJECT_INFO["version"] and
36
+ remote_info.get("signature") == PROJECT_INFO["signature"]
37
+ )
38
+
39
+ def create_project_endpoint():
40
+ """إنشاء endpoint لمعلومات المشروع"""
41
+ return jsonify(PROJECT_INFO)
quick_connection_test.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ #!/usr/bin/env python3
3
+ # اختبار سريع للتحقق من حالة النظام
4
+
5
+ import requests
6
+ import time
7
+ import json
8
+ from offload_lib import discover_peers, matrix_multiply
9
+
10
+ def test_connection():
11
+ """اختبار سريع للاتصال"""
12
+ print("🚀 اختبار اتصال سريع...")
13
+
14
+ # 1. فحص الخادم المحلي
15
+ try:
16
+ response = requests.get("http://localhost:7520/health", timeout=3)
17
+ if response.status_code == 200:
18
+ print("✅ الخادم المحلي يعمل")
19
+ else:
20
+ print("❌ مشكلة في الخادم المحلي")
21
+ return False
22
+ except:
23
+ print("❌ الخادم المحلي غير متاح")
24
+ return False
25
+
26
+ # 2. اختبار اكتشاف الأجهزة
27
+ print("🔍 البحث عن الأجهزة...")
28
+ peers = discover_peers(timeout=2)
29
+ print(f"📱 تم اكتشاف {len(peers)} جهاز")
30
+
31
+ # 3. اختبار مهمة بسيطة
32
+ print("⚙️ اختبار مهمة بسيطة...")
33
+ start_time = time.time()
34
+ try:
35
+ result = matrix_multiply(5)
36
+ duration = time.time() - start_time
37
+ print(f"✅ تمت المعالجة في {duration:.2f} ثانية")
38
+ print(f"📊 النتيجة: مصفوفة {len(result)}x{len(result[0])}")
39
+ return True
40
+ except Exception as e:
41
+ print(f"❌ فشل في المعالجة: {e}")
42
+ return False
43
+
44
+ if __name__ == "__main__":
45
+ if test_connection():
46
+ print("\n🎉 النظام يعمل بشكل جيد!")
47
+ print("💡 يمكنك الآن تشغيل: python test_distributed_system.py")
48
+ else:
49
+ print("\n⚠️ هناك مشاكل تحتاج إصلاح")
quick_test.py ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ #!/usr/bin/env python3
3
+ # quick_test.py - اختبار سريع لنظام التوزيع
4
+
5
+ import requests
6
+ import time
7
+ from offload_lib import discover_peers
8
+
9
+ def quick_connectivity_test():
10
+ """اختبار سريع للاتصال والتوزيع"""
11
+ print("🚀 اختبار سريع لنظام التوزيع")
12
+ print("-" * 40)
13
+
14
+ # 1. اكتشاف الأجهزة
15
+ print("🔍 البحث عن الأجهزة...")
16
+ peers = discover_peers(timeout=2)
17
+
18
+ if not peers:
19
+ print("❌ لم يتم العثور على أجهزة أخرى")
20
+ return False
21
+
22
+ print(f"✅ تم العثور على {len(peers)} جهاز:")
23
+ for peer in peers:
24
+ print(f" 📱 {peer}")
25
+
26
+ # 2. اختبار الاتصال السريع
27
+ working_peers = []
28
+ for peer in peers:
29
+ try:
30
+ response = requests.get(f"{peer}/health", timeout=3)
31
+ if response.status_code == 200:
32
+ working_peers.append(peer)
33
+ print(f"✅ {peer} - متصل ويعمل")
34
+ else:
35
+ print(f"⚠️ {peer} - يستجيب لكن بخطأ")
36
+ except:
37
+ print(f"❌ {peer} - غير متصل")
38
+
39
+ if not working_peers:
40
+ print("❌ لا توجد أجهزة تعمل بشكل صحيح")
41
+ return False
42
+
43
+ # 3. اختبار إرسال مهمة بسيطة
44
+ print(f"\n📡 اختبار إرسال مهمة إلى {working_peers[0]}...")
45
+
46
+ task = {
47
+ "func": "matrix_multiply",
48
+ "args": [5],
49
+ "kwargs": {}
50
+ }
51
+
52
+ try:
53
+ start_time = time.time()
54
+ response = requests.post(f"{working_peers[0]}/run", json=task, timeout=10)
55
+ duration = time.time() - start_time
56
+
57
+ if response.status_code == 200:
58
+ result = response.json()
59
+ print(f"✅ تمت المعالجة بنجاح في {duration:.2f} ثانية")
60
+ print(f"📊 النتيجة: تم ضرب مصفوفة 5x5")
61
+ return True
62
+ else:
63
+ print(f"❌ فشل في المعالجة - كود الخطأ: {response.status_code}")
64
+ return False
65
+
66
+ except Exception as e:
67
+ print(f"❌ خطأ في الإرسال: {str(e)}")
68
+ return False
69
+
70
+ if __name__ == "__main__":
71
+ success = quick_connectivity_test()
72
+
73
+ if success:
74
+ print("\n🎉 النظام يعمل بشكل صحيح!")
75
+ print("💡 يمكنك الآن تشغيل الاختبار الشامل: python test_distributed_system.py")
76
+ else:
77
+ print("\n⚠️ هناك مشاكل في النظام، تحقق من:")
78
+ print(" 1. تشغيل الخادم على الأجهزة الأخرى")
79
+ print(" 2. الاتصال بالشبكة")
80
+ print(" 3. إعدادات الجدار الناري")
remote_executor.py ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # remote_executor.py (مُحدَّث: يدعم التشفير والتوقيع واختيار السيرفر ديناميكياً)
2
+ # ============================================================
3
+ # يرسل المهمّة إلى سيرفر RPC خارجي مع تشفير + توقيع،
4
+ # أو يعمل بوضع JSON صافٍ لو لم يكن SecurityManager مفعَّل.
5
+ # يستخدم قائمة الأقران المكتشفة لاختيار الـ endpoint بدل IP ثابت.
6
+ # ============================================================
7
+
8
+ import requests
9
+ import json
10
+ import os
11
+ from typing import Any
12
+
13
+ # قائمة الأقران (URLs) المستخرجة من peer_discovery
14
+ from peer_discovery import PEERS
15
+
16
+ # عنوان افتراضي احتياطي (يمكن تغييره بمتغير بيئي REMOTE_SERVER)
17
+ FALLBACK_SERVER = os.getenv(
18
+ "REMOTE_SERVER",
19
+ "http://89.111.171.92:7520/run"
20
+ )
21
+
22
+ # محاولة استيراد SecurityManager (اختياري)
23
+ try:
24
+ from security_layer import SecurityManager
25
+ security = SecurityManager(os.getenv("SHARED_SECRET", "my_shared_secret_123"))
26
+ SECURITY_ENABLED = True
27
+ except ImportError:
28
+ security = None
29
+ SECURITY_ENABLED = False
30
+
31
+
32
+ def _choose_remote_server() -> str:
33
+ """
34
+ يختار عنوان السيرفر الذي سترسل إليه المهمة:
35
+ 1) إذا عُيّن متغير بيئي REMOTE_SERVER، يُستخدم.
36
+ 2) وإلا إذا اكتشفنا أقران عبر LAN/Internet، نأخذ أولهم.
37
+ 3) وإلا نعود إلى FALLBACK_SERVER.
38
+ """
39
+ env_url = os.getenv("REMOTE_SERVER")
40
+ if env_url:
41
+ return env_url.rstrip('/') + '/run'
42
+ # PEERS يحوي عناوين كاملة من نوع http://ip:port/run
43
+ if PEERS:
44
+ # نختار الحد الأدنى من التحميل (اختياري) أو أول عنصر
45
+ # هنا ببساطة نأخذ أول URL
46
+ return next(iter(PEERS))
47
+ # استخدام الافتراضي
48
+ return FALLBACK_SERVER.rstrip('/') + '/run'
49
+
50
+
51
+ def execute_remotely(
52
+ func_name: str,
53
+ args: list[Any] | None = None,
54
+ kwargs: dict[str, Any] | None = None
55
+ ) -> Any:
56
+ """إرسال استدعاء دالة إلى الخادم البعيد وإرجاع النتيجة."""
57
+ if args is None:
58
+ args = []
59
+ if kwargs is None:
60
+ kwargs = {}
61
+
62
+ task = {
63
+ "func": func_name,
64
+ "args": args,
65
+ "kwargs": kwargs,
66
+ "sender_id": "client_node"
67
+ }
68
+
69
+ # اختيار السيرفر الصحيح ديناميكياً
70
+ target_url = _choose_remote_server()
71
+
72
+ try:
73
+ if SECURITY_ENABLED:
74
+ # 1) وقّع المهمة ثم شفّرها
75
+ signed_task = security.sign_task(task)
76
+ encrypted = security.encrypt_data(json.dumps(signed_task).encode())
77
+
78
+ headers = {
79
+ "X-Signature": security.signature_hex,
80
+ "Content-Type": "application/octet-stream"
81
+ }
82
+ payload = encrypted # خام ثنائي
83
+ resp = requests.post(
84
+ target_url,
85
+ headers=headers,
86
+ data=payload,
87
+ timeout=15
88
+ )
89
+ else:
90
+ # وضع التطوير: أرسل JSON صريح
91
+ headers = {"Content-Type": "application/json"}
92
+ resp = requests.post(
93
+ target_url,
94
+ headers=headers,
95
+ json=task,
96
+ timeout=15
97
+ )
98
+
99
+ resp.raise_for_status()
100
+ data = resp.json()
101
+ return data.get("result", "⚠️ لا يوجد نتيجة")
102
+
103
+ except Exception as e:
104
+ return f"❌ فشل التنفيذ البعيد على {target_url}: {e}"
rpc_server.py ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # rpc_server.py (مُحدَّث بحيث يدعم التشفير الاختياري)
2
+ # ============================================================
3
+ # خادِم يستقبل مهام عن بُعد:
4
+ # • إن وصلته بيانات خام (Encrypted) في Body → يفك تشفيرها ويتحقق من التوقيع.
5
+ # • وإلا إن وصل JSON خام في Content‑Type: application/json → ينفّذ مباشرة (وضع تطويـر).
6
+ # ============================================================
7
+
8
+ from flask import Flask, request, jsonify
9
+ import smart_tasks # «your_tasks» تمّ استيراده تحت هذا الاسم فى main.py
10
+ import logging, json
11
+ from security_layer import SecurityManager
12
+
13
+ SECURITY = SecurityManager("my_shared_secret_123")
14
+
15
+ logging.basicConfig(
16
+ filename="server.log",
17
+ level=logging.INFO,
18
+ format="%(asctime)s - %(levelname)s - %(message)s"
19
+ )
20
+
21
+ app = Flask(name)
22
+
23
+ # ------------------------------------------------------------------
24
+ @app.route("/health")
25
+ def health():
26
+ return jsonify(status="ok")
27
+
28
+ # ------------------------------------------------------------------
29
+ @app.route("/run", methods=["POST"])
30
+ def run():
31
+ try:
32
+ # 1) حاول قراءة كـ JSON مباشر (وضع التطويـر)
33
+ if request.is_json:
34
+ data = request.get_json()
35
+ else:
36
+ # 2) وإلا اعتبره Payload مُشفَّر (وضع الإنتاج)
37
+ encrypted = request.get_data()
38
+ try:
39
+ decrypted = SECURITY.decrypt_data(encrypted)
40
+ data = json.loads(decrypted.decode())
41
+ except Exception as e:
42
+ logging.error(f"⚠️ فشل فك التشفير: {e}")
43
+ return jsonify(error="Decryption failed"), 400
44
+
45
+ # 3) التحقّق من التوقيع إن وُجد
46
+ if "_signature" in data:
47
+ if not SECURITY.verify_task(data):
48
+ logging.warning("❌ توقيع غير صالح")
49
+ return jsonify(error="Invalid signature"), 403
50
+ # أزل عناصر موقّعة إضافية
51
+ data = {k: v for k, v in data.items() if k not in ("_signature", "sender_id")}
52
+
53
+ func_name = data.get("func")
54
+ args = data.get("args", [])
55
+ kwargs = data.get("kwargs", {})
56
+
57
+ fn = getattr(smart_tasks, func_name, None)
58
+ if not fn:
59
+ logging.warning(f"❌ لم يتم العثور على الدالة: {func_name}")
60
+ return jsonify(error="Function not found"), 404
61
+
62
+ logging.info(f"⚙️ تنفيذ الدالة: {func_name} من جهاز آخر")
63
+ result = fn(*args, **kwargs)
64
+ return jsonify(result=result)
65
+
66
+ except Exception as e:
67
+ logging.error(f"🔥 خطأ أثناء تنفيذ المهمة: {str(e)}")
68
+ return jsonify(error=str(e)), 500
69
+
70
+ # ------------------------------------------------------------------
71
+ if name == "main":
72
+ # تأكد أن المنفذ 7520 مفتوح
73
+ app.run(host="0.0.0.0", port=7520)
security_layer.py ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # security_layer.py (مُحدَّث)
2
+ # ============================================================
3
+ # إدارة التشفير والتوقيع وتبادل المفاتيح بين العقد
4
+ # ============================================================
5
+
6
+ from cryptography.hazmat.primitives import hashes, serialization
7
+ from cryptography.hazmat.primitives.asymmetric import rsa, padding
8
+ from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
9
+ from cryptography.fernet import Fernet
10
+ import os, base64, json
11
+ from typing import Dict
12
+
13
+
14
+ class SecurityManager:
15
+ """طبقة أمان موحّدة لكل العقد."""
16
+
17
+ def __init__(self, shared_secret: str):
18
+ # مفتاح متماثل لاستخدام Fernet
19
+ self._key = self._derive_key(shared_secret)
20
+ self._cipher = Fernet(self._key)
21
+
22
+ # زوج مفاتيح غير متماثل للتوقيع الرقمي
23
+ self._private_key = rsa.generate_private_key(
24
+ public_exponent=65537,
25
+ key_size=2048,
26
+ )
27
+ self._public_pem = (
28
+ self._private_key.public_key()
29
+ .public_bytes(
30
+ encoding=serialization.Encoding.PEM,
31
+ format=serialization.PublicFormat.SubjectPublicKeyInfo,
32
+ )
33
+ .decode()
34
+ )
35
+ # مفاتيح العقد الأخرى {peer_id: public_key_obj}
36
+ self._peer_keys: Dict[str, rsa.RSAPublicKey] = {}
37
+
38
+ # ------------------------------------------------------------
39
+ # تشفير / فك تشفير متماثل
40
+ # ------------------------------------------------------------
41
+ def encrypt_data(self, data: bytes) -> bytes:
42
+ return self._cipher.encrypt(data)
43
+
44
+ def decrypt_data(self, encrypted: bytes) -> bytes:
45
+ return self._cipher.decrypt(encrypted)
46
+
47
+ # ------------------------------------------------------------
48
+ # توقيع/تحقّق رقمي غير متماثل
49
+ # ------------------------------------------------------------
50
+ def sign_task(self, task: Dict) -> Dict:
51
+ """يُرجع نسخة موقّعة من الـtask مضافًا إليها المفتاح العام والمعرّف."""
52
+ signature = self._private_key.sign(
53
+ json.dumps(task, separators=(",", ":")).encode(),
54
+ padding.PSS(
55
+ mgf=padding.MGF1(hashes.SHA256()),
56
+ salt_length=padding.PSS.MAX_LENGTH,
57
+ ),
58
+ hashes.SHA256(),
59
+ )
60
+ task_signed = task.copy()
61
+ task_signed.update(
62
+ {
63
+ "_signature": base64.b64encode(signature).decode(),
64
+ "sender_id": os.getenv("NODE_ID", "unknown"),
65
+ "sender_key": self._public_pem,
66
+ }
67
+ )
68
+ return task_signed
69
+
70
+ def verify_task(self, signed_task: Dict) -> bool:
71
+ """يتحقق من صحة التوقيع باستخدام المفتاح العام للمرسل."""
72
+ if "_signature" not in signed_task or "sender_id" not in signed_task:
73
+ return False
74
+ sig = base64.b64decode(signed_task["_signature"])
75
+ task_copy = {k: v for k, v in signed_task.items() if k not in {"_signature", "sender_key"}}
76
+
77
+ peer_id = signed_task["sender_id"]
78
+ if peer_id not in self._peer_keys:
79
+ # حاول إضافة المفتاح المرسل إن وجد
80
+ if "sender_key" in signed_task:
81
+ self.add_peer_key(peer_id, signed_task["sender_key"])
82
+ else:
83
+ return False
84
+ try:
85
+ self._peer_keys[peer_id].verify(
86
+ sig,
87
+ json.dumps(task_copy, separators=(",", ":")).encode(),
88
+ padding.PSS(
89
+ mgf=padding.MGF1(hashes.SHA256()),
90
+ salt_length=padding.PSS.MAX_LENGTH,
91
+ ),
92
+ hashes.SHA256(),
93
+ )
94
+ return True
95
+ except Exception:
96
+ return False
97
+
98
+ # ------------------------------------------------------------
99
+ # إدارة المفاتيح العامة للأقران
100
+ # ------------------------------------------------------------
101
+ def add_peer_key(self, peer_id: str, public_key_pem: str):
102
+ """تخزين/تحديث المفتاح العام لعقدة أخرى."""
103
+ self._peer_keys[peer_id] = serialization.load_pem_public_key(
104
+ public_key_pem.encode()
105
+ )
106
+
107
+ # ------------------------------------------------------------
108
+ # أدوات داخلية
109
+ # ------------------------------------------------------------
110
+ @staticmethod
111
+ def _derive_key(password: str) -> bytes:
112
+ salt = b"nora_salt_2025" # ◀️ عدِّل في الإنتاج
113
+ kdf = PBKDF2HMAC(
114
+ algorithm=hashes.SHA256(),
115
+ length=32,
116
+ salt=salt,
117
+ iterations=150_000,
118
+ )
119
+ return base64.urlsafe_b64encode(kdf.derive(password.encode()))
120
+
server.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, request, jsonify
2
+ from flask_cors import CORS
3
+ import json
4
+ from your_tasks import *
5
+ from project_identifier import create_project_endpoint, get_project_info
6
+ import logging
7
+
8
+ app = Flask(__name__)
9
+ CORS(app)
10
+
11
+ @app.route('/multiply', methods=['POST'])
12
+ def multiply():
13
+ try:
14
+ data = request.get_json()
15
+ a = data.get("a", 0)
16
+ b = data.get("b", 0)
17
+ result_dict = multiply_task(a, b) # دالة offload
18
+ return jsonify({"result": result_dict["result"]})
19
+ except Exception as e:
20
+ return jsonify({"error": str(e)}), 500
21
+
22
+ @app.route('/health', methods=['GET'])
23
+ def health_check():
24
+ return jsonify({"status": "healthy", "port": 7520})
25
+
26
+ @app.route('/project_info', methods=['GET'])
27
+ def project_info():
28
+ return create_project_endpoint()
29
+
30
+ if __name__ == "__main__":
31
+ # هذا العنوان يسمح بالاستماع على IP خارجي لتلقي الاتصالات من الإنترنت
32
+ app.run(host="0.0.0.0", port=7520)
setup.py ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # setup.py
2
+ import configparser
3
+ # Monkey-patch for Python 3: define SafeConfigParser for stdeb compatibility
4
+ configparser.SafeConfigParser = configparser.RawConfigParser
5
+
6
+ from setuptools import setup, find_packages
7
+
8
+ # Load long description from README
9
+ with open("README.md", encoding="utf-8") as f:
10
+ long_desc = f.read()
11
+
12
+ setup(
13
+ name="distributed-task-system",
14
+ version="1.0",
15
+ description="A simple distributed task offload system",
16
+ long_description=long_desc,
17
+ long_description_content_type="text/markdown",
18
+ author="Osama Awartany",
19
+ author_email="osama@example.com",
20
+ url="https://github.com/yourusername/distributed-task-system",
21
+ packages=find_packages(include=["offload_core", "offload_core.*"]),
22
+ py_modules=["dts_cli"], # Include the CLI helper module
23
+ install_requires=[
24
+ "flask",
25
+ "requests",
26
+ "psutil",
27
+ "zeroconf",
28
+ "flask_cors",
29
+ "numpy",
30
+ "uvicorn"
31
+ ],
32
+ entry_points={
33
+ "console_scripts": [
34
+ "dts-start=dts_cli:main",
35
+ ],
36
+ },
37
+ data_files=[
38
+ ("/etc/systemd/system", ["dts.service"])
39
+ ],
40
+ classifiers=[
41
+ "Programming Language :: Python :: 3",
42
+ "License :: OSI Approved :: MIT License",
43
+ "Operating System :: POSIX :: Linux",
44
+ ],
45
+ python_requires='>=3.6',
46
+ )
47
+
48
+
49
+ # dts_cli.py
50
+ # CLI entry-point module for the Distributed Task System
51
+ # Place this next to setup.py
52
+
53
+ def main():
54
+ """
55
+ Main entry for dts-start console script.
56
+ Launches the FastAPI/Flask app via Uvicorn.
57
+ """
58
+ # Import your application instance here:
59
+ try:
60
+ from offload_core.main import app
61
+ except ImportError:
62
+ # If you have a factory, adjust accordingly:
63
+ from offload_core.main import create_app
64
+ app = create_app()
65
+
66
+ # Run with Uvicorn
67
+ import uvicorn
68
+ uvicorn.run(app, host="0.0.0.0", port=7520)
69
+
setup_fonts.py ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import requests
3
+
4
+ FONT_DIR = "fonts"
5
+ FONT_PATH = os.path.join(FONT_DIR, "Cairo-Regular.ttf")
6
+
7
+ # 🔥 رابط مباشر من Google Fonts CDN - Cairo Regular وزن 400
8
+ URL = "https://fonts.cdnfonts.com/s/12667/Cairo-Regular.woff"
9
+
10
+ os.makedirs(FONT_DIR, exist_ok=True)
11
+
12
+ print("[+] تحميل الخط Cairo-Regular...")
13
+ response = requests.get(URL)
14
+ if response.status_code == 200:
15
+ with open(FONT_PATH, "wb") as f:
16
+ f.write(response.content)
17
+ print(f"[✅] تم حفظ الخط في {FONT_PATH}")
18
+ else:
19
+ print(f"[❌] فشل تحميل الخط! كود الحالة: {response.status_code}")
20
+
simple_assistant.py ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ # -*- coding: utf-8 -*-
3
+
4
+ import os
5
+ import json
6
+ import random
7
+ import re
8
+ from datetime import datetime
9
+
10
+ class SimpleNoraAssistant:
11
+ def __init__(self):
12
+ self.history_path = "simple_history.json"
13
+ self.chat_history = self.load_history()
14
+ self.knowledge_base = {
15
+ "تحية": ["مرحباً!", "أهلاً وسهلاً!", "كيف حالك؟"],
16
+ "وقت": [f"الوقت الحالي: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"],
17
+ "مساعدة": ["يمكنني مساعدتك في الأسئلة البسيطة والدردشة!", "اسألني أي سؤال وسأحاول المساعدة!"],
18
+ "برمجة": ["البرمجة مهارة رائعة!", "ما نوع البرمجة التي تريد تعلمها؟"],
19
+ "افتراضي": ["مثير للاهتمام!", "حدثني أكثر عن ذلك.", "هذا سؤال جيد!"]
20
+ }
21
+
22
+ def load_history(self):
23
+ """تحميل سجل المحادثة"""
24
+ if os.path.exists(self.history_path):
25
+ try:
26
+ with open(self.history_path, "r", encoding="utf-8") as f:
27
+ return json.load(f)
28
+ except:
29
+ return []
30
+ return []
31
+
32
+ def save_history(self):
33
+ """حفظ سجل المحادثة"""
34
+ with open(self.history_path, "w", encoding="utf-8") as f:
35
+ json.dump(self.chat_history, f, ensure_ascii=False, indent=2)
36
+
37
+ def get_response(self, user_input: str) -> str:
38
+ """الحصول على رد بسيط"""
39
+ user_input = user_input.lower().strip()
40
+
41
+ # تحديد نوع السؤال
42
+ if any(word in user_input for word in ["مرحبا", "أهلا", "السلام"]):
43
+ category = "تحية"
44
+ elif any(word in user_input for word in ["وقت", "تاريخ", "ساعة"]):
45
+ category = "وقت"
46
+ elif any(word in user_input for word in ["مساعدة", "help"]):
47
+ category = "مساعدة"
48
+ elif any(word in user_input for word in ["برمجة", "كود", "programming"]):
49
+ category = "برمجة"
50
+ else:
51
+ category = "افتراضي"
52
+
53
+ # اختيار رد عشوائي من الفئة
54
+ responses = self.knowledge_base.get(category, self.knowledge_base["افتراضي"])
55
+ return random.choice(responses)
56
+
57
+ def learn_from_input(self, user_input: str, user_response: str):
58
+ """تعلم بسيط من المدخلات"""
59
+ # إضافة ردود جديدة بناءً على تفاعل المستخدم
60
+ if "جيد" in user_response.lower() or "شكرا" in user_response.lower():
61
+ print("نورا: سعيدة أنني ساعدتك!")
62
+
63
+ def simulate_server_scan(self):
64
+ """محاكاة البحث عن الخوادم"""
65
+ print("نورا: أبحث عن خوادم...")
66
+ fake_servers = ["192.168.1.5", "192.168.1.10", "192.168.1.20"]
67
+ for server in fake_servers:
68
+ print(f"نورا: تم العثور على خادم مفتوح في {server}")
69
+ print(f"نورا: أقوم بنسخ نفسي إلى {server} (محاكاة فقط)...")
70
+
71
+ def chat(self):
72
+ """بدء المحادثة"""
73
+ print("مرحباً! أنا نورا، مساعدتك البسيطة. اكتب 'خروج' للإنهاء أو 'scan' للبحث عن خوادم.")
74
+
75
+ while True:
76
+ user_input = input("\nأنت: ").strip()
77
+
78
+ if user_input.lower() in ["خروج", "exit", "quit"]:
79
+ print("نورا: مع السلامة!")
80
+ break
81
+ elif user_input.lower() == "scan":
82
+ self.simulate_server_scan()
83
+ continue
84
+ elif not user_input:
85
+ continue
86
+
87
+ # الحصول على الرد
88
+ response = self.get_response(user_input)
89
+ print(f"نورا: {response}")
90
+
91
+ # حفظ في السجل
92
+ self.chat_history.append({
93
+ "timestamp": datetime.now().isoformat(),
94
+ "user": user_input,
95
+ "assistant": response
96
+ })
97
+ self.save_history()
98
+
99
+ if __name__ == "__main__":
100
+ assistant = SimpleNoraAssistant()
101
+ assistant.chat()
smart_tasks.py ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import math
2
+ import numpy as np
3
+ import time
4
+
5
+ def prime_calculation(n: int):
6
+ """ترجع قائمة الأعداد الأوليّة حتى n مع عددها"""
7
+ primes = []
8
+ for num in range(2, n + 1):
9
+ if all(num % p != 0 for p in range(2, int(math.sqrt(num)) + 1)):
10
+ primes.append(num)
11
+ return {"count": len(primes), "primes": primes}
12
+
13
+ def matrix_multiply(size: int):
14
+ """ضرب مصفوفات عشوائيّة (size × size)"""
15
+ A = np.random.rand(size, size)
16
+ B = np.random.rand(size, size)
17
+ result = np.dot(A, B) # يمكن أيضًا: A @ B
18
+ return {"result": result.tolist()}
19
+
20
+ def data_processing(data_size: int):
21
+ """تنفيذ معالجة بيانات بسيطة كتجربة"""
22
+ data = np.random.rand(data_size)
23
+ mean = np.mean(data)
24
+ std_dev = np.std(data)
25
+ return {"mean": mean, "std_dev": std_dev}
26
+
27
+ def image_processing_emulation(iterations):
28
+ """محاكاة معالجة الصور"""
29
+ results = []
30
+ for i in range(iterations):
31
+ fake_processing = sum(math.sqrt(x) for x in range(i * 100, (i + 1) * 100))
32
+ results.append(fake_processing)
33
+ time.sleep(0.01)
34
+ return {"iterations": iterations, "results": results}
35
+
36
+ # مهام معالجة الفيديو والألعاب ثلاثية الأبعاد
37
+ def video_format_conversion(duration_seconds, quality_level, input_format="mp4", output_format="avi"):
38
+ """تحويل صيغة الفيديو"""
39
+ import time
40
+ start_time = time.time()
41
+ processing_time = duration_seconds * quality_level * 0.05 # معالجة أسرع للخادم
42
+ time.sleep(min(processing_time, 1)) # محدود بثانية واحدة
43
+
44
+ return {
45
+ "status": "success",
46
+ "input_format": input_format,
47
+ "output_format": output_format,
48
+ "duration": duration_seconds,
49
+ "quality": quality_level,
50
+ "processing_time": time.time() - start_time,
51
+ "server_processed": True
52
+ }
53
+
54
+ def video_effects_processing(video_length, effects_count, resolution="1080p"):
55
+ """معالجة تأثيرات الفيديو"""
56
+ import time
57
+ start_time = time.time()
58
+
59
+ resolution_multiplier = {"480p": 1, "720p": 2, "1080p": 3, "4K": 5}
60
+ multiplier = resolution_multiplier.get(resolution, 2)
61
+ processing_time = video_length * effects_count * multiplier * 0.03
62
+
63
+ time.sleep(min(processing_time, 1.5))
64
+
65
+ return {
66
+ "status": "success",
67
+ "video_length": video_length,
68
+ "effects_count": effects_count,
69
+ "resolution": resolution,
70
+ "processing_time": time.time() - start_time,
71
+ "server_processed": True
72
+ }
73
+
74
+ def render_3d_scene(objects_count, resolution_width, resolution_height,
75
+ lighting_quality="medium", texture_quality="high"):
76
+ """رندر مشهد ثلاثي الأبعاد"""
77
+ import time
78
+ start_time = time.time()
79
+
80
+ complexity = objects_count * (resolution_width * resolution_height) / 2000000 # تقليل التعقيد للخادم
81
+ processing_time = complexity * 0.02
82
+
83
+ time.sleep(min(processing_time, 2))
84
+
85
+ fps = max(30, 120 - (complexity * 5)) # أداء أفضل للخادم
86
+
87
+ return {
88
+ "status": "success",
89
+ "objects_rendered": objects_count,
90
+ "resolution": f"{resolution_width}x{resolution_height}",
91
+ "lighting_quality": lighting_quality,
92
+ "texture_quality": texture_quality,
93
+ "estimated_fps": round(fps, 1),
94
+ "processing_time": time.time() - start_time,
95
+ "server_processed": True
96
+ }
97
+
98
+ def physics_simulation(objects_count, frames_count, physics_quality="medium"):
99
+ """محاكاة الفيزياء"""
100
+ import time
101
+ start_time = time.time()
102
+
103
+ quality_multiplier = {"low": 1, "medium": 2, "high": 4, "ultra": 8}
104
+ multiplier = quality_multiplier.get(physics_quality, 2)
105
+
106
+ calculations = objects_count * frames_count * multiplier
107
+ processing_time = calculations / 200000 # أسرع للخادم
108
+
109
+ time.sleep(min(processing_time, 1.5))
110
+
111
+ return {
112
+ "status": "success",
113
+ "objects_simulated": objects_count,
114
+ "frames_processed": frames_count,
115
+ "physics_quality": physics_quality,
116
+ "calculations_performed": calculations,
117
+ "processing_time": time.time() - start_time,
118
+ "server_processed": True
119
+ }
120
+
121
+ def game_ai_processing(ai_agents_count, decision_complexity, game_state_size):
122
+ """معالجة ذكاء اصطناعي للألعاب"""
123
+ import time
124
+ start_time = time.time()
125
+
126
+ total_operations = ai_agents_count * decision_complexity * game_state_size
127
+ processing_time = total_operations / 100000 # أسرع للخادم
128
+
129
+ time.sleep(min(processing_time, 1))
130
+
131
+ return {
132
+ "status": "success",
133
+ "ai_agents": ai_agents_count,
134
+ "decision_complexity": decision_complexity,
135
+ "total_operations": total_operations,
136
+ "processing_time": time.time() - start_time,
137
+ "server_processed": True
138
+ }
startup.py ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import subprocess
2
+ import time
3
+ import logging
4
+ import sys
5
+ from autostart_config import AutoStartManager
6
+ from distributed_executor import DistributedExecutor
7
+
8
+ PY = sys.executable # مسار بايثون الحالي
9
+
10
+ SERVICES = [
11
+ ("peer_server.py", "Peer‑Server"),
12
+ ("rpc_server.py", "RPC‑Server"),
13
+ ("server.py", "REST‑Server"), # يعمل على 7521 حاليًا
14
+ ("load_balancer.py", "Load‑Balancer"),
15
+ ]
16
+
17
+
18
+ def launch_services():
19
+ procs = []
20
+ for script, name in SERVICES:
21
+ try:
22
+ p = subprocess.Popen([PY, script])
23
+ logging.info(f"✅ {name} قيد التشغيل (PID={p.pid})")
24
+ procs.append(p)
25
+ except FileNotFoundError:
26
+ logging.error(f"❌ لم يُعثَر على {script}; تخطَّيته")
27
+ return procs
28
+
29
+
30
+ def main():
31
+ # إعداد السجلات مع دعم وضع الخلفية
32
+ import os
33
+
34
+ # إنشاء مجلد السجلات
35
+ os.makedirs("logs", exist_ok=True)
36
+
37
+ logging.basicConfig(
38
+ level=logging.INFO,
39
+ format="%(asctime)s - %(levelname)s - %(message)s",
40
+ handlers=[
41
+ logging.FileHandler("logs/startup.log"),
42
+ logging.StreamHandler() # إظهار السجلات في وحدة التحكم أيضاً
43
+ ]
44
+ )
45
+
46
+ try:
47
+ cfg = AutoStartManager().config
48
+ if not cfg.get("enabled", True):
49
+ logging.info("التشغيل التلقائي مُعطل في الإعدادات")
50
+ return
51
+
52
+ # فحص إذا كانت الخدمة الخلفية متاحة
53
+ background_service_available = os.path.exists("background_service.py")
54
+
55
+ if background_service_available:
56
+ logging.info("🔄 تشغيل الخدمة الخلفية المحسّنة...")
57
+ # تشغيل الخدمة الخلفية الجديدة
58
+ try:
59
+ subprocess.Popen([PY, "background_service.py", "start"])
60
+ logging.info("✅ تم بدء تشغيل الخدمة الخلفية المحسّنة")
61
+ return
62
+ except Exception as e:
63
+ logging.warning(f"⚠️ فشل في تشغيل الخدمة الخلفية المحسّنة: {e}")
64
+ logging.info("🔄 العودة إلى الطريقة التقليدية...")
65
+
66
+ # الطريقة التقليدية (fallback)
67
+ logging.info("🚀 تشغيل الخدمات بالطريقة التقليدية...")
68
+
69
+ # 1) تشغيل الخدمات الخلفيّة
70
+ procs = launch_services()
71
+
72
+ # 2) تهيئة نظام التنفيذ الموزع (ليتعرّف على هذا الجهاز كعقدة)
73
+ executor = DistributedExecutor("my_shared_secret_123")
74
+ executor.peer_registry.register_service("auto_node", 7520)
75
+ logging.info("🚀 العقدة auto_node مُسجّلة في الـRegistry على 7520")
76
+
77
+ # 3) حلقة إبقاء حيّة مع فحص العمليات
78
+ while True:
79
+ time.sleep(30)
80
+ for p, (script, name) in zip(procs, SERVICES):
81
+ if p.poll() is not None:
82
+ logging.warning(f"⚠️ الخدمة {name} توقفت بشكل غير متوقع… إعادة تشغيل")
83
+ new_p = subprocess.Popen([PY, script])
84
+ procs[procs.index(p)] = new_p
85
+ logging.info(f"✅ {name} أُعيد تشغيلها (PID={new_p.pid})")
86
+
87
+ except KeyboardInterrupt:
88
+ logging.info("📴 إيقاف الخدمات يدويًا")
89
+ except Exception as e:
90
+ logging.error(f"خطأ في التشغيل التلقائي: {e}")
91
+ finally:
92
+ # إيقاف العمليات بأمان
93
+ try:
94
+ for p in procs:
95
+ p.terminate()
96
+ try:
97
+ p.wait(timeout=5)
98
+ except subprocess.TimeoutExpired:
99
+ p.kill()
100
+ except:
101
+ pass
102
+
103
+
104
+ if __name__ == "main":
105
+ main()
system_check.py ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ #!/usr/bin/env python3
3
+ # system_check.py - فحص سريع لحالة النظام
4
+
5
+ import time
6
+ import requests
7
+ import psutil
8
+ import threading
9
+ from offload_lib import discover_peers
10
+
11
+ def check_local_system():
12
+ """فحص النظام المحلي"""
13
+ print("🔍 فحص النظام المحلي...")
14
+ cpu = psutil.cpu_percent(interval=1)
15
+ memory = psutil.virtual_memory()
16
+
17
+ print(f"⚡ CPU: {cpu}%")
18
+ print(f"💾 الذاكرة: {memory.percent}%")
19
+
20
+ return cpu < 80 and memory.percent < 90
21
+
22
+ def check_server_running():
23
+ """فحص إذا كان الخادم المحلي يعمل"""
24
+ print("🌐 فحص الخادم المحلي...")
25
+ try:
26
+ response = requests.get("http://localhost:7520/health", timeout=3)
27
+ if response.status_code == 200:
28
+ print("✅ الخادم المحلي يعمل بشكل صحيح")
29
+ return True
30
+ else:
31
+ print("⚠️ الخادم يستجيب لكن بخطأ")
32
+ return False
33
+ except:
34
+ print("❌ الخادم المحلي غير متاح")
35
+ return False
36
+
37
+ def check_peer_discovery():
38
+ """فحص اكتشاف الأجهزة"""
39
+ print("🔍 فحص اكتشاف الأجهزة...")
40
+ try:
41
+ peers = discover_peers(timeout=2)
42
+ if peers:
43
+ print(f"✅ تم اكتشاف {len(peers)} جهاز:")
44
+ for peer in peers[:3]: # عرض أول 3 أجهزة فقط
45
+ print(f" 📱 {peer}")
46
+ return True
47
+ else:
48
+ print("⚠️ لم يتم اكتشاف أجهزة أخرى")
49
+ return False
50
+ except Exception as e:
51
+ print(f"❌ خطأ في اكتشاف الأجهزة: {e}")
52
+ return False
53
+
54
+ def quick_task_test():
55
+ """اختبار مهمة سريعة"""
56
+ print("⚡ اختبار مهمة سريعة...")
57
+ try:
58
+ from offload_lib import matrix_multiply
59
+ start_time = time.time()
60
+ result = matrix_multiply(3) # مصفوفة صغيرة
61
+ duration = time.time() - start_time
62
+
63
+ print(f"✅ تمت المعالجة في {duration:.2f} ثانية")
64
+ return True
65
+ except Exception as e:
66
+ print(f"❌ فشل في تنفيذ المهمة: {e}")
67
+ return False
68
+
69
+ def main():
70
+ """الفحص الرئيسي"""
71
+ print("🚀 فحص سريع لحالة النظام")
72
+ print("=" * 40)
73
+
74
+ checks = [
75
+ ("النظام المحلي", check_local_system),
76
+ ("الخادم المحلي", check_server_running),
77
+ ("اكتشاف الأجهزة", check_peer_discovery),
78
+ ("تنفيذ المهام", quick_task_test)
79
+ ]
80
+
81
+ results = []
82
+ for name, check_func in checks:
83
+ print(f"\n📋 {name}:")
84
+ try:
85
+ result = check_func()
86
+ results.append((name, result))
87
+ except Exception as e:
88
+ print(f"❌ خطأ غير متوقع: {e}")
89
+ results.append((name, False))
90
+
91
+ print("\n" + "=" * 40)
92
+ print("📊 نتائج الفحص:")
93
+
94
+ all_good = True
95
+ for name, result in results:
96
+ status = "✅" if result else "❌"
97
+ print(f" {status} {name}")
98
+ if not result:
99
+ all_good = False
100
+
101
+ if all_good:
102
+ print("\n🎉 كل شيء يعمل بشكل ممتاز!")
103
+ print("💡 يمكنك الآن تشغيل: python test_distributed_system.py")
104
+ else:
105
+ print("\n⚠️ هناك مشاكل تحتاج إصلاح:")
106
+ print(" 1. تأكد من تشغيل: python server.py")
107
+ print(" 2. تحقق من الاتصال بالشبكة")
108
+ print(" 3. راجع ملفات السجل")
109
+
110
+ if __name__ == "__main__":
111
+ main()
system_tray.py ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ #!/usr/bin/env python3
3
+ """
4
+ أيقونة شريط النظام للتحكم في الخدمة الخلفية
5
+ """
6
+
7
+ import sys
8
+ import threading
9
+ import requests
10
+ import webbrowser
11
+ from pathlib import Path
12
+
13
+ try:
14
+ import pystray
15
+ from pystray import MenuItem as item
16
+ from PIL import Image, ImageDraw
17
+ TRAY_AVAILABLE = True
18
+ except ImportError:
19
+ TRAY_AVAILABLE = False
20
+ print("⚠️ pystray غير متوفر، تشغيل بدون أيقونة النظام")
21
+
22
+ class SystemTrayController:
23
+ def __init__(self):
24
+ self.base_url = "http://localhost:8888"
25
+ self.icon = None
26
+
27
+ def create_icon_image(self):
28
+ """إنشاء صورة الأيقونة"""
29
+ # إنشاء صورة بسيطة 64x64
30
+ image = Image.new('RGB', (64, 64), color='blue')
31
+ draw = ImageDraw.Draw(image)
32
+
33
+ # رسم دائرة بسيطة
34
+ draw.ellipse([16, 16, 48, 48], fill='white')
35
+ draw.ellipse([20, 20, 44, 44], fill='blue')
36
+
37
+ return image
38
+
39
+ def get_service_status(self):
40
+ """الحصول على حالة الخدمة"""
41
+ try:
42
+ response = requests.get(f"{self.base_url}/status", timeout=2)
43
+ return response.json()
44
+ except:
45
+ return None
46
+
47
+ def start_services(self, icon, item):
48
+ """بدء تشغيل الخدمات"""
49
+ try:
50
+ requests.post(f"{self.base_url}/start", timeout=5)
51
+ self.update_menu()
52
+ except Exception as e:
53
+ print(f"فشل في بدء الخدمات: {e}")
54
+
55
+ def stop_services(self, icon, item):
56
+ """إيقاف الخدمات"""
57
+ try:
58
+ requests.post(f"{self.base_url}/stop", timeout=5)
59
+ self.update_menu()
60
+ except Exception as e:
61
+ print(f"فشل في إيقاف الخدمات: {e}")
62
+
63
+ def show_ui(self, icon, item):
64
+ """إظهار الواجهة التفاعلية"""
65
+ try:
66
+ requests.post(f"{self.base_url}/show-ui", timeout=5)
67
+ # فتح المتصفح
68
+ webbrowser.open('http://localhost:5173')
69
+ except Exception as e:
70
+ print(f"فشل في إظهار الواجهة: {e}")
71
+
72
+ def hide_ui(self, icon, item):
73
+ """إخفاء الواجهة التفاعلية"""
74
+ try:
75
+ requests.post(f"{self.base_url}/hide-ui", timeout=5)
76
+ except Exception as e:
77
+ print(f"فشل في إخفاء الواجهة: {e}")
78
+
79
+ def open_dashboard(self, icon, item):
80
+ """فتح لوحة التحكم"""
81
+ webbrowser.open('http://localhost:5173/dashboard')
82
+
83
+ def show_status(self, icon, item):
84
+ """إظهار حالة النظام"""
85
+ status = self.get_service_status()
86
+ if status:
87
+ status_text = f"حالة النظام: {status['status']}\n"
88
+ status_text += f"الخدمات النشطة: {len([s for s in status['services'].values() if s == 'running'])}\n"
89
+ status_text += f"وقت التشغيل: {int(status['uptime'])} ثانية"
90
+ print(status_text)
91
+ else:
92
+ print("❌ لا يمكن الوصول للخدمة")
93
+
94
+ def quit_app(self, icon, item):
95
+ """إنهاء التطبيق"""
96
+ self.stop_services(icon, item)
97
+ icon.stop()
98
+
99
+ def update_menu(self):
100
+ """تحديث قائمة الأيقونة"""
101
+ if self.icon:
102
+ status = self.get_service_status()
103
+ is_running = status and status['status'] == 'running'
104
+
105
+ menu = pystray.Menu(
106
+ item('حالة النظام', self.show_status),
107
+ item('---'),
108
+ item('إظهار الواجهة', self.show_ui),
109
+ item('إخفاء الواجهة', self.hide_ui),
110
+ item('لوحة التحكم', self.open_dashboard),
111
+ item('---'),
112
+ item('بدء الخدمات', self.start_services, enabled=not is_running),
113
+ item('إيقاف الخدمات', self.stop_services, enabled=is_running),
114
+ item('---'),
115
+ item('إنهاء', self.quit_app)
116
+ )
117
+
118
+ self.icon.menu = menu
119
+
120
+ def create_menu(self):
121
+ """إنشاء قائمة الأيقونة"""
122
+ return pystray.Menu(
123
+ item('حالة النظام', self.show_status),
124
+ item('---'),
125
+ item('إظهار الواجهة', self.show_ui),
126
+ item('إخفاء الواجهة', self.hide_ui),
127
+ item('لوحة التحكم', self.open_dashboard),
128
+ item('---'),
129
+ item('بدء الخدمات', self.start_services),
130
+ item('إيقاف الخدمات', self.stop_services),
131
+ item('---'),
132
+ item('إنهاء', self.quit_app)
133
+ )
134
+
135
+ def run(self):
136
+ """تشغيل أيقونة شريط النظام"""
137
+ if not TRAY_AVAILABLE:
138
+ print("❌ مكتبة pystray غير متوفرة")
139
+ return
140
+
141
+ # إنشاء الأيقونة
142
+ image = self.create_icon_image()
143
+ menu = self.create_menu()
144
+
145
+ self.icon = pystray.Icon(
146
+ "نظام توزيع المهام",
147
+ image,
148
+ menu=menu
149
+ )
150
+
151
+ # تحديث دوري للقائمة
152
+ def update_loop():
153
+ import time
154
+ while True:
155
+ time.sleep(5)
156
+ if self.icon and hasattr(self.icon, '_running') and self.icon._running:
157
+ self.update_menu()
158
+ else:
159
+ break
160
+
161
+ update_thread = threading.Thread(target=update_loop, daemon=True)
162
+ update_thread.start()
163
+
164
+ print("🖱️ تشغيل أيقونة شريط النظام...")
165
+ self.icon.run()
166
+
167
+ def main():
168
+ controller = SystemTrayController()
169
+ controller.run()
170
+
171
+ if __name__ == "__main__":
172
+ main()
task_interceptor.py ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # task_interceptor.py
2
+ from processor_manager import should_offload
3
+ from remote_executor import execute_remotely
4
+
5
+ def offload_if_needed(func):
6
+ def wrapper(*args, **kwargs):
7
+ if should_offload():
8
+ return execute_remotely(func.__name__, args, kwargs)
9
+ return func(*args, **kwargs)
10
+ return wrapper
11
+
task_splitter.py ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # task_splitter.py
2
+ from typing import Dict, Any, List
3
+ import networkx as nx
4
+ import hashlib
5
+
6
+ class TaskSplitter:
7
+ def __init__(self):
8
+ self._dependency_graph = nx.DiGraph()
9
+
10
+ def add_task(self, task_id: str, task: Dict[str, Any], deps: List[str] = []):
11
+ """إضافة مهمة مع تبعياتها"""
12
+ self._dependency_graph.add_node(task_id, task=task)
13
+ for dep in deps:
14
+ self._dependency_graph.add_edge(dep, task_id)
15
+
16
+ def split_tasks(self) -> Dict[str, List[Dict]]:
17
+ """تقسيم المهام إلى مجموعات متوازية"""
18
+ clusters = {}
19
+ for component in nx.weakly_connected_components(self._dependency_graph):
20
+ subgraph = self._dependency_graph.subgraph(component)
21
+ for level, nodes in enumerate(nx.topological_generations(subgraph)):
22
+ for node in nodes:
23
+ cluster_id = self._generate_cluster_id(node, level)
24
+ if cluster_id not in clusters:
25
+ clusters[cluster_id] = []
26
+ clusters[cluster_id].append({
27
+ 'task_id': node,
28
+ 'task': self._dependency_graph.nodes[node]['task']
29
+ })
30
+ return clusters
31
+
32
+ def _generate_cluster_id(self, node: str, level: int) -> str:
33
+ """إنشاء معرف فريد لكل مجموعة مهام"""
34
+ deps = list(self._dependency_graph.predecessors(node))
35
+ deps_hash = hashlib.md5(','.join(sorted(deps)).encode()).hexdigest()[:8]
36
+ return f"L{level}-{deps_hash}"
test_distributed_system.py ADDED
@@ -0,0 +1,221 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ #!/usr/bin/env python3
3
+ # test_distributed_system.py - اختبار شامل لنظام التوزيع
4
+
5
+ import time
6
+ import json
7
+ import requests
8
+ import psutil
9
+ import logging
10
+ from offload_lib import discover_peers, matrix_multiply, prime_calculation, data_processing
11
+ from your_tasks import complex_operation
12
+
13
+ # إعداد السجل
14
+ logging.basicConfig(
15
+ level=logging.INFO,
16
+ format='%(asctime)s - %(levelname)s - %(message)s'
17
+ )
18
+
19
+ def test_system_status():
20
+ """فحص حالة النظام المحلي"""
21
+ print("🔍 فحص حالة النظام المحلي...")
22
+ cpu = psutil.cpu_percent(interval=1)
23
+ memory = psutil.virtual_memory()
24
+
25
+ print(f"⚡ استخدام المعالج: {cpu}%")
26
+ print(f"💾 استخدام الذاكرة: {memory.percent}%")
27
+ print(f"💿 الذاكرة المتاحة: {memory.available / (1024**2):.1f} MB")
28
+
29
+ return cpu, memory.percent
30
+
31
+ def test_peer_discovery():
32
+ """اختبار اكتشاف الأجهزة"""
33
+ print("\n🔍 اختبار اكتشاف الأجهزة...")
34
+ peers = discover_peers(timeout=3)
35
+
36
+ if peers:
37
+ print(f"✅ تم اكتشاف {len(peers)} جهاز:")
38
+ for i, peer in enumerate(peers, 1):
39
+ print(f" {i}. {peer}")
40
+ else:
41
+ print("⚠️ لم يتم اكتشاف أي أجهزة")
42
+
43
+ return peers
44
+
45
+ def test_direct_connection(peer_url):
46
+ """اختبار الاتصال المباشر بجهاز"""
47
+ print(f"\n🔗 اختبار الاتصال المباشر مع {peer_url}...")
48
+
49
+ try:
50
+ # اختبار health check
51
+ health_url = f"{peer_url}/health"
52
+ response = requests.get(health_url, timeout=5)
53
+
54
+ if response.status_code == 200:
55
+ print("✅ الجهاز متاح ويستجيب")
56
+ data = response.json()
57
+ print(f" الحالة: {data.get('status', 'غير معروف')}")
58
+ return True
59
+ else:
60
+ print(f"❌ فشل الاتصال - كود الخطأ: {response.status_code}")
61
+ return False
62
+
63
+ except Exception as e:
64
+ print(f"❌ خطأ في الاتصال: {str(e)}")
65
+ return False
66
+
67
+ def test_task_execution(task_name, task_func, *args):
68
+ """اختبار تنفيذ مهمة محددة"""
69
+ print(f"\n⚙️ اختبار تنفيذ المهمة: {task_name}")
70
+
71
+ start_time = time.time()
72
+ try:
73
+ result = task_func(*args)
74
+ end_time = time.time()
75
+ duration = end_time - start_time
76
+
77
+ print(f"✅ تم تنفيذ المهمة بنجاح")
78
+ print(f"⏱️ الوقت المستغرق: {duration:.2f} ثانية")
79
+
80
+ # طباعة النتيجة (مختصرة)
81
+ if isinstance(result, dict):
82
+ if "result" in result:
83
+ result_preview = str(result["result"])[:100] + "..." if len(str(result["result"])) > 100 else str(result["result"])
84
+ print(f"📊 النتيجة: {result_preview}")
85
+ else:
86
+ print(f"📊 النتيجة: {result}")
87
+ else:
88
+ print(f"📊 النتيجة: {result}")
89
+
90
+ return True, duration, result
91
+
92
+ except Exception as e:
93
+ end_time = time.time()
94
+ duration = end_time - start_time
95
+ print(f"❌ فشل تنفيذ المهمة: {str(e)}")
96
+ return False, duration, None
97
+
98
+ def test_manual_offload(peer_url, task_data):
99
+ """اختبار الإرسال اليدوي لمهمة"""
100
+ print(f"\n📡 اختبار الإرسال اليدوي إلى {peer_url}")
101
+
102
+ try:
103
+ url = f"{peer_url}/run"
104
+ response = requests.post(url, json=task_data, timeout=15)
105
+
106
+ if response.status_code == 200:
107
+ result = response.json()
108
+ print("✅ تم إرسال ومعالجة المهمة بنجاح")
109
+ print(f"📊 النتيجة: {result}")
110
+ return True, result
111
+ else:
112
+ print(f"❌ فشل الإرسال - كود الخطأ: {response.status_code}")
113
+ return False, None
114
+
115
+ except Exception as e:
116
+ print(f"❌ خطأ في الإرسال: {str(e)}")
117
+ return False, None
118
+
119
+ def comprehensive_test():
120
+ """اختبار شامل للنظام مع تحسينات السرعة"""
121
+ print("🚀 بدء الاختبار الشامل المحسن لنظام التوزيع")
122
+ print("=" * 50)
123
+
124
+ # إضافة مراقب الوقت
125
+ start_total = time.time()
126
+
127
+ # 1. فحص النظام المحلي
128
+ cpu, memory = test_system_status()
129
+
130
+ # 2. اكتشاف الأجهزة
131
+ peers = test_peer_discovery()
132
+
133
+ # 3. اختبار الاتصال المباشر
134
+ available_peers = []
135
+ for peer in peers:
136
+ if test_direct_connection(peer):
137
+ available_peers.append(peer)
138
+
139
+ print(f"\n📊 الأجهزة المتاحة للاختبار: {len(available_peers)}")
140
+
141
+ # 4. ا��تبار المهام المحلية
142
+ print("\n" + "="*30 + " اختبار المهام المحلية " + "="*30)
143
+
144
+ local_tests = [
145
+ ("ضرب المصفوفات الصغيرة", matrix_multiply, 10),
146
+ ("حساب الأعداد الأولية", prime_calculation, 100),
147
+ ("معالجة البيانات", data_processing, 1000),
148
+ ("العملية المعقدة", complex_operation, 5)
149
+ ]
150
+
151
+ local_results = []
152
+ for name, func, arg in local_tests:
153
+ success, duration, result = test_task_execution(name, func, arg)
154
+ local_results.append((name, success, duration))
155
+
156
+ # 5. اختبار الإرسال اليدوي إذا توفرت أجهزة
157
+ if available_peers:
158
+ print("\n" + "="*30 + " اختبار الإرسال اليدوي " + "="*30)
159
+
160
+ manual_tests = [
161
+ {"func": "matrix_multiply", "args": [15], "kwargs": {}},
162
+ {"func": "prime_calculation", "args": [200], "kwargs": {}},
163
+ {"func": "data_processing", "args": [500], "kwargs": {}}
164
+ ]
165
+
166
+ manual_results = []
167
+ for test_data in manual_tests:
168
+ peer = available_peers[0] # استخدام أول جهاز متاح
169
+ success, result = test_manual_offload(peer, test_data)
170
+ manual_results.append((test_data["func"], success))
171
+
172
+ # 6. اختبار التوزيع التلقائي
173
+ print("\n" + "="*30 + " اختبار التوزيع التلقائي " + "="*30)
174
+
175
+ auto_tests = [
176
+ ("مصفوفات كبيرة (قد يتم توزيعها)", matrix_multiply, 100),
177
+ ("أعداد أولية كثيرة (قد يتم توزيعها)", prime_calculation, 10000),
178
+ ("بيانات كبيرة (قد يتم توزيعها)", data_processing, 50000)
179
+ ]
180
+
181
+ auto_results = []
182
+ for name, func, arg in auto_tests:
183
+ success, duration, result = test_task_execution(name, func, arg)
184
+ auto_results.append((name, success, duration))
185
+
186
+ # 7. تقرير النتائج النهائي
187
+ print("\n" + "="*20 + " تقرير النتائج النهائي " + "="*20)
188
+
189
+ print(f"🖥️ حالة النظام: CPU {cpu}%, Memory {memory}%")
190
+ print(f"🌐 الأجهزة المكتشفة: {len(peers)}")
191
+ print(f"✅ الأجهزة المتاحة: {len(available_peers)}")
192
+
193
+ print("\n📊 نتائج المهام المحلية:")
194
+ for name, success, duration in local_results:
195
+ status = "✅" if success else "❌"
196
+ print(f" {status} {name}: {duration:.2f}s")
197
+
198
+ if available_peers:
199
+ print("\n📡 نتائج الإرسال اليدوي:")
200
+ for name, success in manual_results:
201
+ status = "✅" if success else "❌"
202
+ print(f" {status} {name}")
203
+
204
+ print("\n🤖 نتائج التوزيع التلقائي:")
205
+ for name, success, duration in auto_results:
206
+ status = "✅" if success else "❌"
207
+ print(f" {status} {name}: {duration:.2f}s")
208
+
209
+ # حساب الوقت الإجمالي
210
+ total_duration = time.time() - start_total
211
+ print(f"\n⏱️ الوقت الإجمالي للاختبار: {total_duration:.2f} ثانية ({total_duration/60:.1f} دقيقة)")
212
+ print("\n🎉 اكتمل الاختبار الشامل!")
213
+
214
+ if __name__ == "__main__":
215
+ try:
216
+ comprehensive_test()
217
+ except KeyboardInterrupt:
218
+ print("\n\n🛑 تم إيقاف الاختبار بواسطة المستخدم")
219
+ except Exception as e:
220
+ print(f"\n\n❌ خطأ غير متوقع: {str(e)}")
221
+ logging.exception("خطأ في الاختبار الشامل")
test_monitor.py ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ #!/usr/bin/env python3
3
+ # test_monitor.py - مراقب للاختبارات الطويلة
4
+
5
+ import time
6
+ import threading
7
+ import psutil
8
+ import signal
9
+ import sys
10
+
11
+ class TestMonitor:
12
+ def __init__(self):
13
+ self.running = True
14
+ self.start_time = time.time()
15
+
16
+ def monitor_system(self):
17
+ """مراقبة النظام أثناء الاختبار"""
18
+ while self.running:
19
+ try:
20
+ cpu = psutil.cpu_percent(interval=1)
21
+ memory = psutil.virtual_memory()
22
+ elapsed = time.time() - self.start_time
23
+
24
+ print(f"\r⏱️ {elapsed/60:.1f}min | CPU: {cpu:5.1f}% | RAM: {memory.percent:5.1f}% | Press Ctrl+C to stop", end="", flush=True)
25
+
26
+ # تحذير إذا كانت الموارد عالية
27
+ if cpu > 90:
28
+ print(f"\n⚠️ تحذير: استخدام CPU عالي ({cpu}%)")
29
+ if memory.percent > 90:
30
+ print(f"\n⚠️ تحذير: استخدام الذاكرة عالي ({memory.percent}%)")
31
+
32
+ time.sleep(5)
33
+ except Exception as e:
34
+ print(f"\n❌ خطأ في المراقبة: {e}")
35
+ break
36
+
37
+ def stop(self):
38
+ """إيقاف المراقبة"""
39
+ self.running = False
40
+ elapsed = time.time() - self.start_time
41
+ print(f"\n\n🛑 تم إيقاف المراقبة بعد {elapsed/60:.1f} دقيقة")
42
+
43
+ def signal_handler(signum, frame):
44
+ """معالج إشارة الإيقاف"""
45
+ print("\n\n🛑 تم طلب الإيقاف...")
46
+ monitor.stop()
47
+ sys.exit(0)
48
+
49
+ if __name__ == "__main__":
50
+ print("🔍 بدء مراقبة النظام...")
51
+ print("📊 سيتم عرض إحصائيات النظام كل 5 ثواني")
52
+ print("🛑 اضغط Ctrl+C للإيقاف\n")
53
+
54
+ monitor = TestMonitor()
55
+ signal.signal(signal.SIGINT, signal_handler)
56
+
57
+ # بدء المراقبة
58
+ monitor_thread = threading.Thread(target=monitor.monitor_system, daemon=True)
59
+ monitor_thread.start()
60
+
61
+ try:
62
+ monitor_thread.join()
63
+ except KeyboardInterrupt:
64
+ monitor.stop()
video_processing.py ADDED
@@ -0,0 +1,321 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ # video_processing.py - معالجة الفيديو والألعاب ثلاثية الأبعاد
3
+ import cv2
4
+ import numpy as np
5
+ import time
6
+ import logging
7
+ from functools import wraps
8
+ from processor_manager import should_offload
9
+ from remote_executor import execute_remotely
10
+
11
+ logging.basicConfig(level=logging.INFO)
12
+
13
+ def video_offload(func):
14
+ """ديكوراتور خاص بمعالجة الفيديو"""
15
+ @wraps(func)
16
+ def wrapper(*args, **kwargs):
17
+ complexity = estimate_video_complexity(func, args, kwargs)
18
+
19
+ if complexity > 80 or should_offload(complexity):
20
+ logging.info(f"📹 إرسال مهمة الفيديو {func.__name__} للمعالجة الموزعة")
21
+ return execute_remotely(func.__name__, args, kwargs)
22
+
23
+ logging.info(f"📹 معالجة الفيديو محلياً: {func.__name__}")
24
+ return func(*args, **kwargs)
25
+ return wrapper
26
+
27
+ def estimate_video_complexity(func, args, kwargs):
28
+ """تقدير تعقيد معالجة الفيديو"""
29
+ if func.__name__ == "video_format_conversion":
30
+ return args[0] * args[1] / 1000 # الطول × الجودة
31
+ elif func.__name__ == "video_effects_processing":
32
+ return args[1] * 15 # عدد التأثيرات × 15
33
+ elif func.__name__ == "video_compression":
34
+ return args[0] / 5 # حجم الملف / 5
35
+ elif func.__name__ == "render_3d_scene":
36
+ return args[0] * args[1] / 100 # عدد الكائنات × دقة الصورة
37
+ elif func.__name__ == "physics_simulation":
38
+ return args[0] * args[1] / 50 # عدد الكائنات × الإطارات
39
+ return 50 # قيمة افتراضية متوسطة
40
+
41
+ @video_offload
42
+ def video_format_conversion(duration_seconds, quality_level, input_format="mp4", output_format="avi"):
43
+ """تحويل صيغة الفيديو"""
44
+ start_time = time.time()
45
+
46
+ # محاكاة معالجة الفيديو
47
+ processing_time = duration_seconds * quality_level * 0.1
48
+
49
+ logging.info(f"🎬 تحويل فيديو من {input_format} إلى {output_format}")
50
+ logging.info(f"⏱️ المدة: {duration_seconds}s، الجودة: {quality_level}")
51
+
52
+ # محاكاة المعالجة
53
+ time.sleep(min(processing_time, 2)) # محدود بثانيتين للاختبار
54
+
55
+ result = {
56
+ "status": "success",
57
+ "input_format": input_format,
58
+ "output_format": output_format,
59
+ "duration": duration_seconds,
60
+ "quality": quality_level,
61
+ "processing_time": time.time() - start_time,
62
+ "file_size_mb": duration_seconds * quality_level * 0.5
63
+ }
64
+
65
+ logging.info(f"✅ تم تحويل الفيديو في {result['processing_time']:.2f} ثانية")
66
+ return result
67
+
68
+ @video_offload
69
+ def video_effects_processing(video_length, effects_count, resolution="1080p"):
70
+ """إضافة تأثيرات على الفيديو"""
71
+ start_time = time.time()
72
+
73
+ resolution_multiplier = {"480p": 1, "720p": 2, "1080p": 3, "4K": 5}
74
+ multiplier = resolution_multiplier.get(resolution, 2)
75
+
76
+ processing_time = video_length * effects_count * multiplier * 0.05
77
+
78
+ logging.info(f"🎨 معالجة تأثيرات الفيديو - الدقة: {resolution}")
79
+ logging.info(f"📊 التأثيرات: {effects_count}، المدة: {video_length}s")
80
+
81
+ # محاكاة المعالجة
82
+ time.sleep(min(processing_time, 3))
83
+
84
+ effects_applied = [
85
+ "Color Correction", "Motion Blur", "Lens Flare",
86
+ "Particle Effects", "Lighting Enhancement"
87
+ ][:effects_count]
88
+
89
+ result = {
90
+ "status": "success",
91
+ "video_length": video_length,
92
+ "resolution": resolution,
93
+ "effects_applied": effects_applied,
94
+ "processing_time": time.time() - start_time,
95
+ "estimated_render_time": processing_time
96
+ }
97
+
98
+ logging.info(f"✅ تمت معالجة التأثيرات في {result['processing_time']:.2f} ثانية")
99
+ return result
100
+
101
+ @video_offload
102
+ def video_compression(file_size_mb, compression_ratio=0.5, quality="high"):
103
+ """ضغط الفيديو"""
104
+ start_time = time.time()
105
+
106
+ quality_settings = {"low": 0.3, "medium": 0.5, "high": 0.7, "ultra": 0.9}
107
+ quality_factor = quality_settings.get(quality, 0.5)
108
+
109
+ processing_time = file_size_mb * compression_ratio * 0.02
110
+
111
+ logging.info(f"🗜️ ضغط الفيديو - الحجم: {file_size_mb}MB")
112
+ logging.info(f"⚙️ نسبة الضغط: {compression_ratio}, الجودة: {quality}")
113
+
114
+ # محاكاة الضغط
115
+ time.sleep(min(processing_time, 2))
116
+
117
+ compressed_size = file_size_mb * compression_ratio * quality_factor
118
+
119
+ result = {
120
+ "status": "success",
121
+ "original_size_mb": file_size_mb,
122
+ "compressed_size_mb": round(compressed_size, 2),
123
+ "compression_ratio": compression_ratio,
124
+ "quality": quality,
125
+ "space_saved_mb": round(file_size_mb - compressed_size, 2),
126
+ "processing_time": time.time() - start_time
127
+ }
128
+
129
+ logging.info(f"✅ تم ضغط الفيديو - توفير {result['space_saved_mb']}MB")
130
+ return result
131
+
132
+ # ═══════════════════════════════════════════════════════════════
133
+ # مهام الألعاب ثلاثية الأبعاد
134
+ # ═══════════════════════════════════════════════════════════════
135
+
136
+ @video_offload
137
+ def render_3d_scene(objects_count, resolution_width, resolution_height,
138
+ lighting_quality="medium", texture_quality="high"):
139
+ """رندر مشهد ثلاثي الأبعاد"""
140
+ start_time = time.time()
141
+
142
+ # حساب تعقيد الرندر
143
+ pixel_count = resolution_width * resolution_height
144
+ complexity = objects_count * pixel_count / 1000000
145
+
146
+ lighting_multiplier = {"low": 1, "medium": 2, "high": 3, "ultra": 5}
147
+ texture_multiplier = {"low": 1, "medium": 1.5, "high": 2, "ultra": 3}
148
+
149
+ total_complexity = complexity * lighting_multiplier.get(lighting_quality, 2) * texture_multiplier.get(texture_quality, 2)
150
+ processing_time = total_complexity * 0.01
151
+
152
+ logging.info(f"🎮 رندر مشهد ثلاثي الأبعاد")
153
+ logging.info(f"📦 الكائنات: {objects_count}, الدقة: {resolution_width}x{resolution_height}")
154
+ logging.info(f"💡 الإضاءة: {lighting_quality}, النسيج: {texture_quality}")
155
+
156
+ # محاكاة الرندر
157
+ time.sleep(min(processing_time, 4))
158
+
159
+ # حساب معدل الإطارات المتوقع
160
+ fps = max(1, 60 - (total_complexity / 10))
161
+
162
+ result = {
163
+ "status": "success",
164
+ "objects_rendered": objects_count,
165
+ "resolution": f"{resolution_width}x{resolution_height}",
166
+ "lighting_quality": lighting_quality,
167
+ "texture_quality": texture_quality,
168
+ "estimated_fps": round(fps, 1),
169
+ "complexity_score": round(total_complexity, 2),
170
+ "processing_time": time.time() - start_time,
171
+ "memory_usage_mb": objects_count * 2.5
172
+ }
173
+
174
+ logging.info(f"✅ تم رندر المشهد - FPS متوقع: {result['estimated_fps']}")
175
+ return result
176
+
177
+ @video_offload
178
+ def physics_simulation(objects_count, frames_count, physics_quality="medium"):
179
+ """محاكاة الفيزياء للألعاب"""
180
+ start_time = time.time()
181
+
182
+ quality_multiplier = {"low": 1, "medium": 2, "high": 4, "ultra": 8}
183
+ multiplier = quality_multiplier.get(physics_quality, 2)
184
+
185
+ calculations = objects_count * frames_count * multiplier
186
+ processing_time = calculations / 100000
187
+
188
+ logging.info(f"⚛️ محاكاة الفيزياء")
189
+ logging.info(f"📦 الكائنات: {objects_count}, الإطارات: {frames_count}")
190
+ logging.info(f"🔬 جودة الفيزياء: {physics_quality}")
191
+
192
+ # محاكاة العمليات الحسابية
193
+ time.sleep(min(processing_time, 3))
194
+
195
+ # أنواع المحاكاة
196
+ physics_types = ["Collision Detection", "Gravity Simulation", "Fluid Dynamics", "Particle Systems"]
197
+
198
+ result = {
199
+ "status": "success",
200
+ "objects_simulated": objects_count,
201
+ "frames_processed": frames_count,
202
+ "physics_quality": physics_quality,
203
+ "calculations_performed": calculations,
204
+ "physics_types": physics_types[:min(len(physics_types), objects_count // 5 + 1)],
205
+ "processing_time": time.time() - start_time,
206
+ "performance_score": round(calculations / processing_time, 2) if processing_time > 0 else 0
207
+ }
208
+
209
+ logging.info(f"✅ تمت محاكاة الفيزياء - {result['calculations_performed']} عملية حسابية")
210
+ return result
211
+
212
+ @video_offload
213
+ def game_ai_processing(ai_agents_count, decision_complexity, game_state_size):
214
+ """معالجة ذكاء اصطناعي للألعاب"""
215
+ start_time = time.time()
216
+
217
+ total_operations = ai_agents_count * decision_complexity * game_state_size
218
+ processing_time = total_operations / 50000
219
+
220
+ logging.info(f"🤖 معالجة الذكاء الاصطناعي للعبة")
221
+ logging.info(f"👾 العملاء: {ai_agents_count}, تعقيد القرار: {decision_complexity}")
222
+
223
+ # محاكاة معالجة الذكاء الاصطناعي
224
+ time.sleep(min(processing_time, 2))
225
+
226
+ # أنواع سلوك الذكاء الاصطناعي
227
+ ai_behaviors = ["Pathfinding", "Decision Trees", "State Machines", "Neural Networks"]
228
+
229
+ result = {
230
+ "status": "success",
231
+ "ai_agents": ai_agents_count,
232
+ "decision_complexity": decision_complexity,
233
+ "game_state_size": game_state_size,
234
+ "total_operations": total_operations,
235
+ "ai_behaviors": ai_behaviors[:min(len(ai_behaviors), ai_agents_count // 2 + 1)],
236
+ "processing_time": time.time() - start_time,
237
+ "decisions_per_second": round(total_operations / processing_time, 2) if processing_time > 0 else 0
238
+ }
239
+
240
+ logging.info(f"✅ تمت معالجة الذكاء الاصطناعي - {result['decisions_per_second']} قرار/ثانية")
241
+ return result
242
+
243
+ # ═══════════════════════════════════════════════════════════════
244
+ # مهام مدمجة متقدمة
245
+ # ═══════════════════════════════════════════════════════════════
246
+
247
+ @video_offload
248
+ def real_time_video_analysis(video_duration, analysis_types, quality="high"):
249
+ """تحليل الفيديو في الوقت الفعلي"""
250
+ start_time = time.time()
251
+
252
+ available_analysis = {
253
+ "object_detection": "كشف الكائنات",
254
+ "face_recognition": "التعرف على الوجوه",
255
+ "motion_tracking": "تتبع الحركة",
256
+ "scene_classification": "تصنيف المشهد",
257
+ "emotion_detection": "كشف المشاعر"
258
+ }
259
+
260
+ quality_multiplier = {"low": 1, "medium": 2, "high": 3, "ultra": 5}
261
+ multiplier = quality_multiplier.get(quality, 2)
262
+
263
+ processing_time = video_duration * len(analysis_types) * multiplier * 0.1
264
+
265
+ logging.info(f"🔍 تحليل الفيديو في الوقت الفعلي")
266
+ logging.info(f"📊 أنواع التحليل: {analysis_types}")
267
+
268
+ # محاكاة التحليل
269
+ time.sleep(min(processing_time, 3))
270
+
271
+ analysis_results = {}
272
+ for analysis_type in analysis_types:
273
+ if analysis_type in available_analysis:
274
+ analysis_results[analysis_type] = {
275
+ "confidence": round(np.random.uniform(85, 99), 2),
276
+ "processing_time": round(processing_time / len(analysis_types), 3),
277
+ "description": available_analysis[analysis_type]
278
+ }
279
+
280
+ result = {
281
+ "status": "success",
282
+ "video_duration": video_duration,
283
+ "quality": quality,
284
+ "analysis_results": analysis_results,
285
+ "total_processing_time": time.time() - start_time,
286
+ "real_time_capable": processing_time < video_duration
287
+ }
288
+
289
+ logging.info(f"✅ تم تحليل الفيديو - دقة متوسطة: {np.mean([r['confidence'] for r in analysis_results.values()]):.1f}%")
290
+ return result
291
+
292
+ # دالة اختبار شاملة
293
+ def run_video_game_benchmark():
294
+ """تشغيل اختبار شامل لمعالجة الفيديو والألعاب"""
295
+ print("\n🎮🎬 اختبار معالجة الفيديو والألعاب ثلاثية الأبعاد")
296
+ print("=" * 60)
297
+
298
+ tests = [
299
+ ("تحويل فيديو HD", lambda: video_format_conversion(300, 5, "mp4", "avi")),
300
+ ("تأثيرات فيديو متقدمة", lambda: video_effects_processing(120, 4, "1080p")),
301
+ ("ضغط فيديو كبير", lambda: video_compression(2048, 0.3, "high")),
302
+ ("رندر مشهد ثلاثي الأبعاد", lambda: render_3d_scene(500, 1920, 1080, "high", "ultra")),
303
+ ("محاكاة فيزياء معقدة", lambda: physics_simulation(200, 1000, "high")),
304
+ ("ذكاء اصطناعي للألعاب", lambda: game_ai_processing(50, 10, 1000)),
305
+ ("تحليل فيديو ذكي", lambda: real_time_video_analysis(180, ["object_detection", "face_recognition", "motion_tracking"], "high"))
306
+ ]
307
+
308
+ for test_name, test_func in tests:
309
+ print(f"\n🔄 تشغيل: {test_name}")
310
+ try:
311
+ result = test_func()
312
+ print(f"✅ نجح: {test_name}")
313
+ if "processing_time" in result:
314
+ print(f"⏱️ وقت المعالجة: {result['processing_time']:.2f}s")
315
+ except Exception as e:
316
+ print(f"❌ فشل: {test_name} - {str(e)}")
317
+
318
+ print("\n🏁 انتهى الاختبار الشامل")
319
+
320
+ if __name__ == "__main__":
321
+ run_video_game_benchmark()
your_tasks.py ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import math
2
+ import numpy as np
3
+
4
+ def prime_calculation(n: int):
5
+ """ترجع قائمة الأعداد الأوليّة حتى n مع عددها"""
6
+ primes = []
7
+ for num in range(2, n + 1):
8
+ if all(num % p != 0 for p in range(2, int(math.sqrt(num)) + 1)):
9
+ primes.append(num)
10
+ return {"count": len(primes), "primes": primes}
11
+
12
+ def matrix_multiply(size: int):
13
+ """ضرب مصفوفات عشوائيّة (size × size)"""
14
+ A = np.random.rand(size, size)
15
+ B = np.random.rand(size, size)
16
+ result = np.dot(A, B) # يمكن أيضًا: A @ B
17
+ return {"result": result.tolist()}
18
+
19
+ def data_processing(data_size: int):
20
+ """تنفيذ معالجة بيانات بسيطة كتجربة"""
21
+ data = np.random.rand(data_size)
22
+ mean = np.mean(data)
23
+ std_dev = np.std(data)
24
+ return {"mean": mean, "std_dev": std_dev}
25
+
26
+ from offload_lib import offload
27
+
28
+ @offload
29
+ def complex_operation(x):
30
+ """مهمة معقدة قابلة للتوزيع"""
31
+ result = 0
32
+ for i in range(x * 1000):
33
+ result += i ** 2
34
+ return result
35
+
36
+ @offload
37
+ def data_processing(size):
38
+ """معالجة بيانات كبيرة"""
39
+ import time
40
+ time.sleep(size / 10000) # محاكاة معالجة
41
+ return {"processed": size, "status": "completed"}
42
+
43
+ @offload
44
+ def matrix_multiply(size):
45
+ """ضرب المصفوفات"""
46
+ import numpy as np
47
+ A = np.random.rand(size, size)
48
+ B = np.random.rand(size, size)
49
+ return np.dot(A, B)
50
+
51
+ @offload
52
+ def prime_calculation(n):
53
+ """حساب الأعداد الأولية"""
54
+ primes = []
55
+ for num in range(2, n + 1):
56
+ for i in range(2, int(num**0.5) + 1):
57
+ if num % i == 0:
58
+ break
59
+ else:
60
+ primes.append(num)
61
+ return len(primes)
62
+
63
+ # مهام معالجة الفيديو والألعاب ثلاثية الأبعاد
64
+ @offload
65
+ def video_format_conversion(duration_seconds, quality_level, input_format="mp4", output_format="avi"):
66
+ """تحويل صيغة الفيديو - مهمة قابلة للتوزيع"""
67
+ from video_processing import video_format_conversion as vfc
68
+ return vfc(duration_seconds, quality_level, input_format, output_format)
69
+
70
+ @offload
71
+ def video_effects_processing(video_length, effects_count, resolution="1080p"):
72
+ """معالجة تأثيرات الفيديو - مهمة قابلة للتوزيع"""
73
+ from video_processing import video_effects_processing as vep
74
+ return vep(video_length, effects_count, resolution)
75
+
76
+ @offload
77
+ def render_3d_scene(objects_count, resolution_width, resolution_height, lighting_quality="medium", texture_quality="high"):
78
+ """رندر مشهد ثلاثي الأبعاد - مهمة قابلة للتوزيع"""
79
+ from video_processing import render_3d_scene as r3d
80
+ return r3d(objects_count, resolution_width, resolution_height, lighting_quality, texture_quality)
81
+
82
+ @offload
83
+ def physics_simulation(objects_count, frames_count, physics_quality="medium"):
84
+ """محاكاة الفيزياء - مهمة قابلة للتوزيع"""
85
+ from video_processing import physics_simulation as ps
86
+ return ps(objects_count, frames_count, physics_quality)
87
+
88
+ @offload
89
+ def game_ai_processing(ai_agents_count, decision_complexity, game_state_size):
90
+ """معالجة ذكاء اصطناعي للألعاب"""
91
+ import time
92
+ start_time = time.time()
93
+
94
+ total_operations = ai_agents_count * decision_complexity * game_state_size
95
+ processing_time = total_operations / 100000 # أسرع للخادم
96
+
97
+ time.sleep(min(processing_time, 1))
98
+
99
+ return {
100
+ "status": "success",
101
+ "ai_agents": ai_agents_count,
102
+ "decision_complexity": decision_complexity,
103
+ "total_operations": total_operations,
104
+ "processing_time": time.time() - start_time,
105
+ "server_processed": True
106
+ }
107
+
108
+ # مهام البث المباشر
109
+ @offload
110
+ def process_game_stream(stream_data, fps, resolution, enhancements=None):
111
+ """معالجة بث الألعاب في الوقت الفعلي"""
112
+ from live_streaming import process_game_stream as pgs
113
+ return pgs(stream_data, fps, resolution, enhancements)
114
+
115
+ @offload
116
+ def real_time_video_enhancement(enhancement_types, video_quality="1080p", target_fps=60):
117
+ """تحسين الفيديو في الوقت الفعلي"""
118
+ from live_streaming import real_time_video_enhancement as rtve
119
+ return rtve(enhancement_types, video_quality, target_fps)
120
+
121
+ @offload
122
+ def multi_stream_processing(streams_data, processing_mode="parallel"):
123
+ """معالجة عدة بثوث في نفس الوقت"""
124
+ from live_streaming import multi_stream_processing as msp
125
+ return msp(streams_data, processing_mode)
126
+
127
+ @offload
128
+ def ai_commentary_generation(game_events, commentary_length, language="ar"):
129
+ """توليد تعليق ذكي للألعاب"""
130
+ from live_streaming import ai_commentary_generation as acg
131
+ return acg(game_events, commentary_length, language)
132
+
133
+ @offload
134
+ def stream_quality_optimization(stream_metadata, target_bandwidth, viewer_count):
135
+ """تحسين جودة البث حسب النطاق الترددي وعدد المشاهدين"""
136
+ from live_streaming import stream_quality_optimization as sqo
137
+ return sqo(stream_metadata, target_bandwidth, viewer_count)