CM93 MySQL importer validated baseline
This commit is contained in:
59
src/cm93db/scanner.py
Normal file
59
src/cm93db/scanner.py
Normal file
@@ -0,0 +1,59 @@
|
||||
from __future__ import annotations
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import Iterable
|
||||
|
||||
SCALE_NATIVE = {
|
||||
"Z": 20_000_000,
|
||||
"A": 3_000_000,
|
||||
"B": 1_000_000,
|
||||
"C": 200_000,
|
||||
"D": 100_000,
|
||||
"E": 50_000,
|
||||
"F": 20_000,
|
||||
"G": 7_500,
|
||||
}
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class CellFile:
|
||||
path: Path
|
||||
relative_path: Path
|
||||
scale_code: str
|
||||
native_scale: int
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ScanResult:
|
||||
root: Path
|
||||
cells: tuple[CellFile, ...]
|
||||
object_dictionary: Path | None
|
||||
attribute_dictionary: Path | None
|
||||
|
||||
def _find_case_insensitive(root: Path, names: set[str]) -> Path | None:
|
||||
lowers = {n.lower() for n in names}
|
||||
for p in root.rglob("*"):
|
||||
if p.is_file() and p.name.lower() in lowers:
|
||||
return p
|
||||
return None
|
||||
|
||||
def scan_cm93(root: Path) -> ScanResult:
|
||||
root = root.resolve()
|
||||
if not root.exists():
|
||||
raise FileNotFoundError(root)
|
||||
cells = []
|
||||
for p in root.rglob("*"):
|
||||
if not p.is_file():
|
||||
continue
|
||||
ext = p.suffix.upper().lstrip(".")
|
||||
if ext in SCALE_NATIVE:
|
||||
cells.append(
|
||||
CellFile(
|
||||
path=p,
|
||||
relative_path=p.relative_to(root),
|
||||
scale_code=ext,
|
||||
native_scale=SCALE_NATIVE[ext],
|
||||
)
|
||||
)
|
||||
cells.sort(key=lambda c: (c.scale_code, str(c.relative_path).lower()))
|
||||
obj = _find_case_insensitive(root, {"CM93OBJ.DIC"})
|
||||
attr = _find_case_insensitive(root, {"ATTRLUT.DIC", "CM93ATTR.DIC"})
|
||||
return ScanResult(root, tuple(cells), obj, attr)
|
||||
Reference in New Issue
Block a user