implemented receive and reset in sender

This commit is contained in:
ikeen0807 2024-05-15 23:40:45 +02:00
parent 96340622d8
commit 88abc6d3de
24 changed files with 240 additions and 73 deletions

5
Cargo.lock generated
View file

@ -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",

View file

@ -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,

View file

@ -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"

View file

@ -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(())
}
}

View file

@ -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(())
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 853 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View file

@ -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");
}

View file

@ -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',

View file

@ -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 },

View file

@ -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;
}

View file

@ -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>

View file

@ -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.');
}
}
}

View file

@ -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>

View file

@ -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.');
}

View file

@ -1,3 +0,0 @@
<h2>Receiver</h2>
<p>Hier können Sie Dateien empfangen.</p>
<button (click)="redirectToHome()">Startseite</button>

View file

@ -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([''])
}
}

View file

@ -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});
}
}