Unique function to send and receive files in session.rs via TransferPayload. Fixed transfer size when sending multiple entries

This commit is contained in:
veeso
2021-06-18 13:02:04 +02:00
parent 71e4cc9413
commit 48483a5c99
9 changed files with 298 additions and 99 deletions

View File

@@ -39,6 +39,7 @@ Released on FIXME: ??
- Fixed [Issue 44](https://github.com/veeso/termscp/issues/44): Could not move files to other paths in FTP - Fixed [Issue 44](https://github.com/veeso/termscp/issues/44): Could not move files to other paths in FTP
- Fixed [Issue 43](https://github.com/veeso/termscp/issues/43): Could not remove non-empty directories in FTP - Fixed [Issue 43](https://github.com/veeso/termscp/issues/43): Could not remove non-empty directories in FTP
- Fixed [Issue 39](https://github.com/veeso/termscp/issues/39): Help panels as `ScrollTable` to allow displaying entire content on small screens - Fixed [Issue 39](https://github.com/veeso/termscp/issues/39): Help panels as `ScrollTable` to allow displaying entire content on small screens
- Fixed [Issue 38](https://github.com/veeso/termscp/issues/38): Transfer size was wrong when transferring "selected" files (with mark)
- Fixed [Issue 37](https://github.com/veeso/termscp/issues/37): progress bar not visible when editing remote files - Fixed [Issue 37](https://github.com/veeso/termscp/issues/37): progress bar not visible when editing remote files
- Dependencies: - Dependencies:
- Updated `textwrap` to `0.14.0` - Updated `textwrap` to `0.14.0`

View File

@@ -227,7 +227,6 @@ impl FsEntry {
} }
} }
#[cfg(test)]
/// ### unwrap_file /// ### unwrap_file
/// ///
/// Unwrap FsEntry as FsFile /// Unwrap FsEntry as FsFile

View File

@@ -27,8 +27,9 @@
*/ */
extern crate tempfile; extern crate tempfile;
// locals // locals
use super::{FileTransferActivity, FsEntry, LogLevel, SelectedEntry}; use super::{FileTransferActivity, FsEntry, LogLevel, SelectedEntry, TransferPayload};
use crate::filetransfer::FileTransferErrorType; use crate::filetransfer::FileTransferErrorType;
use crate::fs::FsFile;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
impl FileTransferActivity { impl FileTransferActivity {
@@ -66,7 +67,7 @@ impl FileTransferActivity {
match self.get_remote_selected_entries() { match self.get_remote_selected_entries() {
SelectedEntry::One(entry) => { SelectedEntry::One(entry) => {
let dest_path: PathBuf = PathBuf::from(input); let dest_path: PathBuf = PathBuf::from(input);
self.remote_copy_file(&entry, dest_path.as_path()); self.remote_copy_file(entry, dest_path.as_path());
// Reload entries // Reload entries
self.reload_remote_dir(); self.reload_remote_dir();
} }
@@ -74,7 +75,7 @@ impl FileTransferActivity {
// Try to copy each file to Input/{FILE_NAME} // Try to copy each file to Input/{FILE_NAME}
let base_path: PathBuf = PathBuf::from(input); let base_path: PathBuf = PathBuf::from(input);
// Iter files // Iter files
for entry in entries.iter() { for entry in entries.into_iter() {
let mut dest_path: PathBuf = base_path.clone(); let mut dest_path: PathBuf = base_path.clone();
dest_path.push(entry.get_name()); dest_path.push(entry.get_name());
self.remote_copy_file(entry, dest_path.as_path()); self.remote_copy_file(entry, dest_path.as_path());
@@ -110,8 +111,8 @@ impl FileTransferActivity {
} }
} }
fn remote_copy_file(&mut self, entry: &FsEntry, dest: &Path) { fn remote_copy_file(&mut self, entry: FsEntry, dest: &Path) {
match self.client.as_mut().copy(entry, dest) { match self.client.as_mut().copy(&entry, dest) {
Ok(_) => { Ok(_) => {
self.log( self.log(
LogLevel::Info, LogLevel::Info,
@@ -143,7 +144,7 @@ impl FileTransferActivity {
/// ### tricky_copy /// ### tricky_copy
/// ///
/// Tricky copy will be used whenever copy command is not available on remote host /// Tricky copy will be used whenever copy command is not available on remote host
fn tricky_copy(&mut self, entry: &FsEntry, dest: &Path) { fn tricky_copy(&mut self, entry: FsEntry, dest: &Path) {
// match entry // match entry
match entry { match entry {
FsEntry::File(entry) => { FsEntry::File(entry) => {
@@ -159,8 +160,10 @@ impl FileTransferActivity {
} }
}; };
// Download file // Download file
let name = entry.name.clone();
let entry_path = entry.abs_path.clone();
if let Err(err) = if let Err(err) =
self.filetransfer_recv_one(entry, tmpfile.path(), entry.name.clone()) self.filetransfer_recv(TransferPayload::File(entry), tmpfile.path(), Some(name))
{ {
self.log_and_alert( self.log_and_alert(
LogLevel::Error, LogLevel::Error,
@@ -169,8 +172,8 @@ impl FileTransferActivity {
return; return;
} }
// Get local fs entry // Get local fs entry
let tmpfile_entry: FsEntry = match self.host.stat(tmpfile.path()) { let tmpfile_entry: FsFile = match self.host.stat(tmpfile.path()) {
Ok(e) => e, Ok(e) => e.unwrap_file(),
Err(err) => { Err(err) => {
self.log_and_alert( self.log_and_alert(
LogLevel::Error, LogLevel::Error,
@@ -183,14 +186,10 @@ impl FileTransferActivity {
return; return;
} }
}; };
let tmpfile_entry = match &tmpfile_entry {
FsEntry::Directory(_) => panic!("tempfile is a directory for some reason"),
FsEntry::File(f) => f,
};
// Upload file to destination // Upload file to destination
let wrkdir = self.remote().wrkdir.clone(); let wrkdir = self.remote().wrkdir.clone();
if let Err(err) = self.filetransfer_send_one( if let Err(err) = self.filetransfer_send(
tmpfile_entry, TransferPayload::File(tmpfile_entry),
wrkdir.as_path(), wrkdir.as_path(),
Some(String::from(dest.to_string_lossy())), Some(String::from(dest.to_string_lossy())),
) { ) {
@@ -198,7 +197,7 @@ impl FileTransferActivity {
LogLevel::Error, LogLevel::Error,
format!( format!(
"Copy failed: could not write file {}: {}", "Copy failed: could not write file {}: {}",
entry.abs_path.display(), entry_path.display(),
err err
), ),
); );
@@ -216,11 +215,19 @@ impl FileTransferActivity {
return; return;
} }
}; };
// Download file
self.filetransfer_recv(entry, tempdir.path(), None);
// Get path of dest // Get path of dest
let mut tempdir_path: PathBuf = tempdir.path().to_path_buf(); let mut tempdir_path: PathBuf = tempdir.path().to_path_buf();
tempdir_path.push(entry.get_name()); tempdir_path.push(entry.get_name());
// Download file
if let Err(err) =
self.filetransfer_recv(TransferPayload::Any(entry), tempdir.path(), None)
{
self.log_and_alert(
LogLevel::Error,
format!("Copy failed: failed to download file: {}", err),
);
return;
}
// Stat dir // Stat dir
let tempdir_entry: FsEntry = match self.host.stat(tempdir_path.as_path()) { let tempdir_entry: FsEntry = match self.host.stat(tempdir_path.as_path()) {
Ok(e) => e, Ok(e) => e,
@@ -238,11 +245,17 @@ impl FileTransferActivity {
}; };
// Upload to destination // Upload to destination
let wrkdir: PathBuf = self.remote().wrkdir.clone(); let wrkdir: PathBuf = self.remote().wrkdir.clone();
self.filetransfer_send( if let Err(err) = self.filetransfer_send(
&tempdir_entry, TransferPayload::Any(tempdir_entry),
wrkdir.as_path(), wrkdir.as_path(),
Some(String::from(dest.to_string_lossy())), Some(String::from(dest.to_string_lossy())),
) {
self.log_and_alert(
LogLevel::Error,
format!("Copy failed: failed to send file: {}", err),
); );
return;
}
} }
} }
} }

View File

@@ -26,7 +26,7 @@
* SOFTWARE. * SOFTWARE.
*/ */
// locals // locals
use super::{FileTransferActivity, FsEntry, LogLevel, SelectedEntry}; use super::{FileTransferActivity, FsEntry, LogLevel, SelectedEntry, TransferPayload};
use crate::fs::FsFile; use crate::fs::FsFile;
// ext // ext
use crossterm::terminal::{disable_raw_mode, enable_raw_mode}; use crossterm::terminal::{disable_raw_mode, enable_raw_mode};
@@ -67,15 +67,15 @@ impl FileTransferActivity {
SelectedEntry::None => vec![], SelectedEntry::None => vec![],
}; };
// Edit all entries // Edit all entries
for entry in entries.iter() { for entry in entries.into_iter() {
// Check if file // Check if file
if let FsEntry::File(file) = entry { if let FsEntry::File(file) = entry {
self.log( self.log(
LogLevel::Info, LogLevel::Info,
format!("Opening file \"{}\"...", entry.get_abs_path().display()), format!("Opening file \"{}\"...", file.abs_path.display()),
); );
// Edit file // Edit file
if let Err(err) = self.edit_remote_file(&file) { if let Err(err) = self.edit_remote_file(file) {
self.log_and_alert(LogLevel::Error, err); self.log_and_alert(LogLevel::Error, err);
} }
} }
@@ -141,7 +141,7 @@ impl FileTransferActivity {
/// ### edit_remote_file /// ### edit_remote_file
/// ///
/// Edit file on remote host /// Edit file on remote host
fn edit_remote_file(&mut self, file: &FsFile) -> Result<(), String> { fn edit_remote_file(&mut self, file: FsFile) -> Result<(), String> {
// Create temp file // Create temp file
let tmpfile: tempfile::NamedTempFile = match tempfile::NamedTempFile::new() { let tmpfile: tempfile::NamedTempFile = match tempfile::NamedTempFile::new() {
Ok(f) => f, Ok(f) => f,
@@ -150,8 +150,14 @@ impl FileTransferActivity {
} }
}; };
// Download file // Download file
if let Err(err) = self.filetransfer_recv_one(file, tmpfile.path(), file.name.clone()) { let file_name = file.name.clone();
return Err(format!("Could not open file {}: {}", file.name, err)); let file_path = file.abs_path.clone();
if let Err(err) = self.filetransfer_recv(
TransferPayload::File(file),
tmpfile.path(),
Some(file_name.clone()),
) {
return Err(format!("Could not open file {}: {}", file_name, err));
} }
// Get current file modification time // Get current file modification time
let prev_mtime: SystemTime = match self.host.stat(tmpfile.path()) { let prev_mtime: SystemTime = match self.host.stat(tmpfile.path()) {
@@ -186,12 +192,12 @@ impl FileTransferActivity {
LogLevel::Info, LogLevel::Info,
format!( format!(
"File \"{}\" has changed; writing changes to remote", "File \"{}\" has changed; writing changes to remote",
file.abs_path.display() file_path.display()
), ),
); );
// Get local fs entry // Get local fs entry
let tmpfile_entry: FsEntry = match self.host.stat(tmpfile.path()) { let tmpfile_entry: FsFile = match self.host.stat(tmpfile.path()) {
Ok(e) => e, Ok(e) => e.unwrap_file(),
Err(err) => { Err(err) => {
return Err(format!( return Err(format!(
"Could not stat \"{}\": {}", "Could not stat \"{}\": {}",
@@ -200,21 +206,16 @@ impl FileTransferActivity {
)) ))
} }
}; };
// Write file
let tmpfile_entry: &FsFile = match &tmpfile_entry {
FsEntry::Directory(_) => panic!("tempfile is a directory for some reason"),
FsEntry::File(f) => f,
};
// Send file // Send file
let wrkdir = self.remote().wrkdir.clone(); let wrkdir = self.remote().wrkdir.clone();
if let Err(err) = self.filetransfer_send_one( if let Err(err) = self.filetransfer_send(
tmpfile_entry, TransferPayload::File(tmpfile_entry),
wrkdir.as_path(), wrkdir.as_path(),
Some(file.name.clone()), Some(file_name),
) { ) {
return Err(format!( return Err(format!(
"Could not write file {}: {}", "Could not write file {}: {}",
file.abs_path.display(), file_path.display(),
err err
)); ));
} }
@@ -222,7 +223,7 @@ impl FileTransferActivity {
false => { false => {
self.log( self.log(
LogLevel::Info, LogLevel::Info,
format!("File \"{}\" hasn't changed", file.abs_path.display()), format!("File \"{}\" hasn't changed", file_path.display()),
); );
} }
} }

View File

@@ -27,7 +27,7 @@
*/ */
// locals // locals
use super::super::browser::FileExplorerTab; use super::super::browser::FileExplorerTab;
use super::{FileTransferActivity, FsEntry, SelectedEntry}; use super::{FileTransferActivity, FsEntry, LogLevel, SelectedEntry, TransferPayload};
use std::path::PathBuf; use std::path::PathBuf;
@@ -77,10 +77,30 @@ impl FileTransferActivity {
match self.get_found_selected_entries() { match self.get_found_selected_entries() {
SelectedEntry::One(entry) => match self.browser.tab() { SelectedEntry::One(entry) => match self.browser.tab() {
FileExplorerTab::FindLocal | FileExplorerTab::Local => { FileExplorerTab::FindLocal | FileExplorerTab::Local => {
self.filetransfer_send(&entry.get_realfile(), wrkdir.as_path(), save_as); if let Err(err) = self.filetransfer_send(
TransferPayload::Any(entry.get_realfile()),
wrkdir.as_path(),
save_as,
) {
self.log_and_alert(
LogLevel::Error,
format!("Could not upload file: {}", err),
);
return;
}
} }
FileExplorerTab::FindRemote | FileExplorerTab::Remote => { FileExplorerTab::FindRemote | FileExplorerTab::Remote => {
self.filetransfer_recv(&entry.get_realfile(), wrkdir.as_path(), save_as); if let Err(err) = self.filetransfer_recv(
TransferPayload::Any(entry.get_realfile()),
wrkdir.as_path(),
save_as,
) {
self.log_and_alert(
LogLevel::Error,
format!("Could not download file: {}", err),
);
return;
}
} }
}, },
SelectedEntry::Many(entries) => { SelectedEntry::Many(entries) => {
@@ -90,21 +110,34 @@ impl FileTransferActivity {
dest_path.push(save_as); dest_path.push(save_as);
} }
// Iter files // Iter files
for entry in entries.iter() { let entries = entries.iter().map(|x| x.get_realfile()).collect();
match self.browser.tab() { match self.browser.tab() {
FileExplorerTab::FindLocal | FileExplorerTab::Local => { FileExplorerTab::FindLocal | FileExplorerTab::Local => {
self.filetransfer_send( if let Err(err) = self.filetransfer_send(
&entry.get_realfile(), TransferPayload::Many(entries),
dest_path.as_path(), dest_path.as_path(),
None, None,
) {
{
self.log_and_alert(
LogLevel::Error,
format!("Could not upload file: {}", err),
); );
return;
}
}
} }
FileExplorerTab::FindRemote | FileExplorerTab::Remote => { FileExplorerTab::FindRemote | FileExplorerTab::Remote => {
self.filetransfer_recv( if let Err(err) = self.filetransfer_recv(
&entry.get_realfile(), TransferPayload::Many(entries),
dest_path.as_path(), dest_path.as_path(),
None, None,
) {
self.log_and_alert(
LogLevel::Error,
format!("Could not download file: {}", err),
); );
return;
} }
} }
} }

View File

@@ -25,7 +25,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
pub(self) use super::{FileTransferActivity, FsEntry, LogLevel}; pub(self) use super::{FileTransferActivity, FsEntry, LogLevel, TransferPayload};
use tuirealm::{Payload, Value}; use tuirealm::{Payload, Value};
// actions // actions

View File

@@ -26,7 +26,7 @@
* SOFTWARE. * SOFTWARE.
*/ */
// locals // locals
use super::{FileTransferActivity, SelectedEntry}; use super::{FileTransferActivity, LogLevel, SelectedEntry, TransferPayload};
use std::path::PathBuf; use std::path::PathBuf;
impl FileTransferActivity { impl FileTransferActivity {
@@ -50,7 +50,19 @@ impl FileTransferActivity {
let wrkdir: PathBuf = self.remote().wrkdir.clone(); let wrkdir: PathBuf = self.remote().wrkdir.clone();
match self.get_local_selected_entries() { match self.get_local_selected_entries() {
SelectedEntry::One(entry) => { SelectedEntry::One(entry) => {
self.filetransfer_send(&entry.get_realfile(), wrkdir.as_path(), save_as); if let Err(err) = self.filetransfer_send(
TransferPayload::Any(entry.get_realfile()),
wrkdir.as_path(),
save_as,
) {
{
self.log_and_alert(
LogLevel::Error,
format!("Could not upload file: {}", err),
);
return;
}
}
} }
SelectedEntry::Many(entries) => { SelectedEntry::Many(entries) => {
// In case of selection: save multiple files in wrkdir/input // In case of selection: save multiple files in wrkdir/input
@@ -59,8 +71,19 @@ impl FileTransferActivity {
dest_path.push(save_as); dest_path.push(save_as);
} }
// Iter files // Iter files
for entry in entries.iter() { let entries = entries.iter().map(|x| x.get_realfile()).collect();
self.filetransfer_send(&entry.get_realfile(), dest_path.as_path(), None); if let Err(err) = self.filetransfer_send(
TransferPayload::Many(entries),
dest_path.as_path(),
None,
) {
{
self.log_and_alert(
LogLevel::Error,
format!("Could not upload file: {}", err),
);
return;
}
} }
} }
SelectedEntry::None => {} SelectedEntry::None => {}
@@ -71,7 +94,19 @@ impl FileTransferActivity {
let wrkdir: PathBuf = self.local().wrkdir.clone(); let wrkdir: PathBuf = self.local().wrkdir.clone();
match self.get_remote_selected_entries() { match self.get_remote_selected_entries() {
SelectedEntry::One(entry) => { SelectedEntry::One(entry) => {
self.filetransfer_recv(&entry.get_realfile(), wrkdir.as_path(), save_as); if let Err(err) = self.filetransfer_recv(
TransferPayload::Any(entry.get_realfile()),
wrkdir.as_path(),
save_as,
) {
{
self.log_and_alert(
LogLevel::Error,
format!("Could not download file: {}", err),
);
return;
}
}
} }
SelectedEntry::Many(entries) => { SelectedEntry::Many(entries) => {
// In case of selection: save multiple files in wrkdir/input // In case of selection: save multiple files in wrkdir/input
@@ -80,8 +115,19 @@ impl FileTransferActivity {
dest_path.push(save_as); dest_path.push(save_as);
} }
// Iter files // Iter files
for entry in entries.iter() { let entries = entries.iter().map(|x| x.get_realfile()).collect();
self.filetransfer_recv(&entry.get_realfile(), dest_path.as_path(), None); if let Err(err) = self.filetransfer_recv(
TransferPayload::Many(entries),
dest_path.as_path(),
None,
) {
{
self.log_and_alert(
LogLevel::Error,
format!("Could not download file: {}", err),
);
return;
}
} }
} }
SelectedEntry::None => {} SelectedEntry::None => {}

View File

@@ -49,9 +49,10 @@ use crate::fs::explorer::FileExplorer;
use crate::fs::FsEntry; use crate::fs::FsEntry;
use crate::host::Localhost; use crate::host::Localhost;
use crate::system::config_client::ConfigClient; use crate::system::config_client::ConfigClient;
pub(crate) use lib::browser; pub(self) use lib::browser;
use lib::browser::Browser; use lib::browser::Browser;
use lib::transfer::TransferStates; use lib::transfer::TransferStates;
pub(self) use session::TransferPayload;
// Includes // Includes
use chrono::{DateTime, Local}; use chrono::{DateTime, Local};

View File

@@ -64,6 +64,19 @@ enum TransferErrorReason {
FileTransferError(FileTransferError), FileTransferError(FileTransferError),
} }
/// ## TransferPayload
///
/// Represents the entity to send or receive during a transfer.
/// - File: describes an individual `FsFile` to send
/// - Any: Can be any kind of `FsEntry`, but just one
/// - Many: a list of `FsEntry`
#[derive(Debug)]
pub(super) enum TransferPayload {
File(FsFile),
Any(FsEntry),
Many(Vec<FsEntry>),
}
impl FileTransferActivity { impl FileTransferActivity {
/// ### connect /// ### connect
/// ///
@@ -155,27 +168,28 @@ impl FileTransferActivity {
/// If entry is a directory, this applies to directory only /// If entry is a directory, this applies to directory only
pub(super) fn filetransfer_send( pub(super) fn filetransfer_send(
&mut self, &mut self,
entry: &FsEntry, payload: TransferPayload,
curr_remote_path: &Path, curr_remote_path: &Path,
dst_name: Option<String>, dst_name: Option<String>,
) { ) -> Result<(), String> {
// Reset states // Use different method based on payload
self.transfer.reset(); match payload {
// Calculate total size of transfer TransferPayload::Any(entry) => {
let total_transfer_size: usize = self.get_total_transfer_size_local(entry); self.filetransfer_send_any(&entry, curr_remote_path, dst_name)
self.transfer.full.init(total_transfer_size); }
// Mount progress bar TransferPayload::File(file) => {
self.mount_progress_bar(format!("Uploading {}...", entry.get_abs_path().display())); self.filetransfer_send_file(&file, curr_remote_path, dst_name)
// Send recurse }
self.filetransfer_send_recurse(entry, curr_remote_path, dst_name); TransferPayload::Many(entries) => {
// Umount progress bar self.filetransfer_send_many(entries, curr_remote_path)
self.umount_progress_bar(); }
}
} }
/// ### filetransfer_send_one /// ### filetransfer_send_file
/// ///
/// Send one file to remote at specified path. /// Send one file to remote at specified path.
pub(super) fn filetransfer_send_one( fn filetransfer_send_file(
&mut self, &mut self,
file: &FsFile, file: &FsFile,
curr_remote_path: &Path, curr_remote_path: &Path,
@@ -197,13 +211,64 @@ impl FileTransferActivity {
}; };
remote_path.push(remote_file_name); remote_path.push(remote_file_name);
// Send // Send
let result = self.filetransfer_send_file(file, remote_path.as_path(), file_name); let result = self.filetransfer_send_one(file, remote_path.as_path(), file_name);
// Umount progress bar // Umount progress bar
self.umount_progress_bar(); self.umount_progress_bar();
// Return result // Return result
result.map_err(|x| x.to_string()) result.map_err(|x| x.to_string())
} }
/// ### filetransfer_send_any
///
/// Send a `TransferPayload` of type `Any`
fn filetransfer_send_any(
&mut self,
entry: &FsEntry,
curr_remote_path: &Path,
dst_name: Option<String>,
) -> Result<(), String> {
// Reset states
self.transfer.reset();
// Calculate total size of transfer
let total_transfer_size: usize = self.get_total_transfer_size_local(entry);
self.transfer.full.init(total_transfer_size);
// Mount progress bar
self.mount_progress_bar(format!("Uploading {}...", entry.get_abs_path().display()));
// Send recurse
self.filetransfer_send_recurse(entry, curr_remote_path, dst_name);
// Umount progress bar
self.umount_progress_bar();
Ok(())
}
/// ### filetransfer_send_many
///
/// Send many entries to remote
fn filetransfer_send_many(
&mut self,
entries: Vec<FsEntry>,
curr_remote_path: &Path,
) -> Result<(), String> {
// Reset states
self.transfer.reset();
// Calculate total size of transfer
let mut total_transfer_size: usize = 0;
for entry in entries.iter() {
total_transfer_size += self.get_total_transfer_size_local(entry);
}
self.transfer.full.init(total_transfer_size);
// Mount progress bar
self.mount_progress_bar(format!("Uploading {} entries...", entries.len()));
// Send recurse
for entry in entries.iter() {
// Send
self.filetransfer_send_recurse(entry, curr_remote_path, None);
}
// Umount progress bar
self.umount_progress_bar();
Ok(())
}
fn filetransfer_send_recurse( fn filetransfer_send_recurse(
&mut self, &mut self,
entry: &FsEntry, entry: &FsEntry,
@@ -225,8 +290,7 @@ impl FileTransferActivity {
// Match entry // Match entry
match entry { match entry {
FsEntry::File(file) => { FsEntry::File(file) => {
if let Err(err) = if let Err(err) = self.filetransfer_send_one(file, remote_path.as_path(), file_name)
self.filetransfer_send_file(file, remote_path.as_path(), file_name)
{ {
// Log error // Log error
self.log_and_alert( self.log_and_alert(
@@ -329,7 +393,7 @@ impl FileTransferActivity {
/// ### filetransfer_send_file /// ### filetransfer_send_file
/// ///
/// Send local file and write it to remote path /// Send local file and write it to remote path
fn filetransfer_send_file( fn filetransfer_send_one(
&mut self, &mut self,
local: &FsFile, local: &FsFile,
remote: &Path, remote: &Path,
@@ -438,11 +502,29 @@ impl FileTransferActivity {
/// If dst_name is Some, entry will be saved with a different name. /// If dst_name is Some, entry will be saved with a different name.
/// If entry is a directory, this applies to directory only /// If entry is a directory, this applies to directory only
pub(super) fn filetransfer_recv( pub(super) fn filetransfer_recv(
&mut self,
payload: TransferPayload,
local_path: &Path,
dst_name: Option<String>,
) -> Result<(), String> {
match payload {
TransferPayload::Any(entry) => self.filetransfer_recv_any(&entry, local_path, dst_name),
TransferPayload::File(file) => self.filetransfer_recv_file(&file, local_path),
TransferPayload::Many(entries) => self.filetransfer_recv_many(entries, local_path),
}
}
/// ### filetransfer_recv_any
///
/// Recv fs entry from remote.
/// If dst_name is Some, entry will be saved with a different name.
/// If entry is a directory, this applies to directory only
fn filetransfer_recv_any(
&mut self, &mut self,
entry: &FsEntry, entry: &FsEntry,
local_path: &Path, local_path: &Path,
dst_name: Option<String>, dst_name: Option<String>,
) { ) -> Result<(), String> {
// Reset states // Reset states
self.transfer.reset(); self.transfer.reset();
// Calculate total transfer size // Calculate total transfer size
@@ -454,18 +536,13 @@ impl FileTransferActivity {
self.filetransfer_recv_recurse(entry, local_path, dst_name); self.filetransfer_recv_recurse(entry, local_path, dst_name);
// Umount progress bar // Umount progress bar
self.umount_progress_bar(); self.umount_progress_bar();
Ok(())
} }
/// ### filetransfer_recv_one /// ### filetransfer_recv_file
/// ///
/// Receive a single file from remote. /// Receive a single file from remote.
/// Use this function instead of `filetransfer_recv_file` from external files fn filetransfer_recv_file(&mut self, entry: &FsFile, local_path: &Path) -> Result<(), String> {
pub(super) fn filetransfer_recv_one(
&mut self,
entry: &FsFile,
local_path: &Path,
dst_name: String,
) -> Result<(), String> {
// Reset states // Reset states
self.transfer.reset(); self.transfer.reset();
// Calculate total transfer size // Calculate total transfer size
@@ -474,13 +551,41 @@ impl FileTransferActivity {
// Mount progress bar // Mount progress bar
self.mount_progress_bar(format!("Downloading {}...", entry.abs_path.display())); self.mount_progress_bar(format!("Downloading {}...", entry.abs_path.display()));
// Receive // Receive
let result = self.filetransfer_recv_file(local_path, entry, dst_name); let result = self.filetransfer_recv_one(local_path, entry, entry.name.clone());
// Umount progress bar // Umount progress bar
self.umount_progress_bar(); self.umount_progress_bar();
// Return result // Return result
result.map_err(|x| x.to_string()) result.map_err(|x| x.to_string())
} }
/// ### filetransfer_send_many
///
/// Send many entries to remote
fn filetransfer_recv_many(
&mut self,
entries: Vec<FsEntry>,
curr_remote_path: &Path,
) -> Result<(), String> {
// Reset states
self.transfer.reset();
// Calculate total size of transfer
let mut total_transfer_size: usize = 0;
for entry in entries.iter() {
total_transfer_size += self.get_total_transfer_size_remote(entry);
}
self.transfer.full.init(total_transfer_size);
// Mount progress bar
self.mount_progress_bar(format!("Uploading {} entries...", entries.len()));
// Send recurse
for entry in entries.iter() {
// Send
self.filetransfer_recv_recurse(entry, curr_remote_path, None);
}
// Umount progress bar
self.umount_progress_bar();
Ok(())
}
fn filetransfer_recv_recurse( fn filetransfer_recv_recurse(
&mut self, &mut self,
entry: &FsEntry, entry: &FsEntry,
@@ -504,7 +609,7 @@ impl FileTransferActivity {
local_file_path.push(local_file_name.as_str()); local_file_path.push(local_file_name.as_str());
// Download file // Download file
if let Err(err) = if let Err(err) =
self.filetransfer_recv_file(local_file_path.as_path(), file, file_name) self.filetransfer_recv_one(local_file_path.as_path(), file, file_name)
{ {
self.log_and_alert( self.log_and_alert(
LogLevel::Error, LogLevel::Error,
@@ -628,10 +733,10 @@ impl FileTransferActivity {
} }
} }
/// ### filetransfer_recv_file /// ### filetransfer_recv_one
/// ///
/// Receive file from remote and write it to local path /// Receive file from remote and write it to local path
fn filetransfer_recv_file( fn filetransfer_recv_one(
&mut self, &mut self,
local: &Path, local: &Path,
remote: &FsFile, remote: &FsFile,