re-org
This commit is contained in:
parent
35b053be79
commit
5161f3db75
4 changed files with 88 additions and 73 deletions
|
@ -60,7 +60,7 @@ impl App {
|
||||||
event_listener,
|
event_listener,
|
||||||
screen: vec![CurrentScreen::Main],
|
screen: vec![CurrentScreen::Main],
|
||||||
file_picker: FileExplorer::new().expect("could not create file explorer"),
|
file_picker: FileExplorer::new().expect("could not create file explorer"),
|
||||||
text: Some("this is content".to_string()),
|
text: None,
|
||||||
events: Default::default(),
|
events: Default::default(),
|
||||||
peers: Default::default(),
|
peers: Default::default(),
|
||||||
peer_state: Default::default(),
|
peer_state: Default::default(),
|
||||||
|
@ -234,13 +234,18 @@ impl App {
|
||||||
async fn send_content(&mut self) {
|
async fn send_content(&mut self) {
|
||||||
debug!("sending content");
|
debug!("sending content");
|
||||||
|
|
||||||
if let Some(text) = self.text.to_owned() {
|
let Some(peer_idx) = self.peer_state.selected() else {
|
||||||
if let Some(idx) = self.peer_state.selected()
|
warn!("no peer selected to send to");
|
||||||
&& let Some(peer) = self.peers.get(idx)
|
return;
|
||||||
{
|
};
|
||||||
if let Err(e) = self.service.send_text(&peer.fingerprint, &text).await {
|
let Some(peer) = self.peers.get(peer_idx) else {
|
||||||
error!("got error sending \"{text}\" to {}: {e:?}", peer.alias);
|
warn!("invalid peer index {peer_idx}");
|
||||||
}
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(ref text) = self.text {
|
||||||
|
if let Err(e) = self.service.send_text(&peer.fingerprint, text).await {
|
||||||
|
error!("got error sending \"{text}\" to {}: {e:?}", peer.alias);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let file = self.file_picker.current().path().clone();
|
let file = self.file_picker.current().path().clone();
|
||||||
|
@ -248,12 +253,10 @@ impl App {
|
||||||
&& let Err(e) = self.file_picker.set_cwd(&file)
|
&& let Err(e) = self.file_picker.set_cwd(&file)
|
||||||
{
|
{
|
||||||
error!("could not list directory {file:?}: {e}");
|
error!("could not list directory {file:?}: {e}");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(idx) = self.peer_state.selected()
|
if file.is_file() {
|
||||||
&& let Some(peer) = self.peers.get(idx)
|
|
||||||
&& file.is_file()
|
|
||||||
{
|
|
||||||
debug!("sending {file:?}");
|
debug!("sending {file:?}");
|
||||||
if let Err(e) = self
|
if let Err(e) = self
|
||||||
.service
|
.service
|
||||||
|
|
|
@ -36,6 +36,9 @@ pub enum LocalSendError {
|
||||||
#[error("Session inactive")]
|
#[error("Session inactive")]
|
||||||
SessionInactive,
|
SessionInactive,
|
||||||
|
|
||||||
|
#[error("Session not found")]
|
||||||
|
SessionNotFound,
|
||||||
|
|
||||||
#[error("Cancel Failed")]
|
#[error("Cancel Failed")]
|
||||||
CancelFailed,
|
CancelFailed,
|
||||||
|
|
||||||
|
|
|
@ -63,22 +63,21 @@ impl FileMetadata {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_text(text: &str) -> Self {
|
pub fn from_text(text: &str) -> crate::error::Result<Self> {
|
||||||
|
let size = text.len() as u64;
|
||||||
let id = Julid::new().as_string();
|
let id = Julid::new().as_string();
|
||||||
let size = text.as_bytes().len() as u64;
|
|
||||||
|
|
||||||
let file_type = "text/plain".into();
|
let file_type = "text/plain".into();
|
||||||
let sha256 = Some(sha256::digest(text));
|
let sha256 = Some(sha256::digest(text));
|
||||||
|
|
||||||
FileMetadata {
|
Ok(FileMetadata {
|
||||||
id,
|
id: id.clone(),
|
||||||
file_name: "".to_string(),
|
file_name: format!("{id}.txt"),
|
||||||
size,
|
size,
|
||||||
file_type,
|
file_type,
|
||||||
sha256,
|
sha256,
|
||||||
preview: Some(text.to_string()),
|
preview: Some(text.to_string()),
|
||||||
metadata: None,
|
metadata: None,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
118
src/transfer.rs
118
src/transfer.rs
|
@ -62,9 +62,7 @@ impl JoecalService {
|
||||||
return Err(LocalSendError::PeerNotFound);
|
return Err(LocalSendError::PeerNotFound);
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!("sending to peer at {addr:?}");
|
let request = self
|
||||||
|
|
||||||
let response = self
|
|
||||||
.client
|
.client
|
||||||
.post(format!(
|
.post(format!(
|
||||||
"{}://{}/api/localsend/v2/prepare-upload",
|
"{}://{}/api/localsend/v2/prepare-upload",
|
||||||
|
@ -73,14 +71,24 @@ impl JoecalService {
|
||||||
.json(&PrepareUploadRequest {
|
.json(&PrepareUploadRequest {
|
||||||
info: self.device.clone(),
|
info: self.device.clone(),
|
||||||
files: files.clone(),
|
files: files.clone(),
|
||||||
})
|
});
|
||||||
.timeout(Duration::from_secs(30))
|
|
||||||
.send()
|
let r = request.timeout(Duration::from_secs(30)).build().unwrap();
|
||||||
.await?;
|
debug!("sending '{r:?}' to peer at {addr:?}");
|
||||||
|
|
||||||
|
let response = self.client.execute(r).await?;
|
||||||
|
|
||||||
debug!("Response: {response:?}");
|
debug!("Response: {response:?}");
|
||||||
|
|
||||||
let response: PrepareUploadResponse = response.json().await?;
|
let response: PrepareUploadResponse = match response.json().await {
|
||||||
|
Err(e) => {
|
||||||
|
error!("got error deserializing response: {e:?}");
|
||||||
|
return Err(LocalSendError::RequestError(e));
|
||||||
|
}
|
||||||
|
Ok(r) => r,
|
||||||
|
};
|
||||||
|
|
||||||
|
debug!("decoded response: {response:?}");
|
||||||
|
|
||||||
let session = Session {
|
let session = Session {
|
||||||
session_id: response.session_id.clone(),
|
session_id: response.session_id.clone(),
|
||||||
|
@ -100,41 +108,6 @@ impl JoecalService {
|
||||||
Ok(response)
|
Ok(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_bytes(
|
|
||||||
&self,
|
|
||||||
session_id: String,
|
|
||||||
content_id: String,
|
|
||||||
token: String,
|
|
||||||
body: Bytes,
|
|
||||||
) -> Result<()> {
|
|
||||||
let sessions = self.sessions.lock().await;
|
|
||||||
let session = sessions.get(&session_id).unwrap();
|
|
||||||
|
|
||||||
if session.status != SessionStatus::Active {
|
|
||||||
return Err(LocalSendError::SessionInactive);
|
|
||||||
}
|
|
||||||
|
|
||||||
if session.file_tokens.get(&content_id) != Some(&token) {
|
|
||||||
return Err(LocalSendError::InvalidToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
let request = self.client
|
|
||||||
.post(format!(
|
|
||||||
"{}://{}/api/localsend/v2/upload?sessionId={session_id}&fileId={content_id}&token={token}",
|
|
||||||
session.receiver.protocol, session.addr))
|
|
||||||
.body(body);
|
|
||||||
|
|
||||||
debug!("Uploading file: {request:?}");
|
|
||||||
let response = request.send().await?;
|
|
||||||
|
|
||||||
if response.status() != 200 {
|
|
||||||
warn!("Upload failed: {response:?}");
|
|
||||||
return Err(LocalSendError::UploadFailed);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn send_file(&self, peer: &str, file_path: PathBuf) -> Result<()> {
|
pub async fn send_file(&self, peer: &str, file_path: PathBuf) -> Result<()> {
|
||||||
// Generate file metadata
|
// Generate file metadata
|
||||||
let file_metadata = FileMetadata::from_path(&file_path)?;
|
let file_metadata = FileMetadata::from_path(&file_path)?;
|
||||||
|
@ -158,9 +131,9 @@ impl JoecalService {
|
||||||
|
|
||||||
// Upload file
|
// Upload file
|
||||||
self.send_bytes(
|
self.send_bytes(
|
||||||
prepare_response.session_id,
|
&prepare_response.session_id,
|
||||||
file_metadata.id,
|
&file_metadata.id,
|
||||||
token.clone(),
|
token,
|
||||||
bytes,
|
bytes,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -170,7 +143,7 @@ impl JoecalService {
|
||||||
|
|
||||||
pub async fn send_text(&self, peer: &str, text: &str) -> Result<()> {
|
pub async fn send_text(&self, peer: &str, text: &str) -> Result<()> {
|
||||||
// Generate file metadata
|
// Generate file metadata
|
||||||
let file_metadata = FileMetadata::from_text(text);
|
let file_metadata = FileMetadata::from_text(text)?;
|
||||||
|
|
||||||
// Prepare files map
|
// Prepare files map
|
||||||
let mut files = BTreeMap::new();
|
let mut files = BTreeMap::new();
|
||||||
|
@ -189,9 +162,9 @@ impl JoecalService {
|
||||||
|
|
||||||
// Upload file
|
// Upload file
|
||||||
self.send_bytes(
|
self.send_bytes(
|
||||||
prepare_response.session_id,
|
&prepare_response.session_id,
|
||||||
file_metadata.id,
|
&file_metadata.id,
|
||||||
token.clone(),
|
token,
|
||||||
bytes,
|
bytes,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -199,15 +172,17 @@ impl JoecalService {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn cancel_upload(&self, session_id: String) -> Result<()> {
|
pub async fn cancel_upload(&self, session_id: &str) -> Result<()> {
|
||||||
let sessions = self.sessions.lock().await;
|
let sessions = self.sessions.lock().await;
|
||||||
let session = sessions.get(&session_id).unwrap();
|
let session = sessions
|
||||||
|
.get(session_id)
|
||||||
|
.ok_or(LocalSendError::SessionNotFound)?;
|
||||||
|
|
||||||
let request = self
|
let request = self
|
||||||
.client
|
.client
|
||||||
.post(format!(
|
.post(format!(
|
||||||
"{}://{}/api/localsend/v2/cancel?sessionId={}",
|
"{}://{}/api/localsend/v2/cancel?sessionId={session_id}",
|
||||||
session.receiver.protocol, session.addr, session_id
|
session.receiver.protocol, session.addr
|
||||||
))
|
))
|
||||||
.send()
|
.send()
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -218,6 +193,41 @@ impl JoecalService {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn send_bytes(
|
||||||
|
&self,
|
||||||
|
session_id: &str,
|
||||||
|
content_id: &str,
|
||||||
|
token: &String,
|
||||||
|
body: Bytes,
|
||||||
|
) -> Result<()> {
|
||||||
|
let sessions = self.sessions.lock().await;
|
||||||
|
let session = sessions.get(session_id).unwrap();
|
||||||
|
|
||||||
|
if session.status != SessionStatus::Active {
|
||||||
|
return Err(LocalSendError::SessionInactive);
|
||||||
|
}
|
||||||
|
|
||||||
|
if session.file_tokens.get(content_id) != Some(token) {
|
||||||
|
return Err(LocalSendError::InvalidToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
let request = self.client
|
||||||
|
.post(format!(
|
||||||
|
"{}://{}/api/localsend/v2/upload?sessionId={session_id}&fileId={content_id}&token={token}",
|
||||||
|
session.receiver.protocol, session.addr))
|
||||||
|
.body(body).build()?;
|
||||||
|
|
||||||
|
debug!("Uploading bytes: {request:?}");
|
||||||
|
let response = self.client.execute(request).await?;
|
||||||
|
|
||||||
|
if response.status() != 200 {
|
||||||
|
warn!("Upload failed: {response:?}");
|
||||||
|
return Err(LocalSendError::UploadFailed);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn prepare_upload(
|
pub async fn prepare_upload(
|
||||||
|
|
Loading…
Reference in a new issue