daemon: add support for getting messages from db
This commit is contained in:
@@ -8,6 +8,8 @@
|
||||
value="Returns the version of the client daemon."/>
|
||||
</method>
|
||||
|
||||
<!-- Conversations -->
|
||||
|
||||
<method name="GetConversations">
|
||||
<arg type="aa{sv}" direction="out" name="conversations">
|
||||
<annotation name="org.freedesktop.DBus.DocString"
|
||||
@@ -31,6 +33,20 @@
|
||||
<annotation name="org.freedesktop.DBus.DocString"
|
||||
value="Emitted when the list of conversations is updated."/>
|
||||
</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 name="net.buzzert.kordophone.Settings">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use tokio::sync::oneshot;
|
||||
use kordophone_db::models::Conversation;
|
||||
use kordophone_db::models::{Conversation, Message};
|
||||
use crate::daemon::settings::Settings;
|
||||
|
||||
pub type Reply<T> = oneshot::Sender<T>;
|
||||
@@ -20,6 +20,12 @@ pub enum Event {
|
||||
|
||||
/// Update settings in the database.
|
||||
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::{
|
||||
database::{Database, DatabaseAccess},
|
||||
models::Conversation,
|
||||
models::{Conversation, Message},
|
||||
};
|
||||
|
||||
use kordophone::model::JwtToken;
|
||||
@@ -54,6 +54,7 @@ impl TokenStore for DatabaseTokenStore {
|
||||
|
||||
mod target {
|
||||
pub static SYNC: &str = "sync";
|
||||
pub static EVENT: &str = "event";
|
||||
}
|
||||
|
||||
pub struct Daemon {
|
||||
@@ -100,7 +101,11 @@ impl Daemon {
|
||||
}
|
||||
|
||||
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 {
|
||||
log::debug!(target: target::EVENT, "Received event: {:?}", event);
|
||||
self.handle_event(event).await;
|
||||
}
|
||||
}
|
||||
@@ -148,6 +153,11 @@ impl Daemon {
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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<()> {
|
||||
log::info!(target: target::SYNC, "Starting conversation sync");
|
||||
|
||||
@@ -180,8 +194,16 @@ impl Daemon {
|
||||
database.with_repository(|r| r.insert_conversation(conversation)).await?;
|
||||
|
||||
// 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);
|
||||
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()
|
||||
.map(|m| kordophone_db::models::Message::from(m))
|
||||
.collect();
|
||||
|
||||
@@ -74,6 +74,28 @@ impl DbusRepository for ServerImpl {
|
||||
fn sync_all_conversations(&mut self) -> Result<(), dbus::MethodErr> {
|
||||
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 {
|
||||
|
||||
@@ -12,9 +12,14 @@ use dbus::interface;
|
||||
use dbus::server_impl::ServerImpl;
|
||||
|
||||
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()
|
||||
.filter_level(LevelFilter::Info)
|
||||
.format_timestamp_secs()
|
||||
.filter_level(log_level)
|
||||
.init();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user