Skip to content

Instantly share code, notes, and snippets.

@MinePlayersPE
Last active April 21, 2023 17:25
Show Gist options
  • Save MinePlayersPE/e983d6603059bd821f0b3b287949f36a to your computer and use it in GitHub Desktop.
Save MinePlayersPE/e983d6603059bd821f0b3b287949f36a to your computer and use it in GitHub Desktop.
Python script to fetch APKs from the Vanced API and install them via ADB
from tqdm import tqdm
from urllib.parse import urljoin
import json
import os
import sys
import requests
import subprocess
API_URL = 'https://api.vancedapp.com/api/v1'
session = requests.Session()
session.headers['User-Agent'] = session.headers.get('User-Agent', 'python-requests') + ' VancedADBInstall/1.0 (+https://gist.github.com/MinePlayersPE/e983d6603059bd821f0b3b287949f36a)'
latest_metadata = session.get(API_URL + '/latest.json').json()
vanced_metadata = latest_metadata['vanced']
version = vanced_metadata['version']
changelog = vanced_metadata['changelog']
print('Getting version ' + version)
print('Changelog: \n' + changelog)
themes = vanced_metadata['themes']
langs = vanced_metadata['langs']
theme = ''
langs_selected = ['']
while not theme in themes:
theme = input('Select theme (' + ','.join(themes) + '; only choose one): ').strip()
while not all(lang in langs for lang in langs_selected):
langs_selected = input('Select languages (' + ','.join(langs) + '; multiple choices seperated by comma): ').strip().replace(' ', '').split(',')
def download(url: str, fname: str, session=requests): # ripped from https://stackoverflow.com/a/62113293, modified for simpler syntax
resp = session.get(url, stream=True)
with tqdm.wrapattr(
open(fname, 'wb'), 'write',
miniters=1,
desc=fname,
total=int(resp.headers.get('content-length', 0)),
) as file:
for data in resp.iter_content(chunk_size=1024):
size = file.write(data)
apks_url = API_URL + '/apks/v' + version + '/nonroot'
theme_url = apks_url + '/Theme/' + theme + '.apk'
print('Downloading ' + theme + ' theme apk...')
download(theme_url, 'theme.apk', session)
for lang in langs_selected:
lang_url = apks_url + '/Language/split_config.' + lang + '.apk'
print('Downloading ' + lang + ' language apk...')
download(lang_url, lang + '.apk', session)
archs = ('x86', 'arm64_v8a', 'armeabi_v7a')
print('Attempting to fetch device\'s architecture via adb...')
arch_cmd = ['adb', 'shell', 'getprop', 'ro.product.cpu.abilist']
print('adb command line: ' + ' '.join(arch_cmd))
arch_proc = subprocess.run(arch_cmd, capture_output=True)
if arch_proc.returncode == 0:
archs_proplist = arch_proc.stdout.decode().strip()
# logic from https://github.com/YTVanced/VancedManager/blob/bd27e34b40/app/src/main/java/com/vanced/manager/utils/DeviceUtils.kt#L5-L9
if 'x86' in archs_proplist:
archs = ('x86',)
elif 'arm64-v8a' in archs_proplist:
archs = ('arm64_v8a',)
else:
archs = ('armeabi_v7a',)
else:
print('Unable to determine arch, retcode from adb: ' + str(arch_proc.returncode) + '; stderr: ' + arch_proc.stderr.decode().strip())
for arch in archs:
arch_url = apks_url + '/Arch/split_config.' + arch + '.apk'
print('Downloading ' + arch + ' architecture apk...')
download(arch_url, arch + '.apk', session)
print('Downloaded split apks. Installing via adb...')
install_cmd = [
'adb', 'install-multiple',
'theme.apk', *(lang + '.apk' for lang in langs_selected), *(arch + '.apk' for arch in archs)
]
print('adb command line: ' + ' '.join(install_cmd))
install_proc = subprocess.Popen(install_cmd, stdout=sys.stdout, stderr=sys.stderr)
stdout, stderr = install_proc.communicate()
if install_proc.returncode == 0:
print('Successfully installed vanced!')
else:
print('Unable to install vanced, retcode from adb: ' + str(install_proc.returncode))
@Fishezzz
Copy link

Fishezzz commented Mar 15, 2022

Nice!
The urls for Vanced Music are https://api.vancedapp.com/api/v1/music/v<version>/<root-nonroot>.apk

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment