Implement module installations and rework some exchanges

This commit is contained in:
Christopher Schnick 2022-12-30 12:53:16 +01:00
parent 0c8624168f
commit b9501bad43
12 changed files with 205 additions and 26 deletions

View file

@ -0,0 +1,50 @@
package io.xpipe.beacon.exchange;
import io.xpipe.beacon.RequestMessage;
import io.xpipe.beacon.ResponseMessage;
import io.xpipe.core.store.DataStore;
import lombok.Builder;
import lombok.NonNull;
import lombok.Value;
import lombok.extern.jackson.Jacksonized;
import java.util.LinkedHashMap;
/**
* Queries general information about a data source.
*/
public class QueryStoreExchange implements MessageExchange {
@Override
public String getId() {
return "queryStore";
}
@Jacksonized
@Builder
@Value
public static class Request implements RequestMessage {
@NonNull
String name;
}
@Jacksonized
@Builder
@Value
public static class Response implements ResponseMessage {
@NonNull
String name;
String information;
String summary;
@NonNull
String provider;
@NonNull
LinkedHashMap<String, String> config;
DataStore internalStore;
}
}

View file

@ -37,7 +37,6 @@ public class ConvertExchange implements MessageExchange {
@Builder
@Value
public static class Response implements ResponseMessage {
@NonNull
DialogReference config;
}
}

View file

@ -25,14 +25,12 @@ public class RenameEntryExchange implements MessageExchange {
DataSourceReference ref;
@NonNull
String newName;
DataSourceId newId;
}
@Jacksonized
@Builder
@Value
public static class Response implements ResponseMessage {
@NonNull
DataSourceId newId;
}
}

View file

@ -47,6 +47,7 @@ module io.xpipe.beacon {
ModeExchange,
ProxyWriteConnectionExchange,
ProxyFunctionExchange,
QueryStoreExchange,
StatusExchange,
StopExchange,
RenameStoreExchange,

View file

@ -122,7 +122,7 @@ public class XPipeInstallation {
} else if (OsType.getLocal().equals(OsType.LINUX)) {
path = "/opt/xpipe";
} else {
path = "~/Applications/X-Pipe.app";
path = "/Applications/X-Pipe.app";
}
return path;
@ -143,7 +143,7 @@ public class XPipeInstallation {
} else if (p.getOsType().equals(OsType.LINUX)) {
path = "/opt/xpipe";
} else {
path = "~/Applications/X-Pipe.app";
path = "/Applications/X-Pipe.app";
}
return path;

View file

@ -8,8 +8,9 @@ public interface Cache {
Cache INSTANCE = ServiceLoader.load(Cache.class).findFirst().orElseThrow();
public static <T> T get(String key, Class<T> type, Supplier<T> notPresent) {
return INSTANCE.getValue(key, type, notPresent);
@SuppressWarnings("unchecked")
public static <T, V extends T> V get(String key, Class<T> type, Supplier<T> notPresent) {
return (V) INSTANCE.getValue(key, type, notPresent);
}
public static <T> Optional<T> getIfPresent(String key, Class<T> type) {
@ -17,7 +18,7 @@ public interface Cache {
}
public static <T> void update(String key, T val) {
INSTANCE.updateValue(key, key);
INSTANCE.updateValue(key, val);
}
public <T> T getValue(String key, Class<?> type, Supplier<T> notPresent);

View file

@ -12,6 +12,10 @@ import java.util.List;
public interface DataStoreProvider {
default ModuleInstall getRequiredAdditionalInstallation() {
return null;
}
default void validate() throws Exception {
getCategory();
for (Class<?> storeClass : getStoreClasses()) {

View file

@ -0,0 +1,32 @@
package io.xpipe.extension;
import lombok.Getter;
import java.util.List;
public abstract class DownloadModuleInstall extends ModuleInstall {
private String licenseFile;
private String vendorURL;
@Getter
private List<String> assets;
public DownloadModuleInstall(
String id, String module, String licenseFile, String vendorURL, List<String> assets
) {
super(id, module);
this.licenseFile = licenseFile;
this.vendorURL = vendorURL;
this.assets = assets;
}
@Override
public String getLicenseFile() {
return licenseFile;
}
@Override
public String getVendorURL() {
return vendorURL;
}
}

View file

@ -0,0 +1,24 @@
package io.xpipe.extension;
import lombok.Getter;
import java.nio.file.Path;
public abstract class ModuleInstall {
@Getter
private final String id;
@Getter
private final String module;
protected ModuleInstall(String id, String module) {
this.id = id;
this.module = module;
}
public abstract String getLicenseFile();
public abstract String getVendorURL();
public abstract void installInternal(Path directory) throws Exception;
}

View file

@ -28,7 +28,7 @@ public class TrackEvent {
private Map<String, Object> tags;
@Singular
private List<String> elements;
private List<Object> elements;
public static TrackEventBuilder fromMessage(String type, String message) {
return builder().type(type).message(message);
@ -128,6 +128,17 @@ public class TrackEvent {
}
s.append("}");
}
if (elements.size() > 0) {
s.append(" [\n");
for (var e : elements) {
s.append(" ")
.append(e != null ? e.toString() : "null")
.append("\n");
}
s.append("]");
}
return s.toString();
}

View file

@ -43,7 +43,6 @@ public class DynamicOptionsComp extends Comp<CompStructure<Pane>> {
pane = content;
} else {
var content = new VBox();
content.setAlignment(Pos.CENTER);
content.setSpacing(7);
pane = content;
}
@ -52,19 +51,19 @@ public class DynamicOptionsComp extends Comp<CompStructure<Pane>> {
var compRegions = new ArrayList<Region>();
for (var entry : getEntries()) {
var line = new HBox();
line.setFillHeight(true);
if (!wrap) {
line.prefWidthProperty().bind(pane.widthProperty());
}
line.setSpacing(8);
Region compRegion = null;
if (entry.comp() != null) {
compRegion = entry.comp().createRegion();
}
if (entry.name() != null) {
var line = new HBox();
line.setFillHeight(true);
if (!wrap) {
line.prefWidthProperty().bind(pane.widthProperty());
}
line.setSpacing(8);
var name = new Label();
name.textProperty().bind(entry.name());
name.prefHeightProperty().bind(line.heightProperty());
@ -76,17 +75,20 @@ public class DynamicOptionsComp extends Comp<CompStructure<Pane>> {
}
nameRegions.add(name);
line.getChildren().add(name);
}
if (entry.comp() != null) {
compRegions.add(compRegion);
line.getChildren().add(compRegion);
if (!wrap) {
HBox.setHgrow(compRegion, Priority.ALWAYS);
if (compRegion != null) {
compRegions.add(compRegion);
line.getChildren().add(compRegion);
if (!wrap) {
HBox.setHgrow(compRegion, Priority.ALWAYS);
}
}
}
pane.getChildren().add(line);
pane.getChildren().add(line);
} else {
compRegions.add(compRegion);
pane.getChildren().add(compRegion);
}
}
if (wrap) {

View file

@ -0,0 +1,57 @@
package io.xpipe.extension.util;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.function.Consumer;
public class HttpHelper {
public static Path downloadFile(String urlS) throws Exception {
var url = new URL(urlS);
var bytes = HttpHelper.executeGet(url, aFloat -> {});
var downloadFile = Files.createTempFile(null, null);
Files.write(downloadFile, bytes);
return downloadFile;
}
public static byte[] executeGet(URL targetURL, Consumer<Float> progress) throws Exception {
HttpURLConnection connection = null;
try {
// Create connection
connection = (HttpURLConnection) targetURL.openConnection();
connection.setRequestMethod("GET");
connection.addRequestProperty("User-Agent", "https://github.com/xpipe-io/xpipe-app");
connection.addRequestProperty("Accept", "*/*");
int responseCode = connection.getResponseCode();
if (responseCode != 200) {
throw new IOException("Got http " + responseCode + " for " + targetURL);
}
InputStream is = connection.getInputStream();
int size = Integer.parseInt(connection.getHeaderField("Content-Length"));
byte[] line;
int bytes = 0;
ByteBuffer b = ByteBuffer.allocate(size);
while ((line = is.readNBytes(500000)).length > 0) {
b.put(line);
bytes += line.length;
if (progress != null) {
progress.accept((float) bytes / (float) size);
}
}
return b.array();
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
}