Compare commits

..

10 commits

Author SHA1 Message Date
296a5b56e0 Add fileExtension config for md files 2024-01-15 18:16:56 -05:00
92bd2d5dee Tribute to Dad 2024-01-15 18:16:34 -05:00
032daf33e4 Add dhall-lsp-server to IDE 2024-01-15 18:16:16 -05:00
f4abf812ad Fix broken link issue 2023-09-26 09:46:01 -04:00
f25dd9c993 Change up how randomness works
Introduce a seed fed into `randoms (mkStdGen (seed config)`
Some light formatting
2023-08-08 17:26:50 -04:00
615f2ff446 Rename Seal for drop 2 to work
Don't want to use birthday/april fools photos randomly
2023-08-08 17:18:22 -04:00
72cf946eb7 Fix image link issues 2023-08-07 17:43:26 -04:00
46b00b50e9 Update README 2023-08-06 21:33:54 -04:00
73235cf0ab Move build script to Nix derivation 2023-08-02 18:32:04 -04:00
4d710afae3 Update versions 2023-08-02 18:26:08 -04:00
8 changed files with 89 additions and 86 deletions

3
.gitignore vendored
View file

@ -6,8 +6,9 @@
dist dist
generateSealPosts generateSealPosts
# Direnv lorri stuff # Nix related
.direnv .direnv
result
# Too many posts, hiding for now # Too many posts, hiding for now
posts posts

View file

@ -4,6 +4,7 @@
"Dhall", "Dhall",
"NOINLINE", "NOINLINE",
"runghc", "runghc",
"txts",
"uncurry", "uncurry",
"unlines", "unlines",
"utct" "utct"

View file

@ -8,17 +8,13 @@ It's an in-joke.
## What's all this code? ## What's all this code?
- generate/ - [config.dhall](./config.dhall)
- generateSealPosts.hs - Typed non-deterministic config file for modifying the generator.
- 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. - [flake.nix](./flake.nix)
- dist/ - Entry point for all the nix ways of running and building the code.
- Place for the Haskell build artifacts to go. - [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 ## 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! 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!
## 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.

View file

@ -1,6 +1,8 @@
{ sealImagesPath = "./images" { sealImagesPath = "images"
, postsOutputPath = "./posts" , postsOutputPath = "posts"
, startDate = 2022-01-01 , startDate = 1959-01-15
, seed = +2016
, fileExtension = "md"
, adjectives1 = , adjectives1 =
[ "absorbing" [ "absorbing"
, "adorable" , "adorable"

14
flake.lock generated
View file

@ -2,16 +2,16 @@
"nodes": { "nodes": {
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1681482634, "lastModified": 1690927903,
"narHash": "sha256-cT/nr3L8khEYZSGp8qqwxFH+/q4/547MfyOdSj6MhBk=", "narHash": "sha256-D5gCaCROnjEKDOel//8TO/pOP87pAEtT0uT8X+0Bj/U=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "fda0d99c2cbbb5c89d8855d258cb0821bd9113ad", "rev": "bd836ac5e5a7358dea73cb74a013ca32864ccb86",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "nixos-22.11", "ref": "nixos-23.05",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
@ -42,11 +42,11 @@
"systems": "systems" "systems": "systems"
}, },
"locked": { "locked": {
"lastModified": 1681202837, "lastModified": 1689068808,
"narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=",
"owner": "numtide", "owner": "numtide",
"repo": "flake-utils", "repo": "flake-utils",
"rev": "cfacdce06f30d2b68473a46042957675eebb3401", "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4",
"type": "github" "type": "github"
}, },
"original": { "original": {

View file

@ -2,7 +2,7 @@
description = "A Nix flake for a blog-post generating script, written in Haskell, with a seal bent."; description = "A Nix flake for a blog-post generating script, written in Haskell, with a seal bent.";
inputs = { inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-22.11"; nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.05";
utils.url = "github:numtide/flake-utils"; utils.url = "github:numtide/flake-utils";
}; };
@ -18,18 +18,25 @@
]); ]);
in 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 { devShells.default = pkgs.mkShell {
name = "seal-generator-shell"; name = "seal-generator-shell";
buildInputs = with pkgs.haskellPackages; buildInputs = with pkgs.haskellPackages;
[ [
ghc' ghc'
hlint hlint
haskell-language-server haskell-language-server
(pkgs.writeShellScriptBin "build-seal-generator" '' dhall-lsp-server
${ghc'}/bin/ghc -outputdir dist -O2 -static generateSealPosts.hs
'')
]; ];
}; };
}); });

View file

@ -13,8 +13,7 @@ import Data.List (sort)
import Data.Text (Text) import Data.Text (Text)
import qualified Data.Text as T import qualified Data.Text as T
import qualified Data.Text.IO as TIO import qualified Data.Text.IO as TIO
import Data.Time.Calendar (Day, addDays, diffDays, fromGregorian, import Data.Time.Calendar (Day, addDays, diffDays, toGregorian)
toGregorian)
import Data.Time.Clock (UTCTime (utctDay), getCurrentTime) import Data.Time.Clock (UTCTime (utctDay), getCurrentTime)
import Dhall (FromDhall, Generic, auto, input) import Dhall (FromDhall, Generic, auto, input)
import NeatInterpolation (text) import NeatInterpolation (text)
@ -22,7 +21,7 @@ import NeatInterpolation (text)
import System.Directory (createDirectoryIfMissing, doesFileExist, import System.Directory (createDirectoryIfMissing, doesFileExist,
listDirectory) listDirectory)
import System.IO.Unsafe (unsafePerformIO) 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 data Config = Config
{ adjectives1 :: [Text] { adjectives1 :: [Text]
, adjectives2 :: [Text] , adjectives2 :: [Text]
, fileExtension :: String
, looks :: [Text] , looks :: [Text]
, sealImagesPath :: FilePath , sealImagesPath :: FilePath
, postsOutputPath :: FilePath , postsOutputPath :: FilePath
, startDate :: Day , startDate :: Day
, seed :: Int
} deriving (Generic, Show) } deriving (Generic, Show)
instance FromDhall Config instance FromDhall Config
@ -68,8 +69,13 @@ generateAllBlogPosts config = forM_ allBlogPosts' writeToFile'
allBlogPosts :: Config -> [(FilePath, Text)] allBlogPosts :: Config -> [(FilePath, Text)]
allBlogPosts config = map createSealText zippedDates allBlogPosts config = map createSealText zippedDates
where where
createSealText = uncurry $ sealText config createSealText = uncurry3 $ sealText config
zippedDates = zip [1..] (allDatesSince (startDate 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 :: Day -> [Day]
allDatesSince startDate = map (`addDays` startDate) [0..daysSinceStart] allDatesSince startDate = map (`addDays` startDate) [0..daysSinceStart]
@ -87,49 +93,22 @@ writeToFile config (fp, txt) = do
fp' = postsOutputPath config <> "/" <> fp 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!
<img
src="$imagesPath'/$seal"
alt="A picture of a $adj1, $adj2 seal! <3"
width="400"
/>
|]
{- {-
Returns a filePath, and a corresponding random blog post Returns a filePath, and a corresponding random blog post
-} -}
sealText :: Config -> Integer -> Day -> (FilePath, Text) sealText :: Config -> Integer -> Int -> Day -> (FilePath, Text)
sealText config n date = ( fileName', bp ) sealText config n rand date = ( fileName', bp )
where where
fileName' = fileName' =
show date <> "-" show date <> "-"
<> "seal-post-" <> "seal-post-"
<> show n <> show n
<> ".markdown" <> "." <> fileExtension'
date' = T.pack . show $ date date' = T.pack . show $ date
title = T.pack $ "Seal Post Number " <> show n title = T.pack $ "Seal Post Number " <> show n
title' = T.replace " " "-" title title' = T.replace " " "-" title
sealImagesPath' = sealImagesPath config sealImagesPath' = sealImagesPath config
fileExtension' = fileExtension config
bp = blogPost' (toGregorian date) bp = blogPost' (toGregorian date)
@ -150,43 +129,60 @@ sealText config n date = ( fileName', bp )
"Foolishly look at" "Foolishly look at"
"beautiful" "beautiful"
"supermodel, singing" "supermodel, singing"
"singerSeal.jpg" "_singerSeal.jpg"
date date
sealImagesPath' sealImagesPath'
blogPost' (_, _, _) = blogPost' (_, _, _) =
blogPost blogPost
title title
(randomPull $ looks config) (randomPull rand (looks config))
(randomPull $ adjectives1 config) (randomPull rand (adjectives1 config))
(randomPull $ adjectives2 config) (randomPull rand (adjectives2 config))
(randomPull $ unsafeListDirContents sealImagesPath') (randomPull rand (unsafeListDirContents sealImagesPath'))
date date
sealImagesPath' 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!
<img
src="/$imagesPath'/$seal"
alt="A picture of a $adj1, $adj2 seal! <3"
width="400"
/>
|]
{- {-
Utils 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 :: 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 :: Show a => [a] -> IO ()
prettyPrint = putStr . unlines . map show prettyPrint = putStr . unlines . map show

View file

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Before After
Before After