Media server support

Still only works for clients and is not federated. Need to figure out
caching when I get to the federated version
This commit is contained in:
2026-05-30 22:22:16 -07:00
parent 8ba58234e0
commit 0e3600c31f
4 changed files with 61 additions and 11 deletions
+43 -7
View File
@@ -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<RwLock<State>>,
// 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,
+11
View File
@@ -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);