diff --git a/backend/open_webui/models/folders.py b/backend/open_webui/models/folders.py index 273867eff1..24bb5e5af0 100644 --- a/backend/open_webui/models/folders.py +++ b/backend/open_webui/models/folders.py @@ -157,6 +157,11 @@ class FolderTable: except Exception: return None + async def get_folders_by_ids(self, ids: list[str], db: AsyncSession | None = None) -> list[FolderModel]: + async with get_async_db_context(db) as db: + result = await db.execute(select(Folder).filter(Folder.id.in_(ids)).order_by(Folder.updated_at.desc())) + return [FolderModel.model_validate(folder) for folder in result.scalars().all()] + async def get_shared_folder_ids_for_user( self, user_id: str, user_group_ids: set[str], db: Optional[AsyncSession] = None ) -> dict[str, str]: @@ -248,7 +253,9 @@ class FolderTable: self, parent_id: Optional[str], user_id: str, db: Optional[AsyncSession] = None ) -> list[FolderModel]: async with get_async_db_context(db) as db: - result = await db.execute(select(Folder).filter_by(parent_id=parent_id, user_id=user_id)) + result = await db.execute( + select(Folder).filter_by(parent_id=parent_id, user_id=user_id).order_by(Folder.updated_at.desc()) + ) return [FolderModel.model_validate(folder) for folder in result.scalars().all()] async def get_folder_ids_by_id_and_user_id_in_subtree( diff --git a/backend/open_webui/routers/folders.py b/backend/open_webui/routers/folders.py index 511d3ee002..c4ed8d0d4d 100644 --- a/backend/open_webui/routers/folders.py +++ b/backend/open_webui/routers/folders.py @@ -233,43 +233,35 @@ async def get_shared_folders( folder_perms = await Folders.get_shared_folder_ids_for_user(user.id, group_ids, db=db) - # Filter out folders owned by the user - results = [] - owner_cache = {} - for folder_id, permission in folder_perms.items(): - folder = await Folders.get_folder_by_id(folder_id, db=db) - if not folder or folder.user_id == user.id: - continue + folders = await Folders.get_folders_by_ids(list(folder_perms.keys()), db=db) + shared_folders = [folder for folder in folders if folder.user_id != user.id] - # Get owner name (cached) - if folder.user_id not in owner_cache: - owner = await Users.get_user_by_id(folder.user_id, db=db) - owner_cache[folder.user_id] = owner.name if owner else 'Unknown' + owners = await Users.get_users_by_user_ids([folder.user_id for folder in shared_folders], db=db) + owner_names = {owner.id: owner.name for owner in owners} - results.append( - { - **folder.model_dump(), - 'owner_name': owner_cache[folder.user_id], - 'permission': permission, - } - ) + results = [ + { + **folder.model_dump(), + 'owner_name': owner_names.get(folder.user_id, 'Unknown'), + 'permission': folder_perms[folder.id], + } + for folder in shared_folders + ] # Also include child folders of shared folders (inheritance) - shared_root_ids = {r['id'] for r in results} - for root_id in list(shared_root_ids): - root_folder = await Folders.get_folder_by_id(root_id, db=db) - if root_folder: - children = await Folders.get_children_folders_by_id_and_user_id(root_id, root_folder.user_id, db=db) - if children: - for child in children: - if child.id not in {r['id'] for r in results}: - results.append( - { - **child.model_dump(), - 'owner_name': owner_cache.get(child.user_id, 'Unknown'), - 'permission': folder_perms.get(root_id, 'read'), - } - ) + seen_ids = {folder.id for folder in shared_folders} + for folder in shared_folders: + children = await Folders.get_children_folders_by_id_and_user_id(folder.id, folder.user_id, db=db) + for child in children or []: + if child.id not in seen_ids: + seen_ids.add(child.id) + results.append( + { + **child.model_dump(), + 'owner_name': owner_names.get(child.user_id, 'Unknown'), + 'permission': folder_perms[folder.id], + } + ) return results