comparison lisp/mail/rmail-spam-filter.el @ 53685:2d1c4cfccc4a

Use two semicolons as Commentary line prefix. Add ";;; Code:" stylized comment. Delete end-of-line whitespace. Wrap (require 'cl) with `eval-when-compile'.
author Thien-Thi Nguyen <ttn@gnuvola.org>
date Sat, 24 Jan 2004 16:59:23 +0000
parents c1b91f41e667
children 2a4fc5c14ddd
comparison
equal deleted inserted replaced
53684:f58a3ce5a982 53685:2d1c4cfccc4a
1 ;;; rmail-spam-filter.el --- spam filter for rmail, the emacs mail reader. 1 ;;; rmail-spam-filter.el --- spam filter for RMAIL
2 2
3 ;; Copyright (C) 2002 3 ;; Copyright (C) 2002
4 ;; Free Software Foundation, Inc. 4 ;; Free Software Foundation, Inc.
5 ;; Keywords: email, spam, filter, rmail 5 ;; Keywords: email, spam, filter, rmail
6 ;; Author: Eli Tziperman <eli@beach.weizmann.ac.il> 6 ;; Author: Eli Tziperman <eli@beach.weizmann.ac.il>
7 7
8 ;; This file is part of GNU Emacs. 8 ;; This file is part of GNU Emacs.
21 ;; along with GNU Emacs; see the file COPYING. If not, write to the 21 ;; along with GNU Emacs; see the file COPYING. If not, write to the
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, 22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA. 23 ;; Boston, MA 02111-1307, USA.
24 24
25 ;;; Commentary: 25 ;;; Commentary:
26 ;;; ----------- 26
27 27 ;; Automatically recognize and delete junk email before it is
28 ;;; Automatically recognize and delete junk email before it is 28 ;; displayed in rmail/rmail-summary. Spam emails are defined by
29 ;;; displayed in rmail/rmail-summary. Spam emails are defined by 29 ;; specifying one or more of the sender, subject and contents.
30 ;;; specifying one or more of the sender, subject and contents. 30 ;; URL: http://www.weizmann.ac.il/~eli/Downloads/rmail-spam-filter/
31 ;;; URL: http://www.weizmann.ac.il/~eli/Downloads/rmail-spam-filter/ 31
32 32 ;; Usage:
33 ;;; Usage: 33 ;; ------
34 ;;; ------ 34
35 35 ;; put in your .emacs:
36 ;;; put in your .emacs: 36
37 37 ;; (load "rmail-spam-filter.el")
38 ;;; (load "rmail-spam-filter.el") 38
39 39 ;; and use customize (in rmail-spam-filter group) to:
40 ;;; and use customize (in rmail-spam-filter group) to: 40
41 41 ;; (*) turn on the variable rmail-use-spam-filter,
42 ;;; (*) turn on the variable rmail-use-spam-filter, 42
43 43 ;; (*) specify in variable rmail-spam-definitions-alist what sender,
44 ;;; (*) specify in variable rmail-spam-definitions-alist what sender, 44 ;; subject and contents make an email be considered spam.
45 ;;; subject and contents make an email be considered spam. 45
46 46 ;; in addition, you may:
47 ;;; in addition, you may: 47
48 48 ;; (*) Block future mail with the subject or sender of a message
49 ;;; (*) Block future mail with the subject or sender of a message 49 ;; while reading it in RMAIL: just click on the "Spam" item on the
50 ;;; while reading it in RMAIL: just click on the "Spam" item on the 50 ;; menubar, and add the subject or sender to the list of spam
51 ;;; menubar, and add the subject or sender to the list of spam 51 ;; definitions using the mouse and the appropriate menu item. Â  You
52 ;;; definitions using the mouse and the appropriate menu item. Â  You 52 ;; need to later also save the list of spam definitions using the
53 ;;; need to later also save the list of spam definitions using the 53 ;; same menu item, or alternatively, see variable
54 ;;; same menu item, or alternatively, see variable 54 ;; `rmail-spam-filter-autosave-newly-added-spam-definitions'.
55 ;;; `rmail-spam-filter-autosave-newly-added-spam-definitions'. 55
56 56 ;; (*) specify if blind-cc'ed mail (no "To:" header field) is to be
57 ;;; (*) specify if blind-cc'ed mail (no "To:" header field) is to be 57 ;; treated as spam (variable rmail-spam-no-blind-cc; Thanks to Ethan
58 ;;; treated as spam (variable rmail-spam-no-blind-cc; Thanks to Ethan 58 ;; Brown <ethan@gso.saic.com> for this).
59 ;;; Brown <ethan@gso.saic.com> for this). 59
60 60 ;; (*) specify if rmail-spam-filter should ignore case of spam
61 ;;; (*) specify if rmail-spam-filter should ignore case of spam 61 ;; definitions (variable rmail-spam-filter-ignore-case; Thanks to
62 ;;; definitions (variable rmail-spam-filter-ignore-case; Thanks to 62 ;; Ethan Brown <ethan@gso.saic.com> for the suggestion).
63 ;;; Ethan Brown <ethan@gso.saic.com> for the suggestion). 63
64 64 ;; (*) Specify a "white-list" of trusted senders. If any
65 ;;; (*) Specify a "white-list" of trusted senders. If any 65 ;; rmail-spam-white-list string matches a substring of the "From"
66 ;;; rmail-spam-white-list string matches a substring of the "From" 66 ;; header, the message is flagged as a valid, non-spam message (Ethan
67 ;;; header, the message is flagged as a valid, non-spam message (Ethan 67 ;; Brown <ethan@gso.saic.com>).
68 ;;; Brown <ethan@gso.saic.com>). 68
69 69 ;; (*) rmail spam filter also works with bbdb to prevent spam senders
70 ;;; (*) rmail spam filter also works with bbdb to prevent spam senders 70 ;; from entering into the .bbdb file. See variable
71 ;;; from entering into the .bbdb file. See variable 71 ;; "rmail-spam-filter-auto-delete-spam-bbdb-entries". This is done
72 ;;; "rmail-spam-filter-auto-delete-spam-bbdb-entries". This is done 72 ;; in two ways: (a) bbdb is made not to auto-create entries for
73 ;;; in two ways: (a) bbdb is made not to auto-create entries for 73 ;; messages that are deleted by the rmail-spam-filter, (b) when a
74 ;;; messages that are deleted by the rmail-spam-filter, (b) when a 74 ;; message is deleted in rmail, the user is offered to delete the
75 ;;; message is deleted in rmail, the user is offered to delete the 75 ;; sender's bbdb entry as well _if_ it was created at the same day.
76 ;;; sender's bbdb entry as well _if_ it was created at the same day. 76
77 ;;; Code:
77 78
78 (require 'rmail) 79 (require 'rmail)
79 80
80 ;; For find-if and other cool common lisp functions we may want to use. (EDB) 81 ;; For find-if and other cool common lisp functions we may want to use. (EDB)
81 (require 'cl) 82 (eval-when-compile
83 (require 'cl))
82 84
83 (defgroup rmail-spam-filter nil 85 (defgroup rmail-spam-filter nil
84 "Spam filter for RMAIL, the mail reader for Emacs." 86 "Spam filter for RMAIL, the mail reader for Emacs."
85 :group 'rmail) 87 :group 'rmail)
86 88
118 120
119 (defcustom rmail-spam-sleep-after-message 2.0 121 (defcustom rmail-spam-sleep-after-message 2.0
120 "*Seconds to wait after display of message that spam was found." 122 "*Seconds to wait after display of message that spam was found."
121 :type 'number 123 :type 'number
122 :group 'rmail-spam-filter ) 124 :group 'rmail-spam-filter )
123 125
124 (defcustom rmail-spam-filter-auto-delete-spam-bbdb-entries nil 126 (defcustom rmail-spam-filter-auto-delete-spam-bbdb-entries nil
125 "*Non-nil to make sure no entries are made in bbdb for spam emails. 127 "*Non-nil to make sure no entries are made in bbdb for spam emails.
126 This is done in two ways: (1) bbdb is made not to auto-create entries 128 This is done in two ways: (1) bbdb is made not to auto-create entries
127 for messages that are deleted by the `rmail-spam-filter', (2) when a 129 for messages that are deleted by the `rmail-spam-filter', (2) when a
128 message is deleted in rmail, the user is offered to delete the 130 message is deleted in rmail, the user is offered to delete the
159 is defined as one that fits all of the specified elements of any one 161 is defined as one that fits all of the specified elements of any one
160 of the spam definitions. The strings that specify spam subject, 162 of the spam definitions. The strings that specify spam subject,
161 sender, etc, may be regexp. For example, to specify that the subject 163 sender, etc, may be regexp. For example, to specify that the subject
162 may be either 'this is spam' or 'another spam', use the regexp: 'this 164 may be either 'this is spam' or 'another spam', use the regexp: 'this
163 is spam\|another spam' (without the single quotes)." 165 is spam\|another spam' (without the single quotes)."
164 :type '(repeat 166 :type '(repeat
165 (list :format "%v" 167 (list :format "%v"
166 (cons :format "%v" :value (from . "") 168 (cons :format "%v" :value (from . "")
167 (const :format "" from) 169 (const :format "" from)
168 (string :tag "From" "")) 170 (string :tag "From" ""))
169 (cons :format "%v" :value (to . "") 171 (cons :format "%v" :value (to . "")
175 (cons :format "%v" :value (contents . "") 177 (cons :format "%v" :value (contents . "")
176 (const :format "" contents) 178 (const :format "" contents)
177 (string :tag "Contents" "")) 179 (string :tag "Contents" ""))
178 (cons :format "%v" :value (action . output-and-delete) 180 (cons :format "%v" :value (action . output-and-delete)
179 (const :format "" action) 181 (const :format "" action)
180 (choice :tag "Action selection" 182 (choice :tag "Action selection"
181 (const :tag "output to spam folder and delete" output-and-delete) 183 (const :tag "output to spam folder and delete" output-and-delete)
182 (const :tag "delete spam" delete-spam) 184 (const :tag "delete spam" delete-spam)
183 )) 185 ))
184 )) 186 ))
185 :group 'rmail-spam-filter) 187 :group 'rmail-spam-filter)
206 (exit-while-loop nil) 208 (exit-while-loop nil)
207 (saved-case-fold-search case-fold-search) 209 (saved-case-fold-search case-fold-search)
208 (save-current-msg) 210 (save-current-msg)
209 (rmail-spam-filter-saved-bbdb/mail_auto_create_p nil) 211 (rmail-spam-filter-saved-bbdb/mail_auto_create_p nil)
210 ) 212 )
211 213
212 ;; make sure bbdb does not create entries for messages while spam 214 ;; make sure bbdb does not create entries for messages while spam
213 ;; filter is scanning the rmail file: 215 ;; filter is scanning the rmail file:
214 (setq rmail-spam-filter-saved-bbdb/mail_auto_create_p 'bbdb/mail_auto_create_p) 216 (setq rmail-spam-filter-saved-bbdb/mail_auto_create_p 'bbdb/mail_auto_create_p)
215 (setq bbdb/mail_auto_create_p nil) 217 (setq bbdb/mail_auto_create_p nil)
216 ;; let `rmail-bbdb-auto-delete-spam-entries' know that rmail spam 218 ;; let `rmail-bbdb-auto-delete-spam-entries' know that rmail spam
234 (setq num-spam-definition-elements (safe-length 236 (setq num-spam-definition-elements (safe-length
235 rmail-spam-definitions-alist)) 237 rmail-spam-definitions-alist))
236 238
237 ;;; do we want to ignore case in spam definitions: 239 ;;; do we want to ignore case in spam definitions:
238 (setq case-fold-search rmail-spam-filter-ignore-case) 240 (setq case-fold-search rmail-spam-filter-ignore-case)
239 241
240 ;; Check for blind CC condition. Set vars such that while 242 ;; Check for blind CC condition. Set vars such that while
241 ;; loop will be bypassed and spam condition will trigger (EDB) 243 ;; loop will be bypassed and spam condition will trigger (EDB)
242 (if (and rmail-spam-no-blind-cc 244 (if (and rmail-spam-no-blind-cc
243 (null message-recipients)) 245 (null message-recipients))
244 (progn 246 (progn
245 (setq exit-while-loop t) 247 (setq exit-while-loop t)
246 (setq maybe-spam t) 248 (setq maybe-spam t)
247 (setq this-is-a-spam-email t))) 249 (setq this-is-a-spam-email t)))
248 250
249 ;; Check white list, and likewise cause while loop 251 ;; Check white list, and likewise cause while loop
250 ;; bypass. (EDB) 252 ;; bypass. (EDB)
251 (if (find-if '(lambda (white-str) 253 (if (find-if '(lambda (white-str)
252 (string-match white-str message-sender)) 254 (string-match white-str message-sender))
253 rmail-spam-white-list) 255 rmail-spam-white-list)
254 (progn 256 (progn
255 (setq exit-while-loop t) 257 (setq exit-while-loop t)
256 (setq maybe-spam nil) 258 (setq maybe-spam nil)
257 (setq this-is-a-spam-email nil))) 259 (setq this-is-a-spam-email nil)))
258 260
259 ;; scan all elements of the list rmail-spam-definitions-alist 261 ;; scan all elements of the list rmail-spam-definitions-alist
260 (while (and 262 (while (and
261 (< num-element num-spam-definition-elements) 263 (< num-element num-spam-definition-elements)
262 (not exit-while-loop)) 264 (not exit-while-loop))
263 (progn 265 (progn
275 ;; field in the scanned message. 277 ;; field in the scanned message.
276 (setq this-is-a-spam-email nil) 278 (setq this-is-a-spam-email nil)
277 279
278 ;; start scanning incoming message: 280 ;; start scanning incoming message:
279 ;;--------------------------------- 281 ;;---------------------------------
280 282
281 ;; if sender field is not specified in message being 283 ;; if sender field is not specified in message being
282 ;; scanned, AND if "from" field does not appear in spam 284 ;; scanned, AND if "from" field does not appear in spam
283 ;; definitions for this element, this may still be spam 285 ;; definitions for this element, this may still be spam
284 ;; due to another element... 286 ;; due to another element...
285 (if (and (not message-sender) 287 (if (and (not message-sender)
583 (define-key rmail-mode-map "\C-cSt" 'rmail-spam-filter-add-subject-to-spam-list) 585 (define-key rmail-mode-map "\C-cSt" 'rmail-spam-filter-add-subject-to-spam-list)
584 586
585 587
586 (defun rmail-bbdb-auto-delete-spam-entries () 588 (defun rmail-bbdb-auto-delete-spam-entries ()
587 "When deleting a message in RMAIL, check to see if the bbdb entry 589 "When deleting a message in RMAIL, check to see if the bbdb entry
588 was created today, and if it was, prompt to delete it too. This function 590 was created today, and if it was, prompt to delete it too. This function
589 needs to be called via the `rmail-delete-message-hook' like this: 591 needs to be called via the `rmail-delete-message-hook' like this:
590 \(add-hook 'rmail-delete-message-hook 'rmail-bbdb-auto-delete-spam-entries)" 592 \(add-hook 'rmail-delete-message-hook 'rmail-bbdb-auto-delete-spam-entries)"
591 (interactive) 593 (interactive)
592 (require 'bbdb-hooks) 594 (require 'bbdb-hooks)
593 (if (not rmail-spam-filter-scanning-messages-now) 595 (if (not rmail-spam-filter-scanning-messages-now)
602 604
603 (defun rmail-spam-filter-bbdb-dont-create-entries-for-spam () 605 (defun rmail-spam-filter-bbdb-dont-create-entries-for-spam ()
604 "Make sure senderes of rmail messages marked as deleted are not added to bbdb. 606 "Make sure senderes of rmail messages marked as deleted are not added to bbdb.
605 Need to add this as a hook like this: 607 Need to add this as a hook like this:
606 \(setq bbdb/mail-auto-create-p 'rmail-spam-filter-bbdb-dont-create-entries-for-spam) 608 \(setq bbdb/mail-auto-create-p 'rmail-spam-filter-bbdb-dont-create-entries-for-spam)
607 and this is also used in conjunction with rmail-bbdb-auto-delete-spam-entries. 609 and this is also used in conjunction with rmail-bbdb-auto-delete-spam-entries.
608 More doc: rmail-bbdb-auto-delete-spam-entries will delete newly created bbdb 610 More doc: rmail-bbdb-auto-delete-spam-entries will delete newly created bbdb
609 entries of mail that is deleted. However, if one scrolls back to the deleted 611 entries of mail that is deleted. However, if one scrolls back to the deleted
610 messages, then the sender is again added to the bbdb. This function 612 messages, then the sender is again added to the bbdb. This function
611 prevents this. Also, don't create entries for messages in the `rmail-spam-file'." 613 prevents this. Also, don't create entries for messages in the `rmail-spam-file'."
612 (interactive) 614 (interactive)
613 (not 615 (not
614 ;; don't create a bbdb entry if one of the following conditions is satisfied: 616 ;; don't create a bbdb entry if one of the following conditions is satisfied:
615 (or 617 (or
616 ;; 1) looking at a deleted message: 618 ;; 1) looking at a deleted message:
617 (rmail-message-deleted-p rmail-current-message) 619 (rmail-message-deleted-p rmail-current-message)
618 ;; 2) looking at messages in rmail-spam-file: 620 ;; 2) looking at messages in rmail-spam-file:
619 (string-match 621 (string-match
629 )) 631 ))
630 632
631 (provide 'rmail-spam-filter) 633 (provide 'rmail-spam-filter)
632 634
633 ;;; arch-tag: 03e1d45d-b72f-4dd7-8f04-e7fd78249746 635 ;;; arch-tag: 03e1d45d-b72f-4dd7-8f04-e7fd78249746
634 ;;; rmail-spam-filter ends here 636 ;;; rmail-spam-filter.el ends here