On Mon, Sep 26 2011, Roland Winkler wrote:

> On Mon Sep 26 2011 Eric Abrahamsen wrote:
>> While we're on the subject of features that won't be considered until
>> version 3 is finished, if ever 
>> 
>> I've been writing a small function to export BBDB records according to
>> an arbitrary text template. I'm running up against the problem that
>> there seems to be no generic "get the value of this field for this
>> record" function. Ie, something like (bbdb-field-value 'mail record) -->
>> "exam...@mail.com". 
>
> How about bbdb-record-get-field? I just noticed that at the end,
> before throwing an error this function could also try to resolve
> individual note fields (same for bbdb-record-set-field).
>
>> Also, does this seem like a good idea in general? I know that we're in
>> some kind of feature freeze, but this would also be relatively distinct
>> from the rest of the codebase, and if it's an attractive idea I'd be
>> happy to chew on it in my spare time. Some generic templates could be
>> included for common needs 
>
> Sounds useful to me.

Okay, I've got this working. It's very bare bones, but works well enough
that the design flaws are becoming apparent.

As I conceived of/implemented this, it's basically a format string, with
the format string's typical placeholders. Two problems with this are
already obvious:

1. If there's no value for a field, you get a nice ugly "nil". Ideally
   we'd have conditional insertion of strings depending on whether or
   not there's a value for a given field, but that means we can't use
   `format' anymore, and suddenly this whole thing gets a *lot* more
   complicated than a Friday afternoon project.
2. There's no obvious way of indicating which value of a multi-valued
   field you want. `bbdb-record-get-field' only gets us so far, as it's
   indiscriminate about fields with string values, list values and
   struct values. With a little work it would be possible to access
   subvalues by constructing complex field names: for instance,
   address-home (to get the address field labelled "home") or mail-3 (to
   get the third element of the mail list, assuming there is one) or
   phone-all (to get some reasonably-formatted list of all the phone
   values). I've seen people mess with symbol names like this before,
   and could probably figure it out.

Issue number one seems way harder to solve, largely because I have no
good ideas for solving it. Issue could be solved the way I mentioned, or
else some other way.

I've attached the patch, including a new file. The whole thing is
early-stage enough that I'd be perfectly happy reworking any aspect of
it, or tossing it out altogether.

Eric

diff --git a/lisp/bbdb-export.el b/lisp/bbdb-export.el
new file mode 100644
index 0000000..ca717aa
--- /dev/null
+++ b/lisp/bbdb-export.el
@@ -0,0 +1,72 @@
+;;; Commentary
+
+;; This is meant to be a generic text-based exporter for the BBDB.
+;; Per-record templates are recorded `bbdb-export-templates', and
+;; exporting is performed by selecting a number of records to export,
+;; then selecting the appropriate template. A temporary buffer is
+;; created, containing first the value of `bbdb-export-preamble', then
+;; the export template filled once per record and separated by
+;; `bbdb-export-separator', and lastly followed by
+;; `bbdb-export-postamble'.
+
+;; Add new templates like this:
+
+;; (bbdb-export-register-template FORMAT_STRING VAL_LIST PREAMBLE POSTAMBLE SEPARATOR)
+;; where PREAMBLE POSTAMBLE and SEPARATOR are optional strings, with defaults.
+
+(require 'bbdb)
+(require 'bbdb-com)
+
+(setq bbdb-export-templates nil)
+(defconst bbdb-export-default-preamble "")
+(defconst bbdb-export-default-postamble "")
+(defconst bbdb-export-default-separator "\n\n")
+
+;;;###autoload
+(defun bbdb-export (records)
+  "Export RECORDS according to a chosen template."
+  (interactive (list (bbdb-do-records)))
+  (setq records (bbdb-record-list records))
+  (let*  ((buf (get-buffer-create "*BBDB Export*"))
+	 (templ (rest (assoc (completing-read "Template name: " bbdb-export-templates)
+			     bbdb-export-templates)))
+	 (pre (or (nth 2 templ)
+		  bbdb-export-default-preamble))
+	 (post (or (nth 3 templ)
+		   bbdb-export-default-postamble))
+	 (sep (or (nth 4 templ)
+		  bbdb-export-default-separator))
+	 (fields (nth 1 templ))
+	 (strg (first templ))
+	 (count 0))
+    (set-buffer buf)
+    (erase-buffer)
+    (fundamental-mode)
+    (insert pre)
+    (insert
+     (mapconcat
+      (lambda (i)
+	(apply 'format strg (mapcar
+			     (lambda (f)
+			       (let ((val (cond ((eq f 'bbdb-export-counter)
+						 (progn
+						   (setq count (1+ count))
+						   count))
+						;; Something with callable sexps here
+						(t
+						 (bbdb-record-get-field i f)))))
+				 (when (consp val) ; totally fudging multi-value fields here
+				   (setq val (first val)))
+				 val))
+			     fields)))
+		records sep))
+    (insert post)
+    (switch-to-buffer buf)))
+
+(defmacro bbdb-export-register-template (label format-string val-list &optional preamble postamble separator)
+  "Add a template to `bbdb-export-templates'"
+  `(add-to-list 'bbdb-export-templates
+	       '(,label ,format-string ,val-list ,preamble ,postamble ,separator)))
+
+(bbdb-export-register-template "default" "Name: %s\nEmail: %s" (name mail))
+(bbdb-export-register-template "fancy" "Hark, this be record %d, for %s" (bbdb-export-counter name) "Here goes the awesome export!\n" "\nAwesome export done.")
\ No newline at end of file
diff --git a/lisp/bbdb.el b/lisp/bbdb.el
index 799bd95..5ed05f2 100644
--- a/lisp/bbdb.el
+++ b/lisp/bbdb.el
@@ -57,6 +57,7 @@
   (autoload 'bbdb-completing-read-records "bbdb-com")
   (autoload 'mail-position-on-field "sendmail")
   (autoload 'vm-select-folder-buffer "vm-folder")
+  (autoload 'bbdb-export "bbdb-export")
 
   ;; cannot use autoload for variables...
   (defvar message-mode-map) ;; message.el
@@ -1389,6 +1390,7 @@ APPEND and INVERT appear in the message area.")
     (define-key km "A"          'bbdb-mail-aliases)
     (define-key km "c"          'bbdb-create)
     (define-key km "e"          'bbdb-edit-field)
+    (define-key km "E"          'bbdb-export)
     (define-key km "n"          'bbdb-next-record)
     (define-key km "p"          'bbdb-prev-record)
     (define-key km "N"          'bbdb-next-field)
------------------------------------------------------------------------------
All of the data generated in your IT infrastructure is seriously valuable.
Why? It contains a definitive record of application performance, security
threats, fraudulent activity, and more. Splunk takes this data and makes
sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-d2dcopy2
_______________________________________________
bbdb-info@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bbdb-info
BBDB Home Page: http://bbdb.sourceforge.net/

Reply via email to