|
|
import os |
|
|
import subprocess |
|
|
from flask import Flask, request, render_template, send_from_directory, flash, redirect, url_for |
|
|
from werkzeug.utils import secure_filename |
|
|
|
|
|
app = Flask(__name__) |
|
|
app.secret_key = 'supersecretkey' |
|
|
UPLOAD_FOLDER = 'uploads' |
|
|
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER |
|
|
|
|
|
if not os.path.exists(UPLOAD_FOLDER): |
|
|
os.makedirs(UPLOAD_FOLDER) |
|
|
|
|
|
@app.route('/') |
|
|
def index(): |
|
|
"""Renders the main page with the URL input form.""" |
|
|
return render_template('index.html') |
|
|
|
|
|
@app.route('/build', methods=['POST']) |
|
|
def build_apk(): |
|
|
"""Handles the form submission and initiates the APK build.""" |
|
|
url = request.form.get('url') |
|
|
if not url: |
|
|
flash('Please provide a URL.') |
|
|
return redirect(url_for('index')) |
|
|
|
|
|
|
|
|
project_name = secure_filename(url.replace('https://', '').replace('http://', '').replace('.', '_')) |
|
|
project_path = os.path.join(app.config['UPLOAD_FOLDER'], project_name) |
|
|
|
|
|
if not os.path.exists(project_path): |
|
|
os.makedirs(project_path) |
|
|
|
|
|
|
|
|
main_py_content = f""" |
|
|
from kivy.app import App |
|
|
from kivy.uix.boxlayout import BoxLayout |
|
|
from kivy.lang import Builder |
|
|
from kivy.uix.webview import WebView |
|
|
|
|
|
Builder.load_string(''' |
|
|
<WebViewLayout>: |
|
|
orientation: 'vertical' |
|
|
WebView: |
|
|
id: webview |
|
|
url: '{url}' |
|
|
''') |
|
|
|
|
|
class WebViewLayout(BoxLayout): |
|
|
pass |
|
|
|
|
|
class SiteToApkApp(App): |
|
|
def build(self): |
|
|
return WebViewLayout() |
|
|
|
|
|
if __name__ == '__main__': |
|
|
SiteToApkApp().run() |
|
|
""" |
|
|
with open(os.path.join(project_path, 'main.py'), 'w') as f: |
|
|
f.write(main_py_content) |
|
|
|
|
|
|
|
|
with open(os.path.join(project_path, 'requirements.txt'), 'w') as f: |
|
|
f.write('kivy\n') |
|
|
f.write('kivy-webview\n') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
|
subprocess.run(['buildozer', '-v', 'init'], cwd=project_path, check=True) |
|
|
|
|
|
|
|
|
spec_path = os.path.join(project_path, 'buildozer.spec') |
|
|
with open(spec_path, 'r') as f: |
|
|
spec_content = f.read() |
|
|
|
|
|
spec_content = spec_content.replace( |
|
|
'# (list) Requirements to be installed (in order separated by commas)\nrequirements = python3,kivy', |
|
|
'requirements = python3,kivy,kivy-webview' |
|
|
) |
|
|
spec_content += '\nandroid.permissions = INTERNET' |
|
|
|
|
|
with open(spec_path, 'w') as f: |
|
|
f.write(spec_content) |
|
|
|
|
|
|
|
|
subprocess.run(['buildozer', '-v', 'android', 'debug'], cwd=project_path, check=True) |
|
|
|
|
|
|
|
|
bin_dir = os.path.join(project_path, 'bin') |
|
|
apk_files = [f for f in os.listdir(bin_dir) if f.endswith('.apk')] |
|
|
if apk_files: |
|
|
return redirect(url_for('download_file', project_name=project_name, filename=apk_files[0])) |
|
|
else: |
|
|
flash('Build failed: APK not found.') |
|
|
return redirect(url_for('index')) |
|
|
|
|
|
except subprocess.CalledProcessError as e: |
|
|
flash(f'An error occurred during the build process: {e}') |
|
|
return redirect(url_for('index')) |
|
|
except FileNotFoundError: |
|
|
flash('Buildozer not found. Make sure it is installed and in your PATH.') |
|
|
return redirect(url_for('index')) |
|
|
|
|
|
|
|
|
@app.route('/uploads/<project_name>/<filename>') |
|
|
def download_file(project_name, filename): |
|
|
"""Provides a download link for the generated APK.""" |
|
|
return send_from_directory(os.path.join(app.config['UPLOAD_FOLDER'], project_name, 'bin'), filename, as_attachment=True) |
|
|
|
|
|
if __name__ == '__main__': |
|
|
app.run(host='0.0.0.0', port=5000, debug=True) |