import base64
from os import getenv
import html
import json
import re
import requests
import logging
import subprocess
from typing import Any, OrderedDict
from xml.dom import minidom
from requests import Session
from packaging import version
class Prop(OrderedDict):
def __init__(self, props: str = ...) -> None:
super().__init__()
for i, line in enumerate(props.splitlines(False)):
if '=' in line:
k, v = line.split('=', 1)
self[k] = v
else:
self[f".{i}"] = line
def __setattr__(self, __name: str, __value: Any) -> None:
self[__name] = __value
def __repr__(self):
return '\n'.join(f'{item}={self[item]}' for item in self)
logging.captureWarnings(True)
env_file = getenv('GITHUB_ENV')
token = getenv("API_KEY")
authorization = f'Bearer {token}'
reqheaders = {
"Accept": "application/vnd.github.v3+json",
"Authorization" : authorization,
}
#Catagory ID
cat_id = '858014f3-3934-4abe-8078-4aa193e74ca8'
release_type = "WIF"
new_version_found = False
session = Session()
session.verify = False
git = (
"git checkout -f update || git switch --discard-changes --orphan update"
)
def MagiskandGappsChecker(type):
global new_version_found
# Get current version
currentver = requests.get(f"https://raw.githubusercontent.com/YT-Advanced/WSA-Script/update/" + type + ".appversion").text.replace('\n', '')
# Write for pushing later
file = open('../' + type + '.appversion', 'w')
file.write(currentver)
if new_version_found:
return 0;
# Get latest version
latestver = ""
msg = ""
if (type == "magisk"):
latestver = json.loads(requests.get(f"https://github.com/topjohnwu/magisk-files/raw/master/stable.json").content)['magisk']['version'].replace('\n', '')
msg="Update Magisk Version from `v" + currentver + "` to `v" + latestver + "`"
elif (type == "gapps"):
latestver = json.loads(requests.get(f"https://api.github.com/repos/YT-Advanced/MindTheGappsBuilder/releases/latest", headers=reqheaders).content)['name']
msg="Update MindTheGapps Version from `v" + currentver + "` to `v" + latestver + "`"
# Check if version is the same or not
if (currentver != latestver):
print("New version found: " + latestver)
new_version_found = True
# Write appversion content
subprocess.Popen(git, shell=True, stdout=None, stderr=None, executable='/bin/bash').wait()
file.seek(0)
file.truncate()
file.write(latestver)
# Write Github Environment
with open(env_file, "a") as wr:
wr.write("SHOULD_BUILD=yes\nMSG=" + msg)
file.close()
def WSAChecker(user, release_type):
global new_version_found
currentver = requests.get(f"https://raw.githubusercontent.com/YT-Advanced/WSA-Script/update/" + release_type + ".appversion").text.replace('\n', '')
# Write for pushing later
file = open('../' + release_type + '.appversion', 'w')
file.write(currentver)
if new_version_found:
return 0;
# Get information
with open("../xml/GetCookie.xml", "r") as f:
cookie_content = f.read().format(user)
f.close()
try:
out = session.post(
'https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx',
data=cookie_content,
headers={'Content-Type': 'application/soap+xml; charset=utf-8'}
)
except:
print("Network Error!")
return 1
doc = minidom.parseString(out.text)
cookie = doc.getElementsByTagName('EncryptedData')[0].firstChild.nodeValue
with open("../xml/WUIDRequest.xml", "r") as f:
cat_id_content = f.read().format(user, cookie, cat_id, release_type)
f.close()
try:
out = session.post(
'https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx',
data=cat_id_content,
headers={'Content-Type': 'application/soap+xml; charset=utf-8'}
)
except:
print("Network Error!")
return 1
doc = minidom.parseString(html.unescape(out.text))
filenames = {}
for node in doc.getElementsByTagName('ExtendedUpdateInfo')[0].getElementsByTagName('Updates')[0].getElementsByTagName('Update'):
node_xml = node.getElementsByTagName('Xml')[0]
node_files = node_xml.getElementsByTagName('Files')
if not node_files:
continue
else:
for node_file in node_files[0].getElementsByTagName('File'):
if node_file.hasAttribute('InstallerSpecificIdentifier') and node_file.hasAttribute('FileName'):
filenames[node.getElementsByTagName('ID')[0].firstChild.nodeValue] = (f"{node_file.attributes['InstallerSpecificIdentifier'].value}_{node_file.attributes['FileName'].value}",
node_xml.getElementsByTagName('ExtendedProperties')[0].attributes['PackageIdentityName'].value)
identities = {}
for node in doc.getElementsByTagName('NewUpdates')[0].getElementsByTagName('UpdateInfo'):
node_xml = node.getElementsByTagName('Xml')[0]
if not node_xml.getElementsByTagName('SecuredFragment'):
continue
else:
id = node.getElementsByTagName('ID')[0].firstChild.nodeValue
update_identity = node_xml.getElementsByTagName('UpdateIdentity')[0]
if id in filenames:
fileinfo = filenames[id]
if fileinfo[0] not in identities:
identities[fileinfo[0]] = ([update_identity.attributes['UpdateID'].value,
update_identity.attributes['RevisionNumber'].value], fileinfo[1])
wsa_build_ver = 0
for filename, value in identities.items():
if re.match(f"MicrosoftCorporationII.WindowsSubsystemForAndroid_.*.msixbundle", filename):
tmp_wsa_build_ver = re.search(r"\d{4}.\d{5}.\d{1,}.\d{1,}", filename).group()
if (wsa_build_ver == 0):
wsa_build_ver = tmp_wsa_build_ver
elif version.parse(wsa_build_ver) < version.parse(tmp_wsa_build_ver):
wsa_build_ver = tmp_wsa_build_ver
# Check new WSA version
if version.parse(currentver) < version.parse(wsa_build_ver):
print("New version found: " + wsa_build_ver)
new_version_found = True
# Write appversion content
subprocess.Popen(git, shell=True, stdout=None, stderr=None, executable='/bin/bash').wait()
file.seek(0)
file.truncate()
file.write(wsa_build_ver)
# Write Github Environment
msg = 'Update WSA Version from `v' + currentver + '` to `v' + wsa_build_ver + '`'
with open(env_file, "a") as wr:
wr.write("SHOULD_BUILD=yes\nRELEASE_TYPE=" + release_type + "\nMSG=" + msg)
file.close()
# Get user_code (Thanks to @bubbles-wow because of his repository)
users = {""}
try:
response = requests.get("https://api.github.com/repos/bubbles-wow/MS-Account-Token/contents/token.cfg")
if response.status_code == 200:
content = response.json()["content"]
content = content.encode("utf-8")
content = base64.b64decode(content)
text = content.decode("utf-8")
user_code = Prop(text).get("user_code")
updatetime = Prop(text).get("update_time")
print("Successfully get user token from server!")
print(f"Last update time: {updatetime}\n")
else:
user_code = ""
print(f"Failed to get user token from server! Error code: {response.status_code}\n")
except:
user_code = ""
if user_code == "":
users = {""}
else:
users = {"", user_code}
for user in users:
if user == "":
print("Checking WSA Stable version...\n")
if WSAChecker(user, "retail") == 1:
break
print("Checking Magisk version...\n")
if MagiskandGappsChecker("magisk") == 1:
break
print("Checking MindTheGapps version...\n")
if MagiskandGappsChecker("gapps") == 1:
break
else:
print("Checking WSA Insider version...\n")
if WSAChecker(user, "WIF") == 1:
break