"""Utilities for accessing packaged resource files."""
from __future__ import annotations
import os
import sys
from pathlib import Path
from typing import Iterable, Iterator, List
def _is_frozen() -> bool:
"""Return True if running inside a PyInstaller bundle."""
return getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS')
[docs]
def resource_path(*relative_parts: str) -> Path:
"""Return the filesystem path for a bundled resource.
Works both in development (using importlib.resources) and when
frozen by PyInstaller (using sys._MEIPASS).
"""
if _is_frozen():
base = Path(sys._MEIPASS) / "pyvisor" / "resources"
result = base
for part in relative_parts:
result = result / part
return result
else:
from importlib import resources
traversable = resources.files(__name__)
for part in relative_parts:
traversable = traversable.joinpath(part)
return Path(traversable)
[docs]
def iter_resource_dirs(*relative_parts: str) -> Iterator[Path]:
"""Yield filesystem paths for sub-directories of a packaged resource."""
base = resource_path(*relative_parts)
for child in base.iterdir():
if child.is_dir():
yield child
[docs]
def icon_categories() -> Iterable[Path]:
"""Return all available icon category directories."""
categories: List[Path] = list(iter_resource_dirs("icons"))
categories.sort(key=lambda path: path.name)
return categories
[docs]
def icons_root() -> Path:
"""Return the root directory for bundled icons."""
return resource_path("icons")