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:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user