Spaces:
Sleeping
Sleeping
| import subprocess | |
| import threading | |
| import os | |
| import glob | |
| from flask import Flask, render_template_string, send_from_directory | |
| from flask_socketio import SocketIO | |
| app = Flask(__name__) | |
| socketio = SocketIO(app, async_mode='eventlet') | |
| HTML_PAGE = """ | |
| <!DOCTYPE html> | |
| <html lang="ar"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>Ajij APK Grinder - Pro Edition</title> | |
| <style> | |
| body { background: #0d1117; color: #39ff14; font-family: 'Consolas', monospace; padding: 20px; } | |
| .container { border: 2px solid #39ff14; padding: 20px; border-radius: 10px; background: #161b22; } | |
| textarea { width: 100%; height: 200px; background: #000; color: #fff; border: 1px solid #30363d; padding: 10px; border-radius: 5px; font-family: monospace; } | |
| #logs { width: 100%; height: 450px; background: #000; border: 1px solid #39ff14; margin-top: 20px; overflow-y: auto; padding: 10px; white-space: pre-wrap; font-size: 11px; color: #adbac7; } | |
| button { background: #238636; color: white; border: none; padding: 15px 30px; cursor: pointer; font-weight: bold; border-radius: 5px; margin-top: 10px; width: 100%; font-size: 18px; } | |
| button:disabled { background: #333; color: #666; cursor: not-allowed; } | |
| .download-link { display: none; margin-top: 20px; padding: 15px; background: #39ff14; color: #000; text-decoration: none; font-weight: bold; border-radius: 5px; text-align: center; } | |
| .status-bar { margin-bottom: 10px; font-weight: bold; } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <h1>🚀 AJIJ APK GRINDER v3.0</h1> | |
| <div class="status-bar" id="status">Status: Ready</div> | |
| <textarea id="code" placeholder="حط كود Kivy هنا..."></textarea><br> | |
| <button id="buildBtn" onclick="startBuild()">START GRINDING (طحن)</button> | |
| <a id="downloadBtn" class="download-link" href="#">⬇️ DOWNLOAD READY APK</a> | |
| <div id="logs">-- Logs will appear here --</div> | |
| </div> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js"></script> | |
| <script> | |
| var socket = io(); | |
| var buildBtn = document.getElementById('buildBtn'); | |
| var downloadBtn = document.getElementById('downloadBtn'); | |
| var statusDisp = document.getElementById('status'); | |
| socket.on('log', function(msg) { | |
| var logs = document.getElementById('logs'); | |
| logs.innerText += msg + '\\n'; | |
| logs.scrollTop = logs.scrollHeight; | |
| }); | |
| socket.on('status_update', function(msg) { | |
| statusDisp.innerText = "Status: " + msg; | |
| }); | |
| socket.on('build_complete', function(data) { | |
| buildBtn.disabled = false; | |
| if(data.success) { | |
| statusDisp.innerText = "Status: Finished Successfully!"; | |
| downloadBtn.href = "/download/" + data.filename; | |
| downloadBtn.style.display = "block"; | |
| } else { | |
| statusDisp.innerText = "Status: Failed!"; | |
| } | |
| }); | |
| function startBuild() { | |
| var code = document.getElementById('code').value; | |
| if(!code) return alert("الكود خاوي!"); | |
| buildBtn.disabled = true; | |
| downloadBtn.style.display = "none"; | |
| document.getElementById('logs').innerText = ""; | |
| socket.emit('start_build', {code: code}); | |
| } | |
| </script> | |
| </body> | |
| </html> | |
| """ | |
| def index(): | |
| return render_template_string(HTML_PAGE) | |
| def download(filename): | |
| return send_from_directory('bin', filename, as_attachment=True) | |
| def emit_log(msg): | |
| socketio.emit('log', msg) | |
| def run_command(cmd, desc): | |
| socketio.emit('status_update', desc) | |
| emit_log(f"\\n>>> Executing: {desc}\\n") | |
| process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True, text=True) | |
| for line in iter(process.stdout.readline, ''): | |
| emit_log(line.strip()) | |
| process.stdout.close() | |
| return process.wait() | |
| def build_logic(): | |
| # 1. تثبيت Cython النسخة المناسبة | |
| run_command("pip install --user cython==0.29.33", "Installing Cython") | |
| # 2. الموافقة الأوتوماتيكية على التراخيص (الحل لمشكل الحبسة اللي وقع ليك) | |
| sdk_path = "/home/user/.buildozer/android/platform/android-sdk" | |
| if os.path.exists(sdk_path): | |
| license_cmd = f"yes | {sdk_path}/tools/bin/sdkmanager --sdk_root={sdk_path} --licenses" | |
| run_command(license_cmd, "Accepting Android Licenses") | |
| # 3. البدء في الطحن الحقيقي | |
| exit_code = run_command("buildozer -v android debug", "Grinding APK (This will take time)") | |
| # 4. التحقق من النتيجة | |
| apk_files = glob.glob("bin/*.apk") | |
| if exit_code == 0 and apk_files: | |
| latest_apk = os.path.basename(apk_files[-1]) | |
| emit_log(f"\\n✅ DONE! APK: {latest_apk}") | |
| socketio.emit('build_complete', {'success': True, 'filename': latest_apk}) | |
| else: | |
| emit_log("\\n❌ ERROR: Build failed or APK not found.") | |
| socketio.emit('build_complete', {'success': False}) | |
| def handle_build(data): | |
| with open("main.py", "w") as f: | |
| f.write(data['code']) | |
| socketio.start_background_task(target=build_logic) | |
| if __name__ == '__main__': | |
| socketio.run(app, host='0.0.0.0', port=7860) | |