buster-2.5: App/Widgets/Environment.hs
module App.Widgets.Environment where
import Control.Monad
import Data.Either
import Data.List (elem)
import App.EventBus
import System.Environment
import Data.Maybe
import Text.Parsec hiding (many)
import Control.Applicative
isNotBlankLine = (/=0) . length . filter (/=' ') . filter (/='\t')
isNotCommentLine = not . (=='#') . head
hasValue = elem '='
parseConfigLine = liftA2 (,) (many1 alphaNum) (spaces *> char '=' *> many anyChar)
-- | Place the command line arguments on the bus as an Event following the pattern
--
-- * name : argv
--
-- * group : Environment
--
-- * source : CommandLineArgsWidget
--
-- * timespan : Persistent
--
-- * data : EStringL of the command line args
commandLineArgsWidget :: Widget [EData a]
commandLineArgsWidget b = getArgs >>=
\args -> produce' "Environment" "CommandLineArgsWidget" "argv" Persistent [EStringL args] b
-- | Read a config file and place it on the bus as individual events for each config item following the pattern:
--
-- * name : config item name
--
-- * group : Environment
--
-- * source : /filename/.ConfigFileWidget
--
-- * timespan : Persistent
--
-- * data : EString config item value
--
-- Config files follow a fairly simple grammar:
--
-- ConfigFile := [ConfigLine]
--
-- ConfigLine := <key> spaces = spaces <value> endl | CommentLine | BlankLine
--
-- CommentLine := # anychars endl
--
-- BlankLine := spaces endl
configFileWidget :: String -> Widget [EData a]
configFileWidget f b = configLines >>= mapM_ produceConfigDataEvent
where produceConfigDataEvent (n,v) = produce' "Environment" (f ++ ".ConfigFileWidget") n Persistent [EString v] b
configLines = rights . map (parse parseConfigLine "(Unknown line in config file)")
. filter isNotBlankLine
. filter isNotCommentLine
. filter hasValue
. lines
<$> readFile f
-- | Read in all environment variables and place them on the bus individually as events following the pattern:
--
-- * name : variable name
--
-- * group : Environment
--
-- * source : EnvironmentWidget
--
-- * timespan : Persistent
--
-- * data : EString variable value
--
environmentWidget :: Widget [EData a]
environmentWidget b = getEnvironment >>=
mapM_ (\(k,v) -> produce' "Environment" "EnvironmentWidget" k Persistent [EString v] b)
-- | Set the program name as an event on the bus using the following pattern:
--
-- * name : ProgramName
--
-- * group : Environment
--
-- * source : ProgramNameWidget
--
-- * timespan : Persistent
--
-- * data : EString progran name
progNameWidget :: Widget [EData a]
progNameWidget b = getProgName >>=
\v -> produce' "Environment" "ProgramNameWidget" "ProgramName" Persistent [EString v] b