mirror of
https://github.com/xpipe-io/xpipe.git
synced 2025-04-19 10:43:39 +00:00
Small shell changes and move some comps to extension module
This commit is contained in:
parent
0d65db95f9
commit
40df1a3233
11 changed files with 245 additions and 17 deletions
|
@ -125,6 +125,17 @@ public class BeaconClient implements AutoCloseable {
|
|||
var command = control.command("xpipe beacon --raw").start();
|
||||
command.discardErr();
|
||||
return new BeaconClient(command, command.getStdout(), command.getStdin()) {
|
||||
|
||||
// {
|
||||
// new Thread(() -> {
|
||||
// while (true) {
|
||||
// if (!control.isRunning()) {
|
||||
// close();
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
|
||||
@Override
|
||||
public <T extends ResponseMessage> T receiveResponse()
|
||||
throws ConnectorException, ClientException, ServerException {
|
||||
|
|
|
@ -5,15 +5,9 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public interface ProcessControl extends Closeable, AutoCloseable {
|
||||
|
||||
static String join(List<String> command) {
|
||||
return command.stream().map(s -> s.contains(" ") ? "\"" + s + "\"" : s).collect(Collectors.joining(" "));
|
||||
}
|
||||
|
||||
void closeStdin() throws IOException;
|
||||
|
||||
boolean isStdinClosed();
|
||||
|
|
|
@ -71,18 +71,17 @@ public interface ShellProcessControl extends ProcessControl {
|
|||
ShellProcessControl start() throws Exception;
|
||||
|
||||
default CommandProcessControl commandListFunction(Function<ShellProcessControl, List<String>> command) {
|
||||
return commandFunction(shellProcessControl -> command.apply(shellProcessControl).stream()
|
||||
.map(s -> s.contains(" ") ? "\"" + s + "\"" : s)
|
||||
.collect(Collectors.joining(" ")));
|
||||
return commandFunction(shellProcessControl -> shellProcessControl.getShellType().flatten(command.apply(shellProcessControl)));
|
||||
}
|
||||
|
||||
CommandProcessControl commandFunction(Function<ShellProcessControl, String> command);
|
||||
|
||||
CommandProcessControl command(String command);
|
||||
default CommandProcessControl command(String command){
|
||||
return commandFunction(shellProcessControl -> command);
|
||||
}
|
||||
|
||||
default CommandProcessControl command(List<String> command) {
|
||||
return command(
|
||||
command.stream().map(s -> s.contains(" ") ? "\"" + s + "\"" : s).collect(Collectors.joining(" ")));
|
||||
return commandFunction(shellProcessControl -> shellProcessControl.getShellType().flatten(command));
|
||||
}
|
||||
|
||||
void exitAndWait() throws IOException;
|
||||
|
|
|
@ -5,10 +5,16 @@ import io.xpipe.core.charsetter.NewLine;
|
|||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
|
||||
public interface ShellType {
|
||||
|
||||
default String flatten(List<String> command) {
|
||||
return command.stream().map(s -> s.contains(" ") ? "\"" + s + "\"" : s).collect(Collectors.joining(" "));
|
||||
}
|
||||
|
||||
|
||||
default String joinCommands(String... s) {
|
||||
return String.join(getConcatenationOperator(), s);
|
||||
}
|
||||
|
|
|
@ -4,8 +4,11 @@ import io.xpipe.core.impl.FileNames;
|
|||
import io.xpipe.core.impl.LocalStore;
|
||||
import io.xpipe.core.process.CommandProcessControl;
|
||||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.process.ProcessOutputException;
|
||||
import io.xpipe.core.process.ShellProcessControl;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class XPipeInstallation {
|
||||
|
||||
public static String getInstallationBasePathForCLI(ShellProcessControl p, String cliExecutable) throws Exception {
|
||||
|
@ -22,8 +25,10 @@ public class XPipeInstallation {
|
|||
}
|
||||
|
||||
public static String queryInstallationVersion(ShellProcessControl p, String exec) throws Exception {
|
||||
try (CommandProcessControl c = p.command(exec + " version").start()) {
|
||||
try (CommandProcessControl c = p.command(List.of(exec, "version")).start()) {
|
||||
return c.readOrThrow();
|
||||
} catch (ProcessOutputException ex) {
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,7 +39,7 @@ public class XPipeInstallation {
|
|||
return false;
|
||||
}
|
||||
|
||||
try (CommandProcessControl c = p.command(executable + " version").start()) {
|
||||
try (CommandProcessControl c = p.command(List.of(executable, "version")).start()) {
|
||||
return c.readOrThrow().equals(version);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,25 @@ public abstract class EventHandler {
|
|||
}
|
||||
};
|
||||
|
||||
public static final EventHandler OMIT = new EventHandler() {
|
||||
@Override
|
||||
public List<TrackEvent> snapshotEvents() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(TrackEvent te) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(ErrorEvent ee) {
|
||||
}
|
||||
};
|
||||
|
||||
public static void set(EventHandler handler) {
|
||||
INSTANCE = handler;
|
||||
}
|
||||
|
||||
private static EventHandler INSTANCE;
|
||||
|
||||
private static void init() {
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
package io.xpipe.extension.fxcomps.impl;
|
||||
|
||||
import io.xpipe.core.impl.FileStore;
|
||||
import io.xpipe.core.impl.LocalStore;
|
||||
import io.xpipe.core.store.FileSystemStore;
|
||||
import io.xpipe.core.store.MachineStore;
|
||||
import io.xpipe.extension.I18n;
|
||||
import io.xpipe.extension.fxcomps.SimpleComp;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.stage.FileChooser;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
public class FileStoreChoiceComp extends SimpleComp {
|
||||
|
||||
private final List<MachineStore> availableFileSystems;
|
||||
private final Property<FileStore> selected;
|
||||
|
||||
public FileStoreChoiceComp(List<MachineStore> availableFileSystems, Property<FileStore> selected) {
|
||||
this.availableFileSystems = availableFileSystems;
|
||||
this.selected = selected;
|
||||
}
|
||||
|
||||
private void setSelected(FileSystemStore fileSystemStore, String file) {
|
||||
selected.setValue(fileSystemStore != null && file != null ? new FileStore(fileSystemStore, file) : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Region createSimple() {
|
||||
var fileProperty = new SimpleStringProperty(
|
||||
selected.getValue() != null ? selected.getValue().getFile() : null);
|
||||
var fileSystemProperty = new SimpleObjectProperty<>(
|
||||
selected.getValue() != null ? selected.getValue().getFileSystem() : availableFileSystems.get(0));
|
||||
|
||||
fileProperty.addListener((observable, oldValue, newValue) -> {
|
||||
setSelected(fileSystemProperty.get(), fileProperty.get());
|
||||
});
|
||||
fileSystemProperty.addListener((observable, oldValue, newValue) -> {
|
||||
setSelected(fileSystemProperty.get(), fileProperty.get());
|
||||
});
|
||||
|
||||
var fileSystemChoiceComp = new FileSystemStoreChoiceComp(fileSystemProperty);
|
||||
if (availableFileSystems.size() == 1) {
|
||||
fileSystemChoiceComp.hide(new SimpleBooleanProperty(true));
|
||||
}
|
||||
|
||||
var fileNameComp = new TextFieldComp(fileProperty).apply(struc -> HBox.setHgrow(struc.get(), Priority.ALWAYS));
|
||||
var fileBrowseButton = new IconButtonComp("mdi2f-folder-open-outline", () -> {
|
||||
if (fileSystemProperty.get() != null && fileSystemProperty.get() instanceof LocalStore) {
|
||||
var fileChooser = createChooser();
|
||||
File file = fileChooser.showOpenDialog(null);
|
||||
if (file != null && file.exists()) {
|
||||
fileProperty.setValue(file.toString());
|
||||
}
|
||||
}
|
||||
})
|
||||
.hide(fileSystemProperty.isNotEqualTo(new LocalStore()));
|
||||
|
||||
var layout = new HorizontalComp(List.of(fileSystemChoiceComp, fileNameComp, fileBrowseButton));
|
||||
|
||||
return layout.createRegion();
|
||||
}
|
||||
|
||||
private FileChooser createChooser() {
|
||||
FileChooser fileChooser = new FileChooser();
|
||||
fileChooser.setTitle(I18n.get("browseFileTitle"));
|
||||
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(I18n.get("anyFile"), "*"));
|
||||
return fileChooser;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package io.xpipe.extension.fxcomps.impl;
|
||||
|
||||
import io.xpipe.core.impl.LocalStore;
|
||||
import io.xpipe.core.store.FileSystemStore;
|
||||
import io.xpipe.extension.DataStoreProviders;
|
||||
import io.xpipe.extension.I18n;
|
||||
import io.xpipe.extension.fxcomps.SimpleComp;
|
||||
import io.xpipe.extension.util.CustomComboBoxBuilder;
|
||||
import io.xpipe.extension.util.XPipeDaemon;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.Region;
|
||||
|
||||
public class FileSystemStoreChoiceComp extends SimpleComp {
|
||||
|
||||
private final Property<FileSystemStore> selected;
|
||||
|
||||
public FileSystemStoreChoiceComp(Property<FileSystemStore> selected) {
|
||||
this.selected = selected;
|
||||
}
|
||||
|
||||
private static String getName(FileSystemStore store) {
|
||||
var name = XPipeDaemon.getInstance().getNamedStores().stream()
|
||||
.filter(e -> e.equals(store))
|
||||
.findAny()
|
||||
.map(e -> XPipeDaemon.getInstance().getStoreName(e).orElse("?"))
|
||||
.orElse(I18n.get("localMachine"));
|
||||
return name;
|
||||
}
|
||||
|
||||
private Region createGraphic(FileSystemStore s) {
|
||||
var provider = DataStoreProviders.byStore(s);
|
||||
var img = new PrettyImageComp(new SimpleStringProperty(provider.getDisplayIconFileName()), 16, 16);
|
||||
return new Label(getName(s), img.createRegion());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Region createSimple() {
|
||||
var comboBox = new CustomComboBoxBuilder<>(selected, this::createGraphic, null, v -> true);
|
||||
comboBox.addFilter((v, s) -> getName(v).toLowerCase().contains(s));
|
||||
comboBox.add(new LocalStore());
|
||||
XPipeDaemon.getInstance().getNamedStores().stream()
|
||||
.filter(e -> e instanceof FileSystemStore)
|
||||
.map(e -> (FileSystemStore) e)
|
||||
.forEach(comboBox::add);
|
||||
ComboBox<Node> cb = comboBox.build();
|
||||
cb.getStyleClass().add("choice-comp");
|
||||
return cb;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package io.xpipe.extension.fxcomps.impl;
|
||||
|
||||
import com.jfoenix.controls.JFXButton;
|
||||
import io.xpipe.extension.fxcomps.Comp;
|
||||
import io.xpipe.extension.fxcomps.CompStructure;
|
||||
import io.xpipe.extension.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.extension.fxcomps.util.PlatformThread;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.css.Size;
|
||||
import javafx.css.SizeUnits;
|
||||
import org.kordamp.ikonli.javafx.FontIcon;
|
||||
|
||||
public class IconButtonComp extends Comp<CompStructure<JFXButton>> {
|
||||
|
||||
private final ObservableValue<String> icon;
|
||||
private final Runnable listener;
|
||||
|
||||
public IconButtonComp(String defaultVal) {
|
||||
this(new SimpleObjectProperty<>(defaultVal), null);
|
||||
}
|
||||
|
||||
public IconButtonComp(String defaultVal, Runnable listener) {
|
||||
this(new SimpleObjectProperty<>(defaultVal), listener);
|
||||
}
|
||||
|
||||
public IconButtonComp(ObservableValue<String> icon, Runnable listener) {
|
||||
this.icon = PlatformThread.sync(icon);
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompStructure<JFXButton> createBase() {
|
||||
var button = new JFXButton();
|
||||
|
||||
var fi = new FontIcon(icon.getValue());
|
||||
icon.addListener((c, o, n) -> {
|
||||
fi.setIconLiteral(n);
|
||||
});
|
||||
fi.setIconSize((int) new Size(fi.getFont().getSize(), SizeUnits.PT).pixels());
|
||||
button.fontProperty().addListener((c, o, n) -> {
|
||||
fi.setIconSize((int) new Size(n.getSize(), SizeUnits.PT).pixels());
|
||||
});
|
||||
fi.iconColorProperty().bind(button.textFillProperty());
|
||||
button.setGraphic(fi);
|
||||
button.setOnAction(e -> {
|
||||
if (listener != null) {
|
||||
listener.run();
|
||||
}
|
||||
});
|
||||
button.getStyleClass().add("icon-button-comp");
|
||||
return new SimpleCompStructure<>(button);
|
||||
}
|
||||
}
|
|
@ -15,7 +15,7 @@ public class DaemonExtensionTest extends ExtensionTest {
|
|||
}
|
||||
|
||||
public static DataSource getSource(String type, String file) {
|
||||
return DataSource.create(null, type, getResource(file));
|
||||
return DataSource.create(null, type, getResourceStore(file));
|
||||
}
|
||||
|
||||
public static DataSource getSource(io.xpipe.core.source.DataSource<?> source) {
|
||||
|
|
|
@ -9,8 +9,18 @@ import java.nio.file.Path;
|
|||
public class ExtensionTest {
|
||||
|
||||
@SneakyThrows
|
||||
public static DataStore getResource(String name) {
|
||||
var url = DaemonExtensionTest.class.getClassLoader().getResource(name);
|
||||
public static Path getResourcePath(Class<?> c, String name) {
|
||||
var url = c.getResource(name);
|
||||
if (url == null) {
|
||||
throw new IllegalArgumentException(String.format("File %s does not exist", name));
|
||||
}
|
||||
var file = Path.of(url.toURI());
|
||||
return file;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static DataStore getResourceStore(String name) {
|
||||
var url = ExtensionTest.class.getClassLoader().getResource(name);
|
||||
if (url == null) {
|
||||
throw new IllegalArgumentException(String.format("File %s does not exist", name));
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue