Журнал выполненных операций
Каждый apply записывает JSON-манифест того, что действительно произошло — это единственный источник данных для отмены.
Каждый успешный вызов apply оставляет след — файл-манифест
в формате JSON, который описывает, что именно было сделано. Без этого журнала команда
undo, о которой пойдёт речь на следующей странице, не знала бы,
что именно нужно отменить.
{
"operation_id": "20260824T011640800152",
"root": "/home/anna/Downloads",
"timestamp": "2026-08-24T01:16:40",
"moves": [
{
"source": "/home/anna/Downloads/otchet.pdf",
"destination": "/home/anna/Downloads/Sorted/documents/otchet.pdf",
"completed": true,
"error": null
}
]
}
Путь до манифеста — не случайный: он предсказуемо строится из корня и идентификатора операции, а сам идентификатор — временна́я метка, отформатированная так, чтобы лексикографический порядок совпадал с хронологическим:
def new_operation_id() -> str:
return datetime.now().strftime("%Y%m%dT%H%M%S%f")
def history_dir(root: Path) -> Path:
return Path(root) / STATE_DIRNAME / "history"
20260824T011640800152 сортируется как текст точно в том же порядке, в каком операции происходили по времени. Это позволяет функции find_latest_manifest() находить последнюю операцию простой сортировкой имён файлов, не читая содержимое каждого манифеста.Модели Path внутри программы нужно превратить в обычные
строки, чтобы записать их в JSON — формат, у которого нет типа «путь». Это единственное
место в SafeSort, где происходит такое преобразование в обе стороны.