{-# LANGUAGE OverloadedStrings #-} module Main where import qualified Codec.Compression.Zlib as Zlib import Control.Monad.State.Strict import Data.Aeson import qualified Data.Aeson.Types as T import qualified Data.Attoparsec.ByteString as Atto import qualified Data.ByteString.Lazy.Char8 as LBS import qualified Data.ByteString.UTF8 as BSU(fromString) import Server.PersistentCommands import System.Console.Haskeline import System.IO (hFlush, stdout, stderr) import System.Environment (getArgs) import Data.Version (showVersion) import Paths_scion_browser import Scion.PersistentBrowser.Util (logToStdout) import GHC.IO.Handle (hDuplicate,hDuplicateTo) main :: IO () main = do args <- getArgs case args of ("--version":_) -> putStrLn ("scion-browser executable, version " ++ showVersion version) ("--clear":_) -> run False _ -> run True run :: Bool -> IO() run doCompression=do runStateT (runInputT defaultSettings (loop doCompression)) initialState return () loop :: Bool -> InputT BrowserM () loop doCompression = do maybeLine <- getInputLine "" case maybeLine of Nothing -> return () -- ctrl+D or EOF Just line -> case Atto.parseOnly json (BSU.fromString line) of Left e -> liftIO (logToStdout ("error in command: " ++ e)) >> loop doCompression Right value -> case T.parse parseJSON value of Error e -> liftIO (logToStdout ("error in command: " ++ e)) >> loop doCompression Success cmd -> do stdout_excl <- liftIO $ hDuplicate stdout liftIO $ hDuplicateTo stderr stdout -- redirect stdout to stderr (res, continue) <- lift $ executeCommand cmd liftIO $ hDuplicateTo stdout_excl stdout -- redirect stdout to original stdout let encoded = LBS.append (encode res) "\n" compressed = if doCompression then Zlib.compressWith Zlib.defaultCompressParams { Zlib.compressLevel = Zlib.bestSpeed } encoded else encoded liftIO $ LBS.putStr compressed liftIO $ hFlush stdout when continue $ loop doCompression