mirror of
https://github.com/xpipe-io/xpipe.git
synced 2026-05-19 05:45:58 -04:00
Rework compress actions
This commit is contained in:
@@ -22,6 +22,9 @@ public abstract class BrowserAction extends StoreAction<FileSystemStore> {
|
||||
@JsonIgnore
|
||||
protected BrowserFileSystemTabModel model;
|
||||
|
||||
@JsonIgnore
|
||||
private List<BrowserEntry> entries;
|
||||
|
||||
@Override
|
||||
protected boolean beforeExecute() throws Exception {
|
||||
AppLayoutModel.get().selectBrowser();
|
||||
@@ -67,7 +70,11 @@ public abstract class BrowserAction extends StoreAction<FileSystemStore> {
|
||||
}
|
||||
|
||||
protected List<BrowserEntry> getEntries() {
|
||||
return files.stream()
|
||||
if (entries != null) {
|
||||
return entries;
|
||||
}
|
||||
|
||||
entries = files.stream()
|
||||
.map(filePath -> {
|
||||
var be = model.getFileList().getAll().getValue().stream()
|
||||
.filter(browserEntry ->
|
||||
@@ -81,6 +88,7 @@ public abstract class BrowserAction extends StoreAction<FileSystemStore> {
|
||||
})
|
||||
.filter(browserEntry -> browserEntry != null)
|
||||
.toList();
|
||||
return entries;
|
||||
}
|
||||
|
||||
public abstract static class BrowserActionBuilder<C extends BrowserAction, B extends BrowserActionBuilder<C, B>>
|
||||
@@ -92,6 +100,7 @@ public abstract class BrowserAction extends StoreAction<FileSystemStore> {
|
||||
files(entries.stream()
|
||||
.map(browserEntry -> browserEntry.getRawFileEntry().getPath())
|
||||
.toList());
|
||||
entries(entries);
|
||||
}
|
||||
|
||||
public void initFiles(BrowserFileSystemTabModel model, List<FilePath> entries) {
|
||||
|
||||
@@ -451,41 +451,6 @@ public final class BrowserFileSystemTabModel extends BrowserStoreSessionTab<File
|
||||
});
|
||||
}
|
||||
|
||||
public void runCommandAsync(CommandBuilder command, boolean refresh) {
|
||||
ThreadHelper.runFailableAsync(() -> {
|
||||
BooleanScope.executeExclusive(busy, () -> {
|
||||
if (getCurrentDirectory() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
fileSystem
|
||||
.getShell()
|
||||
.orElseThrow()
|
||||
.command(command)
|
||||
.withWorkingDirectory(getCurrentDirectory().getPath())
|
||||
.execute();
|
||||
if (refresh) {
|
||||
refreshSync();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public void runAsync(FailableRunnable<Exception> r, boolean refresh) {
|
||||
ThreadHelper.runFailableAsync(() -> {
|
||||
BooleanScope.executeExclusive(busy, () -> {
|
||||
if (getCurrentDirectory() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
r.run();
|
||||
if (refresh) {
|
||||
refreshSync();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public boolean isClosed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package io.xpipe.app.browser.menu.impl.compress;
|
||||
|
||||
import io.xpipe.app.action.AbstractAction;
|
||||
import io.xpipe.app.browser.action.BrowserActionProvider;
|
||||
import io.xpipe.app.browser.file.BrowserEntry;
|
||||
import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
|
||||
import io.xpipe.app.browser.icon.BrowserIconFileType;
|
||||
@@ -38,28 +40,12 @@ public class BaseUntarMenuProvider implements BrowserApplicationPathMenuProvider
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
model.runAsync(
|
||||
() -> {
|
||||
ShellControl sc = model.getFileSystem().getShell().orElseThrow();
|
||||
for (BrowserEntry entry : entries) {
|
||||
var target = getTarget(entry.getRawFileEntry().getPath());
|
||||
var c = CommandBuilder.of().add("tar");
|
||||
if (toDirectory) {
|
||||
c.add("-C").addFile(target);
|
||||
}
|
||||
c.add("-x").addIf(gz, "-z").add("-f");
|
||||
c.addFile(entry.getRawFileEntry().getPath());
|
||||
if (toDirectory) {
|
||||
model.getFileSystem().mkdirs(target);
|
||||
}
|
||||
sc.command(c)
|
||||
.withWorkingDirectory(
|
||||
model.getCurrentDirectory().getPath())
|
||||
.execute();
|
||||
}
|
||||
},
|
||||
true);
|
||||
public AbstractAction createAction(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
var builder = UntarActionProvider.Action.builder();
|
||||
builder.initEntries(model, entries);
|
||||
builder.gz(gz);
|
||||
builder.toDirectory(toDirectory);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.xpipe.app.browser.menu.impl.compress;
|
||||
|
||||
import io.xpipe.app.action.AbstractAction;
|
||||
import io.xpipe.app.browser.file.BrowserEntry;
|
||||
import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
|
||||
import io.xpipe.app.browser.icon.BrowserIconFileType;
|
||||
@@ -36,23 +37,12 @@ public abstract class BaseUnzipUnixMenuProvider implements BrowserMenuLeafProvid
|
||||
return "unzip";
|
||||
}
|
||||
|
||||
public void execute(BrowserFileSystemTabModel model, List<BrowserEntry> entries) throws Exception {
|
||||
ShellControl sc = model.getFileSystem().getShell().orElseThrow();
|
||||
for (BrowserEntry entry : entries) {
|
||||
var command = CommandBuilder.of()
|
||||
.add("unzip", "-o")
|
||||
.addFile(entry.getRawFileEntry().getPath());
|
||||
if (toDirectory) {
|
||||
command.add("-d").addFile(getTarget(entry.getRawFileEntry().getPath()));
|
||||
}
|
||||
try (var cc = sc.command(command)
|
||||
.withWorkingDirectory(model.getCurrentDirectory().getPath())
|
||||
.start()) {
|
||||
cc.discardOrThrow();
|
||||
}
|
||||
}
|
||||
|
||||
model.refreshSync();
|
||||
@Override
|
||||
public AbstractAction createAction(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
var builder = UnzipActionProvider.Action.builder();
|
||||
builder.initEntries(model, entries);
|
||||
builder.toDirectory(toDirectory);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -65,14 +55,10 @@ public abstract class BaseUnzipUnixMenuProvider implements BrowserMenuLeafProvid
|
||||
var sep = model.getFileSystem().getShell().orElseThrow().getOsType().getFileSystemSeparator();
|
||||
var dir = entries.size() > 1
|
||||
? "[...]"
|
||||
: getTarget(entries.getFirst().getRawFileEntry().getPath()).getFileName() + sep;
|
||||
: UnzipActionProvider.getTarget(entries.getFirst().getRawFileEntry().getPath()).getFileName() + sep;
|
||||
return toDirectory ? AppI18n.observable("unzipDirectory", dir) : AppI18n.observable("unzipHere");
|
||||
}
|
||||
|
||||
private FilePath getTarget(FilePath name) {
|
||||
return FilePath.of(name.toString().replaceAll("\\.zip$", ""));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
return entries.stream()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.xpipe.app.browser.menu.impl.compress;
|
||||
|
||||
import io.xpipe.app.action.AbstractAction;
|
||||
import io.xpipe.app.browser.file.BrowserEntry;
|
||||
import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
|
||||
import io.xpipe.app.browser.icon.BrowserIconFileType;
|
||||
@@ -8,11 +9,7 @@ import io.xpipe.app.browser.menu.BrowserMenuCategory;
|
||||
import io.xpipe.app.browser.menu.BrowserMenuLeafProvider;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.util.LabelGraphic;
|
||||
import io.xpipe.core.process.CommandBuilder;
|
||||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.process.ShellControl;
|
||||
import io.xpipe.core.process.ShellDialects;
|
||||
import io.xpipe.core.store.FilePath;
|
||||
|
||||
import javafx.beans.value.ObservableValue;
|
||||
|
||||
@@ -31,38 +28,6 @@ public abstract class BaseUnzipWindowsActionProvider implements BrowserMenuLeafP
|
||||
return new LabelGraphic.CompGraphic(BrowserIcons.createContextMenuIcon(BrowserIconFileType.byId("zip")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
model.runAsync(
|
||||
() -> {
|
||||
var sc = model.getFileSystem().getShell().orElseThrow();
|
||||
if (ShellDialects.isPowershell(sc)) {
|
||||
for (BrowserEntry entry : entries) {
|
||||
runCommand(sc, model, entry);
|
||||
}
|
||||
} else {
|
||||
try (var sub = sc.subShell(ShellDialects.POWERSHELL)) {
|
||||
for (BrowserEntry entry : entries) {
|
||||
runCommand(sub, model, entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
private void runCommand(ShellControl sc, BrowserFileSystemTabModel model, BrowserEntry entry) throws Exception {
|
||||
var command = CommandBuilder.of().add("Expand-Archive", "-Force");
|
||||
if (toDirectory) {
|
||||
var target = getTarget(entry.getRawFileEntry().getPath());
|
||||
command.add("-DestinationPath").addFile(target);
|
||||
}
|
||||
command.add("-Path").addFile(entry.getRawFileEntry().getPath());
|
||||
sc.command(command)
|
||||
.withWorkingDirectory(model.getCurrentDirectory().getPath())
|
||||
.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BrowserMenuCategory getCategory() {
|
||||
return BrowserMenuCategory.CUSTOM;
|
||||
@@ -73,12 +38,16 @@ public abstract class BaseUnzipWindowsActionProvider implements BrowserMenuLeafP
|
||||
var sep = model.getFileSystem().getShell().orElseThrow().getOsType().getFileSystemSeparator();
|
||||
var dir = entries.size() > 1
|
||||
? "[...]"
|
||||
: getTarget(entries.getFirst().getRawFileEntry().getPath()).getFileName() + sep;
|
||||
: UnzipActionProvider.getTarget(entries.getFirst().getRawFileEntry().getPath()).getFileName() + sep;
|
||||
return toDirectory ? AppI18n.observable("unzipDirectory", dir) : AppI18n.observable("unzipHere");
|
||||
}
|
||||
|
||||
private FilePath getTarget(FilePath name) {
|
||||
return FilePath.of(name.toString().replaceAll("\\.zip$", ""));
|
||||
@Override
|
||||
public AbstractAction createAction(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
var builder = UnzipActionProvider.Action.builder();
|
||||
builder.initEntries(model, entries);
|
||||
builder.toDirectory(toDirectory);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -10,18 +10,13 @@ import io.xpipe.app.comp.base.ModalOverlay;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.util.CommandSupport;
|
||||
import io.xpipe.app.util.LabelGraphic;
|
||||
import io.xpipe.core.process.CommandBuilder;
|
||||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.process.ShellDialects;
|
||||
import io.xpipe.core.store.FileKind;
|
||||
import io.xpipe.core.store.FilePath;
|
||||
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.control.TextField;
|
||||
|
||||
import org.kordamp.ikonli.javafx.FontIcon;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class CompressMenuProvider implements BrowserMenuBranchProvider {
|
||||
@@ -39,20 +34,7 @@ public abstract class CompressMenuProvider implements BrowserMenuBranchProvider
|
||||
var foundTar = CommandSupport.findProgram(sc, "tar");
|
||||
model.getCache().getInstalledApplications().put("tar", foundTar.isPresent());
|
||||
|
||||
if (sc.getOsType() == OsType.WINDOWS) {
|
||||
var found = CommandSupport.findProgram(sc, "7z");
|
||||
if (found.isPresent()) {
|
||||
model.getCache().getMultiPurposeCache().put("7zExecutable", "7z");
|
||||
return;
|
||||
}
|
||||
|
||||
var pf = sc.command(sc.getShellDialect().getPrintEnvironmentVariableCommand("ProgramFiles"))
|
||||
.readStdoutOrThrow();
|
||||
var loc = FilePath.of(pf).join("7-Zip", "7z.exe").toWindows();
|
||||
if (model.getFileSystem().fileExists(loc)) {
|
||||
model.getCache().getMultiPurposeCache().put("7zExecutable", loc);
|
||||
}
|
||||
} else {
|
||||
if (sc.getOsType() != OsType.WINDOWS) {
|
||||
var found = CommandSupport.findProgram(sc, "zip");
|
||||
model.getCache().getInstalledApplications().put("zip", found.isPresent());
|
||||
}
|
||||
@@ -75,7 +57,7 @@ public abstract class CompressMenuProvider implements BrowserMenuBranchProvider
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
var ext = List.of("zip", "tar", "tar.gz", "tgz", "7z", "rar", "xar");
|
||||
var ext = List.of("zip", "tar", "tar.gz", "tgz", "rar", "xar");
|
||||
if (entries.stream().anyMatch(browserEntry -> ext.stream().anyMatch(s -> browserEntry
|
||||
.getRawFileEntry()
|
||||
.getPath()
|
||||
@@ -94,9 +76,7 @@ public abstract class CompressMenuProvider implements BrowserMenuBranchProvider
|
||||
public List<BrowserMenuLeafProvider> getBranchingActions(
|
||||
BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
return List.of(
|
||||
new Windows7ZActionProvider(),
|
||||
new WindowsZipActionProvider(),
|
||||
new UnixZipActionProvider(),
|
||||
new ZipActionProvider(),
|
||||
new TarBasedActionProvider(false) {
|
||||
@Override
|
||||
protected String getExtension() {
|
||||
@@ -150,141 +130,21 @@ public abstract class CompressMenuProvider implements BrowserMenuBranchProvider
|
||||
protected abstract String getExtension();
|
||||
}
|
||||
|
||||
private class WindowsZipActionProvider extends LeafProvider {
|
||||
private class ZipActionProvider extends LeafProvider {
|
||||
|
||||
@Override
|
||||
protected void create(String fileName, BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
var base = model.getCurrentDirectory().getPath();
|
||||
var target = base.join(fileName);
|
||||
var command = CommandBuilder.of()
|
||||
.add("Compress-Archive", "-Force", "-DestinationPath")
|
||||
.addFile(target)
|
||||
.add("-Path");
|
||||
for (int i = 0; i < entries.size(); i++) {
|
||||
var rel = entries.get(i).getRawFileEntry().getPath().relativize(base);
|
||||
if (directory) {
|
||||
command.addQuoted(rel.toDirectory().toWindows() + "*");
|
||||
} else {
|
||||
command.addFile(rel.toWindows());
|
||||
}
|
||||
if (i != entries.size() - 1) {
|
||||
command.add(",");
|
||||
}
|
||||
}
|
||||
|
||||
model.runAsync(
|
||||
() -> {
|
||||
var sc = model.getFileSystem().getShell().orElseThrow();
|
||||
if (ShellDialects.isPowershell(sc)) {
|
||||
sc.command(command).withWorkingDirectory(base).execute();
|
||||
} else {
|
||||
try (var sub = sc.subShell(ShellDialects.POWERSHELL)) {
|
||||
sub.command(command).withWorkingDirectory(base).execute();
|
||||
}
|
||||
}
|
||||
},
|
||||
true);
|
||||
var builder = io.xpipe.app.browser.menu.impl.compress.ZipActionProvider.Action.builder();
|
||||
builder.initEntries(model, entries);
|
||||
builder.target(model.getCurrentDirectory().getPath().join(fileName));
|
||||
builder.directoryContentOnly(directory);
|
||||
builder.build().executeAsync();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getExtension() {
|
||||
return "zip";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
return model.getFileSystem().getShell().orElseThrow().getOsType() == OsType.WINDOWS;
|
||||
}
|
||||
}
|
||||
|
||||
private class UnixZipActionProvider extends LeafProvider {
|
||||
|
||||
@Override
|
||||
protected void create(String fileName, BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
var base = model.getCurrentDirectory().getPath();
|
||||
var target = base.join(fileName);
|
||||
var command = CommandBuilder.of().add("zip", "-r", "-");
|
||||
for (BrowserEntry entry : entries) {
|
||||
var rel = entry.getRawFileEntry().getPath().relativize(base).toUnix();
|
||||
if (directory) {
|
||||
command.add(".");
|
||||
} else {
|
||||
command.addFile(rel);
|
||||
}
|
||||
}
|
||||
command.add(">").addFile(target);
|
||||
|
||||
if (directory) {
|
||||
model.runAsync(
|
||||
() -> {
|
||||
var sc = model.getFileSystem().getShell().orElseThrow();
|
||||
sc.command(command)
|
||||
.withWorkingDirectory(
|
||||
entries.getFirst().getRawFileEntry().getPath())
|
||||
.execute();
|
||||
},
|
||||
true);
|
||||
} else {
|
||||
model.runCommandAsync(command, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getExtension() {
|
||||
return "zip";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
return model.getCache().getInstalledApplications().get("zip");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
return model.getFileSystem().getShell().orElseThrow().getOsType() != OsType.WINDOWS;
|
||||
}
|
||||
}
|
||||
|
||||
private class Windows7ZActionProvider extends LeafProvider {
|
||||
|
||||
@Override
|
||||
protected void create(String fileName, BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
var base = model.getCurrentDirectory().getPath();
|
||||
var target = base.join(fileName);
|
||||
var command = CommandBuilder.of()
|
||||
.addFile(model.getCache()
|
||||
.getMultiPurposeCache()
|
||||
.get("7zExecutable")
|
||||
.toString())
|
||||
.add("a")
|
||||
.add("-r")
|
||||
.addFile(target);
|
||||
for (BrowserEntry entry : entries) {
|
||||
var rel = entry.getRawFileEntry().getPath().relativize(base);
|
||||
if (directory) {
|
||||
command.addQuoted(".\\" + rel.toDirectory().toWindows() + "*");
|
||||
} else {
|
||||
command.addFile(rel.toWindows());
|
||||
}
|
||||
}
|
||||
|
||||
model.runCommandAsync(command, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getExtension() {
|
||||
return "7z";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
return model.getCache().getMultiPurposeCache().containsKey("7zExecutable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
return model.getFileSystem().getShell().orElseThrow().getOsType() == OsType.WINDOWS;
|
||||
}
|
||||
}
|
||||
|
||||
private abstract class TarBasedActionProvider extends LeafProvider {
|
||||
@@ -297,32 +157,12 @@ public abstract class CompressMenuProvider implements BrowserMenuBranchProvider
|
||||
|
||||
@Override
|
||||
protected void create(String fileName, BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
var tar = CommandBuilder.of()
|
||||
.add("tar", "-c")
|
||||
.addIf(gz, "-z")
|
||||
.add("-f")
|
||||
.addFile(fileName);
|
||||
var base = model.getCurrentDirectory().getPath();
|
||||
|
||||
if (directory) {
|
||||
var dir = entries.getFirst().getRawFileEntry().getPath();
|
||||
// Fix for bsd find, remove /
|
||||
var command = CommandBuilder.of()
|
||||
.add("find")
|
||||
.addFile(dir.removeTrailingSlash().toUnix())
|
||||
.add("|", "sed")
|
||||
.addLiteral("s,^" + dir.toDirectory().toUnix() + "*,,")
|
||||
.add("|");
|
||||
command.add(tar).add("-C").addFile(dir.toDirectory().toUnix()).add("-T", "-");
|
||||
model.runCommandAsync(command, true);
|
||||
} else {
|
||||
var command = CommandBuilder.of().add(tar);
|
||||
for (BrowserEntry entry : entries) {
|
||||
var rel = entry.getRawFileEntry().getPath().relativize(base);
|
||||
command.addFile(rel);
|
||||
}
|
||||
model.runCommandAsync(command, true);
|
||||
}
|
||||
var builder = TarActionProvider.Action.builder();
|
||||
builder.initEntries(model, entries);
|
||||
builder.target(model.getCurrentDirectory().getPath().join(fileName));
|
||||
builder.directoryContentOnly(directory);
|
||||
builder.gz(gz);
|
||||
builder.build().executeAsync();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
package io.xpipe.app.browser.menu.impl.compress;
|
||||
|
||||
import io.xpipe.app.browser.action.BrowserAction;
|
||||
import io.xpipe.app.browser.action.BrowserActionProvider;
|
||||
import io.xpipe.app.browser.file.BrowserEntry;
|
||||
import io.xpipe.core.process.CommandBuilder;
|
||||
import io.xpipe.core.store.FilePath;
|
||||
import lombok.NonNull;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
public class TarActionProvider implements BrowserActionProvider {
|
||||
|
||||
@Jacksonized
|
||||
@SuperBuilder
|
||||
public static class Action extends BrowserAction {
|
||||
|
||||
@NonNull
|
||||
private final FilePath target;
|
||||
|
||||
private final boolean directoryContentOnly;
|
||||
|
||||
private final boolean gz;
|
||||
|
||||
@Override
|
||||
public boolean isMutation() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeImpl() throws Exception {
|
||||
var sc = model.getFileSystem().getShell().orElseThrow();
|
||||
var tar = CommandBuilder.of()
|
||||
.add("tar", "-c")
|
||||
.addIf(gz, "-z")
|
||||
.add("-f")
|
||||
.addFile(target);
|
||||
var base = model.getCurrentDirectory().getPath();
|
||||
|
||||
if (directoryContentOnly) {
|
||||
var dir = getEntries().getFirst().getRawFileEntry().getPath();
|
||||
// Fix for bsd find, remove /
|
||||
var command = CommandBuilder.of()
|
||||
.add("find")
|
||||
.addFile(dir.removeTrailingSlash().toUnix())
|
||||
.add("|", "sed")
|
||||
.addLiteral("s,^" + dir.toDirectory().toUnix() + "*,,")
|
||||
.add("|");
|
||||
command.add(tar).add("-C").addFile(dir.toDirectory().toUnix()).add("-T", "-");
|
||||
sc.command(command).execute();
|
||||
} else {
|
||||
var command = CommandBuilder.of().add(tar);
|
||||
for (BrowserEntry entry : getEntries()) {
|
||||
var rel = entry.getRawFileEntry().getPath().relativize(base);
|
||||
command.addFile(rel);
|
||||
}
|
||||
sc.command(command).execute();
|
||||
}
|
||||
model.refreshSync();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "tar";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package io.xpipe.app.browser.menu.impl.compress;
|
||||
|
||||
import io.xpipe.app.browser.action.BrowserAction;
|
||||
import io.xpipe.app.browser.action.BrowserActionProvider;
|
||||
import io.xpipe.app.browser.file.BrowserEntry;
|
||||
import io.xpipe.core.process.CommandBuilder;
|
||||
import io.xpipe.core.process.ShellControl;
|
||||
import io.xpipe.core.store.FileKind;
|
||||
import io.xpipe.core.store.FilePath;
|
||||
import lombok.NonNull;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
public class UntarActionProvider implements BrowserActionProvider {
|
||||
|
||||
@Jacksonized
|
||||
@SuperBuilder
|
||||
public static class Action extends BrowserAction {
|
||||
|
||||
private final boolean gz;
|
||||
private final boolean toDirectory;
|
||||
|
||||
@Override
|
||||
public boolean isMutation() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeImpl() throws Exception {
|
||||
ShellControl sc = model.getFileSystem().getShell().orElseThrow();
|
||||
for (BrowserEntry entry : getEntries()) {
|
||||
var target = getTarget(entry.getRawFileEntry().getPath());
|
||||
var c = CommandBuilder.of().add("tar");
|
||||
if (toDirectory) {
|
||||
c.add("-C").addFile(target);
|
||||
}
|
||||
c.add("-x").addIf(gz, "-z").add("-f");
|
||||
c.addFile(entry.getRawFileEntry().getPath());
|
||||
if (toDirectory) {
|
||||
model.getFileSystem().mkdirs(target);
|
||||
}
|
||||
sc.command(c)
|
||||
.withWorkingDirectory(
|
||||
model.getCurrentDirectory().getPath())
|
||||
.execute();
|
||||
}
|
||||
}
|
||||
|
||||
private FilePath getTarget(FilePath name) {
|
||||
return FilePath.of(name.toString()
|
||||
.replaceAll("\\.tar$", "")
|
||||
.replaceAll("\\.tar.gz$", "")
|
||||
.replaceAll("\\.tgz$", ""));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "untar";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package io.xpipe.app.browser.menu.impl.compress;
|
||||
|
||||
import io.xpipe.app.browser.action.BrowserAction;
|
||||
import io.xpipe.app.browser.action.BrowserActionProvider;
|
||||
import io.xpipe.app.browser.file.BrowserEntry;
|
||||
import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
|
||||
import io.xpipe.core.process.CommandBuilder;
|
||||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.process.ShellControl;
|
||||
import io.xpipe.core.process.ShellDialects;
|
||||
import io.xpipe.core.store.FilePath;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
public class UnzipActionProvider implements BrowserActionProvider {
|
||||
|
||||
public static FilePath getTarget(FilePath name) {
|
||||
return FilePath.of(name.toString().replaceAll("\\.zip$", ""));
|
||||
}
|
||||
|
||||
@Jacksonized
|
||||
@SuperBuilder
|
||||
public static class Action extends BrowserAction {
|
||||
|
||||
private final boolean toDirectory;
|
||||
|
||||
@Override
|
||||
public boolean isMutation() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeImpl() throws Exception {
|
||||
var sc = model.getFileSystem().getShell().orElseThrow();
|
||||
if (sc.getOsType() == OsType.WINDOWS) {
|
||||
if (ShellDialects.isPowershell(sc)) {
|
||||
for (BrowserEntry entry : getEntries()) {
|
||||
runPowershellCommand(sc, model, entry);
|
||||
}
|
||||
} else {
|
||||
try (var sub = sc.subShell(ShellDialects.POWERSHELL)) {
|
||||
for (BrowserEntry entry : getEntries()) {
|
||||
runPowershellCommand(sub, model, entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (BrowserEntry entry : getEntries()) {
|
||||
var command = CommandBuilder.of()
|
||||
.add("unzip", "-o")
|
||||
.addFile(entry.getRawFileEntry().getPath());
|
||||
if (toDirectory) {
|
||||
command.add("-d").addFile(getTarget(entry.getRawFileEntry().getPath()));
|
||||
}
|
||||
try (var cc = sc.command(command)
|
||||
.withWorkingDirectory(model.getCurrentDirectory().getPath())
|
||||
.start()) {
|
||||
cc.discardOrThrow();
|
||||
}
|
||||
}
|
||||
}
|
||||
model.refreshSync();
|
||||
}
|
||||
|
||||
private void runPowershellCommand(ShellControl sc, BrowserFileSystemTabModel model, BrowserEntry entry) throws Exception {
|
||||
var command = CommandBuilder.of().add("Expand-Archive", "-Force");
|
||||
if (toDirectory) {
|
||||
var target = getTarget(entry.getRawFileEntry().getPath());
|
||||
command.add("-DestinationPath").addFile(target);
|
||||
}
|
||||
command.add("-Path").addFile(entry.getRawFileEntry().getPath());
|
||||
sc.command(command)
|
||||
.withWorkingDirectory(model.getCurrentDirectory().getPath())
|
||||
.execute();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "unzip";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package io.xpipe.app.browser.menu.impl.compress;
|
||||
|
||||
import io.xpipe.app.browser.action.BrowserAction;
|
||||
import io.xpipe.app.browser.action.BrowserActionProvider;
|
||||
import io.xpipe.app.browser.file.BrowserEntry;
|
||||
import io.xpipe.core.process.CommandBuilder;
|
||||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.process.ShellDialects;
|
||||
import io.xpipe.core.store.FileKind;
|
||||
import io.xpipe.core.store.FilePath;
|
||||
import lombok.NonNull;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
public class ZipActionProvider implements BrowserActionProvider {
|
||||
|
||||
@Jacksonized
|
||||
@SuperBuilder
|
||||
public static class Action extends BrowserAction {
|
||||
|
||||
@NonNull
|
||||
private final FilePath target;
|
||||
|
||||
private final boolean directoryContentOnly;
|
||||
|
||||
@Override
|
||||
public boolean isMutation() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeImpl() throws Exception {
|
||||
var sc = model.getFileSystem().getShell().orElseThrow();
|
||||
if (sc.getOsType() == OsType.WINDOWS) {
|
||||
var base = model.getCurrentDirectory().getPath();
|
||||
var command = CommandBuilder.of()
|
||||
.add("Compress-Archive", "-Force", "-DestinationPath")
|
||||
.addFile(target)
|
||||
.add("-Path");
|
||||
for (int i = 0; i < getEntries().size(); i++) {
|
||||
var rel = getEntries().get(i).getRawFileEntry().getPath().relativize(base);
|
||||
if (getEntries().get(i).getRawFileEntry().getKind() == FileKind.DIRECTORY && directoryContentOnly) {
|
||||
command.addQuoted(rel.toDirectory().toWindows() + "*");
|
||||
} else {
|
||||
command.addFile(rel.toWindows());
|
||||
}
|
||||
if (i != getEntries().size() - 1) {
|
||||
command.add(",");
|
||||
}
|
||||
}
|
||||
|
||||
if (ShellDialects.isPowershell(sc)) {
|
||||
sc.command(command).withWorkingDirectory(base).execute();
|
||||
} else {
|
||||
try (var sub = sc.subShell(ShellDialects.POWERSHELL)) {
|
||||
sub.command(command).withWorkingDirectory(base).execute();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var command = CommandBuilder.of().add("zip", "-r", "-");
|
||||
for (BrowserEntry entry : getEntries()) {
|
||||
var base = target.getParent();
|
||||
var rel = entry.getRawFileEntry().getPath().relativize(base).toUnix();
|
||||
if (entry.getRawFileEntry().getKind() == FileKind.DIRECTORY && directoryContentOnly) {
|
||||
command.add(".");
|
||||
} else {
|
||||
command.addFile(rel);
|
||||
}
|
||||
}
|
||||
command.add(">").addFile(target);
|
||||
|
||||
if (directoryContentOnly) {
|
||||
sc.command(command)
|
||||
.withWorkingDirectory(
|
||||
getEntries().getFirst().getRawFileEntry().getPath())
|
||||
.execute();
|
||||
} else {
|
||||
sc.command(command).execute();
|
||||
}
|
||||
}
|
||||
model.refreshSync();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "zip";
|
||||
}
|
||||
}
|
||||
@@ -157,6 +157,10 @@ open module io.xpipe.app {
|
||||
DeleteMenuProvider,
|
||||
ChownActionProvider,
|
||||
ChmodActionProvider,
|
||||
TarActionProvider,
|
||||
UntarActionProvider,
|
||||
ZipActionProvider,
|
||||
UnzipActionProvider,
|
||||
UnzipHereUnixMenuProvider,
|
||||
UnzipDirectoryUnixMenuProvider,
|
||||
UnzipHereWindowsActionProvider,
|
||||
|
||||
Reference in New Issue
Block a user