packages feed

mp-1.0.0: src/Mp/Player/Client.hs

{-
 *  Programmer:	Piotr Borek
 *  E-mail:     piotrborek@op.pl
 *  Copyright 2014 Piotr Borek
 *
 *  Distributed under the terms of the GPL (GNU Public License)
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-}

module Mp.Player.Client (
    clientSendQuitMessage,
    clientSendAddFile,
    clientSendRemove,
    clientSendClear,
    clientSendGetPlaylist,
    clientSendGetStatus,
    clientSendSetPlaying,
    clientSendGetPlaying,
    clientSendStopPlaying,
    clientSendPausePlaying,
    clientSendResumePlaying,
    clientSendPlayNext,
    clientSendPlayPrev,
    clientSendVolumeUp,
    clientSendVolumeDown,
    clientSendVolumeGet,
    clientSendSeekForward,
    clientSendSeekBackward,
    clientSendGetFlags,
    clientSendToggleRepeat,
    clientSendToggleShuffle,
    clientSendSaveState
) where

import           Control.Monad
import           Control.Monad.IO.Class
import           Network.Socket                 (Family (AF_UNIX),
                                                 SockAddr (SockAddrUnix),
                                                 SocketType (Stream), close,
                                                 connect, defaultProtocol,
                                                 socket)
import           System.FilePath.Posix

import           Mp.Configuration.Configuration
import           Mp.Utils.Network

withConnection :: MonadIO m => (Socket -> IO a) -> m a
withConnection action = liftIO $ do
    confPath <- configDirFilePath
    let socName = confPath </> "mp.socket"

    sock <- socket AF_UNIX Stream defaultProtocol
    connect sock $ SockAddrUnix socName

    value <- action sock

    close sock
    return value

sendMessage :: String -> Socket -> IO String
sendMessage msg sock = do
    sendString sock msg  -- send message
    recvString' sock     -- receive answer

sendMessage_ :: String -> Socket -> IO ()
sendMessage_ msg sock = void $ sendMessage msg sock

clientSendQuitMessage :: MonadIO m => m ()
clientSendQuitMessage = withConnection $ sendMessage_ "Quit"

clientSendAddFile :: MonadIO m => String -> m ()
clientSendAddFile file =
    withConnection $ \conn -> do
        sendMessage_ "Add" conn
        sendMessage_ file conn

clientSendRemove :: MonadIO m => Int -> m ()
clientSendRemove index =
    withConnection $ \conn -> do
        sendMessage_ "Remove" conn
        sendMessage_ (show index) conn

clientSendClear :: MonadIO m => m ()
clientSendClear = withConnection $ sendMessage_ "Clear"

clientSendGetPlaylist :: MonadIO m => m [String]
clientSendGetPlaylist =
    withConnection $ \conn -> do
        item <- sendMessage "GetPlaylist" conn
        if item == "EndPlaylist"
            then return []
            else processMessages [item] conn
    where
        processMessages xs conn = do
            item <- sendMessage "Get" conn
            if item == "EndPlaylist"
                then return xs
                else processMessages (item : xs) conn

clientSendGetStatus :: MonadIO m => m (String, Integer, Integer)
clientSendGetStatus =
    withConnection $ \conn -> do
        status <- sendMessage "GetStatus" conn
        dur    <- sendMessage "GetDuration" conn
        pos    <- sendMessage "GetPosition" conn
        return (status, read dur :: Integer, read pos :: Integer)

clientSendSetPlaying :: MonadIO m => Int -> m ()
clientSendSetPlaying index =
    withConnection $ \conn -> do
        sendMessage_ "SetPlay" conn
        sendMessage_ (show index) conn

clientSendGetPlaying :: MonadIO m => m Int
clientSendGetPlaying =
    withConnection $ \conn -> do
        index <- sendMessage "GetPlay" conn
        return (read index :: Int)

clientSendStopPlaying :: MonadIO m => m ()
clientSendStopPlaying = withConnection $ sendMessage_ "Stop"

clientSendPausePlaying :: MonadIO m => m ()
clientSendPausePlaying = withConnection $ sendMessage_ "Pause"

clientSendResumePlaying :: MonadIO m => m ()
clientSendResumePlaying = withConnection $ sendMessage_ "Resume"

clientSendPlayNext :: MonadIO m => m ()
clientSendPlayNext = withConnection $ sendMessage_ "Next"

clientSendPlayPrev :: MonadIO m => m ()
clientSendPlayPrev = withConnection $ sendMessage_ "Prev"

clientSendVolumeUp :: MonadIO m => m ()
clientSendVolumeUp = withConnection $ sendMessage_ "VolUp"

clientSendVolumeDown :: MonadIO m => m ()
clientSendVolumeDown = withConnection $ sendMessage_ "VolDown"

clientSendVolumeGet :: MonadIO m => m String
clientSendVolumeGet = withConnection $ sendMessage "VolGet"

clientSendSeekForward :: MonadIO m => m ()
clientSendSeekForward = withConnection $ sendMessage_ "SeekForward"

clientSendSeekBackward :: MonadIO m => m ()
clientSendSeekBackward = withConnection $ sendMessage_ "SeekBackward"

clientSendGetFlags :: MonadIO m => m String
clientSendGetFlags = withConnection $ sendMessage "GetFlags"

clientSendToggleRepeat :: MonadIO m => m ()
clientSendToggleRepeat = withConnection $ sendMessage_ "ToggleRepeat"

clientSendToggleShuffle :: MonadIO m => m ()
clientSendToggleShuffle = withConnection $ sendMessage_ "ToggleShuffle"

clientSendSaveState :: MonadIO m => m ()
clientSendSaveState = withConnection $ sendMessage_ "SaveState"