Browse Source

Initial commit: playing around with sockets

Josh Bicking 6 years ago
commit
ac9e98956b
10 changed files with 201 additions and 0 deletions
  1. 3 0
      .gitignore
  2. 3 0
      ChangeLog.md
  3. 30 0
      LICENSE
  4. 1 0
      README.md
  5. 2 0
      Setup.hs
  6. 72 0
      app/Main.hs
  7. 57 0
      package.yaml
  8. 26 0
      src/Lib.hs
  9. 5 0
      stack.yaml
  10. 2 0
      test/Spec.hs

+ 3 - 0
.gitignore

@@ -0,0 +1,3 @@
+.stack-work/
+haskell-jukebox.cabal
+*~

+ 3 - 0
ChangeLog.md

@@ -0,0 +1,3 @@
+# Changelog for haskell-jukebox
+
+## Unreleased changes

+ 30 - 0
LICENSE

@@ -0,0 +1,30 @@
+Copyright Josh Bicking (c) 2018
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Josh Bicking nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 1 - 0
README.md

@@ -0,0 +1 @@
+# haskell-jukebox

+ 2 - 0
Setup.hs

@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain

+ 72 - 0
app/Main.hs

@@ -0,0 +1,72 @@
+{-# LANGUAGE OverloadedStrings #-}
+module Main where
+
+import Lib
+
+import Web.Scotty
+
+import qualified Text.Blaze.Html5 as BlazeHtml
+import qualified Text.Blaze.Html5.Attributes as BlazeAttributes
+
+import qualified Text.Blaze.Html.Renderer.Text as BlazeRenderer
+
+import Network.Wai.Middleware.RequestLogger  -- Logging
+
+import Data.Monoid (mconcat)
+
+import System.Random(randomIO)
+import System.Process
+import System.IO
+import Control.Concurrent(threadDelay)
+
+import Network.Socket(connect, close, SocketType(Stream), socket)
+import Network.Socket.Internal(Family(AF_UNIX), SockAddr(SockAddrUnix))
+import Network.Socket.ByteString(send, recv)
+
+import Data.ByteString(breakSubstring)
+
+main :: IO ()
+main = do
+  num <- (randomIO :: IO Integer)
+  let socket = "/tmp/mpvsocket" ++ (show num)
+    in do
+    putStrLn ("MPV listening at " ++ socket)
+    (_, _, _, p) <- createProcess (proc "mpv" ["--input-ipc-server=" ++ socket, "/home/josh/'IS THAT A MAN RIDING A SHRIMP'-9p_QW_HsKPI.mp3"]){ std_in = NoStream, std_out = NoStream, std_err = NoStream}
+    threadDelay 2000000
+    togglePause socket
+    threadDelay 2000000
+    togglePause socket
+    waitForProcess p
+    return ()
+
+togglePause :: String -> IO ()
+togglePause ipcloc = do
+  soc <- socket AF_UNIX Stream 0
+  connect soc (SockAddrUnix ipcloc)
+  send soc "{ \"command\": [\"get_property\", \"pause\"] }\n"
+  received <- recv soc 4096
+  putStrLn ("Recieved from MPV: " ++ (show received))
+  send soc $
+    case snd $ breakSubstring "true" received of
+      "" -> "{ \"command\": [\"set_property\", \"pause\", true] }\n"
+      otherwise -> "{ \"command\": [\"set_property\", \"pause\", false] }\n"
+  close soc
+
+oldmain :: IO ()
+oldmain = scotty 3000 $ do
+  middleware logStdoutDev  -- Logging
+  get "/say/:word" $ do
+    beam <- param "word"
+    if beam == "" then
+      html "<h1>Go to a URI, such as http://URL/say/beam.</h1>"
+    else
+      html $ mconcat ["<h1>Scotty, ", beam, " me up!</h1>"]
+  get "/hello" $ do  -- Access this with /hello?name=yee
+    name <- param "name"
+    text name
+  get "/agent" $ do
+    agent <- header "User-Agent"
+    text $ maybe "Couldn't determine user agent." id agent
+  get "/" $ do
+    html . BlazeRenderer.renderHtml $ do
+      BlazeHtml.h1 "This is blaze!"

+ 57 - 0
package.yaml

@@ -0,0 +1,57 @@
+name:                haskell-jukebox
+version:             0.1.0.0
+github:              "josh1147582/haskell-jukebox"
+license:             BSD3
+author:              "Josh Bicking"
+maintainer:          "[email protected]"
+copyright:           "GPL3"
+
+extra-source-files:
+- README.md
+- ChangeLog.md
+
+# Metadata used when publishing your package
+# synopsis:            Short description of your package
+# category:            Web
+
+# To avoid duplicated efforts in documentation and dealing with the
+# complications of embedding Haddock markup inside cabal files, it is
+# common to point users to the README.md file.
+description:         Please see the README on Github at <https://github.com/josh1147582/haskell-jukebox#readme>
+
+dependencies:
+- base >= 4.7 && < 5
+- scotty
+- wai-extra
+- blaze-html
+- random
+- process
+- bytestring
+- network
+
+library:
+  source-dirs: src
+  dependencies:
+  - process
+
+executables:
+  haskell-jukebox-exe:
+    main:                Main.hs
+    source-dirs:         app
+    ghc-options:
+    - -threaded
+    - -rtsopts
+    - -with-rtsopts=-N
+    dependencies:
+    - haskell-jukebox
+
+tests:
+  haskell-jukebox-test:
+    main:                Spec.hs
+    source-dirs:         test
+    ghc-options:
+    - -threaded
+    - -rtsopts
+    - -with-rtsopts=-N
+    dependencies:
+    - haskell-jukebox

+ 26 - 0
src/Lib.hs

@@ -0,0 +1,26 @@
+module Lib
+    ( testProcess
+    ) where
+
+import System.Process
+import GHC.IO.Handle
+import Control.Concurrent
+
+testProcess :: IO ()
+testProcess = do
+  -- (Just hin, , _, p) <- createProcess (proc "mpv" ["--input-terminal=yes", "/home/josh/'IS THAT A MAN RIDING A SHRIMP'-9p_QW_HsKPI.mp3"]){ std_in = CreatePipe, std_out = NoStream, std_err = NoStream}
+  (Just hin, Just hout, _, c) <- createProcess (proc "cat" []){ std_in = CreatePipe , std_out = CreatePipe}
+  hSetBuffering hin NoBuffering
+  threadDelay 2000000
+  hPutChar hin 'p'
+  hPutChar hin '\n'
+  threadDelay 2000000
+  hPutChar hin 'p'
+  hPutChar hin '\n'
+  threadDelay 2000000
+  hPutChar hin 'p'
+  hPutChar hin '\n'
+  hClose hin
+  waitForProcess c
+  b <- hGetLine hout
+  putStrLn (show b)

+ 5 - 0
stack.yaml

@@ -0,0 +1,5 @@
+flags: {}
+packages:
+- .
+extra-deps: [socket-unix-0.2.0.0]
+resolver: lts-10.5

+ 2 - 0
test/Spec.hs

@@ -0,0 +1,2 @@
+main :: IO ()
+main = putStrLn "Test suite not yet implemented"