Skip to content

Instantly share code, notes, and snippets.

@Merculous
Last active May 25, 2023 03:27
Show Gist options
  • Save Merculous/a4dc2eb0f2a54fa4328f936f41fd624b to your computer and use it in GitHub Desktop.
Save Merculous/a4dc2eb0f2a54fa4328f936f41fd624b to your computer and use it in GitHub Desktop.
Python3 script to download all ipsw's for a device using the ipsw.me api
#!/usr/bin/env python3
import json
from argparse import ArgumentParser
from concurrent.futures import ThreadPoolExecutor, as_completed
from urllib.error import HTTPError
from urllib.request import urlopen
def readFromURL(url, mode):
try:
r = urlopen(url)
except HTTPError:
raise
else:
if mode == 's': # string (str)
data = r.read().decode('utf-8')
return json.loads(data)
elif mode == 'f': # file (bytes)
data = r.read()
return data
else:
print(f'Unknown mode given: {mode}')
raise ValueError
def getDeviceInfo(device):
url = f'https://api.ipsw.me/v4/device/{device}'
data = readFromURL(url, 's')
return data
def getFirmwaresForDevice(device):
info = getDeviceInfo(device)
firmwares = info.get('firmwares')
return firmwares
def getUrlForVersion(firmware):
url = firmware.get('url')
return url
def downloadIPSW(url, file_name):
print(f'Downloading from url: {url}')
data = readFromURL(url, 'f')
print(f'Writing to file: {file_name}')
with open(file_name, 'wb') as f:
f.write(data)
def downloadAllIPSWSForDevice(device, num_threads):
firmwares = getFirmwaresForDevice(device)
with ThreadPoolExecutor(max_workers=num_threads) as executor:
futures = []
for firmware in firmwares:
url = getUrlForVersion(firmware)
file_name = url.split('/')[-1]
future = executor.submit(downloadIPSW, url, file_name)
futures.append(future)
for future in as_completed(futures):
try:
future.result()
except Exception as e:
print(f'Error occurred: {e}')
def main():
parser = ArgumentParser()
parser.add_argument('-d', help='device', nargs=1)
parser.add_argument('-t', help='number of threads', nargs='?', type=int, default=2)
args = parser.parse_args()
if args.d:
print(f'Download ipsw\'s with {args.t} threads...')
downloadAllIPSWSForDevice(args.d[0], args.t)
else:
parser.print_help()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment