module Monitors.Volume (queryVolume) where import Data.List import Data.Maybe import System.Process import Text.Printf import Text.Regex import Text.Read import qualified Data.Map as M import Monitors.Common mixer :: String mixer = "Master" icons :: M.Map String String icons = M.map buildIcon $ M.fromList [ ( "high" , 64125 ) , ( "low" , 64126 ) , ( "mid" , 64127 ) , ( "off" , 64128 ) , ( "mute" , 64605 ) ] data MixerData = MixerData { mute :: Bool , vol :: Int } deriving Eq getIcon :: MixerData -> String getIcon x = fromMaybe (icons M.! def) $ M.lookup (iconKey x) icons where iconKey MixerData { mute = True } = "mute" iconKey MixerData { vol = vol } | vol >= 80 = "high" | vol >= 10 && vol < 80 = "mid" | vol < 10 = "low" | otherwise = def def = "high" getColor :: MixerData -> String getColor x = fromMaybe (colors M.! def) $ M.lookup (colorKey x) colors where colorKey MixerData { mute = True } = "inactive" colorKey MixerData { vol = vol } | vol > 110 = "red" | vol > 100 && vol <= 110 = "yellow" | vol > 70 && vol <= 100 = "green" | vol > 0 && vol <= 70 = "blue" | vol == 0 = "inactive" | otherwise = def def = "active" getStatus :: MixerData -> String getStatus x@MixerData { mute = mute, vol = vol } = let txtColor = if mute then colors M.! "inactive" else colors M.! "active" icon = colorize (getColor x) (getIcon x) txt = colorize txtColor $ show vol in printf "%s %s" icon txt parseMixerInfo :: String -> Maybe MixerData parseMixerInfo = fmap fmtMixer . matchRegex regex where regex = mkRegex ".+: Playback [0-9]+ \\[([0-9]+)%\\] (\\[.+dB\\] )?\\[(on|off)\\]" fmtMixer [volume,_,state] = let mute = case state of "on" -> False "off" -> True _ -> False vol = read volume in MixerData { mute = mute, vol = vol } fmtData :: MixerData -> String fmtData = (separator ++ ) . getStatus getMute :: IO Bool getMute = parseMute <$> readProcess "/nix/store/ambq4n07zlax0lwz0v1yph85cph1sssk-pamixer-1.4/bin/pamixer" ["--get-mute"] "" where parseMute "true" = True parseMute "false" = False parseMute _ = False getVol :: IO Int getVol = parseVol <$> readProcess "pamixer" ["--get-volume"] "" where parseVol x = case readMaybe x of (Just vol) -> vol Nothing -> 0 getInfo :: IO MixerData getInfo = do mute <- getMute vol <- getVol return $ MixerData { mute = mute, vol = vol } queryVolume :: IO String queryVolume = fmtData <$> getInfo