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 . elem ' ' hasValue = elem '=' parseConfigLine = liftA2 (,) (spaces *> many1 alphaNum <* spaces) (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 := spaces = spaces 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