{-# LANGUAGE OverloadedStrings #-} module Snap.Snaplet.Coffee( CoffeeScript(..) , initCoffee , coffeeServe ) where import qualified Data.Configurator as C (lookup) import qualified Data.ByteString.Char8 as BS (unpack) import Snap.Snaplet import Snap.Core (rqURI, modifyResponse, getRequest, setContentType) import Snap.Util.FileServe (serveDirectory) import Snap.Snaplet.Coffee.Utils import Control.Monad.Reader (liftIO, when, MonadIO) import Control.Monad.State.Class (get) import Control.Applicative ((<$>)) import System.Exit (ExitCode(..)) import Coffee.Bindings (Coffee(..), coffeeCompile) import Control.Monad (liftM) import Paths_snaplet_coffee -- | Snaplet-Coffee initializer initCoffee :: SnapletInit c CoffeeScript initCoffee = makeSnaplet "coffee" "description" dataDir $ do config <- getSnapletUserConfig fp <- getSnapletFilePath [comp, dev, dDir] <- liftIO $ mapM (C.lookup config) configOptions let coffee = CoffeeScript fp comp (getCompilerMode dev) (getDestDir dDir coffee) liftIO $ mapM_ createDirUnlessExists [fp, srcDir coffee, destDir coffee] allCoffees <- liftIO $ allCoffeeFiles coffee when (Production == compileMode coffee) $ liftIO $ compileFiles coffee allCoffees return coffee where dataDir = Just $ liftM (++ "/resources") getDataDir configOptions = ["compilerPath", "compilerMode", "destinationPath"] -- | Serves the compiled CoffeeScript files coffeeServe :: Handler b CoffeeScript () coffeeServe = do modifyResponse . setContentType $ "text/javascript;charset=utf-8" cfg <- get requestedFile <- (srcDir cfg ++) . requestedCoffeeFile . BS.unpack . rqURI <$> getRequest when (Development == compileMode cfg) $ liftIO $ compileFiles cfg [requestedFile] serveDirectory $ destinationDir cfg -- | Compiles the files that are being served, but ignores all other files. compileFiles :: MonadIO m => CoffeeScript -> [FilePath] -> m () compileFiles cfg fp = do let coffeeStruct = Coffee (compiler cfg) False result <- liftIO $ coffeeCompile fp (Just (destinationDir cfg)) coffeeStruct case result of ExitSuccess -> return () ExitFailure x -> error $ show x ++ errMsg where errMsg = unlines [ " - Error while compiling CoffeeScript" , "Does this file really exist?" , "Is your /snaplets/coffee/devel.cfg correct?" , "You might need to restart the server after fixing the issue." ]