023ac84a7ab60f73d74f86e334bc7c27fe51c2ab
[elisp/tm.git] / tm-bbdb.el
1 ;;;
2 ;;; tm-bbdb.el --- tm shared module for BBDB
3 ;;;
4 ;;; Copyright (C) 1995,1996 KOBAYASHI Shuhei
5 ;;; Copyright (C) 1996 Artur Pioro
6 ;;;
7 ;;; Author: KOBAYASHI Shuhei <shuhei@cmpt01.phys.tohoku.ac.jp>
8 ;;;         Artur Pioro <artur@flugor.if.uj.edu.pl>
9 ;;; Maintainer: MORIOKA Tomohiko <morioka@jaist.ac.jp>
10 ;;; Version: $Id: tm-bbdb.el,v 7.2 1996/03/14 13:41:48 morioka Exp $
11 ;;; Keywords: mail, news, MIME, multimedia, multilingual, BBDB
12 ;;;
13 ;;; This file is part of tm (Tools for MIME).
14 ;;;
15 ;;; This program is free software; you can redistribute it and/or
16 ;;; modify it under the terms of the GNU General Public License as
17 ;;; published by the Free Software Foundation; either version 2, or
18 ;;; (at your option) any later version.
19 ;;;
20 ;;; This program is distributed in the hope that it will be useful,
21 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
22 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23 ;;; General Public License for more details.
24 ;;;
25 ;;; You should have received a copy of the GNU General Public License
26 ;;; along with This program.  If not, write to the Free Software
27 ;;; Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
28 ;;;
29 ;;; Code:
30
31 (require 'bbdb)
32 (require 'bbdb-com)
33 (require 'tl-822)
34 (require 'tm-ew-d)
35 (require 'tm-view)
36
37
38 ;;; @ mail-extr
39 ;;;
40
41 (defvar tm-bbdb/use-mail-extr t)
42
43 (defun tm-bbdb/extract-address-components (str)
44   (let* ((ret     (rfc822/extract-address-components str))
45          (phrase  (car ret))
46          (address (cdr ret))
47          (methods tm-bbdb/canonicalize-full-name-methods))
48     (while (and phrase methods)
49       (setq phrase  (funcall (car methods) phrase)
50             methods (cdr methods)))
51     (if (string= phrase "")
52         (setq phrase nil))
53     (cons phrase address)
54     ))
55
56 (or tm-bbdb/use-mail-extr
57     (progn
58       (require 'mail-extr) ; for `what-domain'
59       (fset 'mail-extract-address-components
60             (symbol-function 'tm-bbdb/extract-address-components))
61       ))
62
63
64 ;;; @ bbdb-extract-field-value
65 ;;;
66
67 (or (fboundp 'tm:bbdb-extract-field-value)
68     (progn
69       ;; (require 'bbdb-hooks) ; not provided.
70       ;; (or (fboundp 'bbdb-extract-field-value) ; defined as autoload
71       (or (fboundp 'bbdb-header-start)
72           (load "bbdb-hooks"))
73       (fset 'tm:bbdb-extract-field-value
74             (symbol-function 'bbdb-extract-field-value))
75       (defun bbdb-extract-field-value (field)
76         (let ((value (tm:bbdb-extract-field-value field)))
77           (and value
78                (mime-eword/decode-string value))))
79       ))
80
81
82 ;;; @ full-name canonicalization methods
83 ;;;
84
85 (defun tm-bbdb/canonicalize-spaces (str)
86   (let (dest)
87     (while (string-match "\\s +" str)
88       (setq dest (cons (substring str 0 (match-beginning 0)) dest))
89       (setq str (substring str (match-end 0)))
90       )
91     (or (string= str "")
92         (setq dest (cons str dest)))
93     (setq dest (nreverse dest))
94     (mapconcat 'identity dest " ")
95     ))
96
97 (defun tm-bbdb/canonicalize-dots (str)
98   (let (dest)
99     (while (string-match "\\." str)
100       (setq dest (cons (substring str 0 (match-end 0)) dest))
101       (setq str (substring str (match-end 0)))
102       )
103     (or (string= str "")
104         (setq dest (cons str dest)))
105     (setq dest (nreverse dest))
106     (mapconcat 'identity dest " ")
107     ))
108
109 (defvar tm-bbdb/canonicalize-full-name-methods
110   '(mime-eword/decode-string
111     tm-bbdb/canonicalize-dots
112     tm-bbdb/canonicalize-spaces))
113
114
115 ;;; @ BBDB functions for mime/viewer-mode
116 ;;;
117
118 (defvar tm-bbdb/auto-create-p nil)
119
120 (defun tm-bbdb/update-record (&optional offer-to-create)
121   "Return the record corresponding to the current MIME previewing message.
122 Creating or modifying it as necessary. A record will be created if
123 tm-bbdb/auto-create-p is non-nil, or if OFFER-TO-CREATE is non-nil and
124 the user confirms the creation."
125   (save-excursion
126     (if (and mime::article/preview-buffer
127              (get-buffer mime::article/preview-buffer))
128         (set-buffer mime::article/preview-buffer))
129     (if bbdb-use-pop-up
130         (tm-bbdb/pop-up-bbdb-buffer offer-to-create)
131       (let* ((from (rfc822/get-field-body "From"))
132              (addr (car (cdr (mail-extract-address-components from)))))
133         (if (or (null from)
134                 (null addr)
135                 (string-match (bbdb-user-mail-names) addr))
136             (setq from (or (rfc822/get-field-body "To")
137                            from)))
138         (if from
139             (bbdb-annotate-message-sender
140              from t
141              (or (bbdb-invoke-hook-for-value tm-bbdb/auto-create-p)
142                  offer-to-create)
143              offer-to-create))
144         ))))
145
146 (defun tm-bbdb/annotate-sender (string)
147   "Add a line to the end of the Notes field of the BBDB record 
148 corresponding to the sender of this message."
149   (interactive
150    (list (if bbdb-readonly-p
151              (error "The Insidious Big Brother Database is read-only.")
152            (read-string "Comments: "))))
153   (bbdb-annotate-notes (tm-bbdb/update-record t) string))
154
155 (defun tm-bbdb/edit-notes (&optional arg)
156   "Edit the notes field or (with a prefix arg) a user-defined field
157 of the BBDB record corresponding to the sender of this message."
158   (interactive "P")
159   (let ((record (or (tm-bbdb/update-record t)
160                     (error ""))))
161     (bbdb-display-records (list record))
162     (if arg
163         (bbdb-record-edit-property record nil t)
164       (bbdb-record-edit-notes record t))))
165
166 (defun tm-bbdb/show-sender ()
167   "Display the contents of the BBDB for the sender of this message.
168 This buffer will be in bbdb-mode, with associated keybindings."
169   (interactive)
170   (let ((record (tm-bbdb/update-record t)))
171     (if record
172         (bbdb-display-records (list record))
173         (error "unperson"))))
174
175 (defun tm-bbdb/pop-up-bbdb-buffer (&optional offer-to-create)
176   "Make the *BBDB* buffer be displayed along with the MIME preview window(s),
177 displaying the record corresponding to the sender of the current message."
178   (bbdb-pop-up-bbdb-buffer
179     (function (lambda (w)
180       (let ((b (current-buffer)))
181         (set-buffer (window-buffer w))
182         (prog1 (eq major-mode 'mime/viewer-mode)
183           (set-buffer b))))))
184   (let ((bbdb-gag-messages t)
185         (bbdb-use-pop-up nil)
186         (bbdb-electric-p nil))
187     (let ((record (tm-bbdb/update-record offer-to-create))
188           (bbdb-elided-display (bbdb-pop-up-elided-display))
189           (b (current-buffer)))
190       (bbdb-display-records (if record (list record) nil))
191       (set-buffer b)
192       record)))
193
194
195 ;;; @ for signature.el
196 ;;;
197
198 (defun signature-check-in-bbdb (address)
199   "Returns 'sigtype field from BBDB for user specified by ADDRESS"
200   (let ((addr-comp (mail-extract-address-components address))
201         full-name net-name records record sigtype)
202     (setq full-name (car addr-comp))
203     (setq net-name (mapconcat (lambda (x) x) (cdr addr-comp) "\\|"))
204     (setq records
205           (or
206            (and full-name
207                 (bbdb-search (bbdb-records) full-name))
208            (and net-name
209                 (bbdb-search (bbdb-records) nil nil net-name))))
210     (setq record (car records))
211     (setq records (cdr records))
212     (setq sigtype (and record (bbdb-record-getprop record 'sigtype)))
213     (while (and (not sigtype) records)
214       (setq record (car records))
215       (setq records (cdr records))
216       (setq sigtype (bbdb-record-getprop record 'sigtype)))
217     (if sigtype
218         (message (concat "Using signature for: "
219                          (bbdb-record-firstname record) " "
220                          (bbdb-record-lastname record)
221                          (and (bbdb-record-aka record)
222                               (concat " (AKA: "
223                                       (car (bbdb-record-aka record))
224                                       ")"))
225                          " <" (car (bbdb-record-net record)) ">")))
226     sigtype))
227
228
229 ;;; @ end
230 ;;;
231
232 (provide 'tm-bbdb)
233
234 (run-hooks 'tm-bbdb-load-hook)
235
236 ;;; end of tm-bbdb.el