diff --git a/.idea/KotlinSceneConfigState.xml b/.idea/KotlinSceneConfigState.xml index f1dea95..72f29d2 100644 --- a/.idea/KotlinSceneConfigState.xml +++ b/.idea/KotlinSceneConfigState.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/src/main/kotlin/xbss/config/AppVersion.kt b/src/main/kotlin/xbss/config/AppVersion.kt index 293ca84..d04d2cd 100644 --- a/src/main/kotlin/xbss/config/AppVersion.kt +++ b/src/main/kotlin/xbss/config/AppVersion.kt @@ -63,10 +63,11 @@ package xbss.config * 0.5.9 -- 2023年10月22日20:50:28 :解决了bug10. * 0.6.0 -- 2023年11月8日13:16:18:终端增加了对按键ESC的支持(Vi模式常用);终端界面支持中文输入。 * 0.6.0.1 -- 2023年11月10日16:45:39:终端界面支持中文输入后有bug,暂时退回。 + * 0.6.1 -- 2023年11月10日21:38:07:创建文件夹失败会给出提示。 * * * */ object AppVersion { - const val VERSION = "0.6.0.1" + const val VERSION = "0.6.1" } \ No newline at end of file diff --git a/src/main/kotlin/xbss/config/ImageIcon.kt b/src/main/kotlin/xbss/config/ImageIcon.kt index ae642a5..3ab0c26 100644 --- a/src/main/kotlin/xbss/config/ImageIcon.kt +++ b/src/main/kotlin/xbss/config/ImageIcon.kt @@ -50,4 +50,5 @@ object ImageIcon { val PASTE16 = Image(Image::class.java.getResourceAsStream("/img/paste16.png")) val DONATE24 = Image(Image::class.java.getResourceAsStream("/img/donate24.png")) val PAY = Image(Image::class.java.getResourceAsStream("/img/pay.png")) + val NEW24 = Image(Image::class.java.getResourceAsStream("/img/new24.png")) } \ No newline at end of file diff --git a/src/main/kotlin/xbss/controller/FileCommandTask.kt b/src/main/kotlin/xbss/controller/FileCommandTask.kt index 1ed3da0..6fad72e 100644 --- a/src/main/kotlin/xbss/controller/FileCommandTask.kt +++ b/src/main/kotlin/xbss/controller/FileCommandTask.kt @@ -98,6 +98,7 @@ class FileCommandTask(private val ssh: SSH,private val mainWindow: MainWindow) { when(type){ FileCommandPane.FileCommandType.DELETE -> mainWindow.treeArea.refreshFatherItem() FileCommandPane.FileCommandType.COPY -> mainWindow.treeArea.refreshItem() + FileCommandPane.FileCommandType.CREATE -> TODO() } mainWindow.writeInfoLog("${javaClass.simpleName}完成") } diff --git a/src/main/kotlin/xbss/ssh/SSH.kt b/src/main/kotlin/xbss/ssh/SSH.kt index 23a1dfb..2e7e2a2 100644 --- a/src/main/kotlin/xbss/ssh/SSH.kt +++ b/src/main/kotlin/xbss/ssh/SSH.kt @@ -159,7 +159,14 @@ open class SSH(val account: Account) { fun releaseChannel(channel: ChannelSftp) { chSftpPool.releaseChannel(channel) } - fun execCommand(command:String):String{ + //todo :释放的有没有问题? https://blog.csdn.net/weixin_43898952/article/details/119967566 + /**执行单个命令的结果,返回exitCode和message + * exitCode为0表示成功,其他值(大部分是1)表示失败 + */ + data class ExecResponse(val exitCode: Int, val message: String) + + // fun execCommand(command:String):String{ + fun execCommand(command: String): ExecResponse { // println("执行命令 $command") val result = StringBuilder() var exitStatus = 0 //退出码 @@ -167,7 +174,7 @@ open class SSH(val account: Account) { execChannel.setCommand(command) execChannel.inputStream = null // 错误信息输出流,用于输出错误的信息,当exitstatus<0的时候 - execChannel.setErrStream(System.err) +// execChannel.setErrStream(System.err) try { // 执行命令,等待执行结果 @@ -175,18 +182,20 @@ open class SSH(val account: Account) { }catch (e:Exception){ println("发生异常$e") isConnectProperty.value = false + execChannel.disconnect() close() - return "" +// return "" + return ExecResponse(1, "") } - // 获取命令执行结果 val inputStream = execChannel.inputStream + val errStream = execChannel.errStream + // 错误信息输出流,用于输出错误的信息,当exitstatus<0的时候 /** * 通过channel获取信息的方式,采用官方Demo代码 */ val tmp = ByteArray(1024) while (true) { -// println("还在循环"+execChannel.isClosed+" "+execChannel.isConnected) while (inputStream.available() > 0) { val i: Int = inputStream.read(tmp, 0, 1024) if (i < 0) { @@ -194,12 +203,20 @@ open class SSH(val account: Account) { } result.append(String(tmp, 0, i)) } + while (errStream.available() > 0) { + val i: Int = errStream.read(tmp, 0, 1024) + if (i < 0) { + break + } + result.append(String(tmp, 0, i)) + } // 从channel获取全部信息之后,channel会自动关闭 if (execChannel.isClosed) { if (inputStream.available() > 0) { continue } - exitStatus = execChannel.exitStatus + exitStatus = execChannel.exitStatus//正常是0 错误是1 + execChannel.disconnect() break } } @@ -256,7 +273,8 @@ open class SSH(val account: Account) { // isConnectProperty.value = false // close() // } - return result.toString() +// return result.toString() + return ExecResponse(exitStatus, result.toString()) } /** diff --git a/src/main/kotlin/xbss/utils/FileCommandPane.kt b/src/main/kotlin/xbss/utils/FileCommandPane.kt index 6051cbf..7f2bb62 100644 --- a/src/main/kotlin/xbss/utils/FileCommandPane.kt +++ b/src/main/kotlin/xbss/utils/FileCommandPane.kt @@ -46,12 +46,13 @@ class FileCommandPane( private lateinit var statusListener: ChangeListener enum class FileCommandType { - COPY, DELETE + COPY, DELETE, CREATE, } init { describe = when (type) { FileCommandType.COPY -> "复制" FileCommandType.DELETE -> "删除" + FileCommandType.CREATE -> "创建" } initView() } @@ -98,6 +99,11 @@ class FileCommandPane( imageView.image = ImageIcon.DELETE24 title = "删除${totalNum}个文件" } + + FileCommandType.CREATE -> { + imageView.image = ImageIcon.NEW24 + title = "创建${totalNum}个$sumTitle" + } } titleHBox = HBox(10.0, imageView, Label(title).apply { style = "-fx-font-size: 13" @@ -147,7 +153,10 @@ class FileCommandPane( HBox(10.0, ImageView(ImageIcon.CLOSE24), Label("${describe}出错!").apply { style = "-fx-font-size:19px" }), Label().apply { textProperty().bind(name.map { "($it)" }) - translateX = 40.0 +// translateX = 40.0 + tooltip = Tooltip(this.text).apply { + style = "-fx-background-color: #FFFACD;-fx-text-fill:black;-fx-font-size: 13" + } }) edArea.translateX = 30.0 centerBox.children.clear() diff --git a/src/main/kotlin/xbss/utils/SystemData.kt b/src/main/kotlin/xbss/utils/SystemData.kt index 8230bc7..6920c4d 100644 --- a/src/main/kotlin/xbss/utils/SystemData.kt +++ b/src/main/kotlin/xbss/utils/SystemData.kt @@ -4,6 +4,7 @@ import javafx.application.Platform import javafx.geometry.Insets import javafx.scene.layout.HBox import xbss.MainAPP +import xbss.config.GlobalLog import xbss.ssh.SSH import java.util.* import kotlin.concurrent.timerTask @@ -70,7 +71,7 @@ class SystemData(private val ssh: SSH):HBox() { //// this.children.add(s) // } } - val gpuNum = ssh.execCommand("nvidia-smi --list-gpus | wc -l").replace("\n", "").toInt() + val gpuNum = ssh.execCommand("nvidia-smi --list-gpus | wc -l").message.replace("\n", "").toInt() // Platform.runLater { // for (i in 0 until gpuNum){ // val messageBar = MessageBar("GPU${i}", MessageBar.Type.GPU) @@ -132,13 +133,16 @@ class SystemData(private val ssh: SSH):HBox() { private fun getTimerTask():TimerTask{ return timerTask { dataList.clear() - val cpuResult = ssh.execCommand("top -b -n 1 | grep \"Cpu(s)\" | awk '{print \$2+\$4 \"%\"}'").replace("\n", "") + val cpuResult = + ssh.execCommand("top -b -n 1 | grep \"Cpu(s)\" | awk '{print \$2+\$4 \"%\"}'").message.replace("\n", "") //28.2% dataList.add(Pair(cpuResult.removeSuffix("%").toDouble(),"")) //7.7G 2.4G //15G 643M //这里有可能是两个单位,需要判断换算 - val memoryResult = ssh.execCommand("free -h | awk 'NR==2{print \$2,\$3}'").replace("\n", "").replace("\r", "").split(" ") + val memoryResult = + ssh.execCommand("free -h | awk 'NR==2{print \$2,\$3}'").message.replace("\n", "").replace("\r", "") + .split(" ") val memoryPer = if (memoryResult[1].last()=='M'){ val value1 = memoryResult[1].removeSuffix("M") compute(value1.toDouble().div(1024).reserveOne(),memoryResult[0].removeSuffix("G")) @@ -148,7 +152,11 @@ class SystemData(private val ssh: SSH):HBox() { // val memoryPer = compute(memoryResult[1].removeSuffix("G"),memoryResult[0].removeSuffix("G")) dataList.add(Pair(memoryPer,"${memoryResult[1]}/${memoryResult[0]}")) - val gpuResult = ssh.execCommand("nvidia-smi --query-gpu=index,memory.used,memory.total --format=csv | tail -n+2").replace(" ","").split("\n") + val gpuResult = + ssh.execCommand("nvidia-smi --query-gpu=index,memory.used,memory.total --format=csv | tail -n+2").message.replace( + " ", + "" + ).split("\n") // 3, 21177 MiB, 24576 MiB for (s in gpuResult){ @@ -161,7 +169,11 @@ class SystemData(private val ssh: SSH):HBox() { } Platform.runLater { for ((index,value) in uiList.withIndex()){ - value.update(dataList[index].first,dataList[index].second) + try { + value.update(dataList[index].first, dataList[index].second) + } catch (e: Exception) { + GlobalLog.writeErrorLog("${e} ${dataList} index是${index}") + } } } } diff --git a/src/main/kotlin/xbss/utils/TreeAreaRightMenu.kt b/src/main/kotlin/xbss/utils/TreeAreaRightMenu.kt index b1f42d6..3714dba 100644 --- a/src/main/kotlin/xbss/utils/TreeAreaRightMenu.kt +++ b/src/main/kotlin/xbss/utils/TreeAreaRightMenu.kt @@ -1,5 +1,8 @@ package xbss.utils +import javafx.beans.property.ReadOnlyStringProperty +import javafx.beans.property.SimpleIntegerProperty +import javafx.beans.property.SimpleStringProperty import javafx.geometry.Pos import javafx.scene.Node import javafx.scene.control.* @@ -13,6 +16,7 @@ import javafx.stage.Stage import xbss.config.FileType import xbss.config.ImageIcon import xbss.config.Setting +import xbss.view.MainWindow import xbss.view.TreeArea import java.io.File @@ -156,8 +160,38 @@ class TreeAreaRightMenu(private val treeArea: TreeArea): ContextMenu() { PopName().apply { textObservable.addListener { _,_,newValue -> if (newValue.isNotEmpty()){ - ssh.execCommand("mkdir "+item!!.path+"/"+newValue) - treeArea.refreshItem() + + val status = SimpleIntegerProperty(0) + val name = SimpleStringProperty("") + treeArea.mainWindow.addMessage( + FileCommandPane( + FileCommandPane.FileCommandType.CREATE, + "创建文件夹", + name, + SimpleIntegerProperty(1), + 1, + status + ) + ) + val result = ssh.execCommand("mkdir " + item!!.path + "/" + newValue) + if (result.exitCode == 0) { + name.value = newValue + status.value = 4 + treeArea.refreshItem() + } else { + name.value = result.message + status.value = 5 + } +// else{ +// treeArea.mainWindow.addMessage(FileCommandPane( +// FileCommandPane.FileCommandType.CREATE, +// "创建文件夹", +// SimpleStringProperty(newValue), +// SimpleIntegerProperty(1), +// 1, +// SimpleIntegerProperty(result.exitCode) +// )) +// } } } start(Stage()) diff --git a/src/main/kotlin/xbss/view/TreeArea.kt b/src/main/kotlin/xbss/view/TreeArea.kt index 9628c63..af860d8 100644 --- a/src/main/kotlin/xbss/view/TreeArea.kt +++ b/src/main/kotlin/xbss/view/TreeArea.kt @@ -24,7 +24,8 @@ import java.io.ByteArrayInputStream * @version 1.0 * @describe */ -class TreeArea(mainWindow: MainWindow,val taskHandler: FileTaskHandler,private var defaultPath:String = "/"): VBox() { +class TreeArea(val mainWindow: MainWindow, val taskHandler: FileTaskHandler, private var defaultPath: String = "/") : + VBox() { val ssh = mainWindow.ssh /** diff --git a/src/main/resources/img/new24.png b/src/main/resources/img/new24.png new file mode 100644 index 0000000..ea07d11 Binary files /dev/null and b/src/main/resources/img/new24.png differ