mirror of
https://github.com/Waradu/streamshare.git
synced 2025-04-21 11:54:09 +02:00
init
This commit is contained in:
commit
67788708fd
5 changed files with 1746 additions and 0 deletions
85
src/lib.rs
Normal file
85
src/lib.rs
Normal file
|
@ -0,0 +1,85 @@
|
|||
use tokio::fs;
|
||||
use tokio::io::AsyncReadExt;
|
||||
use std::path::Path;
|
||||
use reqwest::Client;
|
||||
use serde::Deserialize;
|
||||
use tokio::fs::File;
|
||||
use tokio_tungstenite::{connect_async, tungstenite::{self, Message}};
|
||||
use futures::{SinkExt, StreamExt};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct CreateResponse {
|
||||
file_identifier: String,
|
||||
deletion_token: String,
|
||||
}
|
||||
|
||||
pub async fn upload(file_path: &str) -> Result<(String, String), Box<dyn std::error::Error>> {
|
||||
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());
|
||||
}
|
||||
|
||||
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 = 64 * 1024;
|
||||
|
||||
let mut buffer = vec![0u8; CHUNK_SIZE];
|
||||
|
||||
loop {
|
||||
let n = file.read(&mut buffer).await?;
|
||||
|
||||
if n == 0 {
|
||||
break;
|
||||
}
|
||||
|
||||
let chunk = &buffer[..n];
|
||||
|
||||
ws_stream.send(Message::Binary(chunk.to_vec())).await?;
|
||||
|
||||
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))
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue