diff options
Diffstat (limited to 'compiler/src')
-rw-r--r-- | compiler/src/Caching.hs | 6 | ||||
-rw-r--r-- | compiler/src/Compiler.hs | 12 | ||||
-rw-r--r-- | compiler/src/FileProcessors.hs | 28 | ||||
-rw-r--r-- | compiler/src/Input.hs | 10 | ||||
-rw-r--r-- | compiler/src/ItemProcessors.hs | 10 | ||||
-rw-r--r-- | compiler/src/Resource.hs | 17 |
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 | ||
56 | useCached :: ItemCache -> (GalleryItem -> a) -> Cache a | 56 | useCached :: ItemCache -> (GalleryItem -> Maybe a) -> Cache a |
57 | useCached cache propGetter processor itemPath resPath inputFsPath outputFsPath = | 57 | useCached 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 | ||
80 | resizePictureUpTo :: Resolution -> FileTransformer | 80 | resizePictureUpTo :: Resolution -> FileTransformer |
81 | resizePictureUpTo maxResolution inputPath outputPath = | 81 | resizePictureUpTo 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 | ||
101 | getImageResolution :: FilePath -> IO Resolution | 101 | getImageResolution :: FilePath -> IO Resolution |
102 | getImageResolution fsPath = | 102 | getImageResolution 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 | ||
115 | resourceAt :: FileDescriber Resource | 133 | resourceAt :: FileDescriber Resource |
116 | resourceAt resPath fsPath = Resource resPath <$> getModificationTime fsPath | 134 | resourceAt 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 | ||
102 | readInputTree :: AnchoredFSNode -> IO InputTree | 102 | readInputTree :: AnchoredFSNode -> IO InputTree |
103 | readInputTree (AnchoredFSNode _ File{}) = | 103 | readInputTree (AnchoredFSNode anchor root) = mkDirNode root |
104 | throw $ AssertionFailed "Input directory is a file" | ||
105 | readInputTree (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 | |||
36 | data Format = | 36 | data 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 |