aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/ldgallery.1.md11
-rw-r--r--compiler/src/Compiler.hs30
-rw-r--r--compiler/src/Config.hs4
-rw-r--r--compiler/src/Input.hs13
-rw-r--r--example/src/gallery.yaml15
5 files changed, 57 insertions, 16 deletions
diff --git a/compiler/ldgallery.1.md b/compiler/ldgallery.1.md
index 59a5b30..3c52f9d 100644
--- a/compiler/ldgallery.1.md
+++ b/compiler/ldgallery.1.md
@@ -130,10 +130,19 @@ includedFiles[]
130excludedFiles[] 130excludedFiles[]
131: Glob patterns of file names to exclude from the gallery. Defaults to [] (none). 131: Glob patterns of file names to exclude from the gallery. Defaults to [] (none).
132 132
133includedTags[]
134: Glob patterns of tags to include in the gallery.
135 Items with no tags can be matched with the empty pattern.
136 Defaults to ["*"] (matches all tags, includes untagged items).
137
138excludedTags[]
139: Glob patterns of tags to exclude from the gallery.
140 Defaults to [] (none).
141
133tagsFromDirectories.fromParents 142tagsFromDirectories.fromParents
134: Automatically generate tags from the name of parent directories, 143: Automatically generate tags from the name of parent directories,
135 looking up in the hierarchy as far as indicated by this parameter. 144 looking up in the hierarchy as far as indicated by this parameter.
136 Defaults to 0 (do not generate tags from parent directories). 145 Defaults to 0 (does not generate tags from parent directories).
137 146
138tagsFromDirectories.prefix 147tagsFromDirectories.prefix
139: Prefix to use for tags automatically generated from the parent directories' names. 148: Prefix to use for tags automatically generated from the parent directories' names.
diff --git a/compiler/src/Compiler.hs b/compiler/src/Compiler.hs
index 51f5065..fa405a2 100644
--- a/compiler/src/Compiler.hs
+++ b/compiler/src/Compiler.hs
@@ -25,6 +25,7 @@ module Compiler
25import GHC.Generics (Generic) 25import GHC.Generics (Generic)
26import Control.Monad (liftM2, when) 26import Control.Monad (liftM2, when)
27import Data.List (any) 27import Data.List (any)
28import Data.Maybe (fromMaybe)
28import System.FilePath ((</>)) 29import System.FilePath ((</>))
29import qualified System.FilePath.Glob as Glob 30import qualified System.FilePath.Glob as Glob
30import System.Directory (canonicalizePath) 31import System.Directory (canonicalizePath)
@@ -33,7 +34,7 @@ import Data.Aeson (ToJSON)
33import qualified Data.Aeson as JSON 34import qualified Data.Aeson as JSON
34 35
35import Config 36import Config
36import Input (readInputTree) 37import Input (InputTree, readInputTree, filterInputTree, sidecar, tags)
37import Resource (GalleryItem, buildGalleryTree, galleryCleanupResourceDir) 38import Resource (GalleryItem, buildGalleryTree, galleryCleanupResourceDir)
38import Files 39import Files
39 ( FileName 40 ( FileName
@@ -74,6 +75,15 @@ writeJSON outputPath object =
74 ensureParentDir JSON.encodeFile outputPath object 75 ensureParentDir JSON.encodeFile outputPath object
75 76
76 77
78(&&&) :: (a -> Bool) -> (a -> Bool) -> a -> Bool
79(&&&) = liftM2 (&&)
80
81(|||) :: (a -> Bool) -> (a -> Bool) -> a -> Bool
82(|||) = liftM2 (||)
83
84anyPattern :: [String] -> String -> Bool
85anyPattern patterns string = any (flip Glob.match string) (map Glob.compile patterns)
86
77galleryDirFilter :: GalleryConfig -> [FilePath] -> FSNode -> Bool 87galleryDirFilter :: GalleryConfig -> [FilePath] -> FSNode -> Bool
78galleryDirFilter config excludedCanonicalDirs = 88galleryDirFilter config excludedCanonicalDirs =
79 (not . isHidden) 89 (not . isHidden)
@@ -84,9 +94,6 @@ galleryDirFilter config excludedCanonicalDirs =
84 (matchesFile $ anyPattern $ excludedFiles config))) 94 (matchesFile $ anyPattern $ excludedFiles config)))
85 95
86 where 96 where
87 (&&&) = liftM2 (&&)
88 (|||) = liftM2 (||)
89
90 matchesDir :: (FileName -> Bool) -> FSNode -> Bool 97 matchesDir :: (FileName -> Bool) -> FSNode -> Bool
91 matchesDir cond dir@Dir{} = maybe False cond $ nodeName dir 98 matchesDir cond dir@Dir{} = maybe False cond $ nodeName dir
92 matchesDir _ File{} = False 99 matchesDir _ File{} = False
@@ -95,13 +102,19 @@ galleryDirFilter config excludedCanonicalDirs =
95 matchesFile cond file@File{} = maybe False cond $ nodeName file 102 matchesFile cond file@File{} = maybe False cond $ nodeName file
96 matchesFile _ Dir{} = False 103 matchesFile _ Dir{} = False
97 104
98 anyPattern :: [String] -> FileName -> Bool
99 anyPattern patterns filename = any (flip Glob.match filename) (map Glob.compile patterns)
100
101 isExcludedDir :: FSNode -> Bool 105 isExcludedDir :: FSNode -> Bool
102 isExcludedDir Dir{canonicalPath} = any (canonicalPath ==) excludedCanonicalDirs 106 isExcludedDir Dir{canonicalPath} = any (canonicalPath ==) excludedCanonicalDirs
103 isExcludedDir File{} = False 107 isExcludedDir File{} = False
104 108
109inputTreeFilter :: GalleryConfig -> InputTree -> Bool
110inputTreeFilter GalleryConfig{includedTags, excludedTags} =
111 (hasTagMatching $ anyPattern includedTags)
112 &&& (not . (hasTagMatching $ anyPattern excludedTags))
113
114 where
115 hasTagMatching :: (String -> Bool) -> InputTree -> Bool
116 hasTagMatching cond = (any cond) . (fromMaybe [""] . tags) . sidecar
117
105 118
106compileGallery :: FilePath -> FilePath -> FilePath -> FilePath -> [FilePath] -> Bool -> Bool -> IO () 119compileGallery :: FilePath -> FilePath -> FilePath -> FilePath -> [FilePath] -> Bool -> Bool -> IO ()
107compileGallery configPath inputDirPath outputDirPath outputIndexPath excludedDirs rebuildAll cleanOutput = 120compileGallery configPath inputDirPath outputDirPath outputIndexPath excludedDirs rebuildAll cleanOutput =
@@ -113,12 +126,13 @@ compileGallery configPath inputDirPath outputDirPath outputIndexPath excludedDir
113 let sourceFilter = galleryDirFilter config excludedCanonicalDirs 126 let sourceFilter = galleryDirFilter config excludedCanonicalDirs
114 let sourceTree = filterDir sourceFilter inputDir 127 let sourceTree = filterDir sourceFilter inputDir
115 inputTree <- readInputTree sourceTree 128 inputTree <- readInputTree sourceTree
129 let curatedInputTree = filterInputTree (inputTreeFilter config) inputTree
116 130
117 let cache = if rebuildAll then skipCached else withCached 131 let cache = if rebuildAll then skipCached else withCached
118 let itemProc = itemProcessor config cache 132 let itemProc = itemProcessor config cache
119 let thumbnailProc = thumbnailProcessor config cache 133 let thumbnailProc = thumbnailProcessor config cache
120 let galleryBuilder = buildGalleryTree itemProc thumbnailProc (tagsFromDirectories config) 134 let galleryBuilder = buildGalleryTree itemProc thumbnailProc (tagsFromDirectories config)
121 resources <- galleryBuilder inputTree 135 resources <- galleryBuilder curatedInputTree
122 136
123 when cleanOutput $ galleryCleanupResourceDir resources outputDirPath 137 when cleanOutput $ galleryCleanupResourceDir resources outputDirPath
124 writeJSON (outputGalleryIndex outputIndexPath) $ GalleryIndex (viewerConfig config) resources 138 writeJSON (outputGalleryIndex outputIndexPath) $ GalleryIndex (viewerConfig config) resources
diff --git a/compiler/src/Config.hs b/compiler/src/Config.hs
index 1bdb2b8..8796c3c 100644
--- a/compiler/src/Config.hs
+++ b/compiler/src/Config.hs
@@ -55,6 +55,8 @@ data GalleryConfig = GalleryConfig
55 , excludedDirectories :: [String] 55 , excludedDirectories :: [String]
56 , includedFiles :: [String] 56 , includedFiles :: [String]
57 , excludedFiles :: [String] 57 , excludedFiles :: [String]
58 , includedTags :: [String]
59 , excludedTags :: [String]
58 , tagsFromDirectories :: TagsFromDirectoriesConfig 60 , tagsFromDirectories :: TagsFromDirectoriesConfig
59 , thumbnailMaxResolution :: Resolution 61 , thumbnailMaxResolution :: Resolution
60 , pictureMaxResolution :: Maybe Resolution 62 , pictureMaxResolution :: Maybe Resolution
@@ -67,6 +69,8 @@ instance FromJSON GalleryConfig where
67 <*> v .:? "excludedDirectories" .!= [] 69 <*> v .:? "excludedDirectories" .!= []
68 <*> v .:? "includedFiles" .!= ["*"] 70 <*> v .:? "includedFiles" .!= ["*"]
69 <*> v .:? "excludedFiles" .!= [] 71 <*> v .:? "excludedFiles" .!= []
72 <*> v .:? "includedTags" .!= ["*"]
73 <*> v .:? "excludedTags" .!= []
70 <*> v .:? "tagsFromDirectories" .!= (TagsFromDirectoriesConfig 0 "") 74 <*> v .:? "tagsFromDirectories" .!= (TagsFromDirectoriesConfig 0 "")
71 <*> v .:? "thumbnailMaxResolution" .!= (Resolution 400 300) 75 <*> v .:? "thumbnailMaxResolution" .!= (Resolution 400 300)
72 <*> v .:? "pictureMaxResolution" 76 <*> v .:? "pictureMaxResolution"
diff --git a/compiler/src/Input.hs b/compiler/src/Input.hs
index 75d1ed3..6ed7471 100644
--- a/compiler/src/Input.hs
+++ b/compiler/src/Input.hs
@@ -19,7 +19,7 @@
19module Input 19module Input
20 ( decodeYamlFile 20 ( decodeYamlFile
21 , Sidecar(..) 21 , Sidecar(..)
22 , InputTree(..), readInputTree 22 , InputTree(..), readInputTree, filterInputTree
23 ) where 23 ) where
24 24
25 25
@@ -132,3 +132,14 @@ readInputTree (AnchoredFSNode anchor root@Dir{}) = mkDirNode root
132 132
133 findThumbnail :: [FSNode] -> Maybe Path 133 findThumbnail :: [FSNode] -> Maybe Path
134 findThumbnail = (fmap Files.path) . (find isThumbnail) 134 findThumbnail = (fmap Files.path) . (find isThumbnail)
135
136-- | Filters an InputTree. The root is always returned.
137filterInputTree :: (InputTree -> Bool) -> InputTree -> InputTree
138filterInputTree cond = filterNode
139 where
140 filterNode :: InputTree -> InputTree
141 filterNode inputFile@InputFile{} = inputFile
142 filterNode inputDir@InputDir{items} =
143 filter cond items
144 & map filterNode
145 & \curatedItems -> inputDir { items = curatedItems } :: InputTree
diff --git a/example/src/gallery.yaml b/example/src/gallery.yaml
index c4a5077..dba6b39 100644
--- a/example/src/gallery.yaml
+++ b/example/src/gallery.yaml
@@ -11,13 +11,16 @@ includedFiles:
11#excludedFiles: 11#excludedFiles:
12# - "*.md" 12# - "*.md"
13 13
14tagsFromDirectories: 14#includedTags: ["*"]
15 fromParents: 0 # default 15#excludedTags: []
16 prefix: '' # default
17 16
18thumbnailMaxResolution: 17#tagsFromDirectories:
19 width: 400 # default 18# fromParents: 0
20 height: 300 # default 19# prefix: ''
20
21#thumbnailMaxResolution:
22# width: 400
23# height: 300
21 24
22pictureMaxResolution: 25pictureMaxResolution:
23 width: 1024 26 width: 1024