Skip to content

Commit 5e1af36

Browse files
committed
feat(handlers): add supported platforms tag to handlers
Handler and DirectoryHandler can now indicate the specific platforms they do support through the SUPPORTED_PLATFORMS field. This field is a set of Platform objects, an enum with values corresponding to the currently supported platforms by unblob (Linux, OSX). With this addition, a handler such as partclone that uses an extractor that is unavailable on OSX can indicate that it only supports Linux. When starting, unblob will only load handlers that are supported by the platform its currently being executed on. This is done by filtering them in BUILTIN_HANDLERS and BUILTIN_DIR_HANDLERS.
1 parent e87d7f1 commit 5e1af36

File tree

3 files changed

+40
-3
lines changed

3 files changed

+40
-3
lines changed

python/unblob/handlers/__init__.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
)
5353
from .filesystem.android import erofs, sparse
5454

55-
BUILTIN_HANDLERS: Handlers = (
55+
ALL_HANDLERS: Handlers = (
5656
cramfs.CramFSHandler,
5757
extfs.EXTHandler,
5858
fat.FATHandler,
@@ -122,8 +122,14 @@
122122
erofs.EROFSHandler,
123123
partclone.PartcloneHandler,
124124
)
125+
BUILTIN_HANDLERS: Handlers = tuple(
126+
handler for handler in ALL_HANDLERS if handler.is_supported_here()
127+
)
125128

126-
BUILTIN_DIR_HANDLERS: DirectoryHandlers = (
129+
ALL_DIR_HANDLERS: DirectoryHandlers = (
127130
sevenzip.MultiVolumeSevenZipHandler,
128131
gzip.MultiVolumeGzipHandler,
129132
)
133+
BUILTIN_DIR_HANDLERS: DirectoryHandlers = tuple(
134+
handler for handler in ALL_DIR_HANDLERS if handler.is_supported_here()
135+
)

python/unblob/handlers/archive/partclone.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from unblob.extractors import Command
77
from unblob.file_utils import File, InvalidInputFormat, get_endian
8-
from unblob.models import Regex, StructHandler, ValidChunk
8+
from unblob.models import Platform, Regex, StructHandler, ValidChunk
99

1010
C_DEFINITIONS = r"""
1111
typedef struct partclone_header{
@@ -51,6 +51,7 @@ class PartcloneHandler(StructHandler):
5151
"-L",
5252
"/dev/stdout",
5353
)
54+
SUPPORTED_PLATFORMS = {Platform.LINUX}
5455

5556
def is_valid_header(self, header) -> bool:
5657
calculated_crc = binascii.crc32(header.dumps()[0:-4])

python/unblob/models.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import abc
2+
import enum
23
import itertools
34
import json
5+
import sys
46
from collections.abc import Iterable
57
from enum import Enum
8+
from functools import lru_cache
69
from pathlib import Path
710
from typing import Generic, Optional, TypeVar, Union
811

@@ -30,6 +33,19 @@
3033
#
3134

3235

36+
class Platform(enum.Enum):
37+
LINUX = "linux"
38+
MACOS = "darwin"
39+
40+
41+
@lru_cache
42+
def current_platform() -> Platform:
43+
try:
44+
return Platform(sys.platform)
45+
except KeyError:
46+
raise ValueError(f"Unsupported platform: {sys.platform}") from None
47+
48+
3349
@attrs.define(frozen=True)
3450
class Task:
3551
path: Path
@@ -417,13 +433,20 @@ class DirectoryHandler(abc.ABC):
417433

418434
PATTERN: DirectoryPattern
419435

436+
SUPPORTED_PLATFORMS: set[Platform] = {Platform.LINUX, Platform.MACOS}
437+
420438
@classmethod
421439
def get_dependencies(cls):
422440
"""Return external command dependencies needed for this handler to work."""
423441
if cls.EXTRACTOR:
424442
return cls.EXTRACTOR.get_dependencies()
425443
return []
426444

445+
@classmethod
446+
def is_supported_here(cls) -> bool:
447+
"""Check if the current platform is supported by this handler."""
448+
return current_platform() in cls.SUPPORTED_PLATFORMS
449+
427450
@abc.abstractmethod
428451
def calculate_multifile(self, file: Path) -> Optional[MultiFile]:
429452
"""Calculate the MultiFile in a directory, using a file matched by the pattern as a starting point."""
@@ -453,13 +476,20 @@ class Handler(abc.ABC, Generic[TExtractor]):
453476

454477
EXTRACTOR: TExtractor
455478

479+
SUPPORTED_PLATFORMS: set[Platform] = {Platform.LINUX, Platform.MACOS}
480+
456481
@classmethod
457482
def get_dependencies(cls):
458483
"""Return external command dependencies needed for this handler to work."""
459484
if cls.EXTRACTOR is not None:
460485
return cls.EXTRACTOR.get_dependencies()
461486
return []
462487

488+
@classmethod
489+
def is_supported_here(cls) -> bool:
490+
"""Check if the current platform is supported by this handler."""
491+
return current_platform() in cls.SUPPORTED_PLATFORMS
492+
463493
@abc.abstractmethod
464494
def calculate_chunk(self, file: File, start_offset: int) -> Optional[ValidChunk]:
465495
"""Calculate the Chunk offsets from the File and the file type headers."""

0 commit comments

Comments
 (0)