module Hakyll.FileStore.Context
( fsGetItemUTC
, fsGetItemUTC'
, fsDateField
, fsDateFieldWith
, fsGetItemModificationTime
, fsGetItemModificationTime'
, fsModificationTimeField
, fsModificationTimeFieldWith
, fsGetRevisions
, fsGetAuthors
, fsGetAuthorNames
, fsAuthorNamesField
, fsAuthorNamesFieldWith
, fsGetAuthorEmails
, fsAuthorEmailsField
, fsAuthorEmailsFieldWith
) where
import Control.Monad (liftM)
import Data.Time.Clock (UTCTime)
import Data.FileStore (Author,
FileStore,
Revision,
TimeRange (TimeRange),
authorEmail,
authorName,
history,
revAuthor,
revDateTime)
import Data.List (intercalate, nub)
import Data.Maybe (listToMaybe)
import Data.Time.Format (formatTime)
import Data.Time.Locale.Compat (TimeLocale, defaultTimeLocale)
import Hakyll.Core.Compiler (Compiler, unsafeCompiler)
import Hakyll.Core.Identifier (Identifier, toFilePath)
import Hakyll.Core.Item (itemIdentifier)
import Hakyll.Web.Template.Context (Context,
field,
getItemModificationTime,
getItemUTC)
fsGetWithFallback :: Monad m
=> (FileStore -> Identifier -> m (Maybe a))
-> (Identifier -> m a)
-> FileStore
-> Identifier
-> m a
fsGetWithFallback :: (FileStore -> Identifier -> m (Maybe a))
-> (Identifier -> m a) -> FileStore -> Identifier -> m a
fsGetWithFallback FileStore -> Identifier -> m (Maybe a)
fsF Identifier -> m a
f FileStore
fs Identifier
i = do
Maybe a
maybeIt <- FileStore -> Identifier -> m (Maybe a)
fsF FileStore
fs Identifier
i
m a -> (a -> m a) -> Maybe a -> m a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Identifier -> m a
f Identifier
i) a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe a
maybeIt
extractFromRevisions :: ([Revision] -> a)
-> FileStore
-> Identifier
-> Compiler a
[Revision] -> a
f FileStore
fs Identifier
i = IO a -> Compiler a
forall a. IO a -> Compiler a
unsafeCompiler (IO a -> Compiler a) -> IO a -> Compiler a
forall a b. (a -> b) -> a -> b
$ do
let path :: FilePath
path = Identifier -> FilePath
toFilePath Identifier
i
[Revision]
revisions <- FileStore -> [FilePath] -> TimeRange -> Maybe Int -> IO [Revision]
history FileStore
fs [FilePath
path] (Maybe UTCTime -> Maybe UTCTime -> TimeRange
TimeRange Maybe UTCTime
forall a. Maybe a
Nothing Maybe UTCTime
forall a. Maybe a
Nothing) Maybe Int
forall a. Maybe a
Nothing
a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> IO a) -> a -> IO a
forall a b. (a -> b) -> a -> b
$ [Revision] -> a
f [Revision]
revisions
generateFsField :: (FileStore -> Identifier -> Compiler String)
-> FileStore
-> String
-> Context a
generateFsField :: (FileStore -> Identifier -> Compiler FilePath)
-> FileStore -> FilePath -> Context a
generateFsField FileStore -> Identifier -> Compiler FilePath
fsF FileStore
fs FilePath
key =
FilePath -> (Item a -> Compiler FilePath) -> Context a
forall a. FilePath -> (Item a -> Compiler FilePath) -> Context a
field FilePath
key (FileStore -> Identifier -> Compiler FilePath
fsF FileStore
fs (Identifier -> Compiler FilePath)
-> (Item a -> Identifier) -> Item a -> Compiler FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Item a -> Identifier
forall a. Item a -> Identifier
itemIdentifier)
fsIntercalateToContext :: (FileStore -> Identifier -> Compiler [String])
-> FileStore
-> String
-> String
-> Context a
fsIntercalateToContext :: (FileStore -> Identifier -> Compiler [FilePath])
-> FileStore -> FilePath -> FilePath -> Context a
fsIntercalateToContext FileStore -> Identifier -> Compiler [FilePath]
fsF FileStore
fs FilePath
delimeter =
(FileStore -> Identifier -> Compiler FilePath)
-> FileStore -> FilePath -> Context a
forall a.
(FileStore -> Identifier -> Compiler FilePath)
-> FileStore -> FilePath -> Context a
generateFsField (\ FileStore
fs' -> ([FilePath] -> FilePath)
-> Compiler [FilePath] -> Compiler FilePath
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (FilePath -> [FilePath] -> FilePath
forall a. [a] -> [[a]] -> [a]
intercalate FilePath
delimeter) (Compiler [FilePath] -> Compiler FilePath)
-> (Identifier -> Compiler [FilePath])
-> Identifier
-> Compiler FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FileStore -> Identifier -> Compiler [FilePath]
fsF FileStore
fs') FileStore
fs
generateFsTimeFieldWith :: (FileStore -> Identifier -> Compiler UTCTime)
-> FileStore
-> TimeLocale
-> String
-> String
-> Context a
generateFsTimeFieldWith :: (FileStore -> Identifier -> Compiler UTCTime)
-> FileStore -> TimeLocale -> FilePath -> FilePath -> Context a
generateFsTimeFieldWith FileStore -> Identifier -> Compiler UTCTime
fsF FileStore
fs TimeLocale
locale FilePath
key FilePath
fmt = FilePath -> (Item a -> Compiler FilePath) -> Context a
forall a. FilePath -> (Item a -> Compiler FilePath) -> Context a
field FilePath
key ((Item a -> Compiler FilePath) -> Context a)
-> (Item a -> Compiler FilePath) -> Context a
forall a b. (a -> b) -> a -> b
$ \ Item a
i -> do
UTCTime
time <- FileStore -> Identifier -> Compiler UTCTime
fsF FileStore
fs (Identifier -> Compiler UTCTime) -> Identifier -> Compiler UTCTime
forall a b. (a -> b) -> a -> b
$ Item a -> Identifier
forall a. Item a -> Identifier
itemIdentifier Item a
i
FilePath -> Compiler FilePath
forall (m :: * -> *) a. Monad m => a -> m a
return (FilePath -> Compiler FilePath) -> FilePath -> Compiler FilePath
forall a b. (a -> b) -> a -> b
$ TimeLocale -> FilePath -> UTCTime -> FilePath
forall t. FormatTime t => TimeLocale -> FilePath -> t -> FilePath
formatTime TimeLocale
locale FilePath
fmt UTCTime
time
fsGetItemUTC :: FileStore
-> TimeLocale
-> Identifier
-> Compiler UTCTime
fsGetItemUTC :: FileStore -> TimeLocale -> Identifier -> Compiler UTCTime
fsGetItemUTC FileStore
fs TimeLocale
locale =
(FileStore -> Identifier -> Compiler (Maybe UTCTime))
-> (Identifier -> Compiler UTCTime)
-> FileStore
-> Identifier
-> Compiler UTCTime
forall (m :: * -> *) a.
Monad m =>
(FileStore -> Identifier -> m (Maybe a))
-> (Identifier -> m a) -> FileStore -> Identifier -> m a
fsGetWithFallback FileStore -> Identifier -> Compiler (Maybe UTCTime)
fsGetItemUTC' (TimeLocale -> Identifier -> Compiler UTCTime
forall (m :: * -> *).
(MonadMetadata m, MonadFail m) =>
TimeLocale -> Identifier -> m UTCTime
getItemUTC TimeLocale
locale) FileStore
fs
fsGetItemUTC' :: FileStore
-> Identifier
-> Compiler (Maybe UTCTime)
fsGetItemUTC' :: FileStore -> Identifier -> Compiler (Maybe UTCTime)
fsGetItemUTC' =
([Revision] -> Maybe UTCTime)
-> FileStore -> Identifier -> Compiler (Maybe UTCTime)
forall a.
([Revision] -> a) -> FileStore -> Identifier -> Compiler a
extractFromRevisions ([UTCTime] -> Maybe UTCTime
forall a. [a] -> Maybe a
listToMaybe ([UTCTime] -> Maybe UTCTime)
-> ([Revision] -> [UTCTime]) -> [Revision] -> Maybe UTCTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Revision -> UTCTime) -> [Revision] -> [UTCTime]
forall a b. (a -> b) -> [a] -> [b]
map Revision -> UTCTime
revDateTime ([Revision] -> [UTCTime])
-> ([Revision] -> [Revision]) -> [Revision] -> [UTCTime]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Revision] -> [Revision]
forall a. [a] -> [a]
reverse)
fsDateField :: FileStore
-> String
-> String
-> Context a
fsDateField :: FileStore -> FilePath -> FilePath -> Context a
fsDateField FileStore
fs = FileStore -> TimeLocale -> FilePath -> FilePath -> Context a
forall a.
FileStore -> TimeLocale -> FilePath -> FilePath -> Context a
fsDateFieldWith FileStore
fs TimeLocale
defaultTimeLocale
fsDateFieldWith :: FileStore
-> TimeLocale
-> String
-> String
-> Context a
fsDateFieldWith :: FileStore -> TimeLocale -> FilePath -> FilePath -> Context a
fsDateFieldWith FileStore
fs TimeLocale
locale =
(FileStore -> Identifier -> Compiler UTCTime)
-> FileStore -> TimeLocale -> FilePath -> FilePath -> Context a
forall a.
(FileStore -> Identifier -> Compiler UTCTime)
-> FileStore -> TimeLocale -> FilePath -> FilePath -> Context a
generateFsTimeFieldWith (FileStore -> TimeLocale -> Identifier -> Compiler UTCTime
`fsGetItemUTC` TimeLocale
locale) FileStore
fs TimeLocale
locale
fsGetItemModificationTime :: FileStore
-> Identifier
-> Compiler UTCTime
fsGetItemModificationTime :: FileStore -> Identifier -> Compiler UTCTime
fsGetItemModificationTime =
(FileStore -> Identifier -> Compiler (Maybe UTCTime))
-> (Identifier -> Compiler UTCTime)
-> FileStore
-> Identifier
-> Compiler UTCTime
forall (m :: * -> *) a.
Monad m =>
(FileStore -> Identifier -> m (Maybe a))
-> (Identifier -> m a) -> FileStore -> Identifier -> m a
fsGetWithFallback FileStore -> Identifier -> Compiler (Maybe UTCTime)
fsGetItemModificationTime' Identifier -> Compiler UTCTime
getItemModificationTime
fsGetItemModificationTime' :: FileStore
-> Identifier
-> Compiler (Maybe UTCTime)
fsGetItemModificationTime' :: FileStore -> Identifier -> Compiler (Maybe UTCTime)
fsGetItemModificationTime' =
([Revision] -> Maybe UTCTime)
-> FileStore -> Identifier -> Compiler (Maybe UTCTime)
forall a.
([Revision] -> a) -> FileStore -> Identifier -> Compiler a
extractFromRevisions ([UTCTime] -> Maybe UTCTime
forall a. [a] -> Maybe a
listToMaybe ([UTCTime] -> Maybe UTCTime)
-> ([Revision] -> [UTCTime]) -> [Revision] -> Maybe UTCTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Revision -> UTCTime) -> [Revision] -> [UTCTime]
forall a b. (a -> b) -> [a] -> [b]
map Revision -> UTCTime
revDateTime)
fsModificationTimeField :: FileStore
-> String
-> String
-> Context a
fsModificationTimeField :: FileStore -> FilePath -> FilePath -> Context a
fsModificationTimeField FileStore
fs = FileStore -> TimeLocale -> FilePath -> FilePath -> Context a
forall a.
FileStore -> TimeLocale -> FilePath -> FilePath -> Context a
fsModificationTimeFieldWith FileStore
fs TimeLocale
defaultTimeLocale
fsModificationTimeFieldWith :: FileStore
-> TimeLocale
-> String
-> String
-> Context a
fsModificationTimeFieldWith :: FileStore -> TimeLocale -> FilePath -> FilePath -> Context a
fsModificationTimeFieldWith = (FileStore -> Identifier -> Compiler UTCTime)
-> FileStore -> TimeLocale -> FilePath -> FilePath -> Context a
forall a.
(FileStore -> Identifier -> Compiler UTCTime)
-> FileStore -> TimeLocale -> FilePath -> FilePath -> Context a
generateFsTimeFieldWith FileStore -> Identifier -> Compiler UTCTime
fsGetItemModificationTime
fsGetRevisions :: FileStore
-> Identifier
-> Compiler [Revision]
fsGetRevisions :: FileStore -> Identifier -> Compiler [Revision]
fsGetRevisions = ([Revision] -> [Revision])
-> FileStore -> Identifier -> Compiler [Revision]
forall a.
([Revision] -> a) -> FileStore -> Identifier -> Compiler a
extractFromRevisions [Revision] -> [Revision]
forall a. a -> a
id
fsGetAuthors :: FileStore
-> Identifier
-> Compiler [Author]
fsGetAuthors :: FileStore -> Identifier -> Compiler [Author]
fsGetAuthors FileStore
fs Identifier
i = ([Author] -> [Author]
forall a. Eq a => [a] -> [a]
nub ([Author] -> [Author])
-> ([Revision] -> [Author]) -> [Revision] -> [Author]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Revision -> Author) -> [Revision] -> [Author]
forall a b. (a -> b) -> [a] -> [b]
map Revision -> Author
revAuthor ([Revision] -> [Author])
-> ([Revision] -> [Revision]) -> [Revision] -> [Author]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Revision] -> [Revision]
forall a. [a] -> [a]
reverse) ([Revision] -> [Author])
-> Compiler [Revision] -> Compiler [Author]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FileStore -> Identifier -> Compiler [Revision]
fsGetRevisions FileStore
fs Identifier
i
fsGetAuthorNames :: FileStore
-> Identifier
-> Compiler [String]
fsGetAuthorNames :: FileStore -> Identifier -> Compiler [FilePath]
fsGetAuthorNames FileStore
fs Identifier
i = (Author -> FilePath) -> [Author] -> [FilePath]
forall a b. (a -> b) -> [a] -> [b]
map Author -> FilePath
authorName ([Author] -> [FilePath])
-> Compiler [Author] -> Compiler [FilePath]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FileStore -> Identifier -> Compiler [Author]
fsGetAuthors FileStore
fs Identifier
i
fsAuthorNamesField :: FileStore
-> String
-> Context a
fsAuthorNamesField :: FileStore -> FilePath -> Context a
fsAuthorNamesField = (FileStore -> FilePath -> FilePath -> Context a)
-> FilePath -> FileStore -> FilePath -> Context a
forall a b c. (a -> b -> c) -> b -> a -> c
flip FileStore -> FilePath -> FilePath -> Context a
forall a. FileStore -> FilePath -> FilePath -> Context a
fsAuthorNamesFieldWith FilePath
", "
fsAuthorNamesFieldWith :: FileStore
-> String
-> String
-> Context a
fsAuthorNamesFieldWith :: FileStore -> FilePath -> FilePath -> Context a
fsAuthorNamesFieldWith = (FileStore -> Identifier -> Compiler [FilePath])
-> FileStore -> FilePath -> FilePath -> Context a
forall a.
(FileStore -> Identifier -> Compiler [FilePath])
-> FileStore -> FilePath -> FilePath -> Context a
fsIntercalateToContext FileStore -> Identifier -> Compiler [FilePath]
fsGetAuthorNames
fsGetAuthorEmails :: FileStore
-> Identifier
-> Compiler [String]
fsGetAuthorEmails :: FileStore -> Identifier -> Compiler [FilePath]
fsGetAuthorEmails FileStore
fs Identifier
i = (Author -> FilePath) -> [Author] -> [FilePath]
forall a b. (a -> b) -> [a] -> [b]
map Author -> FilePath
authorEmail ([Author] -> [FilePath])
-> Compiler [Author] -> Compiler [FilePath]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FileStore -> Identifier -> Compiler [Author]
fsGetAuthors FileStore
fs Identifier
i
fsAuthorEmailsField :: FileStore
-> String
-> Context a
fsAuthorEmailsField :: FileStore -> FilePath -> Context a
fsAuthorEmailsField = (FileStore -> FilePath -> FilePath -> Context a)
-> FilePath -> FileStore -> FilePath -> Context a
forall a b c. (a -> b -> c) -> b -> a -> c
flip FileStore -> FilePath -> FilePath -> Context a
forall a. FileStore -> FilePath -> FilePath -> Context a
fsAuthorEmailsFieldWith FilePath
", "
fsAuthorEmailsFieldWith :: FileStore
-> String
-> String
-> Context a
fsAuthorEmailsFieldWith :: FileStore -> FilePath -> FilePath -> Context a
fsAuthorEmailsFieldWith = (FileStore -> Identifier -> Compiler [FilePath])
-> FileStore -> FilePath -> FilePath -> Context a
forall a.
(FileStore -> Identifier -> Compiler [FilePath])
-> FileStore -> FilePath -> FilePath -> Context a
fsIntercalateToContext FileStore -> Identifier -> Compiler [FilePath]
fsGetAuthorEmails