diff options
author | pacien | 2020-01-06 00:01:53 +0100 |
---|---|---|
committer | pacien | 2020-01-06 00:01:53 +0100 |
commit | c8dea48bb4a0ec137bafba3bec79352eae2f48c0 (patch) | |
tree | f904a7f59b741211cbbee8a02475a7cc24f0a4e8 | |
parent | 1e3a0e39cb6cdc86a6ba6b570c72c44931cf1c3b (diff) | |
download | ldgallery-c8dea48bb4a0ec137bafba3bec79352eae2f48c0.tar.gz |
compiler: default item date to filesystem last mod date
GitHub: closes #14
-rw-r--r-- | compiler/package.yaml | 2 | ||||
-rw-r--r-- | compiler/src/Resource.hs | 32 | ||||
-rw-r--r-- | compiler/stack.yaml | 6 | ||||
-rw-r--r-- | compiler/stack.yaml.lock | 30 |
4 files changed, 63 insertions, 7 deletions
diff --git a/compiler/package.yaml b/compiler/package.yaml index 0922c36..fd44ccc 100644 --- a/compiler/package.yaml +++ b/compiler/package.yaml | |||
@@ -27,6 +27,8 @@ dependencies: | |||
27 | - JuicyPixels-extra | 27 | - JuicyPixels-extra |
28 | - parallel-io | 28 | - parallel-io |
29 | - Glob | 29 | - Glob |
30 | - safe | ||
31 | - time >= 1.9.3 && < 1.10 | ||
30 | 32 | ||
31 | default-extensions: | 33 | default-extensions: |
32 | - DuplicateRecordFields | 34 | - DuplicateRecordFields |
diff --git a/compiler/src/Resource.hs b/compiler/src/Resource.hs index 261191b..207239f 100644 --- a/compiler/src/Resource.hs +++ b/compiler/src/Resource.hs | |||
@@ -30,6 +30,10 @@ import Data.Char (toLower) | |||
30 | import Data.Maybe (mapMaybe, fromMaybe) | 30 | import Data.Maybe (mapMaybe, fromMaybe) |
31 | import Data.Function ((&)) | 31 | import Data.Function ((&)) |
32 | import qualified Data.Set as Set | 32 | import qualified Data.Set as Set |
33 | import Data.Time.LocalTime (ZonedTime, utc, utcToZonedTime, zonedTimeToUTC) | ||
34 | import Data.Time.Format.ISO8601 (iso8601ParseM) | ||
35 | import System.Directory (getModificationTime) | ||
36 | import Safe.Foldable (maximumByMay) | ||
33 | 37 | ||
34 | import GHC.Generics (Generic) | 38 | import GHC.Generics (Generic) |
35 | import Data.Aeson (FromJSON, ToJSON, genericToJSON, genericToEncoding) | 39 | import Data.Aeson (FromJSON, ToJSON, genericToJSON, genericToEncoding) |
@@ -75,7 +79,7 @@ instance ToJSON GalleryItemProps where | |||
75 | 79 | ||
76 | data GalleryItem = GalleryItem | 80 | data GalleryItem = GalleryItem |
77 | { title :: String | 81 | { title :: String |
78 | , date :: String -- TODO: checked ISO8601 date | 82 | , date :: ZonedTime |
79 | , description :: String | 83 | , description :: String |
80 | , tags :: [Tag] | 84 | , tags :: [Tag] |
81 | , path :: Path | 85 | , path :: Path |
@@ -103,18 +107,22 @@ buildGalleryTree processItem processThumbnail tagsFromDirectories galleryName in | |||
103 | do | 107 | do |
104 | properties <- processItem path | 108 | properties <- processItem path |
105 | processedThumbnail <- processThumbnail path | 109 | processedThumbnail <- processThumbnail path |
110 | fileModTime <- lastModTime path | ||
106 | return GalleryItem | 111 | return GalleryItem |
107 | { title = itemTitle | 112 | { title = itemTitle |
108 | , date = optMeta date "" -- TODO: check and normalise dates | 113 | , date = fromMaybe fileModTime itemDate |
109 | , description = optMeta description "" | 114 | , description = optMeta description "" |
110 | , tags = (optMeta tags []) ++ implicitParentTags parents | 115 | , tags = (optMeta tags []) ++ implicitParentTags parents |
111 | , path = parents </ itemTitle | 116 | , path = parents </ itemTitle |
112 | , thumbnail = processedThumbnail | 117 | , thumbnail = processedThumbnail |
113 | , properties = properties } -- TODO | 118 | , properties = properties } |
114 | where | 119 | where |
115 | itemTitle :: String | 120 | itemTitle :: String |
116 | itemTitle = optMeta title $ fromMaybe "" $ fileName path | 121 | itemTitle = optMeta title $ fromMaybe "" $ fileName path |
117 | 122 | ||
123 | itemDate :: Maybe ZonedTime | ||
124 | itemDate = Input.date sidecar >>= iso8601ParseM | ||
125 | |||
118 | optMeta :: (Sidecar -> Maybe a) -> a -> a | 126 | optMeta :: (Sidecar -> Maybe a) -> a -> a |
119 | optMeta get fallback = fromMaybe fallback $ get sidecar | 127 | optMeta get fallback = fromMaybe fallback $ get sidecar |
120 | 128 | ||
@@ -122,11 +130,10 @@ buildGalleryTree processItem processThumbnail tagsFromDirectories galleryName in | |||
122 | do | 130 | do |
123 | processedThumbnail <- maybeThumbnail dirThumbnailPath | 131 | processedThumbnail <- maybeThumbnail dirThumbnailPath |
124 | processedItems <- parallel $ map (mkGalleryItem Nothing itemPath) items | 132 | processedItems <- parallel $ map (mkGalleryItem Nothing itemPath) items |
133 | dirModTime <- lastModTime path | ||
125 | return GalleryItem | 134 | return GalleryItem |
126 | { title = itemTitle | 135 | { title = itemTitle |
127 | -- TODO: consider using the most recent item's date? what if empty? | 136 | , date = fromMaybe dirModTime $ mostRecentChildModTime processedItems |
128 | , date = "" | ||
129 | -- TODO: consider allowing metadata sidecars for directories too | ||
130 | , description = "" | 137 | , description = "" |
131 | , tags = (aggregateChildTags processedItems) ++ implicitParentTags parents | 138 | , tags = (aggregateChildTags processedItems) ++ implicitParentTags parents |
132 | , path = itemPath | 139 | , path = itemPath |
@@ -143,6 +150,13 @@ buildGalleryTree processItem processThumbnail tagsFromDirectories galleryName in | |||
143 | maybeThumbnail Nothing = return Nothing | 150 | maybeThumbnail Nothing = return Nothing |
144 | maybeThumbnail (Just thumbnailPath) = processThumbnail thumbnailPath | 151 | maybeThumbnail (Just thumbnailPath) = processThumbnail thumbnailPath |
145 | 152 | ||
153 | mostRecentChildModTime :: [GalleryItem] -> Maybe ZonedTime | ||
154 | mostRecentChildModTime = | ||
155 | maximumByMay comparingDates . map (date::(GalleryItem -> ZonedTime)) | ||
156 | |||
157 | comparingDates :: ZonedTime -> ZonedTime -> Ordering | ||
158 | comparingDates l r = compare (zonedTimeToUTC l) (zonedTimeToUTC r) | ||
159 | |||
146 | aggregateChildTags :: [GalleryItem] -> [Tag] | 160 | aggregateChildTags :: [GalleryItem] -> [Tag] |
147 | aggregateChildTags = unique . concatMap (\item -> tags (item::GalleryItem)) | 161 | aggregateChildTags = unique . concatMap (\item -> tags (item::GalleryItem)) |
148 | 162 | ||
@@ -152,6 +166,12 @@ buildGalleryTree processItem processThumbnail tagsFromDirectories galleryName in | |||
152 | implicitParentTags :: Path -> [Tag] | 166 | implicitParentTags :: Path -> [Tag] |
153 | implicitParentTags (Path elements) = take tagsFromDirectories elements | 167 | implicitParentTags (Path elements) = take tagsFromDirectories elements |
154 | 168 | ||
169 | lastModTime :: Path -> IO ZonedTime | ||
170 | lastModTime path = | ||
171 | localPath path | ||
172 | & getModificationTime | ||
173 | >>= return . utcToZonedTime utc | ||
174 | |||
155 | 175 | ||
156 | flattenGalleryTree :: GalleryItem -> [GalleryItem] | 176 | flattenGalleryTree :: GalleryItem -> [GalleryItem] |
157 | flattenGalleryTree dir@(GalleryItem _ _ _ _ _ _ (Directory items)) = | 177 | flattenGalleryTree dir@(GalleryItem _ _ _ _ _ _ (Directory items)) = |
diff --git a/compiler/stack.yaml b/compiler/stack.yaml index 29f8539..146f46b 100644 --- a/compiler/stack.yaml +++ b/compiler/stack.yaml | |||
@@ -41,6 +41,12 @@ packages: | |||
41 | # | 41 | # |
42 | # extra-deps: [] | 42 | # extra-deps: [] |
43 | 43 | ||
44 | extra-deps: | ||
45 | - time-1.9.3@sha256:8f1b5448722a12a952248b356c9eb366e351226543d9086a2da71270522d5f45,5679 | ||
46 | - directory-1.3.4.0@sha256:500019f04494324d1df16cf83eefeb3f809b2b20b32a32ccd755ee0439c18bfd,2829 | ||
47 | - process-1.6.7.0@sha256:305bcf44c42a96425e77af1748183f505a701648f68cc299d5ad8ac1b866a6a1,2468 | ||
48 | - unix-2.7.2.2@sha256:e69269a17b9fa26cb77f3f55e86c39d0a4940ccfa0c4bc20826919d2572076ad,3496 | ||
49 | |||
44 | # Override default flag values for local packages and extra-deps | 50 | # Override default flag values for local packages and extra-deps |
45 | # flags: {} | 51 | # flags: {} |
46 | 52 | ||
diff --git a/compiler/stack.yaml.lock b/compiler/stack.yaml.lock index fc538c1..8e833c5 100644 --- a/compiler/stack.yaml.lock +++ b/compiler/stack.yaml.lock | |||
@@ -3,7 +3,35 @@ | |||
3 | # For more information, please see the documentation at: | 3 | # For more information, please see the documentation at: |
4 | # https://docs.haskellstack.org/en/stable/lock_files | 4 | # https://docs.haskellstack.org/en/stable/lock_files |
5 | 5 | ||
6 | packages: [] | 6 | packages: |
7 | - completed: | ||
8 | hackage: time-1.9.3@sha256:8f1b5448722a12a952248b356c9eb366e351226543d9086a2da71270522d5f45,5679 | ||
9 | pantry-tree: | ||
10 | size: 6558 | ||
11 | sha256: a1043c1719491764f0fa37a1fd70d9451080548a41632fee88d8e1b8db4942d6 | ||
12 | original: | ||
13 | hackage: time-1.9.3@sha256:8f1b5448722a12a952248b356c9eb366e351226543d9086a2da71270522d5f45,5679 | ||
14 | - completed: | ||
15 | hackage: directory-1.3.4.0@sha256:500019f04494324d1df16cf83eefeb3f809b2b20b32a32ccd755ee0439c18bfd,2829 | ||
16 | pantry-tree: | ||
17 | size: 3365 | ||
18 | sha256: 00c09e0c014d29ebfb921b64c1459e61a0ad6f10e70128d795246a47c06394b0 | ||
19 | original: | ||
20 | hackage: directory-1.3.4.0@sha256:500019f04494324d1df16cf83eefeb3f809b2b20b32a32ccd755ee0439c18bfd,2829 | ||
21 | - completed: | ||
22 | hackage: process-1.6.7.0@sha256:305bcf44c42a96425e77af1748183f505a701648f68cc299d5ad8ac1b866a6a1,2468 | ||
23 | pantry-tree: | ||
24 | size: 1211 | ||
25 | sha256: 49c3e531d2473fe455c1cde655f074a320fa4ec8569d650262bf382f9c5796fb | ||
26 | original: | ||
27 | hackage: process-1.6.7.0@sha256:305bcf44c42a96425e77af1748183f505a701648f68cc299d5ad8ac1b866a6a1,2468 | ||
28 | - completed: | ||
29 | hackage: unix-2.7.2.2@sha256:e69269a17b9fa26cb77f3f55e86c39d0a4940ccfa0c4bc20826919d2572076ad,3496 | ||
30 | pantry-tree: | ||
31 | size: 3536 | ||
32 | sha256: c355f7924ce67e5bf8f20767462af18f09b8c0d1f7161117221cbb94c15deee3 | ||
33 | original: | ||
34 | hackage: unix-2.7.2.2@sha256:e69269a17b9fa26cb77f3f55e86c39d0a4940ccfa0c4bc20826919d2572076ad,3496 | ||
7 | snapshots: | 35 | snapshots: |
8 | - completed: | 36 | - completed: |
9 | size: 524799 | 37 | size: 524799 |