From 058d63f0e0037532557cbd0282b92733c0f57219 Mon Sep 17 00:00:00 2001 From: Philipp Balzarek Date: Sat, 23 Mar 2013 18:28:33 +0100 Subject: [PATCH] add rosterAdd and rosterRemove --- source/Network/Xmpp/IM.hs | 2 ++ source/Network/Xmpp/IM/Roster.hs | 54 +++++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/source/Network/Xmpp/IM.hs b/source/Network/Xmpp/IM.hs index d8793a0..70d1510 100644 --- a/source/Network/Xmpp/IM.hs +++ b/source/Network/Xmpp/IM.hs @@ -13,6 +13,8 @@ module Network.Xmpp.IM , Roster(..) , Item(..) , getRoster + , rosterAdd + , rosterRemove ) where import Network.Xmpp.IM.Message diff --git a/source/Network/Xmpp/IM/Roster.hs b/source/Network/Xmpp/IM/Roster.hs index cd7a0ca..6d20f2c 100644 --- a/source/Network/Xmpp/IM/Roster.hs +++ b/source/Network/Xmpp/IM/Roster.hs @@ -7,8 +7,10 @@ module Network.Xmpp.IM.Roster where import Control.Concurrent.STM import Control.Monad +import Data.List (nub) import qualified Data.Map.Strict as Map import Data.Maybe (isJust) +import Data.Text (Text) import Data.XML.Pickle import Data.XML.Types import System.Log.Logger @@ -19,6 +21,45 @@ import Network.Xmpp.Concurrent.Types import Network.Xmpp.Types import Network.Xmpp.Concurrent.IQ +-- | Push a roster item to the server. The values for approved and ask are +-- ignored and all values for subsciption except "remove" are ignored +rosterPush :: Item -> Session -> IO IQResponse +rosterPush item session = do + let el = pickleElem xpQuery (Query Nothing [fromItem item]) + sendIQ' Nothing Set Nothing el session + +-- | Add or update an item to the roster. +-- +-- To update the item just send the complete set of new data +rosterAdd :: Jid -- ^ JID of the item + -> Maybe Text -- ^ Name alias + -> [Text] -- ^ Groups (duplicates will be removed) + -> Session + -> IO IQResponse +rosterAdd j n gs session = do + let el = pickleElem xpQuery (Query Nothing + [QueryItem { qiApproved = Nothing + , qiAsk = False + , qiJid = j + , qiName = n + , qiSubscription = Nothing + , qiGroups = nub gs + }]) + sendIQ' Nothing Set Nothing el session + +-- | Remove an item from the roster. Return True when the item is sucessfully +-- removed or if it wasn't in the roster to begin with. +rosterRemove :: Jid -> Session -> IO Bool +rosterRemove j sess = do + roster <- getRoster sess + case Map.lookup j (items roster) of + Nothing -> return True -- jid is not on the Roster + Just _ -> do + res <- rosterPush (Item False False j Nothing Remove []) sess + case res of + IQResponseResult IQResult{} -> return True + _ -> return False + getRoster :: Session -> IO Roster getRoster session = atomically $ readTVar (rosterRef session) @@ -98,9 +139,20 @@ toItem qi = Item { approved = maybe False id (qiApproved qi) , jid = qiJid qi , name = qiName qi , subscription = maybe None id (qiSubscription qi) - , groups = qiGroups qi + , groups = nub $ qiGroups qi } +fromItem :: Item -> QueryItem +fromItem i = QueryItem { qiApproved = Nothing + , qiAsk = False + , qiJid = jid i + , qiName = name i + , qiSubscription = case subscription i of + Remove -> Just Remove + _ -> Nothing + , qiGroups = nub $ groups i + } + xpItems :: PU [Node] [QueryItem] xpItems = xpWrap (map (\((app_, ask_, jid_, name_, sub_), groups_) -> QueryItem app_ ask_ jid_ name_ sub_ groups_))