module Network.XMPP.Roster ( RosterItem(..), Subscription(..), getRoster, Presence(..), Status(..), StatusType(..), doPresence, doStatus ) where import Network.XMPP.XMPPMonad import Network.XMPP.XMLParse import Network.XMPP.Stanzas -- TODO: add/delete roster items (via sending IQs) -- add/delete subscriptions data RosterItem = RosterItem { itemName :: String , itemJid :: String , itemSubscription :: Subscription , itemGroups :: [String] } deriving Show -- "There are nine possible subscription states" -- It's horrible. data Subscription = SBoth | SFrom | STo | SNone | SUnknown deriving Show getRoster :: XMPP [RosterItem] getRoster = do stanza <- sendIqWait "" "get" [XML "query" [("xmlns", "jabber:iq:roster")] []] let items = xmlPath' ["query", "item"] [stanza] return $ map getItem items where getItem item = let getAttr' attr = maybe "" id $ getAttr attr item name = getAttr' "name" jid = getAttr' "jid" groups = map cdata $ xmlPath' ["group"] [item] subs = case getAttr' "subscription" of "to" -> STo "from" -> SFrom "both" -> SBoth "none" -> SNone _ -> SUnknown in RosterItem name jid subs groups --- Presences data Presence = Available Status | Unavailable Status | Subscribe | Subscribed | Unsubscribe | Unsubscribed | Probe | Error -- | TODO: xml:lang for multiple statuses. data Status = Status StatusType [String] data StatusType = StatusOnline | StatusAway | StatusChat | StatusDND | StatusXA | StatusOffline -- | Read presence stanza. doPresence :: XMLElem -> Presence doPresence stanza = let stanzaType = getAttr "type" stanza status@(Status _ statuses) = doStatus stanza in case stanzaType of Nothing -> Available status Just "unavailable" -> Unavailable (Status StatusOffline statuses) Just "subscribe" -> Subscribe Just "subscribed" -> Subscribed Just "unsubscribe" -> Unsubscribe Just "unsubscribed" -> Unsubscribed Just "probe" -> Probe Just "error" -> Error _ -> Error -- | Read stanza status. doStatus :: XMLElem -> Status doStatus stanza = Status statusType statuses where statuses = map cdata $ xmlPath' ["status"] [stanza] statusType = case cdata' $ xmlPath ["show"] stanza of Just "away" -> StatusAway Just "chat" -> StatusChat Just "dnd" -> StatusDND Just "xa" -> StatusXA _ -> StatusOnline