packages feed

mpd-current-json 1.2.0.0 → 1.3.0.0

raw patch · 5 files changed

+105/−30 lines, 5 filesdep ~mpd-current-json

Dependency ranges changed: mpd-current-json

Files

CHANGELOG.md view
@@ -1,7 +1,17 @@+# v1.3+- Add `filename` key.+- Add `playlist` key and move existing keys to it.+- Customize ordering of displayed output JSON.+- Add cabal tested-with GHC versions+ # v1.2.0.0 - Move literate Org Mode code to LITERATE.org file - Move functions from executable source Main.hs to their own library - Bump dependency versions for `aeson` and `bytestring`+- Changed status.state from "play" to "playing" and "pause" to+  "paused".+  The reason why it was "play" and "pause" before was because+  that was the socket answer string.  # v1.1.0.2 [comment]: # (2023-10-23)
README.org view
@@ -3,21 +3,31 @@ #+OPTIONS: toc:1  * Installation-: cabal install mpd-current-json-or+Packages are available:+- [[https://aur.archlinux.org/packages/mpd-current-json][in the AUR]]+- in Hackage:+  : cabal install mpd-current-json++or compile it from source: #+begin_example git clone https://codeberg.org/useless-utils/mpd-current-json cd mpd-current-json #+end_example-and to install the executable to =./dist=, in the current directory:+to install the executable to =./dist=, in the current directory: : cabal install --install-method=copy --overwrite-policy=always --installdir=dist or to install to =${CABAL_DIR}/bin= remove the =--installdir=dist= argument. =CABAL_DIR= defaults to =~/.local/share/cabal=.  * Usage-get values-: mpd-current-json | jaq .tags.album-: mpd-current-json | jaq .status.elapsed_percent+- Get values+  : mpd-current-json | jaq .tags.album+  : mpd-current-json | jaq .status.elapsed_percent -provide host and port with-: mpd-current-json -h 'localhost' -p 4321+- Provide host and port with+  : mpd-current-json -h 'localhost' -p 4321++- Provide password+  : mpd-current-json --password 'abc123'+  note that the password will be sent as plain text.++Run =mpd-current-json --help= for all the available options.
lib/Network/MPD/Parse.hs view
@@ -2,6 +2,7 @@   ( getStatusItem   , getTag   , processSong+  , maybePath   , headMay   , valueToStringMay   , (.=?)@@ -45,6 +46,13 @@ processSong tag (Just song) = do   let tagVal = MPD.sgGetTag tag song   valueToStringMay =<< (headMay =<< tagVal)++maybePath :: Either a (Maybe Song) -> Maybe String+maybePath cs =+  case cs of+    Left _ -> Nothing+    Right Nothing -> Nothing+    Right (Just song) -> Just $ MPD.toString $ MPD.sgFilePath song  {- | Safely get the head of a list. Same as [Safe.headMay](Safe#headMay). -}
mpd-current-json.cabal view
@@ -7,7 +7,7 @@ -- PVP summary:     +-+------- breaking API changes --                  | | +----- non-breaking API additions --                  | | | +--- code changes with no API change-version:            1.2.0.0+version:            1.3.0.0 synopsis:           Print current MPD song and status as JSON  -- A longer description of the package.@@ -24,13 +24,15 @@ -- A copyright notice. -- copyright: category:           Network-extra-source-files: CHANGELOG.md+extra-doc-files:    CHANGELOG.md                     README.org  source-repository head     type:      git     location:  https://codeberg.org/useless-utils/mpd-current-json +-- tested-with: GHC == 9.4.8+ library     -- exposed: False     exposed-modules:  Network.MPD.Parse@@ -58,7 +60,7 @@                     , aeson                     , bytestring >=0.11 && <0.13                     , aeson-pretty == 0.8.*-                    , mpd-current-json == 1.2.*+                    , mpd-current-json == 1.3.*      -- Directories containing source files.     hs-source-dirs:   src
src/Main.hs view
@@ -6,16 +6,21 @@ import Network.MPD        ( Metadata(..), PlaybackState(Stopped, Playing, Paused) ) import Data.Maybe ( catMaybes )-import Data.Aeson ( object, KeyValue(..) )-import Data.Aeson.Encode.Pretty ( encodePretty )+import Data.Aeson ( object, KeyValue((.=)), Value )+import Data.Aeson.Encode.Pretty+       ( defConfig, encodePretty', keyOrder, Config(confCompare) ) import qualified Data.ByteString.Lazy.Char8 as C import Text.Printf ( printf ) import Options     ( optsParserInfo, execParser, Opts(optPass, optHost, optPort) )  import Network.MPD.Parse ( getStatusItem-                             , getTag-                             , (.=?) )+                         , getTag+                         , maybePath+                         , (.=?) )++import Text.Read (readMaybe)+import Data.Aeson.Types (Pair) {- | Where the program connects to MPD and uses the helper functions to extract values, organize them into a list of key/value pairs, make them a 'Data.Aeson.Value' using 'Data.Aeson.object', then encode it to@@ -69,20 +74,20 @@       elapsed = case time of         Just t -> case t of                     Just (e, _) -> Just e-                    _           -> Nothing+                    _noTag      -> Nothing         Nothing -> Nothing        duration = case time of         Just t -> case t of                     Just (_, d) -> Just d-                    _           -> Nothing+                    _noTag      -> Nothing         Nothing -> Nothing        elapsedPercent :: Maybe Double       elapsedPercent = case time of         Just t -> case t of-                    Just t1 -> Just (read $ printf "%.2f" (uncurry (/) t1 * 100))-                    Nothing -> Just 0+                   Just t1 -> readMaybe $ printf "%.2f" (uncurry (/) t1 * 100)+                   Nothing -> Just 0         Nothing -> Nothing        repeatSt       = getStatusItem st MPD.stRepeat@@ -95,8 +100,10 @@       audioFormat    = getStatusItem st MPD.stAudio       errorSt        = getStatusItem st MPD.stError +  let filename = maybePath cs+   -- sgTags-  let jTags = object . catMaybes $+  let jTags = objectJson         [ "artist"                     .=? artist         , "artist_sort"                .=? artistSort         , "album"                      .=? album@@ -126,23 +133,61 @@         ]    -- status-  let jStatus = object . catMaybes $+  let jStatus = objectJson         [ "state"           .=? state         , "repeat"          .=? repeatSt-        , "elapsed"         .=? elapsed-        , "duration"        .=? duration-        , "elapsed_percent" .=? elapsedPercent         , "random"          .=? randomSt         , "single"          .=? singleSt         , "consume"         .=? consumeSt-        , "song_position"   .=? pos-        , "playlist_length" .=? playlistLength-        , "bitrate"         .=? bitrate+        , "duration"        .=? duration+        , "elapsed"         .=? elapsed+        , "elapsed_percent" .=? elapsedPercent         , "audio_format"    .=? audioFormat+        , "bitrate"         .=? bitrate         , "error"           .=? errorSt         ] -  let jObject = object [ "tags"   .= jTags-                       , "status" .= jStatus ]+  -- let jFilename = objectJson [ "file" .=? filename ] -  C.putStrLn $ encodePretty jObject+  let jPlaylist = objectJson+        [ "position" .=? pos+        , "length"           .=? playlistLength+        ]++  let jObject = object [ "filename" .= filename+                       , "playlist" .= jPlaylist+                       , "status"   .= jStatus+                       , "tags"     .= jTags+                       ]++  C.putStrLn $ encodePretty' customEncodeConf jObject++customEncodeConf :: Config+customEncodeConf = defConfig+  { confCompare = keyOrder [ "title", "name"+                           , "artist", "album_artist", "artist_sort", "album_artist_sort"+                           , "album", "album_sort"+                           , "track", "disc"+                           , "date", "original_date"+                           , "genre", "composer", "performer", "conductor"+                           , "work", "grouping", "label"+                           , "comment"+                           , "musicbrainz_artistid"+                           , "musicbrainz_albumid"+                           , "musicbrainz_albumartistid"+                           , "musicbrainz_trackid"+                           , "musicbrainz_releasetrackid"+                           , "musicbrainz_workid"+                           -- status+                           , "state", "repeat", "random", "single", "consume"+                           , "duration", "elapsed", "elapsed_percent"+                           , "audio_format", "bitrate"+                           , "error"+                           ]+  }++-- | Helper function for creating an JSON 'Data.Aeson.object' where+-- 'Data.Maybe.catMaybes' won't include items from the '[Maybe Pair]'+-- list that return 'Nothing'.+objectJson :: [Maybe Pair] -> Value+objectJson = object . catMaybes