mirror of https://gitlab.com/xmpp-rs/xmpp-rs.git
Merge branch 'refactor-unittests' into 'main'
Draft: Refactoring Agent See merge request xmpp-rs/xmpp-rs!299
This commit is contained in:
commit
e5dfc0cd62
|
@ -36,7 +36,9 @@ impl<C: ServerConnector> Agent<C> {
|
|||
lang: &str,
|
||||
status: &str,
|
||||
) {
|
||||
muc::room::join_room(self, room, nick, password, lang, status).await
|
||||
// Use the provided nickname, or the default if none.
|
||||
let nick = nick.unwrap_or_else(|| self.default_nick.read().unwrap().to_string());
|
||||
muc::room::join_room(&mut self.client, room, &nick, password, lang, status).await
|
||||
}
|
||||
|
||||
/// Request to leave a chatroom.
|
||||
|
@ -57,7 +59,7 @@ impl<C: ServerConnector> Agent<C> {
|
|||
lang: impl Into<String>,
|
||||
status: impl Into<String>,
|
||||
) {
|
||||
muc::room::leave_room(self, room_jid, nickname, lang, status).await
|
||||
muc::room::leave_room(&mut self.client, room_jid, nickname, lang, status).await
|
||||
}
|
||||
|
||||
pub async fn send_message(
|
||||
|
@ -67,7 +69,7 @@ impl<C: ServerConnector> Agent<C> {
|
|||
lang: &str,
|
||||
text: &str,
|
||||
) {
|
||||
message::send::send_message(self, recipient, type_, lang, text).await
|
||||
message::send::send_message(&mut self.client, recipient, type_, lang, text).await
|
||||
}
|
||||
|
||||
pub async fn send_room_private_message(
|
||||
|
@ -90,7 +92,7 @@ impl<C: ServerConnector> Agent<C> {
|
|||
event_loop::wait_for_events(self).await
|
||||
}
|
||||
|
||||
pub async fn upload_file_with(&mut self, service: &str, path: &Path) {
|
||||
pub async fn upload_file_with(&mut self, service: Jid, path: &Path) {
|
||||
upload::send::upload_file_with(self, service, path).await
|
||||
}
|
||||
|
||||
|
|
|
@ -10,10 +10,17 @@ use tokio_xmpp::{
|
|||
Jid,
|
||||
};
|
||||
|
||||
use crate::Agent;
|
||||
use crate::agent::TokioXmppClient;
|
||||
|
||||
/// Send a text message to a recipient.
|
||||
///
|
||||
/// # Arguments
|
||||
/// - `client`: The XMPP client to use to send the message.
|
||||
/// - `recipient`: The JID of the recipient.
|
||||
/// - `type_`: The type of the message.
|
||||
/// - `lang`: The language of the message.
|
||||
pub async fn send_message<C: ServerConnector>(
|
||||
agent: &mut Agent<C>,
|
||||
client: &mut TokioXmppClient<C>,
|
||||
recipient: Jid,
|
||||
type_: MessageType,
|
||||
lang: &str,
|
||||
|
@ -24,5 +31,5 @@ pub async fn send_message<C: ServerConnector>(
|
|||
message
|
||||
.bodies
|
||||
.insert(String::from(lang), Body(String::from(text)));
|
||||
let _ = agent.client.send_stanza(message.into()).await;
|
||||
let _ = client.send_stanza(message.into()).await;
|
||||
}
|
||||
|
|
|
@ -13,27 +13,58 @@ use tokio_xmpp::{
|
|||
BareJid,
|
||||
};
|
||||
|
||||
use crate::{Agent, RoomNick};
|
||||
use crate::agent::TokioXmppClient;
|
||||
use crate::RoomNick;
|
||||
|
||||
pub async fn join_room<C: ServerConnector>(
|
||||
agent: &mut Agent<C>,
|
||||
client: &mut TokioXmppClient<C>,
|
||||
room: BareJid,
|
||||
nick: Option<String>,
|
||||
nick: &String,
|
||||
password: Option<String>,
|
||||
lang: &str,
|
||||
status: &str,
|
||||
) {
|
||||
let presence = create_muc_join_presence_stanza(room, password, lang, status, nick);
|
||||
let _ = client.send_stanza(presence.into()).await;
|
||||
}
|
||||
|
||||
/// Create a Presence stanza for joining a MUC room with a specific nickname.
|
||||
///
|
||||
/// # Arguments
|
||||
/// - `room`: The JID of the room to join.
|
||||
/// - `password`: The password to use to join the room, if any.
|
||||
/// - `lang`: The language of the status message.
|
||||
/// - `status`: The status message to send.
|
||||
/// - `nick`: The nickname to use in the room.
|
||||
pub fn create_muc_join_presence_stanza(
|
||||
room: BareJid,
|
||||
password: Option<String>,
|
||||
lang: &str,
|
||||
status: &str,
|
||||
nick: &String,
|
||||
) -> Presence {
|
||||
// Combine the room JID with the nickname to create the JID of the room occupant.
|
||||
let room_jid = room.with_resource_str(&nick).unwrap();
|
||||
|
||||
// Create a presence stanza.
|
||||
let mut presence = Presence::new(PresenceType::None).with_to(room_jid);
|
||||
|
||||
// MUC presence stanza's must have a Muc payload.
|
||||
let mut muc = Muc::new();
|
||||
|
||||
// If a password is provided, include it in the Muc payload.
|
||||
if let Some(password) = password {
|
||||
muc = muc.with_password(password);
|
||||
}
|
||||
|
||||
let nick = nick.unwrap_or_else(|| agent.default_nick.read().unwrap().clone());
|
||||
let room_jid = room.with_resource_str(&nick).unwrap();
|
||||
let mut presence = Presence::new(PresenceType::None).with_to(room_jid);
|
||||
// Add the Muc payload to the presence stanza.
|
||||
presence.add_payload(muc);
|
||||
|
||||
// Set the user-readable status message.
|
||||
presence.set_status(String::from(lang), String::from(status));
|
||||
let _ = agent.client.send_stanza(presence.into()).await;
|
||||
|
||||
// Return the presence stanza.
|
||||
presence
|
||||
}
|
||||
|
||||
/// Send a "leave room" request to the server (specifically, an "unavailable" presence stanza).
|
||||
|
@ -51,17 +82,40 @@ pub async fn join_room<C: ServerConnector>(
|
|||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `client`: The XMPP client to use to send the status message.
|
||||
/// * `room_jid`: The JID of the room to leave.
|
||||
/// * `nickname`: The nickname to use in the room.
|
||||
/// * `lang`: The language of the status message.
|
||||
/// * `status`: The status message to send.
|
||||
pub async fn leave_room<C: ServerConnector>(
|
||||
agent: &mut Agent<C>,
|
||||
client: &mut TokioXmppClient<C>,
|
||||
room_jid: BareJid,
|
||||
nickname: RoomNick,
|
||||
lang: impl Into<String>,
|
||||
status: impl Into<String>,
|
||||
) {
|
||||
let presence = create_muc_leave_room_status(room_jid, nickname, lang, status);
|
||||
|
||||
// Send the presence stanza.
|
||||
if let Err(e) = client.send_stanza(presence.into()).await {
|
||||
// Report any errors to the log.
|
||||
error!("Failed to send leave room presence: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a Presence stanza for leaving a MUC room that we're in with a specific nickname.
|
||||
///
|
||||
/// # Arguments
|
||||
/// - `room_jid`: The JID of the room to leave.
|
||||
/// - `nickname`: The nickname we are present in the room with.
|
||||
/// - `lang`: The language of the status message.
|
||||
/// - `status`: The status message to send.
|
||||
pub fn create_muc_leave_room_status(
|
||||
room_jid: BareJid,
|
||||
nickname: RoomNick,
|
||||
lang: impl Into<String> + Sized,
|
||||
status: impl Into<String> + Sized,
|
||||
) -> Presence {
|
||||
// XEP-0045 specifies that, to leave a room, the client must send a presence stanza
|
||||
// with type="unavailable".
|
||||
let mut presence = Presence::new(PresenceType::Unavailable).with_to(
|
||||
|
@ -74,10 +128,5 @@ pub async fn leave_room<C: ServerConnector>(
|
|||
// TODO: Should this be optional? The XEP says "MAY", but the method signature requires the arguments.
|
||||
// XEP-0045: "The occupant MAY include normal <status/> information in the unavailable presence stanzas"
|
||||
presence.set_status(lang, status);
|
||||
|
||||
// Send the presence stanza.
|
||||
if let Err(e) = agent.client.send_stanza(presence.into()).await {
|
||||
// Report any errors to the log.
|
||||
error!("Failed to send leave room presence: {}", e);
|
||||
}
|
||||
presence
|
||||
}
|
||||
|
|
|
@ -14,23 +14,44 @@ use tokio_xmpp::{
|
|||
|
||||
use crate::Agent;
|
||||
|
||||
pub async fn upload_file_with<C: ServerConnector>(
|
||||
agent: &mut Agent<C>,
|
||||
service: &str,
|
||||
path: &Path,
|
||||
) {
|
||||
/// Upload a file to the HTTP server associated with a given Jid.
|
||||
///
|
||||
/// # Arguments
|
||||
/// - `agent`: The XMPP agent through which to negociate the request.
|
||||
/// - `service`: The Jid of the HTTP server to upload the file to.
|
||||
/// - `path`: The path to the file to upload.
|
||||
pub async fn upload_file_with<C: ServerConnector>(agent: &mut Agent<C>, service: Jid, path: &Path) {
|
||||
// Create the IQ request to upload the file.
|
||||
let request =
|
||||
Iq::from_get("upload1", slotslot_request_for_file(path).await).with_to(service.clone());
|
||||
|
||||
// Record the upload request so we can handle the response later.
|
||||
agent
|
||||
.uploads
|
||||
.push((String::from("upload1"), service, path.to_path_buf()));
|
||||
|
||||
// Send the request to the server.
|
||||
agent.client.send_stanza(request.into()).await.unwrap();
|
||||
}
|
||||
|
||||
/// Create a SlotRequest for a file, representing a request for a URL to upload the file to.
|
||||
///
|
||||
/// Note: this function is async because it accesses the file system to read the file's metadata.
|
||||
///
|
||||
/// # Arguments
|
||||
/// - `path`: The path to the file to upload.
|
||||
async fn slotslot_request_for_file(path: &Path) -> SlotRequest {
|
||||
// Extract the file's name.
|
||||
let name = path.file_name().unwrap().to_str().unwrap().to_string();
|
||||
|
||||
// Open the file and read its size.
|
||||
let file = File::open(path).await.unwrap();
|
||||
let size = file.metadata().await.unwrap().len();
|
||||
let slot_request = SlotRequest {
|
||||
|
||||
// Create a SlotRequest for the file.
|
||||
SlotRequest {
|
||||
filename: name,
|
||||
size: size,
|
||||
content_type: None,
|
||||
};
|
||||
let to = service.parse::<Jid>().unwrap();
|
||||
let request = Iq::from_get("upload1", slot_request).with_to(to.clone());
|
||||
agent
|
||||
.uploads
|
||||
.push((String::from("upload1"), to, path.to_path_buf()));
|
||||
agent.client.send_stanza(request.into()).await.unwrap();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue