Nomos chat app non interactive (#567)

* Add option to send chat message non iteractively via nomos cli

* Use clap to check if data or file is set

* Require author if message flag set
This commit is contained in:
gusto 2024-01-29 09:43:18 +02:00 committed by GitHub
parent 42d6816b1b
commit f33c2613fb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 48 additions and 15 deletions

View File

@ -63,6 +63,12 @@ pub struct NomosChat {
/// The node to connect to to fetch blocks and blobs /// The node to connect to to fetch blocks and blobs
#[clap(long)] #[clap(long)]
pub node: Url, pub node: Url,
/// Author for non interactive message formation
#[clap(long, requires("message"))]
pub author: Option<String>,
/// Message for non interactive message formation
#[clap(long, requires("author"))]
pub message: Option<String>,
} }
pub struct App { pub struct App {
@ -86,12 +92,6 @@ impl NomosChat {
<NetworkService<Libp2p> as ServiceData>::Settings, <NetworkService<Libp2p> as ServiceData>::Settings,
>(std::fs::File::open(&self.network_config)?)?; >(std::fs::File::open(&self.network_config)?)?;
let da_protocol = self.da_protocol.clone(); let da_protocol = self.da_protocol.clone();
// setup terminal
enable_raw_mode()?;
let mut stdout = io::stdout();
execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
let backend = CrosstermBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
let node_addr = Some(self.node.clone()); let node_addr = Some(self.node.clone());
@ -125,6 +125,21 @@ impl NomosChat {
.wait_finished() .wait_finished()
}); });
if let Some(author) = self.author.as_ref() {
let message = self
.message
.as_ref()
.expect("Should be available if author is set");
return run_once(author, message, payload_sender);
}
// setup terminal
enable_raw_mode()?;
let mut stdout = io::stdout();
execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
let backend = CrosstermBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
let app = App { let app = App {
input: Input::default(), input: Input::default(),
username: None, username: None,
@ -154,6 +169,24 @@ impl NomosChat {
} }
} }
fn run_once(
author: &str,
message: &str,
payload_sender: UnboundedSender<Box<[u8]>>,
) -> Result<(), Box<dyn std::error::Error>> {
payload_sender.send(
wire::serialize(&ChatMessage {
author: author.to_string(),
message: message.to_string(),
_nonce: rand::random(),
})
.unwrap()
.into(),
)?;
Ok(())
}
fn run_app<B: Backend>(terminal: &mut Terminal<B>, mut app: App) { fn run_app<B: Backend>(terminal: &mut Terminal<B>, mut app: App) {
let (message_tx, message_rx) = std::sync::mpsc::channel(); let (message_tx, message_rx) = std::sync::mpsc::channel();
let node = app.node.clone(); let node = app.node.clone();

View File

@ -12,7 +12,7 @@ use tokio::sync::Mutex;
#[derive(Args, Debug, Default)] #[derive(Args, Debug, Default)]
pub struct Disseminate { pub struct Disseminate {
// TODO: accept bytes // TODO: accept bytes
#[clap(short, long)] #[clap(short, long, required_unless_present("file"))]
pub data: Option<String>, pub data: Option<String>,
/// Path to the network config file /// Path to the network config file
#[clap(short, long)] #[clap(short, long)]
@ -44,15 +44,15 @@ impl Disseminate {
<NetworkService<Libp2p> as ServiceData>::Settings, <NetworkService<Libp2p> as ServiceData>::Settings,
>(std::fs::File::open(&self.network_config)?)?; >(std::fs::File::open(&self.network_config)?)?;
let (status_updates, rx) = std::sync::mpsc::channel(); let (status_updates, rx) = std::sync::mpsc::channel();
let bytes: Box<[u8]> = match (&self.data, &self.file) {
(Some(data), None) => data.clone().as_bytes().into(), let bytes: Box<[u8]> = if let Some(data) = &self.data {
(None, Some(file_path)) => { data.clone().as_bytes().into()
let file_bytes = std::fs::read(file_path)?; } else {
file_bytes.into_boxed_slice() let file_path = self.file.as_ref().unwrap();
} let file_bytes = std::fs::read(file_path)?;
(Some(_), Some(_)) => return Err("Cannot specify both data and file".into()), file_bytes.into_boxed_slice()
(None, None) => return Err("Either data or file must be specified".into()),
}; };
let timeout = Duration::from_secs(self.timeout); let timeout = Duration::from_secs(self.timeout);
let da_protocol = self.da_protocol.clone(); let da_protocol = self.da_protocol.clone();
let node_addr = self.node_addr.clone(); let node_addr = self.node_addr.clone();