diff --git a/doc/changelog.d/2101.fixed.md b/doc/changelog.d/2101.fixed.md new file mode 100644 index 0000000000..3fa1276d4a --- /dev/null +++ b/doc/changelog.d/2101.fixed.md @@ -0,0 +1 @@ +Change ``iterdir()`` for ``rglob('*')`` \ No newline at end of file diff --git a/src/ansys/geometry/core/modeler.py b/src/ansys/geometry/core/modeler.py index 03ce400ded..5baef934d5 100644 --- a/src/ansys/geometry/core/modeler.py +++ b/src/ansys/geometry/core/modeler.py @@ -254,6 +254,7 @@ def exit(self, close_design: bool = True) -> None: def _upload_file( self, file_path: str, + project_dir: Path, open_file: bool = False, import_options: ImportOptions = ImportOptions(), ) -> str: @@ -263,6 +264,9 @@ def _upload_file( ---------- file_path : str Path of the file to upload. The extension of the file must be included. + project_dir : Path + Root directory of the folder being uploaded. This is used to + determine the relative path of the file on the server. open_file : bool, default: False Whether to open the file in the Geometry service. import_options : ImportOptions @@ -287,7 +291,7 @@ def _upload_file( if fp_path.is_dir(): raise ValueError("File path must lead to a file, not a directory.") - file_name = fp_path.name + file_name = fp_path.relative_to(project_dir).as_posix() with fp_path.open(mode="rb") as file: data = file.read() @@ -308,6 +312,7 @@ def _upload_file( def _upload_file_stream( self, file_path: str, + project_dir: Path, open_file: bool = False, import_options: ImportOptions = ImportOptions(), ) -> str: @@ -317,6 +322,9 @@ def _upload_file_stream( ---------- file_path : str Path of the file to upload. The extension of the file must be included. + project_dir : Path + Root directory of the folder being uploaded. This is used to + determine the relative path of the file on the server. open_file : bool, default: False Whether to open the file in the Geometry service. import_options : ImportOptions @@ -344,12 +352,12 @@ def _upload_file_stream( c_stub = CommandsStub(self.client.channel) response = c_stub.StreamFileUpload( - self._generate_file_chunks(fp_path, open_file, import_options) + self._generate_file_chunks(fp_path, project_dir, open_file, import_options) ) return response.file_path def _generate_file_chunks( - self, file_path: Path, open_file: bool, import_options: ImportOptions + self, file_path: Path, project_dir: Path, open_file: bool, import_options: ImportOptions ) -> Generator[UploadFileRequest, None, None]: """Generate appropriate chunk sizes for uploading files. @@ -357,6 +365,9 @@ def _generate_file_chunks( ---------- file_path : Path Path of the file to upload. The extension of the file must be included. + project_dir : Path + Root directory of the folder being uploaded. This is used to + determine the relative path of the file on the server. open_file : bool Whether to open the file in the Geometry service. import_options : ImportOptions @@ -372,11 +383,12 @@ def _generate_file_chunks( raise ValueError("MAX_MESSAGE_LENGTH is too small for file upload.") chunk_size = pygeom_defaults.MAX_MESSAGE_LENGTH - msg_buffer + filename = file_path.relative_to(project_dir).as_posix() with Path.open(file_path, "rb") as file: while chunk := file.read(chunk_size): yield UploadFileRequest( data=chunk, - file_name=file_path.name, + file_name=filename, open=open_file, import_options=import_options.to_dict(), ) @@ -441,14 +453,16 @@ def open_file( if any( ext in str(file_path) for ext in [".CATProduct", ".asm", ".solution", ".sldasm"] ): - dir = fp_path.parent - for file in dir.iterdir(): + project_dir = fp_path.parent + for file in project_dir.rglob("*"): full_path = file.resolve() + if not full_path.is_file(): + continue if full_path != fp_path: if full_path.stat().st_size < pygeom_defaults.MAX_MESSAGE_LENGTH: - self._upload_file(full_path) + self._upload_file(full_path, project_dir) elif self.client.backend_version >= (25, 2, 0): - self._upload_file_stream(full_path) + self._upload_file_stream(full_path, project_dir) else: # pragma: no cover raise RuntimeError( "File is too large to upload." diff --git a/tests/integration/files/import/nested_cat_project/A.CATPart b/tests/integration/files/import/nested_cat_project/A.CATPart new file mode 100644 index 0000000000..f4a3eb768d Binary files /dev/null and b/tests/integration/files/import/nested_cat_project/A.CATPart differ diff --git a/tests/integration/files/import/nested_cat_project/B.CATProduct b/tests/integration/files/import/nested_cat_project/B.CATProduct new file mode 100644 index 0000000000..fc0edcdc13 Binary files /dev/null and b/tests/integration/files/import/nested_cat_project/B.CATProduct differ diff --git a/tests/integration/files/import/nested_cat_project/Base.CATPart b/tests/integration/files/import/nested_cat_project/Base.CATPart new file mode 100644 index 0000000000..75ef59905e Binary files /dev/null and b/tests/integration/files/import/nested_cat_project/Base.CATPart differ diff --git a/tests/integration/files/import/nested_cat_project/Car1.CATProduct b/tests/integration/files/import/nested_cat_project/Car1.CATProduct new file mode 100644 index 0000000000..bc022a29e6 Binary files /dev/null and b/tests/integration/files/import/nested_cat_project/Car1.CATProduct differ diff --git a/tests/integration/files/import/nested_cat_project/Wheel1.CATPart b/tests/integration/files/import/nested_cat_project/Wheel1.CATPart new file mode 100644 index 0000000000..f5b7217ddb Binary files /dev/null and b/tests/integration/files/import/nested_cat_project/Wheel1.CATPart differ diff --git a/tests/integration/files/import/nested_cat_project/car.CATProduct b/tests/integration/files/import/nested_cat_project/car.CATProduct new file mode 100644 index 0000000000..c99abb9534 Binary files /dev/null and b/tests/integration/files/import/nested_cat_project/car.CATProduct differ diff --git a/tests/integration/files/import/nested_cat_project/nested/asdf.CATPart b/tests/integration/files/import/nested_cat_project/nested/asdf.CATPart new file mode 100644 index 0000000000..63279f8f02 Binary files /dev/null and b/tests/integration/files/import/nested_cat_project/nested/asdf.CATPart differ diff --git a/tests/integration/test_design_import.py b/tests/integration/test_design_import.py index d1718ebed3..a42d155368 100644 --- a/tests/integration/test_design_import.py +++ b/tests/integration/test_design_import.py @@ -535,3 +535,10 @@ def test_design_insert_id_bug(modeler: Modeler): assert len(design1.components[0].bodies) == 1 assert len(design1.components[1].bodies) == 1 + + +def test_nested_folder_import_with_open_file(modeler: Modeler): + """Test importing a file from a nested folder structure.""" + # Open the design *just verify it can be opened without errors) + file_path = Path(IMPORT_FILES_DIR, "nested_cat_project/car.CATProduct") + modeler.open_file(file_path)