module Hbro.Socket where
import Hbro.Util
import Hbro.Types
import Control.Monad hiding(mapM_)
import Control.Monad.Reader hiding(mapM_)
import Data.ByteString.Char8 (pack, unpack)
import Data.Foldable
import qualified Data.Map as Map
import Graphics.UI.Gtk.General.General
import Graphics.UI.Gtk.WebKit.WebView hiding(webViewGetUri, webViewLoadUri)
import Network.URI
import Prelude hiding(mapM_)
import System.Console.CmdArgs (whenNormal, whenLoud)
import System.FilePath
import System.ZMQ
openRepSocket :: Context -> String -> (Socket Rep -> IO ()) -> IO ()
openRepSocket context socketURI listen = do
whenNormal $ putStrLn ("Opening socket at " ++ socketURI)
withSocket context Rep $ \repSocket -> do
bind repSocket socketURI
listen repSocket
listenToCommands :: Environment -> CommandsMap -> Socket Rep -> IO ()
listenToCommands environment commands repSocket = do
message <- receive repSocket []
let message' = unpack message
case words message' of
[] -> send repSocket (pack "ERROR Unknown command") []
["QUIT"] -> do
whenLoud $ putStrLn "Receiving QUIT command"
send repSocket (pack "OK") []
command:arguments -> do
whenLoud $ putStrLn ("Receiving command: " ++ message')
case Map.lookup command commands of
Just callback -> callback arguments repSocket environment
_ -> send repSocket (pack "ERROR Unknown command") []
listenToCommands environment commands repSocket
closeSocket :: Context -> String -> IO ()
closeSocket context socketURI = void $ sendCommand context socketURI "QUIT"
socketFile :: String -> String -> String
socketFile pid socketDir = "ipc://" ++ socketDir </> "hbro." ++ pid
sendCommand :: Context -> String -> String -> IO String
sendCommand context socketURI command = withSocket context Req $ \reqSocket -> do
connect reqSocket socketURI
send reqSocket (pack command) []
receive reqSocket [] >>= return . unpack
sendCommandToAll :: Context -> FilePath -> String -> IO [String]
sendCommandToAll context socketDir command = getAllProcessIDs >>= mapM (\pid -> sendCommand context (socketFile pid socketDir) command)
defaultCommandsList :: CommandsList
defaultCommandsList = [
("GET_URI", \_arguments repSocket browser -> liftIO $ do
getUri <- postGUISync $ webViewGetUri (mWebView $ mGUI browser)
case getUri of
Just uri -> send repSocket ((pack . show) uri) []
_ -> send repSocket (pack "ERROR No URL opened") [] ),
("GET_TITLE", \_arguments repSocket browser -> liftIO $ do
getTitle <- postGUISync $ webViewGetTitle (mWebView $ mGUI browser)
case getTitle of
Just title -> send repSocket (pack title) []
_ -> send repSocket (pack "ERROR No title") [] ),
("GET_FAVICON_URI", \_arguments repSocket browser -> liftIO $ do
getUri <- postGUISync $ webViewGetIconUri (mWebView $ mGUI browser)
case getUri of
Just uri -> send repSocket (pack uri) []
_ -> send repSocket (pack "ERROR No favicon uri") [] ),
("GET_LOAD_PROGRESS", \_arguments repSocket browser -> liftIO $ do
progress <- postGUISync $ webViewGetProgress (mWebView $ mGUI browser)
send repSocket (pack (show progress)) [] ),
("LOAD_URI", \arguments repSocket browser -> liftIO $ case arguments of
uri:_ -> do
postGUIAsync $ mapM_ (webViewLoadUri (mWebView (mGUI browser))) (parseURIReference uri)
send repSocket (pack "OK") []
_ -> send repSocket (pack "ERROR: argument needed.") [] ),
("STOP_LOADING", \_arguments repSocket browser -> liftIO $do
postGUIAsync $ webViewStopLoading (mWebView $ mGUI browser)
send repSocket (pack "OK") [] ),
("RELOAD", \_arguments repSocket browser -> liftIO $ do
postGUIAsync $ webViewReload (mWebView $ mGUI browser)
send repSocket (pack "OK") [] ),
("GO_BACK", \_arguments repSocket browser -> liftIO $ do
postGUIAsync $ webViewGoBack (mWebView $ mGUI browser)
send repSocket (pack "OK") [] ),
("GO_FORWARD", \_arguments repSocket browser -> liftIO $ do
postGUIAsync $ webViewGoForward (mWebView $ mGUI browser)
send repSocket (pack "OK") [] ),
("ZOOM_IN", \_arguments repSocket browser -> liftIO $ do
postGUIAsync $ webViewZoomIn (mWebView $ mGUI browser)
send repSocket (pack "OK") [] ),
("ZOOM_OUT", \_arguments repSocket browser -> liftIO $ do
postGUIAsync $ webViewZoomOut (mWebView $ mGUI browser)
send repSocket (pack "OK") [] )
]