package org.esa.snap.rcp.cli; import org.esa.snap.python.PyBridge; import org.esa.snap.rcp.session.SessionManager; import org.netbeans.api.sendopts.CommandException; import org.netbeans.spi.sendopts.Arg; import org.netbeans.spi.sendopts.ArgsProcessor; import org.netbeans.spi.sendopts.Description; import org.netbeans.spi.sendopts.Env; import org.openide.util.NbBundle; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; /** * Extra SNAP Desktop command-line arguments: * <ul> * <li>{@code --open [<session-file>] [<file-1> <file-2> ...]} </li> * <li>{@code --python <python-interpreter> [<snappy-python-module-dir>]}</li> * </ul> * * @author Norman Fomferra */ @NbBundle.Messages({ "TXT_OpenOption_Description=Open SNAP session file (*.snap) or any number of EO data product files", "TXT_PythonOption_Description=Configure the SNAP Java-Python adapter 'snappy': python <python-interpreter> [<snappy-python-module-dir>]", }) public class SnapArgsProcessor implements ArgsProcessor { @Arg(longName = "open") @Description(shortDescription = "#TXT_OpenOption_Description") public String[] openArgs; @Arg(longName = "python") @Description(shortDescription = "#TXT_PythonOption_Description") public String[] pythonArgs; public void process(Env env) throws CommandException { if (openArgs != null) { processOpen(openArgs); } if (pythonArgs != null) { processPython(pythonArgs); } } private static void processOpen(String[] args) throws CommandException { int errorExitCode = 100; Path sessionFile = null; List<Path> fileList = new ArrayList<>(); for (String arg : args) { Path file = Paths.get(arg); if (Files.exists(file)) { if (file.toFile() != null && SessionManager.getDefault().getSessionFileFilter().accept(file.toFile())) { if (sessionFile != null) { throw new CommandException(errorExitCode, "Only a single SNAP session file can be given."); } sessionFile = file; } else { fileList.add(file); } } else { System.err.println("File not found: " + file); } } SnapArgs.getDefault().setSessionFile(sessionFile); SnapArgs.getDefault().setFileList(fileList); } private static void processPython(String[] args) throws CommandException { int errorExitCode = 200; Path pythonExecutable = null; Path pythonModuleInstallDir = null; if (args.length >= 1) { pythonExecutable = Paths.get(args[0]); } if (args.length >= 2) { pythonModuleInstallDir = Paths.get(args[1]); } if (pythonExecutable == null) { throw new CommandException(errorExitCode, "Python interpreter executable must be given"); } if (!Files.exists(pythonExecutable)) { throw new CommandException(errorExitCode, "Python interpreter executable not found: " + pythonExecutable); } try { System.out.flush(); System.out.println("Configuring SNAP-Python interface..."); Path snappyDir = PyBridge.installPythonModule(pythonExecutable, pythonModuleInstallDir, true); System.out.flush(); System.out.printf("Done. The SNAP-Python interface is located in '%s'%n", snappyDir); System.out.printf("When using SNAP from Python, either do: sys.path.append('%s')%n", snappyDir.getParent().toString().replace("\\", "\\\\")); System.out.printf("or copy the '%s' module into your Python's 'site-packages' directory.%n", snappyDir.getFileName()); System.out.flush(); } catch (IOException e) { e.printStackTrace(System.out); System.out.flush(); throw new CommandException(errorExitCode, "Python configuration error: " + e.getMessage()); } catch (Throwable t) { t.printStackTrace(System.out); System.out.flush(); throw new CommandException(errorExitCode, "Python configuration internal error: " + t.getMessage()); } } }