Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Roam Statistics MVP
(ns roam-stats
(:require
[roam.datascript :as d]
[clojure.string]
[reagent.core :as r]))
(defn string-bytes [s]
(.-size (js/Blob. [s])))
(defn total-pages []
(count (d/datoms :aevt :node/title)))
(defn things-with-attrs []
(map (comp #(select-keys % [:entity/attrs]) d/entity :e)
(d/datoms :aevt :entity/attrs)))
(defn attr-pairs [nodes]
(reduce
(fn [[total all-attrs] node]
(let [attrs (:entity/attrs node)]
[(+ total (count attrs))
(reduce (fn [all-attrs link]
(update all-attrs (-> link second :value peek) inc))
all-attrs
attrs)]))
[0 {}]
nodes))
(defn uid-to-title [uid]
(d/q '[:find ?t .
:in $ ?uid
:where
[?e :block/uid ?uid]
[?e :node/title ?t]]
uid))
(defn all-blocks []
(->> (d/datoms :aevt :block/string)
(mapv (comp #(select-keys % [:block/string :block/refs]) d/entity :e))))
(defn blocks-stats [blocks]
(reduce (fn [stats b]
(let [s (:block/string b)]
(-> stats
(update :words +
(->> s (re-seq #"[\w']+") count))
(update :chars +
(-> s count))
(update :refs +
(-> (:block/refs b) count)))))
{:words 0
:chars 0
:refs 0}
blocks))
(defn component [_]
(let [data (r/atom [])]
(fn [_]
[:div
[:button
{:on-click
(fn []
(reset! data
(let [blocks (all-blocks)
{:keys [words chars refs]} (blocks-stats blocks)
with-attrs (things-with-attrs)
[attr-pair-count attrs] (attr-pairs with-attrs)]
(into []
(map (juxt first #(.toLocaleString (second %))))
[["Total blocks" (count blocks)]
["Total pages" (total-pages)]
["Database entities" (d/q '[:find (count ?e) . :where
[?e]])]
["Database size (kB)" (quot (+ 2300 ;; account for schema
(string-bytes
(clojure.string/join \space
(into []
(map (comp pr-str pop vec))
(d/datoms :eavt))))) 1000)]
["Links in blocks" refs]
["Links in pages" (d/q '[:find (count ?r) .
:with ?e
:where
[?e :node/title]
[?e :block/refs ?r]])]
["Words" words]
["Characters" chars]
["Blocks/pages with attributes" (count with-attrs)]
["Attribute pairs" attr-pair-count]
["Attributes by count" (str "\n "
(clojure.string/join "\n "
(map #(str (val %)
" - "
(uid-to-title (key %)))
(sort-by val > attrs))))]]))))}
"Get stats"]
(into [:ul]
(map (fn [x]
[:li
[:b (first x) ": "
[:span {:style {:color :green}}
(second x)]]]))
@data)])))
@LuisThiamNye
Copy link
Author

LuisThiamNye commented Feb 16, 2021

To use: {{[[roam/render]]: ((ref-to-clojure-codeblock))}}

image

https://twitter.com/LuisThiamNye/status/1361700661990162437

@LuisThiamNye
Copy link
Author

LuisThiamNye commented Feb 17, 2021

Fixed word count being too low.

@LuisThiamNye
Copy link
Author

LuisThiamNye commented Feb 20, 2021

Added count for references made within page titles, ie [[[[nested]] pages]]

@LuisThiamNye
Copy link
Author

LuisThiamNye commented Mar 13, 2021

Now calculates the size of the database (as an edn export) in kilobytes — at the expense of taking even longer to calculate the statistics.

Screenshot 2021-03-13 at 22 34 56

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment