aboutsummaryrefslogtreecommitdiff
path: root/compiler/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/src')
-rw-r--r--compiler/src/Compiler.hs131
-rw-r--r--compiler/src/Config.hs60
-rw-r--r--compiler/src/Files.hs183
-rw-r--r--compiler/src/Input.hs126
-rw-r--r--compiler/src/Processors.hs201
-rw-r--r--compiler/src/Resource.hs198
6 files changed, 899 insertions, 0 deletions
diff --git a/compiler/src/Compiler.hs b/compiler/src/Compiler.hs
new file mode 100644
index 0000000..a347433
--- /dev/null
+++ b/compiler/src/Compiler.hs
@@ -0,0 +1,131 @@
1-- ldgallery - A static generator which turns a collection of tagged
2-- pictures into a searchable web gallery.
3--
4-- Copyright (C) 2019-2020 Pacien TRAN-GIRARD
5--
6-- This program is free software: you can redistribute it and/or modify
7-- it under the terms of the GNU Affero General Public License as
8-- published by the Free Software Foundation, either version 3 of the
9-- License, or (at your option) any later version.
10--
11-- This program is distributed in the hope that it will be useful,
12-- but WITHOUT ANY WARRANTY; without even the implied warranty of
13-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14-- GNU Affero General Public License for more details.
15--
16-- You should have received a copy of the GNU Affero General Public License
17-- along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19module Compiler
20 ( compileGallery
21 ) where
22
23
24import Control.Monad (liftM2)
25import Data.List (any)
26import System.FilePath ((</>))
27import qualified System.FilePath.Glob as Glob
28
29import Data.Aeson (ToJSON)
30import qualified Data.Aeson as JSON
31
32import Config
33import Input (readInputTree)
34import Resource (buildGalleryTree, galleryCleanupResourceDir)
35import Files
36 ( FileName
37 , FSNode(..)
38 , readDirectory
39 , isHidden
40 , nodeName
41 , filterDir
42 , ensureParentDir )
43import Processors
44 ( itemFileProcessor, thumbnailFileProcessor
45 , skipCached, withCached )
46
47
48galleryConf :: String
49galleryConf = "gallery.yaml"
50
51indexFile :: String
52indexFile = "index.json"
53
54viewerMainFile :: String
55viewerMainFile = "index.html"
56
57viewerConfFile :: String
58viewerConfFile = "viewer.json"
59
60itemsDir :: String
61itemsDir = "items"
62
63thumbnailsDir :: String
64thumbnailsDir = "thumbnails"
65
66
67writeJSON :: ToJSON a => FileName -> a -> IO ()
68writeJSON outputPath object =
69 do
70 putStrLn $ "Generating:\t" ++ outputPath
71 ensureParentDir JSON.encodeFile outputPath object
72
73
74galleryDirFilter :: ([Glob.Pattern], [Glob.Pattern]) -> FSNode -> Bool
75galleryDirFilter (inclusionPatterns, exclusionPatterns) =
76 (not . isHidden)
77 &&& (matchName True $ anyPattern inclusionPatterns)
78 &&& (not . isConfigFile)
79 &&& (not . containsOutputGallery)
80 &&& (not . (matchName False $ anyPattern exclusionPatterns))
81
82 where
83 (&&&) = liftM2 (&&)
84 (|||) = liftM2 (||)
85
86 matchName :: Bool -> (FileName -> Bool) -> FSNode -> Bool
87 matchName matchDir _ Dir{} = matchDir
88 matchName _ cond file@File{} = maybe False cond $ nodeName file
89
90 anyPattern :: [Glob.Pattern] -> FileName -> Bool
91 anyPattern patterns filename = any (flip Glob.match filename) patterns
92
93 isConfigFile = matchName False (== galleryConf)
94 isGalleryIndex = matchName False (== indexFile)
95 isViewerIndex = matchName False (== viewerMainFile)
96 containsOutputGallery File{} = False
97 containsOutputGallery Dir{items} = any (isGalleryIndex ||| isViewerIndex) items
98
99
100compileGallery :: FilePath -> FilePath -> Bool -> IO ()
101compileGallery inputDirPath outputDirPath rebuildAll =
102 do
103 fullConfig <- readConfig inputGalleryConf
104 let config = compiler fullConfig
105
106 inputDir <- readDirectory inputDirPath
107 let inclusionPatterns = map Glob.compile $ includeFiles config
108 let exclusionPatterns = map Glob.compile $ excludeFiles config
109 let sourceFilter = galleryDirFilter (inclusionPatterns, exclusionPatterns)
110 let sourceTree = filterDir sourceFilter inputDir
111 inputTree <- readInputTree sourceTree
112
113 let cache = if rebuildAll then skipCached else withCached
114 let itemProc = itemProcessor (pictureMaxResolution config) cache
115 let thumbnailProc = thumbnailProcessor (thumbnailMaxResolution config) cache
116 let galleryBuilder = buildGalleryTree itemProc thumbnailProc (tagsFromDirectories config)
117 resources <- galleryBuilder (galleryName config) inputTree
118
119 galleryCleanupResourceDir resources outputDirPath
120 writeJSON outputIndex resources
121 writeJSON outputViewerConf $ viewer fullConfig
122
123 where
124 inputGalleryConf = inputDirPath </> galleryConf
125 outputIndex = outputDirPath </> indexFile
126 outputViewerConf = outputDirPath </> viewerConfFile
127
128 itemProcessor maxRes cache =
129 itemFileProcessor maxRes cache inputDirPath outputDirPath itemsDir
130 thumbnailProcessor thumbRes cache =
131 thumbnailFileProcessor thumbRes cache inputDirPath outputDirPath thumbnailsDir
diff --git a/compiler/src/Config.hs b/compiler/src/Config.hs
new file mode 100644
index 0000000..53333a5
--- /dev/null
+++ b/compiler/src/Config.hs
@@ -0,0 +1,60 @@
1-- ldgallery - A static generator which turns a collection of tagged
2-- pictures into a searchable web gallery.
3--
4-- Copyright (C) 2019-2020 Pacien TRAN-GIRARD
5--
6-- This program is free software: you can redistribute it and/or modify
7-- it under the terms of the GNU Affero General Public License as
8-- published by the Free Software Foundation, either version 3 of the
9-- License, or (at your option) any later version.
10--
11-- This program is distributed in the hope that it will be useful,
12-- but WITHOUT ANY WARRANTY; without even the implied warranty of
13-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14-- GNU Affero General Public License for more details.
15--
16-- You should have received a copy of the GNU Affero General Public License
17-- along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19module Config
20 ( GalleryConfig(..)
21 , CompilerConfig(..)
22 , readConfig
23 ) where
24
25
26import GHC.Generics (Generic)
27import Data.Aeson (FromJSON, withObject, (.:?), (.!=))
28import qualified Data.Aeson as JSON
29
30import Files (FileName)
31import Input (decodeYamlFile)
32import Resource (Resolution(..))
33
34
35data CompilerConfig = CompilerConfig
36 { galleryName :: String
37 , includeFiles :: [String]
38 , excludeFiles :: [String]
39 , tagsFromDirectories :: Int
40 , thumbnailMaxResolution :: Resolution
41 , pictureMaxResolution :: Maybe Resolution
42 } deriving (Generic, Show)
43
44instance FromJSON CompilerConfig where
45 parseJSON = withObject "CompilerConfig" $ \v -> CompilerConfig
46 <$> v .:? "galleryName" .!= "Gallery"
47 <*> v .:? "includeFiles" .!= ["*"]
48 <*> v .:? "excludeFiles" .!= []
49 <*> v .:? "tagsFromDirectories" .!= 0
50 <*> v .:? "thumbnailMaxResolution" .!= (Resolution 400 400)
51 <*> v .:? "pictureMaxResolution"
52
53
54data GalleryConfig = GalleryConfig
55 { compiler :: CompilerConfig
56 , viewer :: JSON.Object
57 } deriving (Generic, FromJSON, Show)
58
59readConfig :: FileName -> IO GalleryConfig
60readConfig = decodeYamlFile
diff --git a/compiler/src/Files.hs b/compiler/src/Files.hs
new file mode 100644
index 0000000..41fc5a8
--- /dev/null
+++ b/compiler/src/Files.hs
@@ -0,0 +1,183 @@
1-- ldgallery - A static generator which turns a collection of tagged
2-- pictures into a searchable web gallery.
3--
4-- Copyright (C) 2019-2020 Pacien TRAN-GIRARD
5--
6-- This program is free software: you can redistribute it and/or modify
7-- it under the terms of the GNU Affero General Public License as
8-- published by the Free Software Foundation, either version 3 of the
9-- License, or (at your option) any later version.
10--
11-- This program is distributed in the hope that it will be useful,
12-- but WITHOUT ANY WARRANTY; without even the implied warranty of
13-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14-- GNU Affero General Public License for more details.
15--
16-- You should have received a copy of the GNU Affero General Public License
17-- along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19module Files
20 ( FileName, LocalPath, WebPath, Path(..)
21 , (</>), (</), (/>), (<.>)
22 , fileName, subPaths, pathLength
23 , localPath, webPath
24 , FSNode(..), AnchoredFSNode(..)
25 , nodeName, isHidden, flattenDir, filterDir
26 , readDirectory, copyTo
27 , ensureParentDir, remove, isOutdated
28 ) where
29
30
31import Control.Monad (mapM)
32import Data.Bool (bool)
33import Data.List (isPrefixOf, length, subsequences)
34import Data.Function ((&))
35import Data.Text (pack)
36import Data.Aeson (ToJSON)
37import qualified Data.Aeson as JSON
38
39import System.Directory
40 ( doesDirectoryExist
41 , doesPathExist
42 , getModificationTime
43 , listDirectory
44 , createDirectoryIfMissin