servius (empty) → 0.0.0
raw patch · 4 files changed
+171/−0 lines, 4 filesdep +basedep +blaze-builderdep +blaze-htmlsetup-changed
Dependencies added: base, blaze-builder, blaze-html, bytestring, cmdargs, containers, directory, hamlet, http-types, shakespeare-css, text, transformers, wai, wai-app-static, wai-extra, warp
Files
- LICENSE +30/−0
- Setup.lhs +7/−0
- servius.cabal +32/−0
- servius.hs +102/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c)2011, Michael Snoyman++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 Michael Snoyman 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.
+ Setup.lhs view
@@ -0,0 +1,7 @@+#!/usr/bin/env runhaskell++> module Main where+> import Distribution.Simple++> main :: IO ()+> main = defaultMain
+ servius.cabal view
@@ -0,0 +1,32 @@+Name: servius+Version: 0.0.0+Synopsis: Serve Shakespearean templates via Warp+Homepage: http://github.com/yesodweb/hamlet+License: BSD3+License-file: LICENSE+Author: Michael Snoyman+Maintainer: michael@snoyman.com+Category: Web+Build-type: Simple+Cabal-version: >=1.2+Description: Does not support any variable interpolation. Supports Hamlet and Lucius files (must have .hamlet and .lucius file extensions, respectively).+++Executable servius+ Main-is: servius.hs+ Build-depends: base >= 4 && < 5+ , warp >= 0.4 && < 0.5+ , wai-app-static >= 0.3 && < 0.4+ , wai-extra >= 0.4 && < 0.5+ , cmdargs >= 0.6.7+ , directory >= 1.0+ , containers >= 0.2 && < 0.5+ , bytestring >= 0.9.1.4+ , text >= 0.7+ , blaze-builder+ , blaze-html+ , http-types+ , hamlet+ , shakespeare-css+ , transformers+ , wai
+ servius.hs view
@@ -0,0 +1,102 @@+{-# LANGUAGE DeriveDataTypeable, RecordWildCards #-}+{-# LANGUAGE OverloadedStrings #-}+import Network.Wai.Application.Static+ ( StaticSettings (..), staticApp, defaultMimeType, defaultListing+ , defaultMimeTypes, mimeTypeByExt+ , defaultFileServerSettings, fileSystemLookup+ , fileName, toFilePath+ )+import Network.Wai.Handler.Warp (run)+import System.Console.CmdArgs+import Text.Printf (printf)+import System.Directory (canonicalizePath)+import Control.Monad (unless)+import Network.Wai.Middleware.Autohead+import Network.Wai.Middleware.Debug+import Network.Wai.Middleware.Gzip+import qualified Data.Map as Map+import qualified Data.ByteString.Char8 as S8+import Control.Arrow ((***))+import Data.Text (Text, pack)+import qualified Data.Text as T+import Network.Wai+import Data.ByteString (ByteString)+import Control.Monad.IO.Class (liftIO)+import Data.Text.Encoding (decodeUtf8With)+import Data.Text.Encoding.Error (lenientDecode)+import Text.Lucius (luciusRT)+import Text.Hamlet (defaultHamletSettings)+import Text.Hamlet.RT (parseHamletRT, renderHamletRT)+import Network.HTTP.Types (status200)+import Text.Blaze.Renderer.Utf8 (renderHtmlBuilder)+import qualified Data.Text.Lazy as TL+import Blaze.ByteString.Builder.Char.Utf8 (fromLazyText)++data Args = Args+ { docroot :: FilePath+ , index :: [FilePath]+ , port :: Int+ , noindex :: Bool+ , quiet :: Bool+ , verbose :: Bool+ , mime :: [(String, String)]+ }+ deriving (Show, Data, Typeable)++defaultArgs :: Args+defaultArgs = Args "." ["index.html", "index.htm"] 3000 False False False []++main :: IO ()+main = do+ Args {..} <- cmdArgs defaultArgs+ let mime' = map (toFilePath *** S8.pack) mime+ let mimeMap = Map.fromList mime' `Map.union` defaultMimeTypes+ docroot' <- canonicalizePath docroot+ unless quiet $ printf "Serving directory %s on port %d with %s index files.\n" docroot' port (if noindex then "no" else show index)+ let middle = gzip False+ . (if verbose then debug else id)+ . autohead+ . shake docroot+ run port $ middle $ staticApp defaultFileServerSettings+ { ssFolder = fileSystemLookup $ toFilePath docroot+ , ssIndices = if noindex then [] else map pack index+ , ssListing = Just defaultListing+ , ssGetMimeType = return . mimeTypeByExt mimeMap defaultMimeType . fileName+ }++shake :: FilePath -> Middleware+shake docroot app req+ | any unsafe p = app req+ | null p = app req+ | ".hamlet" `T.isSuffixOf` l = liftIO $ hamlet pr+ | ".lucius" `T.isSuffixOf` l = liftIO $ lucius pr+ | otherwise = app req+ where+ p = pathInfo req+ pr = T.intercalate "/" $ T.pack docroot : p+ l = last p++unsafe :: Text -> Bool+unsafe s+ | T.null s = False+ | T.head s == '.' = True+ | otherwise = T.any (== '/') s++readFileUtf8 :: Text -> IO String+readFileUtf8 fp = do+ bs <- S8.readFile $ T.unpack fp+ let t = decodeUtf8With lenientDecode bs+ return $ T.unpack t++hamlet :: Text -> IO Response+hamlet fp = do+ str <- readFileUtf8 fp+ hrt <- parseHamletRT defaultHamletSettings str+ html <- renderHamletRT hrt [] (error "No URLs allowed")+ return $ ResponseBuilder status200 [("Content-Type", "text/html; charset=utf-8")] $ renderHtmlBuilder html++lucius :: Text -> IO Response+lucius fp = do+ str <- readFileUtf8 fp+ let text = either error id $ luciusRT (TL.pack str) []+ return $ ResponseBuilder status200 [("Content-Type", "text/css; charset=utf-8")] $ fromLazyText text