Poorpoor6976 commited on
Commit
20c8748
·
verified ·
1 Parent(s): b954321

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +225 -0
app.py ADDED
@@ -0,0 +1,225 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ import subprocess
4
+ import shutil
5
+
6
+ def build_app(app_name, url, package_name, build_format, orientation, icon_path, enable_splash, splash_text, fullscreen, encrypt_app, js_enabled, onesignal_id, firebase_path, permissions):
7
+ logs = "🚀 بدء تهيئة بيئة العمل وبناء المشروع...\n"
8
+ yield logs, None
9
+
10
+ project_dir = "/tmp/ProApp"
11
+ if os.path.exists(project_dir):
12
+ shutil.rmtree(project_dir)
13
+ os.makedirs(project_dir, exist_ok=True)
14
+
15
+ package_path = package_name.replace('.', '/')
16
+ java_dir = f"{project_dir}/app/src/main/java/{package_path}"
17
+ res_dir = f"{project_dir}/app/src/main/res"
18
+
19
+ for folder in ['layout', 'values', 'mipmap-xxxhdpi', 'drawable', 'anim']:
20
+ os.makedirs(f"{res_dir}/{folder}", exist_ok=True)
21
+ os.makedirs(java_dir, exist_ok=True)
22
+
23
+ # معالجة الأيقونة
24
+ if icon_path:
25
+ shutil.copy(icon_path, f"{res_dir}/mipmap-xxxhdpi/ic_launcher.png")
26
+ else:
27
+ os.system(f"touch {res_dir}/mipmap-xxxhdpi/ic_launcher.png")
28
+
29
+ # معالجة Firebase
30
+ use_firebase = False
31
+ if firebase_path:
32
+ try:
33
+ shutil.copy(firebase_path, f"{project_dir}/app/google-services.json")
34
+ use_firebase = True
35
+ logs += "✅ تم دمج ملف Firebase بنجاح\n"
36
+ yield logs, None
37
+ except:
38
+ logs += "⚠️ تحذير: فشل في قراءة ملف Firebase المرفوع.\n"
39
+ yield logs, None
40
+
41
+ # مفتاح التوقيع
42
+ os.system(f'keytool -genkey -v -keystore {project_dir}/app/release.keystore -alias appKey -keyalg RSA -keysize 2048 -validity 10000 -storepass 123456 -keypass 123456 -dname "CN=Pro, OU=App, O=Org, L=City, S=State, C=US" 2>/dev/null')
43
+
44
+ # كتابة إعدادات Gradle
45
+ with open(f"{project_dir}/settings.gradle", "w") as f:
46
+ f.write(f"rootProject.name = '{app_name}'\ninclude ':app'\n")
47
+
48
+ with open(f"{project_dir}/build.gradle", "w") as f:
49
+ f.write(f"""
50
+ buildscript {{
51
+ repositories {{ google(); mavenCentral(); gradlePluginPortal() }}
52
+ dependencies {{
53
+ classpath 'com.android.tools.build:gradle:7.4.2'
54
+ classpath 'gradle.plugin.com.onesignal:onesignal-gradle-plugin:[0.12.10, 0.99.99]'
55
+ {'classpath "com.google.gms:google-services:4.3.15"' if use_firebase else ''}
56
+ }}
57
+ }}
58
+ allprojects {{ repositories {{ google(); mavenCentral() }} }}
59
+ """)
60
+
61
+ with open(f"{project_dir}/app/build.gradle", "w") as f:
62
+ f.write(f"""
63
+ plugins {{
64
+ id 'com.android.application'
65
+ {'id "com.onesignal.androidsdk.onesignal-gradle-plugin"' if onesignal_id else ''}
66
+ {'id "com.google.gms.google-services"' if use_firebase else ''}
67
+ }}
68
+ android {{
69
+ namespace '{package_name}'
70
+ compileSdk 33
71
+ defaultConfig {{
72
+ applicationId "{package_name}"
73
+ minSdk 24
74
+ targetSdk 33
75
+ versionCode 1
76
+ versionName "1.0"
77
+ {f'manifestPlaceholders = [onesignal_app_id: "{onesignal_id}", onesignal_google_project_number: "REMOTE"]' if onesignal_id else ''}
78
+ }}
79
+ signingConfigs {{
80
+ release {{ storeFile file("release.keystore"); storePassword "123456"; keyAlias "appKey"; keyPassword "123456" }}
81
+ }}
82
+ buildTypes {{
83
+ release {{ minifyEnabled {str(encrypt_app).lower()}; signingConfig signingConfigs.release }}
84
+ }}
85
+ }}
86
+ dependencies {{
87
+ implementation 'androidx.appcompat:appcompat:1.6.1'
88
+ {'implementation "com.onesignal:OneSignal:[4.0.0, 4.99.99]"' if onesignal_id else ''}
89
+ {'implementation platform("com.google.firebase:firebase-bom:32.1.1"); implementation "com.google.firebase:firebase-messaging"' if use_firebase else ''}
90
+ }}
91
+ """)
92
+
93
+ # ملفات الموارد و XML
94
+ with open(f"{res_dir}/values/styles.xml", "w") as f:
95
+ f.write("""<resources><style name="AppTheme" parent="@android:style/Theme.NoTitleBar.Fullscreen" /></resources>""")
96
+
97
+ with open(f"{res_dir}/layout/activity_main.xml", "w") as f:
98
+ f.write("""<?xml version="1.0" encoding="utf-8"?>
99
+ <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent">
100
+ <WebView android:id="@+id/webview" android:layout_width="match_parent" android:layout_height="match_parent" />
101
+ </RelativeLayout>""")
102
+
103
+ # كود MainActivity
104
+ notch_fix = "if(android.os.Build.VERSION.SDK_INT >= 28) getWindow().getAttributes().layoutInDisplayCutoutMode = android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;" if fullscreen else ""
105
+ fullscreen_code = "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 | android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | android.view.View.SYSTEM_UI_FLAG_FULLSCREEN);" if fullscreen else ""
106
+
107
+ main_java = f"""package {package_name};
108
+ import android.app.Activity;
109
+ import android.os.Bundle;
110
+ import android.webkit.WebSettings;
111
+ import android.webkit.WebView;
112
+ import android.webkit.WebViewClient;
113
+ {'import com.onesignal.OneSignal;' if onesignal_id else ''}
114
+
115
+ public class MainActivity extends Activity {{
116
+ private WebView myWebView;
117
+ @Override protected void onCreate(Bundle savedInstanceState) {{
118
+ super.onCreate(savedInstanceState);
119
+ {notch_fix}
120
+ {fullscreen_code}
121
+
122
+ if (android.os.Build.VERSION.SDK_INT >= 33 && checkSelfPermission(android.Manifest.permission.POST_NOTIFICATIONS) != android.content.pm.PackageManager.PERMISSION_GRANTED) {{
123
+ requestPermissions(new String[]{{android.Manifest.permission.POST_NOTIFICATIONS}}, 101);
124
+ }}
125
+
126
+ {f'OneSignal.setLogLevel(OneSignal.LOG_LEVEL.VERBOSE, OneSignal.LOG_LEVEL.NONE); OneSignal.initWithContext(this); OneSignal.setAppId("{onesignal_id}");' if onesignal_id else ''}
127
+
128
+ setContentView(R.layout.activity_main);
129
+ myWebView = findViewById(R.id.webview);
130
+
131
+ WebSettings ws = myWebView.getSettings();
132
+ ws.setJavaScriptEnabled({str(js_enabled).lower()});
133
+ ws.setDomStorageEnabled(true);
134
+
135
+ myWebView.setWebViewClient(new WebViewClient());
136
+ myWebView.loadUrl("{url}");
137
+ }}
138
+ @Override public void onBackPressed() {{ if (myWebView.canGoBack()) myWebView.goBack(); else super.onBackPressed(); }}
139
+ }}"""
140
+ with open(f"{java_dir}/MainActivity.java", "w") as f: f.write(main_java)
141
+
142
+ # ملف AndroidManifest
143
+ perms_xml = "\n".join([f'<uses-permission android:name="android.permission.{p}" />' for p in permissions])
144
+ if onesignal_id or use_firebase: perms_xml += '\n<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>'
145
+
146
+ manifest_xml = f"""<?xml version="1.0" encoding="utf-8"?>
147
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="{package_name}">
148
+ <uses-permission android:name="android.permission.INTERNET" />
149
+ {perms_xml}
150
+ <application android:label="{app_name}" android:icon="@mipmap/ic_launcher" android:theme="@style/AppTheme" android:usesCleartextTraffic="true">
151
+ <activity android:name=".MainActivity" android:exported="true" android:screenOrientation="{orientation}" android:configChanges="orientation|keyboardHidden|screenSize">
152
+ <intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter>
153
+ </activity>
154
+ </application>
155
+ </manifest>"""
156
+ with open(f"{project_dir}/app/src/main/AndroidManifest.xml", "w") as f: f.write(manifest_xml)
157
+
158
+ logs += "⚙️ بدء عملية التجميع بواسطة Gradle (قد يستغرق دقائق)...\n"
159
+ yield logs, None
160
+
161
+ # تنفيذ أمر البناء
162
+ gradle_cmd = "gradle bundleRelease" if build_format == "aab" else "gradle assembleRelease"
163
+ process = subprocess.Popen(gradle_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, cwd=project_dir)
164
+
165
+ for line in process.stdout:
166
+ logs += line
167
+ yield logs, None
168
+
169
+ process.wait()
170
+
171
+ if process.returncode == 0:
172
+ out_path = 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"
173
+ logs += "\n✅ اكتمل البناء بنجاح! الملف جاهز للتحميل بالأسفل."
174
+ yield logs, out_path
175
+ else:
176
+ logs += "\n❌ فشل البناء. يرجى مراجعة سجلات الخطأ أعلاه."
177
+ yield logs, None
178
+
179
+ # ================== واجهة المستخدم (Gradio UI) ==================
180
+ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue")) as demo:
181
+ gr.Markdown("<h1 style='text-align: center;'>📱 مصنع التطبيقات الشامل - الإصدار السحابي</h1>")
182
+
183
+ with gr.Tabs():
184
+ with gr.Tab("الأساسيات"):
185
+ with gr.Row():
186
+ app_name = gr.Textbox(label="اسم التطبيق", value="تطبيقي الجديد")
187
+ url = gr.Textbox(label="رابط الموقع (URL)", value="https://google.com")
188
+ with gr.Row():
189
+ package_name = gr.Textbox(label="اسم الحزمة", value="com.pro.app")
190
+ build_format = gr.Dropdown(choices=["apk", "aab"], value="apk", label="صيغة التصدير")
191
+ orientation = gr.Dropdown(choices=["unspecified", "portrait", "landscape"], value="unspecified", label="اتجاه ��لشاشة")
192
+
193
+ with gr.Tab("التصميم والأمان"):
194
+ with gr.Row():
195
+ icon_path = gr.Image(type="filepath", label="أيقونة التطبيق (اختياري)")
196
+ firebase_path = gr.File(type="filepath", label="ملف Firebase json (اختياري)")
197
+ with gr.Row():
198
+ enable_splash = gr.Checkbox(label="تفعيل شاشة البداية", value=False)
199
+ splash_text = gr.Textbox(label="نص الشاشة الافتتاحية", value="جاري التحميل...")
200
+ with gr.Row():
201
+ fullscreen = gr.Checkbox(label="وضع ملء الشاشة للألعاب", value=False)
202
+ encrypt_app = gr.Checkbox(label="تشفير الكود (Proguard)", value=True)
203
+ js_enabled = gr.Checkbox(label="دعم JavaScript كامل", value=True)
204
+
205
+ with gr.Tab("الخدمات والصلاحيات"):
206
+ onesignal = gr.Textbox(label="معرف OneSignal (للإشعارات)")
207
+ permissions = gr.CheckboxGroup(
208
+ choices=["CAMERA", "RECORD_AUDIO", "ACCESS_FINE_LOCATION", "READ_EXTERNAL_STORAGE", "WRITE_EXTERNAL_STORAGE"],
209
+ label="الأذونات والصلاحيات"
210
+ )
211
+
212
+ build_btn = gr.Button("🚀 بدء بناء التطبيق", variant="primary", size="lg")
213
+
214
+ with gr.Row():
215
+ logs_out = gr.Textbox(label="شاشة السجلات المباشرة (Live Logs)", lines=15, max_lines=20)
216
+ file_out = gr.File(label="📥 تحميل التطبيق الجاهز")
217
+
218
+ build_btn.click(
219
+ fn=build_app,
220
+ inputs=[app_name, url, package_name, build_format, orientation, icon_path, enable_splash, splash_text, fullscreen, encrypt_app, js_enabled, onesignal, firebase_path, permissions],
221
+ outputs=[logs_out, file_out]
222
+ )
223
+
224
+ demo.queue()
225
+ demo.launch(server_name="0.0.0.0", server_port=7860)