refactor: remove legacy single-root APIs, defer filesystem I/O, enforce POSIX paths

- Remove legacy endpoints: /api/change-folder, /api/index, /api/scan, /api/status,
  /api/playback/resume-positions
- Remove legacy global scanner module-level API from hivescan/scanner.py
- Defer all filesystem validation to background task in server lifespan (macOS-safe)
- CLI and winmain pass raw paths via MEDIAHIVE_ROOTS; no pre-startup validation
- Enforce POSIX paths everywhere (as_posix(), no backslash leakage)
- Remove MEDIAHIVE_PATH and MEDIAHIVE_DEFER_INITIAL_ROOT env vars
- Update frontend api.ts to use per-root resume positions
- Update docs/API.md and docs/multi-index-plan.md
- Fix Python 2 style except clauses in hivescan/utils.py and scanning.py
This commit is contained in:
2026-05-23 22:21:35 +00:00
parent 2f83193ff4
commit 9c75fa4569
25 changed files with 1963 additions and 1150 deletions
+4 -4
View File
@@ -113,7 +113,7 @@
>
<img
v-if="castMember.profile_path && !castMember.profile_path.startsWith('/')"
:src="getCoverUrl(castMember.profile_path)"
:src="getCoverUrl(castMember.profile_path, item.root_id)"
:alt="castMember.name"
class="cast-photo"
>
@@ -341,7 +341,7 @@ watch(collageSlots, async (slots) => {
}, { immediate: true });
function getShowreelUrl(path: string): string {
return getVideoPreviewUrl(getCoverUrl(path));
return getVideoPreviewUrl(getCoverUrl(path, props.item.root_id));
}
function getShowreelSourceAttributes(path: string): VideoSourceAttributes {
@@ -359,7 +359,7 @@ const backdropStyle = computed(() => {
if (props.item.type !== 'movies') return {};
const movie = props.item.data as Movie;
const imagePath = movie.backdrop_path;
const imageUrl = getCoverUrl(imagePath);
const imageUrl = getCoverUrl(imagePath, props.item.root_id);
if (imageUrl) {
return { backgroundImage: `url("${imageUrl}")` };
}
@@ -368,7 +368,7 @@ const backdropStyle = computed(() => {
const synopsisPosterUrl = computed(() => {
if (props.item.type !== 'movies') return null;
return getCoverUrl(props.item.cover_path);
return getCoverUrl(props.item.cover_path, props.item.root_id);
});
const movieGenres = computed(() => {