{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedLists #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PackageImports #-}
{-# LANGUAGE TemplateHaskell #-}
{-# Language QuasiQuotes #-}
module Yesod.Static.Streamly (
staticStreamly,
staticDevelStreamly,
staticFilesStreamly,
staticFilesListStreamly,
staticFilesMapStreamly,
staticFilesMergeMapStreamly,
publicFilesStreamly
) where
import Yesod.Static.Streamly.Internal
import Data.List (foldl')
import qualified Data.Map as M
import Language.Haskell.TH
import Language.Haskell.TH.Syntax as TH
import Network.Wai.Application.Static (webAppSettingsWithLookup)
import qualified System.FilePath as FP
import Yesod.Static
staticStreamly :: FilePath
-> Int
-> IO Static
staticStreamly :: FilePath -> Int -> IO Static
staticStreamly FilePath
dir Int
size = do
ETagLookup
hashLookup <- FilePath -> Int -> IO ETagLookup
cachedETagLookupStreamly FilePath
dir
Int
size
Static -> IO Static
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Static -> IO Static) -> Static -> IO Static
forall a b. (a -> b) -> a -> b
$ StaticSettings -> Static
Static (StaticSettings -> Static) -> StaticSettings -> Static
forall a b. (a -> b) -> a -> b
$ FilePath -> ETagLookup -> StaticSettings
webAppSettingsWithLookup FilePath
dir ETagLookup
hashLookup
staticDevelStreamly :: FilePath
-> Int
-> IO Static
staticDevelStreamly :: FilePath -> Int -> IO Static
staticDevelStreamly FilePath
dir Int
size = do
ETagLookup
hashLookup <- FilePath -> Int -> IO ETagLookup
cachedETagLookupDevelStreamly FilePath
dir
Int
size
Static -> IO Static
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Static -> IO Static) -> Static -> IO Static
forall a b. (a -> b) -> a -> b
$ StaticSettings -> Static
Static (StaticSettings -> Static) -> StaticSettings -> Static
forall a b. (a -> b) -> a -> b
$ FilePath -> ETagLookup -> StaticSettings
webAppSettingsWithLookup FilePath
dir ETagLookup
hashLookup
staticFilesStreamly :: FilePath
-> Int
-> Q [Dec]
staticFilesStreamly :: FilePath -> Int -> Q [Dec]
staticFilesStreamly FilePath
dir Int
size = FilePath -> Int -> Q [Dec]
mkStaticFilesStreamly FilePath
dir
Int
size
staticFilesListStreamly :: FilePath
-> [FilePath]
-> Int
-> Q [Dec]
staticFilesListStreamly :: FilePath -> [FilePath] -> Int -> Q [Dec]
staticFilesListStreamly FilePath
dir [FilePath]
fs Int
size =
FilePath -> [[FilePath]] -> Bool -> Int -> Q [Dec]
mkStaticFilesListStreamly FilePath
dir
((FilePath -> [FilePath]) -> [FilePath] -> [[FilePath]]
forall a b. (a -> b) -> [a] -> [b]
map FilePath -> [FilePath]
split [FilePath]
fs)
Bool
True
Int
size
where
split :: FilePath
-> [String]
split :: FilePath -> [FilePath]
split [] = []
split FilePath
x = let (FilePath
a, FilePath
b) = (Char -> Bool) -> FilePath -> (FilePath, FilePath)
forall a. (a -> Bool) -> [a] -> ([a], [a])
break (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'/') FilePath
x
in FilePath
a FilePath -> [FilePath] -> [FilePath]
forall a. a -> [a] -> [a]
: FilePath -> [FilePath]
split (Int -> FilePath -> FilePath
forall a. Int -> [a] -> [a]
drop Int
1 FilePath
b)
staticFilesMapStreamly :: FilePath
-> M.Map FilePath FilePath
-> Int
-> Q [Dec]
staticFilesMapStreamly :: FilePath -> Map FilePath FilePath -> Int -> Q [Dec]
staticFilesMapStreamly FilePath
fp Map FilePath FilePath
m Int
size =
FilePath -> [([FilePath], [FilePath])] -> Bool -> Int -> Q [Dec]
mkStaticFilesListStreamly' FilePath
fp
(((FilePath, FilePath) -> ([FilePath], [FilePath]))
-> [(FilePath, FilePath)] -> [([FilePath], [FilePath])]
forall a b. (a -> b) -> [a] -> [b]
map (FilePath, FilePath) -> ([FilePath], [FilePath])
splitBoth [(FilePath, FilePath)]
mapList)
Bool
True
Int
size
where
splitBoth :: (FilePath, FilePath) -> ([FilePath], [FilePath])
splitBoth (FilePath
k, FilePath
v) = (FilePath -> [FilePath]
split FilePath
k, FilePath -> [FilePath]
split FilePath
v)
mapList :: [(FilePath, FilePath)]
mapList = Map FilePath FilePath -> [(FilePath, FilePath)]
forall k a. Map k a -> [(k, a)]
M.toList Map FilePath FilePath
m
split :: FilePath
-> [String]
split :: FilePath -> [FilePath]
split [] = []
split FilePath
x = let (FilePath
a, FilePath
b) = (Char -> Bool) -> FilePath -> (FilePath, FilePath)
forall a. (a -> Bool) -> [a] -> ([a], [a])
break (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'/') FilePath
x
in FilePath
a FilePath -> [FilePath] -> [FilePath]
forall a. a -> [a] -> [a]
: FilePath -> [FilePath]
split (Int -> FilePath -> FilePath
forall a. Int -> [a] -> [a]
drop Int
1 FilePath
b)
staticFilesMergeMapStreamly :: FilePath
-> M.Map FilePath FilePath
-> Int
-> Q [Dec]
staticFilesMergeMapStreamly :: FilePath -> Map FilePath FilePath -> Int -> Q [Dec]
staticFilesMergeMapStreamly FilePath
fp Map FilePath FilePath
m Int
size = do
[[FilePath]]
fs <- IO [[FilePath]] -> Q [[FilePath]]
forall a. IO a -> Q a
forall (m :: * -> *) a. Quasi m => IO a -> m a
qRunIO (IO [[FilePath]] -> Q [[FilePath]])
-> IO [[FilePath]] -> Q [[FilePath]]
forall a b. (a -> b) -> a -> b
$ FilePath -> IO [[FilePath]]
getFileListPiecesStreamly FilePath
fp
let filesList :: [FilePath]
filesList = ([FilePath] -> FilePath) -> [[FilePath]] -> [FilePath]
forall a b. (a -> b) -> [a] -> [b]
map [FilePath] -> FilePath
FP.joinPath [[FilePath]]
fs
mergedMapList :: [(FilePath, FilePath)]
mergedMapList = Map FilePath FilePath -> [(FilePath, FilePath)]
forall k a. Map k a -> [(k, a)]
M.toList (Map FilePath FilePath -> [(FilePath, FilePath)])
-> Map FilePath FilePath -> [(FilePath, FilePath)]
forall a b. (a -> b) -> a -> b
$ (Map FilePath FilePath -> FilePath -> Map FilePath FilePath)
-> Map FilePath FilePath -> [FilePath] -> Map FilePath FilePath
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (Map FilePath FilePath
-> Map FilePath FilePath -> FilePath -> Map FilePath FilePath
checkedInsert Map FilePath FilePath
invertedMap) Map FilePath FilePath
m [FilePath]
filesList
FilePath -> [([FilePath], [FilePath])] -> Bool -> Int -> Q [Dec]
mkStaticFilesListStreamly' FilePath
fp
(((FilePath, FilePath) -> ([FilePath], [FilePath]))
-> [(FilePath, FilePath)] -> [([FilePath], [FilePath])]
forall a b. (a -> b) -> [a] -> [b]
map (FilePath, FilePath) -> ([FilePath], [FilePath])
splitBoth [(FilePath, FilePath)]
mergedMapList)
Bool
True
Int
size
where
splitBoth :: (FilePath, FilePath) -> ([FilePath], [FilePath])
splitBoth (FilePath
k,FilePath
v) = (FilePath -> [FilePath]
split FilePath
k, FilePath -> [FilePath]
split FilePath
v)
swap :: (b, a) -> (a, b)
swap (b
x,a
y) = (a
y, b
x)
mapList :: [(FilePath, FilePath)]
mapList = Map FilePath FilePath -> [(FilePath, FilePath)]
forall k a. Map k a -> [(k, a)]
M.toList Map FilePath FilePath
m
invertedMap :: Map FilePath FilePath
invertedMap = [(FilePath, FilePath)] -> Map FilePath FilePath
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([(FilePath, FilePath)] -> Map FilePath FilePath)
-> [(FilePath, FilePath)] -> Map FilePath FilePath
forall a b. (a -> b) -> a -> b
$ ((FilePath, FilePath) -> (FilePath, FilePath))
-> [(FilePath, FilePath)] -> [(FilePath, FilePath)]
forall a b. (a -> b) -> [a] -> [b]
map (FilePath, FilePath) -> (FilePath, FilePath)
forall {b} {a}. (b, a) -> (a, b)
swap [(FilePath, FilePath)]
mapList
split :: FilePath
-> [String]
split :: FilePath -> [FilePath]
split [] = []
split FilePath
x = let (FilePath
a, FilePath
b) = (Char -> Bool) -> FilePath -> (FilePath, FilePath)
forall a. (a -> Bool) -> [a] -> ([a], [a])
break (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'/') FilePath
x
in FilePath
a FilePath -> [FilePath] -> [FilePath]
forall a. a -> [a] -> [a]
: FilePath -> [FilePath]
split (Int -> FilePath -> FilePath
forall a. Int -> [a] -> [a]
drop Int
1 FilePath
b)
checkedInsert
:: M.Map FilePath FilePath
-> M.Map FilePath FilePath
-> FilePath
-> M.Map FilePath FilePath
checkedInsert :: Map FilePath FilePath
-> Map FilePath FilePath -> FilePath -> Map FilePath FilePath
checkedInsert Map FilePath FilePath
iDict Map FilePath FilePath
st FilePath
p = if FilePath -> Map FilePath FilePath -> Bool
forall k a. Ord k => k -> Map k a -> Bool
M.member FilePath
p Map FilePath FilePath
iDict
then Map FilePath FilePath
st
else FilePath
-> FilePath -> Map FilePath FilePath -> Map FilePath FilePath
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert FilePath
p FilePath
p Map FilePath FilePath
st
publicFilesStreamly :: FilePath
-> Int
-> Q [Dec]
publicFilesStreamly :: FilePath -> Int -> Q [Dec]
publicFilesStreamly FilePath
dir Int
size = FilePath -> Bool -> Int -> Q [Dec]
mkStaticFilesStreamly' FilePath
dir
Bool
False
Int
size