{-# LANGUAGE OverloadedStrings #-} module Main ( main ) where import qualified Network.MPD as MPD import Network.MPD ( Metadata(..), PlaybackState(Stopped, Playing, Paused) ) import Data.Maybe ( catMaybes ) import Data.Aeson ( object, KeyValue(..) ) import Data.Aeson.Encode.Pretty ( encodePretty ) 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 , (.=?) ) {- | 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 a conventional JSON @ByteString@ with 'Data.Aeson.Encode.Pretty.encodePretty' for the pretty-print version. -} main :: IO () main = do opts <- execParser optsParserInfo cs <- MPD.withMPDEx (optHost opts) (optPort opts) (optPass opts) MPD.currentSong st <- MPD.withMPDEx (optHost opts) (optPort opts) (optPass opts) MPD.status let artist = getTag Artist cs artistSort = getTag ArtistSort cs album = getTag Album cs albumSort = getTag AlbumSort cs albumArtist = getTag AlbumArtist cs albumArtistSort = getTag AlbumArtistSort cs title = getTag Title cs track = getTag Track cs name = getTag Name cs genre = getTag Genre cs date = getTag Date cs originalDate = getTag OriginalDate cs composer = getTag Composer cs performer = getTag Performer cs conductor = getTag Conductor cs work = getTag Work cs grouping = getTag Grouping cs comment = getTag Comment cs disc = getTag Disc cs label = getTag Label cs musicbrainz_Artistid = getTag MUSICBRAINZ_ARTISTID cs musicbrainz_Albumid = getTag MUSICBRAINZ_ALBUMID cs musicbrainz_Albumartistid = getTag MUSICBRAINZ_ALBUMARTISTID cs musicbrainz_Trackid = getTag MUSICBRAINZ_TRACKID cs musicbrainz_Releasetrackid = getTag MUSICBRAINZ_RELEASETRACKID cs musicbrainz_Workid = getTag MUSICBRAINZ_WORKID cs let state :: Maybe String state = case getStatusItem st MPD.stState of Just ps -> case ps of Playing -> Just "playing" Paused -> Just "paused" Stopped -> Just "stopped" Nothing -> Nothing time = getStatusItem st MPD.stTime elapsed = case time of Just t -> case t of Just (e, _) -> Just e _ -> Nothing Nothing -> Nothing duration = case time of Just t -> case t of Just (_, d) -> Just d _ -> 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 Nothing -> Nothing repeatSt = getStatusItem st MPD.stRepeat randomSt = getStatusItem st MPD.stRandom singleSt = getStatusItem st MPD.stSingle consumeSt = getStatusItem st MPD.stConsume pos = getStatusItem st MPD.stSongPos playlistLength = getStatusItem st MPD.stPlaylistLength bitrate = getStatusItem st MPD.stBitrate audioFormat = getStatusItem st MPD.stAudio errorSt = getStatusItem st MPD.stError -- sgTags let jTags = object . catMaybes $ [ "artist" .=? artist , "artist_sort" .=? artistSort , "album" .=? album , "album_sort" .=? albumSort , "album_artist" .=? albumArtist , "album_artist_sort" .=? albumArtistSort , "title" .=? title , "track" .=? track , "name" .=? name , "genre" .=? genre , "date" .=? date , "original_date" .=? originalDate , "composer" .=? composer , "performer" .=? performer , "conductor" .=? conductor , "work" .=? work , "grouping" .=? grouping , "comment" .=? comment , "disc" .=? disc , "label" .=? label , "musicbrainz_artistid" .=? musicbrainz_Artistid , "musicbrainz_albumid" .=? musicbrainz_Albumid , "musicbrainz_albumartistid" .=? musicbrainz_Albumartistid , "musicbrainz_trackid" .=? musicbrainz_Trackid , "musicbrainz_releasetrackid" .=? musicbrainz_Releasetrackid , "musicbrainz_workid" .=? musicbrainz_Workid ] -- status let jStatus = object . catMaybes $ [ "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 , "audio_format" .=? audioFormat , "error" .=? errorSt ] let jObject = object [ "tags" .= jTags , "status" .= jStatus ] C.putStrLn $ encodePretty jObject