darcsden-1.0: src/WebServer.hs
{-# LANGUAGE OverloadedStrings, CPP #-}
module Main where
import Blaze.ByteString.Builder (fromByteString, toByteString)
import Blaze.ByteString.Builder.Char8 (fromShow)
-- #ifdef DEBUG
-- import Blaze.ByteString.Builder.Char8 (fromString)
-- #endif
import Control.Exception
import Control.Monad (forM_)
import Control.Monad.Trans
import Database.CouchDB
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as B8 (pack)
import Data.Monoid (mconcat)
import Snap.Core
import Snap.Http.Server
import System.Directory (getCurrentDirectory)
import System.Environment
-- import DarcsDen.Debug
import DarcsDen.Handler
import DarcsDen.Settings
import DarcsDen.State.Schema
import DarcsDen.State.Util (runDB, withRedis)
import DarcsDen.WebUtils (exceptionPage)
main :: IO ()
main = do
cwd <- liftIO getCurrentDirectory
as <- getArgs
case as of
("--install":_) -> runDB $ do
liftIO (putStrLn "creating databases...")
createDB "repositories"
createDB "users"
createDB "issues"
createDB "comments"
liftIO (putStrLn "creating repository design documents...")
forM_ repoDesigns $ \js ->
newDoc (db "repositories") js
liftIO (putStrLn "creating user design documents...")
forM_ userDesigns $ \js ->
newDoc (db "users") js
liftIO (putStrLn "creating issue design documents...")
forM_ issueDesigns $ \js ->
newDoc (db "issues") js
liftIO (putStrLn "creating comment design documents...")
forM_ commentDesigns $ \js ->
newDoc (db "comments") js
liftIO (putStrLn "All set!")
[] -> do
checkDBs
putStrLn "darcsden running on port 8900"
startHTTP 8900 hostname cwd
("--port":p:_) -> do
checkDBs
putStrLn $ "darcsden running on port " ++ p
startHTTP (read p) hostname cwd
_ ->
putStr . unlines $
[ "usage:"
, " darcsden --readme : figure out how to use this thing"
, " darcsden --install : set up CouchDB databases"
, " darcsden : start webserver with defaults"
, " darcsden --port PORT : start webserver on given port"
]
where
checkDBs = do
putStrLn "checking couchdb..."
runDB (return ())
putStrLn "checking redis..."
withRedis (return ())
startHTTP p h d = httpServe (config p h) (handler d)
config p h
= setAccessLog (ConfigFileLog $ accessLog)
. setErrorLog (ConfigFileLog $ errorLog)
. setPort p
. setHostname (B8.pack h)
. setDefaultTimeout maxRequestTime
. setErrorHandler errorHandler
#ifdef DEBUG
-- . setVerbose False
#endif
$ defaultConfig
errorHandler :: SomeException -> Snap ()
errorHandler e = do
r <- getRequest
logError $ errorLogMsg e r
exceptionPage e
errorLogMsg :: SomeException -> Request -> B.ByteString
errorLogMsg e r =
toByteString $ mconcat $
[ fromByteString "During processing of request from "
, fromByteString $ rqRemoteAddr r
, fromByteString ":"
, fromShow $ rqRemotePort r
, fromByteString "\n"
, fromByteString "Request handler threw an exception:\n"
, fromShow e
-- #ifdef DEBUG
-- , fromByteString "Request:\n"
-- , fromString $ show r
-- , fromByteString "\n"
-- #endif
]