* updated the guile modules

This commit is contained in:
djcb 2012-01-15 14:32:34 +02:00
parent ddb68cdea9
commit e620a32ee7
5 changed files with 129 additions and 109 deletions

View File

@ -23,40 +23,42 @@
:use-module (oop goops)
:use-module (mu message)
:export (
<mu-contact>
name email
<mu:contact>
mu:name
mu:email
mu:contact->string
;;
mu:for-each-contact
;;
contacts
mu:contacts
;;
<mu-contact-with-stats>
frequency last-seen
<mu:contact-with-stats>
mu:frequency
mu:last-seen
))
(define-class <mu-contact> ()
(name #:init-value #f #:accessor name #:init-keyword #:name)
(email #:init-value #f #:accessor email #:init-keyword #:email))
(define-class <mu:contact> ()
(name #:init-value #f #:accessor mu:name #:init-keyword #:name)
(email #:init-value #f #:accessor mu:email #:init-keyword #:email))
(define-method (contacts (msg <mu-message>) contact-type)
(define-method (mu:contacts (msg <mu:message>) contact-type)
"Get all contacts for MSG of the given CONTACT-TYPE. MSG is of type <mu-message>,
while contact type is either `mu:to', `mu:cc', `mu:from' or `mu:bcc'
to get the corresponding type of contacts, or #t to get all. Returns a
list of <mu-contact> objects."
(map (lambda (pair) ;; a pair (na . addr)
(make <mu-contact> #:name (car pair) #:email (cdr pair)))
(make <mu:contact> #:name (car pair) #:email (cdr pair)))
(mu:get-contacts (slot-ref msg 'msg) contact-type)))
(define-method (contacts (msg <mu-message>))
(define-method (mu:contacts (msg <mu:message>))
"Get contacts of all types for message MSG as a list of <mu-contact>
objects."
(contacts msg #t))
(mu:contacts msg #t))
(define-class <mu-contact-with-stats> (<mu-contact>)
(tstamp #:init-value 0 #:accessor timestamp #:init-keyword #:timestamp)
(last-seen #:init-value 0 #:accessor last-seen)
(freq #:init-value 1 #:accessor frequency))
(define-class <mu:contact-with-stats> (<mu:contact>)
(tstamp #:init-value 0 #:accessor mu:timestamp #:init-keyword #:timestamp)
(last-seen #:init-value 0 #:accessor mu:last-seen)
(freq #:init-value 1 #:accessor mu:frequency))
(define* (mu:for-each-contact proc #:optional (expr #t))
"Execute PROC for each contact. PROC receives a <mu-contact> instance
@ -67,34 +69,61 @@ matching EXPR."
(lambda (msg)
(for-each
(lambda (ct)
(let ((ct-ws (make <mu-contact-with-stats>
#:name (name ct)
#:email (email ct)
#:timestamp (date msg))))
(let ((ct-ws (make <mu:contact-with-stats>
#:name (mu:name ct)
#:email (mu:email ct)
#:timestamp (mu:date msg))))
(update-contacts-hash c-hash ct-ws)))
(contacts msg #t)))
(mu:contacts msg #t)))
expr)
(hash-for-each ;; c-hash now contains a map of email->contact
(lambda (email ct-ws) (proc ct-ws)) c-hash)))
(define-method (update-contacts-hash c-hash (nc <mu-contact-with-stats>))
(define-method (update-contacts-hash c-hash (nc <mu:contact-with-stats>))
"Update the contacts hash with a new and/or existing contact."
;; xc: existing-contact, nc: new contact
(let ((xc (hash-ref c-hash (email nc))))
(let ((xc (hash-ref c-hash (mu:email nc))))
(if (not xc) ;; no existing contact with this email address?
(hash-set! c-hash (email nc) nc) ;; store the new contact.
(hash-set! c-hash (mu:email nc) nc) ;; store the new contact.
;; otherwise:
(begin
;; 1) update the frequency for the existing contact
(set! (frequency xc) (1+ (frequency xc)))
(set! (mu:frequency xc) (1+ (mu:frequency xc)))
;; 2) update the name if the new one is not empty and its timestamp is newer
;; in that case, also update the timestamp
(if (and (name nc) (> (string-length (name nc)))
(> (timestamp nc) (timestamp xc)))
(set! (name xc) (name nc))
(set! (timestamp xc) (timestamp nc)))
(if (and (mu:name nc) (> (string-length (mu:name nc)))
(> (mu:timestamp nc) (mu:timestamp xc)))
(set! (mu:name xc) (mu:name nc))
(set! (mu:timestamp xc) (mu:timestamp nc)))
;; 3) update last-seen with timestamp, if x's timestamp is newer
(if (> (timestamp nc) (last-seen xc))
(set! (last-seen xc) (timestamp nc)))
(if (> (mu:timestamp nc) (mu:last-seen xc))
(set! (mu:last-seen xc) (mu:timestamp nc)))
;; okay --> now xc has been updated; but it back in the hash
(hash-set! c-hash (email xc) xc)))))
(hash-set! c-hash (mu:email xc) xc)))))
(define-method (mu:contact->string (contact <mu:contact>) (form <string>))
"Convert a contact to a string in format FORM, which is a string,
either \"org-contact\", \"mutt-alias\", \"mutt-ab\",
\"wanderlust\" \"plain\"."
(let* ((name (mu:name contact)) (email (mu:email contact))
(nick ;; simplistic nick guessing...
(string-map
(lambda(kar)
(if (char-alphabetic? kar) kar #\_))
(string-downcase (or name email)))))
(cond
((string= form "plain")
(format #f "~a~a~a" (if name name) (if name " ") email))
((string= form "org-contact")
(format #f "* ~s\n:PROPERTIES:\n:EMAIL:~a\n:NICK:~a\n:END:"
(or name email) email nick))
((string= form "wanderlust")
(format #f "~a ~s ~s"
nick (or name email) email))
((string= form "mutt-alias")
(format #f "alias ~a ~a <~a>"
nick (or name email) email))
((string= form "mutt-ab")
(format #f "~a\t~a\t"
email (or name "")))
(else (error "Unsupported format")))))

View File

@ -19,7 +19,7 @@
(define-module (mu message)
:use-module (oop goops)
:export ( ;; classes
<mu-message>
<mu:message>
mu:for-each-message
mu:message-list
;; internal
@ -27,58 +27,59 @@
mu:get-field
mu:for-each-msg-internal
;; message funcs
body
header
;; other symbols
mu:bcc
mu:body-html
mu:body-txt
mu:cc
mu:date
mu:flags
mu:from
mu:maildir
mu:message-id
mu:path
mu:prio
mu:refs
mu:size
mu:subject
mu:tags
mu:to))
mu:field:bcc
mu:field:body-html
mu:field:body-txt
mu:field:cc
mu:field:date
mu:field:flags
mu:field:from
mu:field:maildir
mu:field:message-id
mu:field:path
mu:field:prio
mu:field:refs
mu:field:size
mu:field:subject
mu:field:tags
mu:field:to))
(load-extension "libguile-mu" "mu_guile_message_init")
(define-class <mu-message> ()
(define-class <mu:message> ()
(msg #:init-keyword #:msg)) ;; the MuMsg-smob we're wrapping
(define-syntax define-getter
(syntax-rules ()
((define-getter method-name field)
(begin
(define-method (method-name (msg <mu-message>))
(define-method (method-name (msg <mu:message>))
(mu:get-field (slot-ref msg 'msg) field))
(export method-name)))))
(define-getter bcc mu:bcc)
(define-getter body-html mu:body-html)
(define-getter body-txt mu:body-txt)
(define-getter cc mu:cc)
(define-getter date mu:date)
(define-getter flags mu:flags)
(define-getter from mu:from)
(define-getter maildir mu:maildir)
(define-getter message-id mu:message-id)
(define-getter path mu:path)
(define-getter priority mu:prio)
(define-getter references mu:refs)
(define-getter size mu:size)
(define-getter subject mu:subject)
(define-getter tags mu:tags)
(define-getter to mu:to)
(define-getter mu:bcc mu:field:bcc)
(define-getter mu:body-html mu:field:body-html)
(define-getter mu:body-txt mu:field:body-txt)
(define-getter mu:cc mu:field:cc)
(define-getter mu:date mu:field:date)
(define-getter mu:flags mu:field:flags)
(define-getter mu:from mu:field:from)
(define-getter mu:maildir mu:field:maildir)
(define-getter mu:message-id mu:field:message-id)
(define-getter mu:path mu:field:path)
(define-getter mu:priority mu:field:prio)
(define-getter mu:references mu:field:refs)
(define-getter mu:size mu:field:size)
(define-getter mu:subject mu:field:subject)
(define-getter mu:tags mu:field:tags)
(define-getter mu:to mu:field:to)
(define-method (header (msg <mu-message>) (hdr <string>))
"Get an arbitrary header HDR from message MSG."
(define-method (header (msg <mu:message>) (hdr <string>))
"Get an arbitrary header HDR from message MSG; return #f if it does
not exist."
(mu:get-header (slot-ref msg 'msg) hdr))
(define* (mu:for-each-message func #:optional (expr #t))
@ -86,7 +87,7 @@
If EXPR is not provided, match /all/ messages in the store."
(mu:for-each-msg-internal
(lambda (msg)
(func (make <mu-message> #:msg msg)))
(func (make <mu:message> #:msg msg)))
expr))
(define* (mu:message-list #:optional (expr #t))

View File

@ -22,30 +22,29 @@
:use-module (mu message)
:export (;; get-part
;; classes
<mu-part>
<mu:part>
;; message function
attachments
parts
;; <mu-part> methods
index
name
mime-type
mu:attachments
mu:parts
;; <mu:part> methods
mu:name
mu:mime-type
;; size
save
save-as))
mu:save
mu:save-as))
(define-class <mu-part> ()
(define-class <mu:part> ()
(msgpath #:init-value #f #:init-keyword #:msgpath)
(index #:init-value #f #:init-keyword #:index)
(name #:init-value #f #:getter name #:init-keyword #:name)
(mime-type #:init-value #f #:getter mime-type #:init-keyword #:mime-type)
(size #:init-value 0 #:getter size #:init-keyword #:size))
(name #:init-value #f #:getter mu:name #:init-keyword #:name)
(mime-type #:init-value #f #:getter mu:mime-type #:init-keyword #:mime-type)
(size #:init-value 0 #:getter mu:size #:init-keyword #:size))
(define-method (get-parts (msg <mu-message>) (files-only <boolean>))
"Get the part for MSG as a list of <mu-part> objects; if FILES-ONLY is #t,
(define-method (get-parts (msg <mu:message>) (files-only <boolean>))
"Get the part for MSG as a list of <mu:part> objects; if FILES-ONLY is #t,
only get the part with file names."
(map (lambda (part)
(make <mu-part>
(make <mu:part>
#:msgpath (list-ref part 0)
#:index (list-ref part 1)
#:name (list-ref part 2)
@ -53,20 +52,20 @@ only get the part with file names."
#:size (list-ref part 4)))
(mu:get-parts (slot-ref msg 'msg) files-only)))
(define-method (attachments (msg <mu-message>))
"Get the attachments for MSG as a list of <mu-part> objects."
(define-method (mu:attachments (msg <mu:message>))
"Get the attachments for MSG as a list of <mu:part> objects."
(get-parts msg #t))
(define-method (parts (msg <mu-message>))
(define-method (mu:parts (msg <mu:message>))
"Get the MIME-parts for MSG as a list of <mu-part> objects."
(get-parts msg #f))
(define-method (save (part <mu-part>))
(define-method (mu:save (part <mu:part>))
"Save PART to a temporary file, and return the file name. If the
part had a filename, the temporary file's file name will be just that;
otherwise a name is made up."
(mu:save-part (slot-ref part 'msgpath) (slot-ref part 'index)))
(define-method (save-as (part <mu-part>) (filepath <string>))
(define-method (mu:save-as (part <mu:part>) (filepath <string>))
"Save message-part PART to file system path PATH."
(copy-file (save part) filepath))

View File

@ -19,8 +19,7 @@
(define-module (mu plot)
:use-module (mu message)
:use-module (ice-9 popen)
:export ( mu:plot-x11
mu:plot-ascii))
:export ( mu:plot))
(define (export-pairs pairs)
"Write a temporary file with the list of PAIRS in table format, and
@ -34,14 +33,14 @@ return the file name."
(close output)
datafile))
(define (mu:plot data title x-label y-label want-ascii)
"Plot DATA with TITLE, X-LABEL and X-LABEL. If WANT-ASCII is #t,
output in plain-text; otherwise use an X11 window."
(define* (mu:plot data title x-label y-label #:optional (ascii #f))
"Plot DATA with TITLE, X-LABEL and X-LABEL. If ASCII is true, display
using raw text, otherwise, use a graphical window."
(let ((datafile (export-pairs data))
(gnuplot (open-pipe "gnuplot -p" OPEN_WRITE)))
(display (string-append
"reset\n"
"set term " (if want-ascii "dumb" "x11") "\n"
"set term " (if ascii "wxt" "dumb") "\n"
"set title \"" title "\"\n"
"set xlabel \"" x-label "\"\n"
"set ylabel \"" y-label "\"\n"
@ -49,11 +48,3 @@ output in plain-text; otherwise use an X11 window."
"plot \"" datafile "\" using 2:xticlabels(1) with boxes fs solid\n")
gnuplot)
(close-pipe gnuplot)))
(define* (mu:plot-ascii data #:optional (title "Title") (x-label "X") (y-label "Y"))
"Plot DATA with TITLE, X-LABEL and X-LABEL in plain-text."
(mu:plot data title x-label y-label #t))
(define* (mu:plot-x11 data #:optional (title "Title") (x-label "X") (y-label "Y"))
"Plot DATA with TITLE, X-LABEL and X-LABEL in an X11 window."
(mu:plot data title x-label y-label #f))

View File

@ -23,7 +23,7 @@
:use-module (ice-9 i18n)
:export ( mu:tabulate-messages
mu:average-messages
mu:day-numbers->names
mu:weekday-numbers->names
mu:month-numbers->names))
(define* (mu:tabulate-messages func #:optional (expr #t))
@ -65,7 +65,7 @@ icecream: (mu:average (lambda(msg) (size msg)) \"icecream\" ."
(locale-day-short num))
(iota 7 1)))
(define (mu:day-numbers->names table)
(define (mu:weekday-numbers->names table)
"Convert a list of pairs with the car denoting a day number (0-6)
into a list of pairs with the car replaced by the corresponding day
name (abbreviated)."