Remove the -rs suffix of jid, minidom and xmpp
We know those are Rust libraries, no need to add it to the path. This synchronises their directory with the crate name, hopefully reducing confusion.
This commit is contained in:
parent
e501addb96
commit
714d850e69
28 changed files with 6 additions and 6 deletions
93
xmpp/src/pubsub/avatar.rs
Normal file
93
xmpp/src/pubsub/avatar.rs
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
// Copyright (c) 2019 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
|
||||
//
|
||||
// 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/.
|
||||
|
||||
use super::Agent;
|
||||
use crate::Event;
|
||||
use std::convert::TryFrom;
|
||||
use std::fs::{self, File};
|
||||
use std::io::{self, Write};
|
||||
use xmpp_parsers::{
|
||||
avatar::{Data, Metadata},
|
||||
iq::Iq,
|
||||
ns,
|
||||
pubsub::{
|
||||
event::Item,
|
||||
pubsub::{Items, PubSub},
|
||||
NodeName,
|
||||
},
|
||||
Jid,
|
||||
};
|
||||
|
||||
pub(crate) async fn handle_metadata_pubsub_event(
|
||||
from: &Jid,
|
||||
agent: &mut Agent,
|
||||
items: Vec<Item>,
|
||||
) -> Vec<Event> {
|
||||
let mut events = Vec::new();
|
||||
for item in items {
|
||||
let payload = item.payload.clone().unwrap();
|
||||
if payload.is("metadata", ns::AVATAR_METADATA) {
|
||||
let metadata = Metadata::try_from(payload).unwrap();
|
||||
for info in metadata.infos {
|
||||
let filename = format!("data/{}/{}", from, &*info.id.to_hex());
|
||||
let file_length = match fs::metadata(filename.clone()) {
|
||||
Ok(metadata) => metadata.len(),
|
||||
Err(_) => 0,
|
||||
};
|
||||
// TODO: Also check the hash.
|
||||
if info.bytes as u64 == file_length {
|
||||
events.push(Event::AvatarRetrieved(from.clone(), filename));
|
||||
} else {
|
||||
let iq = download_avatar(from);
|
||||
let _ = agent.client.send_stanza(iq.into()).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
events
|
||||
}
|
||||
|
||||
fn download_avatar(from: &Jid) -> Iq {
|
||||
Iq::from_get(
|
||||
"coucou",
|
||||
PubSub::Items(Items {
|
||||
max_items: None,
|
||||
node: NodeName(String::from(ns::AVATAR_DATA)),
|
||||
subid: None,
|
||||
items: Vec::new(),
|
||||
}),
|
||||
)
|
||||
.with_to(from.clone())
|
||||
}
|
||||
|
||||
// The return value of this function will be simply pushed to a Vec in the caller function,
|
||||
// so it makes no sense to allocate a Vec here - we're lazy instead
|
||||
pub(crate) fn handle_data_pubsub_iq<'a>(
|
||||
from: &'a Jid,
|
||||
items: &'a Items,
|
||||
) -> impl IntoIterator<Item = Event> + 'a {
|
||||
let from = from.clone();
|
||||
items
|
||||
.items
|
||||
.iter()
|
||||
.filter_map(move |item| match (&item.id, &item.payload) {
|
||||
(Some(id), Some(payload)) => {
|
||||
let data = Data::try_from(payload.clone()).unwrap();
|
||||
let filename = save_avatar(&from, id.0.clone(), &data.data).unwrap();
|
||||
Some(Event::AvatarRetrieved(from.clone(), filename))
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
||||
fn save_avatar(from: &Jid, id: String, data: &[u8]) -> io::Result<String> {
|
||||
let directory = format!("data/{}", from);
|
||||
let filename = format!("data/{}/{}", from, id);
|
||||
fs::create_dir_all(directory)?;
|
||||
let mut file = File::create(&filename)?;
|
||||
file.write_all(data)?;
|
||||
Ok(filename)
|
||||
}
|
||||
112
xmpp/src/pubsub/mod.rs
Normal file
112
xmpp/src/pubsub/mod.rs
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
// Copyright (c) 2019 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
|
||||
//
|
||||
// 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/.
|
||||
|
||||
use super::Agent;
|
||||
use crate::Event;
|
||||
use std::convert::TryFrom;
|
||||
use std::str::FromStr;
|
||||
use xmpp_parsers::{
|
||||
bookmarks2::{Autojoin, Conference},
|
||||
ns,
|
||||
pubsub::event::PubSubEvent,
|
||||
pubsub::pubsub::PubSub,
|
||||
BareJid, Element, Jid,
|
||||
};
|
||||
|
||||
#[cfg(feature = "avatars")]
|
||||
pub(crate) mod avatar;
|
||||
|
||||
pub(crate) async fn handle_event(from: &Jid, elem: Element, agent: &mut Agent) -> Vec<Event> {
|
||||
let mut events = Vec::new();
|
||||
let event = PubSubEvent::try_from(elem);
|
||||
trace!("PubSub event: {:#?}", event);
|
||||
match event {
|
||||
Ok(PubSubEvent::PublishedItems { node, items }) => {
|
||||
match node.0 {
|
||||
#[cfg(feature = "avatars")]
|
||||
ref node if node == ns::AVATAR_METADATA => {
|
||||
let new_events =
|
||||
avatar::handle_metadata_pubsub_event(&from, agent, items).await;
|
||||
events.extend(new_events);
|
||||
}
|
||||
ref node if node == ns::BOOKMARKS2 => {
|
||||
// TODO: Check that our bare JID is the sender.
|
||||
assert_eq!(items.len(), 1);
|
||||
let item = items.clone().pop().unwrap();
|
||||
let jid = BareJid::from_str(&item.id.clone().unwrap().0).unwrap();
|
||||
let payload = item.payload.clone().unwrap();
|
||||
match Conference::try_from(payload) {
|
||||
Ok(conference) => {
|
||||
if conference.autojoin == Autojoin::True {
|
||||
events.push(Event::JoinRoom(jid, conference));
|
||||
} else {
|
||||
events.push(Event::LeaveRoom(jid));
|
||||
}
|
||||
}
|
||||
Err(err) => println!("not bookmark: {}", err),
|
||||
}
|
||||
}
|
||||
ref node => unimplemented!("node {}", node),
|
||||
}
|
||||
}
|
||||
Ok(PubSubEvent::RetractedItems { node, items }) => {
|
||||
match node.0 {
|
||||
ref node if node == ns::BOOKMARKS2 => {
|
||||
// TODO: Check that our bare JID is the sender.
|
||||
assert_eq!(items.len(), 1);
|
||||
let item = items.clone().pop().unwrap();
|
||||
let jid = BareJid::from_str(&item.0).unwrap();
|
||||
events.push(Event::LeaveRoom(jid));
|
||||
}
|
||||
ref node => unimplemented!("node {}", node),
|
||||
}
|
||||
}
|
||||
Ok(PubSubEvent::Purge { node }) => {
|
||||
match node.0 {
|
||||
ref node if node == ns::BOOKMARKS2 => {
|
||||
// TODO: Check that our bare JID is the sender.
|
||||
events.push(Event::LeaveAllRooms);
|
||||
}
|
||||
ref node => unimplemented!("node {}", node),
|
||||
}
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
events
|
||||
}
|
||||
|
||||
pub(crate) fn handle_iq_result(from: &Jid, elem: Element) -> impl IntoIterator<Item = Event> {
|
||||
let mut events = Vec::new();
|
||||
let pubsub = PubSub::try_from(elem).unwrap();
|
||||
trace!("PubSub: {:#?}", pubsub);
|
||||
if let PubSub::Items(items) = pubsub {
|
||||
match items.node.0.clone() {
|
||||
#[cfg(feature = "avatars")]
|
||||
ref node if node == ns::AVATAR_DATA => {
|
||||
let new_events = avatar::handle_data_pubsub_iq(&from, &items);
|
||||
events.extend(new_events);
|
||||
}
|
||||
ref node if node == ns::BOOKMARKS2 => {
|
||||
events.push(Event::LeaveAllRooms);
|
||||
for item in items.items {
|
||||
let item = item.0;
|
||||
let jid = BareJid::from_str(&item.id.clone().unwrap().0).unwrap();
|
||||
let payload = item.payload.clone().unwrap();
|
||||
match Conference::try_from(payload) {
|
||||
Ok(conference) => {
|
||||
if let Autojoin::True = conference.autojoin {
|
||||
events.push(Event::JoinRoom(jid, conference));
|
||||
}
|
||||
}
|
||||
Err(err) => panic!("Wrong payload type in bookmarks 2 item: {}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
events
|
||||
}
|
||||
Loading…
Reference in a new issue