Files
p2p-rendering-computation/haskell/app/Main.hs

175 lines
3.8 KiB
Haskell

{-# LANGUAGE OverloadedStrings #-}
module Main where
import Data.Aeson
import System.Process (readProcess, terminateProcess, ProcessHandle, spawnProcess)
import Control.Monad (MonadPlus(mzero))
import Control.Concurrent (threadDelay)
import qualified Data.ByteString.Lazy.Char8 as LBC8
-- TODO: Use it
-- import qualified Data.Text as T
-- TODO: create library to abstract shell and go-level logic
main :: IO ()
main = do
-- TODO: add IO arguments; flag to cleanup environment
-- TODO create record with all functions needed
-- TODO: initialise environment; perhaps cleanup state files
_ <- execProcP2Prc [MkOptAtomic "-dc"] MkEmpty
cmdOut <- getP2PrcCmd
startProcessHandle <- spawnProcP2Prc [MkOptAtomic "-s"]
sleepNSecs 5
outputStr <- (execProcP2PrcParser [MkOptAtomic "-ls"] MkEmpty :: IOEitherError IPAdressTable)
print outputStr
terminateProcess startProcessHandle
putStrLn cmdOut
newtype IPAdressTable
= MkIPAdressTable [ServerInfo]
deriving Show
instance FromJSON IPAdressTable where
parseJSON = withObject "IPAdressTable" $
\v ->
MkIPAdressTable <$> v .: "ip_address"
-- TODO: refactor this datatype; better definition
data ServerInfo = MkServerInfo
{ serverInfoName :: String
-- , serverInfoIp4 :: String
-- , serverInfoIp6 :: String
-- , serverInfoLatency :: Int
-- , serverInfoDownload :: Int
-- , serverInfoUpload :: Int
-- , serverInfoServerPort :: Int
-- , serverInfoBareMetalSSHPort :: Maybe Int
-- , serverInfoNat :: Bool
-- , serverInfoEscapeImplementation :: Maybe String
-- , serverInfoCustomInformation :: Maybe String
}
deriving Show
instance FromJSON ServerInfo where
parseJSON (Object o) = MkServerInfo
<$> o .: "Name"
-- <*> o .: "IPV4"
-- <*> o .: "IPV6"
-- <*> o .: "Latency"
-- <*> o .: "Download"
-- <*> o .: "Upload"
-- <*> o .: "ServerPort"
-- <*> o .: "BareMetalSSHPort"
-- <*> o .: "NAT"
-- <*> o .: "EscapeImplementation"
-- <*> o .: "CustomInformation"
parseJSON _ = mzero
data StdInput
= MkEmpty
instance Show StdInput where
show MkEmpty = ""
type IOEitherError a = IO (Either Error a)
execProcP2PrcParser ::
FromJSON a =>
[CLIOpt] -> StdInput -> IOEitherError a
execProcP2PrcParser opts stdInput =
eitherErrDecode
<$> execProcP2Prc opts stdInput
where
eitherErrDecode = eitherErrorDecode . eitherDecode . LBC8.pack
execProcP2Prc :: [CLIOpt] -> StdInput -> IO String
execProcP2Prc ops stdi =
readProcess
p2prcCmd
(optsToCLI ops)
(show stdi)
data CLIOpt
= MkOptAtomic String
| MkOptTuple (String, String)
type CLIOptsInput = [String]
optsToCLI :: [CLIOpt] -> CLIOptsInput
optsToCLI = concatMap _optToCLI
where
_optToCLI :: CLIOpt -> CLIOptsInput
_optToCLI (MkOptAtomic o) = [o]
_optToCLI (MkOptTuple (o, v)) = [o, show v]
spawnProcP2Prc :: [CLIOpt] -> IO ProcessHandle
spawnProcP2Prc =
spawnProcess p2prcCmd . optsToCLI
p2prcCmd = "/home/xecarlox/Desktop/p2p-rendering-computation/p2p-rendering-computation" :: String
getP2PrcCmd :: IO String
getP2PrcCmd = do
-- assumes the program is ran inside the haskell module in p2prc's repo
readProcess "pwd" [] "" >>=
\pwdOut ->
-- assumes that last path segment is "haskell" and that p2prc binary's name is "p2p-rendering-computation"
readProcess "sed" ["s/haskell/p2p-rendering-computation/"] pwdOut
eitherErrorDecode :: Either String a -> Either Error a
eitherErrorDecode esa =
case esa of
(Left s) -> Left $ assignError s
(Right v) -> Right v
data Error = MkError String
deriving Show
assignError :: String -> Error
assignError = MkError
-- TODO: add megaparsec to parse Error Messages
sleepNSecs :: Int -> IO ()
sleepNSecs i = threadDelay (i * 1000000)