sudo-soldier commited on
Commit
cfed92e
·
verified ·
1 Parent(s): 8d4a057

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +22 -138
app.py CHANGED
@@ -1,145 +1,29 @@
1
- import os
2
  import subprocess
3
- import tempfile
4
- import shutil
5
- import re
6
- import logging
7
- from flask import Flask, request, send_file, jsonify
8
- from werkzeug.utils import secure_filename
9
-
10
- # Configure logging
11
- logging.basicConfig(level=logging.INFO)
12
- logger = logging.getLogger(__name__)
13
-
14
- app = Flask(__name__)
15
-
16
- # Configuration
17
- app.config['MAX_CONTENT_LENGTH'] = 1 * 1024 * 1024 # 1MB max
18
- app.config['ALLOWED_EXTENSIONS'] = {'png', 'jpg', 'jpeg'}
19
- app.config['TEMP_DIR'] = '/tmp/pwa2apk' # Using system temp directory
20
- app.config['BUBBLEWRAP_MIN_VERSION'] = '1.0.0'
21
-
22
- # Ensure temp directory exists
23
- os.makedirs(app.config['TEMP_DIR'], exist_ok=True)
24
-
25
- def is_valid_url(url):
26
- """Validate URL format using regex"""
27
- regex = re.compile(
28
- r'^(https?://)?' # http:// or https://
29
- r'([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}' # domain
30
- r'(/[a-zA-Z0-9-._~:/?#[\]@!$&\'()*+,;=]*)?$', # path
31
- re.IGNORECASE
32
  )
33
- return re.match(regex, url) is not None
34
-
35
- def check_bubblewrap():
36
- """Verify bubblewrap is installed and meets version requirements"""
37
- try:
38
- result = subprocess.run(
39
- ['bubblewrap', '--version'],
40
- capture_output=True,
41
- text=True,
42
- check=True
43
- )
44
- version = result.stdout.strip()
45
- logger.info(f"Bubblewrap version detected: {version}")
46
- return True
47
- except Exception as e:
48
- logger.error(f"Bubblewrap check failed: {str(e)}")
49
- return False
50
-
51
- def cleanup_directory(dir_path):
52
- """Safely remove temporary directory"""
53
- try:
54
- if os.path.exists(dir_path):
55
- shutil.rmtree(dir_path)
56
- logger.info(f"Cleaned up directory: {dir_path}")
57
- except Exception as e:
58
- logger.error(f"Cleanup failed for {dir_path}: {str(e)}")
59
 
60
- def generate_apk_internal(pwa_url, output_dir):
61
- """Core APK generation logic"""
62
- try:
63
- # Initialize project
64
- init_cmd = [
65
- 'bubblewrap', 'init',
66
- '--manifest', pwa_url,
67
- '--directory', output_dir,
68
- '--non-interactive'
69
- ]
70
- subprocess.run(init_cmd, check=True, timeout=300)
71
-
72
- # Build APK
73
- build_cmd = ['bubblewrap', 'build']
74
- subprocess.run(build_cmd, cwd=output_dir, check=True, timeout=600)
75
-
76
- # Verify APK was created
77
- apk_path = os.path.join(output_dir, 'app-release.apk')
78
- if not os.path.exists(apk_path):
79
- raise FileNotFoundError("APK file not found after build")
80
-
81
  return apk_path
 
 
82
 
83
- except subprocess.TimeoutExpired as e:
84
- logger.error(f"Build timed out: {str(e)}")
85
- raise
86
- except subprocess.CalledProcessError as e:
87
- logger.error(f"Build failed with code {e.returncode}: {e.stderr}")
88
- raise
89
- except Exception as e:
90
- logger.error(f"Unexpected error: {str(e)}")
91
- raise
92
-
93
- @app.route('/health', methods=['GET'])
94
- def health_check():
95
- """Health check endpoint"""
96
- return jsonify({'status': 'healthy', 'bubblewrap': check_bubblewrap()})
97
-
98
- @app.route("/generate-apk", methods=["POST"])
99
- def generate_apk():
100
- """Main APK generation endpoint"""
101
- if not check_bubblewrap():
102
- return jsonify({"error": "Bubblewrap not available"}), 503
103
-
104
- if 'url' not in request.form:
105
- return jsonify({"error": "URL parameter is required"}), 400
106
-
107
- pwa_url = request.form['url'].strip()
108
- if not is_valid_url(pwa_url):
109
- return jsonify({"error": "Invalid URL format"}), 400
110
-
111
- # Create unique temp directory
112
- temp_dir = tempfile.mkdtemp(dir=app.config['TEMP_DIR'])
113
- logger.info(f"Created temp directory: {temp_dir}")
114
-
115
- try:
116
- apk_path = generate_apk_internal(pwa_url, temp_dir)
117
-
118
- # Generate safe filename
119
- domain = pwa_url.split('//')[-1].split('/')[0].replace('.', '_')
120
- apk_name = secure_filename(f"{domain}_app.apk")
121
-
122
- logger.info(f"Successfully generated APK: {apk_path}")
123
- return send_file(
124
- apk_path,
125
- as_attachment=True,
126
- download_name=apk_name,
127
- mimetype='application/vnd.android.package-archive'
128
- )
129
 
130
- except Exception as e:
131
- logger.error(f"APK generation failed: {str(e)}")
132
- return jsonify({
133
- "error": "APK generation failed",
134
- "details": str(e)
135
- }), 500
136
- finally:
137
- cleanup_directory(temp_dir)
138
 
139
- if __name__ == "__main__":
140
- # Verify dependencies at startup
141
- if not check_bubblewrap():
142
- logger.error("Bubblewrap not available - service cannot start")
143
- exit(1)
144
-
145
- app.run(host="0.0.0.0", port=7860)
 
1
+ import gradio as gr
2
  import subprocess
3
+ import os
4
+ import uuid
5
+
6
+ def convert_to_apk(manifest_url):
7
+ apk_id = str(uuid.uuid4())
8
+ result = subprocess.run(
9
+ ["bash", "entrypoint.sh", manifest_url, apk_id],
10
+ capture_output=True,
11
+ text=True
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
+ apk_path = f"{apk_id}/app-release-signed.apk"
15
+ if os.path.exists(apk_path):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  return apk_path
17
+ else:
18
+ return f"Error:\n{result.stderr}"
19
 
20
+ iface = gr.Interface(
21
+ fn=convert_to_apk,
22
+ inputs=gr.Textbox(label="Manifest.json URL"),
23
+ outputs=gr.File(label="Download APK"),
24
+ title="URL to APK",
25
+ description="Paste the public URL of a manifest.json from your PWA"
26
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
+ iface.launch()
 
 
 
 
 
 
 
29