FileTransferParams as member of Context

This commit is contained in:
veeso
2021-03-21 16:38:11 +01:00
parent bf4f24ceec
commit 30c2aa144b
7 changed files with 101 additions and 90 deletions

View File

@@ -32,9 +32,9 @@ use crate::system::config_client::ConfigClient;
use crate::system::environment; use crate::system::environment;
use crate::ui::activities::{ use crate::ui::activities::{
auth_activity::AuthActivity, filetransfer_activity::FileTransferActivity, auth_activity::AuthActivity, filetransfer_activity::FileTransferActivity,
filetransfer_activity::FileTransferParams, setup_activity::SetupActivity, Activity, setup_activity::SetupActivity, Activity,
}; };
use crate::ui::context::Context; use crate::ui::context::{Context, FileTransferParams};
// Namespaces // Namespaces
use std::thread::sleep; use std::thread::sleep;
@@ -54,7 +54,6 @@ pub enum NextActivity {
/// The activity manager takes care of running activities and handling them until the application has ended /// The activity manager takes care of running activities and handling them until the application has ended
pub struct ActivityManager { pub struct ActivityManager {
context: Option<Context>, context: Option<Context>,
ftparams: Option<FileTransferParams>,
interval: Duration, interval: Duration,
} }
@@ -77,7 +76,6 @@ impl ActivityManager {
let ctx: Context = Context::new(host, config_client, error); let ctx: Context = Context::new(host, config_client, error);
Ok(ActivityManager { Ok(ActivityManager {
context: Some(ctx), context: Some(ctx),
ftparams: None,
interval, interval,
}) })
} }
@@ -94,7 +92,8 @@ impl ActivityManager {
password: Option<String>, password: Option<String>,
entry_directory: Option<PathBuf>, entry_directory: Option<PathBuf>,
) { ) {
self.ftparams = Some(FileTransferParams { // Put params into the context
self.context.as_mut().unwrap().ft_params = Some(FileTransferParams {
address, address,
port, port,
protocol, protocol,
@@ -161,21 +160,6 @@ impl ActivityManager {
if activity.submit { if activity.submit {
// User submitted, set next activity // User submitted, set next activity
result = Some(NextActivity::FileTransfer); result = Some(NextActivity::FileTransfer);
// Get params
self.ftparams = Some(FileTransferParams {
address: activity.address.clone(),
port: activity.port.parse::<u16>().ok().unwrap(),
username: match activity.username.len() {
0 => None,
_ => Some(activity.username.clone()),
},
password: match activity.password.len() {
0 => None,
_ => Some(activity.password.clone()),
},
protocol: activity.protocol,
entry_directory: None, // Has use only when accessing with address
});
break; break;
} }
// Sleep for ticks // Sleep for ticks
@@ -192,19 +176,21 @@ impl ActivityManager {
/// Returns when activity terminates. /// Returns when activity terminates.
/// Returns the next activity to run /// Returns the next activity to run
fn run_filetransfer(&mut self) -> Option<NextActivity> { fn run_filetransfer(&mut self) -> Option<NextActivity> {
if self.ftparams.is_none() {
return Some(NextActivity::Authentication);
}
// Prepare activity
let mut activity: FileTransferActivity =
FileTransferActivity::new(self.ftparams.take().unwrap());
// Prepare result
let result: Option<NextActivity>;
// Get context // Get context
let ctx: Context = match self.context.take() { let ctx: Context = match self.context.take() {
Some(ctx) => ctx, Some(ctx) => ctx,
None => return None, None => return None,
}; };
// If ft params is None, return None
let ft_params: &FileTransferParams = match ctx.ft_params.as_ref() {
Some(ft_params) => &ft_params,
None => return None,
};
// Prepare activity
let protocol: FileTransferProtocol = ft_params.protocol;
let mut activity: FileTransferActivity = FileTransferActivity::new(protocol);
// Prepare result
let result: Option<NextActivity>;
// Create activity // Create activity
activity.on_create(ctx); activity.on_create(ctx);
loop { loop {

View File

@@ -36,6 +36,7 @@ extern crate tui;
use super::{Activity, Context}; use super::{Activity, Context};
use crate::filetransfer::FileTransferProtocol; use crate::filetransfer::FileTransferProtocol;
use crate::system::bookmarks_client::BookmarksClient; use crate::system::bookmarks_client::BookmarksClient;
use crate::ui::context::FileTransferParams;
use crate::ui::layout::view::View; use crate::ui::layout::view::View;
use crate::utils::git; use crate::utils::git;
@@ -68,11 +69,6 @@ const STORE_KEY_LATEST_VERSION: &str = "AUTH_LATEST_VERSION";
/// ///
/// AuthActivity is the data holder for the authentication activity /// AuthActivity is the data holder for the authentication activity
pub struct AuthActivity { pub struct AuthActivity {
pub address: String,
pub port: String,
pub protocol: FileTransferProtocol,
pub username: String,
pub password: String,
pub submit: bool, // becomes true after user has submitted fields pub submit: bool, // becomes true after user has submitted fields
pub quit: bool, // Becomes true if user has pressed esc pub quit: bool, // Becomes true if user has pressed esc
pub setup: bool, // Becomes true if user has requested setup pub setup: bool, // Becomes true if user has requested setup
@@ -96,11 +92,6 @@ impl AuthActivity {
/// Instantiates a new AuthActivity /// Instantiates a new AuthActivity
pub fn new() -> AuthActivity { pub fn new() -> AuthActivity {
AuthActivity { AuthActivity {
address: String::new(),
port: String::from("22"),
protocol: FileTransferProtocol::Sftp,
username: String::new(),
password: String::new(),
submit: false, submit: false,
quit: false, quit: false,
setup: false, setup: false,
@@ -157,7 +148,9 @@ impl Activity for AuthActivity {
/// `on_create` is the function which must be called to initialize the activity. /// `on_create` is the function which must be called to initialize the activity.
/// `on_create` must initialize all the data structures used by the activity /// `on_create` must initialize all the data structures used by the activity
/// Context is taken from activity manager and will be released only when activity is destroyed /// Context is taken from activity manager and will be released only when activity is destroyed
fn on_create(&mut self, context: Context) { fn on_create(&mut self, mut context: Context) {
// Initialize file transfer params
context.ft_params = Some(FileTransferParams::default());
// Set context // Set context
self.context = Some(context); self.context = Some(context);
// Clear terminal // Clear terminal

View File

@@ -25,11 +25,12 @@
// locals // locals
use super::{ use super::{
AuthActivity, COMPONENT_BOOKMARKS_LIST, COMPONENT_INPUT_ADDR, COMPONENT_INPUT_BOOKMARK_NAME, AuthActivity, FileTransferParams, COMPONENT_BOOKMARKS_LIST, COMPONENT_INPUT_ADDR,
COMPONENT_INPUT_PASSWORD, COMPONENT_INPUT_PORT, COMPONENT_INPUT_USERNAME, COMPONENT_INPUT_BOOKMARK_NAME, COMPONENT_INPUT_PASSWORD, COMPONENT_INPUT_PORT,
COMPONENT_RADIO_BOOKMARK_DEL_BOOKMARK, COMPONENT_RADIO_BOOKMARK_DEL_RECENT, COMPONENT_INPUT_USERNAME, COMPONENT_RADIO_BOOKMARK_DEL_BOOKMARK,
COMPONENT_RADIO_BOOKMARK_SAVE_PWD, COMPONENT_RADIO_PROTOCOL, COMPONENT_RADIO_QUIT, COMPONENT_RADIO_BOOKMARK_DEL_RECENT, COMPONENT_RADIO_BOOKMARK_SAVE_PWD,
COMPONENT_RECENTS_LIST, COMPONENT_TEXT_ERROR, COMPONENT_TEXT_HELP, COMPONENT_RADIO_PROTOCOL, COMPONENT_RADIO_QUIT, COMPONENT_RECENTS_LIST, COMPONENT_TEXT_ERROR,
COMPONENT_TEXT_HELP,
}; };
use crate::ui::activities::keymap::*; use crate::ui::activities::keymap::*;
use crate::ui::layout::{Msg, Payload}; use crate::ui::layout::{Msg, Payload};
@@ -319,12 +320,20 @@ impl AuthActivity {
// Match <ENTER> key for all other components // Match <ENTER> key for all other components
self.save_recent(); self.save_recent();
let (address, port, protocol, username, password) = self.get_input(); let (address, port, protocol, username, password) = self.get_input();
// TOREM: remove this after removing states // Set file transfer params to context
self.address = address; let mut ft_params: &mut FileTransferParams =
self.port = port.to_string(); &mut self.context.as_mut().unwrap().ft_params.as_mut().unwrap();
self.protocol = protocol; ft_params.address = address;
self.username = username; ft_params.port = port;
self.password = password; ft_params.protocol = protocol;
ft_params.username = match username.is_empty() {
true => None,
false => Some(username),
};
ft_params.password = match password.is_empty() {
true => None,
false => Some(password),
};
// Submit true // Submit true
self.submit = true; self.submit = true;
// Return None // Return None

View File

@@ -81,18 +81,6 @@ const COMPONENT_RADIO_SORTING: &str = "RADIO_SORTING";
const COMPONENT_RADIO_DELETE: &str = "RADIO_DELETE"; const COMPONENT_RADIO_DELETE: &str = "RADIO_DELETE";
const COMPONENT_LIST_FILEINFO: &str = "LIST_FILEINFO"; const COMPONENT_LIST_FILEINFO: &str = "LIST_FILEINFO";
/// ### FileTransferParams
///
/// Holds connection parameters for file transfers
pub struct FileTransferParams {
pub address: String,
pub port: u16,
pub protocol: FileTransferProtocol,
pub username: Option<String>,
pub password: Option<String>,
pub entry_directory: Option<PathBuf>,
}
/// ## FileExplorerTab /// ## FileExplorerTab
/// ///
/// File explorer tab /// File explorer tab
@@ -215,7 +203,6 @@ pub struct FileTransferActivity {
pub quit: bool, // Has quit term scp? pub quit: bool, // Has quit term scp?
context: Option<Context>, // Context holder context: Option<Context>, // Context holder
view: View, // View view: View, // View
params: FileTransferParams, // FT connection params
client: Box<dyn FileTransfer>, // File transfer client client: Box<dyn FileTransfer>, // File transfer client
local: FileExplorer, // Local File explorer state local: FileExplorer, // Local File explorer state
remote: FileExplorer, // Remote File explorer state remote: FileExplorer, // Remote File explorer state
@@ -230,8 +217,7 @@ impl FileTransferActivity {
/// ### new /// ### new
/// ///
/// Instantiates a new FileTransferActivity /// Instantiates a new FileTransferActivity
pub fn new(params: FileTransferParams) -> FileTransferActivity { pub fn new(protocol: FileTransferProtocol) -> FileTransferActivity {
let protocol: FileTransferProtocol = params.protocol;
// Get config client // Get config client
let config_client: Option<ConfigClient> = Self::init_config_client(); let config_client: Option<ConfigClient> = Self::init_config_client();
FileTransferActivity { FileTransferActivity {
@@ -248,7 +234,6 @@ impl FileTransferActivity {
Self::make_ssh_storage(config_client.as_ref()), Self::make_ssh_storage(config_client.as_ref()),
)), )),
}, },
params,
local: Self::build_explorer(config_client.as_ref()), local: Self::build_explorer(config_client.as_ref()),
remote: Self::build_explorer(config_client.as_ref()), remote: Self::build_explorer(config_client.as_ref()),
tab: FileExplorerTab::Local, tab: FileExplorerTab::Local,
@@ -306,14 +291,10 @@ impl Activity for FileTransferActivity {
} }
// Check if connected (popup must be None, otherwise would try reconnecting in loop in case of error) // Check if connected (popup must be None, otherwise would try reconnecting in loop in case of error)
if !self.client.is_connected() && self.view.get_props(COMPONENT_TEXT_FATAL).is_none() { if !self.client.is_connected() && self.view.get_props(COMPONENT_TEXT_FATAL).is_none() {
let params = self.context.as_ref().unwrap().ft_params.as_ref().unwrap();
let msg: String = format!("Connecting to {}:{}...", params.address, params.port);
// Set init state to connecting popup // Set init state to connecting popup
self.mount_wait( self.mount_wait(msg.as_str());
format!(
"Connecting to {}:{}...",
self.params.address, self.params.port
)
.as_str(),
);
// Force ui draw // Force ui draw
self.view(); self.view();
// Connect to remote // Connect to remote

View File

@@ -47,28 +47,27 @@ impl FileTransferActivity {
/// ///
/// Connect to remote /// Connect to remote
pub(super) fn connect(&mut self) { pub(super) fn connect(&mut self) {
let params = self.context.as_ref().unwrap().ft_params.as_ref().unwrap();
let addr: String = params.address.clone();
let entry_dir: Option<PathBuf> = params.entry_directory.clone();
// Connect to remote // Connect to remote
match self.client.connect( match self.client.connect(
self.params.address.clone(), params.address.clone(),
self.params.port, params.port,
self.params.username.clone(), params.username.clone(),
self.params.password.clone(), params.password.clone(),
) { ) {
Ok(welcome) => { Ok(welcome) => {
if let Some(banner) = welcome { if let Some(banner) = welcome {
// Log welcome // Log welcome
self.log( self.log(
LogLevel::Info, LogLevel::Info,
format!( format!("Established connection with '{}': \"{}\"", addr, banner).as_ref(),
"Established connection with '{}': \"{}\"",
self.params.address, banner
)
.as_ref(),
); );
} }
// 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) = &self.params.entry_directory { if let Some(entry_directory) = &entry_dir {
remote_chdir = Some(entry_directory.clone()); remote_chdir = Some(entry_directory.clone());
} }
if let Some(entry_directory) = remote_chdir { if let Some(entry_directory) = remote_chdir {
@@ -92,8 +91,10 @@ impl FileTransferActivity {
/// ///
/// disconnect from remote /// disconnect from remote
pub(super) fn disconnect(&mut self) { pub(super) fn disconnect(&mut self) {
let params = self.context.as_ref().unwrap().ft_params.as_ref().unwrap();
let msg: String = format!("Disconnecting from {}...", params.address);
// Show popup disconnecting // Show popup disconnecting
self.mount_wait(format!("Disconnecting from {}...", self.params.address).as_str()); self.mount_wait(msg.as_str());
// Disconnect // Disconnect
let _ = self.client.disconnect(); let _ = self.client.disconnect();
// Quit // Quit

View File

@@ -649,12 +649,13 @@ impl FileTransferActivity {
Some(val) => val, Some(val) => val,
None => 256, // Default None => 256, // Default
}; };
let params = self.context.as_ref().unwrap().ft_params.as_ref().unwrap();
let hostname: String = format!( let hostname: String = format!(
"{}:{} ", "{}:{} ",
self.params.address, params.address,
FileTransferActivity::elide_wrkdir_path( FileTransferActivity::elide_wrkdir_path(
self.remote.wrkdir.as_path(), self.remote.wrkdir.as_path(),
self.params.address.as_str(), params.address.as_str(),
width width
) )
.display() .display()

View File

@@ -30,6 +30,7 @@ extern crate tui;
// Locals // Locals
use super::input::InputHandler; use super::input::InputHandler;
use super::store::Store; use super::store::Store;
use crate::filetransfer::FileTransferProtocol;
use crate::host::Localhost; use crate::host::Localhost;
use crate::system::config_client::ConfigClient; use crate::system::config_client::ConfigClient;
@@ -38,6 +39,7 @@ use crossterm::event::DisableMouseCapture;
use crossterm::execute; use crossterm::execute;
use crossterm::terminal::{EnterAlternateScreen, LeaveAlternateScreen}; use crossterm::terminal::{EnterAlternateScreen, LeaveAlternateScreen};
use std::io::{stdout, Stdout}; use std::io::{stdout, Stdout};
use std::path::PathBuf;
use tui::backend::CrosstermBackend; use tui::backend::CrosstermBackend;
use tui::Terminal; use tui::Terminal;
@@ -46,6 +48,7 @@ use tui::Terminal;
/// Context holds data structures used by the ui /// Context holds data structures used by the ui
pub struct Context { pub struct Context {
pub local: Localhost, pub local: Localhost,
pub ft_params: Option<FileTransferParams>,
pub(crate) config_client: Option<ConfigClient>, pub(crate) config_client: Option<ConfigClient>,
pub(crate) store: Store, pub(crate) store: Store,
pub(crate) input_hnd: InputHandler, pub(crate) input_hnd: InputHandler,
@@ -53,6 +56,18 @@ pub struct Context {
error: Option<String>, error: Option<String>,
} }
/// ### FileTransferParams
///
/// Holds connection parameters for file transfers
pub struct FileTransferParams {
pub address: String,
pub port: u16,
pub protocol: FileTransferProtocol,
pub username: Option<String>,
pub password: Option<String>,
pub entry_directory: Option<PathBuf>,
}
impl Context { impl Context {
/// ### new /// ### new
/// ///
@@ -67,6 +82,7 @@ impl Context {
assert!(execute!(stdout, EnterAlternateScreen).is_ok()); assert!(execute!(stdout, EnterAlternateScreen).is_ok());
Context { Context {
local, local,
ft_params: None,
config_client, config_client,
store: Store::init(), store: Store::init(),
input_hnd: InputHandler::new(), input_hnd: InputHandler::new(),
@@ -132,14 +148,38 @@ impl Drop for Context {
} }
} }
/* impl Default for FileTransferParams {
fn default() -> Self {
Self {
address: String::new(),
port: 22,
protocol: FileTransferProtocol::Sftp,
username: None,
password: None,
entry_directory: None,
}
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::filetransfer::sftp_transfer::SftpFileTransfer;
use std::path::PathBuf;
#[test]
fn test_ui_context_ft_params() {
let params: FileTransferParams = FileTransferParams::default();
assert_eq!(params.address.as_str(), "");
assert_eq!(params.port, 22);
assert_eq!(params.protocol, FileTransferProtocol::Sftp);
assert!(params.username.is_none());
assert!(params.password.is_none());
}
//use crate::filetransfer::sftp_transfer::SftpFileTransfer;
//use std::path::PathBuf;
/*
#[test] #[test]
fn test_ui_context_new() { fn test_ui_context_new() {
// Prepare stuff // Prepare stuff
@@ -162,5 +202,5 @@ mod tests {
.is_ok()); .is_ok());
Box::new(sftp_client) Box::new(sftp_client)
} }
*/
} }
*/