Add media directory commands
This commit is contained in:
Generated
+1
-1
@@ -397,7 +397,6 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "fedichat"
|
name = "fedichat"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://git.firechicken.net/fedichat/fedichat-lib#53398bf4ea611fb8bdff973e348d8bf9d37708ea"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_bytes",
|
"serde_bytes",
|
||||||
@@ -424,6 +423,7 @@ dependencies = [
|
|||||||
"toml",
|
"toml",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
+3
-2
@@ -5,8 +5,8 @@ edition = "2024"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
quinn = "0.11.9"
|
quinn = "0.11.9"
|
||||||
fedichat = {git = "https://git.firechicken.net/fedichat/fedichat-lib"}
|
#fedichat = {git = "https://git.firechicken.net/fedichat/fedichat-lib"}
|
||||||
#fedichat = {path = "../fedichat-lib"}
|
fedichat = {path = "../fedichat-lib"}
|
||||||
tracing = "0.1.44"
|
tracing = "0.1.44"
|
||||||
tracing-subscriber = "0.3.23"
|
tracing-subscriber = "0.3.23"
|
||||||
clap = { version = "4.6.1", features = ["derive"] }
|
clap = { version = "4.6.1", features = ["derive"] }
|
||||||
@@ -20,3 +20,4 @@ dotenv = "0.15.0"
|
|||||||
time = { version = "0.3.47", features = ["serde"] }
|
time = { version = "0.3.47", features = ["serde"] }
|
||||||
hickory-resolver = "0.26.1"
|
hickory-resolver = "0.26.1"
|
||||||
expanduser = "1.2.2"
|
expanduser = "1.2.2"
|
||||||
|
uuid = { version = "1.23.2", features = ["v4"] }
|
||||||
|
|||||||
+35
-10
@@ -2,8 +2,12 @@ use clap::{Parser,Subcommand,ArgAction};
|
|||||||
use fedichat::client::{ClientMessage,SignedClientMessage,AuthMethod};
|
use fedichat::client::{ClientMessage,SignedClientMessage,AuthMethod};
|
||||||
use fedichat::ServerAddr;
|
use fedichat::ServerAddr;
|
||||||
use fedichat::state::StatePath;
|
use fedichat::state::StatePath;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Read;
|
||||||
|
use std::path::PathBuf;
|
||||||
use time::OffsetDateTime;
|
use time::OffsetDateTime;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
// Everything except server, user, and password lives in these
|
// Everything except server, user, and password lives in these
|
||||||
|
|
||||||
@@ -61,6 +65,15 @@ pub enum Command {
|
|||||||
#[clap(short, long, value_parser=Room::from_str)]
|
#[clap(short, long, value_parser=Room::from_str)]
|
||||||
room: Room,
|
room: Room,
|
||||||
},
|
},
|
||||||
|
Upload {
|
||||||
|
file: PathBuf,
|
||||||
|
},
|
||||||
|
Fetch {
|
||||||
|
#[clap(short, long)]
|
||||||
|
id: String,
|
||||||
|
#[clap(short, long)]
|
||||||
|
file: PathBuf
|
||||||
|
},
|
||||||
GetState {
|
GetState {
|
||||||
#[clap(short, long, value_parser=Room::from_str)]
|
#[clap(short, long, value_parser=Room::from_str)]
|
||||||
room: Room,
|
room: Room,
|
||||||
@@ -90,9 +103,9 @@ pub enum Command {
|
|||||||
}
|
}
|
||||||
impl Command {
|
impl Command {
|
||||||
// Returns clientmessage and target server
|
// Returns clientmessage and target server
|
||||||
fn into_client_message(self,username: String) -> (ClientMessage,Option<ServerAddr>) {
|
fn into_client_message(self,username: String) -> Result<(ClientMessage,Option<ServerAddr>),MessageError> {
|
||||||
use Command::*;
|
use Command::*;
|
||||||
match self {
|
Ok(match self {
|
||||||
CreateUser {
|
CreateUser {
|
||||||
password,
|
password,
|
||||||
} => (ClientMessage::UserCreate {username, password},None),
|
} => (ClientMessage::UserCreate {username, password},None),
|
||||||
@@ -118,6 +131,14 @@ impl Command {
|
|||||||
Create {
|
Create {
|
||||||
room,
|
room,
|
||||||
} => (ClientMessage::RoomCreate{room_id: room.get_coord()},room.get_server()),
|
} => (ClientMessage::RoomCreate{room_id: room.get_coord()},room.get_server()),
|
||||||
|
Upload {file} => {
|
||||||
|
let mut buf = Vec::with_capacity(4096);
|
||||||
|
let mut file = File::open(file)?;
|
||||||
|
file.read_to_end(&mut buf)?;
|
||||||
|
(ClientMessage::MediaUpload{bytes: buf},None)
|
||||||
|
|
||||||
|
},
|
||||||
|
Fetch {file: _, id} => (ClientMessage::MediaFetch{id: Uuid::parse_str(&id)?},None),
|
||||||
GetState {
|
GetState {
|
||||||
room,
|
room,
|
||||||
path,
|
path,
|
||||||
@@ -137,20 +158,19 @@ impl Command {
|
|||||||
body,
|
body,
|
||||||
user,
|
user,
|
||||||
} => (ClientMessage::MessagePost{body, user: user.clone()},Some(ServerAddr(user.server))),
|
} => (ClientMessage::MessagePost{body, user: user.clone()},Some(ServerAddr(user.server))),
|
||||||
|
})
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
pub fn into_signed_message(self, username: String) -> SignedClientMessage {
|
pub fn into_signed_message(self, username: String) -> Result<SignedClientMessage,MessageError> {
|
||||||
let (message,target) = self.into_client_message(username);
|
let (message,target) = self.into_client_message(username)?;
|
||||||
SignedClientMessage {
|
Ok(SignedClientMessage {
|
||||||
|
|
||||||
message,
|
message,
|
||||||
target,
|
target,
|
||||||
timestamp: OffsetDateTime::now_utc(),
|
timestamp: OffsetDateTime::now_utc(),
|
||||||
// TODO: actually implement signatures
|
// TODO: actually implement signatures
|
||||||
signature: Box::new([0])
|
signature: Box::new([0])
|
||||||
}
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
pub fn needs_auth(&self) -> bool {
|
pub fn needs_auth(&self) -> bool {
|
||||||
@@ -180,7 +200,7 @@ impl Command {
|
|||||||
signature: Box::new([0])
|
signature: Box::new([0])
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
messages.push(self.into_signed_message(username));
|
messages.push(self.into_signed_message(username)?);
|
||||||
// If this message is authenticating us then we should be generating
|
// If this message is authenticating us then we should be generating
|
||||||
// a new token and saving it for future commands
|
// a new token and saving it for future commands
|
||||||
if !needs_auth {
|
if !needs_auth {
|
||||||
@@ -198,7 +218,12 @@ impl Command {
|
|||||||
#[derive(Error,Debug)]
|
#[derive(Error,Debug)]
|
||||||
pub enum MessageError {
|
pub enum MessageError {
|
||||||
#[error("Command needs a token. Login or create an account first.")]
|
#[error("Command needs a token. Login or create an account first.")]
|
||||||
NoToken
|
NoToken,
|
||||||
|
#[error("Error while parsing uuid: {0}")]
|
||||||
|
UuidError(#[from] uuid::Error),
|
||||||
|
#[error("Error during file IO: {0}")]
|
||||||
|
IoError(#[from] std::io::Error),
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+13
@@ -9,6 +9,8 @@ use clap::Parser;
|
|||||||
use fedichat::client::ServerMessage;
|
use fedichat::client::ServerMessage;
|
||||||
use hickory_resolver::Resolver;
|
use hickory_resolver::Resolver;
|
||||||
use std::net::{IpAddr,SocketAddr};
|
use std::net::{IpAddr,SocketAddr};
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Write;
|
||||||
use quinn::Endpoint;
|
use quinn::Endpoint;
|
||||||
use rmp_serde::encode::Serializer;
|
use rmp_serde::encode::Serializer;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
@@ -76,11 +78,18 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
SocketAddr::new(response,PORT),
|
SocketAddr::new(response,PORT),
|
||||||
&target_server)?.await?;
|
&target_server)?.await?;
|
||||||
|
|
||||||
|
// Dumb pattern
|
||||||
|
let mut file_to_write = None;
|
||||||
|
if let Command::Fetch{file, ..} = &cli.command {
|
||||||
|
file_to_write = Some(file.clone());
|
||||||
|
}
|
||||||
|
|
||||||
// send messages, each time waiting for a response
|
// send messages, each time waiting for a response
|
||||||
let messages = cli.command.generate_messages(cli.username.clone(),token)?;
|
let messages = cli.command.generate_messages(cli.username.clone(),token)?;
|
||||||
|
|
||||||
debug!("Sending commands");
|
debug!("Sending commands");
|
||||||
|
|
||||||
|
|
||||||
for message in messages {
|
for message in messages {
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
|
|
||||||
@@ -101,6 +110,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
ServerMessage::Token(ref token) => {
|
ServerMessage::Token(ref token) => {
|
||||||
config.insert_token(&target_server,cli.username.clone(),token.clone())?;
|
config.insert_token(&target_server,cli.username.clone(),token.clone())?;
|
||||||
},
|
},
|
||||||
|
ServerMessage::Media(ref bytes) => {
|
||||||
|
let mut file = File::create(file_to_write.clone().expect("File path not specified"))?;
|
||||||
|
file.write_all(bytes)?;
|
||||||
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user