daemon: add support for getting messages from db
This commit is contained in:
136
Cargo.lock
generated
136
Cargo.lock
generated
@@ -297,6 +297,27 @@ version = "0.8.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
|
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "csv"
|
||||||
|
version = "1.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "acdc4883a9c96732e4733212c01447ebd805833b7275a73ca3ee080fd77afdaf"
|
||||||
|
dependencies = [
|
||||||
|
"csv-core",
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "csv-core"
|
||||||
|
version = "0.1.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7d02f3b0da4c6504f86e9cd789d8dbafab48c2321be74e9987593de5a894d93d"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ctor"
|
name = "ctor"
|
||||||
version = "0.2.8"
|
version = "0.2.8"
|
||||||
@@ -459,6 +480,16 @@ dependencies = [
|
|||||||
"dirs-sys",
|
"dirs-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dirs-next"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"dirs-sys-next",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dirs-sys"
|
name = "dirs-sys"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
@@ -467,10 +498,21 @@ checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"option-ext",
|
"option-ext",
|
||||||
"redox_users",
|
"redox_users 0.5.0",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dirs-sys-next"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"redox_users 0.4.6",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dotenv"
|
name = "dotenv"
|
||||||
version = "0.15.0"
|
version = "0.15.0"
|
||||||
@@ -497,6 +539,12 @@ version = "1.13.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "encode_unicode"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "env_filter"
|
name = "env_filter"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
@@ -678,6 +726,12 @@ version = "0.3.9"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
|
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hermit-abi"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fbd780fe5cc30f81464441920d82ac8740e2e46b29a6fad543ddd075229ce37e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "http"
|
name = "http"
|
||||||
version = "0.2.12"
|
version = "0.2.12"
|
||||||
@@ -788,6 +842,17 @@ dependencies = [
|
|||||||
"hashbrown",
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "is-terminal"
|
||||||
|
version = "0.4.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9"
|
||||||
|
dependencies = [
|
||||||
|
"hermit-abi 0.5.0",
|
||||||
|
"libc",
|
||||||
|
"windows-sys 0.59.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "is_terminal_polyfill"
|
name = "is_terminal_polyfill"
|
||||||
version = "1.70.1"
|
version = "1.70.1"
|
||||||
@@ -888,7 +953,7 @@ dependencies = [
|
|||||||
"kordophone",
|
"kordophone",
|
||||||
"kordophone-db",
|
"kordophone-db",
|
||||||
"log",
|
"log",
|
||||||
"thiserror",
|
"thiserror 2.0.12",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -906,6 +971,7 @@ dependencies = [
|
|||||||
"kordophone-db",
|
"kordophone-db",
|
||||||
"log",
|
"log",
|
||||||
"pretty",
|
"pretty",
|
||||||
|
"prettytable",
|
||||||
"time",
|
"time",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
@@ -1199,6 +1265,20 @@ dependencies = [
|
|||||||
"unicode-width",
|
"unicode-width",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "prettytable"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "46480520d1b77c9a3482d39939fcf96831537a250ec62d4fd8fbdf8e0302e781"
|
||||||
|
dependencies = [
|
||||||
|
"csv",
|
||||||
|
"encode_unicode",
|
||||||
|
"is-terminal",
|
||||||
|
"lazy_static",
|
||||||
|
"term",
|
||||||
|
"unicode-width",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.95"
|
version = "1.0.95"
|
||||||
@@ -1256,6 +1336,17 @@ dependencies = [
|
|||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_users"
|
||||||
|
version = "0.4.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
"libredox",
|
||||||
|
"thiserror 1.0.69",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_users"
|
name = "redox_users"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
@@ -1264,7 +1355,7 @@ checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom",
|
"getrandom",
|
||||||
"libredox",
|
"libredox",
|
||||||
"thiserror",
|
"thiserror 2.0.12",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1315,6 +1406,12 @@ dependencies = [
|
|||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustversion"
|
||||||
|
version = "1.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.17"
|
version = "1.0.17"
|
||||||
@@ -1477,6 +1574,17 @@ dependencies = [
|
|||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "term"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f"
|
||||||
|
dependencies = [
|
||||||
|
"dirs-next",
|
||||||
|
"rustversion",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "termcolor"
|
name = "termcolor"
|
||||||
version = "1.4.1"
|
version = "1.4.1"
|
||||||
@@ -1495,13 +1603,33 @@ dependencies = [
|
|||||||
"unicode-width",
|
"unicode-width",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "1.0.69"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl 1.0.69",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "2.0.12"
|
version = "2.0.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
|
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl",
|
"thiserror-impl 2.0.12",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "1.0.69"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -207,6 +207,21 @@ impl<'a> Repository<'a> {
|
|||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_last_message_for_conversation(&mut self, conversation_guid: &str) -> Result<Option<Message>> {
|
||||||
|
use crate::schema::messages::dsl::*;
|
||||||
|
use crate::schema::conversation_messages::dsl::*;
|
||||||
|
|
||||||
|
let message_record = conversation_messages
|
||||||
|
.filter(conversation_id.eq(conversation_guid))
|
||||||
|
.inner_join(messages)
|
||||||
|
.select(MessageRecord::as_select())
|
||||||
|
.order_by(schema::messages::date.desc())
|
||||||
|
.first::<MessageRecord>(self.connection)
|
||||||
|
.optional()?;
|
||||||
|
|
||||||
|
Ok(message_record.map(|r| r.into()))
|
||||||
|
}
|
||||||
|
|
||||||
// Helper function to get the last inserted row ID
|
// Helper function to get the last inserted row ID
|
||||||
// This is a workaround since the Sqlite backend doesn't support `RETURNING`
|
// This is a workaround since the Sqlite backend doesn't support `RETURNING`
|
||||||
// Huge caveat with this is that it depends on whatever the last insert was, prevents concurrent inserts.
|
// Huge caveat with this is that it depends on whatever the last insert was, prevents concurrent inserts.
|
||||||
|
|||||||
@@ -310,6 +310,10 @@ async fn test_insert_messages_batch() {
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure the last message is the last one we inserted
|
||||||
|
let last_message = repository.get_last_message_for_conversation(&conversation_id).unwrap().unwrap();
|
||||||
|
assert_eq!(last_message.id, message4.id);
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
value="Returns the version of the client daemon."/>
|
value="Returns the version of the client daemon."/>
|
||||||
</method>
|
</method>
|
||||||
|
|
||||||
|
<!-- Conversations -->
|
||||||
|
|
||||||
<method name="GetConversations">
|
<method name="GetConversations">
|
||||||
<arg type="aa{sv}" direction="out" name="conversations">
|
<arg type="aa{sv}" direction="out" name="conversations">
|
||||||
<annotation name="org.freedesktop.DBus.DocString"
|
<annotation name="org.freedesktop.DBus.DocString"
|
||||||
@@ -31,6 +33,20 @@
|
|||||||
<annotation name="org.freedesktop.DBus.DocString"
|
<annotation name="org.freedesktop.DBus.DocString"
|
||||||
value="Emitted when the list of conversations is updated."/>
|
value="Emitted when the list of conversations is updated."/>
|
||||||
</signal>
|
</signal>
|
||||||
|
|
||||||
|
<!-- Messages -->
|
||||||
|
|
||||||
|
<method name="GetMessages">
|
||||||
|
<arg type="s" name="conversation_id" direction="in"/>
|
||||||
|
<arg type="s" name="last_message_id" direction="in"/>
|
||||||
|
<arg type="aa{sv}" direction="out" name="messages"/>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<signal name="MessagesUpdated">
|
||||||
|
<annotation name="org.freedesktop.DBus.DocString"
|
||||||
|
value="Emitted when the list of messages is updated."/>
|
||||||
|
</signal>
|
||||||
|
|
||||||
</interface>
|
</interface>
|
||||||
|
|
||||||
<interface name="net.buzzert.kordophone.Settings">
|
<interface name="net.buzzert.kordophone.Settings">
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use tokio::sync::oneshot;
|
use tokio::sync::oneshot;
|
||||||
use kordophone_db::models::Conversation;
|
use kordophone_db::models::{Conversation, Message};
|
||||||
use crate::daemon::settings::Settings;
|
use crate::daemon::settings::Settings;
|
||||||
|
|
||||||
pub type Reply<T> = oneshot::Sender<T>;
|
pub type Reply<T> = oneshot::Sender<T>;
|
||||||
@@ -20,6 +20,12 @@ pub enum Event {
|
|||||||
|
|
||||||
/// Update settings in the database.
|
/// Update settings in the database.
|
||||||
UpdateSettings(Settings, Reply<()>),
|
UpdateSettings(Settings, Reply<()>),
|
||||||
|
|
||||||
|
/// Returns all messages for a conversation from the database.
|
||||||
|
/// Parameters:
|
||||||
|
/// - conversation_id: The ID of the conversation to get messages for.
|
||||||
|
/// - last_message_id: (optional) The ID of the last message to get. If None, all messages are returned.
|
||||||
|
GetMessages(String, Option<String>, Reply<Vec<Message>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ use async_trait::async_trait;
|
|||||||
|
|
||||||
use kordophone_db::{
|
use kordophone_db::{
|
||||||
database::{Database, DatabaseAccess},
|
database::{Database, DatabaseAccess},
|
||||||
models::Conversation,
|
models::{Conversation, Message},
|
||||||
};
|
};
|
||||||
|
|
||||||
use kordophone::model::JwtToken;
|
use kordophone::model::JwtToken;
|
||||||
@@ -54,6 +54,7 @@ impl TokenStore for DatabaseTokenStore {
|
|||||||
|
|
||||||
mod target {
|
mod target {
|
||||||
pub static SYNC: &str = "sync";
|
pub static SYNC: &str = "sync";
|
||||||
|
pub static EVENT: &str = "event";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Daemon {
|
pub struct Daemon {
|
||||||
@@ -100,7 +101,11 @@ impl Daemon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run(&mut self) {
|
pub async fn run(&mut self) {
|
||||||
|
log::info!("Starting daemon version {}", self.version);
|
||||||
|
log::debug!("Debug logging enabled.");
|
||||||
|
|
||||||
while let Some(event) = self.event_receiver.recv().await {
|
while let Some(event) = self.event_receiver.recv().await {
|
||||||
|
log::debug!(target: target::EVENT, "Received event: {:?}", event);
|
||||||
self.handle_event(event).await;
|
self.handle_event(event).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -148,6 +153,11 @@ impl Daemon {
|
|||||||
|
|
||||||
reply.send(()).unwrap();
|
reply.send(()).unwrap();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Event::GetMessages(conversation_id, last_message_id, reply) => {
|
||||||
|
let messages = self.get_messages(conversation_id, last_message_id).await;
|
||||||
|
reply.send(messages).unwrap();
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,6 +170,10 @@ impl Daemon {
|
|||||||
self.database.lock().await.with_repository(|r| r.all_conversations().unwrap()).await
|
self.database.lock().await.with_repository(|r| r.all_conversations().unwrap()).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn get_messages(&mut self, conversation_id: String, last_message_id: Option<String>) -> Vec<Message> {
|
||||||
|
self.database.lock().await.with_repository(|r| r.get_messages_for_conversation(&conversation_id).unwrap()).await
|
||||||
|
}
|
||||||
|
|
||||||
async fn sync_all_conversations_impl(database: &mut Arc<Mutex<Database>>, signal_sender: &Sender<Signal>) -> Result<()> {
|
async fn sync_all_conversations_impl(database: &mut Arc<Mutex<Database>>, signal_sender: &Sender<Signal>) -> Result<()> {
|
||||||
log::info!(target: target::SYNC, "Starting conversation sync");
|
log::info!(target: target::SYNC, "Starting conversation sync");
|
||||||
|
|
||||||
@@ -180,8 +194,16 @@ impl Daemon {
|
|||||||
database.with_repository(|r| r.insert_conversation(conversation)).await?;
|
database.with_repository(|r| r.insert_conversation(conversation)).await?;
|
||||||
|
|
||||||
// Fetch and sync messages for this conversation
|
// Fetch and sync messages for this conversation
|
||||||
|
let last_message_id = database.with_repository(|r| -> Option<String> {
|
||||||
|
r.get_last_message_for_conversation(&conversation_id)
|
||||||
|
.unwrap_or(None)
|
||||||
|
.map(|m| m.id)
|
||||||
|
}).await;
|
||||||
|
|
||||||
log::debug!(target: target::SYNC, "Fetching messages for conversation {}", conversation_id);
|
log::debug!(target: target::SYNC, "Fetching messages for conversation {}", conversation_id);
|
||||||
let messages = client.get_messages(&conversation_id, None, None, None).await?;
|
log::debug!(target: target::SYNC, "Last message id: {:?}", last_message_id);
|
||||||
|
|
||||||
|
let messages = client.get_messages(&conversation_id, None, None, last_message_id).await?;
|
||||||
let db_messages: Vec<kordophone_db::models::Message> = messages.into_iter()
|
let db_messages: Vec<kordophone_db::models::Message> = messages.into_iter()
|
||||||
.map(|m| kordophone_db::models::Message::from(m))
|
.map(|m| kordophone_db::models::Message::from(m))
|
||||||
.collect();
|
.collect();
|
||||||
|
|||||||
@@ -74,6 +74,28 @@ impl DbusRepository for ServerImpl {
|
|||||||
fn sync_all_conversations(&mut self) -> Result<(), dbus::MethodErr> {
|
fn sync_all_conversations(&mut self) -> Result<(), dbus::MethodErr> {
|
||||||
self.send_event_sync(Event::SyncAllConversations)
|
self.send_event_sync(Event::SyncAllConversations)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_messages(&mut self, conversation_id: String, last_message_id: String) -> Result<Vec<arg::PropMap>, dbus::MethodErr> {
|
||||||
|
let last_message_id_opt = if last_message_id.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(last_message_id)
|
||||||
|
};
|
||||||
|
|
||||||
|
self.send_event_sync(|r| Event::GetMessages(conversation_id, last_message_id_opt, r))
|
||||||
|
.and_then(|messages| {
|
||||||
|
let result = messages.into_iter().map(|msg| {
|
||||||
|
let mut map = arg::PropMap::new();
|
||||||
|
map.insert("id".into(), arg::Variant(Box::new(msg.id)));
|
||||||
|
map.insert("text".into(), arg::Variant(Box::new(msg.text)));
|
||||||
|
map.insert("date".into(), arg::Variant(Box::new(msg.date.and_utc().timestamp())));
|
||||||
|
map.insert("sender".into(), arg::Variant(Box::new(msg.sender.display_name())));
|
||||||
|
map
|
||||||
|
}).collect();
|
||||||
|
|
||||||
|
Ok(result)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DbusSettings for ServerImpl {
|
impl DbusSettings for ServerImpl {
|
||||||
|
|||||||
@@ -12,9 +12,14 @@ use dbus::interface;
|
|||||||
use dbus::server_impl::ServerImpl;
|
use dbus::server_impl::ServerImpl;
|
||||||
|
|
||||||
fn initialize_logging() {
|
fn initialize_logging() {
|
||||||
|
// Weird: is this the best way to do this?
|
||||||
|
let log_level = std::env::var("RUST_LOG")
|
||||||
|
.map(|s| s.parse::<LevelFilter>().unwrap_or(LevelFilter::Info))
|
||||||
|
.unwrap_or(LevelFilter::Info);
|
||||||
|
|
||||||
env_logger::Builder::from_default_env()
|
env_logger::Builder::from_default_env()
|
||||||
.filter_level(LevelFilter::Info)
|
|
||||||
.format_timestamp_secs()
|
.format_timestamp_secs()
|
||||||
|
.filter_level(log_level)
|
||||||
.init();
|
.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ kordophone = { path = "../kordophone" }
|
|||||||
kordophone-db = { path = "../kordophone-db" }
|
kordophone-db = { path = "../kordophone-db" }
|
||||||
log = "0.4.22"
|
log = "0.4.22"
|
||||||
pretty = { version = "0.12.3", features = ["termcolor"] }
|
pretty = { version = "0.12.3", features = ["termcolor"] }
|
||||||
|
prettytable = "0.10.0"
|
||||||
time = "0.3.37"
|
time = "0.3.37"
|
||||||
tokio = "1.41.1"
|
tokio = "1.41.1"
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use clap::Subcommand;
|
use clap::Subcommand;
|
||||||
use dbus::blocking::{Connection, Proxy};
|
use dbus::blocking::{Connection, Proxy};
|
||||||
|
use prettytable::table;
|
||||||
use crate::printers::{ConversationPrinter, MessagePrinter};
|
use crate::printers::{ConversationPrinter, MessagePrinter};
|
||||||
use std::future;
|
|
||||||
|
|
||||||
const DBUS_NAME: &str = "net.buzzert.kordophonecd";
|
const DBUS_NAME: &str = "net.buzzert.kordophonecd";
|
||||||
const DBUS_PATH: &str = "/net/buzzert/kordophonecd/daemon";
|
const DBUS_PATH: &str = "/net/buzzert/kordophonecd/daemon";
|
||||||
@@ -34,6 +34,12 @@ pub enum Commands {
|
|||||||
|
|
||||||
/// Waits for signals from the daemon.
|
/// Waits for signals from the daemon.
|
||||||
Signals,
|
Signals,
|
||||||
|
|
||||||
|
/// Prints the messages for a conversation.
|
||||||
|
Messages {
|
||||||
|
conversation_id: String,
|
||||||
|
last_message_id: Option<String>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subcommand)]
|
#[derive(Subcommand)]
|
||||||
@@ -66,6 +72,7 @@ impl Commands {
|
|||||||
Commands::Sync => client.sync_conversations().await,
|
Commands::Sync => client.sync_conversations().await,
|
||||||
Commands::Config { command } => client.config(command).await,
|
Commands::Config { command } => client.config(command).await,
|
||||||
Commands::Signals => client.wait_for_signals().await,
|
Commands::Signals => client.wait_for_signals().await,
|
||||||
|
Commands::Messages { conversation_id, last_message_id } => client.print_messages(conversation_id, last_message_id).await,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -107,6 +114,17 @@ impl DaemonCli {
|
|||||||
.map_err(|e| anyhow::anyhow!("Failed to sync conversations: {}", e))
|
.map_err(|e| anyhow::anyhow!("Failed to sync conversations: {}", e))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn print_messages(&mut self, conversation_id: String, last_message_id: Option<String>) -> Result<()> {
|
||||||
|
let messages = KordophoneRepository::get_messages(&self.proxy(), &conversation_id, &last_message_id.unwrap_or_default())?;
|
||||||
|
println!("Number of messages: {}", messages.len());
|
||||||
|
|
||||||
|
for message in messages {
|
||||||
|
println!("{}", MessagePrinter::new(&message.into()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn wait_for_signals(&mut self) -> Result<()> {
|
pub async fn wait_for_signals(&mut self) -> Result<()> {
|
||||||
use dbus::Message;
|
use dbus::Message;
|
||||||
mod dbus_signals {
|
mod dbus_signals {
|
||||||
@@ -136,13 +154,17 @@ impl DaemonCli {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn print_settings(&mut self) -> Result<()> {
|
pub async fn print_settings(&mut self) -> Result<()> {
|
||||||
let server_url = KordophoneSettings::server_url(&self.proxy())?;
|
let server_url = KordophoneSettings::server_url(&self.proxy()).unwrap_or_default();
|
||||||
let username = KordophoneSettings::username(&self.proxy())?;
|
let username = KordophoneSettings::username(&self.proxy()).unwrap_or_default();
|
||||||
let credential_item = KordophoneSettings::credential_item(&self.proxy())?;
|
let credential_item = KordophoneSettings::credential_item(&self.proxy()).unwrap_or_default();
|
||||||
|
|
||||||
|
let table = table!(
|
||||||
|
[ b->"Server URL", &server_url ],
|
||||||
|
[ b->"Username", &username ],
|
||||||
|
[ b->"Credential Item", &credential_item ]
|
||||||
|
);
|
||||||
|
table.printstd();
|
||||||
|
|
||||||
println!("Server URL: {}", server_url);
|
|
||||||
println!("Username: {}", username);
|
|
||||||
println!("Credential Item: {}", credential_item);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -86,6 +86,17 @@ impl From<kordophone_db::models::Message> for PrintableMessage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<arg::PropMap> for PrintableMessage {
|
||||||
|
fn from(value: arg::PropMap) -> Self {
|
||||||
|
Self {
|
||||||
|
guid: value.get("id").unwrap().as_str().unwrap().to_string(),
|
||||||
|
date: OffsetDateTime::from_unix_timestamp(value.get("date").unwrap().as_i64().unwrap()).unwrap(),
|
||||||
|
sender: value.get("sender").unwrap().as_str().unwrap().to_string(),
|
||||||
|
text: value.get("text").unwrap().as_str().unwrap().to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct ConversationPrinter<'a> {
|
pub struct ConversationPrinter<'a> {
|
||||||
doc: RcDoc<'a, PrintableConversation>
|
doc: RcDoc<'a, PrintableConversation>
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user