Skip to content

Commit 8cdf4bf

Browse files
committed
fix: use nc_py_api to get the Nextcloud file tree
Signed-off-by: kyteinsky <kyteinsky@gmail.com>
1 parent dfeccad commit 8cdf4bf

1 file changed

Lines changed: 51 additions & 8 deletions

File tree

ex_app/lib/all_tools/files.py

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
# SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
22
# SPDX-License-Identifier: AGPL-3.0-or-later
3+
import niquests
34
from langchain_core.tools import tool
45
from nc_py_api import AsyncNextcloudApp
5-
import niquests
6+
from nc_py_api.files.files_async import AsyncFilesAPI, FsNode
67

8+
from ex_app.lib.all_tools.lib.decorator import dangerous_tool, safe_tool
79
from ex_app.lib.all_tools.lib.files import get_file_id_from_file_url
810

9-
from ex_app.lib.all_tools.lib.decorator import safe_tool, dangerous_tool
10-
1111

1212
async def get_tools(nc: AsyncNextcloudApp):
1313

@@ -50,16 +50,59 @@ async def get_file_content_by_file_link(file_url: str):
5050

5151
return response.text
5252

53+
def __format_fs_node(fsnode: FsNode) -> dict:
54+
# todo: permissions info
55+
return {
56+
'path': fsnode.user_path,
57+
'file_id': fsnode.info.fileid,
58+
'etag': fsnode.etag.replace('"', '').replace("'", ''),
59+
'bytes': fsnode.info.size,
60+
'creation_date': fsnode.info.creation_date.isoformat(),
61+
'last_modified': fsnode.info.last_modified.isoformat(),
62+
'mimetype': fsnode.info.mimetype,
63+
'is_shared': fsnode.is_shared,
64+
'is_favourite': fsnode.info.favorite,
65+
'is_version': fsnode.info.is_version,
66+
'trash_info': {
67+
'in_trash': fsnode.info.in_trash,
68+
**({
69+
'trashbin_filename': fsnode.info.trashbin_filename,
70+
'original_location': fsnode.info.trashbin_original_location,
71+
'deletion_time': fsnode.info.trashbin_deletion_time,
72+
} if fsnode.info.in_trash else {}),
73+
},
74+
'lock_info': {
75+
'is_locked': fsnode.lock_info.is_locked,
76+
**({
77+
'owner': fsnode.lock_info.owner,
78+
'owner_display_name': fsnode.lock_info.owner_display_name,
79+
'type': fsnode.lock_info.type.name,
80+
'creation_time': fsnode.lock_info.lock_creation_time,
81+
'ttl': fsnode.lock_info.lock_ttl,
82+
'locked_by_app': fsnode.lock_info.owner_editor,
83+
} if fsnode.lock_info.is_locked else {}),
84+
},
85+
}
86+
87+
5388
@tool
5489
@safe_tool
55-
async def get_folder_tree(depth: int):
90+
async def get_file_tree(path: str = '/', include_metadata = False, depth: int = 1):
5691
"""
57-
Get the folder tree of the user (lists the files the user has in Nextcloud Files)
58-
:param depth: the depth of the returned folder tree
92+
Get the file tree of the user (lists the files the user has in Nextcloud Files)
93+
:param path: the path to enumerate. It should start directly with the folder name from at the root like /Media and NOT /userid/files/Media
94+
:param include_metadata: include the etag, file/folder id, last modified times, etc. with the file/folder paths
95+
:param depth: how many directory levels should be included in output. Default = 1 (only specified directory). Max depth = 5.
5996
:return:
6097
"""
6198

62-
return await nc.ocs('GET', '/ocs/v2.php/apps/files/api/v1/folder-tree', params={'depth': depth}, response_type='json')
99+
files_handle = AsyncFilesAPI(nc._session)
100+
fsnode_list = await files_handle.listdir(path, min(5, depth))
101+
if include_metadata:
102+
return [__format_fs_node(fsnode) for fsnode in fsnode_list]
103+
104+
return [fsnode.user_path for fsnode in fsnode_list]
105+
63106

64107
@tool
65108
@dangerous_tool
@@ -163,7 +206,7 @@ async def delete_file(path: str):
163206
return [
164207
get_file_content,
165208
get_file_content_by_file_link,
166-
get_folder_tree,
209+
get_file_tree,
167210
create_public_sharing_link,
168211
upload_file,
169212
create_folder,

0 commit comments

Comments
 (0)