{-# LANGUAGE OverloadedStrings #-}
module Templating
( createFiles
, Interface
, SSID
, Passphrase
)
where
import qualified Config
import qualified Data.Text.IO as TextIO
import System.FilePath ( (</>) )
import qualified System.IO as IO
import System.Posix.Files
import System.Process
import Text.Mustache
import Text.Parsec.Error ( ParseError )
import Control.Monad ( liftM2 )
data ScriptSpec = ScriptSpec
{ interface :: String
, dataFilename :: String
}
instance ToMustache ScriptSpec where
toMustache spec =
object ["interface" ~> interface spec, "data_filename" ~> dataFilename spec]
newtype DataSpec = DataSpec
{ wpaPassphraseOutput :: String
}
instance ToMustache DataSpec where
toMustache spec = object ["wpa_passphrase_output" ~> wpaPassphraseOutput spec]
type Interface = String
type SSID = String
type Passphrase = String
type FileResult = Either ParseError FilePath
type WPAPassphraseOutput = String
createScript :: FilePath -> Interface -> FilePath -> IO FileResult
createScript filename iface dataFile = createFile filename
Config.scriptDirectory
scriptSpec
"script.mustache"
where scriptSpec = ScriptSpec {interface = iface, dataFilename = dataFile}
runWPAPassphrase :: SSID -> Passphrase -> IO WPAPassphraseOutput
runWPAPassphrase ssid passphrase = do
(_, Just hout, _, _) <- createProcess wpa_passphrase_process
{ std_out = CreatePipe
}
IO.hGetContents hout
where wpa_passphrase_process = proc "wpa_passphrase" [ssid, passphrase]
createData :: FilePath -> WPAPassphraseOutput -> IO FileResult
createData filename wpaPPoutput = createFile filename
Config.dataDirectory
dataSpec
"data.mustache"
where dataSpec = DataSpec {wpaPassphraseOutput = wpaPPoutput}
createFile
:: ToMustache a => FilePath -> IO FilePath -> a -> FilePath -> IO FileResult
createFile filename outputDirFunc spec templateFile = do
(templateDir, outputDir) <- liftM2 (,) Config.templateDirectory outputDirFunc
compiled <- automaticCompile [templateDir] templateFile
let outputPath = outputDir </> filename
case compiled of
Left err -> pure (Left err)
Right template -> do
TextIO.writeFile outputPath $ substitute template spec
pure (Right outputPath)
createFiles
:: FilePath -> Interface -> SSID -> Passphrase -> IO (FilePath, FilePath)
createFiles filename iface ssid passphrase = do
wpaPPoutput <- runWPAPassphrase ssid passphrase
(Right dataFile ) <- createData filename wpaPPoutput
(Right scriptFile) <- createScript filename iface dataFile
setFileMode scriptFile ownerModes
setFileMode dataFile (unionFileModes ownerWriteMode ownerReadMode)
pure (dataFile, scriptFile)