hoovie-0.1.1: src/Hoovie/Server.hs
{-# LANGUAGE OverloadedStrings, TemplateHaskell #-}
module Hoovie.Server (
HoovieService(..),
HoovieServerHandle,
startHoovieServer,
stopHoovieServer
) where
import Control.Concurrent (forkIO, ThreadId, killThread)
import Data.List (intersperse)
import Debug.Trace (trace)
import Network.Info (NetworkInterface, ipv4)
import Control.Applicative ((<|>))
import Data.FileEmbed (embedFile)
import qualified Data.ByteString.Char8 as BC
import Snap.Core
import Snap.Http.Server
import Hoovie.SSDP
import Hoovie.SOAP
import Hoovie.Stream
import Hoovie.Monitor
data HoovieService = HoovieService {
hsInterface :: NetworkInterface,
hsPort :: Int,
hsPaths :: [FilePath],
hsDatabase :: FilePath
} deriving (Show)
data HoovieServerHandle = HoovieServerHandle ThreadId SSDPHandle MonitorHandle
snapConfig :: MonadSnap m => String -> Int -> Config m a
snapConfig ip port = ( setLocale "en_US"
. setPort port
. setBind (BC.pack ip)
) emptyConfig
startHoovieServer :: HoovieService -> IO HoovieServerHandle
startHoovieServer (HoovieService interface port paths db) = do
mon <- startMonitor paths db
ssdp <- startSsdpServer $ SSDPService interface port ('/':hoovieXmlUri) "Hoovie" "0.1" [SSDPMediaServer, SSDPContentDirectory, SSDPConnectionManager]
http <- forkIO $ httpServe (snapConfig (show $ ipv4 interface) port) (site (getURL ssdp) (getUUID ssdp) db)
return $ HoovieServerHandle http ssdp mon
stopHoovieServer :: HoovieServerHandle -> IO ()
stopHoovieServer (HoovieServerHandle http ssdp mon) = do
stopSsdpServer ssdp
stopMonitor mon
killThread http
site :: String -> String -> FilePath -> Snap ()
site url uuid db =
logRequest <|>
soapHandler url uuid db <|>
route [("stream/:id", streamHandler db),
("folder/:id", iconHandler),
("icon/:id", iconHandler)]
iconHandler :: Snap ()
iconHandler = do
-- rid <- getParam "id"
staticSendFile "image/jpg" $(embedFile "static/hoovie.jpg")
logRequest :: Snap a
logRequest = do
request <- getRequest
trace (show (rqMethod request) ++ " " ++ show (rqURI request) ++ "\n" ++
concat (intersperse "\n" ([" " ++ show k ++ ": " ++ show v | (k, v) <- listHeaders $ headers request]))) pass