Akwbw commited on
Commit
adca9d6
·
verified ·
1 Parent(s): 6f0db2a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +102 -57
app.py CHANGED
@@ -3,43 +3,69 @@ import os
3
  import zipfile
4
  import subprocess
5
  import shutil
6
- import time
7
 
8
  # Page Config
9
  st.set_page_config(page_title="Android Build Server", layout="centered")
10
 
11
- st.title("📱 Android APK/AAB Generator")
12
- st.markdown("Apna Android Studio Project (ZIP) upload karein aur server APK bana dega.")
13
 
14
- # File Uploader
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  uploaded_file = st.file_uploader("Project ZIP File Upload Karein", type=["zip"])
16
 
17
  if uploaded_file is not None:
18
- # Button Layout
19
- col1, col2 = st.columns(2)
20
- build_apk = col1.button("🔨 Create APK")
21
- build_aab = col2.button("📦 Create AAB")
22
-
23
- if build_apk or build_aab:
24
  status_text = st.empty()
25
  progress_bar = st.progress(0)
26
 
27
- # 1. Cleanup old files
28
  if os.path.exists("project_extract"):
29
  shutil.rmtree("project_extract")
30
  os.makedirs("project_extract", exist_ok=True)
31
 
32
- # 2. Save and Extract Zip
33
  status_text.info("Extracting ZIP file...")
34
  with open("uploaded_project.zip", "wb") as f:
35
  f.write(uploaded_file.getbuffer())
36
-
37
  with zipfile.ZipFile("uploaded_project.zip", "r") as zip_ref:
38
  zip_ref.extractall("project_extract")
39
-
40
  progress_bar.progress(20)
41
 
42
- # 3. Find root directory (Smart Find)
43
  project_root = None
44
  for root, dirs, files in os.walk("project_extract"):
45
  if "gradlew" in files:
@@ -49,67 +75,87 @@ if uploaded_file is not None:
49
  if not project_root:
50
  st.error("❌ ZIP file mein 'gradlew' nahi mila.")
51
  else:
52
- # 4. Permissions fix
53
- status_text.info("Setting up Gradle environment...")
54
  gradlew_path = os.path.join(project_root, "gradlew")
55
  subprocess.run(["chmod", "+x", gradlew_path])
56
 
57
- # 5. Build Command
58
- # Note: Hum 'assemble' use kar rahay hain taake agar release sign na ho to debug ban jaye
59
- build_type = "assemble" if build_apk else "bundle"
60
- status_text.info(f"Building Project... (Wait karein)")
 
 
61
 
62
  try:
63
  result = subprocess.run(
64
- [f"./gradlew", build_type],
65
  cwd=project_root,
66
  stdout=subprocess.PIPE,
67
  stderr=subprocess.PIPE,
68
  text=True
69
  )
70
 
71
- progress_bar.progress(80)
72
 
73
  if result.returncode == 0:
74
- status_text.success("✅ Build Successful!")
75
- progress_bar.progress(100)
76
-
77
- # 6. SMART SEARCH for Output File
78
- output_path = None
79
- file_ext = ".apk" if build_apk else ".aab"
80
 
81
- # Pure folder mein dhoondo
 
82
  for root, dirs, files in os.walk(project_root):
83
  for file in files:
84
- if file.endswith(file_ext):
85
- # Ignore karna intermediate files ko
86
- if "unaligned" in file:
87
- continue
88
- # Prefer release, but accept debug
89
- current_file = os.path.join(root, file)
90
- output_path = current_file
91
- # Agar release mil jaye to loop break kardo
92
- if "release" in file:
93
- break
94
- if output_path and "release" in output_path:
95
- break
96
 
97
- if output_path and os.path.exists(output_path):
98
- file_label = "APP-RELEASE" if "release" in output_path else "APP-DEBUG"
99
- st.write(f"🔍 File Found: {os.path.basename(output_path)}")
 
100
 
101
- with open(output_path, "rb") as f:
102
- st.download_button(
103
- label=f"⬇️ Download {file_ext.upper()}",
104
- data=f,
105
- file_name=f"generated-app{file_ext}",
106
- mime="application/vnd.android.package-archive"
107
- )
108
- else:
109
- st.error("Build pass hogaya lekin koi APK/AAB file generate nahi hui. Shayad ye Library project hai?")
110
- st.warning("Check Log below:")
111
- st.text_area("Build Output", result.stdout[-2000:], height=200)
112
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  else:
114
  st.error("❌ Build Failed!")
115
  st.text_area("Error Log", result.stderr, height=300)
@@ -117,6 +163,5 @@ if uploaded_file is not None:
117
  except Exception as e:
118
  st.error(f"System Error: {str(e)}")
119
 
120
- # Cleanup
121
  if os.path.exists("uploaded_project.zip"):
122
  os.remove("uploaded_project.zip")
 
3
  import zipfile
4
  import subprocess
5
  import shutil
6
+ import glob
7
 
8
  # Page Config
9
  st.set_page_config(page_title="Android Build Server", layout="centered")
10
 
11
+ st.title("📱 Android APK Generator (Auto-Signed)")
12
+ st.markdown("Zip upload karein. Server APK banayega aur **Sign** karke dega taake install ho sakay.")
13
 
14
+ # --- HELPER FUNCTION: FIND TOOLS ---
15
+ def find_tool(tool_name):
16
+ # System path mein dhoondo
17
+ tool_path = shutil.which(tool_name)
18
+ if tool_path:
19
+ return tool_path
20
+
21
+ # Agar nahi mila, to Android SDK folder mein dhoondo
22
+ sdk_root = os.environ.get("ANDROID_HOME", "/opt/android-sdk")
23
+ found_files = glob.glob(f"{sdk_root}/build-tools/*/{tool_name}")
24
+ if found_files:
25
+ return found_files[-1] # Latest version utha lo
26
+ return None
27
+
28
+ # --- HELPER FUNCTION: GENERATE KEYSTORE ---
29
+ def generate_keystore():
30
+ keystore_path = "debug.keystore"
31
+ if not os.path.exists(keystore_path):
32
+ # Keytool command to create a generic key
33
+ cmd = [
34
+ "keytool", "-genkey", "-v",
35
+ "-keystore", keystore_path,
36
+ "-storepass", "android",
37
+ "-alias", "androiddebugkey",
38
+ "-keypass", "android",
39
+ "-keyalg", "RSA",
40
+ "-keysize", "2048",
41
+ "-validity", "10000",
42
+ "-dname", "CN=AndroidDebug,O=Android,C=US"
43
+ ]
44
+ subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
45
+ return keystore_path
46
+
47
+ # --- MAIN UI ---
48
  uploaded_file = st.file_uploader("Project ZIP File Upload Karein", type=["zip"])
49
 
50
  if uploaded_file is not None:
51
+ if st.button("🔨 Create & Sign APK"):
 
 
 
 
 
52
  status_text = st.empty()
53
  progress_bar = st.progress(0)
54
 
55
+ # 1. Cleanup
56
  if os.path.exists("project_extract"):
57
  shutil.rmtree("project_extract")
58
  os.makedirs("project_extract", exist_ok=True)
59
 
60
+ # 2. Extract
61
  status_text.info("Extracting ZIP file...")
62
  with open("uploaded_project.zip", "wb") as f:
63
  f.write(uploaded_file.getbuffer())
 
64
  with zipfile.ZipFile("uploaded_project.zip", "r") as zip_ref:
65
  zip_ref.extractall("project_extract")
 
66
  progress_bar.progress(20)
67
 
68
+ # 3. Find Root
69
  project_root = None
70
  for root, dirs, files in os.walk("project_extract"):
71
  if "gradlew" in files:
 
75
  if not project_root:
76
  st.error("❌ ZIP file mein 'gradlew' nahi mila.")
77
  else:
78
+ # 4. Permissions
79
+ status_text.info("Setting up Gradle...")
80
  gradlew_path = os.path.join(project_root, "gradlew")
81
  subprocess.run(["chmod", "+x", gradlew_path])
82
 
83
+ # 5. Build (Use assembleRelease for production feel)
84
+ # Hum 'assembleRelease' use karenge, jo unsigned APK dega, phir hum usay sign karenge
85
+ status_text.info("Building APK... (Wait karein)")
86
+
87
+ # Note: Hum 'clean' nahi kar rahay taake jaldi ho, agar error aye to clean add kar lena
88
+ build_cmd = ["./gradlew", "assembleRelease", "--no-daemon", "--stacktrace"]
89
 
90
  try:
91
  result = subprocess.run(
92
+ build_cmd,
93
  cwd=project_root,
94
  stdout=subprocess.PIPE,
95
  stderr=subprocess.PIPE,
96
  text=True
97
  )
98
 
99
+ progress_bar.progress(60)
100
 
101
  if result.returncode == 0:
102
+ status_text.info("✅ Build Successful! Ab Signing kar rahay hain...")
 
 
 
 
 
103
 
104
+ # 6. Find Unsigned APK
105
+ unsigned_apk = None
106
  for root, dirs, files in os.walk(project_root):
107
  for file in files:
108
+ if file.endswith(".apk") and "release" in file:
109
+ unsigned_apk = os.path.join(root, file)
110
+ break
 
 
 
 
 
 
 
 
 
111
 
112
+ if unsigned_apk:
113
+ # 7. SIGNING PROCESS ✍️
114
+ keystore = generate_keystore()
115
+ apksigner = find_tool("apksigner")
116
 
117
+ if apksigner:
118
+ signed_apk_name = "production_ready_app.apk"
119
+
120
+ # Align APK (Optimization)
121
+ zipalign = find_tool("zipalign")
122
+ aligned_apk = "aligned.apk"
123
+ if zipalign:
124
+ subprocess.run([zipalign, "-v", "-p", "4", unsigned_apk, aligned_apk], stdout=subprocess.DEVNULL)
125
+ apk_to_sign = aligned_apk
126
+ else:
127
+ apk_to_sign = unsigned_apk
128
 
129
+ # Sign APK
130
+ sign_cmd = [
131
+ apksigner, "sign",
132
+ "--ks", keystore,
133
+ "--ks-pass", "pass:android",
134
+ "--out", signed_apk_name,
135
+ apk_to_sign
136
+ ]
137
+
138
+ sign_result = subprocess.run(sign_cmd, capture_output=True, text=True)
139
+
140
+ if sign_result.returncode == 0:
141
+ status_text.success("🎉 APK Signed & Ready!")
142
+ progress_bar.progress(100)
143
+
144
+ with open(signed_apk_name, "rb") as f:
145
+ st.download_button(
146
+ label="⬇️ Download Signed APK",
147
+ data=f,
148
+ file_name=signed_apk_name,
149
+ mime="application/vnd.android.package-archive"
150
+ )
151
+ else:
152
+ st.error("Build pass hui, magar Signing fail hogayi.")
153
+ st.text_area("Signing Error", sign_result.stderr)
154
+ else:
155
+ st.error("Server par 'apksigner' tool nahi mila.")
156
+ else:
157
+ st.error("Build ho gayi magar APK file dhoondne mein masla hua.")
158
+
159
  else:
160
  st.error("❌ Build Failed!")
161
  st.text_area("Error Log", result.stderr, height=300)
 
163
  except Exception as e:
164
  st.error(f"System Error: {str(e)}")
165
 
 
166
  if os.path.exists("uploaded_project.zip"):
167
  os.remove("uploaded_project.zip")