From 0f47550c32d1f2850ffc443980f38eedc873157a Mon Sep 17 00:00:00 2001 From: scott Date: Tue, 2 Aug 2022 17:24:16 -0400 Subject: [PATCH 1/3] optimize imports Signed-off-by: scott --- asahi_firmware/bluetooth.py | 6 +++++- asahi_firmware/core.py | 5 ++++- asahi_firmware/img4.py | 1 + asahi_firmware/multitouch.py | 8 ++++++-- asahi_firmware/update.py | 9 ++++++--- asahi_firmware/wifi.py | 6 +++++- src/diskutil.py | 6 +++++- src/main.py | 15 +++++++++++++-- src/osenum.py | 4 +++- src/osinstall.py | 5 ++++- src/stub.py | 12 +++++++++--- src/system.py | 5 ++++- src/urlcache.py | 6 ++++-- src/util.py | 7 ++++++- 14 files changed, 75 insertions(+), 20 deletions(-) diff --git a/asahi_firmware/bluetooth.py b/asahi_firmware/bluetooth.py index 1c21ee19..5c77090e 100644 --- a/asahi_firmware/bluetooth.py +++ b/asahi_firmware/bluetooth.py @@ -1,5 +1,9 @@ # SPDX-License-Identifier: MIT -import logging, os, os.path, re, sys +import logging +import os +import os.path +import re +import sys from collections import namedtuple, defaultdict from .core import FWFile diff --git a/asahi_firmware/core.py b/asahi_firmware/core.py index 544f283c..a66c9687 100644 --- a/asahi_firmware/core.py +++ b/asahi_firmware/core.py @@ -1,7 +1,10 @@ # SPDX-License-Identifier: MIT -import tarfile, io, logging +import io +import logging +import tarfile from hashlib import sha256 + class FWFile(object): def __init__(self, name, data): self.name = name diff --git a/asahi_firmware/img4.py b/asahi_firmware/img4.py index f9a9ebd1..431c1746 100644 --- a/asahi_firmware/img4.py +++ b/asahi_firmware/img4.py @@ -2,6 +2,7 @@ from . import asn1 + def img4p_extract(data): decoder = asn1.Decoder() decoder.start(data) diff --git a/asahi_firmware/multitouch.py b/asahi_firmware/multitouch.py index e38bb110..ea677382 100644 --- a/asahi_firmware/multitouch.py +++ b/asahi_firmware/multitouch.py @@ -1,8 +1,12 @@ # SPDX-License-Identifier: MIT +import logging +import os +import plistlib +import struct import xml.etree.ElementTree as ET -import plistlib, base64, struct, os, logging -from .img4 import img4p_extract + from .core import FWFile +from .img4 import img4p_extract log = logging.getLogger("asahi_firmware.multitouch") diff --git a/asahi_firmware/update.py b/asahi_firmware/update.py index 8d4c4806..9b17fb65 100644 --- a/asahi_firmware/update.py +++ b/asahi_firmware/update.py @@ -1,10 +1,13 @@ # SPDX-License-Identifier: MIT -import pathlib, tempfile, subprocess +import pathlib +import subprocess +import tempfile -from .core import FWPackage -from .wifi import WiFiFWCollection from .bluetooth import BluetoothFWCollection +from .core import FWPackage from .multitouch import MultitouchFWCollection +from .wifi import WiFiFWCollection + def update_firmware(source, dest, manifest): raw_fw = source.joinpath("all_firmware.tar.gz") diff --git a/asahi_firmware/wifi.py b/asahi_firmware/wifi.py index 2cbe962f..42ffa923 100644 --- a/asahi_firmware/wifi.py +++ b/asahi_firmware/wifi.py @@ -1,5 +1,9 @@ # SPDX-License-Identifier: MIT -import sys, os, os.path, pprint, statistics, logging +import logging +import os +import os.path +import sys + from .core import FWFile log = logging.getLogger("asahi_firmware.wifi") diff --git a/src/diskutil.py b/src/diskutil.py index ba4fa9cf..8e446eaa 100644 --- a/src/diskutil.py +++ b/src/diskutil.py @@ -1,7 +1,11 @@ # SPDX-License-Identifier: MIT -import plistlib, subprocess, sys, logging +import logging +import plistlib +import subprocess +import sys from dataclasses import dataclass + @dataclass class Partition: name: str diff --git a/src/main.py b/src/main.py index 61f4f6e6..aa71cfe7 100644 --- a/src/main.py +++ b/src/main.py @@ -1,9 +1,20 @@ #!/usr/bin/python3 # SPDX-License-Identifier: MIT -import os, os.path, shlex, subprocess, sys, time, termios, json, getpass +import getpass +import json +import os.path +import shlex +import subprocess +import termios +import time from dataclasses import dataclass -import system, osenum, stub, diskutil, osinstall, asahi_firmware +import asahi_firmware +import diskutil +import osenum +import osinstall +import stub +import system from util import * PART_ALIGN = psize("1MiB") diff --git a/src/osenum.py b/src/osenum.py index 6d729fce..77c2d72a 100644 --- a/src/osenum.py +++ b/src/osenum.py @@ -1,5 +1,7 @@ # SPDX-License-Identifier: MIT -import os, os.path, plistlib, subprocess, logging +import os.path +import plistlib +import subprocess from dataclasses import dataclass from util import * diff --git a/src/osinstall.py b/src/osinstall.py index bed60b8d..5152a24b 100644 --- a/src/osinstall.py +++ b/src/osinstall.py @@ -1,8 +1,11 @@ # SPDX-License-Identifier: MIT -import os, shutil, sys, stat, subprocess, urlcache, zipfile, logging +import subprocess +import urlcache +import zipfile from util import * + class OSInstaller(PackageInstaller): PART_ALIGNMENT = 1024 * 1024 def __init__(self, dutil, data, template): diff --git a/src/stub.py b/src/stub.py index 9d14a950..c40a6cc4 100644 --- a/src/stub.py +++ b/src/stub.py @@ -1,11 +1,17 @@ # SPDX-License-Identifier: MIT -import os, os.path, plistlib, shutil, sys, stat, subprocess, urlcache, zipfile, logging, json -import osenum -from asahi_firmware.wifi import WiFiFWCollection +import json +import os.path +import plistlib +import subprocess +import urlcache +import zipfile + from asahi_firmware.bluetooth import BluetoothFWCollection from asahi_firmware.multitouch import MultitouchFWCollection +from asahi_firmware.wifi import WiFiFWCollection from util import * + class StubInstaller(PackageInstaller): def __init__(self, sysinfo, dutil, osinfo, ipsw_info): super().__init__() diff --git a/src/system.py b/src/system.py index 295705f8..8d284e47 100644 --- a/src/system.py +++ b/src/system.py @@ -1,8 +1,11 @@ # SPDX-License-Identifier: MIT -import base64, plistlib, struct, subprocess, logging +import plistlib +import struct +import subprocess from util import * + class SystemInfo: def __init__(self): self.fetch() diff --git a/src/urlcache.py b/src/urlcache.py index b2cf404d..8ef38c12 100644 --- a/src/urlcache.py +++ b/src/urlcache.py @@ -1,10 +1,12 @@ # SPDX-License-Identifier: MIT -import os, sys, os.path, time, logging +import os.path +import time from dataclasses import dataclass - from urllib import request + from util import * + @dataclass class CacheBlock: idx: int diff --git a/src/util.py b/src/util.py index 621f755e..62532f11 100644 --- a/src/util.py +++ b/src/util.py @@ -1,5 +1,10 @@ # SPDX-License-Identifier: MIT -import re, logging, sys, os, stat, shutil +import logging +import os +import re +import stat +import sys + def ssize(v): suffixes = ["B", "KB", "MB", "GB", "TB"] From 27170ce880e194383236ca9221efd8f1ec833ec0 Mon Sep 17 00:00:00 2001 From: scott Date: Tue, 2 Aug 2022 17:34:06 -0400 Subject: [PATCH 2/3] ignore jetbrains IDE cache Signed-off-by: scott --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5346b913..64b3e97b 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ latest *.egg-info build dist +/.idea From 0f50285944edf22e4d645868e09fed433ca899ca Mon Sep 17 00:00:00 2001 From: scott Date: Tue, 2 Aug 2022 17:34:53 -0400 Subject: [PATCH 3/3] add whitespace to satisfy PEP-301 and PEP-302 Signed-off-by: scott --- asahi_firmware/core.py | 1 + asahi_firmware/multitouch.py | 4 ++++ asahi_firmware/update.py | 1 + asahi_firmware/wifi.py | 4 ++++ src/diskutil.py | 2 ++ src/main.py | 5 +++++ src/osenum.py | 2 ++ src/osinstall.py | 4 ++++ src/urlcache.py | 2 ++ src/util.py | 19 +++++++++++++++++++ 10 files changed, 44 insertions(+) diff --git a/asahi_firmware/core.py b/asahi_firmware/core.py index a66c9687..80db61ec 100644 --- a/asahi_firmware/core.py +++ b/asahi_firmware/core.py @@ -22,6 +22,7 @@ def __eq__(self, other): def __hash__(self): return hash(self.sha) + class FWPackage(object): def __init__(self, target): self.path = target diff --git a/asahi_firmware/multitouch.py b/asahi_firmware/multitouch.py index ea677382..4688b7da 100644 --- a/asahi_firmware/multitouch.py +++ b/asahi_firmware/multitouch.py @@ -10,10 +10,12 @@ log = logging.getLogger("asahi_firmware.multitouch") + def load_plist_xml(d): root = ET.fromstring(d.decode("ascii")) idmap = {} + def unmunge(el, idmap): if "ID" in el.attrib: idmap[el.attrib["ID"]] = el @@ -33,6 +35,7 @@ def unmunge(el, idmap): return plistlib.loads(ET.tostring(pl)) + def plist_to_bin(plist): iface_offset = None @@ -127,6 +130,7 @@ def add_padding(l): return hdr + blob + class MultitouchFWCollection(object): def __init__(self, source_path): self.fwfiles = [] diff --git a/asahi_firmware/update.py b/asahi_firmware/update.py index 9b17fb65..b72897d1 100644 --- a/asahi_firmware/update.py +++ b/asahi_firmware/update.py @@ -33,6 +33,7 @@ def update_firmware(source, dest, manifest): pkg.save_manifest(manifest) + if __name__ == "__main__": import argparse import logging diff --git a/asahi_firmware/wifi.py b/asahi_firmware/wifi.py index 42ffa923..3abf53de 100644 --- a/asahi_firmware/wifi.py +++ b/asahi_firmware/wifi.py @@ -8,6 +8,7 @@ log = logging.getLogger("asahi_firmware.wifi") + class FWNode(object): def __init__(self, this=None, leaves=None): if leaves is None: @@ -29,6 +30,7 @@ def print(self, depth=0, tag=""): for k, v in self.leaves.items(): v.print(depth + 1, k) + class WiFiFWCollection(object): EXTMAP = { "trx": "bin", @@ -37,6 +39,7 @@ class WiFiFWCollection(object): "txcb": "txcap_blob", } DIMS = ["C", "s", "P", "M", "V", "m", "A"] + def __init__(self, source_path): self.root = FWNode() self.load(source_path) @@ -142,6 +145,7 @@ def process_nvram(self, data): def print(self): self.root.print() + if __name__ == "__main__": col = WiFiFWCollection(sys.argv[1]) if len(sys.argv) > 2: diff --git a/src/diskutil.py b/src/diskutil.py index 8e446eaa..8f6ae54e 100644 --- a/src/diskutil.py +++ b/src/diskutil.py @@ -20,8 +20,10 @@ class Partition: container: object = None os: object = None + class DiskUtil: FREE_THRESHOLD = 16 * 1024 * 1024 + def __init__(self): self.verbose = "-v" in sys.argv diff --git a/src/main.py b/src/main.py index aa71cfe7..ca9e1435 100644 --- a/src/main.py +++ b/src/main.py @@ -32,6 +32,7 @@ MIN_MACOS_VERSION = "12.3" MIN_MACOS_VERSION_EXPERT = "12.1" + @dataclass class IPSW: version: str @@ -42,11 +43,13 @@ class IPSW: expert_only: bool url: str + @dataclass class Device: min_ver: str expert_only: bool + CHIP_MIN_VER = { 0x8103: "11.0", # T8103, M1 0x6000: "12.0", # T6000, M1 Pro @@ -96,6 +99,7 @@ class Device: "https://updates.cdn-apple.com/2022SpringFCS/fullrestores/071-08757/74A4F2A1-C747-43F9-A22A-C0AD5FB4ECB6/UniversalMac_12.3_21E230_Restore.ipsw"), ] + class InstallerMain: def __init__(self): self.data = json.load(open("installer_data.json")) @@ -839,6 +843,7 @@ def main_loop(self): elif act == "q": return False + if __name__ == "__main__": logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s', diff --git a/src/osenum.py b/src/osenum.py index 77c2d72a..16afdcc7 100644 --- a/src/osenum.py +++ b/src/osenum.py @@ -9,6 +9,7 @@ UUID_SROS = "3D3287DE-280D-4619-AAAB-D97469CA9C71" UUID_FROS = "C8858560-55AC-400F-BBB9-C9220A8DAC0D" + @dataclass class OSInfo: partition: object @@ -50,6 +51,7 @@ def __str__(self): else: return f"[{lbl}] {col(BRIGHT, RED)}incomplete install{col()} (macOS {self.version} stub) [{self.sys_volume}, {self.vgid}]" + class OSEnum: def __init__(self, sysinfo, dutil, sysdsk): self.sysinfo = sysinfo diff --git a/src/osinstall.py b/src/osinstall.py index 5152a24b..abbfd12f 100644 --- a/src/osinstall.py +++ b/src/osinstall.py @@ -8,6 +8,7 @@ class OSInstaller(PackageInstaller): PART_ALIGNMENT = 1024 * 1024 + def __init__(self, dutil, data, template): super().__init__() self.dutil = dutil @@ -21,12 +22,15 @@ def __init__(self, dutil, data, template): @property def default_os_name(self): return self.template["default_os_name"] + @property def min_size(self): return sum(self.align(psize(part["size"])) for part in self.template["partitions"]) + @property def expandable(self): return any(part.get("expand", False) for part in self.template["partitions"]) + @property def needs_firmware(self): return any(p.get("copy_firmware", False) for p in self.template["partitions"]) diff --git a/src/urlcache.py b/src/urlcache.py index 8ef38c12..1f1dfa08 100644 --- a/src/urlcache.py +++ b/src/urlcache.py @@ -12,6 +12,7 @@ class CacheBlock: idx: int data: bytes + class URLCache: CACHESIZE = 128 BLOCKSIZE = 1 * 1024 * 1024 @@ -139,6 +140,7 @@ def flush_progress(self): else: return False + if __name__ == "__main__": import sys, zipfile diff --git a/src/util.py b/src/util.py index 62532f11..5f9c60c8 100644 --- a/src/util.py +++ b/src/util.py @@ -16,6 +16,7 @@ def ssize(v): return f"{v:.2f} {i}" v /= 1000 + def psize(v, align=None): v = v.upper().replace(" ", "") base = 1000 @@ -36,6 +37,7 @@ def psize(v, align=None): val = align_up(val, align) return val + def split_ver(s): parts = re.split(r"[-,. ]", s) parts2 = [] @@ -49,11 +51,14 @@ def split_ver(s): parts2[-2] = 99 return tuple(parts2) + def align_up(v, a=16384): return (v + a - 1) & ~(a - 1) + align = align_up + def align_down(v, a=16384): return v & ~(a - 1) @@ -71,10 +76,12 @@ def align_down(v, a=16384): NORMAL = 22 RESET_ALL = 0 + def col(*color): color = ";".join(map(str, color)) return f"\033[{color}m" + def p_style(*args, color=[], **kwargs): if isinstance(color, int): color = [color] @@ -84,36 +91,47 @@ def p_style(*args, color=[], **kwargs): text += col() logging.info(f"MSG: {text}") + def p_plain(*args): p_style(*args) + def p_info(*args): p_style(*args, color=(BRIGHT, BLUE)) + def p_progress(*args): p_style(*args, color=(BRIGHT, MAGENTA)) + def p_message(*args): p_style(*args, color=BRIGHT) + def p_error(*args): p_style(*args, color=(BRIGHT, RED)) + def p_warning(*args): p_style(*args, color=(BRIGHT, YELLOW)) + def p_question(*args): p_style(*args, color=(BRIGHT, CYAN)) + def p_success(*args): p_style(*args, color=(BRIGHT, GREEN)) + def p_prompt(*args): p_style(*args, color=(BRIGHT, CYAN)) + def p_choice(*args): p_style(*args) + def input_prompt(*args): while True: p_style(f"{col(BRIGHT, WHITE)}ยป{col(BRIGHT, CYAN)}", *args, end="") @@ -125,6 +143,7 @@ def input_prompt(*args): logging.info(f"INPUT: {val!r}") return val + class PackageInstaller: def __init__(self): self.verbose = "-v" in sys.argv