fix: admin scan skips other users' source root directories

When the admin's source root is the mount root (/photos) and other
users have subdirectories (/photos/bob), the admin's scan now prunes
those directories from os.walk so photos aren't double-indexed under
the wrong user. The scanner queries all active source roots owned by
other users and excludes their paths during directory traversal.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-13 00:04:21 +02:00
parent fbeefb24a0
commit 180efb3eb0

View File

@@ -164,11 +164,28 @@ async def _scan_folder_async(folder_path: str, source_root_id: Optional[str], ta
hidden_folder_cache[folder_row.id] = False
return False
# Build a set of paths owned by OTHER users' source roots so
# the admin's scan of /photos doesn't descend into /photos/bob.
other_root_paths: set[str] = set()
if owner_user_id:
other_roots = (await session.execute(
select(SourceRoot.path)
.where(SourceRoot.is_active == True) # noqa: E712
.where(SourceRoot.user_id != owner_user_id)
)).scalars().all()
other_root_paths = {os.path.normpath(p) for p in other_roots}
def _should_skip_dir(dirpath: str) -> bool:
"""True if dirpath is another user's source root."""
return os.path.normpath(dirpath) in other_root_paths
# Pre-walk to compute the total file count upfront. Without this
# the progress bar would jump every time a new subfolder is
# encountered because the running total kept growing.
total_files = 0
for _root, _dirs, files in os.walk(folder_path):
# Prune other users' directories from count
_dirs[:] = [d for d in _dirs if not _should_skip_dir(os.path.join(_root, d))]
total_files += sum(
1 for f in files if Path(f).suffix.lower() in SUPPORTED_EXTENSIONS
)
@@ -179,6 +196,9 @@ async def _scan_folder_async(folder_path: str, source_root_id: Optional[str], ta
errors = []
for root, dirs, files in os.walk(folder_path):
# Skip directories that belong to other users' source roots
dirs[:] = [d for d in dirs if not _should_skip_dir(os.path.join(root, d))]
# Get or create folder entry
folder = await get_or_create_folder(session, root, source_root_id, owner_user_id)
progress_set(REDIS_KEY_CURRENT_FOLDER, root)