diff --git a/cq_server/exporter.py b/cq_server/exporter.py index 24adefb..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 @@ -165,3 +166,19 @@ 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: + '''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] + # 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) + # 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 b125281..67b673e 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) -> Tuple[str, str]: + return self.modules_dir, self.module_name + + def set_module(self, modules_dir: str, module_name: str) -> None: + 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..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 +from flask import Flask, request, render_template, make_response, Response, send_file, abort from .module_manager import ModuleManager @@ -46,6 +46,26 @@ def _html() -> str: exporter = Exporter(module_manager) return exporter.get_html(ui_options) + @app.route('/download', methods = [ 'GET' ]) + def _download() -> Response: + '''Export specified module in the requested format and send it to the requester''' + module = request.args.get("m") + 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) + 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(500) + + @app.route('/json', methods = [ 'GET' ]) def _json() -> Tuple[str, int]: if module_manager.target_is_dir: