def _test_writable_dir(self, path): """ Ensures the given path is writable, or raises a :class:`myokit.ExportError` if it can't be used. """ if os.path.exists(path): if not os.path.isdir(path): raise myokit.ExportError( 'Can\'t create output directory. A file exists at the' ' specified location: ' + path) elif path != '' and not os.path.isdir(path): os.makedirs(path)
def _test_writable_dir(self, path): """ Tests if the given path is writable, if not, errors are logged and a :class:`myokit.ExportError` is raised. """ self.log('Storing data in: ' + path) if os.path.exists(path): if not os.path.isdir(path): msg = 'Can\'t create output directory. A file exists at the' \ ' specified location ' + path self.log_flair('An error occurred.') self.log(msg) raise myokit.ExportError(msg, self) else: self.log('Using existing directory ' + path) else: if path != '' and not os.path.isdir(path): self.log('Creating directory structure ' + path) os.makedirs(path)
def runnable(self, path, model, protocol=None, *args): """ Exports a :class:`myokit.Model` and optionally a :class:`myokit.Protocol` to something that can be run or compiled. The output will be stored in the **directory** ``path``. """ path = os.path.abspath(os.path.expanduser(path)) path = myokit.format_path(path) self._test_writable_dir(path) # Clone the model, allowing changes to be made during export model = model.clone() model.validate() # Ensure we have a protocol if protocol is None: protocol = myokit.default_protocol() # Build and check template path tpl_dir = self._dir(DIR_FORMATS) if not os.path.exists(tpl_dir): msg = 'Template directory not found: ' + tpl_dir self.log_flair('An error occurred.') self.log(msg) raise myokit.ExportError(msg, self) if not os.path.isdir(tpl_dir): msg = 'Template path is not a directory:' + tpl_dir self.log_flair('An error occurred.') self.log(msg) raise Myokit.ExportError(msg, self) # Render all templates tpl_vars = self._vars(model, protocol, *args) for tpl_name, out_name in self._dict().iteritems(): # Create any dirs embedded in output file path file_dir = os.path.split(out_name)[0] if file_dir: file_dir = os.path.join(path, file_dir) if os.path.exists(file_dir): if not os.path.isdir(file_dir): msg = 'Failed to create directory at: ' msg += myokit.format_path(file_dir) msg += ' A file or link with that name already exists.' self.log_flair('An error occurred.') self.log(msg) raise myokit.ExportError(msg, self) else: try: os.makedirs(file_dir) except IOError as e: msg = 'Failed to create directory at: ' msg += myokit.format_path(file_dir) msg += ' IOError:' + str(e) self.log_flair('An error occurred.') self.log(msg) raise myokit.ExportError(msg, self) # Check if output file already exists out_name = os.path.join(path, out_name) if os.path.exists(out_name): if os.path.isdir(out_name): msg = 'Directory exists at ' + myokit.format_path(out_name) self.log_flair('An error occurred.') self.log(msg) raise myokit.ExportError(msg, self) self.log('Overwriting ' + myokit.format_path(out_name)) # Check template file tpl_name = os.path.join(tpl_dir, tpl_name) if not os.path.exists(tpl_name): msg = 'File not found: ' + myokit.format_path(tpl_name) self.log_flair('An error occurred.') self.log(msg) raise myokit.ExportError(msg, self) if not os.path.isfile(tpl_name): msg = 'Directory found, expecting file at ' msg += myokit.format_path(tpl_name) self.log_flair('An error occurred.') self.log(msg) raise myokit.ExportError(msg, self) # Render with open(out_name, 'w') as f: p = myokit.pype.TemplateEngine() p.set_output_stream(f) try: p.process(tpl_name, tpl_vars) except Exception as e: self.log_flair('An error ocurred while processing the' ' template at ' + myokit.format_path(tpl_name)) self.log(traceback.format_exc()) if isinstance(e, myokit.pype.PypeError): # Pype error? Then add any error details d = p.error_details() if d: self.log(d) raise myokit.ExportError('An internal error ocurred while' ' processing a template.', self)