Contact report

| bbdb, emacs, planner

I started tracking e-mail sent on 2006.09.01 with a
nifty piece of Emacs Lisp code I wrote just for the
purpose. Now I have two months of interesting data which include not
only e-mail but also the occasional in-person contact or phone call
that I remember to note. It's not complete – e-mail's the only thing
that gets automatically tracked – but it does give me interesting
information. Here's the contact report for your amusement:

Contact report

It's sorted by overall frequency and then by regular frequency.
Warning! Parentheses follow.

(defun sacha/count-matches (regexp string)
  (let ((count 0)
        (start 0))
    (while (string-match regexp string start)
      (setq start (match-end 0)
            count (1+ count)))
    count))

(defun sacha/bbdb-contact-report-as-alist (&rest regexps)
  "Creates a list of (name count-regexp1 count-regexp2 count-regexp3)..."
  (setq regexps (reverse regexps))
  (delq nil
        (mapcar
         (lambda (rec)
           (when (bbdb-record-name (car rec))
             (let ((reg regexps)
                   (notes (bbdb-record-notes (car rec)))
                   list)
               (while reg
                 (setq list (cons (sacha/count-matches (car reg) notes)
                                  list))
                 (setq reg (cdr reg)))
               (cons (sacha/planner-bbdb-annotation-from-bbdb rec)
                     list))))
         bbdb-records)))

(defun sacha/bbdb-alist-sort-by-total (alist)
  "Sort ALIST by total contact."
  (sort alist 'sacha/bbdb-contact-sort-predicate))

(defun sacha/bbdb-contact-sort-predicate (a b)
  (and a b
       (let ((count-a (apply '+ (cdr a)))
             (count-b (apply '+ (cdr b))))
         (or
          (> count-a count-b)
          (and (= count-a count-b)
               ;; If equal, look at the subtotal of the rest
               (sacha/bbdb-contact-sort-predicate (cdr a) (cdr b)))))))

(defun sacha/bbdb-kill-contact-barchart (alist)
  "Kill a barchart with the contact report for ALIST."
  (kill-new
   (mapconcat
    (lambda (entry)
      (concat
       (car entry)
       " | "
       (mapconcat (lambda (count)
                    (if (= count 0)
                        " "
                      (make-string count ?-)))
                  (cdr entry)
                  " | ")))
    alist
    "\n")))

;; Usage: (sacha/bbdb-kill-contact-barchart
;;         (sacha/bbdb-alist-sort-by-total
;;          (sacha/bbdb-contact-report-as-alist "2006.09" "2006.10")))
;; Then yank (paste) this into another buffer

Random Emacs symbol: standard-display-cyrillic-translit – Command: Display a cyrillic buffer using a transliteration.

You can comment with Disqus or you can e-mail me at sacha@sachachua.com.