diff options
Diffstat (limited to 'Presence')
-rw-r--r-- | Presence/XMPPServer.hs | 70 |
1 files changed, 67 insertions, 3 deletions
diff --git a/Presence/XMPPServer.hs b/Presence/XMPPServer.hs index 004f7472..52933440 100644 --- a/Presence/XMPPServer.hs +++ b/Presence/XMPPServer.hs | |||
@@ -38,6 +38,8 @@ import Data.Monoid ( (<>) ) | |||
38 | import Data.Text (Text) | 38 | import Data.Text (Text) |
39 | import qualified Data.Text as Text (pack,unpack) | 39 | import qualified Data.Text as Text (pack,unpack) |
40 | import Data.Char (toUpper) | 40 | import Data.Char (toUpper) |
41 | import Data.Map (Map) | ||
42 | import qualified Data.Map as Map | ||
41 | 43 | ||
42 | import qualified Control.Concurrent.STM.UpdateStream as Slotted | 44 | import qualified Control.Concurrent.STM.UpdateStream as Slotted |
43 | import ControlMaybe | 45 | import ControlMaybe |
@@ -75,8 +77,15 @@ data LangSpecificMessage = | |||
75 | } | 77 | } |
76 | deriving (Show,Eq) | 78 | deriving (Show,Eq) |
77 | 79 | ||
78 | data StanzaType = Unrecognized | Ping | Pong | RequestResource (Maybe Text) | SetResource | 80 | data StanzaType |
79 | | SessionRequest | UnrecognizedQuery Name | Error | 81 | = Unrecognized |
82 | | Ping | ||
83 | | Pong | ||
84 | | RequestResource (Maybe Text) | ||
85 | | SetResource | ||
86 | | SessionRequest | ||
87 | | UnrecognizedQuery Name | ||
88 | | Error | ||
80 | | PresenceStatus { presenceShow :: JabberShow | 89 | | PresenceStatus { presenceShow :: JabberShow |
81 | , presencePriority :: Maybe Int8 | 90 | , presencePriority :: Maybe Int8 |
82 | , presenceStatus :: [(Lang,Text)] | 91 | , presenceStatus :: [(Lang,Text)] |
@@ -298,13 +307,67 @@ grokPresence ns stanzaTag = do | |||
298 | Just "probe" -> return . Just $ PresenceRequestStatus | 307 | Just "probe" -> return . Just $ PresenceRequestStatus |
299 | Just "unsubscribe" -> return . Just $ PresenceRequestSubscription False | 308 | Just "unsubscribe" -> return . Just $ PresenceRequestSubscription False |
300 | Just "subscribe" -> return . Just $ PresenceRequestSubscription True | 309 | Just "subscribe" -> return . Just $ PresenceRequestSubscription True |
301 | _ -> return Nothing -- todo | 310 | _ -> return Nothing |
311 | |||
312 | parseMessage ns stanza = do | ||
313 | let bodytag = Name { nameNamespace = Just ns | ||
314 | , nameLocalName = "body" | ||
315 | , namePrefix = Nothing } | ||
316 | subjecttag = Name { nameNamespace = Just ns | ||
317 | , nameLocalName = "subject" | ||
318 | , namePrefix = Nothing } | ||
319 | threadtag = Name { nameNamespace = Just ns | ||
320 | , nameLocalName = "thread" | ||
321 | , namePrefix = Nothing } | ||
322 | let emptyMsg = LangSpecificMessage { msgBody=Nothing, msgSubject=Nothing } | ||
323 | parseChildren (th,cmap) = do | ||
324 | child <- nextElement | ||
325 | lvl <- nesting | ||
326 | xmllang <- xmlLang | ||
327 | let lang = maybe "" id xmllang | ||
328 | let c = maybe emptyMsg id (Map.lookup lang cmap) | ||
329 | -- log $ " child: "<> bshow child | ||
330 | case child of | ||
331 | Just tag | tagName tag==bodytag | ||
332 | -> do | ||
333 | txt <- XML.content | ||
334 | awaitCloser lvl | ||
335 | parseChildren (th,Map.insert lang (c { msgBody=Just txt }) cmap) | ||
336 | Just tag | tagName tag==subjecttag | ||
337 | -> do | ||
338 | txt <- XML.content | ||
339 | awaitCloser lvl | ||
340 | parseChildren (th,Map.insert lang (c { msgSubject=Just txt }) cmap) | ||
341 | Just tag | tagName tag==threadtag | ||
342 | -> do | ||
343 | txt <- XML.content | ||
344 | awaitCloser lvl | ||
345 | parseChildren (th {msgThreadContent=txt},cmap) | ||
346 | Just tag -> do | ||
347 | -- let nm = tagName tag | ||
348 | -- attrs = tagAttrs tag | ||
349 | -- -- elems = msgElements c | ||
350 | -- txt <- XML.content | ||
351 | awaitCloser lvl | ||
352 | parseChildren (th,Map.insert lang c cmap) | ||
353 | Nothing -> return (th,cmap) | ||
354 | (th,langmap) <- parseChildren ( MessageThread {msgThreadParent=Nothing, msgThreadContent=""} | ||
355 | , Map.empty ) | ||
356 | return Message { | ||
357 | msgLangMap = Map.toList langmap, | ||
358 | msgThread = if msgThreadContent th/="" then Just th else Nothing | ||
359 | } | ||
360 | |||
361 | grokMessage ns stanzaTag = do | ||
362 | t <- parseMessage ns stanzaTag | ||
363 | return $ Just t | ||
302 | 364 | ||
303 | grokStanza "jabber:server" stanzaTag = | 365 | grokStanza "jabber:server" stanzaTag = |
304 | case () of | 366 | case () of |
305 | _ | stanzaTag `isServerIQOf` "get" -> grokStanzaIQGet stanzaTag | 367 | _ | stanzaTag `isServerIQOf` "get" -> grokStanzaIQGet stanzaTag |
306 | _ | stanzaTag `isServerIQOf` "result" -> grokStanzaIQResult stanzaTag | 368 | _ | stanzaTag `isServerIQOf` "result" -> grokStanzaIQResult stanzaTag |
307 | _ | tagName stanzaTag == "{jabber:server}presence" -> grokPresence "jabber:server" stanzaTag | 369 | _ | tagName stanzaTag == "{jabber:server}presence" -> grokPresence "jabber:server" stanzaTag |
370 | _ | tagName stanzaTag == "{jabber:server}message" -> grokMessage "jabber:server" stanzaTag | ||
308 | _ -> return $ Just Unrecognized | 371 | _ -> return $ Just Unrecognized |
309 | 372 | ||
310 | grokStanza "jabber:client" stanzaTag = | 373 | grokStanza "jabber:client" stanzaTag = |
@@ -313,6 +376,7 @@ grokStanza "jabber:client" stanzaTag = | |||
313 | _ | stanzaTag `isClientIQOf` "set" -> grokStanzaIQSet stanzaTag | 376 | _ | stanzaTag `isClientIQOf` "set" -> grokStanzaIQSet stanzaTag |
314 | _ | stanzaTag `isClientIQOf` "result" -> grokStanzaIQResult stanzaTag | 377 | _ | stanzaTag `isClientIQOf` "result" -> grokStanzaIQResult stanzaTag |
315 | _ | tagName stanzaTag == "{jabber:client}presence" -> grokPresence "jabber:client" stanzaTag | 378 | _ | tagName stanzaTag == "{jabber:client}presence" -> grokPresence "jabber:client" stanzaTag |
379 | _ | tagName stanzaTag == "{jabber:client}message" -> grokMessage "jabber:client" stanzaTag | ||
316 | _ -> return $ Just Unrecognized | 380 | _ -> return $ Just Unrecognized |
317 | 381 | ||
318 | xmppInbound :: Server ConnectionKey | 382 | xmppInbound :: Server ConnectionKey |