mod.rs

  1// Copyright (c) 2019 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
  2//
  3// This Source Code Form is subject to the terms of the Mozilla Public
  4// License, v. 2.0. If a copy of the MPL was not distributed with this
  5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6
  7use super::Agent;
  8use crate::Event;
  9use std::str::FromStr;
 10use tokio_xmpp::{
 11    connect::ServerConnector,
 12    parsers::{
 13        bookmarks2::{self, Autojoin},
 14        ns,
 15        pubsub::event::PubSubEvent,
 16        pubsub::pubsub::PubSub,
 17        BareJid, Element, Jid,
 18    },
 19};
 20
 21#[cfg(feature = "avatars")]
 22pub(crate) mod avatar;
 23
 24pub(crate) async fn handle_event<C: ServerConnector>(
 25    #[cfg_attr(not(feature = "avatars"), allow(unused_variables))] from: &Jid,
 26    elem: Element,
 27    #[cfg_attr(not(feature = "avatars"), allow(unused_variables))] agent: &mut Agent<C>,
 28) -> Vec<Event> {
 29    let mut events = Vec::new();
 30    let event = PubSubEvent::try_from(elem);
 31    trace!("PubSub event: {:#?}", event);
 32    match event {
 33        Ok(PubSubEvent::PublishedItems { node, items }) => {
 34            match node.0 {
 35                #[cfg(feature = "avatars")]
 36                ref node if node == ns::AVATAR_METADATA => {
 37                    let new_events =
 38                        avatar::handle_metadata_pubsub_event(&from, agent, items).await;
 39                    events.extend(new_events);
 40                }
 41                ref node if node == ns::BOOKMARKS2 => {
 42                    // TODO: Check that our bare JID is the sender.
 43                    assert_eq!(items.len(), 1);
 44                    let item = items.clone().pop().unwrap();
 45                    let jid = BareJid::from_str(&item.id.clone().unwrap().0).unwrap();
 46                    let payload = item.payload.clone().unwrap();
 47                    match bookmarks2::Conference::try_from(payload) {
 48                        Ok(conference) => {
 49                            if conference.autojoin == Autojoin::True {
 50                                events.push(Event::JoinRoom(jid, conference));
 51                            } else {
 52                                events.push(Event::LeaveRoom(jid));
 53                            }
 54                        }
 55                        Err(err) => println!("not bookmark: {}", err),
 56                    }
 57                }
 58                ref node => unimplemented!("node {}", node),
 59            }
 60        }
 61        Ok(PubSubEvent::RetractedItems { node, items }) => {
 62            match node.0 {
 63                ref node if node == ns::BOOKMARKS2 => {
 64                    // TODO: Check that our bare JID is the sender.
 65                    assert_eq!(items.len(), 1);
 66                    let item = items.clone().pop().unwrap();
 67                    let jid = BareJid::from_str(&item.0).unwrap();
 68                    events.push(Event::LeaveRoom(jid));
 69                }
 70                ref node => unimplemented!("node {}", node),
 71            }
 72        }
 73        Ok(PubSubEvent::Purge { node }) => {
 74            match node.0 {
 75                ref node if node == ns::BOOKMARKS2 => {
 76                    // TODO: Check that our bare JID is the sender.
 77                    events.push(Event::LeaveAllRooms);
 78                }
 79                ref node => unimplemented!("node {}", node),
 80            }
 81        }
 82        Err(e) => {
 83            error!("Error parsing PubSub event: {}", e);
 84        }
 85        _ => unimplemented!("PubSub event: {:#?}", event),
 86    }
 87    events
 88}
 89
 90pub(crate) fn handle_iq_result(
 91    #[cfg_attr(not(feature = "avatars"), allow(unused_variables))] from: &Jid,
 92    elem: Element,
 93) -> impl IntoIterator<Item = Event> {
 94    let mut events = Vec::new();
 95    let pubsub = PubSub::try_from(elem).unwrap();
 96    trace!("PubSub: {:#?}", pubsub);
 97    if let PubSub::Items(items) = pubsub {
 98        match items.node.0.clone() {
 99            #[cfg(feature = "avatars")]
100            ref node if node == ns::AVATAR_DATA => {
101                let new_events = avatar::handle_data_pubsub_iq(&from, &items);
102                events.extend(new_events);
103            }
104            ref node if node == ns::BOOKMARKS2 => {
105                events.push(Event::LeaveAllRooms);
106                for item in items.items {
107                    let item = item.0;
108                    let jid = BareJid::from_str(&item.id.clone().unwrap().0).unwrap();
109                    let payload = item.payload.clone().unwrap();
110                    match bookmarks2::Conference::try_from(payload) {
111                        Ok(conference) => {
112                            if let Autojoin::True = conference.autojoin {
113                                events.push(Event::JoinRoom(jid, conference));
114                            }
115                        }
116                        Err(err) => panic!("Wrong payload type in bookmarks 2 item: {}", err),
117                    }
118                }
119            }
120            _ => unimplemented!(),
121        }
122    }
123    events
124}