{-# LANGUAGE FlexibleContexts, OverloadedStrings #-}
module Network.MPD.Commands.Parse where
import Network.MPD.Commands.Types
import Control.Monad.Except
import Data.Maybe (fromMaybe)
import Network.MPD.Util
import Data.ByteString.Char8 (ByteString)
import qualified Data.ByteString.UTF8 as UTF8
parseCount :: [ByteString] -> Either String Count
parseCount :: [ByteString] -> Either String Count
parseCount = forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM Count -> (ByteString, ByteString) -> Either String Count
f forall a. Default a => a
def forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> [(ByteString, ByteString)]
toAssocList
where f :: Count -> (ByteString, ByteString) -> Either String Count
f :: Count -> (ByteString, ByteString) -> Either String Count
f Count
a (ByteString
"songs", ByteString
x) = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b.
(ByteString -> Maybe a) -> (a -> b) -> b -> ByteString -> b
parse forall a. (Read a, Integral a) => ByteString -> Maybe a
parseNum
(\Seconds
x' -> Count
a { cSongs :: Seconds
cSongs = Seconds
x'}) Count
a ByteString
x
f Count
a (ByteString
"playtime", ByteString
x) = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b.
(ByteString -> Maybe a) -> (a -> b) -> b -> ByteString -> b
parse forall a. (Read a, Integral a) => ByteString -> Maybe a
parseNum
(\Seconds
x' -> Count
a { cPlaytime :: Seconds
cPlaytime = Seconds
x' }) Count
a ByteString
x
f Count
_ (ByteString, ByteString)
x = forall a b. a -> Either a b
Left forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show (ByteString, ByteString)
x
parseOutputs :: [ByteString] -> Either String [Device]
parseOutputs :: [ByteString] -> Either String [Device]
parseOutputs = forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM forall {a}.
(Eq a, IsString a, Show a) =>
Device -> (a, ByteString) -> Either String Device
f forall a. Default a => a
def)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString]
-> [(ByteString, ByteString)] -> [[(ByteString, ByteString)]]
splitGroups [ByteString
"outputid"]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> [(ByteString, ByteString)]
toAssocList
where f :: Device -> (a, ByteString) -> Either String Device
f Device
a (a
"outputid", ByteString
x) = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b.
(ByteString -> Maybe a) -> (a -> b) -> b -> ByteString -> b
parse forall a. (Read a, Integral a) => ByteString -> Maybe a
parseNum
(\Int
x' -> Device
a { dOutputID :: Int
dOutputID = Int
x' }) Device
a ByteString
x
f Device
a (a
"outputname", ByteString
x) = forall (m :: * -> *) a. Monad m => a -> m a
return Device
a { dOutputName :: String
dOutputName = ByteString -> String
UTF8.toString ByteString
x }
f Device
a (a
"outputenabled", ByteString
x) = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b.
(ByteString -> Maybe a) -> (a -> b) -> b -> ByteString -> b
parse ByteString -> Maybe Bool
parseBool
(\Bool
x' -> Device
a { dOutputEnabled :: Bool
dOutputEnabled = Bool
x'}) Device
a ByteString
x
f Device
_ (a, ByteString)
x = forall a b. a -> Either a b
Left forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show (a, ByteString)
x
parseStats :: [ByteString] -> Either String Stats
parseStats :: [ByteString] -> Either String Stats
parseStats = forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM forall {a}.
(Eq a, IsString a, Show a) =>
Stats -> (a, ByteString) -> Either String Stats
f forall a. Default a => a
def forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> [(ByteString, ByteString)]
toAssocList
where
f :: Stats -> (a, ByteString) -> Either String Stats
f Stats
a (a
"artists", ByteString
x) = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b.
(ByteString -> Maybe a) -> (a -> b) -> b -> ByteString -> b
parse forall a. (Read a, Integral a) => ByteString -> Maybe a
parseNum
(\Seconds
x' -> Stats
a { stsArtists :: Seconds
stsArtists = Seconds
x' }) Stats
a ByteString
x
f Stats
a (a
"albums", ByteString
x) = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b.
(ByteString -> Maybe a) -> (a -> b) -> b -> ByteString -> b
parse forall a. (Read a, Integral a) => ByteString -> Maybe a
parseNum
(\Seconds
x' -> Stats
a { stsAlbums :: Seconds
stsAlbums = Seconds
x' }) Stats
a ByteString
x
f Stats
a (a
"songs", ByteString
x) = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b.
(ByteString -> Maybe a) -> (a -> b) -> b -> ByteString -> b
parse forall a. (Read a, Integral a) => ByteString -> Maybe a
parseNum
(\Seconds
x' -> Stats
a { stsSongs :: Seconds
stsSongs = Seconds
x' }) Stats
a ByteString
x
f Stats
a (a
"uptime", ByteString
x) = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b.
(ByteString -> Maybe a) -> (a -> b) -> b -> ByteString -> b
parse forall a. (Read a, Integral a) => ByteString -> Maybe a
parseNum
(\Seconds
x' -> Stats
a { stsUptime :: Seconds
stsUptime = Seconds
x' }) Stats
a ByteString
x
f Stats
a (a
"playtime", ByteString
x) = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b.
(ByteString -> Maybe a) -> (a -> b) -> b -> ByteString -> b
parse forall a. (Read a, Integral a) => ByteString -> Maybe a
parseNum
(\Seconds
x' -> Stats
a { stsPlaytime :: Seconds
stsPlaytime = Seconds
x' }) Stats
a ByteString
x
f Stats
a (a
"db_playtime", ByteString
x) = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b.
(ByteString -> Maybe a) -> (a -> b) -> b -> ByteString -> b
parse forall a. (Read a, Integral a) => ByteString -> Maybe a
parseNum
(\Seconds
x' -> Stats
a { stsDbPlaytime :: Seconds
stsDbPlaytime = Seconds
x' }) Stats
a ByteString
x
f Stats
a (a
"db_update", ByteString
x) = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b.
(ByteString -> Maybe a) -> (a -> b) -> b -> ByteString -> b
parse forall a. (Read a, Integral a) => ByteString -> Maybe a
parseNum
(\Seconds
x' -> Stats
a { stsDbUpdate :: Seconds
stsDbUpdate = Seconds
x' }) Stats
a ByteString
x
f Stats
_ (a, ByteString)
x = forall a b. a -> Either a b
Left forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show (a, ByteString)
x
parseMaybeSong :: [ByteString] -> Either String (Maybe Song)
parseMaybeSong :: [ByteString] -> Either String (Maybe Song)
parseMaybeSong [ByteString]
xs | forall (t :: * -> *) a. Foldable t => t a -> Bool
null [ByteString]
xs = forall a b. b -> Either a b
Right forall a. Maybe a
Nothing
| Bool
otherwise = forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ([(ByteString, ByteString)] -> Either String Song
parseSong forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> [(ByteString, ByteString)]
toAssocList) [ByteString]
xs
parseSong :: [(ByteString, ByteString)] -> Either String Song
parseSong :: [(ByteString, ByteString)] -> Either String Song
parseSong [(ByteString, ByteString)]
xs = case [(ByteString, ByteString)]
xs of
(ByteString
"file", ByteString
path):[(ByteString, ByteString)]
ys -> forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM Song -> (ByteString, ByteString) -> Either String Song
f (Path -> Song
defaultSong (ByteString -> Path
Path ByteString
path)) [(ByteString, ByteString)]
ys
[(ByteString, ByteString)]
_ -> forall a b. a -> Either a b
Left String
"Got a song without a file path! This indicates a bug in either libmpd-haskell or MPD itself!"
where
f :: Song -> (ByteString, ByteString) -> Either String Song
f :: Song -> (ByteString, ByteString) -> Either String Song
f Song
s (ByteString
"Last-Modified", ByteString
v) =
forall (m :: * -> *) a. Monad m => a -> m a
return Song
s { sgLastModified :: Maybe UTCTime
sgLastModified = forall t. ParseTime t => ByteString -> Maybe t
parseIso8601 ByteString
v }
f Song
s (ByteString
"Time", ByteString
v) =
forall (m :: * -> *) a. Monad m => a -> m a
return Song
s { sgLength :: Seconds
sgLength = forall a. a -> Maybe a -> a
fromMaybe Seconds
0 forall a b. (a -> b) -> a -> b
$ forall a. (Read a, Integral a) => ByteString -> Maybe a
parseNum ByteString
v }
f Song
s (ByteString
"Id", ByteString
v) =
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b.
(ByteString -> Maybe a) -> (a -> b) -> b -> ByteString -> b
parse forall a. (Read a, Integral a) => ByteString -> Maybe a
parseNum (\Int
v' -> Song
s { sgId :: Maybe Id
sgId = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Int -> Id
Id Int
v' }) Song
s ByteString
v
f Song
s (ByteString
"Pos", ByteString
v) =
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b.
(ByteString -> Maybe a) -> (a -> b) -> b -> ByteString -> b
parse forall a. (Read a, Integral a) => ByteString -> Maybe a
parseNum
(\Int
v' -> Song
s { sgIndex :: Maybe Int
sgIndex = forall a. a -> Maybe a
Just Int
v' }) Song
s ByteString
v)
(forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return Song
s)
(Song -> Maybe Int
sgIndex Song
s)
f Song
s (ByteString
k, ByteString
v) = forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b a. b -> (a -> b) -> Maybe a -> b
maybe Song
s (\Metadata
m -> Metadata -> Value -> Song -> Song
sgAddTag Metadata
m (ByteString -> Value
Value ByteString
v) Song
s) forall a b. (a -> b) -> a -> b
$
forall {a}. (Eq a, IsString a) => a -> Maybe Metadata
readMeta ByteString
k
readMeta :: a -> Maybe Metadata
readMeta a
"Artist" = forall a. a -> Maybe a
Just Metadata
Artist
readMeta a
"ArtistSort" = forall a. a -> Maybe a
Just Metadata
ArtistSort
readMeta a
"Album" = forall a. a -> Maybe a
Just Metadata
Album
readMeta a
"AlbumSort" = forall a. a -> Maybe a
Just Metadata
AlbumSort
readMeta a
"AlbumArtist" = forall a. a -> Maybe a
Just Metadata
AlbumArtist
readMeta a
"AlbumArtistSort" = forall a. a -> Maybe a
Just Metadata
AlbumArtistSort
readMeta a
"Title" = forall a. a -> Maybe a
Just Metadata
Title
readMeta a
"Track" = forall a. a -> Maybe a
Just Metadata
Track
readMeta a
"Name" = forall a. a -> Maybe a
Just Metadata
Name
readMeta a
"Genre" = forall a. a -> Maybe a
Just Metadata
Genre
readMeta a
"Date" = forall a. a -> Maybe a
Just Metadata
Date
readMeta a
"OriginalDate" = forall a. a -> Maybe a
Just Metadata
OriginalDate
readMeta a
"Composer" = forall a. a -> Maybe a
Just Metadata
Composer
readMeta a
"Performer" = forall a. a -> Maybe a
Just Metadata
Performer
readMeta a
"Conductor" = forall a. a -> Maybe a
Just Metadata
Conductor
readMeta a
"Work" = forall a. a -> Maybe a
Just Metadata
Work
readMeta a
"Grouping" = forall a. a -> Maybe a
Just Metadata
Grouping
readMeta a
"Comment" = forall a. a -> Maybe a
Just Metadata
Comment
readMeta a
"Disc" = forall a. a -> Maybe a
Just Metadata
Disc
readMeta a
"Label" = forall a. a -> Maybe a
Just Metadata
Label
readMeta a
"MUSICBRAINZ_ARTISTID" = forall a. a -> Maybe a
Just Metadata
MUSICBRAINZ_ARTISTID
readMeta a
"MUSICBRAINZ_ALBUMID" = forall a. a -> Maybe a
Just Metadata
MUSICBRAINZ_ALBUMID
readMeta a
"MUSICBRAINZ_ALBUMARTISTID" = forall a. a -> Maybe a
Just Metadata
MUSICBRAINZ_ALBUMARTISTID
readMeta a
"MUSICBRAINZ_TRACKID" = forall a. a -> Maybe a
Just Metadata
MUSICBRAINZ_TRACKID
readMeta a
"MUSICBRAINZ_RELEASETRACKID" = forall a. a -> Maybe a
Just Metadata
MUSICBRAINZ_RELEASETRACKID
readMeta a
"MUSICBRAINZ_WORKID" = forall a. a -> Maybe a
Just Metadata
MUSICBRAINZ_WORKID
readMeta a
_ = forall a. Maybe a
Nothing
parse :: (ByteString -> Maybe a) -> (a -> b) -> b -> ByteString -> b
parse :: forall a b.
(ByteString -> Maybe a) -> (a -> b) -> b -> ByteString -> b
parse ByteString -> Maybe a
parser a -> b
f b
x = forall b a. b -> (a -> b) -> Maybe a -> b
maybe b
x a -> b
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Maybe a
parser
pair :: (ByteString -> Maybe a) -> (ByteString, ByteString) -> Maybe (a, a)
pair :: forall a.
(ByteString -> Maybe a) -> (ByteString, ByteString) -> Maybe (a, a)
pair ByteString -> Maybe a
p (ByteString
x, ByteString
y) = case (ByteString -> Maybe a
p ByteString
x, ByteString -> Maybe a
p ByteString
y) of
(Just a
a, Just a
b) -> forall a. a -> Maybe a
Just (a
a, a
b)
(Maybe a, Maybe a)
_ -> forall a. Maybe a
Nothing