muon-0.1.0.0: src/Post.hs
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveDataTypeable #-}
module Post where
import qualified Data.Text as T
import qualified Data.Text.Lazy as TL
import Text.StringTemplate
import Text.StringTemplate.GenericStandard
import Text.Blaze.Html.Renderer.Text
import Text.Markdown
import System.Directory
import System.FilePath.Glob
import Data.Typeable
import Data.Data
import Data.List
import Site
import Control.Monad
import Constant
postPath = "posts/" :: String
data Post = Post { title :: T.Text
, link :: T.Text
, date :: T.Text
, comment :: T.Text
, content :: T.Text
} deriving (Data, Typeable, Show)
postTemplate = do
templates <- directoryGroup "templates" :: IO (STGroup T.Text)
let Just t = getStringTemplate "post" templates
return t
renderPost :: StringTemplate T.Text -> Post -> T.Text
renderPost t p = render
$ setAttribute "site" defaultSite
$ setAttribute "post" p t
renderName :: StringTemplate T.Text -> String -> IO T.Text
renderName t n = liftM (renderPost t) (getPost (0, n))
makeExtract :: Post -> T.Text
makeExtract p = T.pack
$ "<h2>" ++ T.unpack (title p) ++ "</h2>"
++ "<h3>" ++ T.unpack (date p) ++ "</h3>"
++ unlines (take 25 $ lines $ T.unpack $ content p)
++ "<br/><br/><a href=\'" ++ T.unpack (link p) ++ "\'>Read more...</a>"
++ "</code></pre></li></ul></ol><hr/>"
makePost :: (Int, [String]) -> Post
makePost l = Post { title = T.pack $ head (snd l)
, link = T.pack $ "/post/" ++ show (fst l)
, date = T.pack $ snd l !! 1
, comment = T.pack $ snd l !! 2
, content = T.pack $ extractContent (snd l) }
extractContent :: [String] -> String
extractContent l = TL.unpack
$ renderHtml
$ markdown def
$ TL.pack
$ unlines
$ drop 3 l
getPost :: (Int, FilePath) -> IO Post
getPost n = do
c <- readFile (snd n)
return $ makePost (fst n, lines c)
getNames :: IO [(Int, FilePath)]
getNames = do
d <- globDir [compile "*.post"] postPath
let l = (sort . head . fst) d
return $ zip [1..(length l)] l
renderPosts :: IO [T.Text]
renderPosts = do
templates <- directoryGroup "templates" :: IO (STGroup T.Text)
let Just t = getStringTemplate "post" templates
ns <- getNames
mapM (renderName t . snd) ns
writePosts :: [T.Text] -> IO ()
writePosts ps = mapM_ writePost (zip [1..(length ps)] ps)
writePost :: (Int, T.Text) -> IO ()
writePost p = do
mkdir $ sitePath ++ "post"
mkdir $ sitePath ++ "post/" ++ show (fst p)
writeFile (sitePath ++ "post/" ++ show (fst p) ++ "/index.html") (T.unpack $ T.append "\n" $ snd p)
getAllPosts = do
ns <- getNames
mapM getPost ns
getAllExtracts = do
ps <- getAllPosts
return $ map makeExtract ps
generatePosts = renderPosts >>= writePosts >> putStrLn "Generated posts"