xmpp: new Config struct for Agent, with bookmarks_autojoin for now
Signed-off-by: pep <pep@bouah.net>
This commit is contained in:
parent
77acd92c62
commit
147b79ca52
6 changed files with 84 additions and 18 deletions
|
|
@ -43,6 +43,7 @@ XXXX-YY-ZZ [ RELEASER <admin@localhost> ]
|
||||||
stanzas.
|
stanzas.
|
||||||
- Added documentation on `Event` enum.
|
- Added documentation on `Event` enum.
|
||||||
- Update to edition 2024
|
- Update to edition 2024
|
||||||
|
- Add Config::Config struct as a user-facing Agent configuration method.
|
||||||
* Fixes:
|
* Fixes:
|
||||||
- Use tokio::sync::RwLock not std::sync::RwLock (!432)
|
- Use tokio::sync::RwLock not std::sync::RwLock (!432)
|
||||||
- The default caps node has been shortened to https://xmpp.rs since we
|
- The default caps node has been shortened to https://xmpp.rs since we
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ use tokio::io;
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Error, Event, RoomNick, event_loop,
|
Config, Error, Event, RoomNick, event_loop,
|
||||||
jid::{BareJid, Jid},
|
jid::{BareJid, Jid},
|
||||||
message, muc,
|
message, muc,
|
||||||
parsers::disco::DiscoInfoResult,
|
parsers::disco::DiscoInfoResult,
|
||||||
|
|
@ -24,6 +24,7 @@ use tokio_xmpp::{Stanza, stanzastream::StanzaToken};
|
||||||
|
|
||||||
pub struct Agent {
|
pub struct Agent {
|
||||||
pub(crate) client: TokioXmppClient,
|
pub(crate) client: TokioXmppClient,
|
||||||
|
pub(crate) config: Arc<RwLock<Config>>,
|
||||||
pub(crate) default_nick: Arc<RwLock<RoomNick>>,
|
pub(crate) default_nick: Arc<RwLock<RoomNick>>,
|
||||||
pub(crate) lang: Arc<Vec<String>>,
|
pub(crate) lang: Arc<Vec<String>>,
|
||||||
pub(crate) disco: DiscoInfoResult,
|
pub(crate) disco: DiscoInfoResult,
|
||||||
|
|
@ -39,6 +40,7 @@ pub struct Agent {
|
||||||
impl Agent {
|
impl Agent {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
client: TokioXmppClient,
|
client: TokioXmppClient,
|
||||||
|
config: Config,
|
||||||
default_nick: RoomNick,
|
default_nick: RoomNick,
|
||||||
lang: Vec<String>,
|
lang: Vec<String>,
|
||||||
disco: DiscoInfoResult,
|
disco: DiscoInfoResult,
|
||||||
|
|
@ -46,6 +48,7 @@ impl Agent {
|
||||||
) -> Agent {
|
) -> Agent {
|
||||||
Agent {
|
Agent {
|
||||||
client,
|
client,
|
||||||
|
config: Arc::new(RwLock::new(config)),
|
||||||
default_nick: Arc::new(RwLock::new(default_nick)),
|
default_nick: Arc::new(RwLock::new(default_nick)),
|
||||||
lang: Arc::new(lang),
|
lang: Arc::new(lang),
|
||||||
disco,
|
disco,
|
||||||
|
|
@ -58,6 +61,13 @@ impl Agent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reset the agent configuration to the provided Config struct
|
||||||
|
// TODO: refresh everything that is affected by this reset?
|
||||||
|
pub async fn set_config(&mut self, config: Config) {
|
||||||
|
let mut c = self.config.write().await;
|
||||||
|
*c = config;
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn disconnect(self) -> Result<(), Error> {
|
pub async fn disconnect(self) -> Result<(), Error> {
|
||||||
self.client.send_end().await
|
self.client.send_end().await
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ use crate::tokio_xmpp::connect::{DnsConfig, StartTlsServerConnector};
|
||||||
use core::str::FromStr;
|
use core::str::FromStr;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Agent, ClientFeature, RoomNick,
|
Agent, ClientFeature, Config, RoomNick,
|
||||||
jid::{BareJid, Jid, ResourceRef},
|
jid::{BareJid, Jid, ResourceRef},
|
||||||
parsers::{
|
parsers::{
|
||||||
disco::{DiscoInfoResult, Feature, Identity},
|
disco::{DiscoInfoResult, Feature, Identity},
|
||||||
|
|
@ -43,6 +43,7 @@ pub struct ClientBuilder<'a, C: ServerConnector> {
|
||||||
jid: BareJid,
|
jid: BareJid,
|
||||||
password: &'a str,
|
password: &'a str,
|
||||||
server_connector: C,
|
server_connector: C,
|
||||||
|
config: Config,
|
||||||
website: String,
|
website: String,
|
||||||
default_nick: RoomNick,
|
default_nick: RoomNick,
|
||||||
lang: Vec<String>,
|
lang: Vec<String>,
|
||||||
|
|
@ -73,6 +74,7 @@ impl<C: ServerConnector> ClientBuilder<'_, C> {
|
||||||
jid,
|
jid,
|
||||||
password,
|
password,
|
||||||
server_connector,
|
server_connector,
|
||||||
|
config: Config::default(),
|
||||||
website: String::from("https://gitlab.com/xmpp-rs/tokio-xmpp"),
|
website: String::from("https://gitlab.com/xmpp-rs/tokio-xmpp"),
|
||||||
default_nick: RoomNick::from_str("xmpp-rs").unwrap(),
|
default_nick: RoomNick::from_str("xmpp-rs").unwrap(),
|
||||||
lang: vec![String::from("en")],
|
lang: vec![String::from("en")],
|
||||||
|
|
@ -89,6 +91,11 @@ impl<C: ServerConnector> ClientBuilder<'_, C> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_config(mut self, config: Config) -> Self {
|
||||||
|
self.config = config;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_client(mut self, type_: ClientType, name: &str) -> Self {
|
pub fn set_client(mut self, type_: ClientType, name: &str) -> Self {
|
||||||
self.disco = (type_, String::from(name));
|
self.disco = (type_, String::from(name));
|
||||||
self
|
self
|
||||||
|
|
@ -169,6 +176,13 @@ impl<C: ServerConnector> ClientBuilder<'_, C> {
|
||||||
let disco = self.make_disco();
|
let disco = self.make_disco();
|
||||||
let node = self.website;
|
let node = self.website;
|
||||||
|
|
||||||
Agent::new(client, self.default_nick, self.lang, disco, node)
|
Agent::new(
|
||||||
|
client,
|
||||||
|
self.config,
|
||||||
|
self.default_nick,
|
||||||
|
self.lang,
|
||||||
|
disco,
|
||||||
|
node,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
31
xmpp/src/config.rs
Normal file
31
xmpp/src/config.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
// Copyright (c) 2025 Crate authors
|
||||||
|
//
|
||||||
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
/// Store Agent configuration. Differs from state which is generated at runtime
|
||||||
|
pub struct Config {
|
||||||
|
/// Synchronize bookmarks based on autojoin flag.
|
||||||
|
/// The client will join and leave based on the value of the `autojoin` flag on the (pubsub)
|
||||||
|
/// bookmark item.
|
||||||
|
/// If this `bookmarks_autojoin` attribute is set to false, `autojoin` set to false won't make
|
||||||
|
/// the client leave a room, neither will the removal of a bookmark item. This will only happen
|
||||||
|
/// after the client is restarted, as these items won't be automatically joined anymore.
|
||||||
|
/// <https://xmpp.org/extensions/xep-0402.html#notification>
|
||||||
|
pub bookmarks_autojoin: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Config {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
fn new() -> Self {
|
||||||
|
Config {
|
||||||
|
bookmarks_autojoin: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -65,6 +65,7 @@ use parsers::message::Id as MessageId;
|
||||||
|
|
||||||
pub mod agent;
|
pub mod agent;
|
||||||
pub mod builder;
|
pub mod builder;
|
||||||
|
pub mod config;
|
||||||
pub mod delay;
|
pub mod delay;
|
||||||
pub mod disco;
|
pub mod disco;
|
||||||
pub mod event;
|
pub mod event;
|
||||||
|
|
@ -79,6 +80,7 @@ pub mod upload;
|
||||||
|
|
||||||
pub use agent::Agent;
|
pub use agent::Agent;
|
||||||
pub use builder::{ClientBuilder, ClientType};
|
pub use builder::{ClientBuilder, ClientType};
|
||||||
|
pub use config::Config;
|
||||||
pub use event::Event;
|
pub use event::Event;
|
||||||
pub use feature::ClientFeature;
|
pub use feature::ClientFeature;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,18 +66,22 @@ pub(crate) async fn handle_event(
|
||||||
status: None,
|
status: None,
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
} else {
|
||||||
|
if agent.config.read().await.bookmarks_autojoin {
|
||||||
|
// So maybe another client of ours left the room... let's leave it too
|
||||||
|
agent.leave_room(LeaveRoomSettings::new(jid)).await;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// So maybe another client of ours left the room... let's leave it too
|
|
||||||
agent.leave_room(LeaveRoomSettings::new(jid)).await;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => println!("not bookmark: {}", err),
|
Err(err) => println!("not bookmark: {}", err),
|
||||||
}
|
}
|
||||||
} else if let [item] = &retracted[..] {
|
} else if let [item] = &retracted[..] {
|
||||||
let jid = BareJid::from_str(&item.0).unwrap();
|
if agent.config.read().await.bookmarks_autojoin {
|
||||||
|
let jid = BareJid::from_str(&item.0).unwrap();
|
||||||
|
|
||||||
agent.leave_room(LeaveRoomSettings::new(jid)).await;
|
agent.leave_room(LeaveRoomSettings::new(jid)).await;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
error!("No published or retracted item in pubsub event!");
|
error!("No published or retracted item in pubsub event!");
|
||||||
}
|
}
|
||||||
|
|
@ -146,8 +150,10 @@ pub(crate) async fn handle_iq_result(
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Leave the room that is no longer autojoin
|
if agent.config.read().await.bookmarks_autojoin {
|
||||||
agent.leave_room(LeaveRoomSettings::new(jid)).await;
|
// Leave the room that is no longer autojoin
|
||||||
|
agent.leave_room(LeaveRoomSettings::new(jid)).await;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
|
@ -156,16 +162,18 @@ pub(crate) async fn handle_iq_result(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we leave the rooms that are no longer in the bookmarks
|
if agent.config.read().await.bookmarks_autojoin {
|
||||||
let mut rooms_to_leave: Vec<BareJid> = Vec::new();
|
// Now we leave the rooms that are no longer in the bookmarks
|
||||||
for (room, _nick) in &agent.rooms_joined {
|
let mut rooms_to_leave: Vec<BareJid> = Vec::new();
|
||||||
if !new_room_list.contains(&room) {
|
for (room, _nick) in &agent.rooms_joined {
|
||||||
rooms_to_leave.push(room.clone());
|
if !new_room_list.contains(&room) {
|
||||||
|
rooms_to_leave.push(room.clone());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for room in rooms_to_leave {
|
for room in rooms_to_leave {
|
||||||
agent.leave_room(LeaveRoomSettings::new(room)).await;
|
agent.leave_room(LeaveRoomSettings::new(room)).await;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue