def _perform_save_action() -> None: """Saves current pipeline of elements to a user specified JSON file Launches a file dialog box that allows the user to specifiy a JSON file, attempts to encode the element pipeline, and if successful writes out the decoded element pipelin in JSON format to file. config.cvt_elem_to_dict() does most of the hard work, by extracting class and parameter data from the element that allows the element to be JSON encoded and reinstantiated later when the filed is read back in by _perform_load_action(). """ global _pipeline_model # TODO: _element_list is supposed to be private - use data() instead? element_list = _pipeline_model._element_list if element_list: options = QtWidgets.QFileDialog.Options() options |= QtWidgets.QFileDialog.DontUseNativeDialog file_name, _filter = QtWidgets.QFileDialog.getSaveFileName( config.get_main_window(), caption='Save File', filter='JSON (*.json)', options=options) if file_name: if not file_name.lower().endswith('.json'): file_name = file_name + '.json' elem_dict_list = [config.cvt_elem_to_dict(element) for element in element_list] with open(file_name, 'w') as json_file: json.dump(elem_dict_list, json_file)
def test_cvt_methods(self): """Test the methods used to enable JSON coding/decoding. Before JSON encoding, a SpikeElement is converted into a data-based dictionary representation using cvt_elem_to_dict(). After JSON decoding, the resultant dictionary is re-instantiated as a SpikeElement using cvt_dict_to_elem(). This test runs through both conversions back-to-back and compares the resultant SpikeElement with the original SpikeElement to ensure identity. """ cls_list = RecordingExtractor.get_installed_spif_cls_list() elem = RecordingExtractor(cls_list[random.randint( 0, len(cls_list) - 1)]) elem_dict = config.cvt_elem_to_dict(elem) new_elem = config.cvt_dict_to_elem(elem_dict) print(f'SpikeElement tested: {elem.display_name}') assert elem.__class__.__name__ == new_elem.__class__.__name__ assert elem.__module__ == new_elem.__module__ assert elem.spif_class.__name__ == new_elem.spif_class.__name__ assert elem.param_list == new_elem.param_list
def run(self): # Called in response to user pressing Run button in UI missing_param_count = self._missing_param_count() if missing_param_count: QtWidgets.QMessageBox.warning( config.get_main_window(), 'Run Failure', f'Missing mandatory element parameters. Missing parameter ' f'count: {missing_param_count}') return for cls in self._element_policy.required_cls_list: if not self._elem_cls_count(cls): QtWidgets.QMessageBox.warning( config.get_main_window(), 'Run Failure', f'Missing required element: {cls.__name__}') return config.get_main_window().statusBar().showMessage( 'Running pipeline', config.STATUS_MSG_TIMEOUT) elem_jdict_list = [ config.cvt_elem_to_dict(element) for element in self._element_list ] elem_list_str = json.dumps(elem_jdict_list) # TODO: Add plumbing for shared output support if self.share_output: run_path = pkg_resources.resource_filename('spikely.pipeman', 'piperun.py') else: run_path = pkg_resources.resource_filename('spikely.pipeman', 'pipeman.py') run_process = QtCore.QProcess(self) success = run_process.startDetached('python', [f'{run_path}', elem_list_str]) if not success: QtWidgets.QMessageBox.warning( config.get_main_window(), 'Failed to Start Python Process', f'Command line: python {run_path}, elem_list_str')
def test_cvt_elem_raises(self): """cvt_elem_to_dict() shoule raise exception on invalid parameter""" with pytest.raises(TypeError): config.cvt_elem_to_dict('not a SpikeElement')