Update app.py
Browse files
app.py
CHANGED
|
@@ -10,30 +10,22 @@ def analyze_error_ai(log_text):
|
|
| 10 |
if "project_info" in log_text or "google-services" in log_text:
|
| 11 |
return "🤖 تحليل AI: هناك مشكلة في بيانات Firebase. تأكد من لصق محتوى google-services.json بشكل صحيح."
|
| 12 |
if "Unresolved reference" in log_text or "Could not resolve" in log_text:
|
| 13 |
-
return "🤖 تحليل AI: فشل في تحميل مكتبات خارجية
|
| 14 |
if "compileReleaseJavaWithJavac" in log_text or "error: " in log_text:
|
| 15 |
-
return "🤖 تحليل AI: خطأ في كود الجافا (Java Syntax Error). تأكد من
|
| 16 |
-
|
| 17 |
-
return "🤖 تحليل AI: تعارض في ملف AndroidManifest. الأذونات أو الإعدادات تتضارب مع مكتبة أخرى (مثل OneSignal)."
|
| 18 |
-
return "🤖 تحليل AI: خطأ غير معروف. ابحث في السجلات أعلاه عن الكلمات المكتوبة باللون الأحمر أو التي تبدأ بكلمة FAILED."
|
| 19 |
|
| 20 |
# ================== المحرك الرئيسي للبناء ==================
|
| 21 |
def build_ultimate_app(
|
| 22 |
-
# 1. الأساسيات
|
| 23 |
app_name, url, package_name, build_format, version_name, version_code, orientation,
|
| 24 |
dev_name, dev_email,
|
| 25 |
-
# 2. التصميم والواجهة
|
| 26 |
icon_path, enable_splash, splash_text, splash_color, status_bar_color, enable_bottom_nav, fullscreen, keep_screen_on,
|
| 27 |
-
# 3. محرك الويب المتقدم
|
| 28 |
js_enabled, enable_zoom, dom_storage, allow_file_access, clear_cache_exit, custom_user_agent, media_auto_play,
|
| 29 |
-
# 4. الحماية والأمان
|
| 30 |
enable_security, block_root, prevent_screenshots, clear_cookies_exit,
|
| 31 |
-
# 5. الإعلانات والخدمات (Firebase)
|
| 32 |
enable_ads, admob_banner_id, admob_interstitial_id, onesignal_id, firebase_file, firebase_text,
|
| 33 |
-
# 6. الأذونات
|
| 34 |
perm_internet, perm_camera, perm_audio, perm_location, perm_storage, perm_bg, perm_vibrate, perm_contacts
|
| 35 |
):
|
| 36 |
-
logs = f"[{datetime.datetime.now().strftime('%H:%M:%S')}] 🚀 بدء النظام... تهيئة بيئة البناء
|
| 37 |
yield logs, None
|
| 38 |
|
| 39 |
project_dir = "/tmp/SuperApp"
|
|
@@ -48,37 +40,27 @@ def build_ultimate_app(
|
|
| 48 |
os.makedirs(f"{res_dir}/{folder}", exist_ok=True)
|
| 49 |
os.makedirs(java_dir, exist_ok=True)
|
| 50 |
|
| 51 |
-
# --- معالجة الأيقونة ---
|
| 52 |
if icon_path: shutil.copy(icon_path, f"{res_dir}/mipmap-xxxhdpi/ic_launcher.png")
|
| 53 |
else: os.system(f"touch {res_dir}/mipmap-xxxhdpi/ic_launcher.png")
|
| 54 |
|
| 55 |
-
# --- معالجة Firebase (النص أو الملف) ---
|
| 56 |
use_firebase = False
|
| 57 |
fb_content = ""
|
| 58 |
-
if firebase_text and firebase_text.strip() != "":
|
| 59 |
-
fb_content = firebase_text.strip()
|
| 60 |
elif firebase_file:
|
| 61 |
try:
|
| 62 |
with open(firebase_file, 'r', encoding='utf-8') as f: fb_content = f.read()
|
| 63 |
except: pass
|
| 64 |
|
| 65 |
-
if fb_content:
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
use_firebase = True
|
| 70 |
-
logs += "✅ تم دمج Firebase بنجاح (من النص/الملف).\n"
|
| 71 |
-
else:
|
| 72 |
-
logs += "⚠️ تحذير: بيانات Firebase غير صالحة، تم تجاهلها لمنع فشل البناء.\n"
|
| 73 |
yield logs, None
|
| 74 |
|
| 75 |
-
# --- التوقيع الرقمي ---
|
| 76 |
dev_n = dev_name if dev_name else "Dev"
|
| 77 |
os.system(f'keytool -genkey -v -keystore {project_dir}/app/release.keystore -alias appKey -keyalg RSA -keysize 2048 -validity 10000 -storepass 12345678 -keypass 12345678 -dname "CN={dev_n}, EMAILADDRESS={dev_email}, O=App, C=US" 2>/dev/null')
|
| 78 |
|
| 79 |
-
# --- ملفات Gradle ---
|
| 80 |
with open(f"{project_dir}/settings.gradle", "w") as f: f.write(f"rootProject.name = '{app_name}'\ninclude ':app'\n")
|
| 81 |
-
|
| 82 |
with open(f"{project_dir}/build.gradle", "w") as f:
|
| 83 |
f.write(f"""
|
| 84 |
buildscript {{
|
|
@@ -94,11 +76,7 @@ def build_ultimate_app(
|
|
| 94 |
|
| 95 |
with open(f"{project_dir}/app/build.gradle", "w") as f:
|
| 96 |
f.write(f"""
|
| 97 |
-
plugins {{
|
| 98 |
-
id 'com.android.application'
|
| 99 |
-
{'id "com.onesignal.androidsdk.onesignal-gradle-plugin"' if onesignal_id else ''}
|
| 100 |
-
{'id "com.google.gms.google-services"' if use_firebase else ''}
|
| 101 |
-
}}
|
| 102 |
android {{
|
| 103 |
namespace '{package_name}'
|
| 104 |
compileSdk 34
|
|
@@ -110,17 +88,8 @@ def build_ultimate_app(
|
|
| 110 |
versionName "{version_name}"
|
| 111 |
{f'manifestPlaceholders = [onesignal_app_id: "{onesignal_id}", onesignal_google_project_number: "REMOTE"]' if onesignal_id else ''}
|
| 112 |
}}
|
| 113 |
-
signingConfigs {{
|
| 114 |
-
|
| 115 |
-
}}
|
| 116 |
-
buildTypes {{
|
| 117 |
-
release {{
|
| 118 |
-
minifyEnabled {str(enable_security).lower()}
|
| 119 |
-
shrinkResources {str(enable_security).lower()}
|
| 120 |
-
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt')
|
| 121 |
-
signingConfig signingConfigs.release
|
| 122 |
-
}}
|
| 123 |
-
}}
|
| 124 |
}}
|
| 125 |
dependencies {{
|
| 126 |
implementation 'androidx.appcompat:appcompat:1.6.1'
|
|
@@ -132,173 +101,66 @@ def build_ultimate_app(
|
|
| 132 |
}}
|
| 133 |
""")
|
| 134 |
|
| 135 |
-
# --- ملفات التصميم (XML) ---
|
| 136 |
with open(f"{res_dir}/values/styles.xml", "w") as f:
|
| 137 |
-
f.write(f"""<resources>
|
| 138 |
-
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
|
| 139 |
-
<item name="android:statusBarColor">{status_bar_color}</item>
|
| 140 |
-
</style>
|
| 141 |
-
</resources>""")
|
| 142 |
|
| 143 |
with open(f"{res_dir}/layout/activity_main.xml", "w") as f:
|
| 144 |
-
f.write(f"""<?xml version="1.0" encoding="utf-8"?>
|
| 145 |
-
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent">
|
| 146 |
-
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout android:id="@+id/swipeContainer" android:layout_width="match_parent" android:layout_height="match_parent">
|
| 147 |
-
<WebView android:id="@+id/webview" android:layout_width="match_parent" android:layout_height="match_parent" />
|
| 148 |
-
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
| 149 |
-
</RelativeLayout>""")
|
| 150 |
|
| 151 |
-
# --- شاشة البداية الاختيارية (Splash) ---
|
| 152 |
if enable_splash:
|
| 153 |
with open(f"{res_dir}/layout/activity_splash.xml", "w") as f:
|
| 154 |
-
f.write(f"""<?xml version="1.0" encoding="utf-8"?>
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="{splash_text}" android:textColor="#FFFFFF" android:textSize="20sp" android:layout_below="@id/logo" android:layout_marginTop="20dp" android:layout_centerHorizontal="true"/>
|
| 158 |
-
</RelativeLayout>""")
|
| 159 |
-
|
| 160 |
-
splash_java = f"""package {package_name};
|
| 161 |
-
import android.app.Activity;
|
| 162 |
-
import android.content.Intent;
|
| 163 |
-
import android.os.Bundle;
|
| 164 |
-
import android.os.Handler;
|
| 165 |
-
public class SplashActivity extends Activity {{
|
| 166 |
-
@Override protected void onCreate(Bundle savedInstanceState) {{
|
| 167 |
-
super.onCreate(savedInstanceState);
|
| 168 |
-
setContentView(R.layout.activity_splash);
|
| 169 |
-
new Handler().postDelayed(() -> {{ startActivity(new Intent(SplashActivity.this, MainActivity.class)); finish(); }}, 2500);
|
| 170 |
-
}}
|
| 171 |
-
}}"""
|
| 172 |
-
with open(f"{java_dir}/SplashActivity.java", "w") as f: f.write(splash_java)
|
| 173 |
-
|
| 174 |
-
# --- كود الجافا الرئيسي (MainActivity) مع كل الميزات المتقدمة ---
|
| 175 |
-
root_detection = """
|
| 176 |
-
private boolean isRooted() {
|
| 177 |
-
String[] paths = {"/system/app/Superuser.apk", "/sbin/su", "/system/bin/su", "/system/xbin/su", "/data/local/xbin/su"};
|
| 178 |
-
for (String path : paths) { if (new java.io.File(path).exists()) return true; }
|
| 179 |
-
return false;
|
| 180 |
-
}
|
| 181 |
-
""" if block_root else ""
|
| 182 |
|
| 183 |
u_agent = f'ws.setUserAgentString("{custom_user_agent}");' if custom_user_agent else ""
|
| 184 |
-
|
| 185 |
main_java = f"""package {package_name};
|
| 186 |
-
import android.app.Activity;
|
| 187 |
-
import android.content.Intent;
|
| 188 |
-
import android.net.Uri;
|
| 189 |
-
import android.os.Bundle;
|
| 190 |
-
import android.view.WindowManager;
|
| 191 |
-
import android.webkit.CookieManager;
|
| 192 |
-
import android.webkit.WebSettings;
|
| 193 |
-
import android.webkit.WebView;
|
| 194 |
-
import android.webkit.WebViewClient;
|
| 195 |
-
import android.webkit.WebChromeClient;
|
| 196 |
-
import android.webkit.WebResourceRequest;
|
| 197 |
-
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
| 198 |
{'import com.onesignal.OneSignal;' if onesignal_id else ''}
|
| 199 |
-
|
| 200 |
public class MainActivity extends Activity {{
|
| 201 |
-
private WebView myWebView;
|
| 202 |
-
private SwipeRefreshLayout swipeLayout;
|
| 203 |
-
{root_detection}
|
| 204 |
-
|
| 205 |
@Override protected void onCreate(Bundle savedInstanceState) {{
|
| 206 |
super.onCreate(savedInstanceState);
|
| 207 |
-
|
| 208 |
-
{'if (isRooted()) { finish(); return; }' if block_root else ''}
|
| 209 |
{'getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);' if prevent_screenshots else ''}
|
| 210 |
{'getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);' if keep_screen_on else ''}
|
| 211 |
-
|
| 212 |
{'if(android.os.Build.VERSION.SDK_INT >= 28) getWindow().getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;' if fullscreen else ''}
|
| 213 |
-
{'getWindow().getDecorView().setSystemUiVisibility(android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | android.view.View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | android.view.View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
|
| 217 |
-
}}
|
| 218 |
-
|
| 219 |
-
{f'OneSignal.setLogLevel(OneSignal.LOG_LEVEL.VERBOSE, OneSignal.LOG_LEVEL.NONE); OneSignal.initWithContext(this); OneSignal.setAppId("{onesignal_id}");' if onesignal_id else ''}
|
| 220 |
-
|
| 221 |
-
setContentView(R.layout.activity_main);
|
| 222 |
-
myWebView = findViewById(R.id.webview);
|
| 223 |
-
swipeLayout = findViewById(R.id.swipeContainer);
|
| 224 |
-
swipeLayout.setOnRefreshListener(() -> myWebView.reload());
|
| 225 |
-
|
| 226 |
-
WebSettings ws = myWebView.getSettings();
|
| 227 |
-
ws.setJavaScriptEnabled({str(js_enabled).lower()});
|
| 228 |
-
ws.setDomStorageEnabled({str(dom_storage).lower()});
|
| 229 |
-
ws.setAllowFileAccess({str(allow_file_access).lower()});
|
| 230 |
-
ws.setMediaPlaybackRequiresUserGesture({str(not media_auto_play).lower()});
|
| 231 |
-
ws.setSupportZoom({str(enable_zoom).lower()});
|
| 232 |
-
ws.setBuiltInZoomControls({str(enable_zoom).lower()});
|
| 233 |
-
ws.setDisplayZoomControls(false);
|
| 234 |
-
ws.setSupportMultipleWindows(true);
|
| 235 |
-
ws.setJavaScriptCanOpenWindowsAutomatically(true);
|
| 236 |
-
ws.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
|
| 237 |
-
{u_agent}
|
| 238 |
-
|
| 239 |
myWebView.setWebViewClient(new WebViewClient() {{
|
| 240 |
@Override public void onPageFinished(WebView view, String url) {{ swipeLayout.setRefreshing(false); }}
|
| 241 |
@Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {{
|
| 242 |
String reqUrl = request.getUrl().toString();
|
| 243 |
-
if (reqUrl.startsWith("http
|
| 244 |
-
|
| 245 |
-
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(reqUrl)));
|
| 246 |
-
return true;
|
| 247 |
-
}}
|
| 248 |
-
return false;
|
| 249 |
-
}}
|
| 250 |
-
try {{ startActivity(Intent.parseUri(reqUrl, Intent.URI_INTENT_SCHEME)); return true; }}
|
| 251 |
-
catch (Exception e) {{ return false; }}
|
| 252 |
}}
|
| 253 |
}});
|
| 254 |
-
myWebView.setWebChromeClient(new WebChromeClient());
|
| 255 |
-
myWebView.loadUrl("{url}");
|
| 256 |
}}
|
| 257 |
-
|
| 258 |
-
@Override protected void onDestroy() {{
|
| 259 |
-
{'myWebView.clearCache(true);' if clear_cache_exit else ''}
|
| 260 |
-
{'CookieManager.getInstance().removeAllCookies(null); CookieManager.getInstance().flush();' if clear_cookies_exit else ''}
|
| 261 |
-
super.onDestroy();
|
| 262 |
-
}}
|
| 263 |
-
|
| 264 |
@Override public void onBackPressed() {{ if (myWebView.canGoBack()) myWebView.goBack(); else super.onBackPressed(); }}
|
| 265 |
}}"""
|
| 266 |
with open(f"{java_dir}/MainActivity.java", "w") as f: f.write(main_java)
|
| 267 |
|
| 268 |
-
|
| 269 |
-
perms = []
|
| 270 |
-
if perm_internet: perms.extend(["INTERNET", "ACCESS_NETWORK_STATE"])
|
| 271 |
if perm_camera: perms.append("CAMERA")
|
| 272 |
-
if perm_audio: perms.
|
| 273 |
if perm_location: perms.extend(["ACCESS_FINE_LOCATION", "ACCESS_COARSE_LOCATION"])
|
| 274 |
if perm_storage: perms.extend(["READ_EXTERNAL_STORAGE", "WRITE_EXTERNAL_STORAGE"])
|
| 275 |
if perm_bg: perms.append("REQUEST_IGNORE_BATTERY_OPTIMIZATIONS")
|
| 276 |
if perm_vibrate: perms.append("VIBRATE")
|
| 277 |
if perm_contacts: perms.append("READ_CONTACTS")
|
| 278 |
if onesignal_id or use_firebase: perms.append("POST_NOTIFICATIONS")
|
| 279 |
-
|
| 280 |
perms_xml = "\n".join([f'<uses-permission android:name="android.permission.{p}" />' for p in perms])
|
| 281 |
-
admob_meta = f'<meta-data android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="{admob_banner_id}"/>' if enable_ads and admob_banner_id else ""
|
| 282 |
|
| 283 |
-
|
| 284 |
-
|
| 285 |
-
manifest_xml = f"""<?xml version="1.0" encoding="utf-8"?>
|
| 286 |
-
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="{package_name}">
|
| 287 |
-
{perms_xml}
|
| 288 |
-
<application android:label="{app_name}" android:icon="@mipmap/ic_launcher" android:theme="@style/AppTheme" android:usesCleartextTraffic="true" android:hardwareAccelerated="true">
|
| 289 |
-
{admob_meta}
|
| 290 |
-
{f'<activity android:name=".SplashActivity" android:exported="true" android:screenOrientation="portrait"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity>' if enable_splash else ''}
|
| 291 |
-
<activity android:name=".MainActivity" android:exported="true" android:screenOrientation="{orientation}" android:configChanges="orientation|keyboardHidden|screenSize">
|
| 292 |
-
{'' if enable_splash else '<intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter>'}
|
| 293 |
-
</activity>
|
| 294 |
-
</application>
|
| 295 |
-
</manifest>"""
|
| 296 |
with open(f"{project_dir}/app/src/main/AndroidManifest.xml", "w") as f: f.write(manifest_xml)
|
| 297 |
|
| 298 |
-
logs += "⚙️ بدء عملية التجميع...
|
| 299 |
yield logs, None
|
| 300 |
|
| 301 |
-
# --- تنفيذ البناء وقراءة السجلات ---
|
| 302 |
gradle_cmd = "gradle bundleRelease" if build_format == "aab" else "gradle assembleRelease"
|
| 303 |
process = subprocess.Popen(gradle_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, cwd=project_dir, bufsize=1, universal_newlines=True)
|
| 304 |
|
|
@@ -307,89 +169,80 @@ def build_ultimate_app(
|
|
| 307 |
for line in iter(process.stdout.readline, ''):
|
| 308 |
log_buffer.append(line)
|
| 309 |
full_error_log += line
|
| 310 |
-
if len(log_buffer) >
|
| 311 |
yield logs + "".join(log_buffer), None
|
| 312 |
-
|
| 313 |
process.wait()
|
| 314 |
|
| 315 |
-
final_display = logs + "".join(log_buffer)
|
| 316 |
if process.returncode == 0:
|
| 317 |
-
|
| 318 |
-
|
| 319 |
-
yield final_display, out_path
|
| 320 |
else:
|
| 321 |
-
|
| 322 |
-
final_display += f"\n\n❌ [فشل البناء] اكتشف النظام خطأ.\n{ai_diagnosis}"
|
| 323 |
-
yield final_display, None
|
| 324 |
-
|
| 325 |
-
|
| 326 |
-
# ================== واجهة المستخدم المتوافقة مع الموبايل (Accordions) ==================
|
| 327 |
-
with gr.Blocks(theme=gr.themes.Base()) as demo:
|
| 328 |
-
gr.Markdown("<h1 style='text-align: center;'>📱 مصنع التطبيقات الشامل - الإصدار الذهبي</h1>")
|
| 329 |
-
gr.Markdown("<p style='text-align: center;'>تصميم متوافق 100% مع شاشات الهواتف. افتح القوائم أدناه لضبط أكثر من 40 ميزة!</p>")
|
| 330 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 331 |
with gr.Accordion("1️⃣ الأساسيات | Core Basics", open=True):
|
| 332 |
-
app_name = gr.Textbox(label="اسم التطبيق | App Name", value="تطبيقي
|
| 333 |
url = gr.Textbox(label="الرابط | Website URL", value="https://google.com")
|
| 334 |
-
package_name = gr.Textbox(label="اسم الحزمة | Package Name
|
| 335 |
build_format = gr.Dropdown(choices=["apk", "aab"], value="apk", label="صيغة الإخراج | Output Format")
|
| 336 |
with gr.Row():
|
| 337 |
version_name = gr.Textbox(label="الإصدار | Version", value="1.0.0")
|
| 338 |
version_code = gr.Number(label="كود الإصدار | Version Code", value=1)
|
| 339 |
-
orientation = gr.Dropdown(choices=["unspecified", "portrait", "landscape"], value="unspecified", label="اتجاه الشاشة
|
| 340 |
-
dev_name = gr.Textbox(label="اسم المطور (للتوقيع)
|
| 341 |
-
dev_email = gr.Textbox(label="البريد الإلكتروني
|
| 342 |
|
| 343 |
with gr.Accordion("2️⃣ التصميم والواجهة | UI & Design", open=False):
|
| 344 |
-
icon_path = gr.File(label="أيقونة
|
| 345 |
-
status_bar_color = gr.ColorPicker(label="لون شريط الحالة
|
| 346 |
-
enable_splash = gr.Checkbox(label="تفعيل شاشة البداية
|
| 347 |
-
splash_text = gr.Textbox(label="نص شاشة البداية
|
| 348 |
-
splash_color = gr.ColorPicker(label="لون خلفية البداية
|
| 349 |
-
enable_bottom_nav = gr.Checkbox(label="شريط تنقل سفلي
|
| 350 |
-
fullscreen = gr.Checkbox(label="وضع ملء الشاشة
|
| 351 |
-
keep_screen_on = gr.Checkbox(label="إبقاء الشاشة مضاءة دائماً
|
| 352 |
-
|
| 353 |
-
with gr.Accordion("3️⃣ محرك الويب المتقدم |
|
| 354 |
js_enabled = gr.Checkbox(label="تفعيل JavaScript", value=True)
|
| 355 |
-
enable_zoom = gr.Checkbox(label="السماح بتكبير
|
| 356 |
-
dom_storage = gr.Checkbox(label="تفعيل التخزين المحلي (DOM)
|
| 357 |
-
allow_file_access = gr.Checkbox(label="السماح
|
| 358 |
-
media_auto_play = gr.Checkbox(label="تشغيل ال
|
| 359 |
-
clear_cache_exit = gr.Checkbox(label="مسح الكاش عند إغلاق
|
| 360 |
-
custom_user_agent = gr.Textbox(label="User Agent مخصص
|
| 361 |
-
|
| 362 |
-
with gr.Accordion("4️⃣ الحماية والأمان | Security
|
| 363 |
-
enable_security = gr.Checkbox(label="تشفير
|
| 364 |
-
block_root = gr.Checkbox(label="منع
|
| 365 |
-
prevent_screenshots = gr.Checkbox(label="منع
|
| 366 |
-
clear_cookies_exit = gr.Checkbox(label="تسجيل الخروج
|
| 367 |
-
|
| 368 |
-
with gr.Accordion("5️⃣ الإعلانات والخدمات |
|
| 369 |
-
gr.
|
| 370 |
-
|
| 371 |
-
|
| 372 |
-
|
| 373 |
-
|
| 374 |
-
|
| 375 |
-
|
| 376 |
-
|
| 377 |
-
|
| 378 |
-
|
| 379 |
-
|
| 380 |
-
|
| 381 |
-
|
| 382 |
-
|
| 383 |
-
|
| 384 |
-
perm_vibrate = gr.Checkbox(label="الاهتزاز | Vibrate")
|
| 385 |
-
perm_contacts = gr.Checkbox(label="جهات الاتصال | Read Contacts")
|
| 386 |
|
| 387 |
build_btn = gr.Button("🚀 بدء بناء التطبيق | Start Build", variant="primary", size="lg")
|
| 388 |
|
| 389 |
with gr.Group():
|
| 390 |
-
# م
|
| 391 |
-
logs_out = gr.Textbox(label="🖥️ السجلات المباشرة والذكاء الاصطناعي | Live Logs & AI
|
| 392 |
-
file_out = gr.File(label="📥 تحميل التطبيق
|
| 393 |
|
| 394 |
inputs = [
|
| 395 |
app_name, url, package_name, build_format, version_name, version_code, orientation,
|
|
@@ -397,12 +250,12 @@ with gr.Blocks(theme=gr.themes.Base()) as demo:
|
|
| 397 |
icon_path, enable_splash, splash_text, splash_color, status_bar_color, enable_bottom_nav, fullscreen, keep_screen_on,
|
| 398 |
js_enabled, enable_zoom, dom_storage, allow_file_access, clear_cache_exit, custom_user_agent, media_auto_play,
|
| 399 |
enable_security, block_root, prevent_screenshots, clear_cookies_exit,
|
| 400 |
-
enable_ads, admob_banner_id,
|
| 401 |
perm_internet, perm_camera, perm_audio, perm_location, perm_storage, perm_bg, perm_vibrate, perm_contacts
|
| 402 |
]
|
| 403 |
|
| 404 |
build_btn.click(fn=build_ultimate_app, inputs=inputs, outputs=[logs_out, file_out])
|
| 405 |
|
| 406 |
-
#
|
| 407 |
demo.queue(max_size=20, default_concurrency_limit=3)
|
| 408 |
demo.launch(server_name="0.0.0.0", server_port=7860)
|
|
|
|
| 10 |
if "project_info" in log_text or "google-services" in log_text:
|
| 11 |
return "🤖 تحليل AI: هناك مشكلة في بيانات Firebase. تأكد من لصق محتوى google-services.json بشكل صحيح."
|
| 12 |
if "Unresolved reference" in log_text or "Could not resolve" in log_text:
|
| 13 |
+
return "🤖 تحليل AI: فشل في تحميل مكتبات خارجية. تأكد من أن السيرفر متصل بالإنترنت."
|
| 14 |
if "compileReleaseJavaWithJavac" in log_text or "error: " in log_text:
|
| 15 |
+
return "🤖 تحليل AI: خطأ في كود الجافا (Java Syntax Error). تأكد من الروابط واسم الحزمة."
|
| 16 |
+
return "🤖 تحليل AI: فشل البناء. راجع السجلات أعلاه للبحث عن كلمة FAILED."
|
|
|
|
|
|
|
| 17 |
|
| 18 |
# ================== المحرك الرئيسي للبناء ==================
|
| 19 |
def build_ultimate_app(
|
|
|
|
| 20 |
app_name, url, package_name, build_format, version_name, version_code, orientation,
|
| 21 |
dev_name, dev_email,
|
|
|
|
| 22 |
icon_path, enable_splash, splash_text, splash_color, status_bar_color, enable_bottom_nav, fullscreen, keep_screen_on,
|
|
|
|
| 23 |
js_enabled, enable_zoom, dom_storage, allow_file_access, clear_cache_exit, custom_user_agent, media_auto_play,
|
|
|
|
| 24 |
enable_security, block_root, prevent_screenshots, clear_cookies_exit,
|
|
|
|
| 25 |
enable_ads, admob_banner_id, admob_interstitial_id, onesignal_id, firebase_file, firebase_text,
|
|
|
|
| 26 |
perm_internet, perm_camera, perm_audio, perm_location, perm_storage, perm_bg, perm_vibrate, perm_contacts
|
| 27 |
):
|
| 28 |
+
logs = f"[{datetime.datetime.now().strftime('%H:%M:%S')}] 🚀 بدء النظام... تهيئة بيئة البناء.\n"
|
| 29 |
yield logs, None
|
| 30 |
|
| 31 |
project_dir = "/tmp/SuperApp"
|
|
|
|
| 40 |
os.makedirs(f"{res_dir}/{folder}", exist_ok=True)
|
| 41 |
os.makedirs(java_dir, exist_ok=True)
|
| 42 |
|
|
|
|
| 43 |
if icon_path: shutil.copy(icon_path, f"{res_dir}/mipmap-xxxhdpi/ic_launcher.png")
|
| 44 |
else: os.system(f"touch {res_dir}/mipmap-xxxhdpi/ic_launcher.png")
|
| 45 |
|
|
|
|
| 46 |
use_firebase = False
|
| 47 |
fb_content = ""
|
| 48 |
+
if firebase_text and firebase_text.strip() != "": fb_content = firebase_text.strip()
|
|
|
|
| 49 |
elif firebase_file:
|
| 50 |
try:
|
| 51 |
with open(firebase_file, 'r', encoding='utf-8') as f: fb_content = f.read()
|
| 52 |
except: pass
|
| 53 |
|
| 54 |
+
if fb_content and "project_info" in fb_content:
|
| 55 |
+
with open(f"{project_dir}/app/google-services.json", "w", encoding='utf-8') as f: f.write(fb_content)
|
| 56 |
+
use_firebase = True
|
| 57 |
+
logs += "✅ تم دمج Firebase بنجاح.\n"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
yield logs, None
|
| 59 |
|
|
|
|
| 60 |
dev_n = dev_name if dev_name else "Dev"
|
| 61 |
os.system(f'keytool -genkey -v -keystore {project_dir}/app/release.keystore -alias appKey -keyalg RSA -keysize 2048 -validity 10000 -storepass 12345678 -keypass 12345678 -dname "CN={dev_n}, EMAILADDRESS={dev_email}, O=App, C=US" 2>/dev/null')
|
| 62 |
|
|
|
|
| 63 |
with open(f"{project_dir}/settings.gradle", "w") as f: f.write(f"rootProject.name = '{app_name}'\ninclude ':app'\n")
|
|
|
|
| 64 |
with open(f"{project_dir}/build.gradle", "w") as f:
|
| 65 |
f.write(f"""
|
| 66 |
buildscript {{
|
|
|
|
| 76 |
|
| 77 |
with open(f"{project_dir}/app/build.gradle", "w") as f:
|
| 78 |
f.write(f"""
|
| 79 |
+
plugins {{ id 'com.android.application'; {'id "com.onesignal.androidsdk.onesignal-gradle-plugin"' if onesignal_id else ''}; {'id "com.google.gms.google-services"' if use_firebase else ''} }}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 80 |
android {{
|
| 81 |
namespace '{package_name}'
|
| 82 |
compileSdk 34
|
|
|
|
| 88 |
versionName "{version_name}"
|
| 89 |
{f'manifestPlaceholders = [onesignal_app_id: "{onesignal_id}", onesignal_google_project_number: "REMOTE"]' if onesignal_id else ''}
|
| 90 |
}}
|
| 91 |
+
signingConfigs {{ release {{ storeFile file("release.keystore"); storePassword "12345678"; keyAlias "appKey"; keyPassword "12345678" }} }}
|
| 92 |
+
buildTypes {{ release {{ minifyEnabled {str(enable_security).lower()}; shrinkResources {str(enable_security).lower()}; proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'); signingConfig signingConfigs.release }} }}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 93 |
}}
|
| 94 |
dependencies {{
|
| 95 |
implementation 'androidx.appcompat:appcompat:1.6.1'
|
|
|
|
| 101 |
}}
|
| 102 |
""")
|
| 103 |
|
|
|
|
| 104 |
with open(f"{res_dir}/values/styles.xml", "w") as f:
|
| 105 |
+
f.write(f"""<resources><style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar"><item name="android:statusBarColor">{status_bar_color}</item></style></resources>""")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 106 |
|
| 107 |
with open(f"{res_dir}/layout/activity_main.xml", "w") as f:
|
| 108 |
+
f.write(f"""<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"><androidx.swiperefreshlayout.widget.SwipeRefreshLayout android:id="@+id/swipeContainer" android:layout_width="match_parent" android:layout_height="match_parent"><WebView android:id="@+id/webview" android:layout_width="match_parent" android:layout_height="match_parent" /></androidx.swiperefreshlayout.widget.SwipeRefreshLayout></RelativeLayout>""")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 109 |
|
|
|
|
| 110 |
if enable_splash:
|
| 111 |
with open(f"{res_dir}/layout/activity_splash.xml", "w") as f:
|
| 112 |
+
f.write(f"""<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="{splash_color}" android:gravity="center"><ImageView android:id="@+id/logo" android:layout_width="150dp" android:layout_height="150dp" android:src="@mipmap/ic_launcher" /><TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="{splash_text}" android:textColor="#FFFFFF" android:textSize="20sp" android:layout_below="@id/logo" android:layout_marginTop="20dp" android:layout_centerHorizontal="true"/></RelativeLayout>""")
|
| 113 |
+
with open(f"{java_dir}/SplashActivity.java", "w") as f:
|
| 114 |
+
f.write(f"package {package_name}; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.os.Handler; public class SplashActivity extends Activity {{ @Override protected void onCreate(Bundle savedInstanceState) {{ super.onCreate(savedInstanceState); setContentView(R.layout.activity_splash); new Handler().postDelayed(() -> {{ startActivity(new Intent(SplashActivity.this, MainActivity.class)); finish(); }}, 2500); }} }}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 115 |
|
| 116 |
u_agent = f'ws.setUserAgentString("{custom_user_agent}");' if custom_user_agent else ""
|
|
|
|
| 117 |
main_java = f"""package {package_name};
|
| 118 |
+
import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.WindowManager; import android.webkit.CookieManager; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.webkit.WebChromeClient; import android.webkit.WebResourceRequest; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
{'import com.onesignal.OneSignal;' if onesignal_id else ''}
|
|
|
|
| 120 |
public class MainActivity extends Activity {{
|
| 121 |
+
private WebView myWebView; private SwipeRefreshLayout swipeLayout;
|
|
|
|
|
|
|
|
|
|
| 122 |
@Override protected void onCreate(Bundle savedInstanceState) {{
|
| 123 |
super.onCreate(savedInstanceState);
|
|
|
|
|
|
|
| 124 |
{'getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);' if prevent_screenshots else ''}
|
| 125 |
{'getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);' if keep_screen_on else ''}
|
|
|
|
| 126 |
{'if(android.os.Build.VERSION.SDK_INT >= 28) getWindow().getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;' if fullscreen else ''}
|
| 127 |
+
{'getWindow().getDecorView().setSystemUiVisibility(android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | android.view.View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | android.view.View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);' if fullscreen else ''}
|
| 128 |
+
if (android.os.Build.VERSION.SDK_INT >= 33 && checkSelfPermission(android.Manifest.permission.POST_NOTIFICATIONS) != android.content.pm.PackageManager.PERMISSION_GRANTED) requestPermissions(new String[]{{android.Manifest.permission.POST_NOTIFICATIONS}}, 101);
|
| 129 |
+
{f'OneSignal.initWithContext(this); OneSignal.setAppId("{onesignal_id}");' if onesignal_id else ''}
|
| 130 |
+
setContentView(R.layout.activity_main); myWebView = findViewById(R.id.webview); swipeLayout = findViewById(R.id.swipeContainer); swipeLayout.setOnRefreshListener(() -> myWebView.reload());
|
| 131 |
+
WebSettings ws = myWebView.getSettings(); ws.setJavaScriptEnabled({str(js_enabled).lower()}); ws.setDomStorageEnabled({str(dom_storage).lower()}); ws.setAllowFileAccess({str(allow_file_access).lower()}); ws.setMediaPlaybackRequiresUserGesture({str(not media_auto_play).lower()}); ws.setSupportZoom({str(enable_zoom).lower()}); ws.setBuiltInZoomControls({str(enable_zoom).lower()}); ws.setDisplayZoomControls(false); ws.setSupportMultipleWindows(true); ws.setJavaScriptCanOpenWindowsAutomatically(true); {u_agent}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 132 |
myWebView.setWebViewClient(new WebViewClient() {{
|
| 133 |
@Override public void onPageFinished(WebView view, String url) {{ swipeLayout.setRefreshing(false); }}
|
| 134 |
@Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {{
|
| 135 |
String reqUrl = request.getUrl().toString();
|
| 136 |
+
if (reqUrl.startsWith("http")) {{ if(reqUrl.contains("accounts.google.com")) {{ startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(reqUrl))); return true; }} return false; }}
|
| 137 |
+
try {{ startActivity(Intent.parseUri(reqUrl, Intent.URI_INTENT_SCHEME)); return true; }} catch (Exception e) {{ return false; }}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 138 |
}}
|
| 139 |
}});
|
| 140 |
+
myWebView.setWebChromeClient(new WebChromeClient()); myWebView.loadUrl("{url}");
|
|
|
|
| 141 |
}}
|
| 142 |
+
@Override protected void onDestroy() {{ {'myWebView.clearCache(true);' if clear_cache_exit else ''} super.onDestroy(); }}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 143 |
@Override public void onBackPressed() {{ if (myWebView.canGoBack()) myWebView.goBack(); else super.onBackPressed(); }}
|
| 144 |
}}"""
|
| 145 |
with open(f"{java_dir}/MainActivity.java", "w") as f: f.write(main_java)
|
| 146 |
|
| 147 |
+
perms = ["INTERNET", "ACCESS_NETWORK_STATE"]
|
|
|
|
|
|
|
| 148 |
if perm_camera: perms.append("CAMERA")
|
| 149 |
+
if perm_audio: perms.append("RECORD_AUDIO")
|
| 150 |
if perm_location: perms.extend(["ACCESS_FINE_LOCATION", "ACCESS_COARSE_LOCATION"])
|
| 151 |
if perm_storage: perms.extend(["READ_EXTERNAL_STORAGE", "WRITE_EXTERNAL_STORAGE"])
|
| 152 |
if perm_bg: perms.append("REQUEST_IGNORE_BATTERY_OPTIMIZATIONS")
|
| 153 |
if perm_vibrate: perms.append("VIBRATE")
|
| 154 |
if perm_contacts: perms.append("READ_CONTACTS")
|
| 155 |
if onesignal_id or use_firebase: perms.append("POST_NOTIFICATIONS")
|
|
|
|
| 156 |
perms_xml = "\n".join([f'<uses-permission android:name="android.permission.{p}" />' for p in perms])
|
|
|
|
| 157 |
|
| 158 |
+
manifest_xml = f"""<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="{package_name}">{perms_xml}<application android:label="{app_name}" android:icon="@mipmap/ic_launcher" android:theme="@style/AppTheme" android:usesCleartextTraffic="true" android:hardwareAccelerated="true">{'<meta-data android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="' + admob_banner_id + '"/>' if enable_ads and admob_banner_id else ''}{f'<activity android:name=".SplashActivity" android:exported="true" android:screenOrientation="portrait"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity>' if enable_splash else ''}<activity android:name=".MainActivity" android:exported="true" android:screenOrientation="{orientation}" android:configChanges="orientation|keyboardHidden|screenSize">{'' if enable_splash else '<intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter>'}</activity></application></manifest>"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 159 |
with open(f"{project_dir}/app/src/main/AndroidManifest.xml", "w") as f: f.write(manifest_xml)
|
| 160 |
|
| 161 |
+
logs += "⚙️ بدء عملية التجميع... سجلات Gradle المباشرة:\n" + "="*40 + "\n"
|
| 162 |
yield logs, None
|
| 163 |
|
|
|
|
| 164 |
gradle_cmd = "gradle bundleRelease" if build_format == "aab" else "gradle assembleRelease"
|
| 165 |
process = subprocess.Popen(gradle_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, cwd=project_dir, bufsize=1, universal_newlines=True)
|
| 166 |
|
|
|
|
| 169 |
for line in iter(process.stdout.readline, ''):
|
| 170 |
log_buffer.append(line)
|
| 171 |
full_error_log += line
|
| 172 |
+
if len(log_buffer) > 40: log_buffer.pop(0)
|
| 173 |
yield logs + "".join(log_buffer), None
|
|
|
|
| 174 |
process.wait()
|
| 175 |
|
|
|
|
| 176 |
if process.returncode == 0:
|
| 177 |
+
out_p = f"{project_dir}/app/build/outputs/bundle/release/app-release.aab" if build_format == "aab" else f"{project_dir}/app/build/outputs/apk/release/app-release.apk"
|
| 178 |
+
yield logs + "".join(log_buffer) + "\n\n✅ تم بناء التطبيق بنجاح!", out_p
|
|
|
|
| 179 |
else:
|
| 180 |
+
yield logs + "".join(log_buffer) + f"\n\n❌ فشل البناء.\n{analyze_error_ai(full_error_log)}", None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 181 |
|
| 182 |
+
# ================== واجهة المستخدم (Gradio UI المصلحة) ==================
|
| 183 |
+
with gr.Blocks() as demo:
|
| 184 |
+
gr.Markdown("<h1 style='text-align: center;'>📱 مصنع التطبيقات الشامل - الإصدار الذهبي V2</h1>")
|
| 185 |
+
|
| 186 |
with gr.Accordion("1️⃣ الأساسيات | Core Basics", open=True):
|
| 187 |
+
app_name = gr.Textbox(label="اسم التطبيق | App Name", value="تطبيقي")
|
| 188 |
url = gr.Textbox(label="الرابط | Website URL", value="https://google.com")
|
| 189 |
+
package_name = gr.Textbox(label="اسم الحزمة | Package Name", value="com.vip.app")
|
| 190 |
build_format = gr.Dropdown(choices=["apk", "aab"], value="apk", label="صيغة الإخراج | Output Format")
|
| 191 |
with gr.Row():
|
| 192 |
version_name = gr.Textbox(label="الإصدار | Version", value="1.0.0")
|
| 193 |
version_code = gr.Number(label="كود الإصدار | Version Code", value=1)
|
| 194 |
+
orientation = gr.Dropdown(choices=["unspecified", "portrait", "landscape"], value="unspecified", label="اتجاه الشاشة")
|
| 195 |
+
dev_name = gr.Textbox(label="اسم المطور (للتوقيع)")
|
| 196 |
+
dev_email = gr.Textbox(label="البريد الإلكتروني")
|
| 197 |
|
| 198 |
with gr.Accordion("2️⃣ التصميم والواجهة | UI & Design", open=False):
|
| 199 |
+
icon_path = gr.File(label="الأيقونة | App Icon")
|
| 200 |
+
status_bar_color = gr.ColorPicker(label="لون شريط الحالة", value="#000000")
|
| 201 |
+
enable_splash = gr.Checkbox(label="تفعيل شاشة البداية", value=False)
|
| 202 |
+
splash_text = gr.Textbox(label="نص شاشة البداية", value="جاري التحميل...")
|
| 203 |
+
splash_color = gr.ColorPicker(label="لون خلفية البداية", value="#121212")
|
| 204 |
+
enable_bottom_nav = gr.Checkbox(label="شريط تنقل سفلي", value=False)
|
| 205 |
+
fullscreen = gr.Checkbox(label="وضع ملء الشاشة", value=False)
|
| 206 |
+
keep_screen_on = gr.Checkbox(label="إبقاء الشاشة مضاءة دائماً", value=False)
|
| 207 |
+
|
| 208 |
+
with gr.Accordion("3️⃣ محرك الويب المتقدم | Web Engine", open=False):
|
| 209 |
js_enabled = gr.Checkbox(label="تفعيل JavaScript", value=True)
|
| 210 |
+
enable_zoom = gr.Checkbox(label="السماح بالتكبير", value=False)
|
| 211 |
+
dom_storage = gr.Checkbox(label="تفعيل التخزين المحلي (DOM)", value=True)
|
| 212 |
+
allow_file_access = gr.Checkbox(label="السماح برفع/قراءة الملفات", value=True)
|
| 213 |
+
media_auto_play = gr.Checkbox(label="تشغيل الوسائط تلقائياً", value=True)
|
| 214 |
+
clear_cache_exit = gr.Checkbox(label="مسح الكاش عند الإغلاق", value=False)
|
| 215 |
+
custom_user_agent = gr.Textbox(label="User Agent مخصص")
|
| 216 |
+
|
| 217 |
+
with gr.Accordion("4️⃣ الحماية والأمان | Security", open=False):
|
| 218 |
+
enable_security = gr.Checkbox(label="تشفير الكود (ProGuard)", value=True)
|
| 219 |
+
block_root = gr.Checkbox(label="منع الروت والمحاكيات", value=False)
|
| 220 |
+
prevent_screenshots = gr.Checkbox(label="منع لقطات الشاشة", value=False)
|
| 221 |
+
clear_cookies_exit = gr.Checkbox(label="تسجيل الخروج (مسح الكوكيز) عند الإغلاق", value=False)
|
| 222 |
+
|
| 223 |
+
with gr.Accordion("5️⃣ الإعلانات والخدمات | Services", open=False):
|
| 224 |
+
firebase_file = gr.File(label="ملف Firebase json")
|
| 225 |
+
firebase_text = gr.Textbox(label="أو الصق كود Firebase هنا", lines=3)
|
| 226 |
+
onesignal_id = gr.Textbox(label="معرف OneSignal")
|
| 227 |
+
enable_ads = gr.Checkbox(label="تفعيل AdMob", value=False)
|
| 228 |
+
admob_banner_id = gr.Textbox(label="AdMob ID")
|
| 229 |
+
|
| 230 |
+
with gr.Accordion("6️⃣ الأذونات | Permissions", open=False):
|
| 231 |
+
perm_internet = gr.Checkbox(label="الإنترنت", value=True, interactive=False)
|
| 232 |
+
perm_camera = gr.Checkbox(label="الكاميرا")
|
| 233 |
+
perm_audio = gr.Checkbox(label="الميكروفون")
|
| 234 |
+
perm_location = gr.Checkbox(label="الموقع")
|
| 235 |
+
perm_storage = gr.Checkbox(label="الملفات")
|
| 236 |
+
perm_bg = gr.Checkbox(label="العمل في الخلفية")
|
| 237 |
+
perm_vibrate = gr.Checkbox(label="الاهتزاز")
|
| 238 |
+
perm_contacts = gr.Checkbox(label="جهات الاتصال")
|
|
|
|
|
|
|
| 239 |
|
| 240 |
build_btn = gr.Button("🚀 بدء بناء التطبيق | Start Build", variant="primary", size="lg")
|
| 241 |
|
| 242 |
with gr.Group():
|
| 243 |
+
# تم إزالة show_copy_button لحل مشكلة الخطأ
|
| 244 |
+
logs_out = gr.Textbox(label="🖥️ السجلات المباشرة والذكاء الاصطناعي | Live Logs & AI", lines=12, max_lines=15)
|
| 245 |
+
file_out = gr.File(label="📥 تحميل التطبيق")
|
| 246 |
|
| 247 |
inputs = [
|
| 248 |
app_name, url, package_name, build_format, version_name, version_code, orientation,
|
|
|
|
| 250 |
icon_path, enable_splash, splash_text, splash_color, status_bar_color, enable_bottom_nav, fullscreen, keep_screen_on,
|
| 251 |
js_enabled, enable_zoom, dom_storage, allow_file_access, clear_cache_exit, custom_user_agent, media_auto_play,
|
| 252 |
enable_security, block_root, prevent_screenshots, clear_cookies_exit,
|
| 253 |
+
enable_ads, admob_banner_id, gr.State(""), onesignal_id, firebase_file, firebase_text,
|
| 254 |
perm_internet, perm_camera, perm_audio, perm_location, perm_storage, perm_bg, perm_vibrate, perm_contacts
|
| 255 |
]
|
| 256 |
|
| 257 |
build_btn.click(fn=build_ultimate_app, inputs=inputs, outputs=[logs_out, file_out])
|
| 258 |
|
| 259 |
+
# التوافق مع Gradio 6.0
|
| 260 |
demo.queue(max_size=20, default_concurrency_limit=3)
|
| 261 |
demo.launch(server_name="0.0.0.0", server_port=7860)
|