OpenGeodeWeb-Back 6.13.0rc2__tar.gz → 6.13.0rc4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/PKG-INFO +1 -1
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/pyproject.toml +1 -1
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/OpenGeodeWeb_Back.egg-info/PKG-INFO +1 -1
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/blueprint_routes.py +75 -31
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/tests/test_routes.py +100 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/LICENSE +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/README.md +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/requirements.txt +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/setup.cfg +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/OpenGeodeWeb_Back.egg-info/SOURCES.txt +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/OpenGeodeWeb_Back.egg-info/dependency_links.txt +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/OpenGeodeWeb_Back.egg-info/entry_points.txt +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/OpenGeodeWeb_Back.egg-info/requires.txt +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/OpenGeodeWeb_Back.egg-info/top_level.txt +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/__init__.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/app.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/app_config.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_functions.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/__init__.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_brep.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_cross_section.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_edged_curve2d.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_edged_curve3d.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_graph.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_grid2d.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_grid3d.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_hybrid_solid3d.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_implicit_cross_section.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_implicit_structural_model.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_light_regular_grid2d.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_light_regular_grid3d.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_mesh.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_model.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_object.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_point_set2d.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_point_set3d.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_polygonal_surface2d.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_polygonal_surface3d.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_polyhedral_solid3d.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_raster_image2d.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_raster_image3d.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_regular_grid2d.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_regular_grid3d.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_section.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_solid_mesh3d.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_structural_model.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_surface_mesh2d.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_surface_mesh3d.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_tetrahedral_solid3d.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_triangulated_surface2d.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_triangulated_surface3d.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_objects/geode_vertex_set.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/py.typed +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/create/blueprint_create.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/create/schemas/__init__.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/create/schemas/edged_curve.json +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/create/schemas/edged_curve.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/create/schemas/point_set.json +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/create/schemas/point_set.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/create/schemas/polygonal_surface.json +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/create/schemas/polygonal_surface.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/__init__.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/allowed_files.json +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/allowed_files.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/allowed_objects.json +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/allowed_objects.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/cell_attribute_names.json +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/cell_attribute_names.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/edge_attribute_names.json +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/edge_attribute_names.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/export_project.json +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/export_project.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/geode_object_inheritance.json +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/geode_object_inheritance.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/geode_objects_and_output_extensions.json +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/geode_objects_and_output_extensions.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/geographic_coordinate_systems.json +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/geographic_coordinate_systems.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/import_project.json +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/import_project.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/kill.json +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/kill.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/missing_files.json +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/missing_files.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/model_component_edge_attribute_names.json +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/model_component_edge_attribute_names.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/model_component_polygon_attribute_names.json +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/model_component_polygon_attribute_names.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/model_component_polyhedron_attribute_names.json +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/model_component_polyhedron_attribute_names.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/model_component_vertex_attribute_names.json +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/model_component_vertex_attribute_names.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/ping.json +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/ping.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/polygon_attribute_names.json +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/polygon_attribute_names.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/polyhedron_attribute_names.json +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/polyhedron_attribute_names.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/save_viewable_file.json +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/save_viewable_file.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/texture_coordinates.json +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/texture_coordinates.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/upload_file.json +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/upload_file.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/validate.json +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/validate.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/vertex_attribute_names.json +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/routes/schemas/vertex_attribute_names.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/test_utils.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/utils_functions.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/tests/test_create_routes.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/tests/test_geode_functions.py +0 -0
- {opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/tests/test_utils_functions.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: OpenGeodeWeb-Back
|
|
3
|
-
Version: 6.13.
|
|
3
|
+
Version: 6.13.0rc4
|
|
4
4
|
Summary: OpenGeodeWeb-Back is an open source framework that proposes handy python functions and wrappers for the OpenGeode ecosystem
|
|
5
5
|
Author-email: Geode-solutions <team-web@geode-solutions.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/Geode-solutions/OpenGeodeWeb-Back
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "OpenGeodeWeb-Back"
|
|
7
|
-
version = "6.13.0-rc.
|
|
7
|
+
version = "6.13.0-rc.4"
|
|
8
8
|
dynamic = ["dependencies"]
|
|
9
9
|
authors = [{ name = "Geode-solutions", email = "team-web@geode-solutions.com" }]
|
|
10
10
|
description = "OpenGeodeWeb-Back is an open source framework that proposes handy python functions and wrappers for the OpenGeode ecosystem"
|
{opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/OpenGeodeWeb_Back.egg-info/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: OpenGeodeWeb-Back
|
|
3
|
-
Version: 6.13.
|
|
3
|
+
Version: 6.13.0rc4
|
|
4
4
|
Summary: OpenGeodeWeb-Back is an open source framework that proposes handy python functions and wrappers for the OpenGeode ecosystem
|
|
5
5
|
Author-email: Geode-solutions <team-web@geode-solutions.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/Geode-solutions/OpenGeodeWeb-Back
|
|
@@ -4,6 +4,7 @@ import os
|
|
|
4
4
|
import time
|
|
5
5
|
import shutil
|
|
6
6
|
import math
|
|
7
|
+
import typing
|
|
7
8
|
from threading import Timer
|
|
8
9
|
|
|
9
10
|
# Third party imports
|
|
@@ -63,6 +64,18 @@ def allowed_files() -> flask.Response:
|
|
|
63
64
|
return flask.make_response({"extensions": list(extensions)}, 200)
|
|
64
65
|
|
|
65
66
|
|
|
67
|
+
def _write_stream(path: str, stream: typing.IO[bytes], mode: str = "wb") -> None:
|
|
68
|
+
read_buffer_size = 1024 * 1024
|
|
69
|
+
with open(path, mode) as destination:
|
|
70
|
+
while chunk := stream.read(read_buffer_size):
|
|
71
|
+
destination.write(chunk)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _finalize_upload(filename: str) -> flask.Response:
|
|
75
|
+
print(f"{filename=}", flush=True)
|
|
76
|
+
return flask.make_response({"message": "File uploaded"}, 201)
|
|
77
|
+
|
|
78
|
+
|
|
66
79
|
@routes.route(
|
|
67
80
|
schemas_dict["upload_file"]["route"],
|
|
68
81
|
methods=schemas_dict["upload_file"]["methods"],
|
|
@@ -73,8 +86,12 @@ def upload_file() -> flask.Response:
|
|
|
73
86
|
if not os.path.exists(UPLOAD_FOLDER_PATH):
|
|
74
87
|
os.makedirs(UPLOAD_FOLDER_PATH, exist_ok=True)
|
|
75
88
|
|
|
76
|
-
# Multipart callers (e.g. Vease) still send the file as a "file" form
|
|
77
|
-
#
|
|
89
|
+
# Multipart callers (e.g. Vease) still send the whole file as a "file" form
|
|
90
|
+
# part. Everything else PUTs raw bytes with ?filename= as a query param:
|
|
91
|
+
# either the whole file in one request, or one of several chunks (when
|
|
92
|
+
# ?chunk_index=/?total_chunks= are also present) that get appended in
|
|
93
|
+
# order and assembled into the final file once the last one arrives. This
|
|
94
|
+
# keeps every request under cloud hosting's hard request-size limit.
|
|
78
95
|
if flask.request.mimetype == "multipart/form-data":
|
|
79
96
|
file = flask.request.files["file"]
|
|
80
97
|
if file.filename is None:
|
|
@@ -82,22 +99,30 @@ def upload_file() -> flask.Response:
|
|
|
82
99
|
filename = werkzeug.utils.secure_filename(os.path.basename(file.filename))
|
|
83
100
|
file_path = os.path.join(UPLOAD_FOLDER_PATH, filename)
|
|
84
101
|
file.save(file_path)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
102
|
+
return _finalize_upload(filename)
|
|
103
|
+
|
|
104
|
+
raw_filename = flask.request.args.get("filename")
|
|
105
|
+
if not raw_filename:
|
|
106
|
+
flask.abort(400, "Filename is required")
|
|
107
|
+
filename = werkzeug.utils.secure_filename(os.path.basename(raw_filename))
|
|
108
|
+
file_path = os.path.join(UPLOAD_FOLDER_PATH, filename)
|
|
109
|
+
|
|
110
|
+
total_chunks = flask.request.args.get("total_chunks", type=int)
|
|
111
|
+
if total_chunks is None:
|
|
112
|
+
_write_stream(file_path, flask.request.stream)
|
|
113
|
+
return _finalize_upload(filename)
|
|
114
|
+
|
|
115
|
+
chunk_index = flask.request.args.get("chunk_index", type=int)
|
|
116
|
+
if chunk_index is None or not 0 <= chunk_index < total_chunks:
|
|
117
|
+
flask.abort(400, "Invalid chunk_index")
|
|
118
|
+
|
|
119
|
+
part_path = f"{file_path}.part"
|
|
120
|
+
_write_stream(part_path, flask.request.stream, "wb" if chunk_index == 0 else "ab")
|
|
121
|
+
if chunk_index < total_chunks - 1:
|
|
122
|
+
return flask.make_response({"message": "Chunk received"}, 200)
|
|
123
|
+
|
|
124
|
+
os.replace(part_path, file_path)
|
|
125
|
+
return _finalize_upload(filename)
|
|
101
126
|
|
|
102
127
|
|
|
103
128
|
@routes.route(
|
|
@@ -270,23 +295,42 @@ def extract_valid_attribute_values(
|
|
|
270
295
|
attribute_name: str,
|
|
271
296
|
item_index: int,
|
|
272
297
|
) -> tuple[list[float], bool]:
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
)
|
|
276
|
-
if not isinstance(attribute_ids_matching_name, list):
|
|
298
|
+
attribute_ids = attribute_manager.attribute_ids_matching_name(attribute_name)
|
|
299
|
+
if not isinstance(attribute_ids, list):
|
|
277
300
|
return [], False
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
301
|
+
attribute = attribute_manager.find_generic_attribute(attribute_ids[0])
|
|
302
|
+
if (
|
|
303
|
+
attribute is None
|
|
304
|
+
or not attribute.is_genericable()
|
|
305
|
+
or not attribute.properties().transferable
|
|
306
|
+
):
|
|
284
307
|
return [], False
|
|
308
|
+
|
|
309
|
+
nb_items = attribute.nb_items()
|
|
310
|
+
default_values = getattr(attribute, "default_values", None)
|
|
311
|
+
no_value = default_values().no_value if default_values else None
|
|
312
|
+
if no_value is None and (
|
|
313
|
+
"Point" in attribute.type() or "Vector" in attribute.type()
|
|
314
|
+
):
|
|
315
|
+
no_value = [0.0] * nb_items
|
|
316
|
+
|
|
317
|
+
value_getter = getattr(
|
|
318
|
+
attribute,
|
|
319
|
+
"value",
|
|
320
|
+
lambda element_index: [
|
|
321
|
+
attribute.generic_item_value(element_index, i) for i in range(nb_items)
|
|
322
|
+
],
|
|
323
|
+
)
|
|
324
|
+
|
|
285
325
|
valid_values: list[float] = []
|
|
286
326
|
has_nan = False
|
|
287
327
|
for element_index in range(attribute_manager.nb_elements()):
|
|
288
|
-
value =
|
|
289
|
-
if
|
|
328
|
+
value = attribute.generic_item_value(element_index, item_index)
|
|
329
|
+
if (
|
|
330
|
+
value is None
|
|
331
|
+
or math.isnan(value)
|
|
332
|
+
or (no_value is not None and value_getter(element_index) == no_value)
|
|
333
|
+
):
|
|
290
334
|
has_nan = True
|
|
291
335
|
else:
|
|
292
336
|
valid_values.append(value)
|
|
@@ -306,7 +350,7 @@ def attributes_metadata(
|
|
|
306
350
|
attribute_name = attribute.name()
|
|
307
351
|
if attribute_name is None:
|
|
308
352
|
continue
|
|
309
|
-
if not attribute.is_genericable():
|
|
353
|
+
if not attribute.is_genericable() or not attribute.properties().transferable:
|
|
310
354
|
continue
|
|
311
355
|
nb_items = attribute.nb_items()
|
|
312
356
|
min_values, max_values = [], []
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import os
|
|
3
3
|
|
|
4
4
|
# Third party imports
|
|
5
|
+
import opengeode as og
|
|
5
6
|
from werkzeug.datastructures import FileStorage
|
|
6
7
|
from flask.testing import FlaskClient
|
|
7
8
|
from werkzeug.test import TestResponse
|
|
@@ -13,6 +14,7 @@ import zipfile
|
|
|
13
14
|
from opengeodeweb_microservice.database.data import Data
|
|
14
15
|
from opengeodeweb_microservice.database.connection import get_session
|
|
15
16
|
from opengeodeweb_back import geode_functions, test_utils
|
|
17
|
+
from opengeodeweb_back.routes.blueprint_routes import extract_valid_attribute_values
|
|
16
18
|
from opengeodeweb_back.geode_objects.geode_polygonal_surface3d import (
|
|
17
19
|
GeodePolygonalSurface3D,
|
|
18
20
|
)
|
|
@@ -109,6 +111,60 @@ def test_upload_file_raw_missing_filename(client: FlaskClient) -> None:
|
|
|
109
111
|
assert response.status_code == 400
|
|
110
112
|
|
|
111
113
|
|
|
114
|
+
def test_upload_file_chunked(
|
|
115
|
+
client: FlaskClient, filename: str = "test.og_brep"
|
|
116
|
+
) -> None:
|
|
117
|
+
file = os.path.join(data_dir, filename)
|
|
118
|
+
with open(file, "rb") as opened_file:
|
|
119
|
+
file_bytes = opened_file.read()
|
|
120
|
+
|
|
121
|
+
chunk_filename = "chunked_upload_test.og_brep"
|
|
122
|
+
chunk_size = max(1, len(file_bytes) // 3)
|
|
123
|
+
chunks = [
|
|
124
|
+
file_bytes[index : index + chunk_size]
|
|
125
|
+
for index in range(0, len(file_bytes), chunk_size)
|
|
126
|
+
]
|
|
127
|
+
total_chunks = len(chunks)
|
|
128
|
+
|
|
129
|
+
uploaded_path = os.path.join(data_dir, chunk_filename)
|
|
130
|
+
try:
|
|
131
|
+
for chunk_index, chunk in enumerate(chunks):
|
|
132
|
+
response = client.put(
|
|
133
|
+
f"/opengeodeweb_back/upload_file"
|
|
134
|
+
f"?filename={chunk_filename}"
|
|
135
|
+
f"&chunk_index={chunk_index}"
|
|
136
|
+
f"&total_chunks={total_chunks}",
|
|
137
|
+
data=chunk,
|
|
138
|
+
content_type="application/octet-stream",
|
|
139
|
+
)
|
|
140
|
+
if chunk_index < total_chunks - 1:
|
|
141
|
+
assert response.status_code == 200
|
|
142
|
+
assert not os.path.exists(uploaded_path)
|
|
143
|
+
else:
|
|
144
|
+
assert response.status_code == 201
|
|
145
|
+
|
|
146
|
+
with open(uploaded_path, "rb") as uploaded_file:
|
|
147
|
+
assert uploaded_file.read() == file_bytes
|
|
148
|
+
finally:
|
|
149
|
+
if os.path.exists(uploaded_path):
|
|
150
|
+
os.remove(uploaded_path)
|
|
151
|
+
part_path = f"{uploaded_path}.part"
|
|
152
|
+
if os.path.exists(part_path):
|
|
153
|
+
os.remove(part_path)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def test_upload_file_chunked_invalid_chunk_index(client: FlaskClient) -> None:
|
|
157
|
+
response = client.put(
|
|
158
|
+
"/opengeodeweb_back/upload_file"
|
|
159
|
+
"?filename=invalid_chunk_index.og_brep"
|
|
160
|
+
"&chunk_index=2"
|
|
161
|
+
"&total_chunks=2",
|
|
162
|
+
data=b"some raw bytes",
|
|
163
|
+
content_type="application/octet-stream",
|
|
164
|
+
)
|
|
165
|
+
assert response.status_code == 400
|
|
166
|
+
|
|
167
|
+
|
|
112
168
|
def test_missing_files(client: FlaskClient) -> None:
|
|
113
169
|
route = f"/opengeodeweb_back/missing_files"
|
|
114
170
|
|
|
@@ -777,3 +833,47 @@ def test_model_component_polyhedron_attribute_names(client: FlaskClient) -> None
|
|
|
777
833
|
return {"id": model_id, "component_ids": block_ids}
|
|
778
834
|
|
|
779
835
|
test_utils.test_route_wrong_params(client, route, get_full_data)
|
|
836
|
+
|
|
837
|
+
|
|
838
|
+
def test_extract_valid_attribute_values_with_sentinel_no_value() -> None:
|
|
839
|
+
mesh = og.TriangulatedSurface3D.create()
|
|
840
|
+
builder = og.TriangulatedSurfaceBuilder3D.create(mesh)
|
|
841
|
+
vertex_0 = builder.create_point(og.Point3D([0, 0, 0]))
|
|
842
|
+
vertex_1 = builder.create_point(og.Point3D([1, 0, 0]))
|
|
843
|
+
builder.create_triangle([vertex_0, vertex_1, vertex_0])
|
|
844
|
+
|
|
845
|
+
attribute_manager = mesh.vertex_attribute_manager()
|
|
846
|
+
values_config = og.AttributeValuesDouble()
|
|
847
|
+
values_config.no_value = -999.0
|
|
848
|
+
attribute_id = attribute_manager.create_attribute_variable_double(
|
|
849
|
+
"variable_double", values_config, og.AttributeProperties()
|
|
850
|
+
)
|
|
851
|
+
attribute = attribute_manager.find_attribute_variable_double(attribute_id)
|
|
852
|
+
attribute.set_value(vertex_0, -999.0)
|
|
853
|
+
attribute.set_value(vertex_1, 42.0)
|
|
854
|
+
|
|
855
|
+
valid_values, has_nan = extract_valid_attribute_values(
|
|
856
|
+
attribute_manager, "variable_double", 0
|
|
857
|
+
)
|
|
858
|
+
assert has_nan is True
|
|
859
|
+
assert valid_values == [42.0]
|
|
860
|
+
|
|
861
|
+
|
|
862
|
+
def test_extract_valid_attribute_values_with_non_transferable_attribute() -> None:
|
|
863
|
+
mesh = og.TriangulatedSurface3D.create()
|
|
864
|
+
builder = og.TriangulatedSurfaceBuilder3D.create(mesh)
|
|
865
|
+
vertex_0 = builder.create_point(og.Point3D([0, 0, 0]))
|
|
866
|
+
builder.create_triangle([vertex_0, vertex_0, vertex_0])
|
|
867
|
+
|
|
868
|
+
attribute_manager = mesh.vertex_attribute_manager()
|
|
869
|
+
properties = og.AttributeProperties()
|
|
870
|
+
properties.transferable = False
|
|
871
|
+
attribute_manager.create_attribute_variable_double(
|
|
872
|
+
"internal_attribute", og.AttributeValuesDouble(), properties
|
|
873
|
+
)
|
|
874
|
+
|
|
875
|
+
valid_values, has_nan = extract_valid_attribute_values(
|
|
876
|
+
attribute_manager, "internal_attribute", 0
|
|
877
|
+
)
|
|
878
|
+
assert has_nan is False
|
|
879
|
+
assert valid_values == []
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/app_config.py
RENAMED
|
File without changes
|
{opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/geode_functions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/test_utils.py
RENAMED
|
File without changes
|
{opengeodeweb_back-6.13.0rc2 → opengeodeweb_back-6.13.0rc4}/src/opengeodeweb_back/utils_functions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|