packages feed

bird 0.0.14 → 0.0.15

raw patch · 9 files changed

+84/−17 lines, 9 filesdep +MissingHPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: MissingH

API changes (from Hackage documentation)

+ Bird.Config: BirdConfig :: String -> (Request -> Router -> IO Reply) -> BirdConfig
+ Bird.Config: birdLogger :: BirdConfig -> Request -> Router -> IO Reply
+ Bird.Config: data BirdConfig
+ Bird.Config: instance Default BirdConfig
+ Bird.Config: staticDir :: BirdConfig -> String
+ Bird.Config: type Router = Request -> BirdResponder ()
+ Bird.Request: rawRequestUri :: Request -> String
- Bird.BirdResponder: type BirdResponder = StateT Reply (ReaderT Request IO)
+ Bird.BirdResponder: type BirdResponder = StateT Reply (ReaderT Request (WriterT [String] IO))
- Bird.Request: Request :: RequestMethod -> Path -> [(String, Maybe String)] -> Request
+ Bird.Request: Request :: RequestMethod -> Path -> [(String, Maybe String)] -> String -> Request

Files

bin/bird.hs view
@@ -20,12 +20,12 @@       system "ghc --make -O2 Main.hs"       files <- getDirectoryContents appModuleNamePath       system $ "rm *.o *.hi " ++ appModuleName ++ ".hs"-      renameFile "Main" appModuleName+      renameFile "Main" (appModuleName ++ "App")       return ()     ["fly"] -> do       appModuleNamePath <- getCurrentDirectory       appModuleName <- return $ head . reverse $ split '/' appModuleNamePath-      system $ "./" ++ appModuleName+      system $ "./" ++ appModuleName ++ "App"       return ()     ["hatch", appName] -> createBirdApp appName     (action:_) -> do@@ -43,7 +43,8 @@ appModulePrelude appModuleName =   "--This file is generated by bird. It will be overwritten the next time you run 'bird nest'. Edit at your own peril.\n" ++   "module " ++ appModuleName ++ " where\n" ++-  "import Bird\n\n"+  "import Bird\n" +++  "import Prelude hiding( log )\n\n"  appModuleEpilogue =   "get _ = status 404\n" ++@@ -51,15 +52,22 @@   "put _ = status 404\n" ++   "delete _ = status 404\n" - createBirdApp a = do   createDirectory a+  createDirectory (a ++ "/" ++ a ++ "/")   writeFile (a ++ "/" ++ a ++ ".bird.hs") (routeFile a)   writeFile (a ++ "/" ++ "Main.hs") (mainFile a)+  writeFile (a ++ "/" ++ a ++ "/Config.hs") (configFile a)   putStrLn $ "A fresh Bird app has been created in " ++ a ++ "."  routeFile a = "get [] = body \"Hello, Bird!\"" +configFile a = +  "module " ++ a ++ ".Config where\n\n" +++  "import Bird\n\n" ++ +  "config :: BirdConfig" +++  "config = def\n"+ mainFile a =   "import Hack\n" ++   "import qualified Hack as Hack\n" ++@@ -69,7 +77,8 @@   "import Bird.Translator.Hack\n" ++   "import qualified Control.Monad.State as S\n" ++   "import qualified Control.Monad.Reader as R\n" ++-  "import " ++ a ++ "\n" ++ "\n" +++  "import " ++ a ++ "\n" +++  "import " ++ a ++ ".Config\n\n" ++    "app :: Application\n" ++   "app = \\e -> route e\n" ++ "\n" ++@@ -79,7 +88,7 @@   "  where \n" ++   "    req = toBirdRequest e\n" ++   "    response = do \n" ++-  "      reply <- runBirdResponder req matchRequest\n" +++  "      reply <- (birdLogger config) req matchRequest\n" ++   "      return $ fromBirdReply reply\n\n" ++    "matchRequest r = \n" ++
bird.cabal view
@@ -1,5 +1,5 @@ Name:                 bird-Version:              0.0.14+Version:              0.0.15 Build-type:           Simple Synopsis:             A simple, sinatra-inspired web framework. Description:          Bird is a hack-compatible framework for simple websites.@@ -18,6 +18,6 @@   hs-source-dirs: bin    library-  build-depends: haskell98, mtl >= 1.1.0.2, process, containers, parsec >= 2.1.0.1, bytestring, base >= 4.0 && < 5, hack >= 2009.10.30, hack-handler-happstack, data-default >= 0.2, rallod -  exposed-modules: Bird, Bird.Request, Bird.Reply, Bird.Request.QueryStringParser, Bird.BirdResponder, Bird.Translator, Bird.Translator.Hack+  build-depends: haskell98, MissingH >= 1.1.0.3, mtl >= 1.1.0.2, process, containers, parsec >= 2.1.0.1, bytestring, base >= 4.0 && < 5, hack >= 2009.10.30, hack-handler-happstack, data-default >= 0.2, rallod +  exposed-modules: Bird, Bird.Logger, Bird.Config, Bird.Request, Bird.Reply, Bird.Request.QueryStringParser, Bird.BirdResponder, Bird.Translator, Bird.Translator.Hack   hs-source-dirs: src/
readme.markdown view
@@ -54,6 +54,7 @@      get [] = do       name <- param "name"+      log "I'm about to greet a Jedi. Teehee!"       body $ "Greetings, " ++ (maybe "Jedi!" id name)  now recompile your app and start it flying:@@ -106,11 +107,14 @@     -- creates/updates a header     -- ex: get [] = body "Hello World" >> header "X-Powered-By" "BIRD!" +    log :: String -> BirdResponder ()+    -- adds to the log+    -- ex: get [] = body "Hello World" >> log "Why did I just greet the world?"+ ## Notes  This project is *still* in its infancy. Coming features: -* logging * post/put/delete http param processing * helpers for popular html generation solutions (Hamlet, HStringTemplate, HAXML, BlazeHTML, etc.) * WAI support
src/Bird.hs view
@@ -3,9 +3,13 @@ , module Bird.Reply , module Bird.Request  , module Bird.BirdResponder+, module Bird.Logger+, module Bird.Config ) where  import Data.Default import Bird.Reply import Bird.Request import Bird.BirdResponder+import Bird.Logger+import Bird.Config
src/Bird/BirdResponder.hs view
@@ -2,16 +2,17 @@  import Control.Monad.State import Control.Monad.Reader+import Control.Monad.Writer import Data.Default import Data.Maybe import Bird.Reply import Bird.Request import qualified Data.Map as Hash -type BirdResponder = StateT Reply (ReaderT Request IO)+type BirdResponder = StateT Reply (ReaderT Request (WriterT [String] IO))  runBirdResponder request router = -  runReaderT (execStateT (router request) def) request+  runWriterT (runReaderT (execStateT (router request) def) request)  body b = do   reply <- get@@ -24,6 +25,9 @@ param paramName = do   request <- ask   return $ maybe Nothing id (lookup paramName $ params request)++log logMessage = do+  tell [logMessage]  mime m = header "Content-Type" m 
+ src/Bird/Config.hs view
@@ -0,0 +1,22 @@+module Bird.Config where ++import Data.Default+import Bird.Logger+import Bird.Request+import Bird.Reply+import Bird.BirdResponder++type Router = Request -> BirdResponder ()++data BirdConfig = +  BirdConfig {+    staticDir :: String+  , birdLogger :: Request -> Router -> IO Reply+  }++instance Default BirdConfig where+  def = +    BirdConfig {+      staticDir   = "static"+    , birdLogger  = defaultLogger+    }
+ src/Bird/Logger.hs view
@@ -0,0 +1,17 @@+module Bird.Logger where++import Bird.BirdResponder+import Bird.Reply+import Bird.Request+import Text.Printf+import qualified Data.String.Utils as StringUtils (join)+import System.CPUTime++defaultLogger request router = do+  let logPrelude = "\n" ++ (show $ verb request) ++ " " ++ (show $ rawRequestUri request)+  start <- getCPUTime+  (reply, logMessages) <- runBirdResponder request router +  end <- getCPUTime+  let logEpilogue = (printf "  Response code: %s" (show $ replyStatus reply)) ++ (printf "\n  Response time: %0.3fs" (((fromIntegral (end - start)) / (10^12)) :: Double))+  putStrLn $ (StringUtils.join "\n" ([logPrelude] ++ logMessages ++ [logEpilogue])) ++ "\n"+  return reply
src/Bird/Request.hs view
@@ -11,10 +11,11 @@  data Request =    Request { -    verb      :: RequestMethod-  , path      :: Path-  , params    :: [(String, Maybe String)]+    verb          :: RequestMethod+  , path          :: Path+  , params        :: [(String, Maybe String)]+  , rawRequestUri :: String   } deriving (Show)  instance Default Request where-  def = Request { verb = GET, path = [], params = [] }+  def = Request { verb = GET, path = [], params = [], rawRequestUri = "/" }
src/Bird/Translator/Hack.hs view
@@ -19,7 +19,7 @@       Hack.body = pack $ replyBody r     }     where-      insertUnlessPresent _ oldValue = oldValue+      insertUnlessPresent = flip const  instance BirdRequestTranslator Hack.Env where   toBirdRequest e = @@ -27,7 +27,13 @@       verb = hackRequestMethodToBirdRequestMethod $ Hack.requestMethod e     , path = split '/' $ Hack.pathInfo e     , params = parseQueryString $ Hack.queryString e+    , rawRequestUri = (Hack.pathInfo e) ++ maybeQueryString e     }+    where+      maybeQueryString e =+        if Hack.queryString e /= ""+        then "?" ++ Hack.queryString e+        else ""   hackRequestMethodToBirdRequestMethod rm =