Change endpoint URLs for NUS, this greatly improves download speed

This commit is contained in:
Campbell 2024-04-30 23:07:14 -04:00
parent 338446efcb
commit 8eeebd1d75
3 changed files with 21 additions and 20 deletions

View File

@ -1,6 +1,6 @@
[project] [project]
name = "libWiiPy" name = "libWiiPy"
version = "0.2.1" version = "0.2.2"
authors = [ authors = [
{ name="NinjaCheetah", email="ninjacheetah@ncxprogramming.com" }, { name="NinjaCheetah", email="ninjacheetah@ncxprogramming.com" },
{ name="Lillian Skinner", email="lillian@randommeaninglesscharacters.com" } { name="Lillian Skinner", email="lillian@randommeaninglesscharacters.com" }
@ -15,7 +15,7 @@ classifiers = [
] ]
dependencies = [ dependencies = [
"pycryptodome", "pycryptodome",
"urllib3" "requests"
] ]
[project.urls] [project.urls]

View File

@ -1,3 +1,3 @@
build build
pycryptodome pycryptodome
urllib3 requests

View File

@ -4,7 +4,7 @@
# See https://wiibrew.org/wiki/NUS for details about the NUS # See https://wiibrew.org/wiki/NUS for details about the NUS
import io import io
import urllib3 import requests
import hashlib import hashlib
from typing import List from typing import List
from .title import Title from .title import Title
@ -62,18 +62,18 @@ def download_tmd(title_id: str, title_version: int = None) -> bytes:
""" """
# Build the download URL. The structure is download/<TID>/tmd for latest and download/<TID>/tmd.<version> for # Build the download URL. The structure is download/<TID>/tmd for latest and download/<TID>/tmd.<version> for
# when a specific version is requested. # when a specific version is requested.
tmd_url = "http://ccs.shop.wii.com/ccs/download/" + title_id + "/tmd" tmd_url = "http://nus.cdn.shop.wii.com/ccs/download/" + title_id + "/tmd"
# Add the version to the URL if one was specified. # Add the version to the URL if one was specified.
if title_version is not None: if title_version is not None:
tmd_url += "." + str(title_version) tmd_url += "." + str(title_version)
# Make the request. # Make the request.
tmd_response = urllib3.request(method='GET', url=tmd_url, headers={'User-Agent': 'wii libnup/1.0'}) tmd_request = requests.get(url=tmd_url, headers={'User-Agent': 'wii libnup/1.0'}, stream=True)
# Handle a 404 if the TID/version doesn't exist. # Handle a 404 if the TID/version doesn't exist.
if tmd_response.status != 200: if tmd_request.status_code != 200:
raise ValueError("The requested Title ID or TMD version does not exist. Please check the Title ID and Title" raise ValueError("The requested Title ID or TMD version does not exist. Please check the Title ID and Title"
" version and then try again.") " version and then try again.")
# Save the raw TMD. # Save the raw TMD.
raw_tmd = tmd_response.data raw_tmd = tmd_request.content
# Use a TMD object to load the data and then return only the actual TMD. # Use a TMD object to load the data and then return only the actual TMD.
tmd_temp = TMD() tmd_temp = TMD()
tmd_temp.load(raw_tmd) tmd_temp.load(raw_tmd)
@ -98,14 +98,14 @@ def download_ticket(title_id: str) -> bytes:
""" """
# Build the download URL. The structure is download/<TID>/cetk, and cetk will only exist if this is a free # Build the download URL. The structure is download/<TID>/cetk, and cetk will only exist if this is a free
# title. # title.
ticket_url = "http://ccs.shop.wii.com/ccs/download/" + title_id + "/cetk" ticket_url = "http://nus.cdn.shop.wii.com/ccs/download/" + title_id + "/cetk"
# Make the request. # Make the request.
ticket_response = urllib3.request(method='GET', url=ticket_url, headers={'User-Agent': 'wii libnup/1.0'}) ticket_request = requests.get(url=ticket_url, headers={'User-Agent': 'wii libnup/1.0'}, stream=True)
if ticket_response.status != 200: if ticket_request.status_code != 200:
raise ValueError("The requested Title ID does not exist, or refers to a non-free title. Tickets can only" raise ValueError("The requested Title ID does not exist, or refers to a non-free title. Tickets can only"
" be downloaded for titles that are free on the NUS.") " be downloaded for titles that are free on the NUS.")
# Save the raw cetk file. # Save the raw cetk file.
cetk = ticket_response.data cetk = ticket_request.content
# Use a Ticket object to load only the Ticket data from cetk and return it. # Use a Ticket object to load only the Ticket data from cetk and return it.
ticket_temp = Ticket() ticket_temp = Ticket()
ticket_temp.load(cetk) ticket_temp.load(cetk)
@ -123,10 +123,10 @@ def download_cert() -> bytes:
The cert file. The cert file.
""" """
# Download the TMD and cetk for the System Menu 4.3U. # Download the TMD and cetk for the System Menu 4.3U.
tmd = urllib3.request(method='GET', url='http://ccs.shop.wii.com/ccs/download/0000000100000002/tmd.513', tmd = requests.get(url='http://nus.cdn.shop.wii.com/ccs/download/0000000100000002/tmd.513',
headers={'User-Agent': 'wii libnup/1.0'}).data headers={'User-Agent': 'wii libnup/1.0'}, stream=True).content
cetk = urllib3.request(method='GET', url='http://ccs.shop.wii.com/ccs/download/0000000100000002/cetk', cetk = requests.get(url='http://nus.cdn.shop.wii.com/ccs/download/0000000100000002/cetk',
headers={'User-Agent': 'wii libnup/1.0'}).data headers={'User-Agent': 'wii libnup/1.0'}, stream=True).content
# Assemble the certificate. # Assemble the certificate.
with io.BytesIO() as cert_data: with io.BytesIO() as cert_data:
# Certificate Authority data. # Certificate Authority data.
@ -163,14 +163,15 @@ def download_content(title_id: str, content_id: int) -> bytes:
content_id_hex = hex(content_id)[2:] content_id_hex = hex(content_id)[2:]
if len(content_id_hex) < 2: if len(content_id_hex) < 2:
content_id_hex = "0" + content_id_hex content_id_hex = "0" + content_id_hex
content_url = "http://ccs.shop.wii.com/ccs/download/" + title_id + "/000000" + content_id_hex content_url = "http://nus.cdn.shop.wii.com/ccs/download/" + title_id + "/000000" + content_id_hex
# Make the request. # Make the request.
content_response = urllib3.request(method='GET', url=content_url, headers={'User-Agent': 'wii libnup/1.0'}) content_request = requests.get(url=content_url, headers={'User-Agent': 'wii libnup/1.0'}, stream=True)
if content_response.status != 200: if content_request.status_code != 200:
raise ValueError("The requested Title ID does not exist, or an invalid Content ID is present in the" raise ValueError("The requested Title ID does not exist, or an invalid Content ID is present in the"
" content records provided.\n Failed while downloading Content ID: 000000" + " content records provided.\n Failed while downloading Content ID: 000000" +
content_id_hex) content_id_hex)
return content_response.data content_data = content_request.content
return content_data
def download_contents(title_id: str, tmd: TMD) -> List[bytes]: def download_contents(title_id: str, tmd: TMD) -> List[bytes]: