diff options
-rw-r--r-- | readme.md | 3 | ||||
-rw-r--r-- | src/Plugins/Monitors.hs | 39 | ||||
-rw-r--r-- | src/Plugins/Monitors/Net.hs | 53 | ||||
-rw-r--r-- | src/Plugins/PipeReader.hs | 10 |
4 files changed, 82 insertions, 23 deletions
@@ -1044,9 +1044,10 @@ can be used in the output template as `%mydate%` - Runs the given program, and displays its standard output. -`PipeReader "/path/to/pipe" Alias` +`PipeReader "default text:/path/to/pipe" Alias` - Reads its displayed output from the given pipe. +- Prefix an optional default text separated by a colon `BufferedPipeReader Alias [ (Timeout, Bool, "/path/to/pipe1") , (Timeout, Bool, "/path/to/pipe2") diff --git a/src/Plugins/Monitors.hs b/src/Plugins/Monitors.hs index a531e26..009da68 100644 --- a/src/Plugins/Monitors.hs +++ b/src/Plugins/Monitors.hs @@ -48,24 +48,25 @@ import Plugins.Monitors.Volume import Plugins.Monitors.Mpris #endif -data Monitors = Weather Station Args Rate - | Network Interface Args Rate - | BatteryP [String] Args Rate - | DiskU DiskSpec Args Rate - | DiskIO DiskSpec Args Rate - | Thermal Zone Args Rate - | ThermalZone ZoneNo Args Rate - | Memory Args Rate - | Swap Args Rate - | Cpu Args Rate - | MultiCpu Args Rate - | Battery Args Rate - | Brightness Args Rate - | CpuFreq Args Rate - | CoreTemp Args Rate - | TopProc Args Rate - | TopMem Args Rate - | Uptime Args Rate +data Monitors = Weather Station Args Rate + | Network Interface Args Rate + | DynNetwork Args Rate + | BatteryP [String] Args Rate + | DiskU DiskSpec Args Rate + | DiskIO DiskSpec Args Rate + | Thermal Zone Args Rate + | ThermalZone ZoneNo Args Rate + | Memory Args Rate + | Swap Args Rate + | Cpu Args Rate + | MultiCpu Args Rate + | Battery Args Rate + | Brightness Args Rate + | CpuFreq Args Rate + | CoreTemp Args Rate + | TopProc Args Rate + | TopMem Args Rate + | Uptime Args Rate #ifdef IWLIB | Wireless Interface Args Rate #endif @@ -95,6 +96,7 @@ type DiskSpec = [(String, String)] instance Exec Monitors where alias (Weather s _ _) = s alias (Network i _ _) = i + alias (DynNetwork _ _) = "dynnetwork" alias (Thermal z _ _) = z alias (ThermalZone z _ _) = "thermal" ++ show z alias (Memory _ _) = "memory" @@ -126,6 +128,7 @@ instance Exec Monitors where alias (Mpris2 _ _ _) = "mpris2" #endif start (Network i a r) = startNet i a r + start (DynNetwork a r) = startDynNet a r start (Cpu a r) = startCpu a r start (MultiCpu a r) = startMultiCpu a r start (TopProc a r) = startTop a r diff --git a/src/Plugins/Monitors/Net.hs b/src/Plugins/Monitors/Net.hs index 768907c..b8adc74 100644 --- a/src/Plugins/Monitors/Net.hs +++ b/src/Plugins/Monitors/Net.hs @@ -13,12 +13,18 @@ -- ----------------------------------------------------------------------------- -module Plugins.Monitors.Net (startNet) where +module Plugins.Monitors.Net ( + startNet + , startDynNet + ) where import Plugins.Monitors.Common import Data.IORef (IORef, newIORef, readIORef, writeIORef) import Data.Time.Clock (UTCTime, getCurrentTime, diffUTCTime) +import Control.Monad (forM, filterM) +import System.Directory (getDirectoryContents, doesFileExist) +import System.FilePath ((</>)) import qualified Data.ByteString.Lazy.Char8 as B @@ -28,14 +34,39 @@ data NetDev = NA type NetDevRef = IORef (NetDev, UTCTime) +-- The more information available, the better. +-- Note that names don't matter. Therefore, if only the names differ, +-- a compare evaluates to EQ while (==) evaluates to False. +instance Ord NetDev where + compare NA NA = EQ + compare NA _ = LT + compare _ NA = GT + compare (NI _) (NI _) = EQ + compare (NI _) (ND _ _ _) = LT + compare (ND _ _ _) (NI _) = GT + compare (ND _ x1 y1) (ND _ x2 y2) = + if downcmp /= EQ + then downcmp + else y1 `compare` y2 + where downcmp = x1 `compare` x2 + netConfig :: IO MConfig netConfig = mkMConfig "<dev>: <rx>KB|<tx>KB" -- template ["dev", "rx", "tx", "rxbar", "txbar"] -- available replacements +operstateDir :: String -> FilePath +operstateDir d = "/sys/class/net" </> d </> "operstate" + +existingDevs :: IO [String] +existingDevs = getDirectoryContents "/sys/class/net" >>= filterM isDev + where isDev d | d `elem` excludes = return False + | otherwise = doesFileExist (operstateDir d) + excludes = [".", "..", "lo"] + isUp :: String -> IO Bool isUp d = do - operstate <- B.readFile $ "/sys/class/net/" ++ d ++ "/operstate" + operstate <- B.readFile (operstateDir d) return $ "up" == (B.unpack . head . B.lines) operstate readNetDev :: [String] -> IO NetDev @@ -103,9 +134,27 @@ parseNet nref nd = do runNet :: NetDevRef -> String -> [String] -> Monitor String runNet nref i _ = io (parseNet nref i) >>= printNet +parseNets :: [(NetDevRef, String)] -> IO [NetDev] +parseNets = mapM $ \(ref, i) -> parseNet ref i + +runNets :: [(NetDevRef, String)] -> [String] -> Monitor String +runNets refs _ = io (parseActive refs) >>= printNet + where parseActive refs' = parseNets refs' >>= return . selectActive + selectActive = maximum + startNet :: String -> [String] -> Int -> (String -> IO ()) -> IO () startNet i a r cb = do t0 <- getCurrentTime nref <- newIORef (NA, t0) _ <- parseNet nref i runM a netConfig (runNet nref i) r cb + +startDynNet :: [String] -> Int -> (String -> IO ()) -> IO () +startDynNet a r cb = do + devs <- existingDevs + refs <- forM devs $ \d -> do + t <- getCurrentTime + nref <- newIORef (NA, t) + _ <- parseNet nref d + return (nref, d) + runM a netConfig (runNets refs) r cb diff --git a/src/Plugins/PipeReader.hs b/src/Plugins/PipeReader.hs index 3fd0dd4..42ae500 100644 --- a/src/Plugins/PipeReader.hs +++ b/src/Plugins/PipeReader.hs @@ -23,6 +23,12 @@ data PipeReader = PipeReader String String instance Exec PipeReader where alias (PipeReader _ a) = a start (PipeReader p _) cb = do - h <- openFile p ReadWriteMode + let (def, pipe) = split ':' p + h <- openFile pipe ReadWriteMode + cb def forever (hGetLineSafe h >>= cb) - where forever a = a >> forever a + where + forever a = a >> forever a + split c xs | c `elem` xs = let (pre, post) = span ((/=) c) xs + in (pre, dropWhile ((==) c) post) + | otherwise = ([], xs) |