aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/app/Main.hs21
-rw-r--r--compiler/src/Compiler.hs59
-rw-r--r--example/.gitignore3
-rw-r--r--example/gallery.yaml6
-rw-r--r--example/index.json111
5 files changed, 56 insertions, 144 deletions
diff --git a/compiler/app/Main.hs b/compiler/app/Main.hs
index be57c82..d9b019a 100644
--- a/compiler/app/Main.hs
+++ b/compiler/app/Main.hs
@@ -29,29 +29,38 @@ import Compiler
29 29
30data Args = Args 30data Args = Args
31 { inputDir :: String 31 { inputDir :: String
32 , outputDir :: String } 32 , outputDir :: String
33 , rebuild :: Bool }
33 34
34args :: Parser Args 35args :: Parser Args
35args = Args 36args = Args
36 <$> strOption 37 <$> strOption
37 ( long "input" 38 ( long "input"
38 <> short 'i' 39 <> short 'i'
39 <> metavar "INPUT DIR" 40 <> metavar "SOURCE DIR"
41 <> value "./"
42 <> showDefault
40 <> help "Gallery source directory" ) 43 <> help "Gallery source directory" )
41 <*> strOption 44 <*> strOption
42 ( long "output" 45 ( long "output"
43 <> short 'o' 46 <> short 'o'
44 <> metavar "OUTPUT DIR" 47 <> metavar "OUTPUT DIR"
45 <> help "Generated gallery output path, outside of the input directory" ) 48 <> value "./out"
49 <> showDefault
50 <> help "Generated gallery output path" )
51 <*> switch
52 ( long "rebuild"
53 <> short 'r'
54 <> help "Invalidate cache and recompile everything" )
46 55
47main :: IO () 56main :: IO ()
48main = 57main =
49 do 58 do
50 options <- execParser opts 59 options <- execParser opts
51 compileGallery (inputDir options) (outputDir options) 60 compileGallery (inputDir options) (outputDir options) (rebuild options)
52 61
53 where 62 where
54 opts = info (args <**> helper) 63 opts = info (args <**> helper)
55 ( fullDesc 64 ( fullDesc
56 <> progDesc "Compile a picture gallery" 65 <> progDesc "Compile a gallery"
57 <> header "ldgallery - A static generator which turns a collection of tagged pictures into a searchable web gallery.") 66 <> header "ldgallery - a static gallery generator with tags" )
diff --git a/compiler/src/Compiler.hs b/compiler/src/Compiler.hs
index 854fd03..2584570 100644
--- a/compiler/src/Compiler.hs
+++ b/compiler/src/Compiler.hs
@@ -27,31 +27,33 @@ module Compiler
27 ) where 27 ) where
28 28
29 29
30import Control.Monad 30import Control.Monad (liftM2)
31import Data.Function ((&)) 31import Data.Function ((&))
32import Data.List (any)
32import System.FilePath ((</>)) 33import System.FilePath ((</>))
33 34
34import Data.Aeson (ToJSON) 35import Data.Aeson (ToJSON)
35import qualified Data.Aeson as JSON 36import qualified Data.Aeson as JSON
36 37
37import Config 38import Config
39import Input (decodeYamlFile, readInputTree)
40import Resource (ResourceTree, buildResourceTree, cleanupResourceDir)
41import Gallery (buildGalleryTree)
38import Files 42import Files
39 ( FileName 43 ( FileName
44 , FSNode(..)
40 , readDirectory 45 , readDirectory
41 , localPath
42 , isHidden 46 , isHidden
43 , nodeName 47 , nodeName
44 , filterDir 48 , filterDir
45 , flattenDir
46 , root
47 , (/>)
48 , ensureParentDir 49 , ensureParentDir
49 , isOutdated ) 50 , isOutdated )
50
51import Input (decodeYamlFile, readInputTree)
52import Resource (ResourceTree, buildResourceTree, cleanupResourceDir)
53import Gallery (buildGalleryTree)
54import Processors 51import Processors
52 ( dirFileProcessor
53 , itemFileProcessor
54 , thumbnailFileProcessor
55 , skipCached
56 , withCached )
55 57
56 58
57writeJSON :: ToJSON a => FileName -> a -> IO () 59writeJSON :: ToJSON a => FileName -> a -> IO ()
@@ -61,26 +63,21 @@ writeJSON outputPath object =
61 ensureParentDir JSON.encodeFile outputPath object 63 ensureParentDir JSON.encodeFile outputPath object
62 64
63 65
64compileGallery :: FilePath -> FilePath -> IO () 66compileGallery :: FilePath -> FilePath -> Bool -> IO ()
65compileGallery inputDirPath outputDirPath = 67compileGallery inputDirPath outputDirPath rebuildAll =
66 do 68 do
67 fullConfig <- readConfig inputGalleryConf 69 fullConfig <- readConfig inputGalleryConf
68 let config = compiler fullConfig 70 let config = compiler fullConfig
69 71
70 -- TODO: exclude output dir if it's under the input dir
71 inputDir <- readDirectory inputDirPath 72 inputDir <- readDirectory inputDirPath
72 73 let sourceTree = filterDir galleryDirFilter inputDir
73 let isGalleryFile = \n -> nodeName n == galleryConf 74 inputTree <- readInputTree sourceTree
74 let galleryTree = filterDir (liftM2 (&&) (not . isGalleryFile) (not . isHidden)) inputDir
75
76 inputTree <- readInputTree galleryTree
77 75
78 invalidateCache <- isOutdated inputGalleryConf outputIndex 76 invalidateCache <- isOutdated inputGalleryConf outputIndex
79 let cache = if invalidateCache then skipCached else withCached 77 let cache = if invalidateCache || rebuildAll then skipCached else withCached
80 let dirProc = dirFileProcessor inputDirPath outputDirPath itemsDir 78 let itemProc = itemProcessor (pictureMaxResolution config) cache
81 let itemProc = itemFileProcessor (pictureMaxResolution config) cache inputDirPath outputDirPath itemsDir 79 let thumbnailProc = thumbnailProcessor (thumbnailResolution config) cache
82 let thumbnailProc = thumbnailFileProcessor (thumbnailResolution config) cache inputDirPath outputDirPath thumbnailsDir 80 resourceTree <- buildResourceTree dirProcessor itemProc thumbnailProc inputTree
83 resourceTree <- buildResourceTree dirProc itemProc thumbnailProc inputTree
84 81
85 cleanupResourceDir resourceTree outputDirPath 82 cleanupResourceDir resourceTree outputDirPath
86 83
@@ -92,9 +89,23 @@ compileGallery inputDirPath outputDirPath =
92 89
93 where 90 where
94 galleryConf = "gallery.yaml" 91 galleryConf = "gallery.yaml"
92 indexFile = "index.json"
93 viewerConfFile = "viewer.json"
95 itemsDir = "items" 94 itemsDir = "items"
96 thumbnailsDir = "thumbnails" 95 thumbnailsDir = "thumbnails"
97 96
98 inputGalleryConf = inputDirPath </> galleryConf 97 inputGalleryConf = inputDirPath </> galleryConf
99 outputIndex = outputDirPath </> "index.json" 98 outputIndex = outputDirPath </> indexFile
100 outputViewerConf = outputDirPath </> "viewer.json" 99 outputViewerConf = outputDirPath </> viewerConfFile
100
101 (&&&) = liftM2 (&&)
102 galleryDirFilter = (not . containsOutputGallery) &&& (not . isConfigFile) &&& (not . isHidden)
103 isConfigFile = (==) galleryConf . nodeName
104 containsOutputGallery (File _) = False
105 containsOutputGallery (Dir _ items) = any ((==) indexFile . nodeName) items
106
107 dirProcessor = dirFileProcessor inputDirPath outputDirPath itemsDir
108 itemProcessor maxRes cache =
109 itemFileProcessor maxRes cache inputDirPath outputDirPath itemsDir
110 thumbnailProcessor thumbRes cache =
111 thumbnailFileProcessor thumbRes cache inputDirPath outputDirPath thumbnailsDir
diff --git a/example/.gitignore b/example/.gitignore
index f1212bc..1fcb152 100644
--- a/example/.gitignore
+++ b/example/.gitignore
@@ -1,2 +1 @@
1items out
2thumbnails
diff --git a/example/gallery.yaml b/example/gallery.yaml
index fc4bdf9..0a16e59 100644
--- a/example/gallery.yaml
+++ b/example/gallery.yaml
@@ -1,2 +1,6 @@
1compiler: {} 1compiler:
2 pictureMaxResolution:
3 width: 1024
4 height: 768
5
2viewer: {} 6viewer: {}
diff --git a/example/index.json b/example/index.json
deleted file mode 100644
index d693f7b..0000000
--- a/example/index.json
+++ /dev/null
@@ -1,111 +0,0 @@
1{
2 "_comment": "reference gallery index file, manually aggregated",
3
4 "title": "",
5 "date": "",
6 "description": "",
7 "tags": [
8 "photographer.nphilou",
9 "location.germany.berlin",
10 "books",
11 "book-shop",
12 "location.switzerland.ormont-dessus",
13 "glacier3000",
14 "time.day",
15 "weather.foggy",
16 "forest",
17 "trees",
18 "catwalk",
19 "mountain"
20 ],
21 "path": "/",
22 "thumbnail": null,
23 "properties": {
24 "type": "directory",
25 "items": [
26 {
27 "title": "Book shop",
28 "date": "2016:12:19T16:48:50+02:00",
29 "description": "© Philippe NGUYEN",
30 "tags": [
31 "photographer.nphilou",
32 "location.germany.berlin",
33 "books",
34 "book-shop"
35 ],
36 "path": "/items/_DSC8808-1.jpg",
37 "thumbnail": "/thumbnails/_DSC8808-1.jpg",
38 "properties": {
39 "type": "image",
40 "filesize": 987,
41 "resolution": { "width": 3840, "height": 2160 }
42 }
43 },
44 {
45 "title": "Glacier 3000",
46 "date": "",
47 "description": "",
48 "tags": [
49 "photographer.nphilou",
50 "location.switzerland.ormont-dessus",
51 "glacier3000",
52 "time.day",
53