[Scummvm-git-logs] scummvm master -> 2e9862863c1245eadeebc370a9602fea76319c28
sev-
noreply at scummvm.org
Wed Apr 24 22:28:47 UTC 2024
This automated email contains information about 7 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
90ab5bfa5a DEVTOOLS: DUMPERCOMPANION: support iso9660 and hybrid disk images
11279cd07a DEVTOOLS: DUMPERCOMPANION: support Joliet, Rock Ridge and UDF extensions
4aa571b95f DEVTOOLS: DUMPERCOMPANION: support puny encoding, japanese and dry run for iso9660
37b9bbb32f DEVTOOLS: COMPANION: Add autodetection of file system and extensions if unspecified
7e4da992ca DEVTOOLS: COMPANION: Add probe parser and --silent flag in ISO parser
15efeac016 DEVTOOLS: COMPANION: Add enums for file systems and extensions
2e9862863c DEVTOOLS: COMPANION: Add version checker pycdlib module
Commit: 90ab5bfa5aeec7ee3ed2c837e55ce0aa0ce0d3a9
https://github.com/scummvm/scummvm/commit/90ab5bfa5aeec7ee3ed2c837e55ce0aa0ce0d3a9
Author: Darkhood148 (ujjwal.sharma9999999 at gmail.com)
Date: 2024-04-25T00:28:42+02:00
Commit Message:
DEVTOOLS: DUMPERCOMPANION: support iso9660 and hybrid disk images
Add parsers to handle iso9660 and hybrid disk images
Add functions for extracting iso9660 and hybrid disk images
Changed paths:
devtools/dumper-companion.py
diff --git a/devtools/dumper-companion.py b/devtools/dumper-companion.py
index c85db87cd48..c37e911dc3c 100755
--- a/devtools/dumper-companion.py
+++ b/devtools/dumper-companion.py
@@ -7,7 +7,7 @@
# See https://wiki.scummvm.org/index.php?title=HOWTO-Dump_Macintosh_Media for
# the full documentation
#
-# prerequisites: pip3 install machfs
+# prerequisites: pip3 install machfs pycdlib
#
# Development information:
# This file contains tests. They can be run with:
@@ -31,6 +31,7 @@ from struct import pack, unpack
from typing import Any
import machfs
+import pycdlib
# fmt: off
@@ -289,7 +290,7 @@ def encode_string(args: argparse.Namespace) -> int:
return 0
-def extract_volume(args: argparse.Namespace) -> int:
+def extract_volume_hfs(args: argparse.Namespace) -> int:
"""Extract an HFS volume"""
source_volume: Path = args.src
loglevel: str = args.log
@@ -340,6 +341,62 @@ def extract_volume(args: argparse.Namespace) -> int:
extract_partition(args, vol)
+def extract_volume_iso(args: argparse.Namespace):
+ """Extract an ISO volume"""
+ source_volume = args.src
+ loglevel: str = args.log
+
+ numeric_level = getattr(logging, loglevel.upper(), None)
+ if not isinstance(numeric_level, int):
+ raise ValueError("Invalid log level: %s" % loglevel)
+ logging.basicConfig(format="%(levelname)s: %(message)s", level=numeric_level)
+
+ logging.info(f"Loading {source_volume} ...")
+
+ iso = pycdlib.PyCdlib()
+ iso.open(source_volume)
+
+ output_dir = str(args.dir)
+
+ for dirname, dirlist, filelist in iso.walk(iso_path='/'):
+ pwd = output_dir + dirname
+ for dir in dirlist:
+ joined_path = os.path.join(pwd, dir)
+ os.makedirs(joined_path, exist_ok=True)
+ for file in filelist:
+ filename = file.split(';')[0]
+ if dirname != '/':
+ iso_file_path = dirname + '/' + file
+ else:
+ iso_file_path = dirname + file
+ with open(os.path.join(pwd, filename), 'wb') as f:
+ iso.get_file_from_iso_fp(outfp=f, iso_path=iso_file_path)
+
+ iso.close()
+
+
+def extract_volume_hybrid(args: argparse.Namespace):
+ source_volume = args.src
+ loglevel: str = args.log
+
+ numeric_level = getattr(logging, loglevel.upper(), None)
+ if not isinstance(numeric_level, int):
+ raise ValueError("Invalid log level: %s" % loglevel)
+ logging.basicConfig(format="%(levelname)s: %(message)s", level=numeric_level)
+
+ logging.info(f"Loading {source_volume} ...")
+
+ if not args.macdump and not args.iso9660dump:
+ logging.error("Please provide at least one dump for the hybrid drive")
+ return
+ if args.macdump:
+ args.dir = args.macdump
+ extract_volume_hfs(args)
+ if args.iso9660dump:
+ args.dir = args.iso9660dump
+ extract_volume_iso(args)
+
+
def extract_partition(args: argparse.Namespace, vol) -> int:
destination_dir: Path = args.dir
japanese: bool = args.japanese
@@ -731,35 +788,81 @@ def generate_parser() -> argparse.ArgumentParser:
"""
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
- parser_iso = subparsers.add_parser("iso", help="Dump HFS ISOs")
+ parser_hfs = subparsers.add_parser("hfs", help="Dump HFS ISOs")
- parser_iso.add_argument("src", metavar="INPUT", type=Path, help="Disk image")
- parser_iso.add_argument(
+ parser_hfs.add_argument("src", metavar="INPUT", type=Path, help="Disk image")
+ parser_hfs.add_argument(
"--nopunycode", action="store_true", help="never encode pathnames into punycode"
)
- parser_iso.add_argument(
+ parser_hfs.add_argument(
"--japanese", action="store_true", help="read MacJapanese HFS"
)
- parser_iso.add_argument(
+ parser_hfs.add_argument(
"--dryrun", action="store_true", help="do not write any files"
)
- parser_iso.add_argument(
+ parser_hfs.add_argument(
"--log", metavar="LEVEL", help="set logging level", default="INFO"
)
- parser_iso.add_argument(
+ parser_hfs.add_argument(
"--forcemacbinary",
action="store_true",
help="always encode using MacBinary, even for files with no resource fork",
)
- parser_iso.add_argument(
+ parser_hfs.add_argument(
"--addmacbinaryext",
action="store_true",
help="add .bin extension when using MacBinary",
)
- parser_iso.add_argument(
+ parser_hfs.add_argument(
"dir", metavar="OUTPUT", type=Path, help="Destination folder"
)
- parser_iso.set_defaults(func=extract_volume)
+ parser_hfs.set_defaults(func=extract_volume_hfs)
+
+ parser_iso9660 = subparsers.add_parser(
+ "iso9660", help="Dump ISO9660 ISOs"
+ )
+ parser_iso9660.add_argument(
+ "--log", metavar="LEVEL", help="set logging level", default="INFO"
+ )
+ parser_iso9660.add_argument("src", metavar="INPUT", type=Path, help="Disk image")
+ parser_iso9660.add_argument(
+ "dir", metavar="OUTPUT", type=Path, help="Destination folder"
+ )
+ parser_iso9660.set_defaults(func=extract_volume_iso)
+
+ parser_hybrid = subparsers.add_parser(
+ "hybrid", help="Dump Hybrid ISOs"
+ )
+ parser_hybrid.add_argument("src", metavar="INPUT", type=Path, help="Disk image")
+ parser_hybrid.add_argument(
+ "--nopunycode", action="store_true", help="never encode pathnames into punycode"
+ )
+ parser_hybrid.add_argument(
+ "--japanese", action="store_true", help="read MacJapanese HFS"
+ )
+ parser_hybrid.add_argument(
+ "--dryrun", action="store_true", help="do not write any files"
+ )
+ parser_hybrid.add_argument(
+ "--log", metavar="LEVEL", help="set logging level", default="INFO"
+ )
+ parser_hybrid.add_argument(
+ "--forcemacbinary",
+ action="store_true",
+ help="always encode using MacBinary, even for files with no resource fork",
+ )
+ parser_hybrid.add_argument(
+ "--addmacbinaryext",
+ action="store_true",
+ help="add .bin extension when using MacBinary",
+ )
+ parser_hybrid.add_argument(
+ "--macdump", metavar="OUTPUT", type=Path, help="Destination Folder for HFS Dump"
+ )
+ parser_hybrid.add_argument(
+ "--iso9660dump", metavar="OUTPUT", type=Path, help="Destination Folder for ISO9660 Dump"
+ )
+ parser_hybrid.set_defaults(func=extract_volume_hybrid)
parser_dir = subparsers.add_parser(
"dir", help="Punyencode all files and dirs in place"
Commit: 11279cd07a916129dc45edc437f723b88889e7e0
https://github.com/scummvm/scummvm/commit/11279cd07a916129dc45edc437f723b88889e7e0
Author: Darkhood148 (ujjwal.sharma9999999 at gmail.com)
Date: 2024-04-25T00:28:42+02:00
Commit Message:
DEVTOOLS: DUMPERCOMPANION: support Joliet, Rock Ridge and UDF extensions
Add '--extension' argument to handle different iso9660 extensions
Changed paths:
devtools/dumper-companion.py
diff --git a/devtools/dumper-companion.py b/devtools/dumper-companion.py
index c37e911dc3c..9bd495811f5 100755
--- a/devtools/dumper-companion.py
+++ b/devtools/dumper-companion.py
@@ -358,19 +358,28 @@ def extract_volume_iso(args: argparse.Namespace):
output_dir = str(args.dir)
- for dirname, dirlist, filelist in iso.walk(iso_path='/'):
+ if not args.extension:
+ path_type = 'iso_path'
+ elif args.extension == 'joliet':
+ path_type = 'joliet_path'
+ elif args.extension == 'rr':
+ path_type = 'rr_type'
+ else:
+ path_type = 'udf_path'
+
+ arg = {path_type: '/'}
+
+ for dirname, dirlist, filelist in iso.walk(**arg):
pwd = output_dir + dirname
for dir in dirlist:
joined_path = os.path.join(pwd, dir)
os.makedirs(joined_path, exist_ok=True)
for file in filelist:
filename = file.split(';')[0]
- if dirname != '/':
- iso_file_path = dirname + '/' + file
- else:
- iso_file_path = dirname + file
+ iso_file_path = os.path.join(dirname, filename)
with open(os.path.join(pwd, filename), 'wb') as f:
- iso.get_file_from_iso_fp(outfp=f, iso_path=iso_file_path)
+ arg[path_type] = iso_file_path
+ iso.get_file_from_iso_fp(outfp=f, **arg)
iso.close()
@@ -824,6 +833,7 @@ def generate_parser() -> argparse.ArgumentParser:
parser_iso9660.add_argument(
"--log", metavar="LEVEL", help="set logging level", default="INFO"
)
+ parser_iso9660.add_argument("--extension", choices=['joliet', 'rr', 'udf'], metavar="EXTENSION", help="Use if the iso9660 has an extension")
parser_iso9660.add_argument("src", metavar="INPUT", type=Path, help="Disk image")
parser_iso9660.add_argument(
"dir", metavar="OUTPUT", type=Path, help="Destination folder"
Commit: 4aa571b95f2f4f55744ca6cbe320ca33774421d6
https://github.com/scummvm/scummvm/commit/4aa571b95f2f4f55744ca6cbe320ca33774421d6
Author: Darkhood148 (ujjwal.sharma9999999 at gmail.com)
Date: 2024-04-25T00:28:42+02:00
Commit Message:
DEVTOOLS: DUMPERCOMPANION: support puny encoding, japanese and dry run for iso9660
Add optional arguments '--japanese', '--no-punyencode' and '--dryrun' for dealing with 'shift_jis' encoded filenames, disregarding puny encoding and dry running the script respectively
Changed paths:
devtools/dumper-companion.py
diff --git a/devtools/dumper-companion.py b/devtools/dumper-companion.py
index 9bd495811f5..484bdfc1c84 100755
--- a/devtools/dumper-companion.py
+++ b/devtools/dumper-companion.py
@@ -345,6 +345,9 @@ def extract_volume_iso(args: argparse.Namespace):
"""Extract an ISO volume"""
source_volume = args.src
loglevel: str = args.log
+ dopunycode: bool = not args.nopunycode
+ dryrun: bool = args.dryrun
+ japanese: bool = args.japanese
numeric_level = getattr(logging, loglevel.upper(), None)
if not isinstance(numeric_level, int):
@@ -363,24 +366,35 @@ def extract_volume_iso(args: argparse.Namespace):
elif args.extension == 'joliet':
path_type = 'joliet_path'
elif args.extension == 'rr':
- path_type = 'rr_type'
+ path_type = 'rr_path'
else:
path_type = 'udf_path'
arg = {path_type: '/'}
+ if japanese:
+ arg['encoding'] = 'shift_jis'
+
for dirname, dirlist, filelist in iso.walk(**arg):
pwd = output_dir + dirname
for dir in dirlist:
joined_path = os.path.join(pwd, dir)
- os.makedirs(joined_path, exist_ok=True)
+ if not dryrun:
+ os.makedirs(joined_path, exist_ok=True)
+ else:
+ print(joined_path)
+
+ if dryrun:
+ continue
+
for file in filelist:
filename = file.split(';')[0]
iso_file_path = os.path.join(dirname, filename)
with open(os.path.join(pwd, filename), 'wb') as f:
arg[path_type] = iso_file_path
iso.get_file_from_iso_fp(outfp=f, **arg)
-
+ if dopunycode:
+ punyencode_dir(Path(output_dir))
iso.close()
@@ -834,6 +848,15 @@ def generate_parser() -> argparse.ArgumentParser:
"--log", metavar="LEVEL", help="set logging level", default="INFO"
)
parser_iso9660.add_argument("--extension", choices=['joliet', 'rr', 'udf'], metavar="EXTENSION", help="Use if the iso9660 has an extension")
+ parser_iso9660.add_argument(
+ "--nopunycode", action="store_true", help="never encode pathnames into punycode"
+ )
+ parser_iso9660.add_argument(
+ "--dryrun", action="store_true", help="do not write any files"
+ )
+ parser_iso9660.add_argument(
+ "--japanese", action="store_true", help="read MacJapanese HFS"
+ )
parser_iso9660.add_argument("src", metavar="INPUT", type=Path, help="Disk image")
parser_iso9660.add_argument(
"dir", metavar="OUTPUT", type=Path, help="Destination folder"
Commit: 37b9bbb32f3435490dccd28938a13927ca06303f
https://github.com/scummvm/scummvm/commit/37b9bbb32f3435490dccd28938a13927ca06303f
Author: Darkhood148 (ujjwal.sharma9999999 at gmail.com)
Date: 2024-04-25T00:28:42+02:00
Commit Message:
DEVTOOLS: COMPANION: Add autodetection of file system and extensions if unspecified
Add functions which detect the file system (which was provided on discord thanks to eintei) and extensions if not specified by the user; combine iso9660, hfs and hybrid parsers into one common iso parser
Changed paths:
devtools/dumper-companion.py
diff --git a/devtools/dumper-companion.py b/devtools/dumper-companion.py
index 484bdfc1c84..d8c56e7dcb6 100755
--- a/devtools/dumper-companion.py
+++ b/devtools/dumper-companion.py
@@ -18,6 +18,7 @@
from __future__ import annotations
import argparse
+import copy
import logging
import os
import sys
@@ -290,6 +291,82 @@ def encode_string(args: argparse.Namespace) -> int:
return 0
+def check_extension(args):
+ args_copy = copy.copy(args)
+ args_copy.dryrun = True
+ extensions = ['joliet', 'rr', 'udf']
+ args_copy.dir = args.dir.joinpath('test')
+ args_copy.fs = 'iso9660'
+ args.silent = True
+ for extension in extensions:
+ args_copy.extension = extension
+ try:
+ extract_volume_iso(args_copy)
+ except Exception as e:
+ pass
+ else:
+ return extension
+
+
+def check_fs(iso):
+ APPLE_PM_SIGNATURE = b"PM\x00\x00"
+ SECTOR_SIZE = 512
+
+ disk_formats = []
+ f = open(iso, "rb")
+
+ # ISO Primary Volume Descriptor
+ f.seek(64 * SECTOR_SIZE)
+ if f.read(6) == b"\x01CD001":
+ # print('Found ISO PVD')
+ disk_formats.append("iso9660")
+
+ f.seek(0)
+ mac_1 = f.read(4)
+ f.seek(1 * SECTOR_SIZE)
+ mac_2 = f.read(4)
+ f.seek(2 * SECTOR_SIZE)
+ mac_3 = f.read(2)
+ if mac_2 == APPLE_PM_SIGNATURE:
+ partition_num = 1
+ while True:
+ num_partitions, partition_start, partition_size = unpack(">III", f.read(12))
+ f.seek(32, 1)
+ partition_type = f.read(32).decode("mac-roman").split("\x00")[0]
+ if partition_type == "Apple_HFS":
+ disk_formats.append("hfs")
+ break
+ # Check if there are more partitions
+ if partition_num <= num_partitions:
+ # Move onto the next partition
+ partition_num += 1
+ f.seek(partition_num * SECTOR_SIZE + 4)
+ # Bootable Mac-only disc
+ elif mac_1 == b"LK\x60\x00" and mac_3 == b"BD":
+ disk_formats.append("hfs")
+
+ if len(disk_formats) > 1:
+ return 'hybrid'
+ else:
+ return disk_formats[0]
+
+
+def extract_iso(args: argparse.Namespace):
+ if not args.fs:
+ args.fs = check_fs(args.src)
+ print('Detected filesystem:', args.fs)
+ if (args.fs == 'hybrid' or args.fs == 'iso9660') and not args.extension:
+ args.extension = check_extension(args)
+ print('Detected extension:', args.extension)
+
+ if args.fs == 'iso9660':
+ extract_volume_iso(args)
+ elif args.fs == 'hfs':
+ extract_volume_hfs(args)
+ else:
+ extract_volume_hybrid(args)
+
+
def extract_volume_hfs(args: argparse.Namespace) -> int:
"""Extract an HFS volume"""
source_volume: Path = args.src
@@ -381,7 +458,7 @@ def extract_volume_iso(args: argparse.Namespace):
joined_path = os.path.join(pwd, dir)
if not dryrun:
os.makedirs(joined_path, exist_ok=True)
- else:
+ elif not args.silent:
print(joined_path)
if dryrun:
@@ -389,7 +466,7 @@ def extract_volume_iso(args: argparse.Namespace):
for file in filelist:
filename = file.split(';')[0]
- iso_file_path = os.path.join(dirname, filename)
+ iso_file_path = os.path.join(dirname, file)
with open(os.path.join(pwd, filename), 'wb') as f:
arg[path_type] = iso_file_path
iso.get_file_from_iso_fp(outfp=f, **arg)
@@ -409,15 +486,13 @@ def extract_volume_hybrid(args: argparse.Namespace):
logging.info(f"Loading {source_volume} ...")
- if not args.macdump and not args.iso9660dump:
- logging.error("Please provide at least one dump for the hybrid drive")
- return
- if args.macdump:
- args.dir = args.macdump
- extract_volume_hfs(args)
- if args.iso9660dump:
- args.dir = args.iso9660dump
- extract_volume_iso(args)
+ main_dir = args.dir
+
+ args.dir = main_dir.joinpath('hfs')
+ extract_volume_hfs(args)
+
+ args.dir = main_dir.joinpath('iso9660')
+ extract_volume_iso(args)
def extract_partition(args: argparse.Namespace, vol) -> int:
@@ -811,91 +886,39 @@ def generate_parser() -> argparse.ArgumentParser:
"""
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
- parser_hfs = subparsers.add_parser("hfs", help="Dump HFS ISOs")
+ parser_iso = subparsers.add_parser("iso", help="Dump HFS ISOs")
- parser_hfs.add_argument("src", metavar="INPUT", type=Path, help="Disk image")
- parser_hfs.add_argument(
+ parser_iso.add_argument("src", metavar="INPUT", type=Path, help="Disk image")
+ parser_iso.add_argument(
"--nopunycode", action="store_true", help="never encode pathnames into punycode"
)
- parser_hfs.add_argument(
+ parser_iso.add_argument(
"--japanese", action="store_true", help="read MacJapanese HFS"
)
- parser_hfs.add_argument(
+ parser_iso.add_argument(
"--dryrun", action="store_true", help="do not write any files"
)
- parser_hfs.add_argument(
+ parser_iso.add_argument(
"--log", metavar="LEVEL", help="set logging level", default="INFO"
)
- parser_hfs.add_argument(
+ parser_iso.add_argument(
"--forcemacbinary",
action="store_true",
help="always encode using MacBinary, even for files with no resource fork",
)
- parser_hfs.add_argument(
+ parser_iso.add_argument(
"--addmacbinaryext",
action="store_true",
help="add .bin extension when using MacBinary",
)
- parser_hfs.add_argument(
- "dir", metavar="OUTPUT", type=Path, help="Destination folder"
- )
- parser_hfs.set_defaults(func=extract_volume_hfs)
-
- parser_iso9660 = subparsers.add_parser(
- "iso9660", help="Dump ISO9660 ISOs"
- )
- parser_iso9660.add_argument(
- "--log", metavar="LEVEL", help="set logging level", default="INFO"
- )
- parser_iso9660.add_argument("--extension", choices=['joliet', 'rr', 'udf'], metavar="EXTENSION", help="Use if the iso9660 has an extension")
- parser_iso9660.add_argument(
- "--nopunycode", action="store_true", help="never encode pathnames into punycode"
- )
- parser_iso9660.add_argument(
- "--dryrun", action="store_true", help="do not write any files"
- )
- parser_iso9660.add_argument(
- "--japanese", action="store_true", help="read MacJapanese HFS"
- )
- parser_iso9660.add_argument("src", metavar="INPUT", type=Path, help="Disk image")
- parser_iso9660.add_argument(
+ parser_iso.add_argument("--extension", choices=['joliet', 'rr', 'udf'], metavar="EXTENSION",
+ help="Use if the iso9660 has an extension")
+ parser_iso.add_argument("--fs", choices=['iso9660', 'hfs', 'hybrid'], metavar="FILE_SYSTEM",
+ help="Specify the file system of the ISO")
+ parser_iso.add_argument(
"dir", metavar="OUTPUT", type=Path, help="Destination folder"
)
- parser_iso9660.set_defaults(func=extract_volume_iso)
-
- parser_hybrid = subparsers.add_parser(
- "hybrid", help="Dump Hybrid ISOs"
- )
- parser_hybrid.add_argument("src", metavar="INPUT", type=Path, help="Disk image")
- parser_hybrid.add_argument(
- "--nopunycode", action="store_true", help="never encode pathnames into punycode"
- )
- parser_hybrid.add_argument(
- "--japanese", action="store_true", help="read MacJapanese HFS"
- )
- parser_hybrid.add_argument(
- "--dryrun", action="store_true", help="do not write any files"
- )
- parser_hybrid.add_argument(
- "--log", metavar="LEVEL", help="set logging level", default="INFO"
- )
- parser_hybrid.add_argument(
- "--forcemacbinary",
- action="store_true",
- help="always encode using MacBinary, even for files with no resource fork",
- )
- parser_hybrid.add_argument(
- "--addmacbinaryext",
- action="store_true",
- help="add .bin extension when using MacBinary",
- )
- parser_hybrid.add_argument(
- "--macdump", metavar="OUTPUT", type=Path, help="Destination Folder for HFS Dump"
- )
- parser_hybrid.add_argument(
- "--iso9660dump", metavar="OUTPUT", type=Path, help="Destination Folder for ISO9660 Dump"
- )
- parser_hybrid.set_defaults(func=extract_volume_hybrid)
+ parser_iso.set_defaults(func=extract_iso)
parser_dir = subparsers.add_parser(
"dir", help="Punyencode all files and dirs in place"
Commit: 7e4da992ca250d766a853a7ef46078420341a42c
https://github.com/scummvm/scummvm/commit/7e4da992ca250d766a853a7ef46078420341a42c
Author: Darkhood148 (ujjwal.sharma9999999 at gmail.com)
Date: 2024-04-25T00:28:42+02:00
Commit Message:
DEVTOOLS: COMPANION: Add probe parser and --silent flag in ISO parser
Add new parser probe which detects the file system, extension and presence of japanese of a provided ISO; Add a silent flag that disables all print and log messages
Changed paths:
devtools/dumper-companion.py
diff --git a/devtools/dumper-companion.py b/devtools/dumper-companion.py
index d8c56e7dcb6..54a82996ed5 100755
--- a/devtools/dumper-companion.py
+++ b/devtools/dumper-companion.py
@@ -291,13 +291,53 @@ def encode_string(args: argparse.Namespace) -> int:
return 0
+def probe_iso(args):
+ fs = check_fs(args.src)
+ print('Detected file system:', fs)
+ args.fs = fs
+ args.dryrun = True
+ args.dir = Path('testing')
+ args.silent = True
+ args.forcemacbinary = False
+ args.addmacbinaryext = False
+ args.log = 'INFO'
+ args.nopunycode = False
+ args.japanese = False
+ if fs == 'hybrid' or fs == 'iso9660':
+ args.extension = check_extension(args)
+ print('Detected extension:', args.extension)
+ print('Japanese detected:', check_japanese(args))
+
+
+def check_japanese(args):
+ args.japanese = False
+ if args.fs == 'hybrid':
+ fn = extract_volume_hybrid
+ elif args.fs == 'iso9660':
+ fn = extract_volume_iso
+ else:
+ fn = extract_volume_hfs
+ try:
+ fn(args)
+ except Exception as e:
+ args.japanese = True
+ try:
+ fn(args)
+ except Exception as e:
+ raise Exception('Could not determine japanese')
+ else:
+ return True
+ else:
+ return False
+
+
def check_extension(args):
args_copy = copy.copy(args)
args_copy.dryrun = True
extensions = ['joliet', 'rr', 'udf']
args_copy.dir = args.dir.joinpath('test')
args_copy.fs = 'iso9660'
- args.silent = True
+ args_copy.silent = True
for extension in extensions:
args_copy.extension = extension
try:
@@ -371,13 +411,15 @@ def extract_volume_hfs(args: argparse.Namespace) -> int:
"""Extract an HFS volume"""
source_volume: Path = args.src
loglevel: str = args.log
+ silent: bool = args.silent
numeric_level = getattr(logging, loglevel.upper(), None)
if not isinstance(numeric_level, int):
raise ValueError("Invalid log level: %s" % loglevel)
logging.basicConfig(format="%(levelname)s: %(message)s", level=numeric_level)
- logging.info(f"Loading {source_volume} ...")
+ if not silent:
+ logging.info(f"Loading {source_volume} ...")
vol = machfs.Volume()
partitions = []
with source_volume.open(mode="rb") as f:
@@ -425,13 +467,15 @@ def extract_volume_iso(args: argparse.Namespace):
dopunycode: bool = not args.nopunycode
dryrun: bool = args.dryrun
japanese: bool = args.japanese
+ silent: bool = args.silent
numeric_level = getattr(logging, loglevel.upper(), None)
if not isinstance(numeric_level, int):
raise ValueError("Invalid log level: %s" % loglevel)
logging.basicConfig(format="%(levelname)s: %(message)s", level=numeric_level)
- logging.info(f"Loading {source_volume} ...")
+ if not silent:
+ logging.info(f"Loading {source_volume} ...")
iso = pycdlib.PyCdlib()
iso.open(source_volume)
@@ -458,7 +502,7 @@ def extract_volume_iso(args: argparse.Namespace):
joined_path = os.path.join(pwd, dir)
if not dryrun:
os.makedirs(joined_path, exist_ok=True)
- elif not args.silent:
+ elif not silent:
print(joined_path)
if dryrun:
@@ -478,21 +522,25 @@ def extract_volume_iso(args: argparse.Namespace):
def extract_volume_hybrid(args: argparse.Namespace):
source_volume = args.src
loglevel: str = args.log
+ silent: bool = args.silent
numeric_level = getattr(logging, loglevel.upper(), None)
if not isinstance(numeric_level, int):
raise ValueError("Invalid log level: %s" % loglevel)
logging.basicConfig(format="%(levelname)s: %(message)s", level=numeric_level)
- logging.info(f"Loading {source_volume} ...")
+ if not silent:
+ logging.info(f"Loading {source_volume} ...")
main_dir = args.dir
- args.dir = main_dir.joinpath('hfs')
- extract_volume_hfs(args)
+ args_copy = copy.copy(args)
+
+ args_copy.dir = main_dir.joinpath('hfs')
+ extract_volume_hfs(args_copy)
- args.dir = main_dir.joinpath('iso9660')
- extract_volume_iso(args)
+ args_copy.dir = main_dir.joinpath('iso9660')
+ extract_volume_iso(args_copy)
def extract_partition(args: argparse.Namespace, vol) -> int:
@@ -502,6 +550,7 @@ def extract_partition(args: argparse.Namespace, vol) -> int:
dopunycode: bool = not args.nopunycode
force_macbinary: bool = args.forcemacbinary
add_macbinary_ext: bool = args.addmacbinaryext
+ silent: bool = args.silent
if not dryrun:
destination_dir.mkdir(parents=True, exist_ok=True)
@@ -529,14 +578,14 @@ def extract_partition(args: argparse.Namespace, vol) -> int:
upath /= el
- if might_be_jp and not might_be_jp_warned:
+ if might_be_jp and not might_be_jp_warned and not silent:
logging.warning(
"Possible Mac-Japanese string detected, did you mean to use --japanese?"
)
might_be_jp_warned = True
if dryrun:
- if not isinstance(obj, machfs.Folder):
+ if not isinstance(obj, machfs.Folder) and not silent:
print(upath)
continue
@@ -547,7 +596,7 @@ def extract_partition(args: argparse.Namespace, vol) -> int:
folders.append((upath, obj.mddate - 2082844800))
continue
- print(upath)
+ # print(upath)
if obj.data and not obj.rsrc and not force_macbinary:
upath.write_bytes(obj.data)
@@ -906,6 +955,11 @@ def generate_parser() -> argparse.ArgumentParser:
action="store_true",
help="always encode using MacBinary, even for files with no resource fork",
)
+ parser_iso.add_argument(
+ "--silent",
+ action="store_true",
+ help="do not print anything"
+ )
parser_iso.add_argument(
"--addmacbinaryext",
action="store_true",
@@ -926,6 +980,10 @@ def generate_parser() -> argparse.ArgumentParser:
parser_dir.add_argument("directory", metavar="directory ", type=Path, help="Path")
parser_dir.set_defaults(func=punyencode_arg)
+ parser_probe = subparsers.add_parser("probe", help="Detect file system and extension of the given ISO")
+ parser_probe.add_argument("src", metavar="INPUT", type=Path, help="Disk image")
+ parser_probe.set_defaults(func=probe_iso)
+
parser_str = subparsers.add_parser(
"str", help="Convert strings or standard in to or from punycode"
)
Commit: 15efeac0160983e562318c93b5f4ddeaf43eb5e8
https://github.com/scummvm/scummvm/commit/15efeac0160983e562318c93b5f4ddeaf43eb5e8
Author: Darkhood148 (ujjwal.sharma9999999 at gmail.com)
Date: 2024-04-25T00:28:42+02:00
Commit Message:
DEVTOOLS: COMPANION: Add enums for file systems and extensions
Changed paths:
devtools/dumper-companion.py
diff --git a/devtools/dumper-companion.py b/devtools/dumper-companion.py
index 54a82996ed5..cdc37375289 100755
--- a/devtools/dumper-companion.py
+++ b/devtools/dumper-companion.py
@@ -16,6 +16,7 @@
# Code is formatted with `black`
from __future__ import annotations
+from enum import Enum
import argparse
import copy
@@ -86,6 +87,19 @@ decode_map = {
# fmt: on
+class FileSystem(Enum):
+ hybrid = 'hybrid'
+ hfs = 'hfs'
+ iso9660 = 'iso9660'
+
+
+class Extension(Enum):
+ none = None
+ joliet = 'joliet'
+ rr = 'rr'
+ udf = 'udf'
+
+
def decode_macjapanese(text: bytes) -> str:
"""
Decode MacJapanese
@@ -291,9 +305,9 @@ def encode_string(args: argparse.Namespace) -> int:
return 0
-def probe_iso(args):
+def probe_iso(args: argparse.Namespace):
fs = check_fs(args.src)
- print('Detected file system:', fs)
+ print('Detected file system:', fs.value)
args.fs = fs
args.dryrun = True
args.dir = Path('testing')
@@ -303,17 +317,17 @@ def probe_iso(args):
args.log = 'INFO'
args.nopunycode = False
args.japanese = False
- if fs == 'hybrid' or fs == 'iso9660':
+ if fs in [FileSystem.hybrid, FileSystem.iso9660]:
args.extension = check_extension(args)
- print('Detected extension:', args.extension)
+ print('Detected extension:', args.extension.value)
print('Japanese detected:', check_japanese(args))
-def check_japanese(args):
+def check_japanese(args: argparse.Namespace):
args.japanese = False
- if args.fs == 'hybrid':
+ if args.fs == FileSystem.hybrid:
fn = extract_volume_hybrid
- elif args.fs == 'iso9660':
+ elif args.fs == FileSystem.iso9660:
fn = extract_volume_iso
else:
fn = extract_volume_hfs
@@ -331,14 +345,13 @@ def check_japanese(args):
return False
-def check_extension(args):
+def check_extension(args: argparse.Namespace):
args_copy = copy.copy(args)
args_copy.dryrun = True
- extensions = ['joliet', 'rr', 'udf']
args_copy.dir = args.dir.joinpath('test')
- args_copy.fs = 'iso9660'
+ args_copy.fs = FileSystem.iso9660
args_copy.silent = True
- for extension in extensions:
+ for extension in Extension:
args_copy.extension = extension
try:
extract_volume_iso(args_copy)
@@ -346,6 +359,7 @@ def check_extension(args):
pass
else:
return extension
+ return Extension.none
def check_fs(iso):
@@ -359,7 +373,7 @@ def check_fs(iso):
f.seek(64 * SECTOR_SIZE)
if f.read(6) == b"\x01CD001":
# print('Found ISO PVD')
- disk_formats.append("iso9660")
+ disk_formats.append(FileSystem.iso9660)
f.seek(0)
mac_1 = f.read(4)
@@ -374,7 +388,7 @@ def check_fs(iso):
f.seek(32, 1)
partition_type = f.read(32).decode("mac-roman").split("\x00")[0]
if partition_type == "Apple_HFS":
- disk_formats.append("hfs")
+ disk_formats.append(FileSystem.hfs)
break
# Check if there are more partitions
if partition_num <= num_partitions:
@@ -383,25 +397,28 @@ def check_fs(iso):
f.seek(partition_num * SECTOR_SIZE + 4)
# Bootable Mac-only disc
elif mac_1 == b"LK\x60\x00" and mac_3 == b"BD":
- disk_formats.append("hfs")
+ disk_formats.append(FileSystem.hfs)
if len(disk_formats) > 1:
- return 'hybrid'
- else:
- return disk_formats[0]
+ return FileSystem.hybrid
+ return disk_formats[0]
def extract_iso(args: argparse.Namespace):
if not args.fs:
args.fs = check_fs(args.src)
- print('Detected filesystem:', args.fs)
- if (args.fs == 'hybrid' or args.fs == 'iso9660') and not args.extension:
+ print('Detected filesystem:', args.fs.value)
+ else:
+ args.fs = FileSystem(args.fs)
+ if args.fs in [FileSystem.hybrid, FileSystem.iso9660] and not args.extension:
args.extension = check_extension(args)
- print('Detected extension:', args.extension)
+ print('Detected extension:', args.extension.value)
+ elif args.extension:
+ args.extension = Extension(args.extension)
- if args.fs == 'iso9660':
+ if args.fs == FileSystem.iso9660:
extract_volume_iso(args)
- elif args.fs == 'hfs':
+ elif args.fs == FileSystem.hfs:
extract_volume_hfs(args)
else:
extract_volume_hybrid(args)
@@ -482,11 +499,11 @@ def extract_volume_iso(args: argparse.Namespace):
output_dir = str(args.dir)
- if not args.extension:
+ if not args.extension or args.extension == Extension.none:
path_type = 'iso_path'
- elif args.extension == 'joliet':
+ elif args.extension == Extension.joliet:
path_type = 'joliet_path'
- elif args.extension == 'rr':
+ elif args.extension == Extension.rr:
path_type = 'rr_path'
else:
path_type = 'udf_path'
@@ -596,7 +613,9 @@ def extract_partition(args: argparse.Namespace, vol) -> int:
folders.append((upath, obj.mddate - 2082844800))
continue
- # print(upath)
+ if not silent:
+ print(upath)
+
if obj.data and not obj.rsrc and not force_macbinary:
upath.write_bytes(obj.data)
Commit: 2e9862863c1245eadeebc370a9602fea76319c28
https://github.com/scummvm/scummvm/commit/2e9862863c1245eadeebc370a9602fea76319c28
Author: Darkhood148 (ujjwal.sharma9999999 at gmail.com)
Date: 2024-04-25T00:28:42+02:00
Commit Message:
DEVTOOLS: COMPANION: Add version checker pycdlib module
The pycdlib module does not implement the encoding parameter that is required for decoding Japanese filenames. A PR has been made to acknowledge this issue: https://github.com/clalancette/pycdlib/pull/124 . For the time, the PR is not merged, we need a temporary pycdlib version checker. Once the pycdlib PR has been merged, this commit can be removed
Changed paths:
devtools/dumper-companion.py
diff --git a/devtools/dumper-companion.py b/devtools/dumper-companion.py
index cdc37375289..347b4493cf9 100755
--- a/devtools/dumper-companion.py
+++ b/devtools/dumper-companion.py
@@ -943,6 +943,26 @@ def create_macfonts(args: argparse.Namespace) -> int:
return 0
+def search_encoding_parameter(s: str) -> bool:
+ l = -1
+ u = -1
+ for i, line in enumerate(s.split('\n')):
+ if line.strip() == 'Parameters:':
+ l = i + 1
+ if line.strip() == 'Yields:':
+ u = i
+ break
+ parameters = [i.split('-')[0].strip() for i in s.split('\n')[l:u]]
+ return 'encoding' in parameters
+
+
+def check_pycdlib_version() -> bool:
+ iso_test = pycdlib.PyCdlib()
+ doc_walk = iso_test.walk.__doc__
+ doc_get_file_from_iso_fp = iso_test.get_file_from_iso_fp.__doc__
+ return search_encoding_parameter(doc_walk) and search_encoding_parameter(doc_get_file_from_iso_fp)
+
+
def generate_parser() -> argparse.ArgumentParser:
"""
Generate the parser
@@ -1060,6 +1080,8 @@ def generate_parser() -> argparse.ArgumentParser:
if __name__ == "__main__":
+ if not check_pycdlib_version():
+ print('WARNING: Old version of pycdlib detected. Parsing of Japanese filenames in ISO9660 may not work')
parser = generate_parser()
args = parser.parse_args()
try:
More information about the Scummvm-git-logs
mailing list