babashka/examples/whatsapp_counter.clj
2020-04-23 23:06:02 +02:00

64 lines
2.3 KiB
Clojure

;; USAGE: in whatsapp group chat, export your chat _without_ media, and store somewhere.
;; Then
;; $> cat chatfile.txt | bb -i -f whatsapp_counter.clj
(require '[clojure.string :refer [lower-case includes? trim ] :as string])
(defn parse-line
"Returns the name of the message, or nil if it can't be found"
[l]
(->> (string/replace l #"\p{C}" "")
trim
(re-find #"\[.{19}\].(.+?):")
second))
(defn print-table
"NOTE: this is a verbatim copy from
https://github.com/clojure/clojure/blob/93d13d0c0671130b329863570080c72799563ac7/src/clj/clojure/pprint/print_table.clj#L11
Prints a collection of maps in a textual table. Prints table headings
ks, and then a line of output for each row, corresponding to the keys
in ks. If ks are not specified, use the keys of the first item in rows."
([ks rows]
(when (seq rows)
(let [widths (map
(fn [k]
(apply max (count (str k)) (map #(count (str (get % k))) rows)))
ks)
spacers (map #(apply str (repeat % "-")) widths)
fmts (map #(str "%" % "s") widths)
fmt-row (fn [leader divider trailer row]
(str leader
(apply str (interpose divider
(for [[col fmt] (map vector (map #(get row %) ks) fmts)]
(format fmt (str col)))))
trailer))]
(println)
(println (fmt-row "| " " | " " |" (zipmap ks ks)))
(println (fmt-row "|-" "-+-" "-|" (zipmap ks spacers)))
(doseq [row rows]
(println (fmt-row "| " " | " " |" row))))))
([rows] (print-table (keys (first rows)) rows)))
(defn chats-by-user
([lines]
(chats-by-user lines parse-line))
([lines filter-fn]
(let [ histogram (reduce
(fn [acc l]
(if-let [n (filter-fn l)]
(update acc n (fnil inc 0))
;;else ignore
acc))
{}
lines)]
(->> histogram
(sort-by second)
reverse
(map (fn [[name amount]]
{:name name
:amount amount}))
print-table))))
(chats-by-user *input*)
(System/exit 0)