CrimsonSorcerer's picture
Upload 4 files
4f87b7e verified
Raw
History Blame Contribute Delete
4.64 kB
from flask import Flask, request, send_file, jsonify, make_response
import subprocess, os, shutil, uuid
app = Flask(__name__)
def cors(response):
response.headers['Access-Control-Allow-Origin'] = '*'
response.headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
response.headers['Access-Control-Allow-Headers'] = 'Content-Type'
return response
@app.before_request
def handle_options():
if request.method == 'OPTIONS':
return cors(make_response('', 200))
@app.after_request
def after(response):
return cors(response)
@app.route("/", methods=["GET"])
def index():
return jsonify({"status": "HtStudio Python Builder 🚀 (APK + EXE)"})
def make_py_html(py_code, app_name):
escaped = py_code.replace('\\','\\\\').replace('`','\\`').replace('$','\\$')
return f"""<!DOCTYPE html><html><head><meta charset="UTF-8"><title>{app_name}</title>
<script src="https://skulpt.org/js/skulpt.min.js"></script>
<script src="https://skulpt.org/js/skulpt-stdlib.js"></script>
<style>body{{margin:0;background:#1e1e2e;color:#cdd6f4;font-family:monospace;padding:16px;}}
#output{{white-space:pre-wrap;font-size:14px;line-height:1.6;}}.err{{color:#f38ba8;}}</style>
</head><body><div id="output"></div>
<script>
var code=`{escaped}`;
function outf(t){{document.getElementById('output').innerHTML+=t;}}
function builtinRead(x){{if(Sk.builtinFiles===undefined||Sk.builtinFiles["files"][x]===undefined)throw "File not found: '"+x+"'";return Sk.builtinFiles["files"][x];}}
Sk.configure({{output:outf,read:builtinRead}});
Sk.misceval.asyncToPromise(()=>Sk.importMainWithBody("<stdin>",false,code,true))
.catch(e=>{{var el=document.createElement('div');el.className='err';el.textContent='Hata: '+e.toString();document.getElementById('output').appendChild(el);}});
</script></body></html>"""
@app.route("/build-python", methods=["POST"])
def build_python_apk():
data = request.get_json(force=True)
py_code = data.get("code", "")
app_name = data.get("name", "HtApp").strip().replace(" ", "_")
pkg_name = data.get("pkg", "com.htstudio.app").strip()
if not py_code.strip():
return jsonify({"error": "Python kodu boş"}), 400
job_id = str(uuid.uuid4())[:8]
work_dir = f"/tmp/build_py_{job_id}"
os.makedirs(work_dir, exist_ok=True)
try:
with open(f"{work_dir}/index.html", "w", encoding="utf-8") as f:
f.write(make_py_html(py_code, app_name))
result = subprocess.run(
["bash", "/app/build_apk.sh", work_dir, app_name, pkg_name, "/opt/debug.keystore"],
stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, timeout=120
)
if result.returncode != 0:
return jsonify({"error": "Python APK başarısız", "log": result.stdout[-3000:]}), 500
apk_path = f"{work_dir}/output.apk"
if not os.path.exists(apk_path):
return jsonify({"error": "APK oluşturulamadı", "log": result.stdout[-3000:]}), 500
return send_file(apk_path, as_attachment=True,
download_name=f"{app_name}_HtStudio.apk",
mimetype="application/vnd.android.package-archive")
finally:
shutil.rmtree(work_dir, ignore_errors=True)
@app.route("/build-python-exe", methods=["POST"])
def build_python_exe():
data = request.get_json(force=True)
py_code = data.get("code", "")
app_name = data.get("name", "HtApp").strip().replace(" ", "_")
pkg_name = data.get("pkg", "com.htstudio.app").strip()
if not py_code.strip():
return jsonify({"error": "Python kodu boş"}), 400
job_id = str(uuid.uuid4())[:8]
work_dir = f"/tmp/build_pyexe_{job_id}"
os.makedirs(work_dir, exist_ok=True)
try:
with open(f"{work_dir}/index.html", "w", encoding="utf-8") as f:
f.write(make_py_html(py_code, app_name))
result = subprocess.run(
["bash", "/app/build_exe.sh", work_dir, app_name, pkg_name],
stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, timeout=300
)
if result.returncode != 0:
return jsonify({"error": "Python EXE başarısız", "log": result.stdout[-3000:]}), 500
exe_path = f"{work_dir}/output.exe"
if not os.path.exists(exe_path):
return jsonify({"error": "EXE oluşturulamadı", "log": result.stdout[-3000:]}), 500
return send_file(exe_path, as_attachment=True,
download_name=f"{app_name}_HtStudio.exe",
mimetype="application/octet-stream")
finally:
shutil.rmtree(work_dir, ignore_errors=True)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=7860)