Skip to content

Commit 4948a2b

Browse files
Refactor iRODS file source listing methods for improved maintenance
1 parent fde714f commit 4948a2b

1 file changed

Lines changed: 42 additions & 36 deletions

File tree

lib/galaxy/files/sources/irods.py

Lines changed: 42 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,45 @@ class IrodsFilesSource(PyFilesystem2FilesSource[IrodsFileSourceTemplateConfigura
8181
template_config_class = IrodsFileSourceTemplateConfiguration
8282
resolved_config_class = IrodsFileSourceConfiguration
8383

84-
def _normalize_listdir_name(self, value: str) -> str:
85-
# fs-irods currently returns absolute iRODS paths from listdir; convert to simple entry names.
86-
return os.path.basename(str(value).rstrip("/"))
84+
def _iter_directory_entries(self, fs_handle, parent_path: str, normalized_query: Optional[str] = None):
85+
for raw_name in fs_handle.listdir(parent_path):
86+
name = os.path.basename(str(raw_name).rstrip("/"))
87+
if not name:
88+
continue
89+
if normalized_query and not fnmatch(name.lower(), f"*{normalized_query}*"):
90+
continue
91+
entry_path = fs.path.join(parent_path, name)
92+
info = fs_handle.getinfo(entry_path, namespaces=["details"])
93+
yield entry_path, info
94+
95+
def _list_recursive(self, fs_handle, path: str) -> tuple[list[AnyRemoteEntry], int]:
96+
result: list[AnyRemoteEntry] = []
97+
pending = [path]
98+
while pending:
99+
current_path = pending.pop(0)
100+
for entry_path, info in self._iter_directory_entries(fs_handle, current_path):
101+
result.append(self._resource_info_to_dict(current_path, info))
102+
if info.is_dir:
103+
pending.append(entry_path)
104+
return result, len(result)
105+
106+
def _list_non_recursive(
107+
self,
108+
fs_handle,
109+
path: str,
110+
limit: Optional[int] = None,
111+
offset: Optional[int] = None,
112+
query: Optional[str] = None,
113+
) -> tuple[list[AnyRemoteEntry], int]:
114+
normalized_query = query.lower() if query else None
115+
entries = []
116+
for _, info in self._iter_directory_entries(fs_handle, path, normalized_query):
117+
entries.append(self._resource_info_to_dict(path, info))
118+
count = len(entries)
119+
page = self._to_page(limit, offset)
120+
if page is not None:
121+
entries = entries[page[0] : page[1]]
122+
return entries, count
87123

88124
def _list(
89125
self,
@@ -97,40 +133,10 @@ def _list(
97133
sort_by: Optional[str] = None,
98134
) -> tuple[list[AnyRemoteEntry], int]:
99135
try:
100-
with self._open_fs(context) as h:
136+
with self._open_fs(context) as fs_handle:
101137
if recursive:
102-
result: list[AnyRemoteEntry] = []
103-
pending = [path]
104-
while pending:
105-
current_path = pending.pop(0)
106-
for raw_name in h.listdir(current_path):
107-
name = self._normalize_listdir_name(raw_name)
108-
if not name:
109-
continue
110-
entry_path = fs.path.join(current_path, name)
111-
info = h.getinfo(entry_path, namespaces=["details"])
112-
result.append(self._resource_info_to_dict(current_path, info))
113-
if info.is_dir:
114-
pending.append(entry_path)
115-
return result, len(result)
116-
117-
normalized_query = query.lower() if query else None
118-
entries = []
119-
for raw_name in h.listdir(path):
120-
name = self._normalize_listdir_name(raw_name)
121-
if not name:
122-
continue
123-
if normalized_query and not fnmatch(name.lower(), f"*{normalized_query}*"):
124-
continue
125-
entry_path = fs.path.join(path, name)
126-
info = h.getinfo(entry_path, namespaces=["details"])
127-
entries.append(self._resource_info_to_dict(path, info))
128-
129-
count = len(entries)
130-
page = self._to_page(limit, offset)
131-
if page is not None:
132-
entries = entries[page[0] : page[1]]
133-
return entries, count
138+
return self._list_recursive(fs_handle, path)
139+
return self._list_non_recursive(fs_handle, path, limit, offset, query)
134140
except fs.errors.PermissionDenied as e:
135141
raise AuthenticationRequired(
136142
f"Permission Denied. Reason: {e}. Please check your credentials in your preferences for {self.label}."

0 commit comments

Comments
 (0)