XMPP 0.0.4 → 0.1.0
raw patch · 8 files changed
+28/−142 lines, 8 filesnew-uploaderPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Network.XMPP: cdata :: XMLElem -> String
- Network.XMPP: getJidRes :: XMLElem -> (String, String)
- Network.XMPP: getMessageStamp :: XMLElem -> Maybe String
- Network.XMPP.Presence: Available :: Status -> Presence
- Network.XMPP.Presence: Error :: Presence
- Network.XMPP.Presence: Probe :: Presence
- Network.XMPP.Presence: Status :: StatusType -> [String] -> Status
- Network.XMPP.Presence: StatusAway :: StatusType
- Network.XMPP.Presence: StatusChat :: StatusType
- Network.XMPP.Presence: StatusDND :: StatusType
- Network.XMPP.Presence: StatusOffline :: StatusType
- Network.XMPP.Presence: StatusOnline :: StatusType
- Network.XMPP.Presence: StatusXA :: StatusType
- Network.XMPP.Presence: Subscribe :: Presence
- Network.XMPP.Presence: Subscribed :: Presence
- Network.XMPP.Presence: Unavailable :: Status -> Presence
- Network.XMPP.Presence: Unsubscribe :: Presence
- Network.XMPP.Presence: Unsubscribed :: Presence
- Network.XMPP.Presence: data Presence
- Network.XMPP.Presence: data Status
- Network.XMPP.Presence: data StatusType
- Network.XMPP.Presence: doPresence :: XMLElem -> Presence
- Network.XMPP.Roster: RosterItem :: String -> String -> Subscription -> [String] -> RosterItem
- Network.XMPP.Roster: SBoth :: Subscription
- Network.XMPP.Roster: SFrom :: Subscription
- Network.XMPP.Roster: SNone :: Subscription
- Network.XMPP.Roster: STo :: Subscription
- Network.XMPP.Roster: SUnknown :: Subscription
- Network.XMPP.Roster: data RosterItem
- Network.XMPP.Roster: data Subscription
- Network.XMPP.Roster: getRoster :: XMPP [RosterItem]
- Network.XMPP.Roster: instance Show RosterItem
- Network.XMPP.Roster: instance Show Subscription
- Network.XMPP.Roster: itemGroups :: RosterItem -> [String]
- Network.XMPP.Roster: itemJid :: RosterItem -> String
- Network.XMPP.Roster: itemName :: RosterItem -> String
- Network.XMPP.Roster: itemSubscription :: RosterItem -> Subscription
- Network.XMPP: sendPresence :: XMPP ()
+ Network.XMPP: sendPresence :: Maybe (String, Maybe String) -> Maybe Integer -> XMPP ()
- Network.XMPP: startAuth :: String -> String -> String -> String -> XMPP Integer
+ Network.XMPP: startAuth :: String -> String -> String -> String -> Integer -> XMPP Integer
- Network.XMPP: xmlPath' :: [String] -> [XMLElem] -> [XMLElem]
+ Network.XMPP: xmlPath' :: [String] -> [XMLElem] -> Maybe XMLElem
Files
- Network/XMPP.hs +4/−4
- Network/XMPP/Auth.hs +2/−1
- Network/XMPP/Presence.hs +0/−53
- Network/XMPP/Roster.hs +0/−41
- Network/XMPP/Stanzas.hs +6/−27
- Network/XMPP/XMLParse.hs +11/−10
- Network/XMPP/XMPPMonad.hs +3/−3
- XMPP.cabal +2/−3
Network/XMPP.hs view
@@ -3,27 +3,27 @@ -- -- > import Network -- > import Network.XMPP--- >+-- > -- > -- The bot's JID is "bot@example.com" -- > botUsername = "bot" -- > botServer = "example.com" -- > botPassword = "secret" -- > botResource = "bot"--- >+-- > -- > main :: IO () -- > main = withSocketsDo $ -- > do -- > -- Connect to server... -- > c <- openStream botServer -- > getStreamStart c--- >+-- > -- > runXMPP c $ do -- > -- ...authenticate... -- > startAuth botUsername botServer botPassword botResource -- > sendpresence -- > -- ...and do something. -- > run--- >+-- > -- > run :: XMPP () -- > run = do -- > -- Wait for an incoming message...
Network/XMPP/Auth.hs view
@@ -10,8 +10,9 @@ -> String -- ^Server (part after \@ in JID) -> String -- ^Password -> String -- ^Resource (unique identifier for this connection)+ -> Integer -- ^Resource priority -> XMPP Integer -- ^Error number. Zero if authentication succeeded.-startAuth username server password resource = do+startAuth username server password resource priority = do response <- sendIqWait server "get" [XML "query" [("xmlns","jabber:iq:auth")] [XML "username"
− Network/XMPP/Presence.hs
@@ -1,53 +0,0 @@-module Network.XMPP.Presence (- Presence(..),- Status(..),- StatusType(..),- doPresence-) where--import Network.XMPP---data Presence = Available Status- | Unavailable Status- | Subscribe- | Subscribed- | Unsubscribe- | Unsubscribed- | Probe- | Error--data Status = Status StatusType [String]--data StatusType = StatusOnline- | StatusAway- | StatusChat- | StatusDND- | StatusXA- | StatusOffline----- | Parse presence stanza.-doPresence :: XMLElem -> Presence-doPresence stanza =- let stanzaType = getAttr "type" stanza- 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- in case stanzaType of- Nothing -> Available (Status statusType statuses)- 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------cdata' = getCdata . maybe (XML "" [] []) id
− Network/XMPP/Roster.hs
@@ -1,41 +0,0 @@-module Network.XMPP.Roster (- RosterItem(..),- Subscription(..),- getRoster-) where--import Network.XMPP---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
Network/XMPP/Stanzas.hs view
@@ -18,15 +18,11 @@ , handleVersion , getErrorCode , hasNodeName- , getMessageStamp- , getJidRes- , cdata ) where import Network.XMPP.XMPPMonad import Network.XMPP.XMLParse-import Network.XMPP.JID import System.Random import Maybe @@ -108,9 +104,12 @@ --- Presence -- |Send ordinary online presence.-sendPresence :: XMPP ()-sendPresence = sendStanza $ XML "presence" [] []-+sendPresence :: Maybe (String, Maybe String) -> Maybe Integer -> XMPP ()+sendPresence status prio = + let priority = XML "priority" [] [CData $ show $ maybe 0 id prio] in+ case status of+ Nothing -> sendStanza $ XML "presence" [] [priority]+ Just (sh, s) -> sendStanza $ XML "presence" [] [priority, XML "show" [] [CData sh], XML "status" [] [CData $ maybe "" id s]] --- Stanza predicates -- |Conjunction (\"and\") of two predicates.@@ -200,23 +199,3 @@ Just "error" -> read $ maybe "-1" id (getAttr "code" errorNode) :: Integer _ -> 0 where errorNode = maybe (XML [] [] []) id (xmlPath ["error"] stanza)---- |Get the stamp of message, if has any.-getMessageStamp :: XMLElem -> Maybe String-getMessageStamp stanza =- let xs = xmlPath' ["x"] [stanza]- xs' = filter (attributeMatches "xmlns" (=="jabber:x:delay")) xs- stamps = map (getAttr "stamp") xs'- in case stamps of- [stamp@(Just s)] -> stamp- _ -> Nothing---- |Get the jid and the resource of stanza.-getJidRes :: XMLElem -> (String, String)-getJidRes stanza =- let sender = maybe "" id (getAttr "from" stanza)- in (getBareJid sender, getResource sender)---- |Small helper function.-cdata :: XMLElem -> String-cdata = maybe "" id . getCdata
Network/XMPP/XMLParse.hs view
@@ -1,7 +1,7 @@ -- |The difference between this XML parsers and all other XML parsers -- is that this one can parse an XML document that is only partially -- received, returning the parts that have arrived so far.-module Network.XMPP.XMLParse+module Network.XMPP.XMLParse ( XMLElem(..) , xmlPath , getAttr@@ -196,17 +196,18 @@ return () ------------------------------------------------xmlPath' :: [String] -> [XMLElem] -> [XMLElem]-xmlPath' [] [] = []-xmlPath' [] els = els+-- |Default xmlPath doesn't find subtag2 if we have+-- tag1/subtag1 and tag1/subtag2 in xml stanza.+xmlPath' :: [String] -> [XMLElem] -> Maybe XMLElem+xmlPath' [] [] = Nothing+xmlPath' [] els = Just $ head els xmlPath' (name:names) elems = let elems' = map filter_elem elems- filter_elem (XML _ _ els) =- filter (\stanza ->- case stanza of- (XML n _ _) -> name==n- _ -> False- ) els+ filter_elem (XML _ _ els) = filter (\stanza ->+ case stanza of+ (XML n _ _) -> name==n+ _ -> False) els+ in xmlPath' names (concat elems') -----------------------------------------------
Network/XMPP/XMPPMonad.hs view
@@ -30,8 +30,8 @@ -- cooperative threading system: when it decides to wait for more -- input, it \"sleeps\", letting other \"threads\" run, until input -- matching a certain predicate arrives.-data XMPP a =- XMPP { xmppFn :: XMPPConnection c =>+data XMPP a = + XMPP { xmppFn :: XMPPConnection c => (c -> XMPPState -> IO (XMPPState, XMPPRes a)) } type XMPPState = [(StanzaPredicate, -- predicate@@ -64,7 +64,7 @@ modifyState fn = XMPP $ \_ state -> return (fn state, XMPPJust ()) instance MonadIO XMPP where- liftIO iofn = XMPP $ \c state -> do+ liftIO iofn = XMPP $ \c state -> do iores <- iofn return (state, XMPPJust iores)
XMPP.cabal view
@@ -1,5 +1,5 @@ Name: XMPP-Version: 0.0.4+Version: 0.1.0 Synopsis: XMPP library Category: Network Description: XMPP library@@ -15,8 +15,7 @@ Extra-Source-Files: install.sh Library- Exposed-Modules: Network.XMPP, Network.XMPP.MUC, Network.XMPP.Roster,- Network.XMPP.Presence+ Exposed-Modules: Network.XMPP, Network.XMPP.MUC Other-modules: Network.XMPP.Auth, Network.XMPP.JID, Network.XMPP.Stanzas, Network.XMPP.TCPConnection,