mirror of https://github.com/CalyxOS/scripts
132 lines
5.5 KiB
Python
Executable File
132 lines
5.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
#
|
|
# Tries to get device-specific info from various Google sites
|
|
# Best effort
|
|
# We require manual input of build id here to keep things easier
|
|
|
|
import argparse
|
|
import base64
|
|
from bs4 import BeautifulSoup
|
|
from git import cmd
|
|
import os
|
|
import urllib.request
|
|
|
|
SCRIPT_PATH = os.path.realpath(os.path.dirname(__file__))
|
|
VARS_PATH = SCRIPT_PATH + os.path.sep + os.path.pardir + os.path.sep + "vars"
|
|
|
|
IMAGE_URL = "https://developers.google.com/android/images"
|
|
OTA_URL = "https://developers.google.com/android/ota"
|
|
COOKIE = {'Cookie': 'devsite_wall_acks=nexus-image-tos,nexus-ota-tos'}
|
|
|
|
PLATFORM_BUILD_URL = "https://android.googlesource.com/platform/build"
|
|
BUILD_ID_URL = "https://android.googlesource.com/platform/build/+/refs/{}/core/build_id.mk?format=TEXT"
|
|
BUILD_ID_FILTER = "BUILD_ID="
|
|
SECURITY_PATCH_URL = "https://android.googlesource.com/platform/build/+/refs/{}/core/version_defaults.mk?format=TEXT"
|
|
SECURITY_PATCH_FILTER = "PLATFORM_SECURITY_PATCH :="
|
|
|
|
def handle_image(html_id):
|
|
image_html = urllib.request.urlopen(urllib.request.Request(IMAGE_URL, headers=COOKIE)).read()
|
|
soup = BeautifulSoup(image_html, 'html.parser')
|
|
td = soup.find(id=html_id).find_all('td')
|
|
flash_url = td[1].a['href']
|
|
image_url = td[2].a['href']
|
|
image_sha256 = td[3].contents[0]
|
|
build_number = flash_url.split("/")[4].split("?")[0]
|
|
print('new_build_number="{0}"\nnew_flash_url="{1}"\nnew_image_url="{2}"\nnew_image_sha256="{3}"'.format(build_number, flash_url, image_url, image_sha256))
|
|
|
|
def handle_ota(html_id):
|
|
ota_html = urllib.request.urlopen(urllib.request.Request(OTA_URL, headers=COOKIE)).read()
|
|
soup = BeautifulSoup(ota_html, 'html.parser')
|
|
td = soup.find(id=html_id).find_all('td')
|
|
ota_url = td[1].a['href']
|
|
ota_sha256 = td[2].contents[0]
|
|
print('new_ota_url="{0}"\nnew_ota_sha256="{1}"'.format(ota_url, ota_sha256))
|
|
|
|
def get_all_aosp_branches(branch_filter):
|
|
all_branches = []
|
|
try:
|
|
for line in cmd.Git().ls_remote("--sort=v:refname", PLATFORM_BUILD_URL, branch_filter, tags=False, refs=True).split('\n'):
|
|
try:
|
|
(ref, branch) = line.split('\t')
|
|
except ValueError:
|
|
pass
|
|
all_branches.append(branch.replace("refs/heads/", ""))
|
|
return all_branches
|
|
except Exception as e:
|
|
return all_branches
|
|
|
|
def get_aosp_branch_for_build_id(aosp_branches, wanted_build_id):
|
|
try:
|
|
for aosp_branch in aosp_branches:
|
|
output = base64.decodebytes(urllib.request.urlopen(BUILD_ID_URL.format("heads/" + aosp_branch)).read()).decode()
|
|
for line in output.split('\n'):
|
|
if BUILD_ID_FILTER in line:
|
|
found_build_id = line.split("=")[1]
|
|
if found_build_id == wanted_build_id:
|
|
print('new_aosp_branch="{0}"'.format(aosp_branch))
|
|
return aosp_branch
|
|
print('new_aosp_branch="unknown"')
|
|
return 'unknown'
|
|
except Exception as e:
|
|
print('new_aosp_branch="unknown"')
|
|
return 'unknown'
|
|
|
|
def get_all_aosp_tags(tag_filter):
|
|
all_tags = []
|
|
try:
|
|
for line in cmd.Git().ls_remote("--sort=v:refname", PLATFORM_BUILD_URL, tag_filter, tags=True, refs=True).split('\n'):
|
|
try:
|
|
(ref, tag) = line.split('\t')
|
|
except ValueError:
|
|
pass
|
|
all_tags.append(tag.replace("refs/tags/", ""))
|
|
return all_tags
|
|
except Exception as e:
|
|
return all_tags
|
|
|
|
def get_aosp_tag_for_build_id(aosp_tags, wanted_build_id):
|
|
try:
|
|
for aosp_tag in aosp_tags:
|
|
output = base64.decodebytes(urllib.request.urlopen(BUILD_ID_URL.format("tags/" + aosp_tag)).read()).decode()
|
|
for line in output.split('\n'):
|
|
if BUILD_ID_FILTER in line:
|
|
found_build_id = line.split("=")[1]
|
|
if found_build_id == wanted_build_id:
|
|
print('new_aosp_tag="{0}"'.format(aosp_tag))
|
|
return aosp_tag
|
|
print('new_aosp_tag="unknown"')
|
|
return 'unknown'
|
|
except Exception as e:
|
|
print('new_aosp_tag="unknown"')
|
|
return 'unknown'
|
|
|
|
def get_security_patch_for_aosp_tag(aosp_tag):
|
|
try:
|
|
output = base64.decodebytes(urllib.request.urlopen(SECURITY_PATCH_URL.format("tags/" + aosp_tag)).read()).decode()
|
|
except:
|
|
print('new_security_patch=unknown')
|
|
return
|
|
for line in output.split('\n'):
|
|
if SECURITY_PATCH_FILTER in line:
|
|
security_patch = line.split(":=")[1].strip()
|
|
print('new_security_patch="{0}"'.format(security_patch))
|
|
return
|
|
print('new_security_patch="unknown"')
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument('-b', '--build_id', help="Build ID", type=str, required=True)
|
|
parser.add_argument('-d', '--device', help="Device codename", type=str, required=True)
|
|
parser.add_argument('-t', '--tags_match', help='Android version tag to match, such as android-13.0', type=str, required=True)
|
|
parser.add_argument('-br', '--branch_match', help='Android version branch to match, such as android13', type=str, required=True)
|
|
args = parser.parse_args()
|
|
html_id = "{0}{1}".format(args.device, args.build_id.lower())
|
|
handle_image(html_id)
|
|
handle_ota(html_id)
|
|
get_aosp_branch_for_build_id(get_all_aosp_branches("{0}*".format(args.branch_match)), args.build_id.upper())
|
|
aosp_tag = get_aosp_tag_for_build_id(get_all_aosp_tags("{0}*".format(args.tags_match)), args.build_id.upper())
|
|
get_security_patch_for_aosp_tag(aosp_tag)
|
|
|
|
if __name__ == "__main__":
|
|
main()
|