diff --git a/src/octoprint/plugin/types.py b/src/octoprint/plugin/types.py index 72954377..12e41dab 100644 --- a/src/octoprint/plugin/types.py +++ b/src/octoprint/plugin/types.py @@ -194,11 +194,12 @@ class SlicerPlugin(Plugin): def is_slicer_configured(self): return False - def get_slicer_type(self): - return None - - def get_slicer_name(self): - return None + def get_slicer_properties(self): + return dict( + type=None, + name=None, + same_device=True, + ) def get_slicer_profile_options(self): return None diff --git a/src/octoprint/plugins/cura/__init__.py b/src/octoprint/plugins/cura/__init__.py index 037a9bc3..9e963919 100644 --- a/src/octoprint/plugins/cura/__init__.py +++ b/src/octoprint/plugins/cura/__init__.py @@ -190,11 +190,12 @@ class CuraPlugin(octoprint.plugin.SlicerPlugin, cura_engine = s.get(["cura_engine"]) return cura_engine is not None and os.path.exists(cura_engine) - def get_slicer_type(self): - return "cura" - - def get_slicer_name(self): - return "CuraEngine" + def get_slicer_properties(self): + return dict( + type="cura", + name="CuraEngine", + same_device=True + ) def get_slicer_default_profile(self): path = s.get(["default_profile"]) @@ -214,7 +215,8 @@ class CuraPlugin(octoprint.plugin.SlicerPlugin, description = profile_dict["_description"] del profile_dict["_description"] - return octoprint.slicing.SlicingProfile(self.get_slicer_type(), "unknown", profile_dict, display_name=display_name, description=description) + properties = self.get_slicer_properties() + return octoprint.slicing.SlicingProfile(properties["type"], "unknown", profile_dict, display_name=display_name, description=description) def save_slicer_profile(self, path, profile, allow_overwrite=True, overrides=None): new_profile = Profile.merge_profile(profile.data, overrides=overrides) diff --git a/src/octoprint/server/api/files.py b/src/octoprint/server/api/files.py index 33b04398..6f8b78ec 100644 --- a/src/octoprint/server/api/files.py +++ b/src/octoprint/server/api/files.py @@ -301,14 +301,20 @@ def gcodeFileCommand(filename, target): del data["slicer"] if not slicer in slicingManager.registered_slicers: return make_response("Slicer {slicer} is not available".format(**locals()), 400) + slicer_instance = slicingManager.get_slicer(slicer) elif "cura" in slicingManager.registered_slicers: slicer = "cura" + slicer_instance = slicingManager.get_slicer("cura") else: return make_response("Cannot slice {filename}, no slicer available".format(**locals()), 415) if not octoprint.filemanager.valid_file_type(filename, type="stl"): return make_response("Cannot slice {filename}, not an STL file".format(**locals()), 415) + if slicer_instance.get_slicer_properties()["same_device"] and (printer.isPrinting or printer.isPaused()): + # slicer runs on same device as OctoPrint, slicing while printing is hence disabled + return make_response("Cannot slice on {slicer} while printing due to performance reasons".format(**locals()), 409) + if "gcode" in data.keys() and data["gcode"]: gcode_name = data["gcode"] del data["gcode"] @@ -317,6 +323,11 @@ def gcodeFileCommand(filename, target): name, _ = os.path.splitext(filename) gcode_name = name + ".gco" + # prohibit overwriting the file that is currently being printed + currentOrigin, currentFilename = _getCurrentFile() + if currentFilename == gcode_name and currentOrigin == target and (printer.isPrinting() or printer.isPaused()): + make_response("Trying to slice into file that is currently being printed: %s" % gcode_name, 409) + if "profile" in data.keys() and data["profile"]: profile = data["profile"] del data["profile"] @@ -359,14 +370,8 @@ def deleteGcodeFile(filename, target): if not _verifyFileExists(target, filename): return make_response("File not found on '%s': %s" % (target, filename), 404) - currentJob = printer.getCurrentJob() - currentFilename = None - currentOrigin = None - if currentJob is not None and "file" in currentJob.keys() and "name" in currentJob["file"] and "origin" in currentJob["file"]: - currentFilename = currentJob["file"]["name"] - currentOrigin = currentJob["file"]["origin"] - # prohibit deleting the file that is currently being printed + currentOrigin, currentFilename = _getCurrentFile() if currentFilename == filename and currentOrigin == target and (printer.isPrinting() or printer.isPaused()): make_response("Trying to delete file that is currently being printed: %s" % filename, 409) @@ -382,3 +387,10 @@ def deleteGcodeFile(filename, target): return NO_CONTENT +def _getCurrentFile(): + currentJob = printer.getCurrentJob() + if currentJob is not None and "file" in currentJob.keys() and "name" in currentJob["file"] and "origin" in currentJob["file"]: + return currentJob["file"]["origin"], currentJob["file"]["name"] + else: + return None, None + diff --git a/src/octoprint/server/api/slicing.py b/src/octoprint/server/api/slicing.py index 90dc9fd7..6d03ced3 100644 --- a/src/octoprint/server/api/slicing.py +++ b/src/octoprint/server/api/slicing.py @@ -22,7 +22,7 @@ def slicingListAll(): for slicer in slicingManager.registered_slicers: result[slicer] = dict( key=slicer, - displayName=slicingManager.get_slicer(slicer).get_slicer_name(), + displayName=slicingManager.get_slicer(slicer).get_slicer_properties()["name"], default=default_slicer == slicer, profiles=_getSlicingProfilesData(slicer) ) diff --git a/src/octoprint/slicing/__init__.py b/src/octoprint/slicing/__init__.py index 3421e4e6..66e56021 100644 --- a/src/octoprint/slicing/__init__.py +++ b/src/octoprint/slicing/__init__.py @@ -69,7 +69,7 @@ class SlicingManager(object): plugins = octoprint.plugin.plugin_manager().get_implementations(octoprint.plugin.SlicerPlugin) for name, plugin in plugins.items(): if plugin.is_slicer_configured(): - self._slicers[plugin.get_slicer_type()] = plugin + self._slicers[plugin.get_slicer_properties()["type"]] = plugin @property def slicing_enabled(self): @@ -106,7 +106,7 @@ class SlicingManager(object): def slicer_worker(slicer, model_path, machinecode_path, profile_name, overrides, callback, callback_args, callback_kwargs): try: - slicer_name = slicer.get_slicer_type() + slicer_name = slicer.get_slicer_properties()["type"] with self.temporary_profile(slicer_name, name=profile_name, overrides=overrides) as profile_path: ok, result = slicer.do_slice( model_path, diff --git a/src/octoprint/static/js/app/viewmodels/files.js b/src/octoprint/static/js/app/viewmodels/files.js index 9b8de430..130f5260 100644 --- a/src/octoprint/static/js/app/viewmodels/files.js +++ b/src/octoprint/static/js/app/viewmodels/files.js @@ -261,6 +261,10 @@ function GcodeFilesViewModel(printerStateViewModel, loginStateViewModel, slicing return isLoadActionPossible && !self.listHelper.isSelected(data); }; + self.enableSlicing = function(data) { + return self.loginState.isUser() && !(self.isPrinting() || self.isPaused()); + }; + self.enableAdditionalData = function(data) { return data["gcodeAnalysis"] || data["prints"] && data["prints"]["last"]; }; diff --git a/src/octoprint/templates/index.jinja2 b/src/octoprint/templates/index.jinja2 index 53e2c090..cdf9e7cc 100644 --- a/src/octoprint/templates/index.jinja2 +++ b/src/octoprint/templates/index.jinja2 @@ -237,7 +237,7 @@