FCLauncher/FCLauncher.old/src-tauri/src/sftp.rs

103 lines
3.2 KiB
Rust

use futures_util::future::BoxFuture;
use futures_util::io::BufReader;
use futures_util::io::Cursor;
use futures_util::FutureExt;
use ssh2::OpenFlags;
use ssh2::Session;
use ssh2::Sftp;
use std::io::prelude::*;
use std::net::TcpStream;
use std::path::Path;
use std::path::PathBuf;
use tauri::Emitter;
use crate::https;
pub fn connect(username: String, password: String) -> Result<Session, String> {
let tcp = TcpStream::connect("gitea.piwalker.net:22")
.or(Err(format!("Unable to connect to host")))?;
let mut sess = Session::new().or(Err(format!("Unable to creat stream")))?;
sess.set_tcp_stream(tcp);
sess.handshake().unwrap();
sess.userauth_password(username.as_str(), password.as_str())
.or(Err(format!("Invalid username or password")))?;
Ok(sess)
}
pub async fn uplaod(
window: Option<tauri::AppHandle>,
sess: Session,
path: PathBuf,
mut reader: impl Read,
upload_name: String,
total_size: usize,
) -> Result<(), String> {
let sftp = sess.sftp().or(Err("unable to open sftp session"))?;
let mut file = sftp.create(path.as_path()).or(Err("Unable to open file"))?;
let mut uploaded = 0;
while true {
let mut buf = vec![0u8; 1024 * 32];
let res = reader.read(&mut buf).unwrap();
if res <= 0 {
if let Some(window) = window.clone() {
window
.emit("download_finished", true)
.or(Err(format!("Unable to signal window!")))?;
}
break;
}
file.write_all(buf.split_at(res).0).unwrap();
uploaded += res;
println!(
"Uploading {} {}MB / {}MB",
upload_name,
uploaded / (1024 * 1024),
total_size / (1024 * 1024)
);
if let Some(window) = window.clone() {
window
.emit(
"download_progress",
https::DownloadStatus {
downloaded: uploaded as usize,
total: total_size as usize,
time_elapsed: 0,
download_name: upload_name.clone(),
},
)
.or(Err(format!("Unable to signal window")))?;
}
}
Ok(())
}
pub async fn mkdir(sess: Session, path: PathBuf) -> Result<(), String> {
let sftp = sess.sftp().or(Err("Unable to open sftp session"))?;
sftp.mkdir(path.as_path(), 0o775)
.or(Err(format!("Unable to create directory")))?;
Ok(())
}
pub fn rmdir(sess: Session, path: PathBuf) -> BoxFuture<'static, ()> {
async move {
let sftp = sess.sftp().or(Err("Unable to open sftp session")).unwrap();
let dirs = sftp
.readdir(path.as_path())
.or(Err("unable to stat directory"))
.unwrap();
for dir in dirs {
if dir.1.is_dir() {
rmdir(sess.clone(), dir.0).await;
} else {
sftp.unlink(dir.0.as_path())
.or(Err(format!("Unable to delete file")))
.unwrap();
}
}
sftp.rmdir(path.as_path())
.or(Err(format!("Unable to delete directory")))
.unwrap();
}
.boxed()
}