Asi / interface.py
monsefkoko's picture
Update interface.py
afa0430 verified
Raw
History Blame Contribute Delete
5.44 kB
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>
"""
@app.route('/')
def index():
return render_template_string(HTML_PAGE)
@app.route('/download/<path:filename>')
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})
@socketio.on('start_build')
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)