summaryrefslogtreecommitdiff
path: root/src/Hakyll/Core/Resource/Provider.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Hakyll/Core/Resource/Provider.hs')
-rw-r--r--src/Hakyll/Core/Resource/Provider.hs138
1 files changed, 29 insertions, 109 deletions
diff --git a/src/Hakyll/Core/Resource/Provider.hs b/src/Hakyll/Core/Resource/Provider.hs
index 2ed7797..8f4c83f 100644
--- a/src/Hakyll/Core/Resource/Provider.hs
+++ b/src/Hakyll/Core/Resource/Provider.hs
@@ -1,125 +1,45 @@
--------------------------------------------------------------------------------
--- | This module provides an API for resource providers. Resource providers
--- allow Hakyll to get content from resources; the type of resource depends on
--- the concrete instance.
---
--- A resource is represented by the 'Resource' type. This is basically just a
--- newtype wrapper around 'Identifier' -- but it has an important effect: it
--- guarantees that a resource with this identifier can be provided by one or
--- more resource providers.
---
--- Therefore, it is not recommended to read files directly -- you should use the
--- provided 'Resource' methods.
---
+-- | This module provides an wrapper API around the file system which does some
+-- caching.
module Hakyll.Core.Resource.Provider
- ( ResourceProvider (..)
+ ( -- * Constructing resource providers
+ ResourceProvider
+ , newResourceProvider
+
+ -- * Querying resource properties
, resourceList
- , makeResourceProvider
, resourceExists
- , resourceDigest
, resourceModified
- ) where
-
-
---------------------------------------------------------------------------------
-import Control.Applicative ((<$>))
-import Control.Concurrent (MVar, readMVar, modifyMVar_, newMVar)
-import Data.Map (Map)
-import qualified Data.Map as M
-import qualified Data.Set as S
-
-
---------------------------------------------------------------------------------
-import Data.Time (UTCTime)
-import qualified Crypto.Hash.MD5 as MD5
-import qualified Data.ByteString as B
-import qualified Data.ByteString.Lazy as LB
-
-
---------------------------------------------------------------------------------
-import Hakyll.Core.Store (Store)
-import Hakyll.Core.Resource
-import qualified Hakyll.Core.Store as Store
+ , resourceModificationTime
+ -- * Access to raw resource content
+ , resourceString
+ , resourceLBS
---------------------------------------------------------------------------------
--- | A value responsible for retrieving and listing resources
-data ResourceProvider = ResourceProvider
- { -- | A set of all resources this provider is able to provide
- resourceSet :: S.Set Resource
- , -- | Retrieve a certain resource as string
- resourceString :: Resource -> IO String
- , -- | Retrieve a certain resource as lazy bytestring
- resourceLBS :: Resource -> IO LB.ByteString
- , -- | Check when a resource was last modified
- resourceModificationTime :: Resource -> IO UTCTime
- , -- | Cache keeping track of modified items
- resourceModifiedCache :: MVar (Map Resource Bool)
- }
-
-
---------------------------------------------------------------------------------
--- | Create a resource provider
-makeResourceProvider :: [Resource] -- ^ Resource list
- -> (Resource -> IO String) -- ^ String reader
- -> (Resource -> IO LB.ByteString) -- ^ ByteString reader
- -> (Resource -> IO UTCTime) -- ^ Time checker
- -> IO ResourceProvider -- ^ Resulting provider
-makeResourceProvider l s b t =
- ResourceProvider (S.fromList l) s b t <$> newMVar M.empty
-
-
---------------------------------------------------------------------------------
--- | Get the list of all resources
-resourceList :: ResourceProvider -> [Resource]
-resourceList = S.toList . resourceSet
-
-
---------------------------------------------------------------------------------
--- | Check if a given identifier has a resource
-resourceExists :: ResourceProvider -> Resource -> Bool
-resourceExists provider = flip S.member $ resourceSet provider
+ -- * Access to metadata and body content
+ , resourceMetadata
+ , resourceBody
+ ) where
--------------------------------------------------------------------------------
--- | Retrieve a digest for a given resource
-resourceDigest :: ResourceProvider -> Resource -> IO B.ByteString
-resourceDigest provider = fmap MD5.hashlazy . resourceLBS provider
+import Hakyll.Core.Resource
+import qualified Hakyll.Core.Resource.MetadataCache as Internal
+import Hakyll.Core.Resource.Modified
+import Hakyll.Core.Resource.Provider.Internal
--------------------------------------------------------------------------------
--- | Check if a resource was modified
-resourceModified :: ResourceProvider -> Store -> Resource -> IO Bool
-resourceModified provider store r = do
- cache <- readMVar mvar
- case M.lookup r cache of
- -- Already in the cache
- Just m -> return m
- -- Not yet in the cache, check digests (if it exists)
- Nothing -> do
- m <- if resourceExists provider r
- then digestModified provider store r
- else return False
- modifyMVar_ mvar (return . M.insert r m)
- return m
- where
- mvar = resourceModifiedCache provider
+-- | Wrapper to ensure metadata cache is invalidated if necessary
+resourceMetadata :: ResourceProvider -> Resource -> IO Metadata
+resourceMetadata rp r = do
+ _ <- resourceModified rp r
+ Internal.resourceMetadata rp r
--------------------------------------------------------------------------------
--- | Check if a resource digest was modified
-digestModified :: ResourceProvider -> Store -> Resource -> IO Bool
-digestModified provider store r = do
- -- Get the latest seen digest from the store
- lastDigest <- Store.get store key
- -- Calculate the digest for the resource
- newDigest <- resourceDigest provider r
- -- Check digests
- if Store.Found newDigest == lastDigest
- -- All is fine, not modified
- then return False
- -- Resource modified; store new digest
- else do Store.set store key newDigest
- return True
- where
- key = ["Hakyll.Core.ResourceProvider.digestModified", unResource r]
+-- | Wrapper to ensure metadata cache is invalidated if necessary
+resourceBody :: ResourceProvider -> Resource -> IO String
+resourceBody rp r = do
+ _ <- resourceModified rp r
+ Internal.resourceBody rp r