Skip to content

Commit b575267

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 b575267

1 file changed

Lines changed: 53 additions & 8 deletions

File tree

ex_app/lib/all_tools/files.py

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
# SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
22
# SPDX-License-Identifier: AGPL-3.0-or-later
3+
from functools import lru_cache
4+
5+
import niquests
36
from langchain_core.tools import tool
47
from nc_py_api import AsyncNextcloudApp
5-
import niquests
8+
from nc_py_api.files.files_async import AsyncFilesAPI, FsNode
69

10+
from ex_app.lib.all_tools.lib.decorator import dangerous_tool, safe_tool
711
from ex_app.lib.all_tools.lib.files import get_file_id_from_file_url
812

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

1214
async def get_tools(nc: AsyncNextcloudApp):
1315

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

5153
return response.text
5254

55+
def __format_fs_node(fsnode: FsNode) -> dict:
56+
# todo: permissions info
57+
return {
58+
'path': fsnode.user_path,
59+
'file_id': fsnode.info.fileid,
60+
'etag': fsnode.etag.replace('"', '').replace("'", ''),
61+
'bytes': fsnode.info.size,
62+
'creation_date': fsnode.info.creation_date.isoformat(),
63+
'last_modified': fsnode.info.last_modified.isoformat(),
64+
'mimetype': fsnode.info.mimetype,
65+
'is_shared': fsnode.is_shared,
66+
'is_favourite': fsnode.info.favorite,
67+
'is_version': fsnode.info.is_version,
68+
'trash_info': {
69+
'in_trash': fsnode.info.in_trash,
70+
**({
71+
'trashbin_filename': fsnode.info.trashbin_filename,
72+
'original_location': fsnode.info.trashbin_original_location,
73+
'deletion_time': fsnode.info.trashbin_deletion_time,
74+
} if fsnode.info.in_trash else {}),
75+
},
76+
'lock_info': {
77+
'is_locked': fsnode.lock_info.is_locked,
78+
**({
79+
'owner': fsnode.lock_info.owner,
80+
'owner_display_name': fsnode.lock_info.owner_display_name,
81+
'type': fsnode.lock_info.type.name,
82+
'creation_time': fsnode.lock_info.lock_creation_time,
83+
'ttl': fsnode.lock_info.lock_ttl,
84+
'locked_by_app': fsnode.lock_info.owner_editor,
85+
} if fsnode.lock_info.is_locked else {}),
86+
},
87+
}
88+
89+
5390
@tool
5491
@safe_tool
55-
async def get_folder_tree(depth: int):
92+
async def get_file_tree(path: str = '/', include_metadata = False, depth: int = 1):
5693
"""
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
94+
Get the file tree of the user (lists the files the user has in Nextcloud Files)
95+
: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
96+
:param include_metadata: include the etag, file/folder id, last modified times, etc. with the file/folder paths
97+
:param depth: how many directory levels should be included in output. Default = 1 (only specified directory). Max depth = 5.
5998
:return:
6099
"""
61100

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

64109
@tool
65110
@dangerous_tool
@@ -163,7 +208,7 @@ async def delete_file(path: str):
163208
return [
164209
get_file_content,
165210
get_file_content_by_file_link,
166-
get_folder_tree,
211+
get_file_tree,
167212
create_public_sharing_link,
168213
upload_file,
169214
create_folder,

0 commit comments

Comments
 (0)