From b69e5ad9151a82e1fd6c5e6ce34f91a87d72125c Mon Sep 17 00:00:00 2001 From: qwelyt Date: Wed, 5 Oct 2022 21:22:13 +0200 Subject: [PATCH 1/2] Add endpoint for download You can now download your models using the endpoint /download. You need to specify the parametres `m` for wich module and `format` for wich format you want it in. --- cq_server/exporter.py | 12 ++++++++++++ cq_server/module_manager.py | 7 +++++++ cq_server/server.py | 17 ++++++++++++++++- 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/cq_server/exporter.py b/cq_server/exporter.py index 24adefb..99d86c5 100644 --- a/cq_server/exporter.py +++ b/cq_server/exporter.py @@ -165,3 +165,15 @@ def build_website(self, destination: str, ui_options: dict, minify=False): self.save_to(op.join(js_path, f'{ module_name }.js'), 'js') self.save_to(op.join(png_path, f'{ module_name }.png'), 'png') self.save_to(op.join(stl_path, f'{ module_name }.stl'), 'stl') + + def export(self, module: str, file_format: str) -> str: + mm = self.module_manager.get_module() + self.module_manager.set_module(mm[0], module) + name = module.split(".")[0] + tmpdir = tempfile.mkdtemp() + file = name+"."+file_format + destination = op.join(tmpdir, file) + self._save(destination, file_format) + self.module_manager.set_module(mm[0], mm[1]) + return destination + diff --git a/cq_server/module_manager.py b/cq_server/module_manager.py index b125281..a517c89 100644 --- a/cq_server/module_manager.py +++ b/cq_server/module_manager.py @@ -41,6 +41,13 @@ def init(self) -> None: sys.path.insert(1, self.modules_dir) self.available_modules = self.get_available_modules() + def get_module(self) -> (str,str): + return (self.modules_dir, self.module_name) + + def set_module(self, modules_dir: str, module_name: str): + self.modules_dir = modules_dir + self.module_name = module_name + def get_available_modules(self) -> Dict[str, str]: '''Returns a dictionary of available modules as module name: module path''' diff --git a/cq_server/server.py b/cq_server/server.py index 1e930fb..95a7d4c 100644 --- a/cq_server/server.py +++ b/cq_server/server.py @@ -7,7 +7,7 @@ import os.path as op from typing import Tuple -from flask import Flask, request, render_template, make_response, Response +from flask import Flask, request, render_template, make_response, Response, send_file from .module_manager import ModuleManager @@ -46,6 +46,19 @@ def _html() -> str: exporter = Exporter(module_manager) return exporter.get_html(ui_options) + @app.route('/download', methods = [ 'GET' ]) + def _download(): + module = request.args.get("m") + file_format = request.args.get("format") + from .exporter import Exporter + exporter = Exporter(module_manager) + exported_file = exporter.export(module, file_format) + try: + return send_file(exported_file, as_attachment=True) + except FileNotFoundError: + abort(404) + + @app.route('/json', methods = [ 'GET' ]) def _json() -> Tuple[str, int]: if module_manager.target_is_dir: @@ -68,6 +81,8 @@ def stream(): response.headers['Expires'] = 0 return response + + def watchdog() -> None: while True: last_updated_file = module_manager.get_last_updated_file() From 9f166dad7a7e6fc3e17a23bd1aae010381b44434 Mon Sep 17 00:00:00 2001 From: qwelyt Date: Thu, 6 Oct 2022 13:12:17 +0200 Subject: [PATCH 2/2] Make more pretty Some cleanup and stuff --- cq_server/exporter.py | 19 ++++++++++++------- cq_server/module_manager.py | 6 +++--- cq_server/server.py | 19 ++++++++++++------- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/cq_server/exporter.py b/cq_server/exporter.py index 99d86c5..8743bba 100644 --- a/cq_server/exporter.py +++ b/cq_server/exporter.py @@ -32,6 +32,7 @@ class Exporter: '''Class used to export the target in many formats.''' + valid_export_formats = ['step', 'xml', 'gltf', 'vtkjs', 'vrml', 'dxf', 'svg', 'stl', 'amf', 'tjs', 'vtp', '3mf', 'png' , 'pdf'] def __init__(self, module_manager: ModuleManager): self.module_manager = module_manager @@ -167,13 +168,17 @@ def build_website(self, destination: str, ui_options: dict, minify=False): self.save_to(op.join(stl_path, f'{ module_name }.stl'), 'stl') def export(self, module: str, file_format: str) -> str: - mm = self.module_manager.get_module() - self.module_manager.set_module(mm[0], module) + '''Export module with given format + Resets to whatever module was selected before exporting this module + ''' + old_module = self.module_manager.get_module() + # Set new module so we can export it + self.module_manager.set_module(old_module[0], module) + name = module.split(".")[0] - tmpdir = tempfile.mkdtemp() - file = name+"."+file_format - destination = op.join(tmpdir, file) + # Make the export to a tmp-dir so it can be cleaned up later + destination = op.join(tempfile.mkdtemp(), f'{ name }.{ file_format}') self._save(destination, file_format) - self.module_manager.set_module(mm[0], mm[1]) + # Reset to the old module + self.module_manager.set_module(old_module[0], old_module[1]) return destination - diff --git a/cq_server/module_manager.py b/cq_server/module_manager.py index a517c89..67b673e 100644 --- a/cq_server/module_manager.py +++ b/cq_server/module_manager.py @@ -41,10 +41,10 @@ def init(self) -> None: sys.path.insert(1, self.modules_dir) self.available_modules = self.get_available_modules() - def get_module(self) -> (str,str): - return (self.modules_dir, self.module_name) + def get_module(self) -> Tuple[str, str]: + return self.modules_dir, self.module_name - def set_module(self, modules_dir: str, module_name: str): + def set_module(self, modules_dir: str, module_name: str) -> None: self.modules_dir = modules_dir self.module_name = module_name diff --git a/cq_server/server.py b/cq_server/server.py index 95a7d4c..89bc3a6 100644 --- a/cq_server/server.py +++ b/cq_server/server.py @@ -7,7 +7,7 @@ import os.path as op from typing import Tuple -from flask import Flask, request, render_template, make_response, Response, send_file +from flask import Flask, request, render_template, make_response, Response, send_file, abort from .module_manager import ModuleManager @@ -47,16 +47,23 @@ def _html() -> str: return exporter.get_html(ui_options) @app.route('/download', methods = [ 'GET' ]) - def _download(): + def _download() -> Response: + '''Export specified module in the requested format and send it to the requester''' module = request.args.get("m") - file_format = request.args.get("format") + if module is None or module not in module_manager.get_available_modules().keys(): + abort(Response("Module not found", 400)) + from .exporter import Exporter exporter = Exporter(module_manager) - exported_file = exporter.export(module, file_format) + file_format = request.args.get("format") + if file_format is None or file_format not in exporter.valid_export_formats: + abort(Response("File format not supported", 400)) + try: + exported_file = exporter.export(module, file_format) return send_file(exported_file, as_attachment=True) except FileNotFoundError: - abort(404) + abort(500) @app.route('/json', methods = [ 'GET' ]) @@ -81,8 +88,6 @@ def stream(): response.headers['Expires'] = 0 return response - - def watchdog() -> None: while True: last_updated_file = module_manager.get_last_updated_file()