From c708471e50fb73408dd4fb146280f2b62423d7c5 Mon Sep 17 00:00:00 2001 From: sirjonasxx <36828922+sirjonasxx@users.noreply.github.com> Date: Tue, 20 Oct 2020 04:07:21 +0200 Subject: [PATCH] g-python shell part2 --- G-Earth/pom.xml | 4 +- G-Earth/src/main/java/gearth/J11Main.java | 7 --- G-Earth/src/main/java/gearth/Main.java | 30 ++++------ .../network/authentication/Authenticator.java | 15 +++-- .../gearth/services/gpython/GPythonShell.java | 56 ++++++++++++++++--- .../java/gearth/ui/buttons/BoxButton.java | 4 +- .../gearth/ui/buttons/PauseResumeButton.java | 8 +-- .../ui/extensions/ExtensionsController.java | 8 ++- .../gearth/services/gpython/init_script.py | 42 ++++++++++++++ 9 files changed, 126 insertions(+), 48 deletions(-) delete mode 100644 G-Earth/src/main/java/gearth/J11Main.java create mode 100644 G-Earth/src/main/resources/gearth/services/gpython/init_script.py diff --git a/G-Earth/pom.xml b/G-Earth/pom.xml index 8627241..3f6d0d7 100644 --- a/G-Earth/pom.xml +++ b/G-Earth/pom.xml @@ -36,7 +36,7 @@ true true lib/ - gearth.J11Main + gearth.Main false @@ -58,7 +58,7 @@ ${project.build.directory}/bin - gearth.J11Main + gearth.Main diff --git a/G-Earth/src/main/java/gearth/J11Main.java b/G-Earth/src/main/java/gearth/J11Main.java deleted file mode 100644 index 7fc0e6c..0000000 --- a/G-Earth/src/main/java/gearth/J11Main.java +++ /dev/null @@ -1,7 +0,0 @@ -package gearth; - -public class J11Main { - public static void main(String[] args) { - Main.main(args); - } -} diff --git a/G-Earth/src/main/java/gearth/Main.java b/G-Earth/src/main/java/gearth/Main.java index ce3138f..e343ff3 100644 --- a/G-Earth/src/main/java/gearth/Main.java +++ b/G-Earth/src/main/java/gearth/Main.java @@ -1,22 +1,27 @@ package gearth; import gearth.misc.AdminValidator; +import gearth.ui.GEarthController; import javafx.application.Application; import javafx.application.Platform; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; -import javafx.scene.control.*; +import javafx.scene.control.Alert; +import javafx.scene.control.ButtonType; +import javafx.scene.control.Hyperlink; +import javafx.scene.control.Label; import javafx.scene.image.Image; import javafx.scene.layout.FlowPane; import javafx.scene.layout.Region; import javafx.scene.web.WebView; import javafx.stage.Stage; -import gearth.ui.GEarthController; import org.json.JSONObject; import org.jsoup.Jsoup; import java.io.IOException; +import java.util.HashSet; +import java.util.Set; // run as root issue Invalid MIT-MAGIC-COOKIE-1 key fix: https://stackoverflow.com/questions/48139447/invalid-mit-magic-cookie-1-key @@ -30,25 +35,19 @@ public class Main extends Application { public void start(Stage primaryStage) throws Exception{ main = this; - FXMLLoader loader = new FXMLLoader(getClass().getResource("/gearth/ui/G-Earth.fxml")); + FXMLLoader loader = new FXMLLoader(getClass().getResource("ui/G-Earth.fxml")); Parent root = loader.load(); GEarthController companion = loader.getController(); companion.setStage(primaryStage); - primaryStage.getIcons().add(new Image(getClass().getResourceAsStream("/gearth/G-EarthLogoSmaller.png"))); + primaryStage.getIcons().add(new Image(getClass().getResourceAsStream("G-EarthLogoSmaller.png"))); - // TODO fix primaryStage.setResizable(false); -// primaryStage.setResizable(true); -// primaryStage.onShownProperty().addListener(e -> { -// Platform.runLater(() -> primaryStage.setResizable(false)); -// }); - //primaryStage.initStyle(StageStyle.UNDECORATED); primaryStage.setTitle("G-Earth " + version); primaryStage.setScene(new Scene(root, 650, 295)); primaryStage.show(); - primaryStage.getScene().getStylesheets().add(getClass().getResource("/gearth/ui/bootstrap3.css").toExternalForm()); + primaryStage.getScene().getStylesheets().add(getClass().getResource("ui/bootstrap3.css").toExternalForm()); primaryStage.setOnCloseRequest( event -> { companion.exit(); @@ -64,10 +63,6 @@ public class Main extends Application { Alert alert = new Alert(Alert.AlertType.ERROR, "G-Earth needs admin privileges in order to work properly, please restart G-Earth with admin permissions unless you know what you're doing", ButtonType.OK); alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); alert.setResizable(false); -// alert.setResizable(true); -// alert.onShownProperty().addListener(e -> { -// Platform.runLater(() -> alert.setResizable(false)); -// }); alert.show(); }); @@ -103,11 +98,6 @@ public class Main extends Application { webView.setPrefSize(500, 200); alert.setResizable(false); -// alert.setResizable(true); -// alert.onShownProperty().addListener(e -> { -// Platform.runLater(() -> alert.setResizable(false)); -// }); - alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); alert.getDialogPane().setContent(fp); if (isForcedUpdate) { diff --git a/G-Earth/src/main/java/gearth/services/extensionhandler/extensions/implementations/network/authentication/Authenticator.java b/G-Earth/src/main/java/gearth/services/extensionhandler/extensions/implementations/network/authentication/Authenticator.java index 82c5adf..76c4df2 100644 --- a/G-Earth/src/main/java/gearth/services/extensionhandler/extensions/implementations/network/authentication/Authenticator.java +++ b/G-Earth/src/main/java/gearth/services/extensionhandler/extensions/implementations/network/authentication/Authenticator.java @@ -6,9 +6,7 @@ import javafx.application.Platform; import javafx.scene.control.Alert; import javafx.scene.control.ButtonType; -import java.util.HashMap; -import java.util.Map; -import java.util.Random; +import java.util.*; /** * Created by Jonas on 16/10/18. @@ -16,15 +14,24 @@ import java.util.Random; public class Authenticator { private static Map cookies = new HashMap<>(); + private static Set perma_cookies = new HashSet<>(); public static String generateCookieForExtension(String filename) { String cookie = getRandomCookie(); cookies.put(filename, cookie); - + return cookie; + } + public static String generatePermanentCookie() { + String cookie = getRandomCookie(); + perma_cookies.add(cookie); return cookie; } public static boolean evaluate(NetworkExtension extension) { + if (extension.getCookie() != null && perma_cookies.contains(extension.getCookie())) { + return true; + } + if (extension.isInstalledExtension()) { return claimSession(extension.getFileName(), extension.getCookie()); } diff --git a/G-Earth/src/main/java/gearth/services/gpython/GPythonShell.java b/G-Earth/src/main/java/gearth/services/gpython/GPythonShell.java index bb6cc21..734e1f2 100644 --- a/G-Earth/src/main/java/gearth/services/gpython/GPythonShell.java +++ b/G-Earth/src/main/java/gearth/services/gpython/GPythonShell.java @@ -10,20 +10,25 @@ import javafx.scene.control.Label; import javafx.scene.layout.FlowPane; import javafx.scene.layout.Region; -import java.io.BufferedWriter; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; +import java.io.*; +import java.net.URI; +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.List; +import java.util.stream.Collectors; public class GPythonShell { private final String extensionName; + private final int port; private final String cookie; - public GPythonShell(String extensionName, String cookie) { + public GPythonShell(String extensionName, int port, String cookie) { this.extensionName = extensionName; + this.port = port; this.cookie = cookie; } @@ -43,6 +48,41 @@ public class GPythonShell { List sysargs = enterCommandAndAwait(out, in, "import sys; sys.argv"); String kernelName = extractKernelName(sysargs); + InputStream initScriptResource = getClass().getResourceAsStream("init_script.py"); + List initScript = new BufferedReader(new InputStreamReader(initScriptResource, + StandardCharsets.UTF_8)).lines().collect(Collectors.toList()); + + for (String line : initScript) { + line = line.replace("$G_PYTHON_SHELL_TITLE$", extensionName) + .replace("$G_EARTH_PORT$", "" + port) + .replace("$COOKIE$", cookie); + enterCommandAndAwait(out, in, line); + } + + ProcessBuilder qtConsoleBuilder = new ProcessBuilder("python", "-m", "jupyter", "qtconsole", + "--ConsoleWidget.include_other_output", "True", + "--ConsoleWidget.gui_completion", "'droplist'", +// "--ConsoleWidget.other_output_prefix", "'[G-Earth]'", +// "--JupyterWidget.in_prompt", "'>>>: '", +// "--JupyterWidget.out_prompt", "''", + "--KernelManager.autorestart", "False", + "--JupyterConsoleApp.confirm_exit", "False", + "--JupyterConsoleApp.existing", kernelName); + Process qtConsole = qtConsoleBuilder.start(); + + new Thread(() -> { + try { + qtConsole.waitFor(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + try { + enterCommandAndAwait(out, in, "ext.stop()"); + enterCommand(out, "exit()"); + } catch (IOException e) { + e.printStackTrace(); + } + }).start(); onLaunch.launched(false); } @@ -123,7 +163,7 @@ public class GPythonShell { for (int i = 0; i < params.size() - 1; i++) { if (params.get(i).equals("-f")) { - return params.get(i+1); + return "'" + params.get(i+1) + "'"; } } return null; @@ -155,8 +195,8 @@ public class GPythonShell { return extensionName; } - public static void main(String[] args) throws IOException { - GPythonShell shell = new GPythonShell("test", "cookie"); + public static void main(String[] args) { + GPythonShell shell = new GPythonShell("test", 9092, "cookie"); shell.launch((b) -> { System.out.println("launched"); }); diff --git a/G-Earth/src/main/java/gearth/ui/buttons/BoxButton.java b/G-Earth/src/main/java/gearth/ui/buttons/BoxButton.java index d7f69a9..0afd90c 100644 --- a/G-Earth/src/main/java/gearth/ui/buttons/BoxButton.java +++ b/G-Earth/src/main/java/gearth/ui/buttons/BoxButton.java @@ -18,8 +18,8 @@ public class BoxButton extends StackPane { //paths zijn relatief aan deze classpath public BoxButton(String imageName, String imageOnHoverName) { - this.image = new Image(getClass().getResourceAsStream("/gearth/ui/buttons/files/" + imageName)); - this.imageOnHover = new Image(getClass().getResourceAsStream("/gearth/ui/buttons/files/" + imageOnHoverName)); + this.image = new Image(getClass().getResourceAsStream("files/" + imageName)); + this.imageOnHover = new Image(getClass().getResourceAsStream("files/" + imageOnHoverName)); this.imageView = new ImageView(); setCursor(Cursor.DEFAULT); diff --git a/G-Earth/src/main/java/gearth/ui/buttons/PauseResumeButton.java b/G-Earth/src/main/java/gearth/ui/buttons/PauseResumeButton.java index c107334..3df2cff 100644 --- a/G-Earth/src/main/java/gearth/ui/buttons/PauseResumeButton.java +++ b/G-Earth/src/main/java/gearth/ui/buttons/PauseResumeButton.java @@ -33,10 +33,10 @@ public class PauseResumeButton extends StackPane{ public PauseResumeButton(boolean isPaused) { this.isPaused[0] = isPaused; - this.imagePause = new Image(getClass().getResourceAsStream("/gearth/ui/buttons/files/ButtonPause.png")); - this.imagePauseOnHover = new Image(getClass().getResourceAsStream("/gearth/ui/buttons/files/ButtonPauseHover.png")); - this.imageResume = new Image(getClass().getResourceAsStream("/gearth/ui/buttons/files/ButtonResume.png")); - this.imageResumeOnHover = new Image(getClass().getResourceAsStream("/gearth/ui/buttons/files/ButtonResumeHover.png")); + this.imagePause = new Image(getClass().getResourceAsStream("files/ButtonPause.png")); + this.imagePauseOnHover = new Image(getClass().getResourceAsStream("files/ButtonPauseHover.png")); + this.imageResume = new Image(getClass().getResourceAsStream("files/ButtonResume.png")); + this.imageResumeOnHover = new Image(getClass().getResourceAsStream("files/ButtonResumeHover.png")); this.imageView = new ImageView(); setCursor(Cursor.DEFAULT); diff --git a/G-Earth/src/main/java/gearth/ui/extensions/ExtensionsController.java b/G-Earth/src/main/java/gearth/ui/extensions/ExtensionsController.java index 098207b..813599f 100644 --- a/G-Earth/src/main/java/gearth/ui/extensions/ExtensionsController.java +++ b/G-Earth/src/main/java/gearth/ui/extensions/ExtensionsController.java @@ -6,6 +6,7 @@ import gearth.services.extensionhandler.ExtensionHandler; import gearth.services.extensionhandler.extensions.ExtensionListener; import gearth.services.extensionhandler.extensions.GEarthExtension; import gearth.services.extensionhandler.extensions.implementations.network.NetworkExtensionsProducer; +import gearth.services.extensionhandler.extensions.implementations.network.authentication.Authenticator; import gearth.services.extensionhandler.extensions.implementations.network.executer.ExecutionInfo; import gearth.services.extensionhandler.extensions.implementations.network.executer.ExtensionRunner; import gearth.services.extensionhandler.extensions.implementations.network.executer.ExtensionRunnerFactory; @@ -117,11 +118,16 @@ public class ExtensionsController extends SubForm { } + private volatile int gpytonShellCounter = 1; private volatile boolean pythonShellLaunching = false; public void gpythonBtnClicked(ActionEvent actionEvent) { pythonShellLaunching = true; Platform.runLater(() -> btn_gpython.setDisable(true)); - GPythonShell shell = new GPythonShell("test", "cookie"); + GPythonShell shell = new GPythonShell( + "Scripting shell " + gpytonShellCounter++, + networkExtensionsProducer.getPort(), + Authenticator.generatePermanentCookie() + ); shell.launch((b) -> { pythonShellLaunching = false; Platform.runLater(this::updateGPythonStatus); diff --git a/G-Earth/src/main/resources/gearth/services/gpython/init_script.py b/G-Earth/src/main/resources/gearth/services/gpython/init_script.py new file mode 100644 index 0000000..c0a750c --- /dev/null +++ b/G-Earth/src/main/resources/gearth/services/gpython/init_script.py @@ -0,0 +1,42 @@ +from time import sleep + +from g_python.gextension import Extension +from g_python.hmessage import Direction, HMessage +from g_python.hpacket import HPacket +from g_python import hparsers +from g_python import htools + +extension_info = {"title": "$G_PYTHON_SHELL_TITLE$", "description": "G-Python scripting console", "version": "1.0", "author": ""} + +ext = Extension(extension_info, ["--port", "$G_EARTH_PORT$", "--auth-token", "$COOKIE$"], {"can_leave": False}) +ext.start() + + +def is_closed(): return ext.is_closed() + + +def send_to_client(packet): return ext.send_to_client(packet) + + +def send_to_server(packet): return ext.send_to_server(packet) + + +def on_event(event_name: str, func): return ext.on_event(event_name, func) + + +def intercept(direction: Direction, callback, id=-1): return ext.intercept(direction, callback, id) + + +def start(): return ext.start() + + +def stop(): return ext.stop() + + +def write_to_console(text, color='black', mention_title=True): return ext.write_to_console(text, color, mention_title) + + +def request_flags(): return ext.request_flags() + + +HPacket.default_extension = ext