libmpd-0.10.0.0: src/Network/MPD/Applicative/Database.hs
{-# LANGUAGE OverloadedStrings #-}
{- |
Module : Network.MPD.Applicative.Database
Copyright : (c) Joachim Fasting 2012
License : MIT
Maintainer : joachifm@fastmail.fm
Stability : stable
Portability : unportable
The music database.
-}
module Network.MPD.Applicative.Database
( count
, find
, findAdd
, list
, listAll
, listAllInfo
, lsInfo
, readComments
, search
, searchAdd
, searchAddPl
, update
, rescan
) where
import qualified Network.MPD.Commands.Arg as Arg
import Network.MPD.Commands.Arg hiding (Command)
import Network.MPD.Commands.Parse
import Network.MPD.Commands.Query
import Network.MPD.Util
import Network.MPD.Commands.Types
import Network.MPD.Applicative.Internal
import Network.MPD.Applicative.Util
-- | Get a count of songs and their total playtime that exactly match the
-- query.
count :: Query -> Command Count
count q = Command (liftParser parseCount) ["count" <@> q]
-- | Find songs matching the query exactly.
find :: Query -> Command [Song]
find q = Command p ["find" <@> q]
where
p :: Parser [Song]
p = liftParser takeSongs
-- | Like 'find' but adds the results to the current playlist.
findAdd :: Query -> Command ()
findAdd q = Command emptyResponse ["findadd" <@> q]
-- | List all tags of the specified type of songs that that satisfy the query.
--
-- @since 0.10.0.0
list :: Metadata -> Query -> Command [Value]
list m q = Command p c
where
p = map Value . takeValues <$> getResponse
c = ["list" <@> m <++> q]
-- | List all songs and directories in a database path.
listAll :: Path -> Command [Path]
listAll path = Command p ["listall" <@> path]
where
p :: Parser [Path]
p = map (Path . snd) . filter ((== "file") . fst)
. toAssocList <$> getResponse
-- Internal helper
lsInfo' :: Arg.Command -> Path -> Command [LsResult]
lsInfo' cmd path = Command p [cmd <@> path]
where
p :: Parser [LsResult]
p = liftParser takeEntries
-- | Same as 'listAll' but also returns metadata.
listAllInfo :: Path -> Command [LsResult]
listAllInfo = lsInfo' "listallinfo"
-- | List the contents of a database directory.
lsInfo :: Path -> Command [LsResult]
lsInfo = lsInfo' "lsinfo"
-- | Read comments from the file at the specified path.
readComments :: Path -> Command [(String, String)]
readComments uri = Command p ["readcomments" <@> uri]
where p = map decodePair . toAssocList <$> getResponse
-- | Like 'find' but with case insensitive matching.
search :: Query -> Command [Song]
search q = Command p ["search" <@> q]
where
p :: Parser [Song]
p = liftParser takeSongs
-- | Like 'search' but adds the results to the current playlist.
searchAdd :: Query -> Command ()
searchAdd q = Command emptyResponse ["searchadd" <@> q]
-- | Like 'searchAdd' but adds results to the named playlist.
searchAddPl :: PlaylistName -> Query -> Command ()
searchAddPl pl q = Command emptyResponse ["searchaddpl" <@> pl <++> q]
-- | Update the music database.
-- If no path is supplied, the entire database is updated.
update :: Maybe Path -> Command Integer
update = update_ "update"
-- | Like 'update' but also rescan unmodified files.
rescan :: Maybe Path -> Command Integer
rescan = update_ "rescan"
-- A helper for 'update' and 'rescan.
update_ :: Arg.Command -> Maybe Path -> Command Integer
update_ cmd mPath = Command p [cmd <@> mPath]
where
p :: Parser Integer
p = do
r <- getResponse
case toAssocList r of
[("updating_db", id_)] -> maybe (unexpected r)
return
(parseNum id_)
_ -> unexpected r