package com.jetbrains.maya;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.RunContentExecutor;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.process.ProcessOutputTypes;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import java.io.BufferedOutputStream;
import java.io.PrintWriter;
import java.net.Socket;
/**
* @author traff
*/
public class SendToMayaCommand {
private static final Logger LOG = Logger.getInstance(SendToMayaCommand.class);
private Project myProject;
private String myScriptText = null;
private VirtualFile myFile = null;
private final int myPythonCommandPort;
private final static String PY_CMD_TEMPLATE =
"import traceback\nimport sys\nimport __main__\ntry:\n\texec('''%s''', __main__.__dict__, __main__.__dict__)\nexcept:\n\ttraceback.print_exc()\nsys.stdout.write(%s)";
private final static String PY_FILE_TEMPLATE =
"import traceback\nimport sys\nimport __main__\ntry:\n\texecfile('''%s''', __main__.__dict__, __main__.__dict__)\nexcept:\n\ttraceback.print_exc()\nsys.stdout.write(%s)";
private final static String TERMINATION_STRING = "'%c\\n'%26";
public SendToMayaCommand(Project project, int port) {
myProject = project;
myPythonCommandPort = port;
}
public void run() {
try {
final ProcessHandler process = createRunInMayaProcessHandler();
new RunContentExecutor(myProject, process)
.withTitle(getTitle())
.withRerun(() -> this.run())
.withStop(() -> process.destroyProcess(), () -> !process.isProcessTerminated()
)
.run();
}
catch (ExecutionException e) {
Messages.showErrorDialog(myProject, e.getMessage(), getTitle());
}
}
private ProcessHandler createRunInMayaProcessHandler() throws ExecutionException {
try {
final Socket socket = new Socket("127.0.0.1", myPythonCommandPort);
final SocketProcessHandler processHandler = new SocketProcessHandler(socket, getTitle());
try {
PrintWriter writer = new PrintWriter(new BufferedOutputStream(socket.getOutputStream()));
if (myScriptText != null) {
String[] lines = getScriptLines();
writeLines(writer, lines);
processHandler.notifyTextAvailable(
"Sent " + lines.length + " line" + (lines.length != 1 ? "s" : "") + " to command port " + myPythonCommandPort + "\n",
ProcessOutputTypes.SYSTEM);
}
else {
writeFile(writer, myFile);
processHandler.notifyTextAvailable(
"Sent " + myFile.getPath() + " to command port " + myPythonCommandPort + "\n", ProcessOutputTypes.SYSTEM);
}
writer.flush();
}
catch (Exception e) {
if (!socket.isClosed()) {
socket.close();
}
throw new ExecutionException(e.getMessage());
}
return processHandler;
}
catch (Exception e) {
throw new ExecutionException(e.getMessage());
}
}
private static void writeLines(PrintWriter writer, String[] lines) {
writer.print(String.format(PY_CMD_TEMPLATE, StringUtil.join(lines, "\n"), TERMINATION_STRING));
}
private static void writeFile(PrintWriter writer, VirtualFile file) {
writer.print(String.format(PY_FILE_TEMPLATE, file.getPath(), TERMINATION_STRING));
}
public String[] getScriptLines() {
return StringUtil.splitByLines(myScriptText);
}
public String getTitle() {
return "Send to Maya";
}
public SendToMayaCommand withSelectionText(String selectionText) {
myScriptText = selectionText;
return this;
}
public SendToMayaCommand withFile(VirtualFile file) {
myFile = file;
return this;
}
}