Akwbw commited on
Commit
c8a55c9
·
verified ·
1 Parent(s): 2ce48b3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +40 -140
app.py CHANGED
@@ -1,161 +1,61 @@
1
  from flask import Flask, request, send_file, Response
2
- import os
3
- import zipfile
4
- import subprocess
5
- import shutil
6
 
7
  app = Flask(__name__)
8
 
9
- # --- HELPER: GENERATE KEY (Same as before) ---
10
- def generate_keystore():
11
- keystore_path = "debug.keystore"
12
- if not os.path.exists(keystore_path):
13
- cmd = [
14
- "keytool", "-genkey", "-v",
15
- "-keystore", keystore_path,
16
- "-storepass", "android",
17
- "-alias", "androiddebugkey",
18
- "-keypass", "android",
19
- "-keyalg", "RSA",
20
- "-keysize", "2048",
21
- "-validity", "10000",
22
- "-dname", "CN=AndroidDebug,O=Android,C=US"
23
- ]
24
- subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
25
  return keystore_path
26
 
27
- # --- ROUTE: HOME (HTML FORM FOR TESTING) ---
28
  @app.route('/')
29
  def index():
30
- return '''
31
- <!doctype html>
32
- <title>Android Build Server</title>
33
- <h1>Upload Project ZIP</h1>
34
- <form action="/upload" method="post" enctype="multipart/form-data">
35
- <input type="file" name="file" required>
36
- <input type="submit" value="Build & Sign APK">
37
- </form>
38
- '''
39
 
40
- # --- ROUTE: API ENDPOINT ---
41
  @app.route('/upload', methods=['POST'])
42
  def upload_file():
43
- if 'file' not in request.files:
44
- return "No file part", 400
45
 
46
  file = request.files['file']
47
- if file.filename == '':
48
- return "No selected file", 400
49
-
50
- if file:
51
- # 1. Cleanup & Save
52
- if os.path.exists("project_extract"):
53
- shutil.rmtree("project_extract")
54
- os.makedirs("project_extract", exist_ok=True)
55
-
56
- zip_path = "uploaded_project.zip"
57
- file.save(zip_path)
58
-
59
- # 2. Extract
60
- try:
61
- with zipfile.ZipFile(zip_path, "r") as zip_ref:
62
- zip_ref.extractall("project_extract")
63
- except Exception as e:
64
- return f"Error extracting ZIP: {str(e)}", 400
65
 
66
- # 3. Find Root
67
- project_root = None
68
- for root, dirs, files in os.walk("project_extract"):
69
- if "gradlew" in files:
70
- project_root = root
71
- break
72
 
73
- if not project_root:
74
- return "Error: ZIP file mein 'gradlew' nahi mila.", 400
 
75
 
76
- # 4. Permissions
77
- gradlew_path = os.path.join(project_root, "gradlew")
78
- subprocess.run(["chmod", "+x", gradlew_path])
79
 
80
- # 5. Build
81
- # Hum assembleRelease chala rahe hain
82
- build_cmd = ["./gradlew", "assembleRelease", "--no-daemon", "--stacktrace"]
83
 
84
- try:
85
- result = subprocess.run(
86
- build_cmd,
87
- cwd=project_root,
88
- stdout=subprocess.PIPE,
89
- stderr=subprocess.PIPE,
90
- text=True
91
- )
92
-
93
- if result.returncode == 0:
94
- # 6. Find Unsigned APK
95
- unsigned_apk = None
96
- for root, dirs, files in os.walk(project_root):
97
- for f in files:
98
- if f.endswith(".apk") and "release" in f:
99
- unsigned_apk = os.path.join(root, f)
100
- break
101
 
102
- if unsigned_apk:
103
- # 7. SIGNING
104
- keystore = generate_keystore()
105
- signed_apk_name = "Installable_App.apk"
106
- aligned_apk = "aligned.apk"
107
-
108
- # Full path for output
109
- output_apk_path = os.path.abspath(signed_apk_name)
110
-
111
- # Step A: ZipAlign
112
- try:
113
- subprocess.run(["zipalign", "-v", "-p", "4", unsigned_apk, aligned_apk],
114
- stdout=subprocess.DEVNULL, check=True)
115
- apk_to_sign = aligned_apk
116
- except:
117
- apk_to_sign = unsigned_apk
118
-
119
- # Step B: APKSigner
120
- sign_cmd = [
121
- "apksigner", "sign",
122
- "--ks", keystore,
123
- "--ks-pass", "pass:android",
124
- "--out", output_apk_path,
125
- apk_to_sign
126
- ]
127
-
128
- sign_result = subprocess.run(sign_cmd, capture_output=True, text=True)
129
-
130
- if sign_result.returncode == 0:
131
- # CLEANUP ZIP before sending
132
- if os.path.exists(zip_path):
133
- os.remove(zip_path)
134
-
135
- # RETURN THE SIGNED APK
136
- return send_file(
137
- output_apk_path,
138
- as_attachment=True,
139
- download_name=signed_apk_name,
140
- mimetype="application/vnd.android.package-archive"
141
- )
142
- else:
143
- # Signing Failed - Show Logs
144
- logs = sign_result.stderr.splitlines()[:200]
145
- return Response("\n".join(logs), status=500, mimetype="text/plain")
146
- else:
147
- return "Build Success but APK file not found.", 500
148
- else:
149
- # BUILD FAILED - RETURN FIRST 200 LINES OF LOGS
150
- # Combining stdout and stderr to capture full context
151
- full_log = result.stdout + "\n" + result.stderr
152
- logs = full_log.splitlines()[:200]
153
- error_message = "BUILD FAILED. LOGS (First 200 lines):\n\n" + "\n".join(logs)
154
- return Response(error_message, status=500, mimetype="text/plain")
155
-
156
- except Exception as e:
157
- return f"System Error: {str(e)}", 500
158
 
159
  if __name__ == '__main__':
160
- # Hugging Face Spaces port 7860 use karta hai
161
- app.run(host='0.0.0.0', port=7860)
 
1
  from flask import Flask, request, send_file, Response
2
+ import os, zipfile, subprocess, shutil, uuid
 
 
 
3
 
4
  app = Flask(__name__)
5
 
6
+ def generate_keystore(work_dir):
7
+ keystore_path = os.path.join(work_dir, "debug.keystore")
8
+ cmd = ["keytool", "-genkey", "-v", "-keystore", keystore_path, "-storepass", "android", "-alias", "androiddebugkey", "-keypass", "android", "-keyalg", "RSA", "-keysize", "2048", "-validity", "10000", "-dname", "CN=AndroidDebug,O=Android,C=US"]
9
+ subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
 
 
 
 
 
 
 
 
 
 
 
 
10
  return keystore_path
11
 
 
12
  @app.route('/')
13
  def index():
14
+ return "Backend is running. Use the HTML interface to upload."
 
 
 
 
 
 
 
 
15
 
 
16
  @app.route('/upload', methods=['POST'])
17
  def upload_file():
18
+ if 'file' not in request.files: return "No file", 400
 
19
 
20
  file = request.files['file']
21
+ unique_id = str(uuid.uuid4())[:8]
22
+ work_dir = f"build_{unique_id}"
23
+ os.makedirs(work_dir, exist_ok=True)
24
+
25
+ zip_path = os.path.join(work_dir, "project.zip")
26
+ extract_path = os.path.join(work_dir, "extract")
27
+ file.save(zip_path)
 
 
 
 
 
 
 
 
 
 
 
28
 
29
+ try:
30
+ with zipfile.ZipFile(zip_path, "r") as z:
31
+ z.extractall(extract_path)
 
 
 
32
 
33
+ # Find gradlew
34
+ project_root = next((root for root, _, files in os.walk(extract_path) if "gradlew" in files), None)
35
+ if not project_root: return "Gradlew not found", 400
36
 
37
+ gradlew = os.path.join(project_root, "gradlew")
38
+ subprocess.run(["chmod", "+x", gradlew])
 
39
 
40
+ # Build
41
+ build_res = subprocess.run(["./gradlew", "assembleRelease", "--no-daemon"], cwd=project_root, capture_output=True, text=True)
 
42
 
43
+ if build_res.returncode == 0:
44
+ unsigned_apk = next((os.path.join(r, f) for r, _, fs in os.walk(project_root) for f in fs if f.endswith(".apk") and "release" in f), None)
45
+ if unsigned_apk:
46
+ ks = generate_keystore(work_dir)
47
+ out_apk = os.path.abspath(os.path.join(work_dir, f"App_{unique_id}.apk"))
48
+ # Sign
49
+ subprocess.run(["apksigner", "sign", "--ks", ks, "--ks-pass", "pass:android", "--out", out_apk, unsigned_apk])
 
 
 
 
 
 
 
 
 
 
50
 
51
+ return send_file(out_apk, as_attachment=True, download_name=f"Build_{unique_id}.apk")
52
+
53
+ return f"Build Failed: {build_res.stderr[:500]}", 500
54
+ finally:
55
+ # Optional: Cleanup folder after some time or immediately
56
+ # shutil.rmtree(work_dir)
57
+ pass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
 
59
  if __name__ == '__main__':
60
+ app.run(host='0.0.0.0', port=7860)
61
+