22
33import com .badlogic .gdx .jnigen .commons .HostDetection ;
44import com .badlogic .gdx .jnigen .commons .Os ;
5+ import io .github .berstanio .pymobiledevice3 .ipc .PyMobileDevice3IPC ;
56
67import java .io .File ;
78import java .io .IOException ;
89import java .io .InputStream ;
10+ import java .net .MalformedURLException ;
11+ import java .net .URL ;
912import java .nio .charset .StandardCharsets ;
1013import java .nio .file .Files ;
1114import java .nio .file .Path ;
@@ -19,16 +22,56 @@ public class PyInstallationHandler {
1922 private static final String HANDLER_NAME = "handler.py" ;
2023 private static final String REQUIREMENTS_NAME = "requirements.txt" ;
2124 private static final String PYTHON_PATH = "bin/python3" ;
25+ private static final String BASE_URL = "https://raw.githubusercontent.com/multi-os-engine/IPCPyMobileDevice3/refs/tags/v" + PyMobileDevice3IPC .PROTOCOL_VERSION ;
26+ private static final String HANDLER_DEFAULT_URL = BASE_URL + "/" + HANDLER_NAME ;
27+ private static final String REQUIREMENTS_DEFAULT_URL = BASE_URL + "/" + REQUIREMENTS_NAME ;
2228
2329 public static PyInstallation install (File directory ) {
30+ try {
31+ return PyInstallationHandler .install (directory , new URL (HANDLER_DEFAULT_URL ), new URL (REQUIREMENTS_DEFAULT_URL ));
32+ } catch (MalformedURLException e ) {
33+ throw new RuntimeException ("Failed to resolve IPC URL" , e );
34+ }
35+ }
36+
37+ public static PyInstallation install (File directory , File handlerFile , File requirementsFile ) {
38+ directory .mkdirs ();
39+ if (!directory .exists () || !directory .isDirectory ())
40+ throw new IllegalArgumentException (directory .getAbsolutePath () + " does not exist or is not a directory" );
41+
42+ try {
43+ Files .copy (handlerFile .toPath (), directory .toPath ().resolve (HANDLER_NAME ), StandardCopyOption .REPLACE_EXISTING );
44+ Files .copy (requirementsFile .toPath (), directory .toPath ().resolve (REQUIREMENTS_NAME ), StandardCopyOption .REPLACE_EXISTING );
45+ } catch (IOException e ) {
46+ throw new RuntimeException ("Failed to copy files" , e );
47+ }
48+
49+ return installInternal (directory );
50+ }
51+
52+ public static PyInstallation install (File directory , URL handlerFile , URL requirementsFile ) {
2453 directory .mkdirs ();
2554 if (!directory .exists () || !directory .isDirectory ())
2655 throw new IllegalArgumentException (directory .getAbsolutePath () + " does not exist or is not a directory" );
56+
57+ try {
58+ try (InputStream in = handlerFile .openStream ()) {
59+ Files .copy (in , directory .toPath ().resolve (HANDLER_NAME ), StandardCopyOption .REPLACE_EXISTING );
60+ }
61+ try (InputStream in = requirementsFile .openStream ()) {
62+ Files .copy (in , directory .toPath ().resolve (REQUIREMENTS_NAME ), StandardCopyOption .REPLACE_EXISTING );
63+ }
64+ } catch (IOException e ) {
65+ throw new RuntimeException ("Failed to download files" , e );
66+ }
67+
68+ return installInternal (directory );
69+ }
70+
71+ private static PyInstallation installInternal (File directory ) {
2772 File venv = new File (directory , VENV_NAME );
2873 if (venv .exists ()) {
2974 if (checkVEnv (venv )) {
30- // Env is valid. Copy files again, just in case
31- copyFiles (directory );
3275 installRequirements (directory );
3376
3477 return finalizeInstallation (directory );
@@ -69,7 +112,6 @@ public static PyInstallation install(File directory) {
69112 throw new IllegalStateException ("Installed venv at " + venv .getAbsolutePath () + ", but it's invalid?" );
70113 }
71114
72- copyFiles (directory );
73115 installRequirements (directory );
74116
75117 return finalizeInstallation (directory );
@@ -106,24 +148,6 @@ private static File copyToTempDir(File directory) {
106148 }
107149 }
108150
109- private static void copyFiles (File directory ) {
110- try {
111- try (InputStream in = PyInstallationHandler .class .getResourceAsStream ("/" + HANDLER_NAME )) {
112- if (in == null )
113- throw new IllegalStateException (HANDLER_NAME + " not found in resources" );
114- Files .copy (in , directory .toPath ().resolve (HANDLER_NAME ), StandardCopyOption .REPLACE_EXISTING );
115- }
116-
117- try (InputStream in = PyInstallationHandler .class .getResourceAsStream ("/" + REQUIREMENTS_NAME )) {
118- if (in == null )
119- throw new IllegalStateException (REQUIREMENTS_NAME + " not found in resources" );
120- Files .copy (in , directory .toPath ().resolve (REQUIREMENTS_NAME ), StandardCopyOption .REPLACE_EXISTING );
121- }
122- } catch (IOException e ) {
123- throw new RuntimeException (e );
124- }
125- }
126-
127151 private static boolean checkVEnv (File venv ) {
128152 File pythonExecutable = new File (venv , PYTHON_PATH );
129153 if (!pythonExecutable .exists ()) {
0 commit comments