2df7843d8b
Replaces the monolithic FileManager class + scattered helpers in
alfred/infrastructure/filesystem with five free functions, each
single-responsibility and pathlib-native:
list_dir / create_dir / link_file / move_file / move_dir
The infra layer now raises typed exceptions (FilesystemError base
+ SourceNotFound / DestinationExists / NotADirectory / NotAFile /
PermissionDenied / CrossDevice / FilesystemOSError) instead of
returning {status: ok|error} dicts. No more get_memory() reads
from infra.
Application layer mirrors the same split: five free use cases
(<op>_use_case) wrap each infra op, guard inputs against escaping
the new DirectoryRoots VO (downloads / torrents / movies /
tv_shows), catch infra exceptions, and return frozen DTOs. Roots
are injected — no global state.
Legacy files kept on disk with _OLD suffix for reference during
the follow-up rewiring (FileManager, MediaOrganizer,
create_folder/move helpers; CreateSeedLinks/ListFolder/MoveMedia/
ManageSubtitles use cases, resolve_destination). They are no
longer exported from __init__, which intentionally breaks current
agent tool wrappers and downstream tests — re-wiring is the next
chunk of work on the unfuck branch.
41 lines
1.2 KiB
Python
41 lines
1.2 KiB
Python
"""list_dir — return the immediate children of a directory."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import errno
|
|
from pathlib import Path
|
|
|
|
from .exceptions import (
|
|
FilesystemOSError,
|
|
NotADirectory,
|
|
PermissionDenied,
|
|
SourceNotFound,
|
|
)
|
|
|
|
|
|
def list_dir(path: Path) -> list[Path]:
|
|
"""Return the immediate children of ``path``, sorted by name.
|
|
|
|
Returns absolute :class:`~pathlib.Path` objects for both files and
|
|
directories. Does not recurse.
|
|
|
|
Raises:
|
|
SourceNotFound: ``path`` does not exist.
|
|
NotADirectory: ``path`` exists but is not a directory.
|
|
PermissionDenied: the directory is not readable.
|
|
FilesystemOSError: any other ``OSError`` from ``iterdir``.
|
|
"""
|
|
if not path.exists():
|
|
raise SourceNotFound(path)
|
|
if not path.is_dir():
|
|
raise NotADirectory(path)
|
|
|
|
try:
|
|
return sorted(path.iterdir())
|
|
except PermissionError as e:
|
|
raise PermissionDenied(path, action="list_dir") from e
|
|
except OSError as e:
|
|
if e.errno == errno.EACCES:
|
|
raise PermissionDenied(path, action="list_dir") from e
|
|
raise FilesystemOSError("list_dir", path, e) from e
|