com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of BowlerScriptingKernel Show documentation
Show all versions of BowlerScriptingKernel Show documentation
A command line utility for accsing the bowler framework.
package com.neuronrobotics.bowlerstudio.scripting;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.PullResult;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
import org.eclipse.jgit.api.errors.TransportException;
import org.eclipse.jgit.internal.storage.file.FileRepository;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Attributes;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.select.Elements;
import org.kohsuke.github.GHGist;
import org.kohsuke.github.GitHub;
import org.python.antlr.ast.ExceptHandler;
import com.neuronrobotics.sdk.common.Log;
import com.neuronrobotics.sdk.util.ThreadUtil;
import javafx.scene.layout.BorderPane;
import javafx.scene.web.WebEngine;
public class ScriptingEngine {// this subclasses boarder pane for the widgets sake, because multiple inheritance is TOO hard for java...
private static final int TIME_TO_WAIT_BETWEEN_GIT_PULL = 100000;
/**
*
*/
private static final Map fileLastLoaded = new HashMap();
private static boolean hasnetwork=false;
private static boolean autoupdate=false;
private static final String[] imports = new String[] { //"haar",
"java.awt",
"eu.mihosoft.vrl.v3d",
"eu.mihosoft.vrl.v3d.samples",
"com.neuronrobotics.sdk.addons.kinematics.xml",
"com.neuronrobotics.sdk.dyio.peripherals",
"com.neuronrobotics.sdk.dyio",
"com.neuronrobotics.sdk.common",
"com.neuronrobotics.sdk.ui",
"com.neuronrobotics.sdk.util",
"com.neuronrobotics.sdk.serial",
"javafx.scene.control",
"com.neuronrobotics.bowlerstudio.scripting",
"com.neuronrobotics.sdk.config",
"com.neuronrobotics.bowlerstudio",
"com.neuronrobotics.imageprovider",
"com.neuronrobotics.bowlerstudio.tabs",
"javafx.scene.text", "javafx.scene",
"com.neuronrobotics.sdk.addons.kinematics",
"com.neuronrobotics.sdk.addons.kinematics.math", "java.util",
"com.neuronrobotics.sdk.addons.kinematics.gui",
"javafx.scene.transform", "javafx.scene.shape",
"java.awt.image.BufferedImage",
"com.neuronrobotics.bowlerstudio.vitamins.Vitamins",
"com.neuronrobotics.bowlerkernel.BowlerDatabase",
"com.neuronrobotics.bowlerstudio.physics.PhysicsEngine",
"com.neuronrobotics.bowlerstudio.physics.CSGPhysicsManager",
"com.neuronrobotics.bowlerstudio.physics.MobileBasePhysicsManager"};
private static GitHub github;
private static HashMap filesRun = new HashMap<>();
private static File creds=null;
//private static GHGist gist;
private static File workspace;
private static File lastFile;
private static String loginID=null;
private static String pw =null;
private static CredentialsProvider cp;// = new UsernamePasswordCredentialsProvider(name, password);
private static ArrayList loginListeners = new ArrayList();
private static ArrayList langauges=new ArrayList<>();
private static IGitHubLoginManager loginManager = new IGitHubLoginManager() {
@Override
public String[] prompt(String username) {
new RuntimeException("Login required").printStackTrace();
if (username != null) {
if (username.equals(""))
username = null;
}
String[] creds = new String[] { "", "" };
System.out.println("#Github Login Prompt#");
System.out.println("For anynomous mode hit enter twice");
System.out.print("Github Username: " + username != null ? "(" + username + ")" : "");
// create a scanner so we can read the command-line input
BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));
do {
try {
creds[0] = buf.readLine();
} catch (IOException e) {
return null;
}
if (creds[0].equals("") && (username == null)) {
System.out.println("No username, using anynomous login");
return null;
} else
creds[0] = username;
} while (creds[0] == null);
System.out.print("Github Password: ");
try {
creds[1] = buf.readLine();
if (creds[1].equals("")) {
System.out.println("No password, using anynomous login");
}
} catch (IOException e) {
return null;
}
return creds;
}
};
private static boolean loginSuccess=false;
static {
try {
final URL url = new URL("http://github.com");
final URLConnection conn = url.openConnection();
conn.connect();
conn.getInputStream();
hasnetwork= true;
} catch (Exception e) {
// we assuming we have no access to the server and run off of the chached gists.
hasnetwork= false;
}
workspace = new File(System.getProperty("user.home")+"/bowler-workspace/");
if(!workspace.exists()){
workspace.mkdir();
}
try {
loadLoginData();
//runLogin();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
addScriptingLanguage(new ClojureHelper());
addScriptingLanguage(new GroovyHelper());
addScriptingLanguage(new JythonHelper());
addScriptingLanguage(new RobotHelper());
addScriptingLanguage(new JsonRunner());
addScriptingLanguage(new ArduinoLoader());
}
private static void loadLoginData() throws IOException{
if(loginID == null && getCreds().exists() && hasnetwork){
try {
String line;
InputStream fis = new FileInputStream(getCreds().getAbsolutePath());
InputStreamReader isr = new InputStreamReader(fis, Charset.forName("UTF-8"));
@SuppressWarnings("resource")
BufferedReader br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
if(line.startsWith("login")||line.startsWith("username")){
loginID = line.split("=")[1];
}
if(line.startsWith("password") ){
pw = line.split("=")[1];
}
}
if(pw != null&& loginID != null){
// password loaded, we can now autoupdate
ScriptingEngine.setAutoupdate(true);
}
if(cp == null){
cp = new UsernamePasswordCredentialsProvider(loginID, pw);
}
} catch (Exception e) {
logout();
//e.printStackTrace();
}
}
}
public static void addScriptingLanguage(IScriptingLanguage lang){
getLangauges().add(lang);
}
public static void addIGithubLoginListener(IGithubLoginListener l){
if(!loginListeners.contains(l)){
loginListeners.add(l);
}
}
public static void removeIGithubLoginListener(IGithubLoginListener l){
if(loginListeners.contains(l)){
loginListeners.remove(l);
}
}
public static File getWorkspace() {
//System.err.println("Workspace: "+workspace.getAbsolutePath());
return workspace;
}
public static String getShellType(String name) {
for (IScriptingLanguage l:getLangauges()){
if(l.isSupportedFileExtenetion(name))
return l.getShellType();
}
return "Groovy";
}
public static String getLoginID(){
return loginID;
}
public static void login() throws IOException{
if(! hasnetwork)
return;
loginID=null;
gitHubLogin();
}
public static void logout() throws IOException{
//new RuntimeException("Logout callsed").printStackTrace();
if(getCreds()!= null)
if(getCreds().exists())
Files.delete(getCreds().toPath());
setGithub(null);
for(IGithubLoginListener l:loginListeners){
l.onLogout(loginID);
}
loginID=null;
}
public static GitHub setupAnyonmous() throws IOException{
System.err.println("Using anynomous login, autoupdate disabled");
ScriptingEngine.setAutoupdate(false);
logout();
setGithub(GitHub.connectAnonymously());
return getGithub();
}
public static String urlToGist(String in) {
if(in.endsWith(".git")){
in=in.substring(0, in.lastIndexOf('.'));
}
String domain = in.split("//")[1];
String[] tokens = domain.split("/");
if (tokens[0].toLowerCase().contains("gist.github.com")
&& tokens.length >= 2) {
try{
String id = tokens[2].split("#")[0];
Log.debug("Gist URL Detected " + id);
return id;
}catch(ArrayIndexOutOfBoundsException e){
try{
String id = tokens[1].split("#")[0];
Log.debug("Gist URL Detected " + id);
return id;
}catch(ArrayIndexOutOfBoundsException ex){
Log.error("Parsing "+in+" failed to find gist");
return "d4312a0787456ec27a2a";
}
}
}
return null;
}
private static List returnFirstGist(String html) {
// Log.debug(html);
ArrayList ret = new ArrayList<>();
Document doc = Jsoup.parse(html);
Elements links = doc.select("script");
for(int i=0;i getCurrentGist(String addr, WebEngine engine) {
String gist = urlToGist(addr);
if (gist == null) {
try {
Log.debug("Non Gist URL Detected");
String html;
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
StringWriter sw = new StringWriter();
t.transform(new DOMSource(engine.getDocument()),
new StreamResult(sw));
html = sw.getBuffer().toString();
return returnFirstGist(html);
} catch (TransformerConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
ArrayList ret = new ArrayList<>();
ret.add(gist);
return ret;
}
public static GitHub gitHubLogin() throws IOException{
String[] creds = loginManager.prompt(loginID);
if(creds==null){
return setupAnyonmous();
}else{
if(creds[0].contains("@")){
System.err.print("###ERROR Enter the Username not the Email Address### ");
return gitHubLogin();
}if(creds[0].equals("") || creds[1].equals("") ){
System.err.print("###No Username or password### ");
return setupAnyonmous();
}
}
loginID = creds[0];
pw= creds[1];
String content= "login="+loginID+"\n";
content+= "password="+pw+"\n";
PrintWriter out;
try {
out = new PrintWriter(getCreds().getAbsoluteFile());
out.println(content);
out.flush();
out.close();
runLogin();
} catch (Exception e) {
e.printStackTrace();
System.out.println("Login failed");
setGithub(null);
}
if(getGithub()==null){
ThreadUtil.wait(200);
return gitHubLogin();
}
else
return getGithub();
}
public static void runLogin() throws IOException{
setGithub(GitHub.connect());
if(getGithub().isCredentialValid()){
cp = new UsernamePasswordCredentialsProvider(loginID, pw);
for(IGithubLoginListener l:loginListeners){
l.onLogin(loginID);
}
System.out.println("Success Login as "+loginID+"");
setLoginSuccess(true);
}else{
System.err.println("Bad login credentials for "+loginID);
setGithub(null);
pw= null;
}
}
/**
*
* @param id The GistID we are waiting to see
* @throws IOException
* @throws InvalidRemoteException
* @throws TransportException
* @throws GitAPIException
*/
private static void waitForLogin() throws IOException, InvalidRemoteException, TransportException, GitAPIException{
try {
final URL url = new URL("http://github.com");
final URLConnection conn = url.openConnection();
conn.connect();
conn.getInputStream();
hasnetwork= true;
} catch (Exception e) {
// we assuming we have no access to the server and run off of the chached gists.
hasnetwork= false;
}
if(!hasnetwork)
return;
if(getGithub() == null){
if (getCreds().exists()){
try{
setGithub(GitHub.connect());
}catch(IOException ex){
logout();
}
}else{
getCreds().createNewFile();
}
if(getGithub()==null){
login();
}
}
try{
if(getGithub().getRateLimit().remaining<2){
System.err.println("##Github Is Rate Limiting You## Disabling autoupdate");
setAutoupdate(false);
}
}catch(IOException e){
logout();
}
loadLoginData();
}
private static void deleteFolder(File folder) {
File[] files = folder.listFiles();
if(files!=null) { //some JVMs return null for empty dirs
for(File f: files) {
if(f.isDirectory()) {
deleteFolder(f);
} else {
f.delete();
}
}
}
folder.delete();
}
// private static ArrayList filesInGist(String gistcode, String extnetion) throws Exception {
//
// return filesInGit("https://gist.github.com/"+gistcode+".git","master", extnetion);
// }
private static void loadFilesToList(ArrayList f,File directory, String extnetion){
for (final File fileEntry : directory.listFiles()) {
if(fileEntry.isDirectory()){
loadFilesToList(f,fileEntry,extnetion);
}else{
if(!fileEntry.getName().endsWith(".git"))
if(extnetion!=null)
if(!fileEntry.getName().endsWith(extnetion))
continue;// skip this file as it fails the filter from the user
boolean supportedExtention=false;
for(IScriptingLanguage l:getLangauges()){
if(l.isSupportedFileExtenetion(fileEntry.getName())){
supportedExtention=true;
}
}
if(supportedExtention)// make sure the file has a supported runtime
f.add(findLocalPath(fileEntry));
}
}
}
public static ArrayList filesInGit(String remote,String branch, String extnetion) throws Exception {
ArrayList f=new ArrayList<>();
waitForLogin();
File gistDir=cloneRepo( remote,branch);
loadFilesToList(f,gistDir,extnetion);
return f;
}
public static ArrayList filesInGit(String remote) throws Exception {
return filesInGit(remote,"master", null);
}
// private static ArrayList filesInGist(String id) throws Exception{
// return filesInGist(id, null);
// }
//
public static String getUserIdOfGist(String id) throws Exception{
waitForLogin();
Log.debug("Loading Gist: " + id);
GHGist gist;
gist = getGithub().getGist(id);
return gist.getOwner().getLogin();
}
public static File createFile(String git, String fileName, String commitMessage) throws Exception{
pushCodeToGit(git,"master",fileName,null,commitMessage);
return fileFromGit(git, fileName);
}
public static void pushCodeToGit(String id, String branch, String FileName, String content, String commitMessage) throws Exception{
if (loginID == null)
login();
if (loginID == null)
return;// No login info means there is no way to publish
File gistDir = cloneRepo(id, branch);
File desired = new File(gistDir.getAbsoluteFile() + "/" + FileName);
boolean flagNewFile =false;
if (!desired.exists()) {
desired.createNewFile();
flagNewFile=true;
}
pushCodeToGit(id,branch,FileName,content,commitMessage,flagNewFile);
}
public static void pushCodeToGit(String id, String branch, String FileName, String content, String commitMessage,boolean flagNewFile)
throws Exception {
if (loginID == null)
login();
if (loginID == null)
return;// No login info means there is no way to publish
File gistDir = cloneRepo(id, branch);
File desired = new File(gistDir.getAbsoluteFile() + "/" + FileName);
if (!hasnetwork && content!=null) {
OutputStream out = null;
try {
out = FileUtils.openOutputStream(desired, false);
IOUtils.write(content, out);
out.close(); // don't swallow close Exception if copy completes
// normally
} finally {
IOUtils.closeQuietly(out);
}
return;
}
waitForLogin();
String localPath = gistDir.getAbsolutePath();
File gitRepoFile = new File(localPath + "/.git");
Repository localRepo = new FileRepository(gitRepoFile.getAbsoluteFile());
Git git = new Git(localRepo);
try {
git.pull().setCredentialsProvider(cp).call();// updates to the
// latest version
if (flagNewFile) {
git.add().addFilepattern(FileName).call();
}
if(content!=null){
OutputStream out = null;
try {
out = FileUtils.openOutputStream(desired, false);
IOUtils.write(content, out);
out.close(); // don't swallow close Exception if copy completes
// normally
} finally {
IOUtils.closeQuietly(out);
}
}
git.commit().setAll(true).setMessage(commitMessage).call();
git.push().setCredentialsProvider(cp).call();
System.out.println("Pushed file: " + desired);
} catch (Exception ex) {
git.close();
throw ex;
}
git.close();
}
public static String[] codeFromGit(String id, String FileName) throws Exception{
File targetFile = fileFromGit(id,FileName);
if(targetFile.exists()){
//System.err.println("Loading file: "+targetFile.getAbsoluteFile());
//Target file is ready to go
String text = new String(Files.readAllBytes(Paths.get(targetFile.getAbsolutePath())), StandardCharsets.UTF_8);
return new String[] { text, FileName , targetFile.getAbsolutePath()};
}
return null;
}
private static String[] codeFromGistID(String id, String FileName) throws Exception{
File targetFile = fileFromGit("https://gist.github.com/"+id+".git",FileName);
if(targetFile.exists()){
//System.err.println("Loading file: "+targetFile.getAbsoluteFile());
//Target file is ready to go
String text = new String(Files.readAllBytes(Paths.get(targetFile.getAbsolutePath())), StandardCharsets.UTF_8);
return new String[] { text, FileName , targetFile.getAbsolutePath()};
}
return null;
}
public static Object inlineFileScriptRun(File f, ArrayList
© 2015 - 2025 Weber Informatics LLC | Privacy Policy