implemented receive and reset in sender
This commit is contained in:
parent
96340622d8
commit
88abc6d3de
24 changed files with 240 additions and 73 deletions
5
Cargo.lock
generated
5
Cargo.lock
generated
|
|
@ -151,9 +151,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.82"
|
||||
version = "1.0.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519"
|
||||
checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3"
|
||||
|
||||
[[package]]
|
||||
name = "ashpd"
|
||||
|
|
@ -652,6 +652,7 @@ name = "caesar-core"
|
|||
version = "0.3.1"
|
||||
dependencies = [
|
||||
"aes-gcm",
|
||||
"anyhow",
|
||||
"axum 0.7.5",
|
||||
"axum-client-ip",
|
||||
"axum-extra",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use caesar_core::receiver;
|
||||
use caesar_core::relay;
|
||||
use caesar_core::sender;
|
||||
use caesar_core::sender::util::generate_random_name;
|
||||
use clap::{Parser, Subcommand};
|
||||
use std::{env, sync::Arc};
|
||||
use tracing::debug;
|
||||
|
|
@ -70,7 +71,8 @@ impl Args {
|
|||
let relay_string: String = relay.as_deref().unwrap_or(&cfg.app_origin).to_string();
|
||||
let relay_arc = Arc::new(relay_string);
|
||||
let files_arc = Arc::new(files.to_vec());
|
||||
sender::start_sender(relay_arc, files_arc).await;
|
||||
let transfer_name = generate_random_name();
|
||||
sender::start_sender(relay_arc, files_arc, transfer_name).await;
|
||||
}
|
||||
Some(Commands::Receive {
|
||||
relay,
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ headers = "0.4"
|
|||
tower = { version = "0.4", features = ["util"] }
|
||||
reqwest = { version = "0.12.4", features = ["blocking", "json"] }
|
||||
hex = "0.4.3"
|
||||
anyhow = "1.0.83"
|
||||
|
||||
[build-dependencies]
|
||||
prost-build = "0.12.4"
|
||||
|
|
|
|||
|
|
@ -1,27 +1,22 @@
|
|||
use anyhow::{anyhow, Result};
|
||||
use hex;
|
||||
use reqwest::{self, Client};
|
||||
use sha2::{Digest, Sha256};
|
||||
use tracing::error;
|
||||
|
||||
use crate::relay::transfer::TransferResponse;
|
||||
|
||||
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
|
||||
|
||||
pub async fn download_info(relay: &str, name: &str) -> Result<TransferResponse> {
|
||||
let url = String::from(relay);
|
||||
let hashed_name = Sha256::digest(name.as_bytes());
|
||||
let hashed_string = hex::encode(hashed_name);
|
||||
|
||||
match reqwest::get(format!("{}/download/{}", url, hashed_string)).await {
|
||||
Ok(resp) => match resp.json::<TransferResponse>().await {
|
||||
Ok(res) => Ok(res),
|
||||
Err(e) => Err(Box::new(e)),
|
||||
},
|
||||
Err(err) => {
|
||||
error!("Error: {err}");
|
||||
Err(Box::new(err))
|
||||
}
|
||||
}
|
||||
let resp = reqwest::get(format!("{}/download/{}", url, hashed_string))
|
||||
.await
|
||||
.map_err(|e| anyhow!("Failed to send GET request: {}", e))?;
|
||||
|
||||
resp.json::<TransferResponse>()
|
||||
.await
|
||||
.map_err(|e| anyhow!("Failed to parse JSON response: {}", e))
|
||||
}
|
||||
|
||||
pub async fn download_success(relay: &str, name: &str) -> Result<()> {
|
||||
|
|
@ -33,6 +28,8 @@ pub async fn download_success(relay: &str, name: &str) -> Result<()> {
|
|||
let _ = client
|
||||
.post(format!("{}/download_success/{}", url, hashed_string))
|
||||
.send()
|
||||
.await?;
|
||||
.await
|
||||
.map_err(|e| anyhow!("Failed to send POST request: {}", e))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
pub mod client;
|
||||
pub mod http_client;
|
||||
|
||||
use anyhow::{Result, anyhow};
|
||||
use crate::{receiver::client as receiver, sender::util::replace_protocol};
|
||||
|
||||
use tokio_tungstenite::{
|
||||
|
|
@ -9,7 +10,7 @@ use tokio_tungstenite::{
|
|||
};
|
||||
use tracing::{debug, error};
|
||||
|
||||
pub async fn start_receiver(relay: &str, name: &str) {
|
||||
pub async fn start_receiver(relay: &str, name: &str) -> Result<()> {
|
||||
let http_url = replace_protocol(relay);
|
||||
let res = http_client::download_info(http_url.as_str(), name)
|
||||
.await
|
||||
|
|
@ -23,19 +24,19 @@ pub async fn start_receiver(relay: &str, name: &str) {
|
|||
debug!("Failed to connect remote: {relay_err}");
|
||||
}
|
||||
}
|
||||
let success = http_client::download_success(http_url.as_str(), name).await;
|
||||
match success {
|
||||
Ok(()) => debug!("Success"),
|
||||
Err(e) => error!("Error: {e:?}"),
|
||||
};
|
||||
let _success = http_client::download_success(http_url.as_str(), name)
|
||||
.await
|
||||
.map_err(|e| anyhow!("Failed to download success: {}", e))?;
|
||||
|
||||
debug!("Success");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn start_ws_com(relay: &str, name: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||
pub async fn start_ws_com(relay: &str, name: &str) -> Result<()> {
|
||||
let url = String::from(relay) + "/ws";
|
||||
let Ok(mut request) = url.into_client_request() else {
|
||||
println!("Error: Failed to create request.");
|
||||
return Err("Failed to create request".into());
|
||||
};
|
||||
let mut request = url
|
||||
.into_client_request()
|
||||
.map_err(|e| anyhow!("Failed to create request: {}", e))?;
|
||||
|
||||
request
|
||||
.headers_mut()
|
||||
|
|
@ -60,4 +61,4 @@ pub async fn start_ws_com(relay: &str, name: &str) -> Result<(), Box<dyn std::er
|
|||
}?,
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
BIN
caesar-tauri-angular/src-tauri/Screenshot_20240421-122623.png
Normal file
BIN
caesar-tauri-angular/src-tauri/Screenshot_20240421-122623.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 853 KiB |
BIN
caesar-tauri-angular/src-tauri/bow.png
Normal file
BIN
caesar-tauri-angular/src-tauri/bow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
|
|
@ -1,23 +1,37 @@
|
|||
use caesar_core::{receiver, relay::server::start_ws, sender::{self, util::generate_random_name}};
|
||||
use std::sync::Arc;
|
||||
use tauri::{AppHandle, Manager};
|
||||
|
||||
|
||||
#[tauri::command]
|
||||
async fn send(relay: Option<String>, files: Vec<String>) {
|
||||
async fn send(app_handle: tauri::AppHandle, relay: Option<String>, files: Vec<String>) {
|
||||
let relay_string = relay.unwrap_or_else(|| "default_relay_address".to_string());
|
||||
log::info!("Using relay: {}", relay_string);
|
||||
let relay_arc = Arc::new(relay_string);
|
||||
let files_arc = Arc::new(files);
|
||||
let transfer_name = generate_random_name();
|
||||
|
||||
app_handle.emit("transfer_name_event", transfer_name.clone())
|
||||
.expect("Failed to emit event");
|
||||
|
||||
sender::start_sender(relay_arc, files_arc, transfer_name.clone()).await;
|
||||
}
|
||||
|
||||
// #[tauri::command]
|
||||
// async fn receive(relay: Option<String>, overwrite: bool, name: String) {
|
||||
// let relay_string = relay.unwrap_or_else(|| "default_relay_address".to_string());
|
||||
// receiver::start_receiver(&relay_string, &name).await;
|
||||
// }
|
||||
|
||||
#[tauri::command]
|
||||
async fn receive(relay: Option<String>, name: String) -> Result<(), String> {
|
||||
let relay_string = relay.unwrap_or_else(|| "default_relay_address".to_string());
|
||||
|
||||
match receiver::start_receiver(&relay_string, &name).await {
|
||||
Ok(_) => {
|
||||
println!("Receiver started successfully.");
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Failed to start receiver: {:?}", e);
|
||||
Err(format!("Failed to start receiver: {:?}", e))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn serve(port: Option<i32>, listen_address: Option<String>) {
|
||||
|
|
@ -32,7 +46,7 @@ pub fn run() {
|
|||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
.plugin(tauri_plugin_shell::init())
|
||||
.invoke_handler(tauri::generate_handler![send, serve])
|
||||
.invoke_handler(tauri::generate_handler![send, serve, receive])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common';
|
|||
import { Router, RouterOutlet } from '@angular/router';
|
||||
import { SenderComponent } from './components/sender/sender.component';
|
||||
import { TauriService } from './services/tauri.service';
|
||||
import { ReceiverComponent } from './receiver/receiver.component';
|
||||
import { ReceiverComponent } from './components/receiver/receiver.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { Routes } from "@angular/router";
|
||||
import { SenderComponent } from "./components/sender/sender.component";
|
||||
import { ReceiverComponent } from "./receiver/receiver.component";
|
||||
import { HomeComponent } from "./home/home.component";
|
||||
import { ReceiverComponent } from "./components/receiver/receiver.component";
|
||||
import { HomeComponent } from "./components/home/home.component";
|
||||
|
||||
export const routes: Routes = [
|
||||
{ path: 'sender', component: SenderComponent },
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
h2 {
|
||||
text-align: center;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
p {
|
||||
text-align: center;
|
||||
font-size: 1.2em;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin: 20px auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
input[type="text"] {
|
||||
width: 50%;
|
||||
padding: 10px;
|
||||
margin: 10px 0;
|
||||
box-sizing: border-box;
|
||||
border: 2px solid #ccc;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 10px 20px;
|
||||
margin: 10px;
|
||||
font-size: 1em;
|
||||
color: #fff;
|
||||
background-color: #007BFF;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
li {
|
||||
margin: 5px 0;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<h2>Receiver</h2>
|
||||
<p>Hier können Sie Dateien empfangen.</p>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="relayAddress">Relay Server Adresse:</label>
|
||||
<input type="text" id="relayAddress" [(ngModel)]="relayAddress" placeholder="::1">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="relayPort">Port:</label>
|
||||
<input type="text" id="relayPort" [(ngModel)]="relayPort" placeholder="8000">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="relayPort">Transfername:</label>
|
||||
<input type="text" id="transferName" [(ngModel)]="transferName" placeholder="Transfername">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<button (click)="receiveData()">Daten empfangen</button>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button (click)="redirectToHome()">Startseite</button>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
import { Component } from '@angular/core';
|
||||
import { TauriService } from '../../services/tauri.service';
|
||||
import { Router } from '@angular/router';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'app-receiver',
|
||||
standalone: true,
|
||||
imports: [FormsModule, CommonModule],
|
||||
templateUrl: './receiver.component.html',
|
||||
styleUrl: './receiver.component.css'
|
||||
})
|
||||
export class ReceiverComponent {
|
||||
relayAddress: string = '';
|
||||
relayPort?: number;
|
||||
transferName: string = '';
|
||||
constructor(private tauriService: TauriService, private router: Router) {}
|
||||
redirectToHome() {
|
||||
this.router.navigate([''])
|
||||
}
|
||||
getRelayURL(): string {
|
||||
return `ws://${this.relayAddress}:${this.relayPort}`;
|
||||
}
|
||||
receiveData() {
|
||||
const relay = this.getRelayURL();
|
||||
if (this.transferName.length > 0) {
|
||||
this.tauriService.receive(relay, this.transferName)
|
||||
.then(sendDataReturn => console.log(sendDataReturn + ' Data received successfully'))
|
||||
.catch(error => console.error('Error receiving data:', error));
|
||||
} else {
|
||||
console.error('No files to receive.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +1,39 @@
|
|||
<!-- src/app/app.component.html -->
|
||||
<h2>Sender</h2>
|
||||
<p>Hier können Sie Dateien senden.</p>
|
||||
|
||||
<div class="form-group">
|
||||
<div *ngIf="!sendingInProgress && !sendingSuccess" class="form-group">
|
||||
<label for="relayAddress">Relay Server Adresse:</label>
|
||||
<input type="text" id="relayAddress" [(ngModel)]="relayAddress" placeholder="::1">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div *ngIf="!sendingInProgress && !sendingSuccess" class="form-group">
|
||||
<label for="relayPort">Port:</label>
|
||||
<input type="text" id="relayPort" [(ngModel)]="relayPort" placeholder="8000">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<button (click)="selectFile()">Datei anfügen</button>
|
||||
<div *ngIf="!sendingInProgress && !sendingSuccess" class="form-group">
|
||||
<button (click)="selectFile()" [disabled]="sendingInProgress">Datei anfügen</button>
|
||||
</div>
|
||||
|
||||
<ul class="file-list">
|
||||
<li *ngFor="let fileName of fileNames">{{ fileName }}</li>
|
||||
</ul>
|
||||
|
||||
<div class="form-group">
|
||||
<button (click)="sendData()">Daten senden</button>
|
||||
<div *ngIf="!sendingInProgress && !sendingSuccess" class="form-group">
|
||||
<button (click)="sendData()" [disabled]="sendingInProgress">Daten senden</button>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button (click)="redirectToHome()">Startseite</button>
|
||||
</div>
|
||||
<div *ngIf="sendingInProgress">
|
||||
<p>Sending files... Transfer Name: {{ transferName }}</p>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!sendingInProgress && sendingSuccess">
|
||||
<p>Data sent successfully! Transfer Name: {{ transferName }}</p>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!sendingInProgress && !sendingSuccess && transferName === null">
|
||||
<p>No data being sent.</p>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import { Component } from '@angular/core';
|
||||
import { Component, ChangeDetectorRef } from '@angular/core';
|
||||
import { TauriService } from '../../services/tauri.service';
|
||||
import { Router } from '@angular/router';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FileResponse, open } from '@tauri-apps/plugin-dialog';
|
||||
import { listen } from '@tauri-apps/api/event';
|
||||
|
||||
@Component({
|
||||
selector: 'app-sender',
|
||||
|
|
@ -16,13 +17,35 @@ export class SenderComponent {
|
|||
files: string[] = [];
|
||||
fileNames: string[] = [];
|
||||
relayAddress: string = '';
|
||||
relayPort?: number;
|
||||
constructor(private tauriService: TauriService, private router: Router) {}
|
||||
relayPort?: number | null;
|
||||
sendingInProgress = false;
|
||||
sendingSuccess = false;
|
||||
transferName: string = "";
|
||||
constructor(private tauriService: TauriService, private router: Router, private cdr: ChangeDetectorRef) {
|
||||
this.listenToTransferEvents();
|
||||
}
|
||||
|
||||
redirectToHome() {
|
||||
this.router.navigate([''])
|
||||
}
|
||||
|
||||
private listenToTransferEvents() {
|
||||
listen('transfer_name_event', (event) => {
|
||||
this.transferName = event.payload as string;
|
||||
this.cdr.detectChanges();
|
||||
})
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.files = [];
|
||||
this.fileNames = [];
|
||||
this.relayAddress = '';
|
||||
this.sendingInProgress = false;
|
||||
this.sendingSuccess = false;
|
||||
this.transferName = '';
|
||||
this.relayPort = null;
|
||||
}
|
||||
|
||||
async selectFile() {
|
||||
// Open the file dialog and get the file path(s)
|
||||
const selected:any = await open({
|
||||
|
|
@ -40,9 +63,24 @@ export class SenderComponent {
|
|||
sendData() {
|
||||
const relay = this.getRelayURL();
|
||||
if (this.files.length > 0) {
|
||||
this.sendingInProgress = true;
|
||||
this.sendingSuccess = false;
|
||||
this.tauriService.send(relay, this.files)
|
||||
.then(sendDataReturn => console.log(sendDataReturn + ' Data sent successfully'))
|
||||
.catch(error => console.error('Error sending data:', error));
|
||||
.then(sendDataReturn => {
|
||||
console.log(sendDataReturn + ' Data sent successfully');
|
||||
this.sendingSuccess = true;
|
||||
setTimeout(() => {
|
||||
this.reset();
|
||||
}, 5000);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error sending data:', error);
|
||||
this.sendingSuccess = false;
|
||||
this.sendingInProgress = false;
|
||||
})
|
||||
.finally(() => {
|
||||
this.sendingInProgress = false;
|
||||
});
|
||||
} else {
|
||||
console.error('No files to send.');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
<h2>Receiver</h2>
|
||||
<p>Hier können Sie Dateien empfangen.</p>
|
||||
<button (click)="redirectToHome()">Startseite</button>
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
import { Component } from '@angular/core';
|
||||
import { TauriService } from '../services/tauri.service';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'app-receiver',
|
||||
standalone: true,
|
||||
imports: [],
|
||||
templateUrl: './receiver.component.html',
|
||||
styleUrl: './receiver.component.css'
|
||||
})
|
||||
export class ReceiverComponent {
|
||||
constructor(private tauriService: TauriService, private router: Router) {}
|
||||
redirectToHome() {
|
||||
this.router.navigate([''])
|
||||
}
|
||||
}
|
||||
|
|
@ -13,8 +13,12 @@ export class TauriService {
|
|||
await invoke('send', { relay, files });
|
||||
}
|
||||
|
||||
serve(port: number, listen_addr: string): Promise<any> {
|
||||
async serve(port: number, listen_addr: string): Promise<any> {
|
||||
console.log("Listening on address:" + listen_addr + ":" + port);
|
||||
return invoke('serve', { port: port, listen_addr: listen_addr });
|
||||
}
|
||||
|
||||
async receive(relay: string, name: string) {
|
||||
return invoke('receive',{relay: relay, name: name});
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue