Last active
January 12, 2022 23:21
-
-
Save paulchabotca/746dd676add048ce3d7d79b47d14bb7e to your computer and use it in GitHub Desktop.
Very hacky script I made formyself before I realized I was probably re-making the wheel.. but its finished. Needs requests and pick. Windows/Linux/Darwin compatible.. should be.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from typing import Match | |
import requests, os, argparse, sys, platform | |
import xml.etree.ElementTree as ET | |
from urllib.parse import urlparse | |
from pick import pick | |
from os import path | |
''' | |
Playstation 3 Game Update Downloader | |
Downloads game updates with given serial. | |
by: paulchabot.ca | |
Notes: Needs exception handling... | |
''' | |
def parseArgs(): | |
parser = argparse.ArgumentParser() | |
parser.add_argument("serial", help="Game serial ex: BCUS98114") | |
parser.add_argument("--download", help="<all / select> download all or select") | |
return parser | |
BASE_URL = "https://a0.ww.np.dl.playstation.net/tpl/np/" | |
GAME_SERIAL = "" | |
END_URL = "-ver.xml" | |
#https://a0.ww.np.dl.playstation.net/tpl/np/BCUS98114/BCUS98114 | |
# Build the Url by serial. | |
def buildURL(serial): | |
finalUrl = BASE_URL + serial + "/" + serial + END_URL | |
return finalUrl | |
# Download Update XML from PS Network | |
def getXML(url): | |
# print('Url: ' + url + '\n') | |
session = requests.Session() | |
session.verify = False | |
session.trust_env = False | |
resp = session.get(url) | |
## print("RESPONSE!" + str(resp.content) + "\n") | |
print(resp.content) | |
pkg_content = resp.content.decode('utf-8') | |
if len(pkg_content) > 0: | |
pkg = parsePKGS(pkg_content) | |
return pkg | |
else: | |
sys.exit('Error: Can not find any updates...') | |
## Download the package | |
# progress bar by Endophage | |
# https://stackoverflow.com/questions/15644964/python-progress-bar-and-downloads | |
def getPKG(url): | |
global args | |
uparse = urlparse(url) | |
packageFile = os.path.basename(uparse.path) | |
print("Downloading Package : " + packageFile) | |
session = requests.Session() | |
session.verify = False | |
session.trust_env = False | |
downloadDirWin = os.path.abspath('.') + "\\" + args.serial | |
downloadDirElse = os.path.abspath('.') + "/" + args.serial | |
# TODO: Make windows compatible. | |
if platform.system() == 'Windows': | |
if path.exists(downloadDirWin) is False: | |
os.mkdir(downloadDirWin) | |
with open(args.serial + "\\" + packageFile, "wb") as f: | |
print("Downloading %s" % packageFile) | |
response = requests.get(url, stream=True) | |
total_length = response.headers.get('content-length') | |
if total_length is None: # no content length header | |
f.write(response.content) | |
else: | |
dl = 0 | |
total_length = int(total_length) | |
for data in response.iter_content(chunk_size=4096): | |
dl += len(data) | |
f.write(data) | |
done = int(50 * dl / total_length) | |
sys.stdout.write("\r[%s%s]" % ('=' * done, ' ' * (50-done)) ) | |
sys.stdout.flush() | |
return True | |
else: | |
if path.exists(downloadDirElse) is False: | |
os.mkdir(downloadDirElse) | |
with open(args.serial + '/' + packageFile, "wb") as f: | |
print("Downloading %s" % packageFile) | |
response = requests.get(url, stream=True) | |
total_length = response.headers.get('content-length') | |
if total_length is None: # no content length header | |
f.write(response.content) | |
else: | |
dl = 0 | |
total_length = int(total_length) | |
for data in response.iter_content(chunk_size=4096): | |
dl += len(data) | |
f.write(data) | |
done = int(50 * dl / total_length) | |
sys.stdout.write("\r[%s%s]" % ('=' * done, ' ' * (50-done)) ) | |
sys.stdout.flush() | |
return True | |
# Parse the Update XML | |
# This is horrible, but works. | |
def parsePKGS(xmlDump): | |
# print("XMLDUMP\n" + xmlDump + "\n") | |
root = ET.fromstring(xmlDump) | |
updatePKGS = [] | |
for packages in root: | |
package = {} | |
for item in packages: | |
# print(str(item.tag) + " " + str(item.attrib)) | |
package[str(item.attrib['version'])] = {'ps3_system_ver': str(item.attrib['ps3_system_ver']),'url' : str(item.attrib['url']), 'version': str(item.attrib['version']) } | |
updatePKGS.append(package) | |
return updatePKGS | |
# Download All | |
# just download all packages | |
def downloadALL(serial): | |
packages = getXML(buildURL(serial)) | |
for package in packages: | |
print("Downloading all updates for " + serial + "\n") | |
for values in package.values(): | |
if getPKG(values['url']) == False: | |
print("Error Downloading : " + str(values['url'])) | |
print('\n') | |
print('Downloaded all packages for ' + serial + '\n') | |
# Package Menu | |
# creates a selection menu using pick | |
def packageMENU(args): | |
packages = getXML(buildURL(args.serial)) | |
pkgOptions = [] | |
for package in packages: | |
for values in package.values(): | |
pkgOptions.append({'Version': values['version'], 'System Ver': values['ps3_system_ver'], 'Url': values['url']}) | |
# Create the menu | |
title = 'PS3 Game Update: Choose the packages you want to download ' | |
selected = pick(pkgOptions, title, multiselect=True, min_selection_count=1) | |
for pkg in selected: | |
for item in pkg: | |
if isinstance(item, dict): | |
print('Downloading package' + item['Version'] + ".... \n") | |
if getPKG(item['Url']) == False: | |
print("Error Downloading : " + str(item['Url'])) | |
print('\n') | |
print('Finished Downloading!') | |
# MAIN | |
if __name__ == '__main__': | |
parser = parseArgs() | |
args = parser.parse_args() | |
if args.download: | |
match args.download: | |
case 'all' : print("Download all set."); downloadALL(args.serial) | |
match args.download: | |
case 'select' : print("Select Version"); packageMENU(args) ## sending all args for future outputdir argument |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment