You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

124 lines
3.1 KiB

{-# LANGUAGE OverloadedStrings #-}
module Network.XMPP.Monad where
import Control.Applicative((<$>))
import Control.Monad
import Control.Monad.IO.Class
import Control.Monad.Trans.Class
--import Control.Monad.Trans.Resource
import Control.Concurrent
import Control.Monad.State.Strict
import Data.ByteString as BS
import Data.Conduit
import Data.Conduit.Binary as CB
import Data.Conduit.List as CL
import Data.Text(Text)
import Data.XML.Pickle
import Data.XML.Types
import Network
import Network.XMPP.Types
import Network.XMPP.Marshal
import Network.XMPP.Pickle
import System.IO
import Text.XML.Stream.Elements
import Text.XML.Stream.Parse as XP
import Text.XML.Stream.Render as XR
pushN :: Element -> XMPPConMonad ()
pushN x = do
sink <- gets sConPushBS
liftIO . sink $ renderElement x
push :: Stanza -> XMPPConMonad ()
push = pushN . pickleElem stanzaP
pushOpen :: Element -> XMPPConMonad ()
pushOpen e = do
sink <- gets sConPushBS
liftIO . sink $ renderOpenElement e
return ()
pulls :: Sink Event IO b -> XMPPConMonad b
pulls snk = do
source <- gets sConSrc
(src', r) <- lift $ source $$+ snk
modify $ (\s -> s {sConSrc = src'})
return r
pullE :: XMPPConMonad Element
pullE = pulls elementFromEvents
pullPickle :: PU [Node] a -> XMPPConMonad a
pullPickle p = unpickleElem' p <$> pullE
pull :: XMPPConMonad Stanza
pull = pullPickle stanzaP
xmppFromHandle :: Handle
-> Text
-> Text
-> Maybe Text
-> XMPPConMonad a
-> IO (a, XMPPConState)
xmppFromHandle handle hostname username res f = do
liftIO $ hSetBuffering handle NoBuffering
let raw = sourceHandle handle
let src = raw $= XP.parseBytes def
let st = XMPPConState
src
(raw)
(BS.hPut handle)
(Just handle)
(SF Nothing [] [])
False
(Just hostname)
(Just username)
res
runStateT f st
zeroSource :: Source IO output
zeroSource = sourceState () (\_ -> forever $ threadDelay 10000000)
xmppZeroConState :: XMPPConState
xmppZeroConState = XMPPConState
{ sConSrc = zeroSource
, sRawSrc = zeroSource
, sConPushBS = (\_ -> return ())
, sConHandle = Nothing
, sFeatures = SF Nothing [] []
, sHaveTLS = False
, sHostname = Nothing
, sUsername = Nothing
, sResource = Nothing
}
xmppRawConnect :: HostName -> Text -> XMPPConMonad ()
xmppRawConnect host hostname = do
uname <- gets sUsername
con <- liftIO $ do
con <- connectTo host (PortNumber 5222)
hSetBuffering con NoBuffering
return con
let raw = sourceHandle con
let src = raw $= XP.parseBytes def
let st = XMPPConState
src
(raw)
(BS.hPut con)
(Just con)
(SF Nothing [] [])
False
(Just hostname)
uname
Nothing
put st
withNewSession :: XMPPConMonad a -> IO (a, XMPPConState)
withNewSession action = do
runStateT action xmppZeroConState