module Ideas.Main.Default
( defaultMain, defaultCGI
, Some(..), serviceList, metaServiceList, Service
, module Ideas.Service.DomainReasoner
) where
import Control.Exception
import Control.Monad
import Data.Maybe
import Data.Time
import Ideas.Common.Utils (useFixedStdGen, Some(..))
import Ideas.Common.Utils.TestSuite
import Ideas.Encoding.ModeJSON (processJSON)
import Ideas.Encoding.ModeXML (processXML)
import Ideas.Main.BlackBoxTests
import Ideas.Main.Documentation
import Ideas.Main.LoggingDatabase
import Ideas.Main.Options hiding (fullVersion)
import Ideas.Service.DomainReasoner
import Ideas.Service.FeedbackScript.Analysis
import Ideas.Service.Request
import Ideas.Service.ServiceList
import Ideas.Service.Types (Service)
import Network.CGI
import Prelude hiding (catch)
import System.IO
import System.IO.Error (ioeGetErrorString)
defaultMain :: DomainReasoner -> IO ()
defaultMain dr = do
flags <- getFlags
if null flags
then defaultCGI dr
else defaultCommandLine dr flags
defaultCGI :: DomainReasoner -> IO ()
defaultCGI dr = runCGI $ handleErrors $ do
startTime <- liftIO getCurrentTime
addr <- remoteAddr
cgiBin <- scriptName
input <- inputOrDefault
(req, txt, ctp) <- liftIO $
process dr (Just cgiBin) input
when (useLogging req) $
liftIO $ logMessage req input txt addr startTime
setHeader "Content-type" ctp
setHeader "Access-Control-Allow-Origin" "*"
output txt
inputOrDefault :: CGI String
inputOrDefault = do
inHtml <- acceptsHTML
ms <- getInput "input"
case ms of
Just s -> return s
Nothing
| inHtml -> return defaultBrowser
| otherwise -> fail "environment variable 'input' is empty"
where
defaultBrowser :: String
defaultBrowser = "<request service='index' encoding='html'/>"
acceptsHTML :: CGI Bool
acceptsHTML = do
maybeAcceptCT <- requestAccept
let htmlCT = ContentType "text" "html" []
xs = negotiate [htmlCT] maybeAcceptCT
return (isJust maybeAcceptCT && not (null xs))
defaultCommandLine :: DomainReasoner -> [Flag] -> IO ()
defaultCommandLine dr flags = do
hSetBinaryMode stdout True
useFixedStdGen
mapM_ doAction flags
where
doAction flag =
case flag of
Version -> putStrLn ("IDEAS, " ++ versionText)
Help -> putStrLn helpText
InputFile file ->
withBinaryFile file ReadMode $ \h -> do
input <- hGetContents h
(_, txt, _) <- process dr Nothing input
putStrLn txt
Test dir -> do
tests <- blackBoxTests dr dir
result <- runTestSuiteResult True tests
printSummary result
MakePages dir ->
makeDocumentation dr dir
MakeScriptFor s -> makeScriptFor dr s
AnalyzeScript file -> parseAndAnalyzeScript dr file
process :: DomainReasoner -> Maybe String -> String -> IO (Request, String, String)
process dr cgiBin input = do
format <- discoverDataFormat input
run format (Just 5) cgiBin dr input
`catch` \ioe ->
let msg = "Error: " ++ ioeGetErrorString ioe
in return (emptyRequest, msg, "text/plain")
where
run XML = processXML
run JSON = processJSON