/**
* Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Eclipse Public License (EPL).
* Please see the license.txt included with this distribution for details.
* Any modifications to this file must keep this entire header intact.
*/
/*
* Created on 08/08/2005
*/
package org.python.pydev.ui.pythonpathconf;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.dialogs.ListDialog;
import org.python.pydev.core.IInterpreterManager;
import org.python.pydev.core.log.Log;
import org.python.pydev.editor.actions.PyAction;
import org.python.pydev.plugin.PydevPlugin;
import org.python.pydev.ui.UIConstants;
import at.jta.Key;
import at.jta.Regor;
import com.aptana.shared_core.structure.Tuple;
import com.aptana.shared_core.utils.PlatformUtils;
public class PythonInterpreterEditor extends AbstractInterpreterEditor {
public PythonInterpreterEditor(String labelText, Composite parent, IInterpreterManager interpreterManager) {
super(IInterpreterManager.PYTHON_INTERPRETER_PATH, labelText, parent, interpreterManager);
}
@Override
public String[] getInterpreterFilterExtensions() {
if (PlatformUtils.isWindowsPlatform()) {
return new String[] { "*.exe", "*.*" };
}
return null;
}
@Override
protected Tuple<String, String> getAutoNewInput() throws CancelException {
List<String> pathsToSearch = new ArrayList<String>();
if (!PlatformUtils.isWindowsPlatform()) {
pathsToSearch.add("/usr/bin");
pathsToSearch.add("/usr/local/bin");
Tuple<String, String> ret = super.getAutoNewInputFromPaths(pathsToSearch, "python", "python");
if (ret != null) {
return ret;
}
} else {
//On windows we can try to see the installed versions...
List<File> foundVersions = new ArrayList<File>();
try {
Regor regor = new Regor();
//The structure for Python is something as Software\\Python\\PythonCore\\2.6\\InstallPath
for (Key root : new Key[] { Regor.HKEY_LOCAL_MACHINE, Regor.HKEY_CURRENT_USER }) {
Key key = regor.openKey(root, "Software\\Python\\PythonCore", Regor.KEY_READ);
if (key != null) {
try {
List l = regor.listKeys(key);
for (Object o : l) {
Key openKey = regor.openKey(key, (String) o + "\\InstallPath", Regor.KEY_READ);
if (openKey != null) {
try {
byte buf[] = regor.readValue(openKey, "");
if (buf != null) {
String parseValue = Regor.parseValue(buf);
//Ok, this should be the directory where it's installed, try to find a 'python.exe' there...
File file = new File(parseValue, "python.exe");
if (file.isFile()&&file.exists()) {
foundVersions.add(file);
}
}
} finally {
regor.closeKey(openKey);
}
}
}
} finally {
regor.closeKey(key);
}
}
try {
foundPythonByCMD(foundVersions, root);
} catch (Exception e) {
//do nothing
}
}
} catch (Throwable e) {
Log.log(e);
}
if (foundVersions.size() == 1) {
return new Tuple<String, String>(getUniqueInterpreterName("python"), foundVersions.get(0).toString());
}
if (foundVersions.size() > 1) {
//The user should select which one to use...
ListDialog listDialog = new ListDialog(PyAction.getShell());
listDialog.setContentProvider(new ArrayContentProvider());
listDialog.setLabelProvider(new LabelProvider() {
@Override
public Image getImage(Object element) {
return PydevPlugin.getImageCache().get(UIConstants.PY_INTERPRETER_ICON);
}
});
listDialog.setInput(foundVersions.toArray());
listDialog
.setMessage("Multiple interpreters were found installed.\nPlease select which one you want to configure.");
int open = listDialog.open();
if (open != ListDialog.OK) {
throw cancelException;
}
Object[] result = listDialog.getResult();
if (result == null || result.length == 0) {
throw cancelException;
}
return new Tuple<String, String>(getUniqueInterpreterName("python"), result[0].toString());
}
}
return new Tuple<String, String>(getUniqueInterpreterName("python"), "python"); //This should be enough to find it from the PATH or any other way it's defined.
}
/**
* @param foundVersions
* @param root
* @throws IOException
* @throws UnsupportedEncodingException
*/
protected void foundPythonByCMD(List<File> foundVersions, Key root) throws IOException,
UnsupportedEncodingException {
ProcessBuilder process = new ProcessBuilder();
String path = root.getPath() + "\\SOFTWARE\\Python\\PythonCore";
process.command("REG", "QUERY", path, "/s", "/reg:64");
process.redirectErrorStream(true);
Process p = process.start();
p.getOutputStream().flush();
p.getOutputStream().close();
InputStream is = p.getInputStream();
StringBuffer sb = new StringBuffer();
byte[] caches = new byte[1024];
try{
int len = -1;
while ((len = is.read(caches)) != -1) {
sb.append(new String(caches, 0, len, "gbk"));
}
}finally{
if(is!=null){
is.close();
}
}
Pattern pt = Pattern.compile(path.replace("\\", "\\\\") + "\\\\([0-9\\.]+)\\\\" + "InstallPath");
String[] lines = sb.toString().split("\r\n");
boolean find = false;
for (String line : lines) {
if (find) {
String valueType = "REG_SZ";
String loc = line.substring(line.indexOf(valueType) + valueType.length()).trim();
File file = new File(loc, "python.exe");
if (file.isFile()&&file.exists()) {
foundVersions.add(file);
}
find = false;
}
Matcher m = pt.matcher(line);
if (m.matches()) {
// System.out.println(m.group(1));
find = true;
}
}
}
protected void doFillIntoGrid(Composite parent, int numColumns) {
super.doFillIntoGrid(parent, numColumns);
this.autoConfigButton.setToolTipText("Will try to find Python on the PATH (will fail if not available)");
}
}