mirror of
https://github.com/veeso/termscp.git
synced 2025-12-07 01:26:04 -08:00
save local file paths in bookmark (#204)
* fix: renamed Bookmark 'directory' to 'remote_path' (keep name in file) * feat: local_path as file transfer parameter and in bookmark
This commit is contained in:
committed by
GitHub
parent
ee28d34f29
commit
ca005cbecd
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
// Deps
|
// Deps
|
||||||
// Namespaces
|
// Namespaces
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::PathBuf;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use remotefs_ssh::SshKeyStorage as SshKeyStorageTrait;
|
use remotefs_ssh::SshKeyStorage as SshKeyStorageTrait;
|
||||||
@@ -34,12 +34,11 @@ pub enum NextActivity {
|
|||||||
pub struct ActivityManager {
|
pub struct ActivityManager {
|
||||||
context: Option<Context>,
|
context: Option<Context>,
|
||||||
ticks: Duration,
|
ticks: Duration,
|
||||||
local_dir: PathBuf,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ActivityManager {
|
impl ActivityManager {
|
||||||
/// Initializes a new Activity Manager
|
/// Initializes a new Activity Manager
|
||||||
pub fn new(local_dir: &Path, ticks: Duration) -> Result<ActivityManager, HostError> {
|
pub fn new(ticks: Duration) -> Result<ActivityManager, HostError> {
|
||||||
// Prepare Context
|
// Prepare Context
|
||||||
// Initialize configuration client
|
// Initialize configuration client
|
||||||
let (config_client, error_config): (ConfigClient, Option<String>) =
|
let (config_client, error_config): (ConfigClient, Option<String>) =
|
||||||
@@ -59,7 +58,6 @@ impl ActivityManager {
|
|||||||
let ctx: Context = Context::new(bookmarks_client, config_client, theme_provider, error);
|
let ctx: Context = Context::new(bookmarks_client, config_client, theme_provider, error);
|
||||||
Ok(ActivityManager {
|
Ok(ActivityManager {
|
||||||
context: Some(ctx),
|
context: Some(ctx),
|
||||||
local_dir: local_dir.to_path_buf(),
|
|
||||||
ticks,
|
ticks,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -243,8 +241,19 @@ impl ActivityManager {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// get local path:
|
||||||
|
// - if set in file transfer params, get it from there
|
||||||
|
// - otherwise is env current dir
|
||||||
|
// - otherwise is /
|
||||||
|
let local_wrkdir = ft_params
|
||||||
|
.local_path
|
||||||
|
.clone()
|
||||||
|
.or(std::env::current_dir().ok())
|
||||||
|
.unwrap_or(PathBuf::from("/"));
|
||||||
|
|
||||||
// Prepare activity
|
// Prepare activity
|
||||||
let host: Localhost = match Localhost::new(self.local_dir.clone()) {
|
let host: Localhost = match Localhost::new(local_wrkdir) {
|
||||||
Ok(host) => host,
|
Ok(host) => host,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
// Set error in context
|
// Set error in context
|
||||||
|
|||||||
@@ -38,8 +38,11 @@ pub struct Bookmark {
|
|||||||
pub username: Option<String>,
|
pub username: Option<String>,
|
||||||
/// Password is optional; base64, aes-128 encrypted password
|
/// Password is optional; base64, aes-128 encrypted password
|
||||||
pub password: Option<String>,
|
pub password: Option<String>,
|
||||||
/// Remote folder to connect to
|
/// Remote folder to connect to (serde rename for legacy reasons)
|
||||||
pub directory: Option<PathBuf>,
|
#[serde(rename = "directory")]
|
||||||
|
pub remote_path: Option<PathBuf>,
|
||||||
|
/// local folder to open at startup
|
||||||
|
pub local_path: Option<PathBuf>,
|
||||||
/// S3 params; optional. When used other fields are empty for sure
|
/// S3 params; optional. When used other fields are empty for sure
|
||||||
pub s3: Option<S3Params>,
|
pub s3: Option<S3Params>,
|
||||||
/// SMB params; optional. Extra params required for SMB protocol
|
/// SMB params; optional. Extra params required for SMB protocol
|
||||||
@@ -71,7 +74,8 @@ pub struct SmbParams {
|
|||||||
impl From<FileTransferParams> for Bookmark {
|
impl From<FileTransferParams> for Bookmark {
|
||||||
fn from(params: FileTransferParams) -> Self {
|
fn from(params: FileTransferParams) -> Self {
|
||||||
let protocol = params.protocol;
|
let protocol = params.protocol;
|
||||||
let directory = params.entry_directory;
|
let remote_path = params.remote_path;
|
||||||
|
let local_path = params.local_path;
|
||||||
// Create generic or others
|
// Create generic or others
|
||||||
match params.params {
|
match params.params {
|
||||||
ProtocolParams::Generic(params) => Self {
|
ProtocolParams::Generic(params) => Self {
|
||||||
@@ -80,7 +84,8 @@ impl From<FileTransferParams> for Bookmark {
|
|||||||
port: Some(params.port),
|
port: Some(params.port),
|
||||||
username: params.username,
|
username: params.username,
|
||||||
password: params.password,
|
password: params.password,
|
||||||
directory,
|
remote_path,
|
||||||
|
local_path,
|
||||||
s3: None,
|
s3: None,
|
||||||
smb: None,
|
smb: None,
|
||||||
},
|
},
|
||||||
@@ -90,7 +95,8 @@ impl From<FileTransferParams> for Bookmark {
|
|||||||
port: None,
|
port: None,
|
||||||
username: None,
|
username: None,
|
||||||
password: None,
|
password: None,
|
||||||
directory,
|
remote_path,
|
||||||
|
local_path,
|
||||||
s3: Some(S3Params::from(params)),
|
s3: Some(S3Params::from(params)),
|
||||||
smb: None,
|
smb: None,
|
||||||
},
|
},
|
||||||
@@ -104,7 +110,8 @@ impl From<FileTransferParams> for Bookmark {
|
|||||||
port: None,
|
port: None,
|
||||||
username: params.username,
|
username: params.username,
|
||||||
password: params.password,
|
password: params.password,
|
||||||
directory,
|
remote_path,
|
||||||
|
local_path,
|
||||||
s3: None,
|
s3: None,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -155,7 +162,8 @@ impl From<Bookmark> for FileTransferParams {
|
|||||||
Self::new(bookmark.protocol, ProtocolParams::Smb(params))
|
Self::new(bookmark.protocol, ProtocolParams::Smb(params))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.entry_directory(bookmark.directory) // Set entry directory
|
.remote_path(bookmark.remote_path) // Set entry remote_path
|
||||||
|
.local_path(bookmark.local_path) // Set entry local path
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,7 +254,8 @@ mod tests {
|
|||||||
protocol: FileTransferProtocol::Sftp,
|
protocol: FileTransferProtocol::Sftp,
|
||||||
username: Some(String::from("root")),
|
username: Some(String::from("root")),
|
||||||
password: Some(String::from("password")),
|
password: Some(String::from("password")),
|
||||||
directory: Some(PathBuf::from("/tmp")),
|
remote_path: Some(PathBuf::from("/tmp")),
|
||||||
|
local_path: Some(PathBuf::from("/usr")),
|
||||||
s3: None,
|
s3: None,
|
||||||
smb: None,
|
smb: None,
|
||||||
};
|
};
|
||||||
@@ -256,7 +265,8 @@ mod tests {
|
|||||||
protocol: FileTransferProtocol::Scp,
|
protocol: FileTransferProtocol::Scp,
|
||||||
username: Some(String::from("admin")),
|
username: Some(String::from("admin")),
|
||||||
password: Some(String::from("password")),
|
password: Some(String::from("password")),
|
||||||
directory: Some(PathBuf::from("/home")),
|
remote_path: Some(PathBuf::from("/home")),
|
||||||
|
local_path: Some(PathBuf::from("/usr")),
|
||||||
s3: None,
|
s3: None,
|
||||||
smb: None,
|
smb: None,
|
||||||
};
|
};
|
||||||
@@ -273,9 +283,13 @@ mod tests {
|
|||||||
assert_eq!(bookmark.username.as_deref().unwrap(), "root");
|
assert_eq!(bookmark.username.as_deref().unwrap(), "root");
|
||||||
assert_eq!(bookmark.password.as_deref().unwrap(), "password");
|
assert_eq!(bookmark.password.as_deref().unwrap(), "password");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
bookmark.directory.as_deref().unwrap(),
|
bookmark.remote_path.as_deref().unwrap(),
|
||||||
std::path::Path::new("/tmp")
|
std::path::Path::new("/tmp")
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
bookmark.local_path.as_deref().unwrap(),
|
||||||
|
std::path::Path::new("/usr")
|
||||||
|
);
|
||||||
let bookmark: &Bookmark = hosts
|
let bookmark: &Bookmark = hosts
|
||||||
.recents
|
.recents
|
||||||
.get(&String::from("ISO20201218T181432"))
|
.get(&String::from("ISO20201218T181432"))
|
||||||
@@ -286,9 +300,13 @@ mod tests {
|
|||||||
assert_eq!(bookmark.username.as_deref().unwrap(), "admin");
|
assert_eq!(bookmark.username.as_deref().unwrap(), "admin");
|
||||||
assert_eq!(bookmark.password.as_deref().unwrap(), "password");
|
assert_eq!(bookmark.password.as_deref().unwrap(), "password");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
bookmark.directory.as_deref().unwrap(),
|
bookmark.remote_path.as_deref().unwrap(),
|
||||||
std::path::Path::new("/home")
|
std::path::Path::new("/home")
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
bookmark.local_path.as_deref().unwrap(),
|
||||||
|
std::path::Path::new("/usr")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -300,7 +318,8 @@ mod tests {
|
|||||||
password: Some(String::from("omar")),
|
password: Some(String::from("omar")),
|
||||||
});
|
});
|
||||||
let params: FileTransferParams = FileTransferParams::new(FileTransferProtocol::Scp, params)
|
let params: FileTransferParams = FileTransferParams::new(FileTransferProtocol::Scp, params)
|
||||||
.entry_directory(Some(PathBuf::from("/home")));
|
.remote_path(Some(PathBuf::from("/home")))
|
||||||
|
.local_path(Some(PathBuf::from("/tmp")));
|
||||||
let bookmark = Bookmark::from(params);
|
let bookmark = Bookmark::from(params);
|
||||||
assert_eq!(bookmark.protocol, FileTransferProtocol::Scp);
|
assert_eq!(bookmark.protocol, FileTransferProtocol::Scp);
|
||||||
assert_eq!(bookmark.address.as_deref().unwrap(), "127.0.0.1");
|
assert_eq!(bookmark.address.as_deref().unwrap(), "127.0.0.1");
|
||||||
@@ -308,9 +327,13 @@ mod tests {
|
|||||||
assert_eq!(bookmark.username.as_deref().unwrap(), "root");
|
assert_eq!(bookmark.username.as_deref().unwrap(), "root");
|
||||||
assert_eq!(bookmark.password.as_deref().unwrap(), "omar");
|
assert_eq!(bookmark.password.as_deref().unwrap(), "omar");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
bookmark.directory.as_deref().unwrap(),
|
bookmark.remote_path.as_deref().unwrap(),
|
||||||
std::path::Path::new("/home")
|
std::path::Path::new("/home")
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
bookmark.local_path.as_deref().unwrap(),
|
||||||
|
std::path::Path::new("/tmp")
|
||||||
|
);
|
||||||
assert!(bookmark.s3.is_none());
|
assert!(bookmark.s3.is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,16 +368,21 @@ mod tests {
|
|||||||
protocol: FileTransferProtocol::Sftp,
|
protocol: FileTransferProtocol::Sftp,
|
||||||
username: Some(String::from("root")),
|
username: Some(String::from("root")),
|
||||||
password: Some(String::from("password")),
|
password: Some(String::from("password")),
|
||||||
directory: Some(PathBuf::from("/tmp")),
|
remote_path: Some(PathBuf::from("/tmp")),
|
||||||
|
local_path: Some(PathBuf::from("/usr")),
|
||||||
s3: None,
|
s3: None,
|
||||||
smb: None,
|
smb: None,
|
||||||
};
|
};
|
||||||
let params = FileTransferParams::from(bookmark);
|
let params = FileTransferParams::from(bookmark);
|
||||||
assert_eq!(params.protocol, FileTransferProtocol::Sftp);
|
assert_eq!(params.protocol, FileTransferProtocol::Sftp);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
params.entry_directory.as_deref().unwrap(),
|
params.remote_path.as_deref().unwrap(),
|
||||||
std::path::Path::new("/tmp")
|
std::path::Path::new("/tmp")
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
params.local_path.as_deref().unwrap(),
|
||||||
|
std::path::Path::new("/usr")
|
||||||
|
);
|
||||||
let gparams = params.params.generic_params().unwrap();
|
let gparams = params.params.generic_params().unwrap();
|
||||||
assert_eq!(gparams.address.as_str(), "192.168.1.1");
|
assert_eq!(gparams.address.as_str(), "192.168.1.1");
|
||||||
assert_eq!(gparams.port, 22);
|
assert_eq!(gparams.port, 22);
|
||||||
@@ -370,7 +398,8 @@ mod tests {
|
|||||||
port: None,
|
port: None,
|
||||||
username: None,
|
username: None,
|
||||||
password: None,
|
password: None,
|
||||||
directory: Some(PathBuf::from("/tmp")),
|
remote_path: Some(PathBuf::from("/tmp")),
|
||||||
|
local_path: Some(PathBuf::from("/usr")),
|
||||||
s3: Some(S3Params {
|
s3: Some(S3Params {
|
||||||
bucket: String::from("veeso"),
|
bucket: String::from("veeso"),
|
||||||
region: Some(String::from("eu-west-1")),
|
region: Some(String::from("eu-west-1")),
|
||||||
@@ -385,9 +414,13 @@ mod tests {
|
|||||||
let params = FileTransferParams::from(bookmark);
|
let params = FileTransferParams::from(bookmark);
|
||||||
assert_eq!(params.protocol, FileTransferProtocol::AwsS3);
|
assert_eq!(params.protocol, FileTransferProtocol::AwsS3);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
params.entry_directory.as_deref().unwrap(),
|
params.remote_path.as_deref().unwrap(),
|
||||||
std::path::Path::new("/tmp")
|
std::path::Path::new("/tmp")
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
params.local_path.as_deref().unwrap(),
|
||||||
|
std::path::Path::new("/usr")
|
||||||
|
);
|
||||||
let gparams = params.params.s3_params().unwrap();
|
let gparams = params.params.s3_params().unwrap();
|
||||||
assert_eq!(gparams.bucket_name.as_str(), "veeso");
|
assert_eq!(gparams.bucket_name.as_str(), "veeso");
|
||||||
assert_eq!(gparams.region.as_deref().unwrap(), "eu-west-1");
|
assert_eq!(gparams.region.as_deref().unwrap(), "eu-west-1");
|
||||||
@@ -407,7 +440,8 @@ mod tests {
|
|||||||
port: Some(445),
|
port: Some(445),
|
||||||
username: Some("foo".to_string()),
|
username: Some("foo".to_string()),
|
||||||
password: Some("bar".to_string()),
|
password: Some("bar".to_string()),
|
||||||
directory: Some(PathBuf::from("/tmp")),
|
remote_path: Some(PathBuf::from("/tmp")),
|
||||||
|
local_path: Some(PathBuf::from("/usr")),
|
||||||
s3: None,
|
s3: None,
|
||||||
smb: Some(SmbParams {
|
smb: Some(SmbParams {
|
||||||
share: "test".to_string(),
|
share: "test".to_string(),
|
||||||
@@ -418,9 +452,13 @@ mod tests {
|
|||||||
let params = FileTransferParams::from(bookmark);
|
let params = FileTransferParams::from(bookmark);
|
||||||
assert_eq!(params.protocol, FileTransferProtocol::Smb);
|
assert_eq!(params.protocol, FileTransferProtocol::Smb);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
params.entry_directory.as_deref().unwrap(),
|
params.remote_path.as_deref().unwrap(),
|
||||||
std::path::Path::new("/tmp")
|
std::path::Path::new("/tmp")
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
params.local_path.as_deref().unwrap(),
|
||||||
|
std::path::Path::new("/usr")
|
||||||
|
);
|
||||||
let smb_params = params.params.smb_params().unwrap();
|
let smb_params = params.params.smb_params().unwrap();
|
||||||
assert_eq!(smb_params.address.as_str(), "localhost");
|
assert_eq!(smb_params.address.as_str(), "localhost");
|
||||||
assert_eq!(smb_params.port, 445);
|
assert_eq!(smb_params.port, 445);
|
||||||
@@ -439,7 +477,8 @@ mod tests {
|
|||||||
port: Some(445),
|
port: Some(445),
|
||||||
username: None,
|
username: None,
|
||||||
password: None,
|
password: None,
|
||||||
directory: Some(PathBuf::from("/tmp")),
|
remote_path: Some(PathBuf::from("/tmp")),
|
||||||
|
local_path: Some(PathBuf::from("/usr")),
|
||||||
s3: None,
|
s3: None,
|
||||||
smb: Some(SmbParams {
|
smb: Some(SmbParams {
|
||||||
share: "test".to_string(),
|
share: "test".to_string(),
|
||||||
@@ -450,9 +489,13 @@ mod tests {
|
|||||||
let params = FileTransferParams::from(bookmark);
|
let params = FileTransferParams::from(bookmark);
|
||||||
assert_eq!(params.protocol, FileTransferProtocol::Smb);
|
assert_eq!(params.protocol, FileTransferProtocol::Smb);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
params.entry_directory.as_deref().unwrap(),
|
params.remote_path.as_deref().unwrap(),
|
||||||
std::path::Path::new("/tmp")
|
std::path::Path::new("/tmp")
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
params.local_path.as_deref().unwrap(),
|
||||||
|
std::path::Path::new("/usr")
|
||||||
|
);
|
||||||
let smb_params = params.params.smb_params().unwrap();
|
let smb_params = params.params.smb_params().unwrap();
|
||||||
assert_eq!(smb_params.address.as_str(), "localhost");
|
assert_eq!(smb_params.address.as_str(), "localhost");
|
||||||
assert_eq!(smb_params.share.as_str(), "test");
|
assert_eq!(smb_params.share.as_str(), "test");
|
||||||
|
|||||||
@@ -380,7 +380,7 @@ mod tests {
|
|||||||
assert_eq!(host.username.as_deref().unwrap(), "cvisintin");
|
assert_eq!(host.username.as_deref().unwrap(), "cvisintin");
|
||||||
assert_eq!(host.password.as_deref().unwrap(), "mysecret");
|
assert_eq!(host.password.as_deref().unwrap(), "mysecret");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
host.directory.as_deref().unwrap(),
|
host.remote_path.as_deref().unwrap(),
|
||||||
std::path::Path::new("/tmp")
|
std::path::Path::new("/tmp")
|
||||||
);
|
);
|
||||||
let host: &Bookmark = hosts.bookmarks.get("aws-server-prod1").unwrap();
|
let host: &Bookmark = hosts.bookmarks.get("aws-server-prod1").unwrap();
|
||||||
@@ -441,7 +441,8 @@ mod tests {
|
|||||||
protocol: FileTransferProtocol::Sftp,
|
protocol: FileTransferProtocol::Sftp,
|
||||||
username: Some(String::from("root")),
|
username: Some(String::from("root")),
|
||||||
password: None,
|
password: None,
|
||||||
directory: None,
|
remote_path: None,
|
||||||
|
local_path: None,
|
||||||
s3: None,
|
s3: None,
|
||||||
smb: None,
|
smb: None,
|
||||||
},
|
},
|
||||||
@@ -454,7 +455,8 @@ mod tests {
|
|||||||
protocol: FileTransferProtocol::Sftp,
|
protocol: FileTransferProtocol::Sftp,
|
||||||
username: Some(String::from("cvisintin")),
|
username: Some(String::from("cvisintin")),
|
||||||
password: Some(String::from("password")),
|
password: Some(String::from("password")),
|
||||||
directory: Some(PathBuf::from("/tmp")),
|
remote_path: Some(PathBuf::from("/tmp")),
|
||||||
|
local_path: Some(PathBuf::from("/usr")),
|
||||||
s3: None,
|
s3: None,
|
||||||
smb: None,
|
smb: None,
|
||||||
},
|
},
|
||||||
@@ -467,7 +469,8 @@ mod tests {
|
|||||||
protocol: FileTransferProtocol::AwsS3,
|
protocol: FileTransferProtocol::AwsS3,
|
||||||
username: None,
|
username: None,
|
||||||
password: None,
|
password: None,
|
||||||
directory: None,
|
remote_path: None,
|
||||||
|
local_path: None,
|
||||||
s3: Some(S3Params {
|
s3: Some(S3Params {
|
||||||
bucket: "veeso".to_string(),
|
bucket: "veeso".to_string(),
|
||||||
region: Some("eu-west-1".to_string()),
|
region: Some("eu-west-1".to_string()),
|
||||||
@@ -492,7 +495,8 @@ mod tests {
|
|||||||
protocol: FileTransferProtocol::Smb,
|
protocol: FileTransferProtocol::Smb,
|
||||||
username: None,
|
username: None,
|
||||||
password: None,
|
password: None,
|
||||||
directory: None,
|
remote_path: None,
|
||||||
|
local_path: None,
|
||||||
s3: None,
|
s3: None,
|
||||||
smb: smb_params,
|
smb: smb_params,
|
||||||
},
|
},
|
||||||
@@ -506,7 +510,8 @@ mod tests {
|
|||||||
protocol: FileTransferProtocol::Scp,
|
protocol: FileTransferProtocol::Scp,
|
||||||
username: Some(String::from("omar")),
|
username: Some(String::from("omar")),
|
||||||
password: Some(String::from("aaa")),
|
password: Some(String::from("aaa")),
|
||||||
directory: Some(PathBuf::from("/tmp")),
|
remote_path: Some(PathBuf::from("/tmp")),
|
||||||
|
local_path: Some(PathBuf::from("/usr")),
|
||||||
s3: None,
|
s3: None,
|
||||||
smb: None,
|
smb: None,
|
||||||
},
|
},
|
||||||
@@ -547,7 +552,7 @@ mod tests {
|
|||||||
let file_content: &str = r#"
|
let file_content: &str = r#"
|
||||||
[bookmarks]
|
[bookmarks]
|
||||||
raspberrypi2 = { address = "192.168.1.31", port = 22, protocol = "SFTP", username = "root", password = "mypassword" }
|
raspberrypi2 = { address = "192.168.1.31", port = 22, protocol = "SFTP", username = "root", password = "mypassword" }
|
||||||
msi-estrem = { address = "192.168.1.30", port = 22, protocol = "SFTP", username = "cvisintin", password = "mysecret", directory = "/tmp" }
|
msi-estrem = { address = "192.168.1.30", port = 22, protocol = "SFTP", username = "cvisintin", password = "mysecret", directory = "/tmp", local_path = "/usr" }
|
||||||
aws-server-prod1 = { address = "51.23.67.12", port = 21, protocol = "FTPS", username = "aws001" }
|
aws-server-prod1 = { address = "51.23.67.12", port = 21, protocol = "FTPS", username = "aws001" }
|
||||||
|
|
||||||
[bookmarks.my-bucket]
|
[bookmarks.my-bucket]
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ use super::FileTransferProtocol;
|
|||||||
pub struct FileTransferParams {
|
pub struct FileTransferParams {
|
||||||
pub protocol: FileTransferProtocol,
|
pub protocol: FileTransferProtocol,
|
||||||
pub params: ProtocolParams,
|
pub params: ProtocolParams,
|
||||||
pub entry_directory: Option<PathBuf>,
|
pub remote_path: Option<PathBuf>,
|
||||||
|
pub local_path: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Container for protocol params
|
/// Container for protocol params
|
||||||
@@ -64,13 +65,20 @@ impl FileTransferParams {
|
|||||||
Self {
|
Self {
|
||||||
protocol,
|
protocol,
|
||||||
params,
|
params,
|
||||||
entry_directory: None,
|
remote_path: None,
|
||||||
|
local_path: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set entry directory
|
/// Set remote directory
|
||||||
pub fn entry_directory<P: AsRef<Path>>(mut self, dir: Option<P>) -> Self {
|
pub fn remote_path<P: AsRef<Path>>(mut self, dir: Option<P>) -> Self {
|
||||||
self.entry_directory = dir.map(|x| x.as_ref().to_path_buf());
|
self.remote_path = dir.map(|x| x.as_ref().to_path_buf());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set local directory
|
||||||
|
pub fn local_path<P: AsRef<Path>>(mut self, dir: Option<P>) -> Self {
|
||||||
|
self.local_path = dir.map(|x| x.as_ref().to_path_buf());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -325,16 +333,15 @@ mod test {
|
|||||||
fn test_filetransfer_params() {
|
fn test_filetransfer_params() {
|
||||||
let params: FileTransferParams =
|
let params: FileTransferParams =
|
||||||
FileTransferParams::new(FileTransferProtocol::Scp, ProtocolParams::default())
|
FileTransferParams::new(FileTransferProtocol::Scp, ProtocolParams::default())
|
||||||
.entry_directory(Some(&Path::new("/tmp")));
|
.remote_path(Some(&Path::new("/tmp")))
|
||||||
|
.local_path(Some(&Path::new("/usr")));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
params.params.generic_params().unwrap().address.as_str(),
|
params.params.generic_params().unwrap().address.as_str(),
|
||||||
"localhost"
|
"localhost"
|
||||||
);
|
);
|
||||||
assert_eq!(params.protocol, FileTransferProtocol::Scp);
|
assert_eq!(params.protocol, FileTransferProtocol::Scp);
|
||||||
assert_eq!(
|
assert_eq!(params.remote_path.as_deref().unwrap(), Path::new("/tmp"));
|
||||||
params.entry_directory.as_deref().unwrap(),
|
assert_eq!(params.local_path.as_deref().unwrap(), Path::new("/usr"));
|
||||||
Path::new("/tmp")
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
11
src/main.rs
11
src/main.rs
@@ -14,9 +14,9 @@ extern crate log;
|
|||||||
extern crate magic_crypt;
|
extern crate magic_crypt;
|
||||||
|
|
||||||
// External libs
|
// External libs
|
||||||
use std::path::PathBuf;
|
use std::env;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::{env, path::Path};
|
|
||||||
|
|
||||||
// Include
|
// Include
|
||||||
mod activity_manager;
|
mod activity_manager;
|
||||||
@@ -172,13 +172,8 @@ fn run_install_update() -> i32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn run_activity(activity: NextActivity, ticks: Duration, remote: Remote) -> i32 {
|
fn run_activity(activity: NextActivity, ticks: Duration, remote: Remote) -> i32 {
|
||||||
// Get working directory
|
|
||||||
let wrkdir: PathBuf = match env::current_dir() {
|
|
||||||
Ok(dir) => dir,
|
|
||||||
Err(_) => PathBuf::from("/"),
|
|
||||||
};
|
|
||||||
// Create activity manager (and context too)
|
// Create activity manager (and context too)
|
||||||
let mut manager: ActivityManager = match ActivityManager::new(wrkdir.as_path(), ticks) {
|
let mut manager: ActivityManager = match ActivityManager::new(ticks) {
|
||||||
Ok(m) => m,
|
Ok(m) => m,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("Could not start activity manager: {err}");
|
eprintln!("Could not start activity manager: {err}");
|
||||||
|
|||||||
@@ -150,7 +150,13 @@ impl AuthActivity {
|
|||||||
self.mount_protocol(bookmark.protocol);
|
self.mount_protocol(bookmark.protocol);
|
||||||
self.mount_remote_directory(
|
self.mount_remote_directory(
|
||||||
bookmark
|
bookmark
|
||||||
.entry_directory
|
.remote_path
|
||||||
|
.map(|x| x.to_string_lossy().to_string())
|
||||||
|
.unwrap_or_default(),
|
||||||
|
);
|
||||||
|
self.mount_local_directory(
|
||||||
|
bookmark
|
||||||
|
.local_path
|
||||||
.map(|x| x.to_string_lossy().to_string())
|
.map(|x| x.to_string_lossy().to_string())
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -8,13 +8,12 @@ use tuirealm::event::{Key, KeyEvent, KeyModifiers};
|
|||||||
use tuirealm::props::{Alignment, BorderType, Borders, Color, InputType, Style};
|
use tuirealm::props::{Alignment, BorderType, Borders, Color, InputType, Style};
|
||||||
use tuirealm::{Component, Event, MockComponent, NoUserEvent, State, StateValue};
|
use tuirealm::{Component, Event, MockComponent, NoUserEvent, State, StateValue};
|
||||||
|
|
||||||
|
use super::{FileTransferProtocol, FormMsg, Msg, UiMsg};
|
||||||
use crate::ui::activities::auth::{
|
use crate::ui::activities::auth::{
|
||||||
RADIO_PROTOCOL_FTP, RADIO_PROTOCOL_FTPS, RADIO_PROTOCOL_S3, RADIO_PROTOCOL_SCP,
|
RADIO_PROTOCOL_FTP, RADIO_PROTOCOL_FTPS, RADIO_PROTOCOL_S3, RADIO_PROTOCOL_SCP,
|
||||||
RADIO_PROTOCOL_SFTP, RADIO_PROTOCOL_SMB,
|
RADIO_PROTOCOL_SFTP, RADIO_PROTOCOL_SMB,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{FileTransferProtocol, FormMsg, Msg, UiMsg};
|
|
||||||
|
|
||||||
// -- protocol
|
// -- protocol
|
||||||
|
|
||||||
#[derive(MockComponent)]
|
#[derive(MockComponent)]
|
||||||
@@ -118,7 +117,7 @@ impl InputRemoteDirectory {
|
|||||||
)
|
)
|
||||||
.foreground(color)
|
.foreground(color)
|
||||||
.placeholder("/home/foo", Style::default().fg(Color::Rgb(128, 128, 128)))
|
.placeholder("/home/foo", Style::default().fg(Color::Rgb(128, 128, 128)))
|
||||||
.title("Default remote directory", Alignment::Left)
|
.title("Default remote working directory", Alignment::Left)
|
||||||
.input_type(InputType::Text)
|
.input_type(InputType::Text)
|
||||||
.value(remote_dir),
|
.value(remote_dir),
|
||||||
}
|
}
|
||||||
@@ -136,6 +135,42 @@ impl Component<Msg, NoUserEvent> for InputRemoteDirectory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -- remote directory
|
||||||
|
|
||||||
|
#[derive(MockComponent)]
|
||||||
|
pub struct InputLocalDirectory {
|
||||||
|
component: Input,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InputLocalDirectory {
|
||||||
|
pub fn new(local_dir: &str, color: Color) -> Self {
|
||||||
|
Self {
|
||||||
|
component: Input::default()
|
||||||
|
.borders(
|
||||||
|
Borders::default()
|
||||||
|
.color(color)
|
||||||
|
.modifiers(BorderType::Rounded),
|
||||||
|
)
|
||||||
|
.foreground(color)
|
||||||
|
.placeholder("/home/foo", Style::default().fg(Color::Rgb(128, 128, 128)))
|
||||||
|
.title("Default local working directory", Alignment::Left)
|
||||||
|
.input_type(InputType::Text)
|
||||||
|
.value(local_dir),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Component<Msg, NoUserEvent> for InputLocalDirectory {
|
||||||
|
fn on(&mut self, ev: Event<NoUserEvent>) -> Option<Msg> {
|
||||||
|
handle_input_ev(
|
||||||
|
self,
|
||||||
|
ev,
|
||||||
|
Msg::Ui(UiMsg::LocalDirectoryBlurDown),
|
||||||
|
Msg::Ui(UiMsg::LocalDirectoryBlurUp),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// -- address
|
// -- address
|
||||||
|
|
||||||
#[derive(MockComponent)]
|
#[derive(MockComponent)]
|
||||||
|
|||||||
@@ -16,9 +16,10 @@ pub use bookmarks::{
|
|||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
pub use form::InputSmbWorkgroup;
|
pub use form::InputSmbWorkgroup;
|
||||||
pub use form::{
|
pub use form::{
|
||||||
InputAddress, InputPassword, InputPort, InputRemoteDirectory, InputS3AccessKey, InputS3Bucket,
|
InputAddress, InputLocalDirectory, InputPassword, InputPort, InputRemoteDirectory,
|
||||||
InputS3Endpoint, InputS3Profile, InputS3Region, InputS3SecretAccessKey, InputS3SecurityToken,
|
InputS3AccessKey, InputS3Bucket, InputS3Endpoint, InputS3Profile, InputS3Region,
|
||||||
InputS3SessionToken, InputSmbShare, InputUsername, ProtocolRadio, RadioS3NewPathStyle,
|
InputS3SecretAccessKey, InputS3SecurityToken, InputS3SessionToken, InputSmbShare,
|
||||||
|
InputUsername, ProtocolRadio, RadioS3NewPathStyle,
|
||||||
};
|
};
|
||||||
pub use popup::{
|
pub use popup::{
|
||||||
ErrorPopup, InfoPopup, InstallUpdatePopup, Keybindings, QuitPopup, ReleaseNotes, WaitPopup,
|
ErrorPopup, InfoPopup, InstallUpdatePopup, Keybindings, QuitPopup, ReleaseNotes, WaitPopup,
|
||||||
|
|||||||
@@ -59,7 +59,8 @@ impl AuthActivity {
|
|||||||
Ok(FileTransferParams {
|
Ok(FileTransferParams {
|
||||||
protocol,
|
protocol,
|
||||||
params: ProtocolParams::Generic(params),
|
params: ProtocolParams::Generic(params),
|
||||||
entry_directory: self.get_input_remote_directory(),
|
local_path: self.get_input_local_directory(),
|
||||||
|
remote_path: self.get_input_remote_directory(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,7 +73,8 @@ impl AuthActivity {
|
|||||||
Ok(FileTransferParams {
|
Ok(FileTransferParams {
|
||||||
protocol: FileTransferProtocol::AwsS3,
|
protocol: FileTransferProtocol::AwsS3,
|
||||||
params: ProtocolParams::AwsS3(params),
|
params: ProtocolParams::AwsS3(params),
|
||||||
entry_directory: self.get_input_remote_directory(),
|
local_path: self.get_input_local_directory(),
|
||||||
|
remote_path: self.get_input_remote_directory(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +93,8 @@ impl AuthActivity {
|
|||||||
Ok(FileTransferParams {
|
Ok(FileTransferParams {
|
||||||
protocol: FileTransferProtocol::Smb,
|
protocol: FileTransferProtocol::Smb,
|
||||||
params: ProtocolParams::Smb(params),
|
params: ProtocolParams::Smb(params),
|
||||||
entry_directory: self.get_input_remote_directory(),
|
local_path: self.get_input_local_directory(),
|
||||||
|
remote_path: self.get_input_remote_directory(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ pub enum Id {
|
|||||||
InfoPopup,
|
InfoPopup,
|
||||||
InstallUpdatePopup,
|
InstallUpdatePopup,
|
||||||
Keybindings,
|
Keybindings,
|
||||||
|
LocalDirectory,
|
||||||
NewVersionChangelog,
|
NewVersionChangelog,
|
||||||
NewVersionDisclaimer,
|
NewVersionDisclaimer,
|
||||||
Password,
|
Password,
|
||||||
@@ -108,6 +109,8 @@ pub enum UiMsg {
|
|||||||
CloseKeybindingsPopup,
|
CloseKeybindingsPopup,
|
||||||
CloseQuitPopup,
|
CloseQuitPopup,
|
||||||
CloseSaveBookmark,
|
CloseSaveBookmark,
|
||||||
|
LocalDirectoryBlurDown,
|
||||||
|
LocalDirectoryBlurUp,
|
||||||
ParamsFormBlur,
|
ParamsFormBlur,
|
||||||
PasswordBlurDown,
|
PasswordBlurDown,
|
||||||
PasswordBlurUp,
|
PasswordBlurUp,
|
||||||
|
|||||||
@@ -158,6 +158,12 @@ impl AuthActivity {
|
|||||||
assert!(self.app.umount(&Id::BookmarkName).is_ok());
|
assert!(self.app.umount(&Id::BookmarkName).is_ok());
|
||||||
assert!(self.app.umount(&Id::BookmarkSavePassword).is_ok());
|
assert!(self.app.umount(&Id::BookmarkSavePassword).is_ok());
|
||||||
}
|
}
|
||||||
|
UiMsg::LocalDirectoryBlurDown => {
|
||||||
|
assert!(self.app.active(&Id::Protocol).is_ok());
|
||||||
|
}
|
||||||
|
UiMsg::LocalDirectoryBlurUp => {
|
||||||
|
assert!(self.app.active(&Id::RemoteDirectory).is_ok());
|
||||||
|
}
|
||||||
UiMsg::ParamsFormBlur => {
|
UiMsg::ParamsFormBlur => {
|
||||||
assert!(self.app.active(&Id::BookmarksList).is_ok());
|
assert!(self.app.active(&Id::BookmarksList).is_ok());
|
||||||
}
|
}
|
||||||
@@ -201,13 +207,13 @@ impl AuthActivity {
|
|||||||
.is_ok());
|
.is_ok());
|
||||||
}
|
}
|
||||||
UiMsg::ProtocolBlurUp => {
|
UiMsg::ProtocolBlurUp => {
|
||||||
assert!(self.app.active(&Id::RemoteDirectory).is_ok());
|
assert!(self.app.active(&Id::LocalDirectory).is_ok());
|
||||||
}
|
}
|
||||||
UiMsg::RececentsListBlur => {
|
UiMsg::RececentsListBlur => {
|
||||||
assert!(self.app.active(&Id::BookmarksList).is_ok());
|
assert!(self.app.active(&Id::BookmarksList).is_ok());
|
||||||
}
|
}
|
||||||
UiMsg::RemoteDirectoryBlurDown => {
|
UiMsg::RemoteDirectoryBlurDown => {
|
||||||
assert!(self.app.active(&Id::Protocol).is_ok());
|
assert!(self.app.active(&Id::LocalDirectory).is_ok());
|
||||||
}
|
}
|
||||||
UiMsg::RemoteDirectoryBlurUp => {
|
UiMsg::RemoteDirectoryBlurUp => {
|
||||||
assert!(self
|
assert!(self
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ impl AuthActivity {
|
|||||||
// Auth form
|
// Auth form
|
||||||
self.mount_protocol(default_protocol);
|
self.mount_protocol(default_protocol);
|
||||||
self.mount_remote_directory("");
|
self.mount_remote_directory("");
|
||||||
|
self.mount_local_directory("");
|
||||||
self.mount_address("");
|
self.mount_address("");
|
||||||
self.mount_port(Self::get_default_port_for_protocol(default_protocol));
|
self.mount_port(Self::get_default_port_for_protocol(default_protocol));
|
||||||
self.mount_username("");
|
self.mount_username("");
|
||||||
@@ -582,14 +583,14 @@ impl AuthActivity {
|
|||||||
.is_ok());
|
.is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn mount_remote_directory<S: AsRef<str>>(&mut self, entry_directory: S) {
|
pub(super) fn mount_remote_directory<S: AsRef<str>>(&mut self, remote_path: S) {
|
||||||
let protocol_color = self.theme().auth_protocol;
|
let protocol_color = self.theme().auth_protocol;
|
||||||
assert!(self
|
assert!(self
|
||||||
.app
|
.app
|
||||||
.remount(
|
.remount(
|
||||||
Id::RemoteDirectory,
|
Id::RemoteDirectory,
|
||||||
Box::new(components::InputRemoteDirectory::new(
|
Box::new(components::InputRemoteDirectory::new(
|
||||||
entry_directory.as_ref(),
|
remote_path.as_ref(),
|
||||||
protocol_color
|
protocol_color
|
||||||
)),
|
)),
|
||||||
vec![]
|
vec![]
|
||||||
@@ -597,6 +598,21 @@ impl AuthActivity {
|
|||||||
.is_ok());
|
.is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn mount_local_directory<S: AsRef<str>>(&mut self, local_path: S) {
|
||||||
|
let color = self.theme().auth_username;
|
||||||
|
assert!(self
|
||||||
|
.app
|
||||||
|
.remount(
|
||||||
|
Id::LocalDirectory,
|
||||||
|
Box::new(components::InputLocalDirectory::new(
|
||||||
|
local_path.as_ref(),
|
||||||
|
color
|
||||||
|
)),
|
||||||
|
vec![]
|
||||||
|
)
|
||||||
|
.is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) fn mount_address(&mut self, address: &str) {
|
pub(super) fn mount_address(&mut self, address: &str) {
|
||||||
let addr_color = self.theme().auth_address;
|
let addr_color = self.theme().auth_address;
|
||||||
assert!(self
|
assert!(self
|
||||||
@@ -853,6 +869,15 @@ impl AuthActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn get_input_local_directory(&self) -> Option<PathBuf> {
|
||||||
|
match self.app.state(&Id::LocalDirectory) {
|
||||||
|
Ok(State::One(StateValue::String(x))) if !x.is_empty() => {
|
||||||
|
Some(PathBuf::from(x.as_str()))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) fn get_input_addr(&self) -> String {
|
pub(super) fn get_input_addr(&self) -> String {
|
||||||
match self.app.state(&Id::Address) {
|
match self.app.state(&Id::Address) {
|
||||||
Ok(State::One(StateValue::String(x))) => x,
|
Ok(State::One(StateValue::String(x))) => x,
|
||||||
@@ -1053,6 +1078,12 @@ impl AuthActivity {
|
|||||||
Some(&Id::RemoteDirectory) => {
|
Some(&Id::RemoteDirectory) => {
|
||||||
[Id::Port, Id::Username, Id::Password, Id::RemoteDirectory]
|
[Id::Port, Id::Username, Id::Password, Id::RemoteDirectory]
|
||||||
}
|
}
|
||||||
|
Some(&Id::LocalDirectory) => [
|
||||||
|
Id::Username,
|
||||||
|
Id::Password,
|
||||||
|
Id::RemoteDirectory,
|
||||||
|
Id::LocalDirectory,
|
||||||
|
],
|
||||||
_ => [Id::Address, Id::Port, Id::Username, Id::Password],
|
_ => [Id::Address, Id::Port, Id::Username, Id::Password],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1093,6 +1124,12 @@ impl AuthActivity {
|
|||||||
Id::S3NewPathStyle,
|
Id::S3NewPathStyle,
|
||||||
Id::RemoteDirectory,
|
Id::RemoteDirectory,
|
||||||
],
|
],
|
||||||
|
Some(&Id::LocalDirectory) => [
|
||||||
|
Id::S3SessionToken,
|
||||||
|
Id::S3NewPathStyle,
|
||||||
|
Id::RemoteDirectory,
|
||||||
|
Id::LocalDirectory,
|
||||||
|
],
|
||||||
_ => [Id::S3Bucket, Id::S3Region, Id::S3Endpoint, Id::S3Profile],
|
_ => [Id::S3Bucket, Id::S3Region, Id::S3Endpoint, Id::S3Profile],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1111,6 +1148,12 @@ impl AuthActivity {
|
|||||||
Id::SmbWorkgroup,
|
Id::SmbWorkgroup,
|
||||||
Id::RemoteDirectory,
|
Id::RemoteDirectory,
|
||||||
],
|
],
|
||||||
|
Some(&Id::LocalDirectory) => [
|
||||||
|
Id::Password,
|
||||||
|
Id::SmbWorkgroup,
|
||||||
|
Id::RemoteDirectory,
|
||||||
|
Id::LocalDirectory,
|
||||||
|
],
|
||||||
_ => [Id::Address, Id::Port, Id::SmbShare, Id::Username],
|
_ => [Id::Address, Id::Port, Id::SmbShare, Id::Username],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1127,6 +1170,12 @@ impl AuthActivity {
|
|||||||
Id::Password,
|
Id::Password,
|
||||||
Id::RemoteDirectory,
|
Id::RemoteDirectory,
|
||||||
],
|
],
|
||||||
|
Some(&Id::LocalDirectory) => [
|
||||||
|
Id::Username,
|
||||||
|
Id::Password,
|
||||||
|
Id::RemoteDirectory,
|
||||||
|
Id::LocalDirectory,
|
||||||
|
],
|
||||||
_ => [Id::Address, Id::SmbShare, Id::Username, Id::Password],
|
_ => [Id::Address, Id::SmbShare, Id::Username, Id::Password],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ pub struct FileTransferActivity {
|
|||||||
cache: Option<TempDir>,
|
cache: Option<TempDir>,
|
||||||
/// Fs watcher
|
/// Fs watcher
|
||||||
fswatcher: Option<FsWatcher>,
|
fswatcher: Option<FsWatcher>,
|
||||||
/// conncted once
|
/// connected once
|
||||||
connected: bool,
|
connected: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ impl FileTransferActivity {
|
|||||||
/// Connect to remote
|
/// Connect to remote
|
||||||
pub(super) fn connect(&mut self) {
|
pub(super) fn connect(&mut self) {
|
||||||
let ft_params = self.context().ft_params().unwrap().clone();
|
let ft_params = self.context().ft_params().unwrap().clone();
|
||||||
let entry_dir: Option<PathBuf> = ft_params.entry_directory;
|
let entry_dir: Option<PathBuf> = ft_params.remote_path;
|
||||||
// Connect to remote
|
// Connect to remote
|
||||||
match self.client.connect() {
|
match self.client.connect() {
|
||||||
Ok(Welcome { banner, .. }) => {
|
Ok(Welcome { banner, .. }) => {
|
||||||
@@ -71,11 +71,11 @@ impl FileTransferActivity {
|
|||||||
}
|
}
|
||||||
// Try to change directory to entry directory
|
// Try to change directory to entry directory
|
||||||
let mut remote_chdir: Option<PathBuf> = None;
|
let mut remote_chdir: Option<PathBuf> = None;
|
||||||
if let Some(entry_directory) = &entry_dir {
|
if let Some(remote_path) = &entry_dir {
|
||||||
remote_chdir = Some(entry_directory.clone());
|
remote_chdir = Some(remote_path.clone());
|
||||||
}
|
}
|
||||||
if let Some(entry_directory) = remote_chdir {
|
if let Some(remote_path) = remote_chdir {
|
||||||
self.remote_changedir(entry_directory.as_path(), false);
|
self.remote_changedir(remote_path.as_path(), false);
|
||||||
}
|
}
|
||||||
// Set state to explorer
|
// Set state to explorer
|
||||||
self.umount_wait();
|
self.umount_wait();
|
||||||
|
|||||||
@@ -218,7 +218,7 @@ fn parse_generic_remote_opt(
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
// Get workdir
|
// Get workdir
|
||||||
let entry_directory: Option<PathBuf> =
|
let remote_path: Option<PathBuf> =
|
||||||
groups.get(4).map(|group| PathBuf::from(group.as_str()));
|
groups.get(4).map(|group| PathBuf::from(group.as_str()));
|
||||||
let params: ProtocolParams = ProtocolParams::Generic(
|
let params: ProtocolParams = ProtocolParams::Generic(
|
||||||
GenericProtocolParams::default()
|
GenericProtocolParams::default()
|
||||||
@@ -226,7 +226,7 @@ fn parse_generic_remote_opt(
|
|||||||
.port(port)
|
.port(port)
|
||||||
.username(username),
|
.username(username),
|
||||||
);
|
);
|
||||||
Ok(FileTransferParams::new(protocol, params).entry_directory(entry_directory))
|
Ok(FileTransferParams::new(protocol, params).remote_path(remote_path))
|
||||||
}
|
}
|
||||||
None => Err(String::from("Bad remote host syntax!")),
|
None => Err(String::from("Bad remote host syntax!")),
|
||||||
}
|
}
|
||||||
@@ -245,13 +245,13 @@ fn parse_s3_remote_opt(s: &str) -> Result<FileTransferParams, String> {
|
|||||||
.map(|x| x.as_str().to_string())
|
.map(|x| x.as_str().to_string())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let profile: Option<String> = groups.get(3).map(|x| x.as_str().to_string());
|
let profile: Option<String> = groups.get(3).map(|x| x.as_str().to_string());
|
||||||
let entry_directory: Option<PathBuf> =
|
let remote_path: Option<PathBuf> =
|
||||||
groups.get(4).map(|group| PathBuf::from(group.as_str()));
|
groups.get(4).map(|group| PathBuf::from(group.as_str()));
|
||||||
Ok(FileTransferParams::new(
|
Ok(FileTransferParams::new(
|
||||||
FileTransferProtocol::AwsS3,
|
FileTransferProtocol::AwsS3,
|
||||||
ProtocolParams::AwsS3(AwsS3Params::new(bucket, Some(region), profile)),
|
ProtocolParams::AwsS3(AwsS3Params::new(bucket, Some(region), profile)),
|
||||||
)
|
)
|
||||||
.entry_directory(entry_directory))
|
.remote_path(remote_path))
|
||||||
}
|
}
|
||||||
None => Err(String::from("Bad remote host syntax!")),
|
None => Err(String::from("Bad remote host syntax!")),
|
||||||
}
|
}
|
||||||
@@ -282,14 +282,14 @@ fn parse_smb_remote_opts(s: &str) -> Result<FileTransferParams, String> {
|
|||||||
Some(group) => group.as_str().to_string(),
|
Some(group) => group.as_str().to_string(),
|
||||||
None => return Err(String::from("Missing address")),
|
None => return Err(String::from("Missing address")),
|
||||||
};
|
};
|
||||||
let entry_directory: Option<PathBuf> =
|
let remote_path: Option<PathBuf> =
|
||||||
groups.get(5).map(|group| PathBuf::from(group.as_str()));
|
groups.get(5).map(|group| PathBuf::from(group.as_str()));
|
||||||
|
|
||||||
Ok(FileTransferParams::new(
|
Ok(FileTransferParams::new(
|
||||||
FileTransferProtocol::Smb,
|
FileTransferProtocol::Smb,
|
||||||
ProtocolParams::Smb(SmbParams::new(address, share).port(port).username(username)),
|
ProtocolParams::Smb(SmbParams::new(address, share).port(port).username(username)),
|
||||||
)
|
)
|
||||||
.entry_directory(entry_directory))
|
.remote_path(remote_path))
|
||||||
}
|
}
|
||||||
None => Err(String::from("Bad remote host syntax!")),
|
None => Err(String::from("Bad remote host syntax!")),
|
||||||
}
|
}
|
||||||
@@ -308,14 +308,14 @@ fn parse_smb_remote_opts(s: &str) -> Result<FileTransferParams, String> {
|
|||||||
Some(group) => group.as_str().to_string(),
|
Some(group) => group.as_str().to_string(),
|
||||||
None => return Err(String::from("Missing address")),
|
None => return Err(String::from("Missing address")),
|
||||||
};
|
};
|
||||||
let entry_directory: Option<PathBuf> =
|
let remote_path: Option<PathBuf> =
|
||||||
groups.get(4).map(|group| PathBuf::from(group.as_str()));
|
groups.get(4).map(|group| PathBuf::from(group.as_str()));
|
||||||
|
|
||||||
Ok(FileTransferParams::new(
|
Ok(FileTransferParams::new(
|
||||||
FileTransferProtocol::Smb,
|
FileTransferProtocol::Smb,
|
||||||
ProtocolParams::Smb(SmbParams::new(address, share).username(username)),
|
ProtocolParams::Smb(SmbParams::new(address, share).username(username)),
|
||||||
)
|
)
|
||||||
.entry_directory(entry_directory))
|
.remote_path(remote_path))
|
||||||
}
|
}
|
||||||
None => Err(String::from("Bad remote host syntax!")),
|
None => Err(String::from("Bad remote host syntax!")),
|
||||||
}
|
}
|
||||||
@@ -441,7 +441,7 @@ mod tests {
|
|||||||
params.username.as_deref().unwrap().to_string(),
|
params.username.as_deref().unwrap().to_string(),
|
||||||
String::from("root")
|
String::from("root")
|
||||||
);
|
);
|
||||||
assert!(result.entry_directory.is_none());
|
assert!(result.remote_path.is_none());
|
||||||
// User + port
|
// User + port
|
||||||
let result: FileTransferParams = parse_remote_opt(&String::from("root@172.26.104.1:8022"))
|
let result: FileTransferParams = parse_remote_opt(&String::from("root@172.26.104.1:8022"))
|
||||||
.ok()
|
.ok()
|
||||||
@@ -454,7 +454,7 @@ mod tests {
|
|||||||
String::from("root")
|
String::from("root")
|
||||||
);
|
);
|
||||||
assert_eq!(result.protocol, FileTransferProtocol::Sftp);
|
assert_eq!(result.protocol, FileTransferProtocol::Sftp);
|
||||||
assert!(result.entry_directory.is_none());
|
assert!(result.remote_path.is_none());
|
||||||
// Port only
|
// Port only
|
||||||
let result: FileTransferParams = parse_remote_opt(&String::from("172.26.104.1:4022"))
|
let result: FileTransferParams = parse_remote_opt(&String::from("172.26.104.1:4022"))
|
||||||
.ok()
|
.ok()
|
||||||
@@ -464,7 +464,7 @@ mod tests {
|
|||||||
assert_eq!(params.address, String::from("172.26.104.1"));
|
assert_eq!(params.address, String::from("172.26.104.1"));
|
||||||
assert_eq!(params.port, 4022);
|
assert_eq!(params.port, 4022);
|
||||||
assert!(params.username.is_none());
|
assert!(params.username.is_none());
|
||||||
assert!(result.entry_directory.is_none());
|
assert!(result.remote_path.is_none());
|
||||||
// Protocol
|
// Protocol
|
||||||
let result: FileTransferParams = parse_remote_opt(&String::from("ftp://172.26.104.1"))
|
let result: FileTransferParams = parse_remote_opt(&String::from("ftp://172.26.104.1"))
|
||||||
.ok()
|
.ok()
|
||||||
@@ -474,7 +474,7 @@ mod tests {
|
|||||||
assert_eq!(params.address, String::from("172.26.104.1"));
|
assert_eq!(params.address, String::from("172.26.104.1"));
|
||||||
assert_eq!(params.port, 21); // Fallback to ftp default
|
assert_eq!(params.port, 21); // Fallback to ftp default
|
||||||
assert!(params.username.is_none()); // Doesn't fall back
|
assert!(params.username.is_none()); // Doesn't fall back
|
||||||
assert!(result.entry_directory.is_none());
|
assert!(result.remote_path.is_none());
|
||||||
// Protocol
|
// Protocol
|
||||||
let result: FileTransferParams = parse_remote_opt(&String::from("sftp://172.26.104.1"))
|
let result: FileTransferParams = parse_remote_opt(&String::from("sftp://172.26.104.1"))
|
||||||
.ok()
|
.ok()
|
||||||
@@ -484,7 +484,7 @@ mod tests {
|
|||||||
assert_eq!(params.address, String::from("172.26.104.1"));
|
assert_eq!(params.address, String::from("172.26.104.1"));
|
||||||
assert_eq!(params.port, 22); // Fallback to sftp default
|
assert_eq!(params.port, 22); // Fallback to sftp default
|
||||||
assert!(params.username.is_none()); // Doesn't fall back
|
assert!(params.username.is_none()); // Doesn't fall back
|
||||||
assert!(result.entry_directory.is_none());
|
assert!(result.remote_path.is_none());
|
||||||
let result: FileTransferParams = parse_remote_opt(&String::from("scp://172.26.104.1"))
|
let result: FileTransferParams = parse_remote_opt(&String::from("scp://172.26.104.1"))
|
||||||
.ok()
|
.ok()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -493,7 +493,7 @@ mod tests {
|
|||||||
assert_eq!(params.address, String::from("172.26.104.1"));
|
assert_eq!(params.address, String::from("172.26.104.1"));
|
||||||
assert_eq!(params.port, 22); // Fallback to scp default
|
assert_eq!(params.port, 22); // Fallback to scp default
|
||||||
assert!(params.username.is_none()); // Doesn't fall back
|
assert!(params.username.is_none()); // Doesn't fall back
|
||||||
assert!(result.entry_directory.is_none());
|
assert!(result.remote_path.is_none());
|
||||||
// Protocol + user
|
// Protocol + user
|
||||||
let result: FileTransferParams =
|
let result: FileTransferParams =
|
||||||
parse_remote_opt(&String::from("ftps://anon@172.26.104.1"))
|
parse_remote_opt(&String::from("ftps://anon@172.26.104.1"))
|
||||||
@@ -507,7 +507,7 @@ mod tests {
|
|||||||
params.username.as_deref().unwrap().to_string(),
|
params.username.as_deref().unwrap().to_string(),
|
||||||
String::from("anon")
|
String::from("anon")
|
||||||
);
|
);
|
||||||
assert!(result.entry_directory.is_none());
|
assert!(result.remote_path.is_none());
|
||||||
// Path
|
// Path
|
||||||
let result: FileTransferParams =
|
let result: FileTransferParams =
|
||||||
parse_remote_opt(&String::from("root@172.26.104.1:8022:/var"))
|
parse_remote_opt(&String::from("root@172.26.104.1:8022:/var"))
|
||||||
@@ -521,7 +521,7 @@ mod tests {
|
|||||||
params.username.as_deref().unwrap().to_string(),
|
params.username.as_deref().unwrap().to_string(),
|
||||||
String::from("root")
|
String::from("root")
|
||||||
);
|
);
|
||||||
assert_eq!(result.entry_directory.unwrap(), PathBuf::from("/var"));
|
assert_eq!(result.remote_path.unwrap(), PathBuf::from("/var"));
|
||||||
// Port only
|
// Port only
|
||||||
let result: FileTransferParams = parse_remote_opt(&String::from("172.26.104.1:home"))
|
let result: FileTransferParams = parse_remote_opt(&String::from("172.26.104.1:home"))
|
||||||
.ok()
|
.ok()
|
||||||
@@ -531,7 +531,7 @@ mod tests {
|
|||||||
assert_eq!(params.address, String::from("172.26.104.1"));
|
assert_eq!(params.address, String::from("172.26.104.1"));
|
||||||
assert_eq!(params.port, 22);
|
assert_eq!(params.port, 22);
|
||||||
assert!(params.username.is_none());
|
assert!(params.username.is_none());
|
||||||
assert_eq!(result.entry_directory.unwrap(), PathBuf::from("home"));
|
assert_eq!(result.remote_path.unwrap(), PathBuf::from("home"));
|
||||||
// All together now
|
// All together now
|
||||||
let result: FileTransferParams =
|
let result: FileTransferParams =
|
||||||
parse_remote_opt(&String::from("ftp://anon@172.26.104.1:8021:/tmp"))
|
parse_remote_opt(&String::from("ftp://anon@172.26.104.1:8021:/tmp"))
|
||||||
@@ -545,7 +545,7 @@ mod tests {
|
|||||||
params.username.as_deref().unwrap().to_string(),
|
params.username.as_deref().unwrap().to_string(),
|
||||||
String::from("anon")
|
String::from("anon")
|
||||||
);
|
);
|
||||||
assert_eq!(result.entry_directory.unwrap(), PathBuf::from("/tmp"));
|
assert_eq!(result.remote_path.unwrap(), PathBuf::from("/tmp"));
|
||||||
// bad syntax
|
// bad syntax
|
||||||
// Bad protocol
|
// Bad protocol
|
||||||
assert!(parse_remote_opt(&String::from("omar://172.26.104.1")).is_err());
|
assert!(parse_remote_opt(&String::from("omar://172.26.104.1")).is_err());
|
||||||
@@ -562,7 +562,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let params = result.params.s3_params().unwrap();
|
let params = result.params.s3_params().unwrap();
|
||||||
assert_eq!(result.protocol, FileTransferProtocol::AwsS3);
|
assert_eq!(result.protocol, FileTransferProtocol::AwsS3);
|
||||||
assert_eq!(result.entry_directory, None);
|
assert_eq!(result.remote_path, None);
|
||||||
assert_eq!(params.bucket_name.as_str(), "mybucket");
|
assert_eq!(params.bucket_name.as_str(), "mybucket");
|
||||||
assert_eq!(params.region.as_deref().unwrap(), "eu-central-1");
|
assert_eq!(params.region.as_deref().unwrap(), "eu-central-1");
|
||||||
assert_eq!(params.profile, None);
|
assert_eq!(params.profile, None);
|
||||||
@@ -573,7 +573,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let params = result.params.s3_params().unwrap();
|
let params = result.params.s3_params().unwrap();
|
||||||
assert_eq!(result.protocol, FileTransferProtocol::AwsS3);
|
assert_eq!(result.protocol, FileTransferProtocol::AwsS3);
|
||||||
assert_eq!(result.entry_directory, None);
|
assert_eq!(result.remote_path, None);
|
||||||
assert_eq!(params.bucket_name.as_str(), "mybucket");
|
assert_eq!(params.bucket_name.as_str(), "mybucket");
|
||||||
assert_eq!(params.region.as_deref().unwrap(), "eu-central-1");
|
assert_eq!(params.region.as_deref().unwrap(), "eu-central-1");
|
||||||
assert_eq!(params.profile.as_deref(), Some("default"));
|
assert_eq!(params.profile.as_deref(), Some("default"));
|
||||||
@@ -584,7 +584,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let params = result.params.s3_params().unwrap();
|
let params = result.params.s3_params().unwrap();
|
||||||
assert_eq!(result.protocol, FileTransferProtocol::AwsS3);
|
assert_eq!(result.protocol, FileTransferProtocol::AwsS3);
|
||||||
assert_eq!(result.entry_directory, Some(PathBuf::from("/foobar")));
|
assert_eq!(result.remote_path, Some(PathBuf::from("/foobar")));
|
||||||
assert_eq!(params.bucket_name.as_str(), "mybucket");
|
assert_eq!(params.bucket_name.as_str(), "mybucket");
|
||||||
assert_eq!(params.region.as_deref().unwrap(), "eu-central-1");
|
assert_eq!(params.region.as_deref().unwrap(), "eu-central-1");
|
||||||
assert_eq!(params.profile, None);
|
assert_eq!(params.profile, None);
|
||||||
@@ -595,7 +595,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let params = result.params.s3_params().unwrap();
|
let params = result.params.s3_params().unwrap();
|
||||||
assert_eq!(result.protocol, FileTransferProtocol::AwsS3);
|
assert_eq!(result.protocol, FileTransferProtocol::AwsS3);
|
||||||
assert_eq!(result.entry_directory, Some(PathBuf::from("/foobar")));
|
assert_eq!(result.remote_path, Some(PathBuf::from("/foobar")));
|
||||||
assert_eq!(params.bucket_name.as_str(), "mybucket");
|
assert_eq!(params.bucket_name.as_str(), "mybucket");
|
||||||
assert_eq!(params.region.as_deref().unwrap(), "eu-central-1");
|
assert_eq!(params.region.as_deref().unwrap(), "eu-central-1");
|
||||||
assert_eq!(params.profile.as_deref(), Some("default"));
|
assert_eq!(params.profile.as_deref(), Some("default"));
|
||||||
@@ -615,7 +615,7 @@ mod tests {
|
|||||||
assert!(params.username.is_some());
|
assert!(params.username.is_some());
|
||||||
assert!(params.password.is_none());
|
assert!(params.password.is_none());
|
||||||
assert!(params.workgroup.is_none());
|
assert!(params.workgroup.is_none());
|
||||||
assert!(result.entry_directory.is_none());
|
assert!(result.remote_path.is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -633,7 +633,7 @@ mod tests {
|
|||||||
assert!(params.workgroup.is_none());
|
assert!(params.workgroup.is_none());
|
||||||
assert_eq!(params.share.as_str(), "myshare");
|
assert_eq!(params.share.as_str(), "myshare");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result.entry_directory.as_deref().unwrap(),
|
result.remote_path.as_deref().unwrap(),
|
||||||
std::path::Path::new("/dir/subdir")
|
std::path::Path::new("/dir/subdir")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -648,7 +648,7 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!(params.address.as_str(), "myserver");
|
assert_eq!(params.address.as_str(), "myserver");
|
||||||
assert_eq!(params.share.as_str(), "myshare");
|
assert_eq!(params.share.as_str(), "myshare");
|
||||||
assert!(result.entry_directory.is_none());
|
assert!(result.remote_path.is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -663,7 +663,7 @@ mod tests {
|
|||||||
assert_eq!(params.share.as_str(), "myshare");
|
assert_eq!(params.share.as_str(), "myshare");
|
||||||
assert_eq!(params.username.as_deref().unwrap(), "omar");
|
assert_eq!(params.username.as_deref().unwrap(), "omar");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result.entry_directory.as_deref().unwrap(),
|
result.remote_path.as_deref().unwrap(),
|
||||||
std::path::Path::new("\\path")
|
std::path::Path::new("\\path")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ pub fn parse_ssh2_config(path: &str) -> Result<SshConfig, String> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
|
||||||
use crate::utils::{ssh::parse_ssh2_config, test_helpers};
|
use crate::utils::ssh::parse_ssh2_config;
|
||||||
|
use crate::utils::test_helpers;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_parse_ssh2_config() {
|
fn should_parse_ssh2_config() {
|
||||||
|
|||||||
Reference in New Issue
Block a user