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
+34 -21
View File
@@ -27,8 +27,9 @@
*/
extern crate tempfile;
// locals
use super::{FileTransferActivity, FsEntry, LogLevel, SelectedEntry};
use super::{FileTransferActivity, FsEntry, LogLevel, SelectedEntry, TransferPayload};
use crate::filetransfer::FileTransferErrorType;
use crate::fs::FsFile;
use std::path::{Path, PathBuf};
impl FileTransferActivity {
@@ -66,7 +67,7 @@ impl FileTransferActivity {
match self.get_remote_selected_entries() {
SelectedEntry::One(entry) => {
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
self.reload_remote_dir();
}
@@ -74,7 +75,7 @@ impl FileTransferActivity {
// Try to copy each file to Input/{FILE_NAME}
let base_path: PathBuf = PathBuf::from(input);
// Iter files
for entry in entries.iter() {
for entry in entries.into_iter() {
let mut dest_path: PathBuf = base_path.clone();
dest_path.push(entry.get_name());
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) {
match self.client.as_mut().copy(entry, dest) {
fn remote_copy_file(&mut self, entry: FsEntry, dest: &Path) {
match self.client.as_mut().copy(&entry, dest) {
Ok(_) => {
self.log(
LogLevel::Info,
@@ -143,7 +144,7 @@ impl FileTransferActivity {
/// ### tricky_copy
///
/// 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 {
FsEntry::File(entry) => {
@@ -159,8 +160,10 @@ impl FileTransferActivity {
}
};
// Download file
let name = entry.name.clone();
let entry_path = entry.abs_path.clone();
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(
LogLevel::Error,
@@ -169,8 +172,8 @@ impl FileTransferActivity {
return;
}
// Get local fs entry
let tmpfile_entry: FsEntry = match self.host.stat(tmpfile.path()) {
Ok(e) => e,
let tmpfile_entry: FsFile = match self.host.stat(tmpfile.path()) {
Ok(e) => e.unwrap_file(),
Err(err) => {
self.log_and_alert(
LogLevel::Error,
@@ -183,14 +186,10 @@ impl FileTransferActivity {
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
let wrkdir = self.remote().wrkdir.clone();
if let Err(err) = self.filetransfer_send_one(
tmpfile_entry,
if let Err(err) = self.filetransfer_send(
TransferPayload::File(tmpfile_entry),
wrkdir.as_path(),
Some(String::from(dest.to_string_lossy())),
) {
@@ -198,7 +197,7 @@ impl FileTransferActivity {
LogLevel::Error,
format!(
"Copy failed: could not write file {}: {}",
entry.abs_path.display(),
entry_path.display(),
err
),
);
@@ -216,11 +215,19 @@ impl FileTransferActivity {
return;
}
};
// Download file
self.filetransfer_recv(entry, tempdir.path(), None);
// Get path of dest
let mut tempdir_path: PathBuf = tempdir.path().to_path_buf();
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
let tempdir_entry: FsEntry = match self.host.stat(tempdir_path.as_path()) {
Ok(e) => e,
@@ -238,11 +245,17 @@ impl FileTransferActivity {
};
// Upload to destination
let wrkdir: PathBuf = self.remote().wrkdir.clone();
self.filetransfer_send(
&tempdir_entry,
if let Err(err) = self.filetransfer_send(
TransferPayload::Any(tempdir_entry),
wrkdir.as_path(),
Some(String::from(dest.to_string_lossy())),
);
) {
self.log_and_alert(
LogLevel::Error,
format!("Copy failed: failed to send file: {}", err),
);
return;
}
}
}
}
+21 -20
View File
@@ -26,7 +26,7 @@
* SOFTWARE.
*/
// locals
use super::{FileTransferActivity, FsEntry, LogLevel, SelectedEntry};
use super::{FileTransferActivity, FsEntry, LogLevel, SelectedEntry, TransferPayload};
use crate::fs::FsFile;
// ext
use crossterm::terminal::{disable_raw_mode, enable_raw_mode};
@@ -67,15 +67,15 @@ impl FileTransferActivity {
SelectedEntry::None => vec![],
};
// Edit all entries
for entry in entries.iter() {
for entry in entries.into_iter() {
// Check if file
if let FsEntry::File(file) = entry {
self.log(
LogLevel::Info,
format!("Opening file \"{}\"...", entry.get_abs_path().display()),
format!("Opening file \"{}\"...", file.abs_path.display()),
);
// 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);
}
}
@@ -141,7 +141,7 @@ impl FileTransferActivity {
/// ### edit_remote_file
///
/// 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
let tmpfile: tempfile::NamedTempFile = match tempfile::NamedTempFile::new() {
Ok(f) => f,
@@ -150,8 +150,14 @@ impl FileTransferActivity {
}
};
// Download file
if let Err(err) = self.filetransfer_recv_one(file, tmpfile.path(), file.name.clone()) {
return Err(format!("Could not open file {}: {}", file.name, err));
let file_name = file.name.clone();
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
let prev_mtime: SystemTime = match self.host.stat(tmpfile.path()) {
@@ -186,12 +192,12 @@ impl FileTransferActivity {
LogLevel::Info,
format!(
"File \"{}\" has changed; writing changes to remote",
file.abs_path.display()
file_path.display()
),
);
// Get local fs entry
let tmpfile_entry: FsEntry = match self.host.stat(tmpfile.path()) {
Ok(e) => e,
let tmpfile_entry: FsFile = match self.host.stat(tmpfile.path()) {
Ok(e) => e.unwrap_file(),
Err(err) => {
return Err(format!(
"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
let wrkdir = self.remote().wrkdir.clone();
if let Err(err) = self.filetransfer_send_one(
tmpfile_entry,
if let Err(err) = self.filetransfer_send(
TransferPayload::File(tmpfile_entry),
wrkdir.as_path(),
Some(file.name.clone()),
Some(file_name),
) {
return Err(format!(
"Could not write file {}: {}",
file.abs_path.display(),
file_path.display(),
err
));
}
@@ -222,7 +223,7 @@ impl FileTransferActivity {
false => {
self.log(
LogLevel::Info,
format!("File \"{}\" hasn't changed", file.abs_path.display()),
format!("File \"{}\" hasn't changed", file_path.display()),
);
}
}
+49 -16
View File
@@ -27,7 +27,7 @@
*/
// locals
use super::super::browser::FileExplorerTab;
use super::{FileTransferActivity, FsEntry, SelectedEntry};
use super::{FileTransferActivity, FsEntry, LogLevel, SelectedEntry, TransferPayload};
use std::path::PathBuf;
@@ -77,10 +77,30 @@ impl FileTransferActivity {
match self.get_found_selected_entries() {
SelectedEntry::One(entry) => match self.browser.tab() {
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 => {
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) => {
@@ -90,21 +110,34 @@ impl FileTransferActivity {
dest_path.push(save_as);
}
// Iter files
for entry in entries.iter() {
match self.browser.tab() {
FileExplorerTab::FindLocal | FileExplorerTab::Local => {
self.filetransfer_send(
&entry.get_realfile(),
dest_path.as_path(),
None,
);
let entries = entries.iter().map(|x| x.get_realfile()).collect();
match self.browser.tab() {
FileExplorerTab::FindLocal | FileExplorerTab::Local => {
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;
}
}
FileExplorerTab::FindRemote | FileExplorerTab::Remote => {
self.filetransfer_recv(
&entry.get_realfile(),
dest_path.as_path(),
None,
}
FileExplorerTab::FindRemote | FileExplorerTab::Remote => {
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;
}
}
}
@@ -25,7 +25,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
pub(self) use super::{FileTransferActivity, FsEntry, LogLevel};
pub(self) use super::{FileTransferActivity, FsEntry, LogLevel, TransferPayload};
use tuirealm::{Payload, Value};
// actions
+53 -7
View File
@@ -26,7 +26,7 @@
* SOFTWARE.
*/
// locals
use super::{FileTransferActivity, SelectedEntry};
use super::{FileTransferActivity, LogLevel, SelectedEntry, TransferPayload};
use std::path::PathBuf;
impl FileTransferActivity {
@@ -50,7 +50,19 @@ impl FileTransferActivity {
let wrkdir: PathBuf = self.remote().wrkdir.clone();
match self.get_local_selected_entries() {
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) => {
// In case of selection: save multiple files in wrkdir/input
@@ -59,8 +71,19 @@ impl FileTransferActivity {
dest_path.push(save_as);
}
// Iter files
for entry in entries.iter() {
self.filetransfer_send(&entry.get_realfile(), dest_path.as_path(), None);
let entries = entries.iter().map(|x| x.get_realfile()).collect();
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 => {}
@@ -71,7 +94,19 @@ impl FileTransferActivity {
let wrkdir: PathBuf = self.local().wrkdir.clone();
match self.get_remote_selected_entries() {
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) => {
// In case of selection: save multiple files in wrkdir/input
@@ -80,8 +115,19 @@ impl FileTransferActivity {
dest_path.push(save_as);
}
// Iter files
for entry in entries.iter() {
self.filetransfer_recv(&entry.get_realfile(), dest_path.as_path(), None);
let entries = entries.iter().map(|x| x.get_realfile()).collect();
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 => {}