babashka and nbb feel like they gain momentum, so I chose nbb and dabbled a little.

What I got, was an easy to use Screenshot Tool I can run from the terminal.

You can find the repo here, on GitHub.

The project relies on playwright and Node’s ArgumentParser and of course nbb.

“Lisp is worth learning for the profound enlightenment experience you will have when you finally get it; that experience will make you a better programmer for the rest of your days, even if you never actually use Lisp itself a lot.”

  • Eric Raymond, “How to Become a Hacker”

Learn ClojureScript

(ns script
  (:require
   ["playwright$default" :as playwright :refer [firefox]]
   ["argparse" :as argparse :refer [ArgumentParser]]))

(defn- sleep [f ms]
  (js/setTimeout f ms))

(def parser
  (ArgumentParser. #js {:prog "main.cljs"
                        :description "This is a simple screenshot app!"}))

(.add_argument parser ""
               #js {:help "url of which to take a screenshot"})
(.add_argument parser "-t" "--timeout"
               #js {:help "timeout after page visit before taking the screenshot"})

#_(.dir js/console (.parse_args parser (clj->js (vec *command-line-args*))))

(defn- get-url-command-line-arg
  "Parses the first string after calling the script
  `$ nbb main.cljs https://www.simon-neutert.de`"
  []
  (.- (.parse_args parser (clj->js (vec *command-line-args*)))))

(defn- get-timeout-command-line-arg
  "Parses the argument passed with `-t` or `--timeout` after calling the script
  `$ nbb main.cljs https://www.simon-neutert.de`"
  []
  (js/parseInt
   (or
    (.-t (.parse_args parser (clj->js (vec *command-line-args*))))
    (.-timeout (.parse_args parser (clj->js (vec *command-line-args*))))
    300)))

(defn sleep-promise+
  "wraps a Promise around a timeout returning the given object"
  [obj wait]
  (js/Promise.
   (fn [resolve _reject]
     (sleep #(resolve obj) wait))))

(defn screenshot
  "This is where the magic happens" 
  []
  (->
   (.launch firefox)
   (.then (fn [browser]
            (->
             (.newPage browser)
             (.then (fn [page]
                      (-> (.goto page (get-url-command-line-arg))
                          (.then #(sleep-promise+ browser (get-timeout-command-line-arg)))
                          (.then #(.screenshot page #js{:path "screenshot.png"}))
                          (.catch #(js/console.log %))
                          (.then #(.close browser))))))))))

(screenshot)