summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Plugins/Monitors.hs39
-rw-r--r--src/Plugins/Monitors/Net.hs53
-rw-r--r--src/Plugins/PipeReader.hs10
3 files changed, 80 insertions, 22 deletions
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)