packages feed

libmpd 0.9.2.0 → 0.9.3.0

raw patch · 18 files changed

+146/−69 lines, 18 filesdep −old-localedep ~basedep ~mtldep ~time

Dependencies removed: old-locale

Dependency ranges changed: base, mtl, time

Files

changelog.md view
@@ -1,15 +1,23 @@-* v0.9.2.0+* v0.9.3.0 2021-01-02+    - Drop support for GHC < 8.4, require base > 4.11.+    - Bump `cabal-version` to 2.4.+    - Add `Ord` instance for `PlaylistName`, `Path`, and `Value`+    - Add support for MPD 0.21 style filters to the `Query` type,+      see [Filters](https://www.musicpd.org/doc/html/protocol.html#filters) in the MPD protocol documentation. +      Implemented through the added combinators `/=?`, `%?`, `~?`, `/~?`, `qNot`, `qModSince`, `qFile`, `qBase`.+    +* v0.9.2.0 2020-10-02     - New command: `seekCur`     - Add `newtype Sign` to pass positive numbers to `MPDArg` with leading `+/-`.     - Add monadic versions of `deleteRange` and `moveRange` commands (previously       only had applicative versions)     - Deprecate `<&>`, use `<>` instead. `<&>` will be removed in the next major version. -* v0.9.1.0+* v0.9.1.0 2020-01-27     - Support partition in Network.MPD.Status     - Ignore unknown key-value pairs in Network.MPD.status so that it breaks much less often. -* v0.9.0.10+* v0.9.0.10 2019-10-06     - Port it for newer network library  * v0.9.0, 2014-09-21
libmpd.cabal view
@@ -1,5 +1,6 @@+Cabal-Version:      2.4 Name:               libmpd-Version:            0.9.2.0+Version:            0.9.3.0 Synopsis:           An MPD client library. Description:        A client library for MPD, the Music Player Daemon. Category:           Network, Sound@@ -19,9 +20,8 @@ Homepage:           http://github.com/vimus/libmpd-haskell#readme Bug-reports:        http://github.com/vimus/libmpd-haskell/issues -Tested-With:        GHC ==8.0.1, GHC==8.2.2, GHC==8.4.3, GHC==8.6.1+Tested-With:        GHC ==8.4.4, GHC==8.6.5, GHC==8.8.4, GHC==8.10.2 Build-Type:         Simple-Cabal-Version:      >= 1.10  Extra-Source-Files:     README.md@@ -39,14 +39,14 @@      Build-Depends:         -- Platform dependencies-        base >= 4.9 && < 5+        base >= 4.11 && < 5       , attoparsec >= 0.10.1 && < 1       , bytestring >= 0.9 && < 1       , containers >= 0.3 && < 1       , filepath >= 1 && < 2-      , mtl >= 2.0 && < 3-      , old-locale >= 1 && < 2+      , mtl >= 2.2.2 && < 3       , text >= 0.11 && < 2+      , time >= 1.5 && < 2          -- Additional dependencies       , data-default-class >= 0.0.1 && < 1@@ -54,13 +54,6 @@       , safe-exceptions >= 0.1 && < 0.2       , utf8-string >= 0.3.1 && < 1.1 -    if impl(ghc >= 7.10.0)-        Build-Depends:-            time >= 1.5-    else-        Build-Depends:-            time >= 1.1 && <1.5-     Exposed-Modules:         Network.MPD       , Network.MPD.Applicative@@ -121,7 +114,6 @@       , containers       , filepath       , mtl-      , old-locale       , text       , time 
src/Network/MPD/Applicative/ClientToClient.hs view
@@ -25,8 +25,6 @@     , sendMessage     ) where -import           Control.Applicative- import           Network.MPD.Commands.Arg hiding (Command) import           Network.MPD.Applicative.Internal import           Network.MPD.Applicative.Util
src/Network/MPD/Applicative/Database.hs view
@@ -14,8 +14,6 @@  module Network.MPD.Applicative.Database where -import           Control.Applicative- import qualified Network.MPD.Commands.Arg as Arg import           Network.MPD.Commands.Arg hiding (Command) import           Network.MPD.Commands.Parse
src/Network/MPD/Applicative/Internal.hs view
@@ -1,7 +1,6 @@ {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TupleSections #-}-{-# LANGUAGE CPP #-}  {- | Module      : Network.MPD.Applicative.Internal@@ -32,13 +31,12 @@     , runCommand     ) where -import           Control.Applicative import           Control.Monad import           Data.ByteString.Char8 (ByteString)  import           Network.MPD.Core hiding (getResponse) import qualified Network.MPD.Core as Core-import           Control.Monad.Error+import           Control.Monad.Except import qualified Control.Monad.Fail as Fail  -- | A line-oriented parser that returns a value along with any remaining input.
src/Network/MPD/Applicative/Stickers.hs view
@@ -26,8 +26,6 @@ import           Network.MPD.Commands.Types import           Network.MPD.Util -import           Control.Applicative- import qualified Data.ByteString.UTF8 as UTF8  -- | Read sticker value for the object specified.
src/Network/MPD/Applicative/StoredPlaylists.hs view
@@ -32,8 +32,6 @@ import           Network.MPD.Commands.Types import           Network.MPD.Util -import           Control.Applicative- -- | List song items in the playlist. listPlaylist :: PlaylistName -> Command [Path] listPlaylist plName = Command p ["listplaylist" <@> plName]
src/Network/MPD/Commands/CurrentPlaylist.hs view
@@ -47,7 +47,7 @@ import           Network.MPD.Core import           Network.MPD.Util -import           Control.Monad.Error (throwError)+import           Control.Monad.Except (throwError)  -- | Like 'add', but returns a playlist id. addId :: MonadMPD m => Path -> Maybe Position -> m Id
src/Network/MPD/Commands/Extensions.hs view
@@ -23,7 +23,6 @@ import           Control.Monad (liftM) import           Data.Traversable (for) import           Data.Foldable (for_)-import           Data.Semigroup ((<>))  -- | This is exactly the same as `update`. updateId :: MonadMPD m => Maybe Path -> m Integer
src/Network/MPD/Commands/Parse.hs view
@@ -12,8 +12,7 @@  import           Network.MPD.Commands.Types -import           Control.Applicative-import           Control.Monad.Error+import           Control.Monad.Except import           Data.Maybe (fromMaybe)  import           Network.MPD.Util
src/Network/MPD/Commands/Query.hs view
@@ -10,13 +10,11 @@ Query interface. -} -module Network.MPD.Commands.Query (Query, (=?), (<&>), anything) where+module Network.MPD.Commands.Query (Query, (=?) ,(/=?), (%?), (~?), (/~?), qNot, qModSince, qFile, qBase, (<&>), anything) where  import           Network.MPD.Commands.Arg import           Network.MPD.Commands.Types--import           Data.Monoid-import           Data.Semigroup+import           Data.Time (UTCTime,formatTime,defaultTimeLocale)  -- | An interface for creating MPD queries. --@@ -30,33 +28,136 @@ -- is \"Bar\", we use: -- -- > Artist =? "Foo" <> Album =? "Bar"-newtype Query = Query [Match] deriving Show+data Query = Query [Match] | Filter Expr+  deriving Show  -- A single query clause, comprising a metadata key and a desired value. data Match = Match Metadata Value  instance Show Match where-    show (Match meta query) = show meta ++ " \"" ++ toString query ++ "\""-    showList xs _ = unwords $ map show xs+  show (Match meta query) = show meta ++ " \"" ++ toString query ++ "\""+  showList xs _ = unwords $ fmap show xs +data Expr = Exact Match+          | ExactNot Match+          | Contains Match+          | Regex Match+          | RegexNot Match+          | File Path+          | Base Path+          | ModifiedSince UTCTime+          | ExprNot Expr+          | ExprAnd Expr Expr+          | ExprEmpty+instance Show Expr where+ show (Exact (Match meta query)) = "(" ++ show meta ++ " == " +++                                   "\\\"" ++ toString query ++ "\\\"" ++ ")"+ show (ExactNot (Match meta query)) = "(" ++ show meta ++ " != " +++                                   "\\\"" ++ toString query ++ "\\\"" ++ ")"+ show (Contains (Match meta query)) = "(" ++ show meta ++ " contains " +++                                   "\\\"" ++ toString query ++ "\\\"" ++ ")"+ show (Regex (Match meta query)) = "(" ++ show meta ++ " =~ " +++                                   "\\\"" ++ toString query ++ "\\\"" ++ ")"+ show (RegexNot (Match meta query)) = "(" ++ show meta ++ " !~ " +++                                   "\\\"" ++ toString query ++ "\\\"" ++ ")"+ show (File file) = "(file == " ++ "\\\"" ++ toString file ++ "\\\"" ++ ")"+ show (Base dir) = "(base " ++ "\\\"" ++ toString dir ++ "\\\"" ++ ")"+ show (ModifiedSince time) = "(modified-since " ++  "\\\"" +++                           formatTime defaultTimeLocale "%Y-%m-%dT%H:%M:%SZ" time +++                           "\\\"" ++ ")"+ show (ExprNot expr) = "(!" ++ show expr ++ ")"+ show (ExprAnd e1 e2) = "(" ++ show e1 ++ " AND " ++ show e2 ++ ")"+ show ExprEmpty = ""++toExpr :: [Match] -> Expr+toExpr [] = ExprEmpty+toExpr (m:[]) = Exact m+toExpr (m:ms) = ExprAnd (Exact m) (toExpr ms)+ instance Monoid Query where     mempty  = Query []-    Query a `mappend` Query b = Query (a ++ b)+    Query  a  `mappend` Query    b  = Query (a ++ b)+    Query  [] `mappend` Filter   b  = Filter b+    Filter a  `mappend` Query    [] = Filter a+    Query  a  `mappend` Filter   b  = Filter (ExprAnd (toExpr a) b)+    Filter a  `mappend` Query    b  = Filter (ExprAnd a (toExpr b))+    Filter a  `mappend` Filter   b  = Filter (a <> b)  instance Semigroup Query where     (<>) = mappend+instance Semigroup Expr where+  ex1 <> ex2 = ExprAnd ex1 ex2  instance MPDArg Query where-    prep = foldl (<++>) (Args []) . f-        where f (Query ms) = map (\(Match m q) -> Args [show m] <++> q) ms+    prep (Query ms) = foldl (<++>) (Args [])+                        (fmap (\(Match m q) -> Args [show m] <++> q) ms)+    prep (Filter expr) = Args ["\"" ++ show expr ++ "\""]  -- | An empty query. Matches anything. anything :: Query anything = mempty --- | Create a query.+-- | Create a query matching a tag with a value. (=?) :: Metadata -> Value -> Query m =? s = Query [Match m s]++-- | Create a query matching a tag with anything but a value.+-- Requires MPD 0.21 or newer.+--+-- @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 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 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 0.9.3.0+(/~?) :: Metadata -> Value -> Query+m /~? s = Filter (RegexNot (Match m s))++-- | Negate a Query.+-- Requires MPD 0.21 or newer.+--+-- @since 0.9.3.0+qNot :: Query -> Query+qNot (Query ms) = Filter (ExprNot (toExpr ms))+qNot (Filter (ExprNot ex)) = Filter ex+qNot (Filter ex) = Filter (ExprNot ex)++-- | Create a query for songs modified since a date.+-- Requires MPD 0.21 or newer.+--+-- @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 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 0.9.3.0+qBase :: Path -> Query+qBase dir = Filter (Base dir)  -- | Combine queries. infixr 6 <&>
src/Network/MPD/Commands/Types.hs view
@@ -74,7 +74,7 @@ -- | Used for commands which require a playlist name. -- If empty, the current playlist is used. newtype PlaylistName = PlaylistName ByteString-  deriving (Eq, Show, MPDArg)+  deriving (Eq, Show, Ord, MPDArg)  instance ToString PlaylistName where   toString (PlaylistName x) = UTF8.toString x@@ -87,7 +87,7 @@ -- | Used for commands which require a path within the database. -- If empty, the root path is used. newtype Path = Path ByteString-  deriving (Eq, Show, MPDArg)+  deriving (Eq, Show, Ord, MPDArg)  instance ToString Path where   toString (Path x) = UTF8.toString x@@ -124,7 +124,7 @@  -- | A metadata value. newtype Value = Value ByteString-  deriving (Eq, Show, MPDArg)+  deriving (Eq, Show, Ord, MPDArg)  instance ToString Value where   toString (Value x) = UTF8.toString x
src/Network/MPD/Core.hs view
@@ -26,11 +26,10 @@ import           Network.MPD.Core.Error  import           Data.Char (isDigit)-import           Control.Applicative (Applicative(..), (<$>), (<*)) import qualified Control.Exception as E import           Control.Exception.Safe (catch, catchAny) import           Control.Monad (ap, unless)-import           Control.Monad.Error (ErrorT(..), MonadError(..))+import           Control.Monad.Except (ExceptT(..),runExceptT, MonadError(..)) import           Control.Monad.Reader (ReaderT(..), ask) import           Control.Monad.State (StateT, MonadIO(..), modify, gets, evalStateT) import qualified Data.Foldable as F@@ -76,14 +75,14 @@ -- -- To use the error throwing\/catching capabilities: ----- > import Control.Monad.Error (throwError, catchError)+-- > import Control.Monad.Except (throwError, catchError) -- -- To run IO actions within the MPD monad: -- -- > import Control.Monad.Trans (liftIO)  newtype MPD a =-    MPD { runMPD :: ErrorT MPDError+    MPD { runMPD :: ExceptT MPDError                     (StateT MPDState                      (ReaderT (Host, Port) IO)) a         } deriving (Functor, Monad, MonadIO, MonadError MPDError)@@ -113,7 +112,7 @@ -- | The most configurable API for running an MPD action. withMPDEx :: Host -> Port -> Password -> MPD a -> IO (Response a) withMPDEx host port pw x = withSocketsDo $-    runReaderT (evalStateT (runErrorT . runMPD $ open >> (x <* close)) initState)+    runReaderT (evalStateT (runExceptT . runMPD $ open >> (x <* close)) initState)                (host, port)     where initState = MPDState Nothing pw (0, 0, 0) 
src/Network/MPD/Core/Class.hs view
@@ -14,7 +14,7 @@  import           Network.MPD.Core.Error (MPDError) -import           Control.Monad.Error (MonadError)+import           Control.Monad.Except (MonadError)  type Password = String 
src/Network/MPD/Core/Error.hs view
@@ -15,7 +15,6 @@ module Network.MPD.Core.Error where  import qualified Control.Exception as E-import           Control.Monad.Error (Error(..)) import           Data.Typeable  -- | The MPDError type is used to signal errors, both from the MPD and@@ -44,10 +43,6 @@                           ]     show (Custom s)     = s     show (ACK _ s)      = s--instance Error MPDError where-    noMsg  = Custom "An error occurred"-    strMsg = Custom  -- | Represents various MPD errors (aka. ACKs). data ACKType = InvalidArgument  -- ^ Invalid argument passed (ACK 2)
src/Network/MPD/Util.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE OverloadedStrings, CPP #-}+{-# LANGUAGE OverloadedStrings #-} -- | Module    : Network.MPD.Util -- Copyright   : (c) Ben Sinclair 2005-2009, Joachim Fasting 2010 -- License     : MIT (see LICENSE)@@ -15,13 +15,9 @@  import           Control.Arrow -import           Data.Time.Format (ParseTime, parseTime, FormatTime, formatTime)+import           Data.Time.Format (ParseTime, parseTimeM, FormatTime, formatTime) -#if MIN_VERSION_time(1,5,0) import           Data.Time.Format (defaultTimeLocale)-#else-import           System.Locale (defaultTimeLocale)-#endif  import qualified Prelude import           Prelude hiding        (break, take, drop, dropWhile, read)@@ -50,7 +46,7 @@  -- Parse date in iso 8601 format parseIso8601 :: (ParseTime t) => ByteString -> Maybe t-parseIso8601 = parseTime defaultTimeLocale iso8601Format . UTF8.toString+parseIso8601 = parseTimeM True defaultTimeLocale iso8601Format . UTF8.toString  formatIso8601 :: FormatTime t => t -> String formatIso8601 = formatTime defaultTimeLocale iso8601Format
tests/ParserSpec.hs view
@@ -51,8 +51,6 @@ prop_parseOutputs ds =     Right ds `shouldBe` (parseOutputs . map UTF8.fromString . lines . concatMap unparse) ds -deriving instance Ord Value- prop_parseSong :: Song -> Expectation prop_parseSong s = Right (sortTags s) `shouldBe` sortTags `fmap` (parseSong . toAssocList . map UTF8.fromString . lines . unparse) s   where
tests/StringConn.hs view
@@ -13,7 +13,7 @@  import           Control.Applicative import           Prelude hiding (exp)-import           Control.Monad.Error+import           Control.Monad.Except import           Control.Monad.Identity import           Control.Monad.Reader import           Control.Monad.State@@ -37,7 +37,7 @@       deriving (Show, Eq)  newtype StringMPD a =-    SMPD { runSMPD :: ErrorT MPDError+    SMPD { runSMPD :: ExceptT MPDError                       (StateT [(Expect, Response String)]                        (ReaderT Password Identity)) a          } deriving (Functor, Applicative, Monad, MonadError MPDError)@@ -73,4 +73,4 @@         -> Password                    -- ^ A password to be supplied.         -> StringMPD a                 -- ^ The MPD action to run.         -> Response a-testMPDWithPassword pairs passwd m = runIdentity $ runReaderT (evalStateT (runErrorT $ runSMPD m) pairs) passwd+testMPDWithPassword pairs passwd m = runIdentity $ runReaderT (evalStateT (runExceptT $ runSMPD m) pairs) passwd