{-# LANGUAGE OverloadedStrings, TupleSections #-}
module Network.MPD.Applicative.Status
( clearError
, currentSong
, idle
, noidle
, status
, stats
) where
import Control.Monad
import Control.Arrow ((***))
import Network.MPD.Util
import Network.MPD.Applicative.Internal
import Network.MPD.Commands.Arg hiding (Command)
import Network.MPD.Commands.Parse
import Network.MPD.Commands.Types
import Data.ByteString.Char8 (ByteString)
import qualified Data.ByteString.UTF8 as UTF8
clearError :: Command ()
clearError :: Command ()
clearError = Parser () -> [String] -> Command ()
forall a. Parser a -> [String] -> Command a
Command Parser ()
emptyResponse [String
"clearerror"]
currentSong :: Command (Maybe Song)
currentSong :: Command (Maybe Song)
currentSong = Parser (Maybe Song) -> [String] -> Command (Maybe Song)
forall a. Parser a -> [String] -> Command a
Command (([ByteString] -> Either String (Maybe Song)) -> Parser (Maybe Song)
forall a. ([ByteString] -> Either String a) -> Parser a
liftParser [ByteString] -> Either String (Maybe Song)
parseMaybeSong) [String
"currentsong"]
takeSubsystems :: [ByteString] -> Either String [Subsystem]
takeSubsystems :: [ByteString] -> Either String [Subsystem]
takeSubsystems = ((ByteString, ByteString) -> Either String Subsystem)
-> [(ByteString, ByteString)] -> Either String [Subsystem]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (ByteString, ByteString) -> Either String Subsystem
f ([(ByteString, ByteString)] -> Either String [Subsystem])
-> ([ByteString] -> [(ByteString, ByteString)])
-> [ByteString]
-> Either String [Subsystem]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> [(ByteString, ByteString)]
toAssocList
where
f :: (ByteString, ByteString) -> Either String Subsystem
f :: (ByteString, ByteString) -> Either String Subsystem
f (ByteString
"changed", ByteString
system) =
case ByteString
system of
ByteString
"database" -> Subsystem -> Either String Subsystem
forall a b. b -> Either a b
Right Subsystem
DatabaseS
ByteString
"update" -> Subsystem -> Either String Subsystem
forall a b. b -> Either a b
Right Subsystem
UpdateS
ByteString
"stored_playlist" -> Subsystem -> Either String Subsystem
forall a b. b -> Either a b
Right Subsystem
StoredPlaylistS
ByteString
"playlist" -> Subsystem -> Either String Subsystem
forall a b. b -> Either a b
Right Subsystem
PlaylistS
ByteString
"player" -> Subsystem -> Either String Subsystem
forall a b. b -> Either a b
Right Subsystem
PlayerS
ByteString
"mixer" -> Subsystem -> Either String Subsystem
forall a b. b -> Either a b
Right Subsystem
MixerS
ByteString
"output" -> Subsystem -> Either String Subsystem
forall a b. b -> Either a b
Right Subsystem
OutputS
ByteString
"options" -> Subsystem -> Either String Subsystem
forall a b. b -> Either a b
Right Subsystem
OptionsS
ByteString
"partition" -> Subsystem -> Either String Subsystem
forall a b. b -> Either a b
Right Subsystem
PartitionS
ByteString
"sticker" -> Subsystem -> Either String Subsystem
forall a b. b -> Either a b
Right Subsystem
StickerS
ByteString
"subscription" -> Subsystem -> Either String Subsystem
forall a b. b -> Either a b
Right Subsystem
SubscriptionS
ByteString
"message" -> Subsystem -> Either String Subsystem
forall a b. b -> Either a b
Right Subsystem
MessageS
ByteString
"neighbor" -> Subsystem -> Either String Subsystem
forall a b. b -> Either a b
Right Subsystem
NeighborS
ByteString
"mount" -> Subsystem -> Either String Subsystem
forall a b. b -> Either a b
Right Subsystem
MountS
ByteString
k -> String -> Either String Subsystem
forall a b. a -> Either a b
Left (String
"Unknown subsystem: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ ByteString -> String
UTF8.toString ByteString
k)
f (ByteString, ByteString)
x = String -> Either String Subsystem
forall a b. a -> Either a b
Left (String
"idle: Unexpected " String -> String -> String
forall a. [a] -> [a] -> [a]
++ (ByteString, ByteString) -> String
forall a. Show a => a -> String
show (ByteString, ByteString)
x)
idle :: [Subsystem] -> Command [Subsystem]
idle :: [Subsystem] -> Command [Subsystem]
idle [Subsystem]
ss = Parser [Subsystem] -> [String] -> Command [Subsystem]
forall a. Parser a -> [String] -> Command a
Command (([ByteString] -> Either String [Subsystem]) -> Parser [Subsystem]
forall a. ([ByteString] -> Either String a) -> Parser a
liftParser [ByteString] -> Either String [Subsystem]
takeSubsystems) [String]
c
where
c :: [String]
c = [Command
"idle" Command -> Args -> String
forall a. MPDArg a => Command -> a -> String
<@> (Subsystem -> Args -> Args) -> Args -> [Subsystem] -> Args
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Subsystem -> Args -> Args
forall a b. (MPDArg a, MPDArg b) => a -> b -> Args
(<++>) ([String] -> Args
Args []) [Subsystem]
ss]
noidle :: Command ()
noidle :: Command ()
noidle = Parser () -> [String] -> Command ()
forall a. Parser a -> [String] -> Command a
Command Parser ()
emptyResponse [String
"noidle"]
stats :: Command Stats
stats :: Command Stats
stats = Parser Stats -> [String] -> Command Stats
forall a. Parser a -> [String] -> Command a
Command (([ByteString] -> Either String Stats) -> Parser Stats
forall a. ([ByteString] -> Either String a) -> Parser a
liftParser [ByteString] -> Either String Stats
parseStats) [String
"stats"]
status :: Command Status
status :: Command Status
status = Parser Status -> [String] -> Command Status
forall a. Parser a -> [String] -> Command a
Command (([ByteString] -> Either String Status) -> Parser Status
forall a. ([ByteString] -> Either String a) -> Parser a
liftParser [ByteString] -> Either String Status
parseStatus) [String
"status"]
where
parseStatus :: [ByteString] -> Either String Status
parseStatus :: [ByteString] -> Either String Status
parseStatus = (Status -> (ByteString, ByteString) -> Either String Status)
-> Status -> [(ByteString, ByteString)] -> Either String Status
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM Status -> (ByteString, ByteString) -> Either String Status
forall {a}.
(Eq a, IsString a, Show a) =>
Status -> (a, ByteString) -> Either String Status
go Status
forall a. Default a => a
def ([(ByteString, ByteString)] -> Either String Status)
-> ([ByteString] -> [(ByteString, ByteString)])
-> [ByteString]
-> Either String Status
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> [(ByteString, ByteString)]
toAssocList
where
go :: Status -> (a, ByteString) -> Either String Status
go Status
a p :: (a, ByteString)
p@(a
k, ByteString
v) = case a
k of
a
"volume" -> (Maybe Volume -> Status) -> Either String Status
forall {a} {b}. Num a => (Maybe a -> b) -> Either String b
vol ((Maybe Volume -> Status) -> Either String Status)
-> (Maybe Volume -> Status) -> Either String Status
forall a b. (a -> b) -> a -> b
$ \Maybe Volume
x -> Status
a { stVolume = x }
a
"repeat" -> (Bool -> Status) -> Either String Status
forall {b}. (Bool -> b) -> Either String b
bool ((Bool -> Status) -> Either String Status)
-> (Bool -> Status) -> Either String Status
forall a b. (a -> b) -> a -> b
$ \Bool
x -> Status
a { stRepeat = x }
a
"random" -> (Bool -> Status) -> Either String Status
forall {b}. (Bool -> b) -> Either String b
bool ((Bool -> Status) -> Either String Status)
-> (Bool -> Status) -> Either String Status
forall a b. (a -> b) -> a -> b
$ \Bool
x -> Status
a { stRandom = x }
a
"single" -> (Bool -> Status) -> Either String Status
forall {b}. (Bool -> b) -> Either String b
single ((Bool -> Status) -> Either String Status)
-> (Bool -> Status) -> Either String Status
forall a b. (a -> b) -> a -> b
$ \Bool
x -> Status
a { stSingle = x }
a
"consume" -> (Bool -> Status) -> Either String Status
forall {b}. (Bool -> b) -> Either String b
bool ((Bool -> Status) -> Either String Status)
-> (Bool -> Status) -> Either String Status
forall a b. (a -> b) -> a -> b
$ \Bool
x -> Status
a { stConsume = x }
a
"playlist" -> (Integer -> Status) -> Either String Status
forall {a} {b}. (Read a, Integral a) => (a -> b) -> Either String b
num ((Integer -> Status) -> Either String Status)
-> (Integer -> Status) -> Either String Status
forall a b. (a -> b) -> a -> b
$ \Integer
x -> Status
a { stPlaylistVersion = x }
a
"playlistlength" -> (Integer -> Status) -> Either String Status
forall {a} {b}. (Read a, Integral a) => (a -> b) -> Either String b
num ((Integer -> Status) -> Either String Status)
-> (Integer -> Status) -> Either String Status
forall a b. (a -> b) -> a -> b
$ \Integer
x -> Status
a { stPlaylistLength = x }
a
"state" -> (PlaybackState -> Status) -> Either String Status
forall {b}. (PlaybackState -> b) -> Either String b
state ((PlaybackState -> Status) -> Either String Status)
-> (PlaybackState -> Status) -> Either String Status
forall a b. (a -> b) -> a -> b
$ \PlaybackState
x -> Status
a { stState = x }
a
"song" -> (Int -> Status) -> Either String Status
forall {b}. (Int -> b) -> Either String b
int ((Int -> Status) -> Either String Status)
-> (Int -> Status) -> Either String Status
forall a b. (a -> b) -> a -> b
$ \Int
x -> Status
a { stSongPos = Just x }
a
"songid" -> (Int -> Status) -> Either String Status
forall {b}. (Int -> b) -> Either String b
int ((Int -> Status) -> Either String Status)
-> (Int -> Status) -> Either String Status
forall a b. (a -> b) -> a -> b
$ \Int
x -> Status
a { stSongID = Just $ Id x }
a
"nextsong" -> (Int -> Status) -> Either String Status
forall {b}. (Int -> b) -> Either String b
int ((Int -> Status) -> Either String Status)
-> (Int -> Status) -> Either String Status
forall a b. (a -> b) -> a -> b
$ \Int
x -> Status
a { stNextSongPos = Just x }
a
"nextsongid" -> (Int -> Status) -> Either String Status
forall {b}. (Int -> b) -> Either String b
int ((Int -> Status) -> Either String Status)
-> (Int -> Status) -> Either String Status
forall a b. (a -> b) -> a -> b
$ \Int
x -> Status
a { stNextSongID = Just $ Id x }
a
"time" -> ((FractionalSeconds, FractionalSeconds) -> Status)
-> Either String Status
forall {a} {b} {b}.
(Fractional a, Fractional b, Read a, Read b) =>
((a, b) -> b) -> Either String b
time (((FractionalSeconds, FractionalSeconds) -> Status)
-> Either String Status)
-> ((FractionalSeconds, FractionalSeconds) -> Status)
-> Either String Status
forall a b. (a -> b) -> a -> b
$ \(FractionalSeconds, FractionalSeconds)
x -> Status
a { stTime = Just x }
a
"elapsed" -> (FractionalSeconds -> Status) -> Either String Status
forall {a} {b}.
(Fractional a, Read a) =>
(a -> b) -> Either String b
frac ((FractionalSeconds -> Status) -> Either String Status)
-> (FractionalSeconds -> Status) -> Either String Status
forall a b. (a -> b) -> a -> b
$ \FractionalSeconds
x -> Status
a { stTime = fmap ((x,) . snd) (stTime a) }
a
"duration" -> (FractionalSeconds -> Status) -> Either String Status
forall {a} {b}.
(Fractional a, Read a) =>
(a -> b) -> Either String b
frac ((FractionalSeconds -> Status) -> Either String Status)
-> (FractionalSeconds -> Status) -> Either String Status
forall a b. (a -> b) -> a -> b
$ \FractionalSeconds
x -> Status
a { stTime = fmap ((,x) . fst) (stTime a) }
a
"bitrate" -> (Int -> Status) -> Either String Status
forall {b}. (Int -> b) -> Either String b
int ((Int -> Status) -> Either String Status)
-> (Int -> Status) -> Either String Status
forall a b. (a -> b) -> a -> b
$ \Int
x -> Status
a { stBitrate = Just x }
a
"xfade" -> (Integer -> Status) -> Either String Status
forall {a} {b}. (Read a, Integral a) => (a -> b) -> Either String b
num ((Integer -> Status) -> Either String Status)
-> (Integer -> Status) -> Either String Status
forall a b. (a -> b) -> a -> b
$ \Integer
x -> Status
a { stXFadeWidth = x }
a
"mixrampdb" -> (FractionalSeconds -> Status) -> Either String Status
forall {a} {b}.
(Fractional a, Read a) =>
(a -> b) -> Either String b
frac ((FractionalSeconds -> Status) -> Either String Status)
-> (FractionalSeconds -> Status) -> Either String Status
forall a b. (a -> b) -> a -> b
$ \FractionalSeconds
x -> Status
a { stMixRampdB = x }
a
"mixrampdelay" -> (FractionalSeconds -> Status) -> Either String Status
forall {a} {b}.
(Fractional a, Read a) =>
(a -> b) -> Either String b
frac ((FractionalSeconds -> Status) -> Either String Status)
-> (FractionalSeconds -> Status) -> Either String Status
forall a b. (a -> b) -> a -> b
$ \FractionalSeconds
x -> Status
a { stMixRampDelay = x }
a
"audio" -> ((Int, Int, Int) -> Status) -> Either String Status
forall {a} {a}.
(Read a, Integral a) =>
((a, a, a) -> Status) -> Either a Status
audio (((Int, Int, Int) -> Status) -> Either String Status)
-> ((Int, Int, Int) -> Status) -> Either String Status
forall a b. (a -> b) -> a -> b
$ \(Int, Int, Int)
x -> Status
a { stAudio = x }
a
"updating_db" -> (Integer -> Status) -> Either String Status
forall {a} {b}. (Read a, Integral a) => (a -> b) -> Either String b
num ((Integer -> Status) -> Either String Status)
-> (Integer -> Status) -> Either String Status
forall a b. (a -> b) -> a -> b
$ \Integer
x -> Status
a { stUpdatingDb = Just x }
a
"error" -> Status -> Either String Status
forall a b. b -> Either a b
Right Status
a { stError = Just (UTF8.toString v) }
a
"partition" -> Status -> Either String Status
forall a b. b -> Either a b
Right Status
a { stPartition = UTF8.toString v }
a
_ -> Status -> Either String Status
forall a b. b -> Either a b
Right Status
a
where
unexpectedPair :: Either String b
unexpectedPair = String -> Either String b
forall a b. a -> Either a b
Left (String
"unexpected key-value pair: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ (a, ByteString) -> String
forall a. Show a => a -> String
show (a, ByteString)
p)
int :: (Int -> b) -> Either String b
int Int -> b
f = Either String b
-> (Int -> Either String b) -> Maybe Int -> Either String b
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Either String b
forall {b}. Either String b
unexpectedPair (b -> Either String b
forall a b. b -> Either a b
Right (b -> Either String b) -> (Int -> b) -> Int -> Either String b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> b
f) (ByteString -> Maybe Int
forall a. (Read a, Integral a) => ByteString -> Maybe a
parseNum ByteString
v :: Maybe Int)
num :: (a -> b) -> Either String b
num a -> b
f = Either String b
-> (a -> Either String b) -> Maybe a -> Either String b
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Either String b
forall {b}. Either String b
unexpectedPair (b -> Either String b
forall a b. b -> Either a b
Right (b -> Either String b) -> (a -> b) -> a -> Either String b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f) (ByteString -> Maybe a
forall a. (Read a, Integral a) => ByteString -> Maybe a
parseNum ByteString
v)
bool :: (Bool -> b) -> Either String b
bool Bool -> b
f = Either String b
-> (Bool -> Either String b) -> Maybe Bool -> Either String b
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Either String b
forall {b}. Either String b
unexpectedPair (b -> Either String b
forall a b. b -> Either a b
Right (b -> Either String b) -> (Bool -> b) -> Bool -> Either String b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> b
f) (ByteString -> Maybe Bool
parseBool ByteString
v)
frac :: (a -> b) -> Either String b
frac a -> b
f = Either String b
-> (a -> Either String b) -> Maybe a -> Either String b
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Either String b
forall {b}. Either String b
unexpectedPair (b -> Either String b
forall a b. b -> Either a b
Right (b -> Either String b) -> (a -> b) -> a -> Either String b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f) (ByteString -> Maybe a
forall a. (Fractional a, Read a) => ByteString -> Maybe a
parseFrac ByteString
v)
single :: (Bool -> b) -> Either String b
single Bool -> b
f = Either String b
-> (Bool -> Either String b) -> Maybe Bool -> Either String b
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Either String b
forall {b}. Either String b
unexpectedPair (b -> Either String b
forall a b. b -> Either a b
Right (b -> Either String b) -> (Bool -> b) -> Bool -> Either String b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> b
f) (ByteString -> Maybe Bool
parseSingle ByteString
v)
audio :: ((a, a, a) -> Status) -> Either a Status
audio (a, a, a) -> Status
f = Status -> Either a Status
forall a b. b -> Either a b
Right (Status -> Either a Status) -> Status -> Either a Status
forall a b. (a -> b) -> a -> b
$ Status -> ((a, a, a) -> Status) -> Maybe (a, a, a) -> Status
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Status
a (a, a, a) -> Status
f (Char -> (ByteString -> Maybe a) -> ByteString -> Maybe (a, a, a)
forall a.
Char -> (ByteString -> Maybe a) -> ByteString -> Maybe (a, a, a)
parseTriple Char
':' ByteString -> Maybe a
forall a. (Read a, Integral a) => ByteString -> Maybe a
parseNum ByteString
v)
time :: ((a, b) -> b) -> Either String b
time (a, b) -> b
f = case ByteString -> Maybe a
forall a. (Fractional a, Read a) => ByteString -> Maybe a
parseFrac (ByteString -> Maybe a)
-> (ByteString -> Maybe b)
-> (ByteString, ByteString)
-> (Maybe a, Maybe b)
forall b c b' c'. (b -> c) -> (b' -> c') -> (b, b') -> (c, c')
forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** ByteString -> Maybe b
forall a. (Fractional a, Read a) => ByteString -> Maybe a
parseFrac ((ByteString, ByteString) -> (Maybe a, Maybe b))
-> (ByteString, ByteString) -> (Maybe a, Maybe b)
forall a b. (a -> b) -> a -> b
$ Char -> ByteString -> (ByteString, ByteString)
breakChar Char
':' ByteString
v of
(Just a
a_, Just b
b) -> (b -> Either String b
forall a b. b -> Either a b
Right (b -> Either String b)
-> ((a, b) -> b) -> (a, b) -> Either String b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a, b) -> b
f) (a
a_, b
b)
(Maybe a, Maybe b)
_ -> Either String b
forall {b}. Either String b
unexpectedPair
state :: (PlaybackState -> b) -> Either String b
state PlaybackState -> b
f = case ByteString
v of
ByteString
"play" -> (b -> Either String b
forall a b. b -> Either a b
Right (b -> Either String b)
-> (PlaybackState -> b) -> PlaybackState -> Either String b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PlaybackState -> b
f) PlaybackState
Playing
ByteString
"pause" -> (b -> Either String b
forall a b. b -> Either a b
Right (b -> Either String b)
-> (PlaybackState -> b) -> PlaybackState -> Either String b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PlaybackState -> b
f) PlaybackState
Paused
ByteString
"stop" -> (b -> Either String b
forall a b. b -> Either a b
Right (b -> Either String b)
-> (PlaybackState -> b) -> PlaybackState -> Either String b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PlaybackState -> b
f) PlaybackState
Stopped
ByteString
_ -> Either String b
forall {b}. Either String b
unexpectedPair
vol :: (Maybe a -> b) -> Either String b
vol Maybe a -> b
f = case (ByteString -> Maybe Int
forall a. (Read a, Integral a) => ByteString -> Maybe a
parseNum ByteString
v :: Maybe Int) of
Maybe Int
Nothing -> Either String b
forall {b}. Either String b
unexpectedPair
Just Int
v' -> (b -> Either String b
forall a b. b -> Either a b
Right (b -> Either String b)
-> (Maybe a -> b) -> Maybe a -> Either String b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe a -> b
f) (Int -> Maybe a
forall {a} {a}. (Integral a, Num a) => a -> Maybe a
g Int
v')
where g :: a -> Maybe a
g a
n | a
n a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
0 = Maybe a
forall a. Maybe a
Nothing
| Bool
otherwise = a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> a -> Maybe a
forall a b. (a -> b) -> a -> b
$ a -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
n