espial/src/Application.hs

177 lines
5.7 KiB
Haskell
Raw Normal View History

2019-01-31 02:54:47 +00:00
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Application
( getApplicationDev
, appMain
, develMain
, makeFoundation
, makeLogWare
-- * for DevelMain
, getApplicationRepl
, shutdownApp
-- * for GHCI
, handler
, db
) where
2019-09-15 13:43:03 +00:00
import Control.Monad.Logger (liftLoc, runLoggingT)
import Database.Persist.Sqlite (createSqlitePool, runSqlPool, sqlDatabase, sqlPoolSize)
import Import
import Language.Haskell.TH.Syntax (qLocation)
2020-03-29 23:49:28 +00:00
-- import Lens.Micro
2019-09-15 13:43:03 +00:00
import Network.HTTP.Client.TLS
import Network.Wai (Middleware)
import Network.Wai.Handler.Warp (Settings, defaultSettings, defaultShouldDisplayException, runSettings, setHost, setOnException, setPort, getPort)
import Network.Wai.Middleware.AcceptOverride
import Network.Wai.Middleware.Autohead
import Network.Wai.Middleware.Gzip
import Network.Wai.Middleware.MethodOverride
import Network.Wai.Middleware.RequestLogger (Destination(Logger), IPAddrSource(..), OutputFormat(..), destination, mkRequestLogger, outputFormat)
import System.Log.FastLogger (defaultBufSize, newStdoutLoggerSet, toLogStr)
import Yesod.Auth (getAuth)
2019-01-31 02:54:47 +00:00
2020-03-29 23:49:28 +00:00
-- import qualified Control.Monad.Metrics as MM
-- import qualified Network.Wai.Metrics as WM
-- import qualified System.Metrics as EKG
-- import qualified System.Remote.Monitoring as EKG
2019-01-31 02:54:47 +00:00
-- Import all relevant handler modules here.
-- Don't forget to add new modules to your cabal file!
2019-09-15 13:43:03 +00:00
import Handler.Common
import Handler.Home
import Handler.User
import Handler.AccountSettings
import Handler.Add
import Handler.Edit
import Handler.Notes
import Handler.Docs
2019-01-31 02:54:47 +00:00
mkYesodDispatch "App" resourcesApp
makeFoundation :: AppSettings -> IO App
makeFoundation appSettings = do
appHttpManager <- getGlobalManager
appLogger <- newStdoutLoggerSet defaultBufSize >>= makeYesodLogger
2020-03-29 23:49:28 +00:00
-- store <- EKG.newStore
-- EKG.registerGcMetrics store
-- appMetrics <- MM.initializeWith store
2019-01-31 02:54:47 +00:00
appStatic <-
(if appMutableStatic appSettings
then staticDevel
else static)
(appStaticDir appSettings)
let mkFoundation appConnPool = App { ..}
tempFoundation = mkFoundation (error "connPool forced in tempFoundation")
logFunc = messageLoggerSource tempFoundation appLogger
pool <-
flip runLoggingT logFunc $
createSqlitePool
(sqlDatabase (appDatabaseConf appSettings))
(sqlPoolSize (appDatabaseConf appSettings))
2019-09-15 13:43:03 +00:00
runLoggingT
(runSqlPool runMigrations pool)
logFunc
2019-01-31 02:54:47 +00:00
return (mkFoundation pool)
makeApplication :: App -> IO Application
makeApplication foundation = do
logWare <- makeLogWare foundation
appPlain <- toWaiAppPlain foundation
2020-03-29 23:49:28 +00:00
-- let store = appMetrics foundation ^. MM.metricsStore
-- waiMetrics <- WM.registerWaiMetrics store
return (logWare (makeMiddleware appPlain))
2019-01-31 02:54:47 +00:00
2020-03-29 23:49:28 +00:00
makeMiddleware :: Middleware
makeMiddleware =
-- WM.metrics waiMetrics .
2019-01-31 02:54:47 +00:00
acceptOverride .
autohead .
gzip def {gzipFiles = GzipPreCompressed GzipIgnore} .
methodOverride
makeLogWare :: App -> IO Middleware
makeLogWare foundation =
mkRequestLogger
def
{ outputFormat =
if appDetailedRequestLogging (appSettings foundation)
then Detailed True
else Apache
(if appIpFromHeader (appSettings foundation)
then FromFallback
else FromSocket)
, destination = Logger (loggerSet (appLogger foundation))
}
-- | Warp settings for the given foundation value.
warpSettings :: App -> Settings
warpSettings foundation =
setPort (appPort (appSettings foundation)) $
setHost (appHost (appSettings foundation)) $
setOnException
(\_req e ->
when (defaultShouldDisplayException e) $
messageLoggerSource
foundation
(appLogger foundation)
$(qLocation >>= liftLoc)
"yesod"
LevelError
(toLogStr $ "Exception from Warp: " ++ show e))
defaultSettings
-- | For yesod devel, return the Warp settings and WAI Application.
getApplicationDev :: IO (Settings, Application)
getApplicationDev = do
settings <- getAppSettings
foundation <- makeFoundation settings
wsettings <- getDevSettings (warpSettings foundation)
app <- makeApplication foundation
2020-03-29 23:49:28 +00:00
-- forkEKG foundation
2019-01-31 02:54:47 +00:00
return (wsettings, app)
getAppSettings :: IO AppSettings
getAppSettings = loadYamlSettings [configSettingsYml] [] useEnv
-- | main function for use by yesod devel
develMain :: IO ()
develMain = develMainHelper getApplicationDev
2020-03-29 23:49:28 +00:00
-- forkEKG :: App -> IO ()
-- forkEKG foundation =
-- let settings = appSettings foundation in
-- for_ (appEkgHost settings) $ \ekgHost ->
-- for_ (appEkgPort settings) $ \ekgPort ->
-- EKG.forkServerWith
-- (appMetrics foundation ^. MM.metricsStore)
-- (encodeUtf8 ekgHost)
-- ekgPort
2019-01-31 02:54:47 +00:00
-- | The @main@ function for an executable running this site.
appMain :: IO ()
appMain = do
settings <- loadYamlSettingsArgs [configSettingsYmlValue] useEnv
foundation <- makeFoundation settings
app <- makeApplication foundation
2020-03-29 23:49:28 +00:00
-- forkEKG foundation
2019-01-31 02:54:47 +00:00
runSettings (warpSettings foundation) app
getApplicationRepl :: IO (Int, App, Application)
getApplicationRepl = do
settings <- getAppSettings
foundation <- makeFoundation settings
wsettings <- getDevSettings (warpSettings foundation)
app1 <- makeApplication foundation
return (getPort wsettings, foundation, app1)
shutdownApp :: App -> IO ()
shutdownApp _ = return ()
-- | Run a handler
handler :: Handler a -> IO a
handler h = getAppSettings >>= makeFoundation >>= flip unsafeHandler h
-- | Run DB queries
db :: ReaderT SqlBackend (HandlerFor App) a -> IO a
db = handler . runDB