#+title: mu-guile: guile-bindings for mu
#+style: <link rel="stylesheet" type="text/css" href="mu.css">
#+options: skip t

  Starting from version 0.9.7, [[http://www.djcbsoftware.nl/code/mu][mu]] had experimental bindings for the [[http://www.gnu.org/software/guile/][GNU/Guile]]
  programming language, which is a version of the [[http://en.wikipedia.org/wiki/Scheme_(programming_language)][Scheme]] programming language,
  specifically designed for extending existing programs.

  =mu= version 0.9.8 has much improved bindings, and they are [[file:mu-guile/index.html][documented]], with
  many examples. You can find more examples in the =guile/examples= directory of
  the =mu= source package.

  It must be said that Scheme (and in general, languages from the Lisp-family)
  initially may look a bit 'strange' -- all these parentheses etc.; so please
  bear with us -- you will get used to it.

** Some examples

   Here are some examples; we don't provide too much explanation /how/ they do
   what they do, but the [[file:mu-guile/index.html][manual]] takes you through that, step-by-step.

   *NOTE (1)*: if you get errors like =ERROR: no code for module (mu)=, ~guile~
   cannot find the ~mu~ modules. To solve this, you need to set the
   ~GUILE_LOAD_PATH~ to the directory with the installed ~mu.scm~, e.g.

#+begin_src sh
   export GUILE_LOAD_PATH="/usr/local/share/guile/site/2.0"
#+end_src

   (you need to adapt this if you installed =mu= in some non-standard place; but
   it's always the directory with the installed ~mu.scm~).

   *NOTE (2)*: for the graphs (below) to work, you will need to have the =gnuplot=
    program installed.
    
   *NOTE (3)*: the examples below assume that you have your messages indexed
   already using =mu=; see the man pages, or the [[http://www.djcbsoftware.nl/code/mu/cheatsheet.html][mu cheat sheet]].

*** Messages per weekday

#+begin_src scheme
#!/bin/sh
exec guile -s $0 $@
!#

(use-modules (mu) (mu message) (mu stats) (mu plot))
(mu:initialize)

;; create a list like (("Mon" . 13) ("Tue" . 23) ...)
(define weekday-table
  (mu:weekday-numbers->names
    (sort
      (mu:tabulate-messages
	(lambda (msg)
	  (tm:wday (localtime (mu:date msg)))))
      (lambda (a b) (< (car a) (car b))))))

(for-each
  (lambda (elm)
    (format #t "~a: ~a\n" (car elm) (cdr elm)))
  weekday-table)
#+end_src

    Which outputs something like:

#+begin_example
Sun: 2278
Mon: 2991
Tue: 3077
Wed: 2734
Thu: 2796
Fri: 2343
Sat: 1856
#+end_example

    The numbers may be a bit different though... In my case, Saturday seems a
    particularly slow day for e-mail.

*** Drawing graphs

    We can also draw graphs from this, by adding the following to the script:

#+begin_src scheme
;; plain-text graph
(mu:plot (weekday-table) "Messages per weekday" "Day" "Messages" #t)

;; GUI graph
(mu:plot (weekday-table) "Messages per weekday" "Day" "Messages")
#+end_src scheme

    This gives us the following:

**** plain text graph
#+begin_example
                               Messages per weekday
 Messages
   3200 ++---+--------+---------+--------+---------+---------+--------+---++
        |    +        +     "/tmp/filel8NGRf" using 2:xticlabels(1) ****** |
   3000 ++                  *       *                                     ++
        |         ***********       *                                      |
        |         *        **       *                                      |
   2800 ++        *        **       *          *********                  ++
        |         *        **       ************       *                   |
   2600 ++        *        **       **        **       *                  ++
        |         *        **       **        **       *                   |
        |         *        **       **        **       *                   |
   2400 ++        *        **       **        **       ***********        ++
        ***********        **       **        **       **        *         |
   2200 *+       **        **       **        **       **        *        ++
        *        **        **       **        **       **        *         |
        *        **        **       **        **       **        *         |
   2000 *+       **        **       **        **       **        *        ++
        *    +   **   +    **   +   **   +    **   +   **    +   ***********
   1800 ********************************************************************
            Sun      Mon       Tue      Wed       Thu       Fri      Sat
                                        Day
#+end_example

**** GUI graph

     [[file:graph01.png]]



*** Export contacts to =mutt=

    =mu= provides =mu cfind= to get contact information from the database; it's
    fast, since it uses cached contact data. But sometimes, we may want to get a
    bit more advanced. For examples, suppose I want a list of names and e-mail
    addresses of people that were seen at least 20 times since 2010, in the
    =mutt= address book format.

    We could get such a list with something like the following:

#+begin_src scheme
#!/bin/sh
exec guile -s $0 $@
!#

(use-modules (mu) (mu message) (mu contact))
(mu:initialize)

;; Get a list of contacts that were seen at least 20 times since 2010
(define (selected-contacts)
  (let  ((addrs '())
	  (start (car (mktime (car (strptime "%F" "2010-01-01")))))
	  (minfreq 20))
    (mu:for-each-contact
      (lambda (contact)
	(if (and (mu:email contact)
	      (>= (mu:frequency contact) minfreq)
	      (>= (mu:last-seen contact) start))
	  (set! addrs (cons contact addrs)))))
      addrs))

(for-each
  (lambda (contact)
    (format #t "~a\n" (mu:contact->string contact "mutt-alias")))
  (selected-contacts))
#+end_src

** License & Copyright

   *mu-guile* was designed and implemented by Dirk-Jan C. Binnema, and is Free
   Software, licensed under the GNU GPLv3

#+html:<hr/><div align="center">&copy; 2011-2012 Dirk-Jan C. Binnema</div>
#+begin_html
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
var pageTracker = _gat._getTracker("UA-578531-1");
pageTracker._trackPageview();
</script>
#+end_html
