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:
Generated
+4
-2
@@ -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",
|
||||
|
||||
+3
-2
@@ -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"]}
|
||||
|
||||
+43
-7
@@ -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
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user