packages feed

AGI 1.1.1 → 1.2

raw patch · 3 files changed

+61/−15 lines, 3 filesdep +networkPVP ok

version bump matches the API change (PVP)

Dependencies added: network

API changes (from Hackage documentation)

- Network.AGI: instance MonadReader [(String, String)] AGI
+ Network.AGI: fastAGI :: Maybe PortID -> (HostName -> PortNumber -> AGI a) -> IO ()
+ Network.AGI: instance MonadReader AGIEnv AGI
+ Network.AGI: runInternal :: AGI a -> Handle -> Handle -> IO a

Files

AGI.cabal view
@@ -7,7 +7,7 @@      can be used to write external programs that interact with      Asterisk. It is typically used for creating Interactive Voice      Response (IVR) systems. -Version:        1.1.1+Version:        1.2 License:        BSD3 License-File:   LICENSE Author:         Jeremy Shaw@@ -33,9 +33,9 @@     build-depends:  parsec, mtl      if flag(small_base)-        build-depends:  base >= 3, random, unix+        build-depends:  base >= 3, random, unix, network     else-        build-depends:  base <  3+        build-depends:  base <  3, network      Exposed-modules:             Network.AGI 
Network/AGI.hs view
@@ -3,6 +3,8 @@     ( Digit(..)     , AGI     , run+    , fastAGI+    , runInternal     , ppDigit     , ppEscapeDigits     , SoundType(..)@@ -18,6 +20,8 @@     , record     ) where +import Control.Concurrent+import Control.Exception (finally) import Control.Monad import Control.Monad.Trans import Control.Monad.Reader@@ -25,14 +29,20 @@ import Data.Char import Data.Maybe import Data.Word+import Network import Text.ParserCombinators.Parsec import System.IO import System.Posix.Signals import System.Random -newtype AGI a = AGI { runAGI :: ReaderT [(String, String)] IO a }-    deriving (Monad, MonadIO, Functor, MonadError IOError, MonadReader [(String, String)])+data AGIEnv = AGIEnv { agiVars :: [(String, String)]+                     , agiInH :: Handle+                     , agiOutH :: Handle+                     } +newtype AGI a = AGI { runAGI :: ReaderT AGIEnv IO a }+    deriving (Monad, MonadIO, Functor, MonadError IOError, MonadReader AGIEnv)+ data Digit     = Pound     | Star@@ -76,26 +86,54 @@     show GSM  = "gsm"  -- TODO: let user install a custom sipHUP handler (sigHUP is sent when the caller hangs ups)+-- |Top-level wrapper for single-shot AGI scripts.+-- Example:+-- @ main = run yourAGI Ignore @ run :: AGI a -> Handler -> IO a run agi hupHandler =     do installHandler sigHUP hupHandler Nothing-       hSetBuffering stdin LineBuffering-       hSetBuffering stdout LineBuffering-       agiVars <- readAgiVars-       runReaderT (runAGI agi) agiVars+       runInternal agi stdin stdout -readAgiVars :: IO [(String, String)]-readAgiVars = +-- |Top-level for long running AGI scripts.+-- Example:+-- @ main = fastAGI Nothing yourAGI @+-- You should be sure to compile with -threaded. Note that 'yourAGI'+-- may be running simultaneously in multiple threads, so you will need+-- some concurrency control for shared data.+-- TODO: support a hang-up handler+fastAGI :: Maybe PortID -> (HostName -> PortNumber -> AGI a) -> IO ()+fastAGI portId agi =+    do installHandler sigPIPE Ignore Nothing +       s <- listenOn $ fromMaybe (PortNumber 4573) portId+       (forever $ (do (h, hostname, portNum) <- accept s+                      forkIO $ runInternal (agi hostname portNum) h h >> hClose h+                  )) `finally` (sClose s)+++-- |runInternal - run an AGI script using the supplied Handles for input and output+-- You probably want 'run' or 'fastAGI'. This function is exposed so+-- that 3rd party libraries such as HAppS can easily add support for+-- FastAGI support.+-- TODO: support general method of handling extra arguments (query_string vs command-line arguments)+runInternal :: AGI a -> Handle -> Handle -> IO a+runInternal agi inh outh =+    do vars <- readAgiVars inh+       hSetBuffering inh  LineBuffering+       hSetBuffering outh LineBuffering+       runReaderT (runAGI agi) (AGIEnv vars inh outh)++readAgiVars :: Handle -> IO [(String, String)]+readAgiVars inh =      do mAgiVar <- readAgiVar         case mAgiVar of 	    Nothing ->  		return [] 	    Just agiVar ->-		do rest <- readAgiVars+		do rest <- readAgiVars inh 		   return (agiVar:rest)     where readAgiVar :: IO (Maybe (String, String)) 	  readAgiVar =-	      do l <- getLine+	      do l <- hGetLine inh 		 case l of 		      "" -> return Nothing 		      _ -> let (a,v) = break ((==) ':') l in@@ -103,8 +141,10 @@  sendRecv :: Command -> AGI String sendRecv cmd =-    liftIO $ do putStrLn cmd-                getLine+    do inh  <- liftM agiInH  $ ask+       outh <- liftM agiOutH $ ask+       liftIO $ do hPutStrLn inh cmd+                   hGetLine outh  {- Usage: ANSWER
debian/changelog view
@@ -1,3 +1,9 @@+haskell-agi (1.2) unstable; urgency=low++  * Added initial support for FastAGI (very lightly tested)++ -- Jeremy Shaw <jeremy@n-heptane.com>  Wed, 02 Jul 2008 23:56:03 -0700+ haskell-agi (1.1.1) unstable; urgency=low    * Debianization generated by cabal-debian