Skip to content

Commit 5c153c1

Browse files
author
Khôi Tran
committed
Basic download functionality
1 parent 7fe7acc commit 5c153c1

2 files changed

Lines changed: 135 additions & 1 deletion

File tree

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package ch.compile.blitzremote.actions
2+
3+
import ch.compile.blitzremote.BlitzRemote
4+
import ch.compile.blitzremote.model.ConnectionEntry
5+
import com.jcraft.jsch.*
6+
import org.slf4j.LoggerFactory
7+
import java.awt.event.ActionEvent
8+
import java.io.File
9+
import java.util.*
10+
import javax.swing.AbstractAction
11+
import javax.swing.JOptionPane
12+
import kotlin.collections.ArrayList
13+
14+
class DownloadAction(private val connectionEntry: ConnectionEntry) : AbstractAction("Download from remote...") {
15+
companion object {
16+
val LOG = LoggerFactory.getLogger(this::class.java)!!
17+
}
18+
19+
var channelSftp: ChannelSftp = ChannelSftp()
20+
21+
var downloadDir = File(System.getProperty("user.home") + "/Downloads/blitz-remote")
22+
23+
override fun actionPerformed(p0: ActionEvent?) {
24+
val file = JOptionPane.showInputDialog(BlitzRemote.instance, "Please provide a path", "Download from remote...", JOptionPane.QUESTION_MESSAGE, null, null, "./.profile")
25+
LOG.debug("User selected $file")
26+
val jsch = JSch()
27+
jsch.setKnownHosts(System.getProperty("user.home") + "/.ssh/known_hosts")
28+
29+
if (connectionEntry.identity != null) {
30+
try {
31+
val f = connectionEntry.identity
32+
val kp = KeyPair.load(jsch, f)
33+
if (kp.isEncrypted) {
34+
val passphrase = JOptionPane.showInputDialog(BlitzRemote.instance, "Please enter passphrase for $f", "Passphrase needed", JOptionPane.QUESTION_MESSAGE, null, null, "")
35+
if (passphrase is String) {
36+
jsch.addIdentity(f, passphrase)
37+
}
38+
} else {
39+
jsch.addIdentity(f)
40+
}
41+
} catch (e: JSchException) {
42+
System.err.println("Error adding identity: " + connectionEntry.identity)
43+
}
44+
} else {
45+
try {
46+
val f = System.getProperty("user.home") + "/.ssh/id_rsa"
47+
val kp = KeyPair.load(jsch, f)
48+
if (kp.isEncrypted) {
49+
val passphrase = JOptionPane.showInputDialog(BlitzRemote.instance, "Please enter passphrase for $f", "Passphrase needed", JOptionPane.QUESTION_MESSAGE, null, null, "")
50+
if (passphrase is String) {
51+
jsch.addIdentity(f, passphrase)
52+
}
53+
} else {
54+
jsch.addIdentity(f)
55+
}
56+
} catch (e: JSchException) {
57+
System.err.println("Error adding identity: " + System.getProperty("user.home") + "/.ssh/id_rsa")
58+
}
59+
}
60+
61+
val session = jsch.getSession(connectionEntry.username, connectionEntry.hostname, connectionEntry.port)
62+
session.connect()
63+
64+
channelSftp = session.openChannel("sftp") as ChannelSftp
65+
channelSftp.connect()
66+
val list = fileList(file as String)
67+
list.forEach {
68+
download(it)
69+
}
70+
LOG.debug("DONE DOWNLOADING!")
71+
}
72+
73+
private fun fileList(file: String): List<String> {
74+
val list = ArrayList<String>()
75+
val attrs = channelSftp.stat(file)
76+
if (attrs.isDir) {
77+
val fileList = channelSftp.ls(file) as Vector<ChannelSftp.LsEntry>
78+
channelSftp.cd(file)
79+
fileList.filter { !it.filename.startsWith('.') }.forEach {
80+
if (!it.filename.startsWith('.')) {
81+
list.addAll(fileList(it.filename))
82+
}
83+
}
84+
channelSftp.cd("..")
85+
} else {
86+
list.add("${channelSftp.pwd()}/$file")
87+
}
88+
return list
89+
}
90+
91+
private fun download(file: String) {
92+
val local = File("${downloadDir.path}/${connectionEntry.name}/$file")
93+
LOG.debug("Would download to $local")
94+
local.parentFile.mkdirs()
95+
channelSftp.get(file, local.path, DownloadMonitor())
96+
/* channelSftp.lcd(downloadDir.path)
97+
channelSftp.get(file)*/
98+
}
99+
100+
class DownloadMonitor : SftpProgressMonitor {
101+
var op: Int = 0
102+
var src: String? = null
103+
var dest: String? = null
104+
var max: Long = 0
105+
var pos: Long = 0
106+
107+
override fun count(count: Long): Boolean {
108+
pos += count
109+
val progress = String.format("%5.2f", pos / this.max.toDouble() * 100)
110+
LOG.debug("$src ($progress)")
111+
return true
112+
}
113+
114+
override fun end() {
115+
when (op) {
116+
SftpProgressMonitor.GET -> LOG.debug("Finished download: $src")
117+
SftpProgressMonitor.PUT -> LOG.debug("Finished upload: $src")
118+
}
119+
}
120+
121+
override fun init(op: Int, src: String, dest: String, max: Long) {
122+
this.op = op
123+
this.src = src
124+
this.dest = dest
125+
this.max = max
126+
when (op) {
127+
SftpProgressMonitor.GET -> LOG.debug("Starting download: $src => $dest ($max)")
128+
SftpProgressMonitor.PUT -> LOG.debug("Starting upload: $src => $dest ($max)")
129+
}
130+
}
131+
132+
}
133+
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
package ch.compile.blitzremote.model
22

33
import ch.compile.blitzremote.actions.ConnectAction
4+
import ch.compile.blitzremote.actions.DownloadAction
45
import javax.swing.Action
56

67
class ConnectionEntryTreeNode(name: String) : AbstractBlitzTreeNode(ConnectionEntry(name), false) {
78

89
override val actions: List<Action>
9-
get() = super.actions + listOf(ConnectAction(this.userObject as ConnectionEntry))
10+
get() = super.actions + listOf(ConnectAction(this.userObject as ConnectionEntry), DownloadAction(this.userObject as ConnectionEntry))
1011
}

0 commit comments

Comments
 (0)