mirror of
https://github.com/euzu/tuliprox.git
synced 2026-09-24 01:52:17 +02:00
Playback could not find any recording. Two independent path computations existed and disagreed: writer RecordingTask::new -> <root>[/<subdir>]/<filename> reader resolve_for_open -> <root>/users/<owner>/<filename> resolve_recording_dir invented a users/<owner>/ or shared/ prefix that nothing ever wrote, and relative_path stored only the bare filename while the organised subdirectory lived in file_dir. Nothing covered the round trip, so the mismatch survived. recording_path.rs is now the only layout. It is pure, and deliberately owner-independent: one physical file is shared by every user who requested it, so keying its directory on an owner is wrong the moment a second user attaches and would force the file to move when the first detaches. resolve_recording_dir and its RecordingVisibility are deleted rather than left as a second answer. relative_path is now root-relative and carries the full layout, so the writer's path and the reader's resolution are the same expression. Series recordings gain the Season NN level they were documented to have but never produced. Component sanitisation is one function with a table test: separators, control characters and the Windows-forbidden set collapse to _, leading and trailing dots are stripped so a name cannot be hidden or silently aliased, Windows device names fall back to a placeholder, and components are capped at 255 bytes on a character boundary so a multi-byte title truncates to valid UTF-8 rather than to a split character. A property test asserts that no input the builder accepts can produce a path the containment check rejects. Collision suffixes now apply to the file component only, so reserving a name no longer flattens the directory it belongs to.