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.
42 lines
1.2 KiB
Python
42 lines
1.2 KiB
Python
"""Internal helpers: mapping infra exceptions → error codes.
|
|
|
|
Kept private (``_errors``) — only the 5 use cases in this package use
|
|
it. Centralizes the exception → code translation so every use case
|
|
returns consistent error payloads.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from alfred.infrastructure.filesystem import (
|
|
CrossDevice,
|
|
DestinationExists,
|
|
FilesystemError,
|
|
FilesystemOSError,
|
|
NotADirectory,
|
|
NotAFile,
|
|
PermissionDenied,
|
|
SourceNotFound,
|
|
)
|
|
|
|
# Application-layer error codes (guard violations, not infra).
|
|
PATH_NOT_ALLOWED = "path_not_allowed"
|
|
|
|
|
|
def code_for(exc: FilesystemError) -> str:
|
|
"""Return the snake-case error code for an infra exception."""
|
|
if isinstance(exc, SourceNotFound):
|
|
return "source_not_found"
|
|
if isinstance(exc, DestinationExists):
|
|
return "destination_exists"
|
|
if isinstance(exc, NotADirectory):
|
|
return "not_a_directory"
|
|
if isinstance(exc, NotAFile):
|
|
return "not_a_file"
|
|
if isinstance(exc, PermissionDenied):
|
|
return "permission_denied"
|
|
if isinstance(exc, CrossDevice):
|
|
return "cross_device"
|
|
if isinstance(exc, FilesystemOSError):
|
|
return "filesystem_os_error"
|
|
return "filesystem_error"
|