Skip to content

Instantly share code, notes, and snippets.

@paulchabotca
Last active January 12, 2022 23:21
Show Gist options
  • Save paulchabotca/746dd676add048ce3d7d79b47d14bb7e to your computer and use it in GitHub Desktop.
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.
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