aboutsummaryrefslogtreecommitdiff
path: root/compiler/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/src')
-rw-r--r--compiler/src/Caching.hs6
-rw-r--r--compiler/src/Compiler.hs12
-rw-r--r--compiler/src/FileProcessors.hs28
-rw-r--r--compiler/src/Input.hs10
-rw-r--r--compiler/src/ItemProcessors.hs10
-rw-r--r--compiler/src/Resource.hs17
6 files changed, 53 insertions, 30 deletions
diff --git a/compiler/src/Caching.hs b/compiler/src/Caching.hs
index c2b5a43..1a8b710 100644
--- a/compiler/src/Caching.hs
+++ b/compiler/src/Caching.hs
@@ -53,7 +53,7 @@ buildItemCache cachedItems = lookupCache
53 cachedMap = Map.fromList (map withKey cachedItemList) 53 cachedMap = Map.fromList (map withKey cachedItemList)
54 lookupCache path = Map.lookup (webPath path) cachedMap 54 lookupCache path = Map.lookup (webPath path) cachedMap
55 55
56useCached :: ItemCache -> (GalleryItem -> a) -> Cache a 56useCached :: ItemCache -> (GalleryItem -> Maybe a) -> Cache a
57useCached cache propGetter processor itemPath resPath inputFsPath outputFsPath = 57useCached cache propGetter processor itemPath resPath inputFsPath outputFsPath =
58 do 58 do
59 isDir <- doesDirectoryExist outputFsPath 59 isDir <- doesDirectoryExist outputFsPath
@@ -63,7 +63,7 @@ useCached cache propGetter processor itemPath resPath inputFsPath outputFsPath =
63 if fileExists then 63 if fileExists then
64 do 64 do
65 needUpdate <- isOutdated True inputFsPath outputFsPath 65 needUpdate <- isOutdated True inputFsPath outputFsPath
66 case (needUpdate, cache itemPath) of 66 case (needUpdate, cache itemPath >>= propGetter) of
67 (False, Just props) -> fromCache props 67 (False, Just props) -> fromCache props
68 _ -> update 68 _ -> update
69 else 69 else
@@ -73,4 +73,4 @@ useCached cache propGetter processor itemPath resPath inputFsPath outputFsPath =
73 update = processor itemPath resPath inputFsPath outputFsPath 73 update = processor itemPath resPath inputFsPath outputFsPath
74 fromCache props = 74 fromCache props =
75 putStrLn ("From cache:\t" ++ outputFsPath) 75 putStrLn ("From cache:\t" ++ outputFsPath)
76 >> return (propGetter props) 76 >> return props
diff --git a/compiler/src/Compiler.hs b/compiler/src/Compiler.hs
index 1ec55c5..d92d8e9 100644
--- a/compiler/src/Compiler.hs
+++ b/compiler/src/Compiler.hs
@@ -85,7 +85,8 @@ loadGalleryIndex path =
85 doesFileExist path >>= bool (return Nothing) decodeIndex 85 doesFileExist path >>= bool (return Nothing) decodeIndex
86 where 86 where
87 decodeIndex = 87 decodeIndex =
88 JSON.eitherDecodeFileStrict path 88 putStrLn ("Loading previous index:\t" ++ path)
89 >> JSON.eitherDecodeFileStrict path
89 >>= either (\err -> warn err >> return Nothing) (return . Just) 90 >>= either (\err -> warn err >> return Nothing) (return . Just)
90 warn = putStrLn . ("Warning:\tUnable to reuse existing index as cache: " ++) 91 warn = putStrLn . ("Warning:\tUnable to reuse existing index as cache: " ++)
91 92
@@ -136,10 +137,13 @@ compileGallery configPath inputDirPath outputDirPath outputIndexPath excludedDir
136 do 137 do
137 config <- readConfig $ inputGalleryConf configPath 138 config <- readConfig $ inputGalleryConf configPath
138 139
140 putStrLn "Inventorying input files"
139 inputDir <- readDirectory inputDirPath 141 inputDir <- readDirectory inputDirPath
140 excludedCanonicalDirs <- mapM canonicalizePath excludedDirs 142 excludedCanonicalDirs <- mapM canonicalizePath excludedDirs
143
141 let sourceFilter = galleryDirFilter config excludedCanonicalDirs 144 let sourceFilter = galleryDirFilter config excludedCanonicalDirs
142 let sourceTree = filterDir sourceFilter inputDir 145 let sourceTree = filterDir sourceFilter inputDir
146 putStrLn "Reading input metadata"
143 inputTree <- readInputTree sourceTree 147 inputTree <- readInputTree sourceTree
144 let curatedInputTree = filterInputTree (inputTreeFilter config) inputTree 148 let curatedInputTree = filterInputTree (inputTreeFilter config) inputTree
145 149
@@ -147,8 +151,8 @@ compileGallery configPath inputDirPath outputDirPath outputIndexPath excludedDir
147 cachedIndex <- loadCachedIndex galleryIndexPath 151 cachedIndex <- loadCachedIndex galleryIndexPath
148 let cache = mkCache cachedIndex 152 let cache = mkCache cachedIndex
149 153
150 let itemProc = itemProcessor config (cache Resource.properties) 154 let itemProc = itemProcessor config (cache $ return . Resource.properties)
151 let thumbnailProc = thumbnailProcessor config (cache Resource.thumbnail) 155 let thumbnailProc = thumbnailProcessor config (cache $ fmap return . Resource.thumbnail)
152 let galleryBuilder = buildGalleryTree itemProc thumbnailProc (tagsFromDirectories config) 156 let galleryBuilder = buildGalleryTree itemProc thumbnailProc (tagsFromDirectories config)
153 resources <- galleryBuilder curatedInputTree 157 resources <- galleryBuilder curatedInputTree
154 158
@@ -170,7 +174,7 @@ compileGallery configPath inputDirPath outputDirPath outputIndexPath excludedDir
170 then return Nothing 174 then return Nothing
171 else loadGalleryIndex galleryIndexPath 175 else loadGalleryIndex galleryIndexPath
172 176
173 mkCache :: Maybe GalleryIndex -> (GalleryItem -> a) -> Cache a 177 mkCache :: Maybe GalleryIndex -> (GalleryItem -> Maybe a) -> Cache a
174 mkCache refGalleryIndex = 178 mkCache refGalleryIndex =
175 if rebuildAll 179 if rebuildAll
176 then const noCache 180 then const noCache
diff --git a/compiler/src/FileProcessors.hs b/compiler/src/FileProcessors.hs
index 5c4e1c8..78e7351 100644
--- a/compiler/src/FileProcessors.hs
+++ b/compiler/src/FileProcessors.hs
@@ -1,7 +1,7 @@
1-- ldgallery - A static generator which turns a collection of tagged 1-- ldgallery - A static generator which turns a collection of tagged
2-- pictures into a searchable web gallery. 2-- pictures into a searchable web gallery.
3-- 3--
4-- Copyright (C) 2019-2020 Pacien TRAN-GIRARD 4-- Copyright (C) 2019-2022 Pacien TRAN-GIRARD
5-- 5--
6-- This program is free software: you can redistribute it and/or modify 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 7-- it under the terms of the GNU Affero General Public License as
@@ -79,7 +79,7 @@ copyFileProcessor inputPath outputPath =
79 79
80resizePictureUpTo :: Resolution -> FileTransformer 80resizePictureUpTo :: Resolution -> FileTransformer
81resizePictureUpTo maxResolution inputPath outputPath = 81resizePictureUpTo maxResolution inputPath outputPath =
82 putStrLn ("Generating:\t" ++ outputPath) 82 putStrLn ("Processing:\t" ++ outputPath)
83 >> ensureParentDir (flip resize) outputPath inputPath 83 >> ensureParentDir (flip resize) outputPath inputPath
84 where 84 where
85 maxSize :: Resolution -> String 85 maxSize :: Resolution -> String
@@ -100,17 +100,35 @@ type FileDescriber a =
100 100
101getImageResolution :: FilePath -> IO Resolution 101getImageResolution :: FilePath -> IO Resolution
102getImageResolution fsPath = 102getImageResolution fsPath =
103 readProcess "magick" ["identify", "-format", "%w %h", firstFrame] [] 103 readProcess "magick"
104 >>= parseResolution . break (== ' ') 104 [ "identify"
105 , "-ping"
106 , "-format", "%[orientation] %w %h"
107 , firstFrame
108 ] []
109 >>= parseOutput . words
110
105 where 111 where
106 firstFrame :: FilePath 112 firstFrame :: FilePath
107 firstFrame = fsPath ++ "[0]" 113 firstFrame = fsPath ++ "[0]"
108 114
115 -- Flip the dimensions when necessary according to the metadata.
116 -- ImageMagick's `-auto-orient` flag does the same, but isn't compatible
117 -- with `-ping` and causes the whole image file to be loaded.
118 parseOutput :: [String] -> IO Resolution
119 parseOutput ["RightTop", w, h] = parseResolution (h, w)
120 parseOutput ["LeftBottom", w, h] = parseResolution (h, w)
121 parseOutput [_, w, h] = parseResolution (w, h)
122 parseOutput _ = throwIO failedRead
123
109 parseResolution :: (String, String) -> IO Resolution 124 parseResolution :: (String, String) -> IO Resolution
110 parseResolution (widthString, heightString) = 125 parseResolution (widthString, heightString) =
111 case (readMaybe widthString, readMaybe heightString) of 126 case (readMaybe widthString, readMaybe heightString) of
112 (Just w, Just h) -> return $ Resolution w h 127 (Just w, Just h) -> return $ Resolution w h
113 _ -> throwIO $ ProcessingException fsPath "Unable to read image resolution." 128 _ -> throwIO failedRead
129
130 failedRead :: ProcessingException
131 failedRead = ProcessingException fsPath "Unable to read image resolution."
114 132
115resourceAt :: FileDescriber Resource 133resourceAt :: FileDescriber Resource
116resourceAt resPath fsPath = Resource resPath <$> getModificationTime fsPath 134resourceAt resPath fsPath = Resource resPath <$> getModificationTime fsPath
diff --git a/compiler/src/Input.hs b/compiler/src/Input.hs
index 48931ec..7990571 100644
--- a/compiler/src/Input.hs
+++ b/compiler/src/Input.hs
@@ -1,7 +1,7 @@
1-- ldgallery - A static generator which turns a collection of tagged 1-- ldgallery - A static generator which turns a collection of tagged
2-- pictures into a searchable web gallery. 2-- pictures into a searchable web gallery.
3-- 3--
4-- Copyright (C) 2019-2020 Pacien TRAN-GIRARD 4-- Copyright (C) 2019-2022 Pacien TRAN-GIRARD
5-- 5--
6-- This program is free software: you can redistribute it and/or modify 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 7-- it under the terms of the GNU Affero General Public License as
@@ -100,9 +100,7 @@ readSidecarFile filepath =
100 100
101 101
102readInputTree :: AnchoredFSNode -> IO InputTree 102readInputTree :: AnchoredFSNode -> IO InputTree
103readInputTree (AnchoredFSNode _ File{}) = 103readInputTree (AnchoredFSNode anchor root) = mkDirNode root
104 throw $ AssertionFailed "Input directory is a file"
105readInputTree (AnchoredFSNode anchor root@Dir{}) = mkDirNode root
106 where 104 where
107 mkInputNode :: Map.Map FileName FSNode -> FSNode -> IO (Maybe InputTree) 105 mkInputNode :: Map.Map FileName FSNode -> FSNode -> IO (Maybe InputTree)
108 mkInputNode dir file@File{path} | not (isSidecar file) && not (isThumbnail file) = 106 mkInputNode dir file@File{path} | not (isSidecar file) && not (isThumbnail file) =
@@ -155,6 +153,4 @@ filterInputTree cond = filterNode
155 filterNode :: InputTree -> InputTree 153 filterNode :: InputTree -> InputTree
156 filterNode inputFile@InputFile{} = inputFile 154 filterNode inputFile@InputFile{} = inputFile
157 filterNode inputDir@InputDir{items} = 155 filterNode inputDir@InputDir{items} =
158 filter cond items 156 inputDir { Input.items = filter cond items & map filterNode }
159 & map filterNode
160 & \curatedItems -> inputDir { items = curatedItems } :: InputTree
diff --git a/compiler/src/ItemProcessors.hs b/compiler/src/ItemProcessors.hs
index f967954..6035477 100644
--- a/compiler/src/ItemProcessors.hs
+++ b/compiler/src/ItemProcessors.hs
@@ -1,7 +1,7 @@
1-- ldgallery - A static generator which turns a collection of tagged 1-- ldgallery - A static generator which turns a collection of tagged
2-- pictures into a searchable web gallery. 2-- pictures into a searchable web gallery.
3-- 3--
4-- Copyright (C) 2019-2020 Pacien TRAN-GIRARD 4-- Copyright (C) 2019-2022 Pacien TRAN-GIRARD
5-- 5--
6-- This program is free software: you can redistribute it and/or modify 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 7-- it under the terms of the GNU Affero General Public License as
@@ -36,7 +36,9 @@ import Files
36data Format = 36data Format =
37 PictureFormat 37 PictureFormat
38 | PlainTextFormat 38 | PlainTextFormat
39 | MarkdownFormat
39 | PortableDocumentFormat 40 | PortableDocumentFormat
41 | EPUBFormat
40 | VideoFormat 42 | VideoFormat
41 | AudioFormat 43 | AudioFormat
42 | Unknown 44 | Unknown
@@ -54,9 +56,11 @@ formatFromPath =
54 ".tiff" -> PictureFormat 56 ".tiff" -> PictureFormat
55 ".hdr" -> PictureFormat 57 ".hdr" -> PictureFormat
56 ".gif" -> PictureFormat 58 ".gif" -> PictureFormat
59 ".webp" -> PictureFormat
57 ".txt" -> PlainTextFormat 60 ".txt" -> PlainTextFormat