dixi-0.6: main/Main.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE ConstraintKinds #-}
import Control.Exception(bracket)
import Control.Monad
import Data.Acid
import Network.Wai.Handler.Warp
import Servant
import System.Directory
import System.FilePath
import System.Environment
import System.Exit
import System.IO
import qualified Data.Yaml as Y
import qualified Data.Text.Lazy.IO as L
import Dixi.API
import Dixi.Config
import Dixi.Database
import Dixi.Forms () -- imported for orphans
import Dixi.Server
import Dixi.Markup (defaultStylesheet)
getChar' :: IO Char
getChar' =
bracket (hGetBuffering stdin)
(hSetBuffering stdin)
$ const $ do
hSetBuffering stdin NoBuffering
bracket (hGetEcho stdin)
(hSetEcho stdin)
$ const $ hSetEcho stdin False >> getChar
handleStatics, handleStylesheet :: FilePath -> IO ()
handleStatics fn = do
c <- doesDirectoryExist fn
unless c $ do
putStrLn "Statics directory not found, would you like to [c]reate it, or e[x]it?"
getChar' >>= \i -> case i of
_ | i `elem` ("cC" :: String) -> createDirectory fn
| otherwise -> exitFailure
handleStylesheet fn = do
c <- doesFileExist fn
unless c $ do
putStrLn "Stylesheet file not found, would you like to [c]reate one, or e[x]it?"
getChar' >>= \i -> case i of
_ | i `elem` ("cC" :: String) -> L.writeFile fn defaultStylesheet
| otherwise -> exitFailure
handleConfig :: FilePath -> IO (Either Y.ParseException Config)
handleConfig fn = do
c <- doesFileExist fn
if c then Y.decodeFileEither fn
else do
putStrLn "Configuration file not found, would you like to [c]reate one, [r]un with default configuration or e[x]it?"
getChar' >>= \i -> case i of
_ | i `elem` ("cC" :: String) -> Y.encodeFile fn defaultConfig >> return (Right defaultConfig)
| i `elem` ("rR" :: String) -> return (Right defaultConfig)
| otherwise -> exitFailure
dixiWithStatic :: Proxy (Dixi :| "static" :> Raw)
dixiWithStatic = Proxy
main :: IO ()
main = getArgs >>= main'
where
main' [] = main' ["config.yaml"]
main' [x] = handleConfig x >>= main''
main' _ = do
p <- getProgName
hPutStrLn stderr $ "usage:\n " ++ p ++ " [/path/to/config.yaml]"
exitFailure
main'' (Left e) = do
hPutStrLn stderr $ Y.prettyPrintParseException e
exitFailure
main'' (Right cfg@(Config {..})) = do
case static of
Just st -> do
handleStatics st
handleStylesheet (st </> stylesheet)
Nothing -> return ()
db <- openLocalStateFrom storage emptyDB
createCheckpoint db
createArchive db
rs <- configToRenders cfg
putStrLn "Starting dixi"
run port $ case static of
Just st -> serve dixiWithStatic $ server db rs |: serveDirectory st
Nothing -> serve dixi $ server db rs