A music player that connects to your cloud/distributed storage.
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

at df22eb08f006cc55f4e454a905fb314660883ed9 208 lines 4.7 kB view raw
1module Main where 2 3import Data.Time.Clock.POSIX (getPOSIXTime) 4import Flow 5import Protolude hiding (list) 6import Renderers 7import Shikensu hiding (list) 8import Shikensu.Contrib 9import Shikensu.Contrib.IO as Shikensu 10import Shikensu.Utilities 11 12import qualified Data.Aeson as Aeson 13import qualified Data.Aeson.KeyMap as KeyMap (fromList) 14import qualified Data.ByteString.Lazy as BSL (toStrict) 15import qualified Data.Char as Char 16import qualified Data.List as List 17import qualified Data.Text as Text 18import qualified Data.Text.Encoding as Text 19import qualified Data.Text.IO as Text 20 21 22-- | (• ◡•)| (❍ᴥ❍ʋ) 23 24 25main :: IO () 26main = 27 do 28 de <- dependencies 29 se <- sequences 30 31 -- Execute flows 32 -- & reduce to a single dictionary 33 let dictionary = List.concatMap (flow de) se 34 35 -- Write everything to disk 36 write "../build" dictionary 37 38 -- Make a file tree 39 build <- list "../build/**/*.*" 40 41 build 42 |> makeTree 43 |> write "../build" 44 45 -- Inject build timestamp 46 -- 47 -- NOTE: Done by esbuild at the moment (see Justfile) 48 -- But we leave it here in case we need it anywhere else. 49 -- 50 -- insertBuildTimestamp (de !~> "timestamp") build 51 52 -- Fin 53 return () 54 55 56list :: [Char] -> IO Dictionary 57list pattern = 58 Shikensu.listRelativeF "./src" [pattern] >>= Shikensu.read 59 60 61 62-- SEQUENCES 63 64 65data Sequence 66 = AboutPages 67 | Favicons 68 | Fonts 69 | Hosting 70 | Html 71 | Images 72 | Manifests 73 74 75sequences :: IO [( Sequence, Dictionary )] 76sequences = lsequence 77 [ ( AboutPages, list "Static/About/**/*.md" ) 78 , ( Favicons, list "Static/Favicons/**/*.*" ) 79 , ( Fonts, list "Static/Fonts/**/*.*" ) 80 , ( Hosting, list "Static/Hosting/**/*" ) 81 , ( Html, list "Static/Html/**/*.html" ) 82 , ( Images, list "Static/Images/**/*.*" ) 83 , ( Manifests, list "Static/Manifests/**/*.*" ) 84 ] 85 86 87 88-- FLOWS 89 90 91flow :: Dependencies -> (Sequence, Dictionary) -> Dictionary 92flow _ (Html, dict) = 93 rename "Application.html" "index.html" dict 94 95 96flow _ (Favicons, dict) = dict 97flow _ (Fonts, dict) = prefixDirname "fonts/" dict 98flow _ (Hosting, dict) = dict 99flow _ (Images, dict) = prefixDirname "images/" dict 100 101 102{-| Manifests -} 103flow _ (Manifests, dict) = 104 dict 105 |> clone "manifest.json" "site.webmanifest" 106 |> rename "Nextcloud/appinfo.xml" "appinfo/info.xml" 107 108 109{-| About Pages -} 110flow x (AboutPages, dict) = 111 dict 112 |> map lowerCasePath 113 |> renameExt ".md" ".html" 114 |> permalink "index" 115 |> prefixDirname "about/" 116 |> renderContent markdownRenderer 117 |> renderContent (layoutRenderer $ x !~> "aboutLayout") 118 119 120 121-- ADDITIONAL IO 122-- FLOW DEPENDENCIES 123 124 125type Dependencies = Aeson.Object 126 127 128dependencies :: IO Dependencies 129dependencies = do 130 aboutLayout <- Text.readFile "src/Static/About/Layout.html" 131 timestamp <- fmap show unixTime :: IO Text 132 133 return $ KeyMap.fromList 134 [ ( "aboutLayout", Aeson.toJSON aboutLayout ) 135 , ( "timestamp", Aeson.toJSON timestamp ) 136 ] 137 138 139 140-- INSERT 141 142 143makeTree :: Dictionary -> Dictionary 144makeTree dict = 145 let 146 treeContent = 147 dict 148 |> List.map localPath 149 |> List.filter (\p -> p /= "tree.json") 150 |> Aeson.encode 151 |> BSL.toStrict 152 153 defs = 154 case headMay dict of 155 Just def -> 156 def 157 |> forkDefinition "tree.json" 158 |> wrap 159 |> setContent treeContent 160 161 Nothing -> 162 [] 163 in 164 defs 165 166 167insertBuildTimestamp :: Text -> Dictionary -> IO () 168insertBuildTimestamp version dict = 169 dict 170 |> List.filter 171 (\def -> 172 localPath def == "service-worker.js" 173 ) 174 |> List.map 175 (\def -> 176 def 177 |> content 178 |> fmap Text.decodeUtf8 179 |> fmap (Text.replace "{{BUILD_TIMESTAMP}}" version) 180 |> fmap Text.encodeUtf8 181 |> (\c -> def { content = c }) 182 ) 183 |> write "../build" 184 |> fmap (\_ -> ()) 185 186 187 188-- COMMON 189 190 191lowerCasePath :: Definition -> Definition 192lowerCasePath def = 193 Shikensu.forkDefinition 194 ( def 195 |> localPath 196 |> List.map Char.toLower 197 ) 198 def 199 200 201unixTime :: IO Int 202unixTime = 203 fmap floor getPOSIXTime 204 205 206wrap :: a -> [a] 207wrap a = 208 [a]