packages feed

libmpd 0.9.3.0 → 0.10.0.0

raw patch · 18 files changed

+227/−131 lines, 18 filesdep ~hspec

Dependency ranges changed: hspec

Files

README.md view
@@ -5,7 +5,7 @@  ## About libmpd-haskell is a pure [Haskell] client library for [MPD], the-music playing daemon.+music playing daemon. Requires MPD version 0.19 or later.  [MPD]: http://www.musicpd.org [Haskell]: http://www.haskell.org
changelog.md view
@@ -1,3 +1,18 @@+* v0.10.0.0 2021-01-25+    - Require MPD version 0.19 or later.+    - Breaking: `list` now takes a `Query` instead of a `Maybe Artist`, and lists the requested tag of songs matching the query.+      Migrate by changing `list $Tag Nothing` to `list $Tag mempty` and `list Album (Just "someone")` to `list Album (Artist =? "someone")`.+    - Breaking: song ranges now expressed with the `Range` datatype rather than `(Position,Position)`, allowing for partial ranges (see documentation).+      Migrate by changing `(x,y)` to `Range x y`.+    - Breaking: add missing `Metadata` constructors: `AlbumSort`, `OriginalDate`, `Conductor`, `Work`, `Grouping`, `Label`, `MUSICBRAINZ_WORKID`.+    - Breaking: add missing `Subsystem` constructors: `PartitionS`, `NeighborS`, `MountS`.+    - Breaking: add missing `ReplayGainMode` constructor: `AutoMode`.+    - Breaking: move `toggle` from `N.M.C.Extensions` to `N.M.(C|A).PlaybackControl`.+    - Fix: `idle` now properly detects the following subsystems: `PartitionS`, `StickerS`, `SubscriptionS`, `MessageS`, `NeighborS`, `MountS`.+    - Remove deprecated functions: `(<&>)` (use `<>` instead), `updateId`, `addList`, `playlistAddList`.+    - Add monadic versions of `searchAdd` and `searchAddPl` commands (previously only had applicative versions)+    - Fix: The server setting "single: oneshot" now sets `stSingle` to `True` rather than erroring out.+ * v0.9.3.0 2021-01-02     - Drop support for GHC < 8.4, require base > 4.11.     - Bump `cabal-version` to 2.4.
libmpd.cabal view
@@ -1,6 +1,6 @@ Cabal-Version:      2.4 Name:               libmpd-Version:            0.9.3.0+Version:            0.10.0.0 Synopsis:           An MPD client library. Description:        A client library for MPD, the Music Player Daemon. Category:           Network, Sound@@ -20,7 +20,7 @@ Homepage:           http://github.com/vimus/libmpd-haskell#readme Bug-reports:        http://github.com/vimus/libmpd-haskell/issues -Tested-With:        GHC ==8.4.4, GHC==8.6.5, GHC==8.8.4, GHC==8.10.2+Tested-With:        GHC ==8.4.4, GHC==8.6.5, GHC==8.8.4, GHC==8.10.3 Build-Type:         Simple  Extra-Source-Files:@@ -126,4 +126,6 @@         -- Test dependencies       , unix       , QuickCheck >= 2.10-      , hspec >= 1.3+      , hspec >= 2+    build-tool-depends:+      hspec-discover:hspec-discover
src/Network/MPD/Applicative/CurrentPlaylist.hs view
@@ -72,7 +72,9 @@ delete pos = Command emptyResponse ["delete" <@> pos]  -- | Delete a range of songs from the playlist.-deleteRange :: (Position, Position) -> Command ()+--+-- @since 0.10.0.0+deleteRange :: Range -> Command () deleteRange range = Command emptyResponse ["delete" <@> range]  -- | Delete song by id.@@ -84,7 +86,9 @@ move pos to = Command emptyResponse ["move" <@> pos <++> to]  -- | Move a range of songs.-moveRange :: (Position, Position) -> Position -> Command ()+--+-- @since 0.10.0.0+moveRange :: Range -> Position -> Command () moveRange range to = Command emptyResponse ["move" <@> range <++> to]  -- | Move song id to position.@@ -109,7 +113,9 @@  -- | Like 'playlistInfo' but can restrict listing to a range -- of songs.-playlistInfoRange :: Maybe (Position, Position) -> Command [Song]+--+-- @since 0.10.0.0+playlistInfoRange :: Maybe Range -> Command [Song] playlistInfoRange = playlist' "playlistinfo"  -- | Get song metadata for all items in the current playlist.@@ -140,7 +146,9 @@              | otherwise = Left ""  -- | Set the priority of the specified songs.-prio :: Priority -> (Position, Position) -> Command ()+--+-- @since 0.10.0.0+prio :: Priority -> Range -> Command () prio p range = Command emptyResponse ["prio" <@> p <++> range]  -- | Set priority by song id.@@ -149,7 +157,9 @@  -- | Shuffle the current playlist. -- Optionally restrict to a range of songs.-shuffle :: Maybe (Position, Position) -> Command ()+--+-- @since 0.10.0.0+shuffle :: Maybe Range -> Command () shuffle mbRange = Command emptyResponse ["shuffle" <@> mbRange]  -- | Swap songs by position.@@ -170,6 +180,8 @@  -- | Specify portion of song that shall be played. -- Both ends of the range are optional; omitting both plays everything.+--+-- Since MPD 0.19. rangeId :: Id -> (Maybe Double, Maybe Double) -> Command () rangeId id' (mbStart, mbEnd) = Command emptyResponse ["rangeid " ++ show id' ++ " " ++ arg ]   where arg = maybe "" show mbStart ++ ":" ++ maybe "" show mbEnd
src/Network/MPD/Applicative/Database.hs view
@@ -12,7 +12,21 @@ The music database. -} -module Network.MPD.Applicative.Database where+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)@@ -39,18 +53,14 @@ findAdd :: Query -> Command () findAdd q = Command emptyResponse ["findadd" <@> q] --- | Lists all tags of the specified type.+-- | List all tags of the specified type of songs that that satisfy the query. ----- Note that the optional artist value is only ever used if the--- metadata type is 'Album', and is then taken to mean that the albums--- by that artist be listed.-list :: Metadata -> Maybe Artist -> Command [Value]+-- @since 0.10.0.0+list :: Metadata -> Query -> Command [Value] list m q = Command p c     where         p = map Value . takeValues <$> getResponse-        c = case m of-                Album -> ["list Album" <@> q]-                _     -> ["list" <@> m]+        c = ["list" <@> m <++> q]  -- | List all songs and directories in a database path. listAll :: Path -> Command [Path]@@ -80,7 +90,7 @@ readComments uri = Command p ["readcomments" <@> uri]   where p = map decodePair . toAssocList <$> getResponse --- | Like 'find' but with inexact matching.+-- | Like 'find' but with case insensitive matching. search :: Query -> Command [Song] search q = Command p ["search" <@> q]     where@@ -88,14 +98,10 @@         p = liftParser takeSongs  -- | Like 'search' but adds the results to the current playlist.------ Since MPD 0.17. searchAdd :: Query -> Command () searchAdd q = Command emptyResponse ["searchadd" <@> q]  -- | Like 'searchAdd' but adds results to the named playlist.------ Since MPD 0.17. searchAddPl :: PlaylistName -> Query -> Command () searchAddPl pl q = Command emptyResponse ["searchaddpl" <@> pl <++> q] 
src/Network/MPD/Applicative/PlaybackControl.hs view
@@ -15,6 +15,7 @@ module Network.MPD.Applicative.PlaybackControl     ( next     , pause+    , toggle     , play     , playId     , previous@@ -32,9 +33,16 @@ next :: Command () next = Command emptyResponse ["next"] --- | Toggle pause.+-- | Pauses playback on True, resumes on False. pause :: Bool -> Command () pause f = Command emptyResponse ["pause" <@> f]++-- | Toggles playback.+--+-- @since 0.10.0.0+toggle :: Command ()+toggle = Command emptyResponse ["pause"]+  -- | Begin playback (optionally at a specific position). play :: Maybe Position -> Command ()
src/Network/MPD/Applicative/Status.hs view
@@ -54,6 +54,12 @@                 "mixer"           -> Right MixerS                 "output"          -> Right OutputS                 "options"         -> Right OptionsS+                "partition"       -> Right PartitionS+                "sticker"         -> Right StickerS+                "subscription"    -> Right SubscriptionS+                "message"         -> Right MessageS+                "neighbor"        -> Right NeighborS+                "mount"           -> Right MountS                 k                 -> Left ("Unknown subsystem: " ++ UTF8.toString k)         f x                       =  Left ("idle: Unexpected " ++ show x) @@ -82,36 +88,37 @@     parseStatus = foldM go def . toAssocList         where             go a p@(k, v) = case k of-                "volume"         -> vol   $ \x -> a { stVolume          = x }-                "repeat"         -> bool  $ \x -> a { stRepeat          = x }-                "random"         -> bool  $ \x -> a { stRandom          = x }-                "single"         -> bool  $ \x -> a { stSingle          = x }-                "consume"        -> bool  $ \x -> a { stConsume         = x }-                "playlist"       -> num   $ \x -> a { stPlaylistVersion = x }-                "playlistlength" -> num   $ \x -> a { stPlaylistLength  = x }-                "state"          -> state $ \x -> a { stState           = x }-                "song"           -> int   $ \x -> a { stSongPos         = Just x }-                "songid"         -> int   $ \x -> a { stSongID          = Just $ Id x }-                "nextsong"       -> int   $ \x -> a { stNextSongPos     = Just x }-                "nextsongid"     -> int   $ \x -> a { stNextSongID      = Just $ Id x }-                "time"           -> time  $ \x -> a { stTime            = Just x }-                "elapsed"        -> frac  $ \x -> a { stTime            = fmap ((x,) . snd) (stTime a) }-                "duration"       -> frac  $ \x -> a { stTime            = fmap ((,x) . fst) (stTime a) }-                "bitrate"        -> int   $ \x -> a { stBitrate         = Just x }-                "xfade"          -> num   $ \x -> a { stXFadeWidth      = x }-                "mixrampdb"      -> frac  $ \x -> a { stMixRampdB       = x }-                "mixrampdelay"   -> frac  $ \x -> a { stMixRampDelay    = x }-                "audio"          -> audio $ \x -> a { stAudio           = x }-                "updating_db"    -> num   $ \x -> a { stUpdatingDb      = Just x }-                "error"          -> Right         a { stError           = Just (UTF8.toString v) }-                "partition"      -> Right a { stPartition = UTF8.toString v }-                _                -> Right a+                "volume"         -> vol    $ \x -> a { stVolume          = x }+                "repeat"         -> bool   $ \x -> a { stRepeat          = x }+                "random"         -> bool   $ \x -> a { stRandom          = x }+                "single"         -> single $ \x -> a { stSingle          = x }+                "consume"        -> bool   $ \x -> a { stConsume         = x }+                "playlist"       -> num    $ \x -> a { stPlaylistVersion = x }+                "playlistlength" -> num    $ \x -> a { stPlaylistLength  = x }+                "state"          -> state  $ \x -> a { stState           = x }+                "song"           -> int    $ \x -> a { stSongPos         = Just x }+                "songid"         -> int    $ \x -> a { stSongID          = Just $ Id x }+                "nextsong"       -> int    $ \x -> a { stNextSongPos     = Just x }+                "nextsongid"     -> int    $ \x -> a { stNextSongID      = Just $ Id x }+                "time"           -> time   $ \x -> a { stTime            = Just x }+                "elapsed"        -> frac   $ \x -> a { stTime            = fmap ((x,) . snd) (stTime a) }+                "duration"       -> frac   $ \x -> a { stTime            = fmap ((,x) . fst) (stTime a) }+                "bitrate"        -> int    $ \x -> a { stBitrate         = Just x }+                "xfade"          -> num    $ \x -> a { stXFadeWidth      = x }+                "mixrampdb"      -> frac   $ \x -> a { stMixRampdB       = x }+                "mixrampdelay"   -> frac   $ \x -> a { stMixRampDelay    = x }+                "audio"          -> audio  $ \x -> a { stAudio           = x }+                "updating_db"    -> num    $ \x -> a { stUpdatingDb      = Just x }+                "error"          -> Right          a { stError           = Just (UTF8.toString v) }+                "partition"      -> Right          a { stPartition = UTF8.toString v }+                _                -> Right          a                 where                     unexpectedPair = Left ("unexpected key-value pair: " ++ show p)-                    int   f = maybe unexpectedPair (Right . f) (parseNum v :: Maybe Int)-                    num   f = maybe unexpectedPair (Right . f) (parseNum  v)-                    bool  f = maybe unexpectedPair (Right . f) (parseBool v)-                    frac  f = maybe unexpectedPair (Right . f) (parseFrac v)+                    int    f = maybe unexpectedPair (Right . f) (parseNum v :: Maybe Int)+                    num    f = maybe unexpectedPair (Right . f) (parseNum  v)+                    bool   f = maybe unexpectedPair (Right . f) (parseBool v)+                    frac   f = maybe unexpectedPair (Right . f) (parseFrac v)+                    single f = maybe unexpectedPair (Right . f) (parseSingle v)                      -- This is sometimes "audio: 0:?:0", so we ignore any parse                     -- errors.
src/Network/MPD/Commands.hs view
@@ -34,6 +34,7 @@     , Song(..)     , Priority(..)     , Position+    , Range(..)     , Volume     , Id(..)     , sgGetTag
src/Network/MPD/Commands/CurrentPlaylist.hs view
@@ -67,8 +67,8 @@  -- | Remove a range of songs from the current playlist. ----- @since 0.9.2.0-deleteRange :: MonadMPD m => (Position, Position) -> m ()+-- @since 0.10.0.0+deleteRange :: MonadMPD m => Range -> m () deleteRange = A.runCommand . A.deleteRange  -- | Remove a song from the current playlist.@@ -81,8 +81,8 @@  -- | Move a range of songs to a given position in the current playlist. ----- @since 0.9.2.0-moveRange :: MonadMPD m => (Position, Position) -> Position -> m ()+-- @since 0.10.0.0+moveRange :: MonadMPD m => Range -> Position -> m () moveRange range = A.runCommand . A.moveRange range  -- | Move a song from (songid) to (playlist index) in the playlist. If to is@@ -111,7 +111,9 @@ playlistInfo = A.runCommand . A.playlistInfo  -- | Like 'playlistInfo' but can restrict to a range of songs.-playlistInfoRange :: MonadMPD m => Maybe (Position, Position) -> m [Song]+--+-- @since 0.10.0.0+playlistInfoRange :: MonadMPD m => Maybe Range -> m [Song] playlistInfoRange = A.runCommand . A.playlistInfoRange  -- | Displays a list of songs in the playlist.@@ -134,16 +136,20 @@ plChangesPosId = A.runCommand . A.plChangesPosId  -- | Set the priority of the specified songs.-prio :: MonadMPD m => Priority -> (Position, Position) -> m ()+--+-- @since 0.10.0.0+prio :: MonadMPD m => Priority -> Range -> m () prio p = A.runCommand . A.prio p  -- | Set priority by song id. prioId :: MonadMPD m => Priority -> Id -> m () prioId p = A.runCommand . A.prioId p --- | Shuffle the playlist.-shuffle :: MonadMPD m => Maybe (Position, Position) -- ^ Optional range (start, end)-        -> m ()+-- | Shuffle the current playlist.+-- Optionally restrict to a range of songs.+--+-- @since 0.10.0.0+shuffle :: MonadMPD m => Maybe Range -> m () shuffle = A.runCommand . A.shuffle  -- | Swap the positions of two songs.
src/Network/MPD/Commands/Database.hs view
@@ -22,6 +22,8 @@     , lsInfo     , readComments     , search+    , searchAdd+    , searchAddPl     , update     , rescan     ) where@@ -44,10 +46,12 @@ findAdd :: MonadMPD m => Query -> m () findAdd = A.runCommand . A.findAdd --- | List all tags of the specified type.+-- | List all tags of the specified type of songs that that satisfy the query.+--+-- @since 0.10.0.0 list :: MonadMPD m      => Metadata -- ^ Metadata to list-     -> Maybe Artist -> m [Value]+     -> Query -> m [Value] list m = A.runCommand . A.list m  -- | List the songs (without metadata) in a database directory recursively.@@ -69,6 +73,18 @@ -- | Search the database using case insensitive matching. search :: MonadMPD m => Query -> m [Song] search = A.runCommand . A.search++-- | Like 'search' but adds the results to the current playlist.+--+-- @since 0.10.0.0+searchAdd :: MonadMPD m => Query -> m ()+searchAdd = A.runCommand . A.searchAdd++-- | Like 'searchAdd' but adds results to the named playlist.+--+-- @since 0.10.0.0+searchAddPl :: MonadMPD m => PlaylistName -> Query -> m ()+searchAddPl pl = A.runCommand . A.searchAddPl pl  -- | Update the server's database. --
src/Network/MPD/Commands/Extensions.hs view
@@ -24,16 +24,6 @@ import           Data.Traversable (for) import           Data.Foldable (for_) --- | This is exactly the same as `update`.-updateId :: MonadMPD m => Maybe Path -> m Integer-updateId = update-{-# DEPRECATED updateId "use `update` instead" #-}---- | Toggles play\/pause. Plays if stopped.-toggle :: MonadMPD m => m ()-toggle = status >>= \st -> case stState st of Playing -> pause True-                                              _       -> play Nothing- -- | Add a list of songs\/folders to a playlist. -- Should be more efficient than running 'add' many times. addMany :: MonadMPD m => PlaylistName -> [Path] -> m ()@@ -53,16 +43,6 @@     fs <- listAll x     A.runCommand $ for fs (`A.addId` Nothing) --- | Like 'add' but returns a list of the files added.-addList :: MonadMPD m => Path -> m [Path]-addList x = add x >> listAll x-{-# DEPRECATED addList "will be removed in a future version" #-}---- | Like 'playlistAdd' but returns a list of the files added.-playlistAddList :: MonadMPD m => PlaylistName -> Path -> m [Path]-playlistAddList plname path = playlistAdd plname path >> listAll path-{-# DEPRECATED playlistAddList "will be removed in a future version" #-}- {- -- | Returns all songs and directories that match the given partial -- path name.@@ -79,12 +59,14 @@  -- | List the artists in the database. listArtists :: MonadMPD m => m [Artist]-listArtists = list Artist Nothing+listArtists = list Artist mempty  -- | List the albums in the database, optionally matching a given -- artist. listAlbums :: MonadMPD m => Maybe Artist -> m [Album]-listAlbums = list Album+listAlbums ma = list Album (case ma of+                              Nothing -> mempty+                              Just a -> Artist =? a)  -- | List the songs in an album of some artist. listAlbum :: MonadMPD m => Artist -> Album -> m [Song]
src/Network/MPD/Commands/Parse.hs view
@@ -89,25 +89,32 @@                      readMeta k          -- Custom-made Read instance-        readMeta "ArtistSort" = Just ArtistSort         readMeta "Artist" = Just Artist+        readMeta "ArtistSort" = Just ArtistSort         readMeta "Album" = Just Album+        readMeta "AlbumSort" = Just AlbumSort         readMeta "AlbumArtist" = Just AlbumArtist         readMeta "AlbumArtistSort" = Just AlbumArtistSort         readMeta "Title" = Just Title-        readMeta "Genre" = Just Genre+        readMeta "Track" = Just Track         readMeta "Name" = Just Name+        readMeta "Genre" = Just Genre+        readMeta "Date" = Just Date+        readMeta "OriginalDate" = Just OriginalDate         readMeta "Composer" = Just Composer         readMeta "Performer" = Just Performer+        readMeta "Conductor" = Just Conductor+        readMeta "Work" = Just Work+        readMeta "Grouping" = Just Grouping         readMeta "Comment" = Just Comment-        readMeta "Date" = Just Date-        readMeta "Track" = Just Track         readMeta "Disc" = Just Disc+        readMeta "Label" = Just Label         readMeta "MUSICBRAINZ_ARTISTID" = Just MUSICBRAINZ_ARTISTID         readMeta "MUSICBRAINZ_ALBUMID" = Just MUSICBRAINZ_ALBUMID         readMeta "MUSICBRAINZ_ALBUMARTISTID" = Just MUSICBRAINZ_ALBUMARTISTID         readMeta "MUSICBRAINZ_TRACKID" = Just MUSICBRAINZ_TRACKID         readMeta "MUSICBRAINZ_RELEASETRACKID" = Just MUSICBRAINZ_RELEASETRACKID+        readMeta "MUSICBRAINZ_WORKID" = Just MUSICBRAINZ_WORKID         readMeta _ = Nothing  -- | A helper that runs a parser on a string and, depending on the
src/Network/MPD/Commands/PlaybackControl.hs view
@@ -15,6 +15,7 @@ module Network.MPD.Commands.PlaybackControl     ( next     , pause+    , toggle     , play     , playId     , previous@@ -33,9 +34,15 @@ next :: MonadMPD m => m () next = A.runCommand A.next --- | Pause playing.+-- | Pauses playback on True, resumes on False. pause :: MonadMPD m => Bool -> m () pause = A.runCommand . A.pause++-- | Toggles play\/pause. Plays if stopped.+--+-- @since 0.10.0.0+toggle :: MonadMPD m => m ()+toggle = A.runCommand A.toggle  -- | Begin\/continue playing. play :: MonadMPD m => Maybe Position -> m ()
src/Network/MPD/Commands/Query.hs view
@@ -10,7 +10,7 @@ Query interface. -} -module Network.MPD.Commands.Query (Query, (=?) ,(/=?), (%?), (~?), (/~?), qNot, qModSince, qFile, qBase, (<&>), anything) where+module Network.MPD.Commands.Query (Query, (=?) ,(/=?), (%?), (~?), (/~?), qNot, qModSince, qFile, qBase, anything) where  import           Network.MPD.Commands.Arg import           Network.MPD.Commands.Types@@ -38,6 +38,7 @@   show (Match meta query) = show meta ++ " \"" ++ toString query ++ "\""   showList xs _ = unwords $ fmap show xs +-- A general MPD 0.21 style filter. data Expr = Exact Match           | ExactNot Match           | Contains Match@@ -102,36 +103,41 @@ m =? s = Query [Match m s]  -- | Create a query matching a tag with anything but a value.--- Requires MPD 0.21 or newer. --+-- Since MPD 0.21.+-- -- @since 0.9.3.0 (/=?) :: Metadata -> Value -> Query m /=? s = Filter (ExactNot (Match m s))  -- | Create a query for a tag containing a value.--- Requires MPD 0.21 or newer. --+-- Since MPD 0.21.+-- -- @since 0.9.3.0 (%?) :: Metadata -> Value -> Query m %? s = Filter (Contains (Match m s))  -- | Create a query matching a tag with regexp.--- Requires MPD 0.21 or newer. --+-- Since MPD 0.21.+-- -- @since 0.9.3.0 (~?) :: Metadata -> Value -> Query m ~? s = Filter (Regex (Match m s))  -- | Create a query matching a tag with anything but a regexp.--- Requires MPD 0.21 or newer. --+-- Since MPD 0.21.+-- -- @since 0.9.3.0 (/~?) :: Metadata -> Value -> Query m /~? s = Filter (RegexNot (Match m s))  -- | Negate a Query.--- Requires MPD 0.21 or newer. --+-- Since MPD 0.21.+-- -- @since 0.9.3.0 qNot :: Query -> Query qNot (Query ms) = Filter (ExprNot (toExpr ms))@@ -139,28 +145,25 @@ qNot (Filter ex) = Filter (ExprNot ex)  -- | Create a query for songs modified since a date.--- Requires MPD 0.21 or newer. --+-- Since MPD 0.21.+-- -- @since 0.9.3.0 qModSince :: UTCTime -> Query qModSince time = Filter (ModifiedSince time)  -- | Create a query for the full song URI relative to the music directory.--- Requires MPD 0.21 or newer. --+-- Since MPD 0.21.+-- -- @since 0.9.3.0 qFile :: Path -> Query qFile file = Filter (File file)  -- | Limit the query to the given directory, relative to the music directory.--- Requires MPD 0.21 or newer. --+-- Since MPD 0.21.+-- -- @since 0.9.3.0 qBase :: Path -> Query qBase dir = Filter (Base dir)---- | Combine queries.-infixr 6 <&>-(<&>) :: Query -> Query -> Query-(<&>) = mappend-{-# DEPRECATED (<&>) "will be removed in the next major version of libmpd, use `(<>)` instead" #-}
src/Network/MPD/Commands/Types.hs view
@@ -28,6 +28,7 @@     , Device(..)     , Song(..)     , Position+    , Range(..)     , Id(..)     , Priority(..)     , sgGetTag@@ -102,6 +103,7 @@ data Metadata = Artist               | ArtistSort               | Album+              | AlbumSort -- ^ @since 0.10.0.0               | AlbumArtist               | AlbumArtistSort               | Title@@ -109,15 +111,21 @@               | Name               | Genre               | Date+              | OriginalDate -- ^ @since 0.10.0.0               | Composer               | Performer+              | Conductor -- ^ @since 0.10.0.0+              | Work -- ^ @since 0.10.0.0+              | Grouping -- ^ @since 0.10.0.0               | Comment               | Disc+              | Label -- ^ @since 0.10.0.0               | MUSICBRAINZ_ARTISTID               | MUSICBRAINZ_ALBUMID               | MUSICBRAINZ_ALBUMARTISTID               | MUSICBRAINZ_TRACKID               | MUSICBRAINZ_RELEASETRACKID+              | MUSICBRAINZ_WORKID -- ^ @since 0.10.0.0               deriving (Eq, Enum, Ord, Bounded, Show)  instance MPDArg Metadata@@ -164,9 +172,18 @@     | MixerS             -- ^ The volume mixer     | OutputS            -- ^ Audio outputs     | OptionsS           -- ^ Playback options+    | PartitionS         -- ^ Partition changes+                         --+                         --  @since 0.10.0.0     | StickerS           -- ^ Sticker database     | SubscriptionS      -- ^ Subscription     | MessageS           -- ^ Message on subscribed channel+    | NeighborS          -- ^ finding or losing a neighbor+                         --+                         --  @since 0.10.0.0+    | MountS             -- ^ Mount list changes+                         --+                         --  @since 0.10.0.0       deriving (Eq, Enum, Ord, Bounded, Show)  instance MPDArg Subsystem where@@ -178,20 +195,27 @@     prep MixerS = Args ["mixer"]     prep OutputS = Args ["output"]     prep OptionsS = Args ["options"]+    prep PartitionS = Args ["partition"]     prep StickerS = Args ["sticker"]     prep SubscriptionS = Args ["subscription"]     prep MessageS = Args ["message"]+    prep NeighborS = Args ["neighbor"]+    prep MountS = Args ["mount"]  data ReplayGainMode     = Off       -- ^ Disable replay gain     | TrackMode -- ^ Per track mode     | AlbumMode -- ^ Per album mode+    | AutoMode  -- ^ Auto mode+                --+                -- @since 0.10.0.0       deriving (Eq, Enum, Ord, Bounded, Show)  instance MPDArg ReplayGainMode where     prep Off = Args ["off"]     prep TrackMode = Args ["track"]     prep AlbumMode = Args ["album"]+    prep AutoMode = Args ["auto"]  -- | Represents the result of running 'count'. data Count =@@ -246,6 +270,16 @@ -- | The position of a song in a playlist. type Position = Int +-- | A range of songs.+data Range+  = Range Position Position -- ^ Start and end of the range, not including the end position.+  | Start Position -- ^ From the given position until the end of the playlist.+  deriving (Eq, Show)++instance MPDArg Range where+    prep (Range start end) = Args [show start ++ ":" ++ show end]+    prep (Start start) = Args [show start ++ ":"]+ newtype Id = Id Int     deriving (Eq, Show) @@ -377,6 +411,7 @@              -- | Job ID of currently running update (if any).            , stUpdatingDb      :: Maybe Integer              -- | If True, MPD will play only one song and stop after finishing it.+             -- If single is set to "oneshot" by another client, it's interperted as True.            , stSingle          :: Bool              -- | If True, a song will be removed after it has been played.            , stConsume         :: Bool
src/Network/MPD/Core.hs view
@@ -155,7 +155,7 @@                 modify (\st -> st { stVersion = version })                 return True             where-                requiredVersion = (0, 15, 0)+                requiredVersion = (0, 19, 0)          parseVersion = parseTriple '.' parseNum . dropWhile (not . isDigit) 
src/Network/MPD/Util.hs view
@@ -9,7 +9,7 @@  module Network.MPD.Util (     parseDate, parseIso8601, formatIso8601, parseNum, parseFrac,-    parseBool, showBool, breakChar, parseTriple,+    parseBool, parseSingle, showBool, breakChar, parseTriple,     toAssoc, toAssocList, splitGroups, read     ) where @@ -78,6 +78,14 @@ parseBool = parseMaybe p     where         p = A.char '1' *> pure True <|> A.char '0' *> pure False++-- Parse a boolean response value.+parseSingle :: ByteString -> Maybe Bool+parseSingle = parseMaybe p+    where+        p = A.char '1' *> pure True+            <|> A.char '0' *> pure False+            <|> A.string "oneshot" *> pure True  -- Break a string into triple. parseTriple :: Char -> (ByteString -> Maybe a) -> ByteString -> Maybe (a, a, a)
tests/CommandSpec.hs view
@@ -119,9 +119,11 @@     describe "crossfade" $ do         it "sets crossfade between songs" $ testCrossfade     describe "play" $ do-        it "toggles playback" $ testPlay+        it "resumes playback" $ testPlay     describe "pause" $ do         it "pauses playback" $ testPause+    describe "toggle" $ do+        it "toggles playback" $ testToggle     describe "stop" $ do         it "stops playback" $ testStop     describe "next" $ do@@ -160,9 +162,6 @@         it "gets database stats" $ testStats      -- * Extensions-    describe "toggle" $ do-        it "starts playback if paused" $ testTogglePlay-        it "stops playback if playing" $ testToggleStop     describe "addMany" $ do         it "adds multiple paths in one go" $ testAddMany0         it "can also add to stored playlists" $ testAddMany1@@ -299,6 +298,8 @@  testPause = cmd_ [("pause 0", Right "OK")] (pause False) +testToggle = cmd_ [("pause", Right "OK")] (toggle)+ testStop = cmd_ [("stop", Right "OK")] stop  testNext = cmd_ [("next", Right "OK")] next@@ -375,26 +376,6 @@ -- -- Extensions\/shortcuts ----testTogglePlay = cmd_-               [("status", Right resp)-               ,("pause 1", Right "OK")]-               toggle-    where resp = unparse def { stState = Playing }--testToggleStop = cmd_-                [("status", Right resp)-                ,("play", Right "OK")]-                toggle-    where resp = unparse def { stState = Stopped }--{- this overlaps with testToggleStop, no?-testTogglePause = cmd_-                [("status", Right resp)-                ,("play", Right "OK")]-                toggle-    where resp = unparse def { stState = Paused }--}  testAddMany0 = cmd_ [("add \"bar\"", Right "OK")]                (addMany "" ["bar"])