chore: improve rm -rf

This commit is contained in:
hstyi
2025-07-04 15:27:09 +08:00
committed by hstyi
parent 1c90fb4e18
commit 919c06779d
5 changed files with 88 additions and 50 deletions

View File

@@ -0,0 +1,34 @@
package app.termora.transfer
import org.apache.sshd.sftp.client.fs.SftpFileSystem
import org.apache.sshd.sftp.client.fs.SftpPath
import kotlin.math.max
class CommandTransfer(
parentId: String,
path: SftpPath,
isDirectory: Boolean,
private val size: Long,
val command: String,
) : AbstractTransfer(parentId, path, path, isDirectory) {
private var executed = false
override suspend fun transfer(bufferSize: Int): Long {
if (executed) return 0
val fs = source().fileSystem as SftpFileSystem
fs.session.executeRemoteCommand(command)
executed = true
return this.size()
}
override fun scanning(): Boolean {
return false
}
override fun size(): Long {
return max(size, 1)
}
}

View File

@@ -11,6 +11,7 @@ import kotlinx.coroutines.swing.Swing
import kotlinx.coroutines.withContext
import org.apache.commons.lang3.StringUtils
import org.apache.commons.lang3.time.DateFormatUtils
import org.apache.sshd.sftp.client.fs.SftpPath
import org.slf4j.LoggerFactory
import java.awt.Component
import java.awt.Dimension
@@ -31,6 +32,7 @@ import kotlin.collections.ArrayDeque
import kotlin.collections.List
import kotlin.collections.Set
import kotlin.collections.isNotEmpty
import kotlin.io.path.absolutePathString
import kotlin.io.path.exists
import kotlin.io.path.name
import kotlin.io.path.pathString
@@ -267,8 +269,8 @@ class DefaultInternalTransferManager(
val isDirectory = pair.second.isDirectory
val path = pair.first
if (isDirectory.not()) {
val transfer = createTransfer(path, workdir.resolve(path.name), false, StringUtils.EMPTY, mode, action)
if (isDirectory.not() || mode == TransferMode.Rmrf) {
val transfer = createTransfer(path, workdir.resolve(path.name), isDirectory, StringUtils.EMPTY, mode, action)
return if (transferManager.addTransfer(transfer)) FileVisitResult.CONTINUE else FileVisitResult.TERMINATE
}
@@ -363,39 +365,49 @@ class DefaultInternalTransferManager(
action:TransferAction,
permissions: Set<PosixFilePermission>? = null
): Transfer {
if (mode == TransferMode.Delete) {
return DeleteTransfer(
parentId,
source,
isDirectory,
if (isDirectory) 1 else Files.size(source)
)
} else if (mode == TransferMode.ChangePermission) {
if (permissions == null) throw IllegalStateException()
return ChangePermissionTransfer(
parentId,
target,
isDirectory = isDirectory,
permissions = permissions,
size = if (isDirectory) 1 else Files.size(target)
)
}
if (isDirectory) {
return DirectoryTransfer(
when {
mode == TransferMode.Delete -> {
return DeleteTransfer(
parentId,
source,
isDirectory,
if (isDirectory) 1 else Files.size(source)
)
}
mode == TransferMode.Rmrf -> {
return CommandTransfer(
parentId,
source as SftpPath,
isDirectory,
if (isDirectory) 1 else Files.size(source),
"rm -rf ${source.absolutePathString()}",
)
}
mode == TransferMode.ChangePermission -> {
if (permissions == null) throw IllegalStateException()
return ChangePermissionTransfer(
parentId,
target,
isDirectory = isDirectory,
permissions = permissions,
size = if (isDirectory) 1 else Files.size(target)
)
}
isDirectory -> {
return DirectoryTransfer(
parentId = parentId,
source = source,
target = target,
)
}
else -> return FileTransfer(
parentId = parentId,
source = source,
target = target,
action = action,
size = Files.size(source)
)
}
return FileTransfer(
parentId = parentId,
source = source,
target = target,
action = action,
size = Files.size(source)
)
}

View File

@@ -9,6 +9,7 @@ interface InternalTransferManager {
Delete,
Transfer,
ChangePermission,
Rmrf,
}
/**

View File

@@ -77,13 +77,15 @@ class TransferTreeTableNode(transfer: Transfer) : DefaultMutableTreeTableNode(tr
private fun formatPath(path: Path, target: Boolean): String {
if (target) {
if (transfer is DeleteTransfer) {
return I18n.getString("termora.transport.sftp.status.deleting")
} else if (transfer is ChangePermissionTransfer) {
val permissions = (transfer as ChangePermissionTransfer).permissions
// @formatter:off
return "${I18n.getString("termora.transport.table.permissions")} -> ${PosixFilePermissions.toString(permissions)}"
// @formatter:on
when (transfer) {
is DeleteTransfer -> return I18n.getString("termora.transport.sftp.status.deleting")
is CommandTransfer -> return (transfer as CommandTransfer).command
is ChangePermissionTransfer -> {
val permissions = (transfer as ChangePermissionTransfer).permissions
// @formatter:off
return "${I18n.getString("termora.transport.table.permissions")} -> ${PosixFilePermissions.toString(permissions)}"
// @formatter:on
}
}
}
@@ -95,7 +97,7 @@ class TransferTreeTableNode(transfer: Transfer) : DefaultMutableTreeTableNode(tr
}
private fun formatStatus(state: State): String {
if (transfer is DeleteTransfer && state == State.Processing) {
if ((transfer is DeleteTransfer || transfer is CommandTransfer) && state == State.Processing) {
return I18n.getString("termora.transport.sftp.status.deleting")
}

View File

@@ -18,7 +18,6 @@ import org.apache.commons.lang3.ArrayUtils
import org.apache.commons.lang3.StringUtils
import org.apache.commons.lang3.exception.ExceptionUtils
import org.apache.commons.lang3.time.DateFormatUtils
import org.apache.sshd.sftp.client.fs.SftpFileSystem
import org.apache.sshd.sftp.client.fs.WithFileAttributes
import org.jdesktop.swingx.JXBusyLabel
import org.jdesktop.swingx.JXPanel
@@ -34,7 +33,6 @@ import java.awt.event.*
import java.beans.PropertyChangeEvent
import java.beans.PropertyChangeListener
import java.io.File
import java.io.OutputStream
import java.nio.file.FileSystem
import java.nio.file.FileSystems
import java.nio.file.Files
@@ -1023,16 +1021,7 @@ class TransportPanel(
val target = source.parent.resolve(e.source.toString())
processPath(e.source.toString()) { source.moveTo(target) }
} else if (actionCommand == TransportPopupMenu.ActionCommand.Rmrf) {
processPath(StringUtils.EMPTY) {
val session = (_fileSystem as SftpFileSystem).clientSession
for (path in files.map { it.first }) {
session.executeRemoteCommand(
"rm -rf '${path.absolutePathString()}'",
OutputStream.nullOutputStream(),
Charsets.UTF_8
)
}
}
transferManager.addTransfer(files, InternalTransferManager.TransferMode.Rmrf)
} else if (actionCommand == TransportPopupMenu.ActionCommand.ChangePermissions) {
val c = e.source as TransportPopupMenu.ChangePermission
val path = files.first().first