Add 'core/' from commit 'b0dfc4146ca0da535a87f8509aec68817fb2ab14'
git-subtree-dir: core git-subtree-mainline:a07f3dcd23git-subtree-split:b0dfc4146c
This commit is contained in:
178
core/kpcli/src/client/mod.rs
Normal file
178
core/kpcli/src/client/mod.rs
Normal file
@@ -0,0 +1,178 @@
|
||||
use kordophone::api::event_socket::{EventSocket, SocketEvent, SocketUpdate};
|
||||
use kordophone::api::http_client::Credentials;
|
||||
use kordophone::api::http_client::HTTPAPIClient;
|
||||
use kordophone::api::InMemoryAuthenticationStore;
|
||||
use kordophone::APIInterface;
|
||||
|
||||
use crate::printers::{ConversationPrinter, MessagePrinter};
|
||||
use anyhow::Result;
|
||||
use clap::Subcommand;
|
||||
use kordophone::model::event::EventData;
|
||||
use kordophone::model::outgoing_message::OutgoingMessage;
|
||||
|
||||
use futures_util::StreamExt;
|
||||
|
||||
pub fn make_api_client_from_env() -> HTTPAPIClient<InMemoryAuthenticationStore> {
|
||||
dotenv::dotenv().ok();
|
||||
|
||||
// read from env
|
||||
let base_url = std::env::var("KORDOPHONE_API_URL").expect("KORDOPHONE_API_URL must be set");
|
||||
|
||||
let credentials = Credentials {
|
||||
username: std::env::var("KORDOPHONE_USERNAME").expect("KORDOPHONE_USERNAME must be set"),
|
||||
|
||||
password: std::env::var("KORDOPHONE_PASSWORD").expect("KORDOPHONE_PASSWORD must be set"),
|
||||
};
|
||||
|
||||
HTTPAPIClient::new(
|
||||
base_url.parse().unwrap(),
|
||||
InMemoryAuthenticationStore::new(Some(credentials)),
|
||||
)
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
pub enum Commands {
|
||||
/// Prints all known conversations on the server.
|
||||
Conversations,
|
||||
|
||||
/// Prints all messages in a conversation.
|
||||
Messages { conversation_id: String },
|
||||
|
||||
/// Prints the server Kordophone version.
|
||||
Version,
|
||||
|
||||
/// Prints all events from the server.
|
||||
Events,
|
||||
|
||||
/// Prints all raw updates from the server.
|
||||
RawUpdates,
|
||||
|
||||
/// Sends a message to the server.
|
||||
SendMessage {
|
||||
conversation_id: String,
|
||||
message: String,
|
||||
},
|
||||
|
||||
/// Marks a conversation as read.
|
||||
Mark { conversation_id: String },
|
||||
}
|
||||
|
||||
impl Commands {
|
||||
pub async fn run(cmd: Commands) -> Result<()> {
|
||||
let mut client = ClientCli::new();
|
||||
match cmd {
|
||||
Commands::Version => client.print_version().await,
|
||||
Commands::Conversations => client.print_conversations().await,
|
||||
Commands::Messages { conversation_id } => client.print_messages(conversation_id).await,
|
||||
Commands::RawUpdates => client.print_raw_updates().await,
|
||||
Commands::Events => client.print_events().await,
|
||||
Commands::SendMessage {
|
||||
conversation_id,
|
||||
message,
|
||||
} => client.send_message(conversation_id, message).await,
|
||||
Commands::Mark { conversation_id } => {
|
||||
client.mark_conversation_as_read(conversation_id).await
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ClientCli {
|
||||
api: HTTPAPIClient<InMemoryAuthenticationStore>,
|
||||
}
|
||||
|
||||
impl ClientCli {
|
||||
pub fn new() -> Self {
|
||||
let api = make_api_client_from_env();
|
||||
Self { api }
|
||||
}
|
||||
|
||||
pub async fn print_version(&mut self) -> Result<()> {
|
||||
let version = self.api.get_version().await?;
|
||||
println!("Version: {}", version);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn print_conversations(&mut self) -> Result<()> {
|
||||
let conversations = self.api.get_conversations().await?;
|
||||
for conversation in conversations {
|
||||
println!("{}", ConversationPrinter::new(&conversation.into()));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn print_messages(&mut self, conversation_id: String) -> Result<()> {
|
||||
let messages = self
|
||||
.api
|
||||
.get_messages(&conversation_id, None, None, None)
|
||||
.await?;
|
||||
for message in messages {
|
||||
println!("{}", MessagePrinter::new(&message.into()));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn print_events(&mut self) -> Result<()> {
|
||||
let socket = self.api.open_event_socket(None).await?;
|
||||
|
||||
let (mut stream, _) = socket.events().await;
|
||||
while let Some(Ok(socket_event)) = stream.next().await {
|
||||
match socket_event {
|
||||
SocketEvent::Update(event) => match event.data {
|
||||
EventData::ConversationChanged(conversation) => {
|
||||
println!("Conversation changed: {}", conversation.guid);
|
||||
}
|
||||
EventData::MessageReceived(conversation, message) => {
|
||||
println!(
|
||||
"Message received: msg: {} conversation: {}",
|
||||
message.guid, conversation.guid
|
||||
);
|
||||
}
|
||||
},
|
||||
SocketEvent::Pong => {
|
||||
println!("Pong");
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn print_raw_updates(&mut self) -> Result<()> {
|
||||
let socket = self.api.open_event_socket(None).await?;
|
||||
|
||||
println!("Listening for raw updates...");
|
||||
let mut stream = socket.raw_updates().await;
|
||||
while let Some(Ok(update)) = stream.next().await {
|
||||
match update {
|
||||
SocketUpdate::Update(updates) => {
|
||||
for update in updates {
|
||||
println!("Got update: {:?}", update);
|
||||
}
|
||||
}
|
||||
SocketUpdate::Pong => {
|
||||
println!("Pong");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn send_message(&mut self, conversation_id: String, message: String) -> Result<()> {
|
||||
let outgoing_message = OutgoingMessage::builder()
|
||||
.conversation_id(conversation_id)
|
||||
.text(message)
|
||||
.build();
|
||||
|
||||
let message = self.api.send_message(&outgoing_message).await?;
|
||||
println!("Message sent: {}", message.guid);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn mark_conversation_as_read(&mut self, conversation_id: String) -> Result<()> {
|
||||
self.api.mark_conversation_as_read(&conversation_id).await?;
|
||||
println!("Conversation marked as read: {}", conversation_id);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user