packages feed

bamboo-2009.6.6: src/Bamboo/Controller/Helper.hs

{-# LANGUAGE NoMonomorphismRestriction#-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE NamedFieldPuns #-}

module Bamboo.Controller.Helper where


import Bamboo.Env hiding (get, p)
import Bamboo.Helper.StateHelper
import Bamboo.Type.State
import Control.Monad.State
import Data.Default
import Data.List hiding (length)
import Data.Maybe
import Hack
import Bamboo.Controller.Type
import qualified Hack
import System.IO as IO
import qualified Bamboo.Model.Post as Post
import qualified Bamboo.Model.Tag as Tag
import qualified Bamboo.Model.Comment as Comment
import qualified Bamboo.Type.Pager as Pager
import qualified Bamboo.Type.State as S
import qualified Hack.Contrib.Request as Request


data CachedController = CachedController
  {
    etag_controller :: ETagController
  , controller :: Controller
  }

init_state :: Controller
init_state = fill_latest_posts >> fill_tags

params, inputs :: Env -> Assoc
params = Request.params > map_fst b2u > map_snd b2u
inputs = Request.inputs > map_fst b2u > map_snd b2u

param_with_default, input_with_default :: String -> String -> Env -> String
param_with_default s d env = env .get_param s .fromMaybe d
input_with_default s d env = env .get_input s .fromMaybe d

get_param, get_input :: String -> Env -> Maybe String
get_param s env = env .params .lookup s
get_input s env = env .inputs .lookup s

just_param, just_input :: String -> Env -> String
just_param s env = env .get_param s .fromJust
just_input s env = env .get_input s .fromJust

only_for :: Extension -> (a -> IO Response) -> a -> IO Response
only_for ext x = if has_extension ext then x else const not_found_response

io :: (MonadIO m) => IO a -> m a
io = liftIO

blog_regex :: String
blog_regex = static_config.url_date_matcher


fill_latest_posts :: Part ()
fill_latest_posts = do
  s <- get
  latest_posts <- Post.latest ( s.config.number_of_latest_posts ) .io
  put s { latest_posts }

fill_tags :: Part ()
fill_tags = do
  s <- get
  tags <- list .io
  put s { tags }

paginate :: [a] -> Part Pager
paginate xs = do
  s <- get
  let per_page' = s.config.per_page
      current = s.env.param_with_default "page" "1" .read
      total = xs.length
      has_next = current * per_page' < total.from_i
      has_previous = current `gt` n1
      next         = current + n1
      previous     = current + (- n1)
      n1 = 1 :: Int
  
  return def 
    {
      Pager.per_page = per_page'
    , current       
    , has_next      
    , has_previous  
    , next          
    , previous
    , total      
    }

paged :: [a] -> Part ([a], Pager)
paged xs = do
  pager <- paginate xs
  return (xs.for_current_page pager, pager)
  
for_current_page :: Pager -> [a] -> [a]
for_current_page p xs = 
  xs.drop ((p.current - 1) * p.Pager.per_page) .take (p.Pager.per_page)


init_post_meta_data :: Post.Post -> Part Post.Post
init_post_meta_data x = do
  tags <- get ^ tags
  x.Tag.fill_tag tags.Comment.fill_comment_size.io

run :: Controller -> View -> Application
run x v env = do
  s <- execStateT x def {env}
  v s
  
  
  {- cache should

      * get tag from env
      * get tag from current controller
      * if equal
          then return unmodify
          else return data
  -}

not_found :: Controller
not_found = get >>= \s -> put s {S.status = 404}

not_found_response :: IO Response
not_found_response = return $ def { Hack.status = 404 }