diff --git a/.gitignore b/.gitignore
index f2a83d1..804bcaf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,8 +6,9 @@
dist
generateSealPosts
-# Direnv lorri stuff
+# Nix related
.direnv
+result
# Too many posts, hiding for now
posts
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 727200a..3580a6d 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -4,6 +4,7 @@
"Dhall",
"NOINLINE",
"runghc",
+ "txts",
"uncurry",
"unlines",
"utct"
diff --git a/README.md b/README.md
index 23deda8..92b6ff3 100644
--- a/README.md
+++ b/README.md
@@ -8,17 +8,13 @@ It's an in-joke.
## What's all this code?
-- generate/
- - generateSealPosts.hs
- - A Haskell script that checks the website/posts folder and creates a blog post for every day from 1998 until the current date. There you will find the adjective lists if you think of more words to describe seals.
-- dist/
- - Place for the Haskell build artifacts to go.
+- [config.dhall](./config.dhall)
+ - Typed non-deterministic config file for modifying the generator.
+- [flake.nix](./flake.nix)
+ - Entry point for all the nix ways of running and building the code.
+- [generateSealPosts.hs](./generateSealPosts.hs)
+ - A Haskell script that creates a blog post for every day from the configured date until the current day.
## These seals need more adjectives
-In [config.dhall](https://git.ewanick.com/bill/sealPostGenerator/src/branch/main/config.dhall) you'll find two lists of adjectives. For the repo and add your own! Editing dhall config files does not require recompilation of the Haskell executable!
-
-## Recent work
-
-- Should running the generate function replace existing posts, or not? Probably not.
- - But need to split out the archive build vs the incremental post creation.
+In [config.dhall](./config.dhall) you'll find two lists of adjectives. For the repo and add your own! Editing dhall config files does not require recompilation of the Haskell executable!
diff --git a/config.dhall b/config.dhall
index 4753bbe..cbddeb2 100644
--- a/config.dhall
+++ b/config.dhall
@@ -1,6 +1,8 @@
-{ sealImagesPath = "./images"
-, postsOutputPath = "./posts"
-, startDate = 2022-01-01
+{ sealImagesPath = "images"
+, postsOutputPath = "posts"
+, startDate = 1959-01-15
+, seed = +2016
+, fileExtension = "md"
, adjectives1 =
[ "absorbing"
, "adorable"
diff --git a/flake.lock b/flake.lock
index 4e6b285..dd13566 100644
--- a/flake.lock
+++ b/flake.lock
@@ -2,16 +2,16 @@
"nodes": {
"nixpkgs": {
"locked": {
- "lastModified": 1681482634,
- "narHash": "sha256-cT/nr3L8khEYZSGp8qqwxFH+/q4/547MfyOdSj6MhBk=",
+ "lastModified": 1690927903,
+ "narHash": "sha256-D5gCaCROnjEKDOel//8TO/pOP87pAEtT0uT8X+0Bj/U=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "fda0d99c2cbbb5c89d8855d258cb0821bd9113ad",
+ "rev": "bd836ac5e5a7358dea73cb74a013ca32864ccb86",
"type": "github"
},
"original": {
"owner": "NixOS",
- "ref": "nixos-22.11",
+ "ref": "nixos-23.05",
"repo": "nixpkgs",
"type": "github"
}
@@ -42,11 +42,11 @@
"systems": "systems"
},
"locked": {
- "lastModified": 1681202837,
- "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
+ "lastModified": 1689068808,
+ "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=",
"owner": "numtide",
"repo": "flake-utils",
- "rev": "cfacdce06f30d2b68473a46042957675eebb3401",
+ "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4",
"type": "github"
},
"original": {
diff --git a/flake.nix b/flake.nix
index 019212b..d370e72 100644
--- a/flake.nix
+++ b/flake.nix
@@ -2,7 +2,7 @@
description = "A Nix flake for a blog-post generating script, written in Haskell, with a seal bent.";
inputs = {
- nixpkgs.url = "github:NixOS/nixpkgs/nixos-22.11";
+ nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.05";
utils.url = "github:numtide/flake-utils";
};
@@ -18,18 +18,25 @@
]);
in
{
+ packages.default = pkgs.runCommand "generateSealPosts" { } ''
+ echo Generating seal posts
+ mkdir -p $out/bin
+ ${ghc'}/bin/ghc \
+ -O2 \
+ -static \
+ -o $out/bin/generateSealPosts \
+ ${./generateSealPosts.hs}
+ '';
+
devShells.default = pkgs.mkShell {
name = "seal-generator-shell";
-
buildInputs = with pkgs.haskellPackages;
[
ghc'
hlint
haskell-language-server
- (pkgs.writeShellScriptBin "build-seal-generator" ''
- ${ghc'}/bin/ghc -outputdir dist -O2 -static generateSealPosts.hs
- '')
+ dhall-lsp-server
];
};
});
diff --git a/generateSealPosts.hs b/generateSealPosts.hs
index c01fe7e..ccd1560 100755
--- a/generateSealPosts.hs
+++ b/generateSealPosts.hs
@@ -13,8 +13,7 @@ import Data.List (sort)
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.IO as TIO
-import Data.Time.Calendar (Day, addDays, diffDays, fromGregorian,
- toGregorian)
+import Data.Time.Calendar (Day, addDays, diffDays, toGregorian)
import Data.Time.Clock (UTCTime (utctDay), getCurrentTime)
import Dhall (FromDhall, Generic, auto, input)
import NeatInterpolation (text)
@@ -22,7 +21,7 @@ import NeatInterpolation (text)
import System.Directory (createDirectoryIfMissing, doesFileExist,
listDirectory)
import System.IO.Unsafe (unsafePerformIO)
-import System.Random (Random, randomRIO)
+import System.Random (Random (randoms), mkStdGen)
{-
@@ -31,10 +30,12 @@ import System.Random (Random, randomRIO)
data Config = Config
{ adjectives1 :: [Text]
, adjectives2 :: [Text]
+ , fileExtension :: String
, looks :: [Text]
, sealImagesPath :: FilePath
, postsOutputPath :: FilePath
, startDate :: Day
+ , seed :: Int
} deriving (Generic, Show)
instance FromDhall Config
@@ -68,8 +69,13 @@ generateAllBlogPosts config = forM_ allBlogPosts' writeToFile'
allBlogPosts :: Config -> [(FilePath, Text)]
allBlogPosts config = map createSealText zippedDates
where
- createSealText = uncurry $ sealText config
- zippedDates = zip [1..] (allDatesSince (startDate config))
+ createSealText = uncurry3 $ sealText config
+ zippedDates = zip3 [1..] randomNumbers (allDatesSince (startDate config))
+ randomNumbers = randoms (mkStdGen (seed config))
+
+ -- | Converts a curried function to a function on a triple.
+ uncurry3 :: (a -> b -> c -> d) -> ((a, b, c) -> d)
+ uncurry3 f (a,b,c) = f a b c
allDatesSince :: Day -> [Day]
allDatesSince startDate = map (`addDays` startDate) [0..daysSinceStart]
@@ -87,49 +93,22 @@ writeToFile config (fp, txt) = do
fp' = postsOutputPath config <> "/" <> fp
-{-
- Blog post format
--}
-blogPost
- :: Text
- -> Text
- -> Text
- -> Text
- -> Text
- -> Day
- -> FilePath
- -> Text
-blogPost title see adj1 adj2 seal date imagesPath =
- let imagesPath' = T.pack imagesPath
- in
- [text|
- ---
- title: $title
- ---
-
- $see this $adj1, $adj2 seal!
-
- |]
-
{-
Returns a filePath, and a corresponding random blog post
-}
-sealText :: Config -> Integer -> Day -> (FilePath, Text)
-sealText config n date = ( fileName', bp )
+sealText :: Config -> Integer -> Int -> Day -> (FilePath, Text)
+sealText config n rand date = ( fileName', bp )
where
fileName' =
show date <> "-"
<> "seal-post-"
<> show n
- <> ".markdown"
+ <> "." <> fileExtension'
date' = T.pack . show $ date
title = T.pack $ "Seal Post Number " <> show n
title' = T.replace " " "-" title
sealImagesPath' = sealImagesPath config
+ fileExtension' = fileExtension config
bp = blogPost' (toGregorian date)
@@ -150,43 +129,60 @@ sealText config n date = ( fileName', bp )
"Foolishly look at"
"beautiful"
"supermodel, singing"
- "singerSeal.jpg"
+ "_singerSeal.jpg"
date
sealImagesPath'
blogPost' (_, _, _) =
blogPost
title
- (randomPull $ looks config)
- (randomPull $ adjectives1 config)
- (randomPull $ adjectives2 config)
- (randomPull $ unsafeListDirContents sealImagesPath')
+ (randomPull rand (looks config))
+ (randomPull rand (adjectives1 config))
+ (randomPull rand (adjectives2 config))
+ (randomPull rand (unsafeListDirContents sealImagesPath'))
date
sealImagesPath'
+ where
+ randomPull r txts = txts !! (rand `mod` l)
+ where l = length txts - 1
+
+ {-
+ Blog post format
+ -}
+ blogPost
+ :: Text
+ -> Text
+ -> Text
+ -> Text
+ -> Text
+ -> Day
+ -> FilePath
+ -> Text
+ blogPost title see adj1 adj2 seal date imagesPath =
+ let imagesPath' = T.pack imagesPath
+ in
+ [text|
+ ---
+ title: $title
+ ---
+
+ $see this $adj1, $adj2 seal!
+
+ |]
{-
Utils
-}
- {-
- Given a list, returns a random element
- -}
-randomPull :: [a] -> a
-randomPull lst = lst !! r'
- where
- r' = randomNum 0 l
- l = length lst - 1
-
- {-
- Gives a random number between from and to
- Uses unsafeIO to get the number out of IO
- It's safe because we're only shuffling
- -}
- randomNum :: Random a => a -> a -> a
- randomNum from to = unsafePerformIO $ randomRIO (from, to)
-
unsafeListDirContents :: FilePath -> [Text]
-unsafeListDirContents = map T.pack . sort . unsafePerformIO . listDirectory
+unsafeListDirContents = map T.pack . drop 2 . sort . unsafePerformIO . listDirectory
+-- ^^^^^^
+-- drop 2 used to remove the birthday and singer photos
+-- TODO: find a better way to hardcode this
prettyPrint :: Show a => [a] -> IO ()
prettyPrint = putStr . unlines . map show
diff --git a/images/singerSeal.jpg b/images/_singerSeal.jpg
similarity index 100%
rename from images/singerSeal.jpg
rename to images/_singerSeal.jpg