package org.molgenis.python; import freemarker.template.Template; import freemarker.template.TemplateException; import org.apache.commons.io.IOUtils; import org.apache.commons.io.output.FileWriterWithEncoding; import org.molgenis.file.FileStore; import org.molgenis.script.Script; import org.molgenis.script.ScriptRunner; import org.molgenis.script.ScriptRunnerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.FileCopyUtils; import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer; import java.io.*; import java.nio.charset.Charset; import java.util.Map; import java.util.UUID; @Service public class PythonScriptRunner implements ScriptRunner { private static final String NAME = "python"; private static final Charset CHARSET = Charset.forName("utf-8"); private final PythonScriptExecutor pythonScriptExecutor; private final FileStore fileStore; private final FreeMarkerConfigurer freeMarkerConfig; @Autowired public PythonScriptRunner(PythonScriptExecutor pythonScriptExecutor, FileStore fileStore, FreeMarkerConfigurer freeMarkerConfig, ScriptRunnerFactory scriptRunnerFactory) { this.pythonScriptExecutor = pythonScriptExecutor; this.fileStore = fileStore; this.freeMarkerConfig = freeMarkerConfig; } /** * Run a Python script as freemarker template * * @param templateName * @param parameters * @throws IOException * @throws TemplateException */ public void runPythonScript(String templateName, Map<String, Object> parameters, PythonOutputHandler outputHandler) throws IOException, TemplateException { String scriptName = generateRandomPythonScriptName(); runPythonScript(scriptName, templateName, parameters, outputHandler); } /** * Run an Python script as freemarker template * * @param scriptName * @param templateName * @param parameters * @throws IOException * @throws TemplateException */ public void runPythonScript(String scriptName, String templateName, Map<String, Object> parameters, PythonOutputHandler outputHandler) throws IOException, TemplateException { File pythonScriptFile = fileStore.getFile(scriptName); Template template = freeMarkerConfig.getConfiguration().getTemplate(templateName); Writer w = new FileWriterWithEncoding(pythonScriptFile, CHARSET); try { template.process(parameters, w); } finally { IOUtils.closeQuietly(w); } pythonScriptExecutor.executeScript(pythonScriptFile, outputHandler); } /** * Run an Python script as string * * @param script * @param outputHandler * @throws IOException * @throws FileNotFoundException */ public void runPythonScript(String script, PythonOutputHandler outputHandler) throws FileNotFoundException, IOException { String scriptName = generateRandomPythonScriptName(); File file = fileStore.getFile(scriptName); FileCopyUtils.copy(script, new OutputStreamWriter(new FileOutputStream(file), CHARSET)); pythonScriptExecutor.executeScript(file, outputHandler); } @Override public String getName() { return NAME; } @Override public String runScript(Script script, Map<String, Object> parameters) { File pythonScriptFile = script.generateScript(fileStore, "python", parameters); StringPythonOutputHandler handler = new StringPythonOutputHandler(); runPythonScript(pythonScriptFile, handler); return handler.toString(); } /** * Run an Python script * * @param script * @param outputHandler */ public void runPythonScript(File script, PythonOutputHandler outputHandler) { pythonScriptExecutor.executeScript(script, outputHandler); } private String generateRandomPythonScriptName() { return UUID.randomUUID().toString().replaceAll("-", "") + ".python"; } }