File size: 3,927 Bytes
9098781 2b62729 9098781 2b62729 9098781 2b62729 9098781 f7e7f3d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
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'))
# Sanitize the URL to create a valid project name
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)
# Create the main.py for the Android app
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)
# Create the requirements.txt for the Android app
with open(os.path.join(project_path, 'requirements.txt'), 'w') as f:
f.write('kivy\n')
f.write('kivy-webview\n')
# Initiate the build process using a separate script or a task queue
# For simplicity, we'll call buildozer directly here.
# In a real-world application, you would use a task queue like Celery.
try:
# Initialize buildozer
subprocess.run(['buildozer', '-v', 'init'], cwd=project_path, check=True)
# Update buildozer.spec for webview and permissions
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)
# Run the build
subprocess.run(['buildozer', '-v', 'android', 'debug'], cwd=project_path, check=True)
# Find the generated APK
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) |