diff --git a/.gitignore b/.gitignore index 804bcaf..f2a83d1 100644 --- a/.gitignore +++ b/.gitignore @@ -6,9 +6,8 @@ dist generateSealPosts -# Nix related +# Direnv lorri stuff .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 3580a6d..727200a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,7 +4,6 @@ "Dhall", "NOINLINE", "runghc", - "txts", "uncurry", "unlines", "utct" diff --git a/README.md b/README.md index 92b6ff3..23deda8 100644 --- a/README.md +++ b/README.md @@ -8,13 +8,17 @@ It's an in-joke. ## What's all this code? -- [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. +- 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. ## These seals need more adjectives -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! +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. diff --git a/config.dhall b/config.dhall index cbddeb2..4753bbe 100644 --- a/config.dhall +++ b/config.dhall @@ -1,8 +1,6 @@ -{ sealImagesPath = "images" -, postsOutputPath = "posts" -, startDate = 1959-01-15 -, seed = +2016 -, fileExtension = "md" +{ sealImagesPath = "./images" +, postsOutputPath = "./posts" +, startDate = 2022-01-01 , adjectives1 = [ "absorbing" , "adorable" diff --git a/flake.lock b/flake.lock index dd13566..4e6b285 100644 --- a/flake.lock +++ b/flake.lock @@ -2,16 +2,16 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1690927903, - "narHash": "sha256-D5gCaCROnjEKDOel//8TO/pOP87pAEtT0uT8X+0Bj/U=", + "lastModified": 1681482634, + "narHash": "sha256-cT/nr3L8khEYZSGp8qqwxFH+/q4/547MfyOdSj6MhBk=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "bd836ac5e5a7358dea73cb74a013ca32864ccb86", + "rev": "fda0d99c2cbbb5c89d8855d258cb0821bd9113ad", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixos-23.05", + "ref": "nixos-22.11", "repo": "nixpkgs", "type": "github" } @@ -42,11 +42,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1689068808, - "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", + "lastModified": 1681202837, + "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", "owner": "numtide", "repo": "flake-utils", - "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", + "rev": "cfacdce06f30d2b68473a46042957675eebb3401", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index d370e72..019212b 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-23.05"; + nixpkgs.url = "github:NixOS/nixpkgs/nixos-22.11"; utils.url = "github:numtide/flake-utils"; }; @@ -18,25 +18,18 @@ ]); 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 - dhall-lsp-server + (pkgs.writeShellScriptBin "build-seal-generator" '' + ${ghc'}/bin/ghc -outputdir dist -O2 -static generateSealPosts.hs + '') ]; }; }); diff --git a/generateSealPosts.hs b/generateSealPosts.hs index ccd1560..c01fe7e 100755 --- a/generateSealPosts.hs +++ b/generateSealPosts.hs @@ -13,7 +13,8 @@ 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, toGregorian) +import Data.Time.Calendar (Day, addDays, diffDays, fromGregorian, + toGregorian) import Data.Time.Clock (UTCTime (utctDay), getCurrentTime) import Dhall (FromDhall, Generic, auto, input) import NeatInterpolation (text) @@ -21,7 +22,7 @@ import NeatInterpolation (text) import System.Directory (createDirectoryIfMissing, doesFileExist, listDirectory) import System.IO.Unsafe (unsafePerformIO) -import System.Random (Random (randoms), mkStdGen) +import System.Random (Random, randomRIO) {- @@ -30,12 +31,10 @@ import System.Random (Random (randoms), mkStdGen) 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 @@ -69,13 +68,8 @@ generateAllBlogPosts config = forM_ allBlogPosts' writeToFile' allBlogPosts :: Config -> [(FilePath, Text)] allBlogPosts config = map createSealText zippedDates where - 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 + createSealText = uncurry $ sealText config + zippedDates = zip [1..] (allDatesSince (startDate config)) allDatesSince :: Day -> [Day] allDatesSince startDate = map (`addDays` startDate) [0..daysSinceStart] @@ -93,22 +87,49 @@ 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! + A picture of a $adj1, $adj2 seal! <3 + |] + {- Returns a filePath, and a corresponding random blog post -} -sealText :: Config -> Integer -> Int -> Day -> (FilePath, Text) -sealText config n rand date = ( fileName', bp ) +sealText :: Config -> Integer -> Day -> (FilePath, Text) +sealText config n date = ( fileName', bp ) where fileName' = show date <> "-" <> "seal-post-" <> show n - <> "." <> fileExtension' + <> ".markdown" 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) @@ -129,60 +150,43 @@ sealText config n rand date = ( fileName', bp ) "Foolishly look at" "beautiful" "supermodel, singing" - "_singerSeal.jpg" + "singerSeal.jpg" date sealImagesPath' blogPost' (_, _, _) = blogPost title - (randomPull rand (looks config)) - (randomPull rand (adjectives1 config)) - (randomPull rand (adjectives2 config)) - (randomPull rand (unsafeListDirContents sealImagesPath')) + (randomPull $ looks config) + (randomPull $ adjectives1 config) + (randomPull $ adjectives2 config) + (randomPull $ 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! - A picture of a $adj1, $adj2 seal! <3 - |] {- 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 . drop 2 . sort . unsafePerformIO . listDirectory --- ^^^^^^ --- drop 2 used to remove the birthday and singer photos --- TODO: find a better way to hardcode this +unsafeListDirContents = map T.pack . sort . unsafePerformIO . listDirectory 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