This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "heist".

The branch, master has been updated
       via  599a6e874e881a4748d43b4f89309d0e60934a80 (commit)
      from  adeb763231793c424ba2d6e5493ed2e74e879e20 (commit)


Summary of changes:
 heist.cabal                                |    2 +
 src/Text/Templating/Heist/Splices.hs       |    1 +
 src/Text/Templating/Heist/Splices/Cache.hs |  146 ++++++++++++++++++++++++++++
 3 files changed, 149 insertions(+), 0 deletions(-)
 create mode 100644 src/Text/Templating/Heist/Splices/Cache.hs

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 599a6e874e881a4748d43b4f89309d0e60934a80
Author: Mighty Byte <[email protected]>
Date:   Fri Mar 18 00:55:30 2011 -0400

    Added a splice for a <cache> tag.

diff --git a/heist.cabal b/heist.cabal
index 7bffeee..beefb61 100644
--- a/heist.cabal
+++ b/heist.cabal
@@ -68,6 +68,7 @@ Library
     Text.Templating.Heist.Splices,
     Text.Templating.Heist.Splices.Apply,
     Text.Templating.Heist.Splices.Bind,
+    Text.Templating.Heist.Splices.Cache,
     Text.Templating.Heist.Splices.Html,
     Text.Templating.Heist.Splices.Ignore,
     Text.Templating.Heist.Splices.Markdown,
@@ -93,6 +94,7 @@ Library
     process,
     random,
     text >= 0.10 && < 0.12,
+    time >= 1.1 && < 1.3,
     transformers,
     xmlhtml == 0.1.*
 
diff --git a/src/Text/Templating/Heist/Splices.hs 
b/src/Text/Templating/Heist/Splices.hs
index 96a0bf5..5b2042f 100644
--- a/src/Text/Templating/Heist/Splices.hs
+++ b/src/Text/Templating/Heist/Splices.hs
@@ -9,6 +9,7 @@ module Text.Templating.Heist.Splices
 
 import Text.Templating.Heist.Splices.Apply
 import Text.Templating.Heist.Splices.Bind
+import Text.Templating.Heist.Splices.Cache
 import Text.Templating.Heist.Splices.Html
 import Text.Templating.Heist.Splices.Ignore
 import Text.Templating.Heist.Splices.Markdown
diff --git a/src/Text/Templating/Heist/Splices/Cache.hs 
b/src/Text/Templating/Heist/Splices/Cache.hs
new file mode 100644
index 0000000..2ba59a8
--- /dev/null
+++ b/src/Text/Templating/Heist/Splices/Cache.hs
@@ -0,0 +1,146 @@
+module Text.Templating.Heist.Splices.Cache
+  ( CacheTagState
+  , mkCacheTag
+  , clearCacheTagState
+  ) where
+
+------------------------------------------------------------------------------
+import           Control.Concurrent
+import           Control.Monad
+import           Control.Monad.Trans
+import           Data.IORef
+import qualified Data.Map as Map
+import           Data.Map (Map)
+import           Data.Maybe
+import qualified Data.Set as Set
+import           Data.Text (Text)
+import qualified Data.Text as T
+import           Data.Text.Read
+import           Data.Time.Clock
+import           System.Random
+import           Text.XmlHtml.Cursor
+import           Text.XmlHtml hiding (Node)
+
+
+------------------------------------------------------------------------------
+import           Text.Templating.Heist.Internal
+import           Text.Templating.Heist.Types
+
+
+cacheTagName :: Text
+cacheTagName = "cache"
+
+------------------------------------------------------------------------------
+-- | State for storing cache tag information
+newtype CacheTagState = CTS (MVar (Map Text (UTCTime, Template)))
+
+
+------------------------------------------------------------------------------
+-- | Clears the cache tag state.
+clearCacheTagState :: CacheTagState -> IO ()
+clearCacheTagState (CTS cacheMVar) =
+    modifyMVar_ cacheMVar (const $ return Map.empty)
+
+
+------------------------------------------------------------------------------
+-- | Converts a TTL string into an integer number of seconds.
+parseTTL :: Text -> Int
+parseTTL s = value * multiplier
+  where
+    value = either (const 0) fst $ decimal s
+    multiplier = case T.last s of
+        's' -> 1
+        'm' -> 60
+        'h' -> 3600
+        'd' -> 86400
+        'w' -> 604800
+        _   -> 0
+        
+------------------------------------------------------------------------------
+-- | The \"cache\" splice ensures that its contents are cached and only
+-- evaluated periodically.  The cached contents are returned every time the
+-- splice is referenced.
+--
+-- Use the ttl attribute to set the amount of time between reloads.  The ttl
+-- value should be a positive integer followed by a single character
+-- specifying the units.  Valid units are seconds, minutes, hours, days, and
+-- weeks.  If the ttl string is invalid or the ttl attribute is not specified,
+-- the cache is never refreshed unless explicitly cleared with
+-- clearCacheTagState.
+cacheImpl :: (MonadIO m)
+           => CacheTagState
+           -> TemplateMonad m Template
+cacheImpl (CTS mv) = do
+    tree <- getParamNode
+    let i = fromJust $ getAttribute "id" tree
+        ttl = maybe 0 parseTTL $ getAttribute "ttl" tree
+    mp <- liftIO $ readMVar mv
+
+    (mp',ns) <- do
+                   curTime <- liftIO getCurrentTime
+                   let mbn = Map.lookup i mp
+                       reload = do
+                           nodes' <- runNodeList $ childNodes tree
+                           return $! (Map.insert i (curTime,nodes') mp, nodes')
+                   case mbn of
+                       Nothing -> reload
+                       (Just (lastUpdate,n)) -> do
+                           if ttl > 0 &&
+                              diffUTCTime curTime lastUpdate > fromIntegral ttl
+                             then reload
+                             else do
+                                 stopRecursion
+                                 return $! (mp,n)
+
+    liftIO $ modifyMVar_ mv (const $ return mp')
+
+    return ns
+
+
+mkCacheTagState :: IO CacheTagState
+mkCacheTagState = liftM CTS $ newMVar Map.empty
+
+------------------------------------------------------------------------------
+-- | Modifies a TemplateState to include a \"cache\" tag.  The cache tag is
+-- not bound automatically with the other default Heist tags.  This is because
+-- this function also returns CacheTagState, so the user will be able to
+-- clear it with the 'clearCacheTagState' function.
+mkCacheTag :: MonadIO m
+           => IO (TemplateState m -> TemplateState m, CacheTagState)
+mkCacheTag = do
+    sr <- newIORef $ Set.empty
+    mv <- liftM CTS $ newMVar Map.empty
+
+    return $ (addOnLoadHook (assignIds sr) .
+              bindSplice cacheTagName (cacheImpl mv), mv)
+
+  where
+    generateId :: IO Int
+    generateId = getStdRandom random
+
+    assignIds setref = mapM f
+        where
+          f node = g $ fromNode node
+
+          getId = do
+              i  <- liftM (T.pack . show) generateId
+              st <- readIORef setref
+              if Set.member i st
+                then getId
+                else do
+                    writeIORef setref $ Set.insert i st
+                    return $ T.append "cache-id-" i
+
+          g curs = do
+              let node = current curs
+              curs' <- if tagName node == Just cacheTagName
+                         then do
+                             i <- getId
+                             return $ modifyNode (setAttribute "id" i) curs
+                         else return curs
+              let mbc = nextDF curs'
+              maybe (return $ topNode curs') g mbc
+
+
+
+
-----------------------------------------------------------------------


hooks/post-receive
-- 
heist
_______________________________________________
Snap mailing list
[email protected]
http://mailman-mail5.webfaction.com/listinfo/snap

Reply via email to