AGI 1.2 → 1.2.1
raw patch · 4 files changed
+58/−11 lines, 4 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Network.AGI: digitsToInteger :: [Digit] -> Maybe Integer
+ Network.AGI: instance Data Digit
+ Network.AGI: instance Data RecordResult
+ Network.AGI: instance Data SoundType
+ Network.AGI: instance Enum SoundType
+ Network.AGI: instance Typeable Digit
+ Network.AGI: instance Typeable RecordResult
+ Network.AGI: instance Typeable SoundType
Files
- AGI.cabal +1/−1
- Network/AGI.hs +47/−9
- debian/changelog +7/−0
- debian/control +3/−1
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.2+Version: 1.2.1 License: BSD3 License-File: LICENSE Author: Jeremy Shaw
Network/AGI.hs view
@@ -1,12 +1,13 @@-{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE GeneralizedNewtypeDeriving, DeriveDataTypeable #-} module Network.AGI ( Digit(..)+ , ppDigit+ , ppEscapeDigits+ , digitsToInteger , AGI , run , fastAGI , runInternal- , ppDigit- , ppEscapeDigits , SoundType(..) , sendRecv , answer@@ -27,6 +28,7 @@ import Control.Monad.Reader import Control.Monad.Error import Data.Char+import Data.Generics import Data.Maybe import Data.Word import Network@@ -43,6 +45,7 @@ newtype AGI a = AGI { runAGI :: ReaderT AGIEnv IO a } deriving (Monad, MonadIO, Functor, MonadError IOError, MonadReader AGIEnv) +-- |DTMF digits data Digit = Pound | Star@@ -56,8 +59,9 @@ | Seven | Eight | Nine- deriving (Eq, Ord, Read, Show, Enum)+ deriving (Eq, Ord, Read, Show, Enum, Data, Typeable) +-- |convert a 'Digit' to its ASCII representation ppDigit :: Digit -> Char ppDigit Pound = '#' ppDigit Star = '*'@@ -72,14 +76,24 @@ ppDigit Eight = '8' ppDigit Nine = '9' +-- |convert a list of 'Digit's into a quoted string.+-- The quoted string format is used by many AGI commands ppEscapeDigits :: [Digit] -> String ppEscapeDigits digits = '"' : (map ppDigit digits ++ "\"") +-- |convert a list of 'Digit's to an 'Integer'.+-- Will fail if the list is empty or contains * or #+digitsToInteger :: [Digit] -> Maybe Integer+digitsToInteger digits =+ case reads (map ppDigit digits) of+ [(i, [])] -> (Just i)+ _ -> Nothing+ type Command = String -- data Timeout = Timeout Word (Maybe Word) -- ^ timeout, max digits data SoundType = WAV | GSM- deriving Eq+ deriving (Eq, Enum, Data, Typeable) instance Show SoundType where show WAV = "wav"@@ -87,7 +101,9 @@ -- 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 =@@ -95,11 +111,15 @@ runInternal agi stdin stdout -- |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 =@@ -111,9 +131,11 @@ -- |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 =@@ -139,6 +161,9 @@ _ -> let (a,v) = break ((==) ':') l in return (Just (a, dropWhile ((==) ' ') (tail v))) +-- |send an AGI Command, and return the Response+--+-- this function provides the low-level send/receive functionality. sendRecv :: Command -> AGI String sendRecv cmd = do inh <- liftM agiInH $ ask@@ -172,7 +197,9 @@ failure: 200 result=-1 success: 200 result=1 -}-hangUp :: Maybe String -> AGI Bool+-- |hangUp the specified channel+hangUp :: Maybe String -- ^ channel to hangup, or current channel if not specified+ -> AGI Bool hangUp mChannel = do res <- sendRecv ("HANGUP" ++ (maybe "" (' ' :) mChannel)) parseResult (pResult >> ((char '1' >> return True) <|> (string "-1" >> return False))) res@@ -190,7 +217,9 @@ -} -- TODO: does digit include # and * ?--- default timeout is 2000 ms+-- |play a file and return and digits pressed+--+-- See also: 'streamFile' getData :: FilePath -- ^ file to stream -> Maybe Integer -- ^ timout in ms after keypress (default: 2000 ms) -> Maybe Integer -- ^ max@@ -234,8 +263,9 @@ | Interrupted Digit | Timeout | RandomError String- deriving (Eq, Show)+ deriving (Eq, Show, Data, Typeable) +-- |record channel to a file record :: FilePath -- ^ record to this file -> SoundType -- ^ |GSM \| WAV| -> [Digit] -- ^ stop recording if one of these digits is entered@@ -304,7 +334,10 @@ <digit> is the ascii code for the digit pressed. -} -sayDigits :: [Digit] -> [Digit] -> AGI (Maybe (Maybe Digit))+-- |say the given digit string+sayDigits :: [Digit] -- ^ digits to say+ -> [Digit] -- ^ digits which can stop playback+ -> AGI (Maybe (Maybe Digit)) -- ^ Nothing on error, Just Nothing on success. Just (Just <digit>) if interrupted. sayDigits digits escapeDigits = do res <- sendRecv $ "SAY DIGITS " ++ map ppDigit digits ++ " " ++ ppEscapeDigits escapeDigits parseResult p res@@ -366,6 +399,9 @@ Workaround: Use EXEC PLAYBACK instead. -} +-- |playback the specified file, can be interupted by the given digits.+--+-- See also: 'getData' streamFile :: FilePath -- ^ file to stream -> [Digit] -- ^ escape digits -> Maybe Integer -- ^ sample offset@@ -412,6 +448,8 @@ -} -- |wait for channel to receive a DTMF digit. +--+-- See also: 'getData' for multiple digits waitForDigit :: Integer -- ^ timeout in milliseconds, -1 to block indefinitely -> AGI (Maybe (Maybe Digit)) -- ^ |Nothing| on error, |Just Nothing| on timeout, |Just (Just <digit>)| on success waitForDigit timeout =
debian/changelog view
@@ -1,3 +1,10 @@+haskell-agi (1.2.1) unstable; urgency=low++ * Added digitsToInteger+ * Minor improvements to haddock documentation++ -- Jeremy Shaw <jeremy@n-heptane.com> Fri, 04 Jul 2008 15:06:58 -0700+ haskell-agi (1.2) unstable; urgency=low * Added initial support for FastAGI (very lightly tested)
debian/control view
@@ -12,7 +12,9 @@ libghc6-parsec-prof, libghc6-parsec-doc, libghc6-mtl-prof,- libghc6-mtl-doc+ libghc6-mtl-doc,+ libghc6-network-prof,+ libghc6-network-doc Standards-Version: 3.7.2.2 Homepage: http://www.n-heptane.com/nhlab/repos/haskell-agi