diff --git a/src/opengeodeweb_back/routes/blueprint_routes.py b/src/opengeodeweb_back/routes/blueprint_routes.py index 4654d0d9..0c56be1a 100644 --- a/src/opengeodeweb_back/routes/blueprint_routes.py +++ b/src/opengeodeweb_back/routes/blueprint_routes.py @@ -7,6 +7,7 @@ import flask_cors from .. import geode_functions import werkzeug +import uuid routes = flask.Blueprint("routes", __name__) @@ -204,3 +205,57 @@ def geode_objects_and_output_extensions(): {"geode_objects_and_output_extensions": geode_objects_and_output_extensions}, 200, ) + + +with open( + os.path.join(schemas, "save_viewable_file.json"), + "r", +) as file: + save_viewable_file_json = json.load(file) + + +@routes.route( + save_viewable_file_json["route"], + methods=save_viewable_file_json["methods"], +) +def save_viewable_file(): + UPLOAD_FOLDER = flask.current_app.config["UPLOAD_FOLDER"] + geode_functions.validate_request(flask.request, save_viewable_file_json) + + secure_filename = werkzeug.utils.secure_filename(flask.request.json["filename"]) + file_path = os.path.abspath(os.path.join(UPLOAD_FOLDER, secure_filename)) + data = geode_functions.load(flask.request.json["input_geode_object"], file_path) + generated_id = str(uuid.uuid4()).replace("-", "") + + if geode_functions.is_viewable(flask.request.json["input_geode_object"]): + name = data.name() + else: + name = flask.request.json["filename"] + + native_extension = data.native_extension() + + absolute_native_file_path = os.path.join( + UPLOAD_FOLDER, generated_id + "." + native_extension + ) + + saved_viewable_file_path = geode_functions.save_viewable( + flask.request.json["input_geode_object"], data, UPLOAD_FOLDER, generated_id + ) + geode_functions.save( + flask.request.json["input_geode_object"], + data, + UPLOAD_FOLDER, + generated_id + "." + native_extension, + ) + + native_file_name = os.path.basename(absolute_native_file_path) + viewable_file_name = os.path.basename(saved_viewable_file_path) + return flask.make_response( + { + "name": name, + "native_file_name": native_file_name, + "viewable_file_name": viewable_file_name, + "id": generated_id, + }, + 200, + ) diff --git a/src/opengeodeweb_back/routes/schemas/save_viewable_file.json b/src/opengeodeweb_back/routes/schemas/save_viewable_file.json new file mode 100644 index 00000000..d77136b7 --- /dev/null +++ b/src/opengeodeweb_back/routes/schemas/save_viewable_file.json @@ -0,0 +1,20 @@ +{ + "route": "/save_viewable_file", + "methods": [ + "POST" + ], + "type": "object", + "properties": { + "input_geode_object": { + "type": "string" + }, + "filename": { + "type": "string" + } + }, + "required": [ + "input_geode_object", + "filename" + ], + "additionalProperties": false +} \ No newline at end of file diff --git a/tests/test_routes.py b/tests/test_routes.py index 86df062b..0661f025 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -155,3 +155,33 @@ def get_full_data(): assert ( error_message == "Validation error: 'input_geode_object' is a required property" ) + + +def test_save_viewable_file(client): + route = f"/save_viewable_file" + + def get_full_data(): + return { + "input_geode_object": "BRep", + "filename": "corbi.og_brep", + } + + # Normal test with filename 'corbi.og_brep' + response = client.post(route, json=get_full_data()) + assert response.status_code == 200 + name = response.json["name"] + assert type(name) is str + native_file_name = response.json["native_file_name"] + assert type(native_file_name) is str + viewable_file_name = response.json["viewable_file_name"] + assert type(viewable_file_name) is str + id = response.json["id"] + assert type(id) is str + + for key, value in get_full_data().items(): + json = get_full_data() + json.pop(key) + response = client.post(route, json=json) + assert response.status_code == 400 + error_description = response.json["description"] + assert error_description == f"Validation error: '{key}' is a required property"