mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-10 19:47:12 +01:00
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (mypy, mypy) (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (pylint, pylint) (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (rest, ) (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (shellcheck, shellcheck) (push) Waiting to run
Python tests / test (push) Waiting to run
Shell tests / shell-tests (push) Waiting to run
Shell tests / lib-tests (push) Waiting to run
Shell tests / arch-tests (push) Waiting to run
Kept videos land in ~/data/cloud/Media/<year>/wsg (~/Downloads without the cloud folder); trash/ keeps only the newest 200 passes and marks the rest purged. Legacy keep/ is migrated once. Undo follows a keep through every place it can end up. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F8G3BNETGmbr6aM5cc18g4
81 lines
2.4 KiB
Python
81 lines
2.4 KiB
Python
"""The only code in this package that moves bytes around on disk.
|
|
|
|
Deliberately tiny, because everything interesting about a verdict was already
|
|
decided in :mod:`python_pkg.wsg_grabber.verdict`. The one ``unlink`` lives
|
|
here too, so that "what touches the disk" stays a one-module question; only
|
|
:mod:`python_pkg.wsg_grabber._prune` and the keep migration call it.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import TYPE_CHECKING
|
|
|
|
from python_pkg.wsg_grabber import logs
|
|
|
|
if TYPE_CHECKING:
|
|
from pathlib import Path
|
|
|
|
from python_pkg.wsg_grabber.models import FileMove
|
|
|
|
|
|
def existing_names(directory: Path) -> set[str]:
|
|
"""Return the filenames already present in *directory*.
|
|
|
|
Args:
|
|
directory: Directory to inspect; need not exist.
|
|
|
|
Returns:
|
|
set[str]: Names currently in the directory.
|
|
"""
|
|
if not directory.is_dir():
|
|
return set()
|
|
return {entry.name for entry in directory.iterdir()}
|
|
|
|
|
|
def apply_move(move: FileMove) -> bool:
|
|
"""Carry out a planned relocation.
|
|
|
|
Refuses to overwrite an existing destination. ``Path.replace`` clobbers
|
|
silently, so without this check a caller that forgot to pick a
|
|
collision-free name would destroy a video the user had already decided to
|
|
keep -- exactly the thing this package promises never to do. Callers pick
|
|
the name with :func:`verdict.unique_destination`; this is the backstop that
|
|
makes the guarantee structural rather than a convention.
|
|
|
|
Args:
|
|
move: Where the file is and where it should go.
|
|
|
|
Returns:
|
|
bool: True when the file was moved. False when the source had already
|
|
vanished, or when the destination is occupied -- the caller treats
|
|
either as "this file is not where I thought", never as success.
|
|
"""
|
|
if not move.src.exists():
|
|
return False
|
|
if move.dst.exists():
|
|
logs.error(
|
|
"files.destination_occupied",
|
|
src=str(move.src),
|
|
dst=str(move.dst),
|
|
)
|
|
return False
|
|
move.dst.parent.mkdir(parents=True, exist_ok=True)
|
|
move.src.replace(move.dst)
|
|
return True
|
|
|
|
|
|
def remove(path: Path) -> bool:
|
|
"""Delete a file for good.
|
|
|
|
Args:
|
|
path: File to delete.
|
|
|
|
Returns:
|
|
bool: True when a file was removed; False when nothing was there.
|
|
"""
|
|
try:
|
|
path.unlink()
|
|
except FileNotFoundError:
|
|
return False
|
|
return True
|