refractored code

This commit is contained in:
Waradu 2024-10-20 17:21:39 +02:00
parent 11456948d5
commit 2d635f5807
No known key found for this signature in database
GPG key ID: F85AAC8BA8B8DAAD
4 changed files with 116 additions and 85 deletions

2
Cargo.lock generated
View file

@ -1084,7 +1084,7 @@ checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
[[package]]
name = "streamshare"
version = "3.0.0"
version = "4.0.0"
dependencies = [
"futures",
"reqwest",

View file

@ -1,6 +1,6 @@
[package]
name = "streamshare"
version = "3.0.0"
version = "4.0.0"
edition = "2021"
description = "Upload to streamshare library"
license = "MIT"

View file

@ -7,6 +7,8 @@ Upload files to [streamshare](https://streamshare.wireway.ch)
Upload:
```rust
let client = StreamShare::default();
let callback = |uploaded_bytes, total_bytes| {
println!(
"Uploaded {}b of {}b",
@ -15,7 +17,7 @@ let callback = |uploaded_bytes, total_bytes| {
);
}
match upload(&file_path, callback).await {
match client.upload(&file_path, callback).await {
Ok((file_identifier, _deletion_token)) => {
let download_url = format!(
"https://streamshare.wireway.ch/download/{}",
@ -32,7 +34,9 @@ match upload(&file_path, callback).await {
Delete:
```rust
match streamshare::delete(file_identifier, deletion_token).await {
let client = StreamShare::default();
match client.delete(file_identifier, deletion_token).await {
Ok(_) => println!("File deleted successfully"),
Err(e) => eprintln!("Error deleting file: {}", e),
}

View file

@ -17,97 +17,124 @@ struct CreateResponse {
deletion_token: String,
}
pub async fn upload<F>(file_path: &str, mut callback: F) -> Result<(String, String), Box<dyn std::error::Error>>
where
F: FnMut(u64, u64)
{
let path = Path::new(file_path);
let metadata = fs::metadata(path).await?;
if !metadata.is_file() {
return Err("Selected item is not a file".into());
pub struct StreamShare {
server_url: String,
chunk_size: usize,
client: Client,
}
impl StreamShare {
pub fn new(server_url: String, chunk_size: usize) -> Self {
Self {
server_url: server_url,
chunk_size: chunk_size,
client: Client::new(),
}
}
let file_size = metadata.len();
let file_name = path
.file_name()
.and_then(|s| s.to_str())
.unwrap_or("unknown");
let client = Client::new();
let create_url = "https://streamshare.wireway.ch/api/create";
let res = client
.post(create_url)
.json(&serde_json::json!({ "name": file_name }))
.send()
.await?;
if !res.status().is_success() {
return Err(format!("Failed to create upload: {}", res.status()).into());
}
let create_response: CreateResponse = res.json().await?;
let ws_url = format!(
"wss://streamshare.wireway.ch/api/upload/{}",
create_response.file_identifier
);
let (mut ws_stream, _) = connect_async(ws_url).await?;
let mut file = File::open(path).await?;
const CHUNK_SIZE: usize = 1024 * 1024;
let mut buffer = vec![0u8; CHUNK_SIZE];
let mut uploaded: u64 = 0;
loop {
let n = file.read(&mut buffer).await?;
if n == 0 {
break;
pub async fn upload<F>(
&self,
file_path: &str,
mut callback: F,
) -> Result<(String, String), Box<dyn std::error::Error>>
where
F: FnMut(u64, u64),
{
let path = Path::new(file_path);
let metadata = fs::metadata(path).await?;
if !metadata.is_file() {
return Err(format!("Selected item is not a file: {}", file_path).into());
}
let chunk = &buffer[..n];
ws_stream.send(Message::Binary(chunk.to_vec())).await?;
uploaded += n as u64;
let file_size = metadata.len();
let file_name = path
.file_name()
.and_then(|s| s.to_str())
.unwrap_or("unknown");
callback(uploaded, file_size);
let create_url = format!("https://{}/api/create", self.server_url);
match ws_stream.next().await {
Some(Ok(Message::Text(text))) if text == "ACK" => (),
Some(Ok(msg)) => {
return Err(format!("Unexpected message: {:?}", msg).into());
let res = self
.client
.post(&create_url)
.json(&serde_json::json!({ "name": file_name }))
.send()
.await?;
if !res.status().is_success() {
return Err(format!("Failed to create upload: {}", res.status()).into());
}
let create_response: CreateResponse = res.json().await?;
let ws_url = format!(
"wss://{}/api/upload/{}",
self.server_url, create_response.file_identifier
);
let (mut ws_stream, _) = connect_async(ws_url).await?;
let mut file = File::open(path).await?;
let mut buffer = vec![0u8; self.chunk_size];
let mut uploaded: u64 = 0;
loop {
let n = file.read(&mut buffer).await?;
if n == 0 {
break;
}
Some(Err(e)) => return Err(format!("WebSocket error: {}", e).into()),
None => return Err("WebSocket closed unexpectedly".into()),
let chunk = &buffer[..n];
ws_stream.send(Message::Binary(chunk.to_vec())).await?;
uploaded += n as u64;
callback(uploaded, file_size);
match ws_stream.next().await {
Some(Ok(Message::Text(text))) if text == "ACK" => (),
Some(Ok(msg)) => {
return Err(format!("Unexpected message: {:?}", msg).into());
}
Some(Err(e)) => return Err(format!("WebSocket error: {}", e).into()),
None => return Err("WebSocket closed unexpectedly".into()),
}
}
ws_stream
.close(Some(tungstenite::protocol::CloseFrame {
code: tungstenite::protocol::frame::coding::CloseCode::Normal,
reason: "FILE_UPLOAD_DONE".into(),
}))
.await?;
Ok((
create_response.file_identifier,
create_response.deletion_token,
))
}
pub async fn delete(
&self,
file_identifier: &str,
deletion_token: &str,
) -> Result<(), Box<dyn std::error::Error>> {
let delete_url = format!(
"https://{}/api/delete/{}/{}",
self.server_url, file_identifier, deletion_token
);
let res = self.client.delete(&delete_url).send().await?;
if res.status().is_success() {
Ok(())
} else {
Err(format!("Failed to delete file: {}", res.status()).into())
}
}
ws_stream
.close(Some(tungstenite::protocol::CloseFrame {
code: tungstenite::protocol::frame::coding::CloseCode::Normal,
reason: "FILE_UPLOAD_DONE".into(),
}))
.await?;
Ok((
create_response.file_identifier,
create_response.deletion_token,
))
}
pub async fn delete(
file_identifier: &str,
deletion_token: &str,
) -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new();
let delete_url = format!(
"https://streamshare.wireway.ch/api/delete/{}/{}",
file_identifier, deletion_token
);
let res = client.delete(&delete_url).send().await?;
if res.status().is_success() {
Ok(())
} else {
Err(format!("Failed to delete file: {}", res.status()).into())
impl Default for StreamShare {
fn default() -> Self {
Self {
server_url: "streamshare.wireway.ch".to_string(),
chunk_size: 1024 * 1024,
client: Client::new(),
}
}
}