()
| 1309 | f"{_('Android Version')}: {android_version}\n" |
| 1310 | f"{_('Device Model')}: {device_model}\n" |
| 1311 | f"{_('Manufacturer')}: {manufacturer}\n" |
| 1312 | f"{_('Uptime')}: {uptime}\n" |
| 1313 | f"{battery}" |
| 1314 | ) |
| 1315 | return details |
| 1316 | |
| 1317 | def get_user(): |
| 1318 | output, _err = run_command_silent("whoami") |
| 1319 | return output if output else "Unknown" |
| 1320 | |
| 1321 | def _remove_path_if_exists(target_path): |
| 1322 | """Removes a file/directory/symlink if it exists.""" |
| 1323 | try: |
| 1324 | if os.path.islink(target_path) or os.path.isfile(target_path): |
| 1325 | os.remove(target_path) |
| 1326 | elif os.path.isdir(target_path): |
| 1327 | shutil.rmtree(target_path) |
| 1328 | except Exception: |
| 1329 | pass |
| 1330 | |
| 1331 | |
| 1332 | def _download_file_silent(url, destination_path): |
| 1333 | headers = {"User-Agent": "Mozilla/5.0 (Termux; Android) DedSecProjectLegacySave/1.0"} |
| 1334 | with requests.get(url, stream=True, allow_redirects=True, timeout=120, headers=headers) as response: |
| 1335 | response.raise_for_status() |
| 1336 | with open(destination_path, "wb") as handle: |
| 1337 | for chunk in response.iter_content(chunk_size=1024 * 256): |
| 1338 | if chunk: |
| 1339 | handle.write(chunk) |
| 1340 | |
| 1341 | |
| 1342 | def _resolve_fdroid_package_apk_url(package_name): |
| 1343 | headers = {"User-Agent": "Mozilla/5.0 (Termux; Android) DedSecProjectLegacySave/1.0"} |
| 1344 | response = requests.get(f"https://f-droid.org/packages/{package_name}/", timeout=60, headers=headers) |
| 1345 | response.raise_for_status() |
| 1346 | html = response.text |
| 1347 | |
| 1348 | patterns = [ |
| 1349 | r'href="([^"]+\.apk)"[^>]*>\s*Download APK', |
| 1350 | r'href="([^"]*' + re.escape(package_name) + r'[^"]*\.apk)"', |
| 1351 | r'href="([^"]+\.apk)"', |
| 1352 | ] |
| 1353 | |
| 1354 | for pattern in patterns: |
| 1355 | match = re.search(pattern, html, re.IGNORECASE | re.DOTALL) |
| 1356 | if match: |
| 1357 | apk_url = match.group(1).strip() |
| 1358 | if apk_url.startswith("//"): |
| 1359 | return "https:" + apk_url |
| 1360 | if apk_url.startswith("/"): |
| 1361 | return "https://f-droid.org" + apk_url |
| 1362 | if apk_url.startswith("http://") or apk_url.startswith("https://"): |
| 1363 | return apk_url |
| 1364 | return "https://f-droid.org/" + apk_url.lstrip("/") |
| 1365 | |
| 1366 | raise RuntimeError(f"Unable to resolve APK URL for {package_name}") |
| 1367 | |
| 1368 |
no test coverage detected