diff --git a/Cargo.lock b/Cargo.lock index 71984bf..1151d2b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -275,6 +275,7 @@ dependencies = [ "toml", "tracing", "tracing-subscriber", + "uuid", ] [[package]] @@ -545,6 +546,7 @@ dependencies = [ [[package]] name = "fedichat" version = "0.1.0" +source = "git+https://git.firechicken.net/fedichat/fedichat-lib#49cbd905ceecb7bf7be463f81836742e3a7ddc24" dependencies = [ "serde", "serde_bytes", @@ -1870,9 +1872,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.23.1" +version = "1.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" +checksum = "d258b83ceec21034727ecee8c382cfa6c3e133699b0742c64571814fb420c9f7" dependencies = [ "getrandom 0.4.2", "js-sys", diff --git a/Cargo.toml b/Cargo.toml index 3a73735..473e2ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,8 +6,8 @@ edition = "2024" [dependencies] diesel = { version = "2.3.9", features = ["postgres_backend"] } quinn = "0.11.9" -#fedichat = {git = "https://git.firechicken.net/fedichat/fedichat-lib"} -fedichat = {path = "../fedichat-lib"} +fedichat = {git = "https://git.firechicken.net/fedichat/fedichat-lib"} +#fedichat = {path = "../fedichat-lib"} tracing = "0.1.44" tracing-subscriber = "0.3.23" clap = { version = "4.6.1", features = ["derive"] } @@ -22,4 +22,5 @@ diesel-derive-composite = "0.1.0" bcrypt = "0.19.1" time = { version = "0.3.47", features = ["serde"] } rand = "0.10.1" +uuid = { version = "1.23.2", features = ["v4"] } #postcard = {version = "1.1.3", features = ["use-std"]} diff --git a/src/client.rs b/src/client.rs index be3f613..2605f17 100644 --- a/src/client.rs +++ b/src/client.rs @@ -6,10 +6,13 @@ use diesel_async::AsyncPgConnection; use diesel_async::pooled_connection::deadpool::{Pool,Object}; use rmp_serde; use std::collections::{HashMap,HashSet}; +use std::fs::File; +use std::io::{Read,Write}; use std::sync::{Arc}; use thiserror::Error; use tokio::sync::{broadcast,mpsc,RwLock}; use tokio::select; +use uuid::Uuid; use crate::Coordinate; use crate::db; use crate::state::{self,State}; @@ -17,12 +20,6 @@ use crate::state::{self,State}; use quinn::ConnectionError; use tracing::{warn,error,debug,instrument}; -#[derive(Error,Debug)] -enum HandlerError { - #[error("Foo")] - Foo -} - pub struct Client { statehandle: Arc>, // Channel for local messages, all are broadcast to all @@ -457,7 +454,46 @@ impl Client { // with users MediaUpload { bytes, - } => {unimplemented!()}, + } => { + //NOTE: This maybe should have a limit on filesize + // Right now the only limit is on message size in the quic + // handler. Probably should be configurable too + // + // On boot the media directory should have already been created + let uuid = Uuid::new_v4(); + let path = config.media_directory.clone() + &format!("/{}",uuid); + // Hide fs errors from the user but print on server console + let mut file = File::create(&path).map_err(|e| { + error!("Problem writing media file {}: {}",path,e); + ServerError::Generic + })?; + debug!("Writing file: {:?}", bytes); + file.write_all(&bytes).map_err(|e| { + error!("Problem writing media file {}: {}",path,e); + ServerError::Generic + })?; + Ok(ServerMessage::MediaId(uuid)) + }, + MediaFetch { + id + } => { + let path = config.media_directory.clone() + &format!("/{}",id); + // Hide fs errors from the user but print on server console + let mut file = File::open(&path).map_err(|e| { + error!("Problem reading media file {}: {}",path,e); + ServerError::Generic + })?; + // Start the buffer at 4KiB. Probably could be larger because + // we expect the files stored using this method to be at least + // a few MB + let mut buf = Vec::with_capacity(4096); + file.read_to_end(&mut buf).map_err(|e| { + error!("Problem reading media file {}: {}",path,e); + ServerError::Generic + })?; + Ok(ServerMessage::Media(buf.into_boxed_slice())) + + }, // Join and subscribe RoomJoin { room_id, diff --git a/src/main.rs b/src/main.rs index 976fd13..cbe9afc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -79,6 +79,17 @@ async fn main() -> ExitCode { tracing_subscriber::fmt().with_max_level(level).finish() ).expect("Failed to setup logger"); + // Check to make sure media directory exists + match std::fs::exists(&config.media_directory) { + Ok(true) => {}, + // NOTE: maybe shouldnt shadow this error + _ => { + error!("Media directory {} does not exist. Check to make sure it is a directory and is writable.",config.media_directory); + return ExitCode::FAILURE; + } + + } + // Set up database connection let db_string = format!("postgres://{}:{}@{}/{}",config.database.user,config.database.password,config.database.url,config.database.db_name);