Files
cd-browser/src/app/filesystem.py

74 lines
1.7 KiB
Python

from __future__ import annotations
from dataclasses import dataclass
from pathlib import Path
@dataclass(frozen=True, slots=True)
class DirectoryEntry:
"""Directory metadata used by the navigator layer."""
name: str
path: Path
has_children: bool
def list_directories(path: Path, show_hidden: bool = False) -> list[DirectoryEntry]:
"""Return direct child directories sorted by name."""
directory_path = path.expanduser().resolve()
entries: list[DirectoryEntry] = []
try:
children = list(directory_path.iterdir())
except PermissionError:
return []
for child in children:
try:
is_directory = child.is_dir()
except OSError:
continue
if not is_directory:
continue
if not show_hidden and child.name.startswith("."):
continue
entries.append(
DirectoryEntry(
name=child.name,
path=child,
has_children=has_subdirectories(child, show_hidden=show_hidden),
)
)
return sorted(entries, key=lambda entry: entry.name.casefold())
def has_subdirectories(path: Path, show_hidden: bool = False) -> bool:
"""Return whether the directory contains at least one subdirectory."""
directory_path = path.expanduser().resolve()
try:
children = list(directory_path.iterdir())
except PermissionError:
return False
for child in children:
try:
is_directory = child.is_dir()
except OSError:
continue
if not is_directory:
continue
if not show_hidden and child.name.startswith("."):
continue
return True
return False