Module refinery.units.formats.archive.xtiso

Expand source code Browse git
from __future__ import annotations

from refinery.lib.iso import FileSystemType, ISOArchive
from refinery.lib.types import Param
from refinery.units.formats.archive import ArchiveUnit, Arg


class xtiso(ArchiveUnit, docs='{0}{p}{PathExtractorUnit}'):
    """
    Extract files from a ISO archive.
    """
    def __init__(
        self,
        *paths, list=False, join_path=False, drop_path=False, fuzzy=0, exact=False, regex=False,
        path=b'path', date=b'date',
        fs: Param[str, Arg.Option('-s', metavar='TYPE', choices=FileSystemType, help=(
            'Specify a file system ({choices}) extension to use. The default setting {default} will automatically '
            'detect the first of the other available options and use it.'))] = 'auto'
    ):
        super().__init__(
            *paths,
            list=list,
            join_path=join_path,
            drop_path=drop_path,
            fuzzy=fuzzy,
            exact=exact,
            regex=regex,
            path=path,
            date=date,
            fs=Arg.AsOption(fs, FileSystemType),
        )

    def unpack(self, data):
        if not self.handles(data):
            self.log_warn('The data does not look like an ISO file.')
        iso = ISOArchive(data)
        if (fs := self.args.fs) != FileSystemType.AUTO:
            iso.select_filesystem(fs)
        self.log_info(F'using format: {iso.filesystem_type}')
        for entry in iso.entries():
            def extract(e=entry):
                return iso.extract(e)
            yield self._pack(entry.path, entry.date, extract)

    @classmethod
    def handles(cls, data) -> bool:
        return any(data[k] == B'CD001' for k in (
            slice(0x8001, 0x8006),
            slice(0x8801, 0x8806),
            slice(0x9001, 0x9006),
        ))

Classes

class xtiso (*paths, list=False, join_path=False, drop_path=False, fuzzy=0, exact=False, regex=False, path=b'path', date=b'date', fs='auto')

Extract files from a ISO archive.

This unit extracts items with an associated virtual path from a container. Each extracted item is emitted as a separate chunk and has attached to it a meta variable that contains its path within the container format. The positional arguments to the command are patterns that can be used to filter the extracted items by their path. To view only the paths of all chunks, use the listing switch:

emit something | xtiso --list

Otherwise, extracted items are written to the standard output port and usually require a frame to properly process. In order to dump all extracted data to disk, the following pipeline can be used:

emit something | xtiso [| dump extracted/{path} ]

The value {path} is a placeholder which is substituted by the virtual path of the extracted item. When using xtiso to unpack a file on disk, the following pattern can be useful:

ef pack.bin [| xtiso -j | d2p ]

The unit ef is also a path extractor. By specifying -j (or --join), the paths of extracted items are combined. Here, d2p is a shortcut for dump {path}. It deconflicts the joined paths with the local file system: If pack.bin contains items one.txt and two.txt, the following local file tree would be the result:

pack.bin
pack/one.txt
pack/two.txt

Finally, the -d (or --drop) switch can be used to not create (or alter) the path metadata at all, which is useful in cases where path metadata from a previous unit should be preserved.

Expand source code Browse git
class xtiso(ArchiveUnit, docs='{0}{p}{PathExtractorUnit}'):
    """
    Extract files from a ISO archive.
    """
    def __init__(
        self,
        *paths, list=False, join_path=False, drop_path=False, fuzzy=0, exact=False, regex=False,
        path=b'path', date=b'date',
        fs: Param[str, Arg.Option('-s', metavar='TYPE', choices=FileSystemType, help=(
            'Specify a file system ({choices}) extension to use. The default setting {default} will automatically '
            'detect the first of the other available options and use it.'))] = 'auto'
    ):
        super().__init__(
            *paths,
            list=list,
            join_path=join_path,
            drop_path=drop_path,
            fuzzy=fuzzy,
            exact=exact,
            regex=regex,
            path=path,
            date=date,
            fs=Arg.AsOption(fs, FileSystemType),
        )

    def unpack(self, data):
        if not self.handles(data):
            self.log_warn('The data does not look like an ISO file.')
        iso = ISOArchive(data)
        if (fs := self.args.fs) != FileSystemType.AUTO:
            iso.select_filesystem(fs)
        self.log_info(F'using format: {iso.filesystem_type}')
        for entry in iso.entries():
            def extract(e=entry):
                return iso.extract(e)
            yield self._pack(entry.path, entry.date, extract)

    @classmethod
    def handles(cls, data) -> bool:
        return any(data[k] == B'CD001' for k in (
            slice(0x8001, 0x8006),
            slice(0x8801, 0x8806),
            slice(0x9001, 0x9006),
        ))

Ancestors

Subclasses

Class variables

var reverse

The type of the None singleton.

Methods

def unpack(self, data)
Expand source code Browse git
def unpack(self, data):
    if not self.handles(data):
        self.log_warn('The data does not look like an ISO file.')
    iso = ISOArchive(data)
    if (fs := self.args.fs) != FileSystemType.AUTO:
        iso.select_filesystem(fs)
    self.log_info(F'using format: {iso.filesystem_type}')
    for entry in iso.entries():
        def extract(e=entry):
            return iso.extract(e)
        yield self._pack(entry.path, entry.date, extract)

Inherited members