hi3status-0.1.0.0: lib-src/Hi3Status/Blocks/Music.hs
{-|
Module : Hi3Status.Blocks.Music
License : MIT
Maintainer : Josh Kirklin (jjvk2@cam.ac.uk)
Stability : experimental
-}
module Hi3Status.Blocks.Music
( MusicBlock (..)
) where
import Hi3Status.Block
import Hi3Status.Block.Util
import qualified Data.Text as T
import Data.List (isInfixOf)
import Data.Maybe (fromJust)
import Control.Monad.IO.Class
import System.Process
import System.Exit
-- | Currently playing music. Uses @playerctl@.
data MusicBlock = MusicBlock {
-- | The format of the displayed text.
--
-- *@{playpause}@ = Play/pause icon.
-- *@{artist}@ = Artist.
-- *@{track}@ = Track.
-- *@{album}@ = Album.
format :: String,
-- | The maximum length of the displayed text.
maxLength :: Maybe Int,
-- | The icon to display when playing.
playIcon :: String,
-- | The icon to display when paused.
pauseIcon :: String
}
instance Block MusicBlock where
runBlock b = periodic 1000000 $ do
p <- liftIO playing
if p == Nothing
then pushBlockDescription $ emptyBlockDescription
else do
(artist, track, album) <- liftIO metadata
pushBlockDescription $ emptyBlockDescription
{ full_text = T.pack . (flip maxLengthText (maxLength b)) . T.unpack $ formatText
[ ("artist", artist)
, ("track", track)
, ("album", album)
, ("playpause", if fromJust p then playIcon b else pauseIcon b)
] (format b)
}
playing :: IO (Maybe Bool)
playing = do
(e,p,_) <- readProcessWithExitCode "playerctl" ["status"] ""
if e == ExitFailure 1 then return Nothing
else if "laying" `isInfixOf` p then return (Just True)
else if "ause" `isInfixOf` p then return (Just False)
else return Nothing
metadata :: IO (String, String, String)
metadata = do
artist <- filter (/='\n') <$> readProcess "playerctl" ["metadata","artist"] ""
track <- filter (/='\n') <$> readProcess "playerctl" ["metadata","title"] ""
album <- filter (/='\n') <$> readProcess "playerctl" ["metadata","album"] ""
return (artist, track, album)