-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
202 lines (144 loc) · 10.4 KB
/
app.py
File metadata and controls
202 lines (144 loc) · 10.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# مفتاح تفعيل نضام Python
#================================#
# استيراد المكتبات اللازمة
#================================#
import os # للتعامل مع مسارات الملفات
import json # للتعامل مع ملفات JSON
import shutil # للتحقق من وجود البرامج في PATH
import subprocess # لتشغيل العمليات الخارجية
from datetime import datetime # للتعامل مع الطوابع الزمنية
# =============================
# مسارات وإعدادات التطبيق
# =============================
BASE_DIR = os.path.dirname(os.path.abspath(__file__)) # دليل التطبيق الحالي سيتم تشغيله منه
REPO_ROOT = os.path.dirname(BASE_DIR) # جذر المستودع (المجلد الأب) ؤستخدم لمصادر Java والملفات الأخرى
HISTORY_FILE = os.path.join(BASE_DIR, "launcher_history.jsonl") # ملف سجل الإطلاق (كل سطر هو كائن JSON)
MAIN_CLASS = "svc.Main" # الفئة الرئيسية لتشغيل Java التطبيق سيتم تشغيلها
JAVA = shutil.which("java") # مسار برنامج Java
JAVAC = shutil.which("javac") # مسار برنامج Java Compiler يستخدم للترجمة
JAVA_SRC_DIR = os.path.join(REPO_ROOT, "src", "main", "java", "svc",) # دليل مصادر Java
BUILD_DIR = os.path.join(REPO_ROOT, "out") # دليل بناء Java
# =============================
# مساعدات السجل
# =============================
def read_history(): # قراءة سجل الإطلاق من الملف
if not os.path.exists(HISTORY_FILE): # إذا لم يكن الملف موجودًا
return [] # إرجاع قائمة فارغة
entries = [] # قائمة لتخزين الإدخالات
with open(HISTORY_FILE, "r", encoding="utf-8") as f: # فتح الملف للقراءة
for line in f: # قراءة كل سطر في الملف
line = line.strip() # إزالة الفراغات الزائدة
if not line: # إذا كان السطر فارغًا
continue # تخطي السطر
try: # محاولة تحميل السطر ككائن JSON
entries.append(json.loads(line)) # إضافة الإدخال إلى القائمة
except Exception: # تجاهل الأخطاء في التحميل
pass # تجاهل الإدخالات غير الصالحة
return entries # إرجاع قائمة الإدخالات
# =============================
# سجل الإطلاقات صفحات المساعدة
# =============================
def clear_history(): # مسح سجل الإطلاق
open(HISTORY_FILE, "w", encoding="utf-8").close() # فتح الملف للكتابة وإغلاقه (مسح المحتوى)
print(" History cleared.") # إعلام المستخدم بأن السجل تم مسحه
def add_launch_time(): # إضافة طابع زمني للإطلاق الحالي
entry = { # إنشاء إدخال جديد
"timestamp": datetime.now().isoformat(sep=" ", timespec="seconds"), # الطابع الزمني الحالي
"event": "launch" # نوع الحدث
} # حفظ الإدخال في الملف
os.makedirs(os.path.dirname(HISTORY_FILE), exist_ok=True) # إنشاء الدليل إذا لم يكن موجودًا
with open(HISTORY_FILE, "a", encoding="utf-8") as f: # فتح الملف للإضافة
f.write(json.dumps(entry, ensure_ascii=False) + "\n") # كتابة الإدخال ككائن JSON في الملف
print(f" Launch time: {entry['timestamp']}") # إعلام المستخدم بالطابع الزمني للإطلاق
def show_launch_list(): # عرض قائمة الإطلاقات السابقة
entries = read_history() # قراءة سجل الإطلاق
launches = [e for e in entries if e.get("event") == "launch"] # تصفية الإدخالات لتشمل فقط أحداث الإطلاق
if not launches: # إذا لم تكن هناك إطلاقات سابقة
print("No previous launches.") # إعلام المستخدم بذلك
return # إنهاء الدالة
print(" Launch history:") # طباعة عنوان سجل الإطلاق
for i, e in enumerate(launches, 1): # طباعة كل إدخال مع ترقيمه
print(f"{i}. {e['timestamp']}") # طباعة الطابع الزمني للإطلاق
# =============================#
# بدء عملية Java في الخلفية
# =============================#
def start_java(): # بدء عملية Java في الخلفية
if not JAVA: # التحقق من وجود Java في PATH
print(" Java runtime (java) not found in PATH.") # إعلام المستخدم بعدم وجود Java
return None # إنهاء الدالة بإرجاع None
if not os.path.exists(JAVA_SRC_DIR): # التحقق من وجود دليل مصادر Java
print(f" Java source dir not found: {JAVA_SRC_DIR}") # إعلام المستخدم بعدم وجود الدليل
return None # إنهاء الدالة بإرجاع None
os.makedirs(BUILD_DIR, exist_ok=True) # إنشاء دليل البناء إذا لم يكن موجودًا
#================================#
# مرحلة ترجمة ملفات Java
#================================#
if JAVAC: # التحقق من وجود Java Compiler في PATH
# compile all .java files under src/main/java
java_files = [] # قائمة لتخزين ملفات Java
for root, _, files in os.walk(JAVA_SRC_DIR): # استعراض جميع الملفات في دليل مصادر Java
for fn in files: # التحقق من كل ملف
if fn.endswith(".java"): # إذا كان الملف ينتهي بامتداد .java
java_files.append(os.path.join(root, fn)) # إضافة مسار الملف إلى القائمة
if not java_files: # إذا لم تكن هناك ملفات Java
print(" No Java sources found to compile.") # إعلام المستخدم بعدم وجود ملفات للترجمة
return None # إنهاء الدالة بإرجاع None
print(" Compiling Java sources...") # إعلام المستخدم ببدء الترجمة
try: # محاولة ترجمة ملفات Java
subprocess.run([JAVAC, "-d", BUILD_DIR] + java_files, check=True, cwd=REPO_ROOT) # تشغيل javac لترجمة الملفات
except subprocess.CalledProcessError: # في حالة حدوث خطأ أثناء الترجمة
print(" Compilation failed. Ensure JDK is installed and source is valid.") # إعلام المستخدم بفشل الترجمة
return None # إنهاء الدالة بإرجاع None
else: # إذا لم يكن javac موجودًا
print(" javac not found; skipping compilation (assuming already compiled).") # إعلام المستخدم بتخطي الترجمة
#================================#
# بدء عملية Java في الخلفية
#================================#
proc = subprocess.Popen( # بدء عملية Java في الخلفية
[JAVA, "-cp", BUILD_DIR, MAIN_CLASS], # الأمر لتشغيل Java مع تحديد مسار الفئة الرئيسية
cwd=REPO_ROOT, # تعيين دليل العمل إلى جذر المستودع
stdout=subprocess.DEVNULL, # تجاهل مخرجات stdout
stderr=subprocess.DEVNULL, # تجاهل مخرجات stderr
stdin=subprocess.PIPE # توجيه stdin إلى أنبوب (غير مستخدم هنا)
)
print(" Java process started in background.") # إعلام المستخدم بأن عملية Java بدأت في الخلفية
return proc # إرجاع كائن العملية
#================================#
# معالجة أوامر المستخدم
#================================#
def handle_command(cmd): # معالجة أوامر المستخدم
cmd = cmd.strip().lower() # تنظيف الأمر وتحويله إلى أحرف صغيرة
if cmd in ("show", "list"): # إذا كان الأمر هو "show" أو "list"
show_launch_list() # عرض قائمة الإطلاقات
return True # إرجاع True للإشارة إلى أن الأمر تم التعامل معه
elif cmd == "clear": # إذا كان الأمر هو "clear"
clear_history() # مسح سجل الإطلاق
return True # إرجاع True للإشارة إلى أن الأمر تم التعامل معه
return False # إرجاع False للإشارة إلى أن الأمر غير معروف
# =============================
# نقطة الدخول الرئيسية للتطبيق
# =============================
def main(): # الدالة الرئيسية للتشغيل
add_launch_time() # إضافة طابع زمني للإطلاق الحالي
java_proc = start_java() # بدء عملية Java في الخلفية
print("Type: show / list / clear / exit") # تعليمات للمستخدم
print("--------------------------------") # خط فاصل في الإخراج
try: # بدء حلقة الأوامر
while True: # حلقة لا نهائية
cmd = input(">>> ") # قراءة أمر من المستخدم
if cmd.lower() in ("exit", "quit"): # إذا كان الأمر هو "exit" أو "quit"
break # إنهاء الحلقة
if handle_command(cmd): # إذا تم التعامل مع الأمر
continue # الانتقال إلى التكرار التالي للحلقة
print("Unknown command (show, list, clear, exit). Try again.") # إعلام المستخدم بأن الأمر غير معروف
finally: # عند الانتهاء من الحلقة (بغض النظر عن السبب)
if java_proc: # إذا كانت عملية Java قد بدأت
java_proc.terminate() # إنهاء عملية Java
java_proc.wait() # الانتظار حتى تنتهي العملية
print(" Java terminated.") # إعلام المستخدم بأن عملية Java تم إنهاؤها
print(" Bye.") # رسالة وداع للمستخدم
# =============================
# نقطه تفعيل
# =============================
if __name__ == "__main__": # نقطة الدخول الرئيسية للتطبيق
main() # استدعاء الدالة الرئيسية للتشغيل التطبيق