diff options
| author | Richard M. Stallman | 2004-01-27 19:01:24 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 2004-01-27 19:01:24 +0000 |
| commit | f5ea26f8ec93457d25c7ebf4cb7b1d2baf00d7f5 (patch) | |
| tree | 9c1a71a37d96a7c9dbcbe3198dd5a86aeb465037 | |
| parent | 6e74cce2f95ed5304b25a7c1842f4ad58b939768 (diff) | |
| download | emacs-f5ea26f8ec93457d25c7ebf4cb7b1d2baf00d7f5.tar.gz emacs-f5ea26f8ec93457d25c7ebf4cb7b1d2baf00d7f5.zip | |
Change rmail-spam-filter- or spam-filter-
or rmail-spam- to rsf- in all function and variable names.
(rsf-min-region-to-spam-list): New variable.
(rsf-bbdb-auto-delete-spam-entries): Renamed from
rmail-bbdb-auto-delete-spam-bbdb-entries. The cc: field is
scanned together with the recipients field for spam testing; Don't
delete spam message if rmail-delete-after-output is non-nil;
(check-field) New function, extracted from code in
rmail-spam-filter to ease addition of header fields like content-type:.
(message-content-type) New variable. The content-type: field was
added also in defcustom of rsf-definitions-alist;
(rmail-spam-filter): Replace repeated test code for header fields
by calls to check-field; change the call to
rmail-output-to-rmail-file such that rmail-current-message stays
the same to avoid wrong deletion of unseen flags.
(rmail-use-spam-filter): Add autoload cookie.
| -rw-r--r-- | lisp/ChangeLog | 34 | ||||
| -rw-r--r-- | lisp/mail/rmail-spam-filter.el | 617 |
2 files changed, 342 insertions, 309 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 788231e9210..d4aecda9e1a 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,37 @@ | |||
| 1 | 2004-01-27 Eli Tziperman <eli@deas.harvard.edu> | ||
| 2 | |||
| 3 | * rmail-spam-filter.el: Change rmail-spam-filter- or spam-filter- | ||
| 4 | or rmail-spam- to rsf- in all function and variable names. | ||
| 5 | (rsf-min-region-to-spam-list): New variable. | ||
| 6 | (rsf-bbdb-auto-delete-spam-entries): Renamed from | ||
| 7 | rmail-bbdb-auto-delete-spam-bbdb-entries. The cc: field is | ||
| 8 | scanned together with the recipients field for spam testing; Don't | ||
| 9 | delete spam message if rmail-delete-after-output is non-nil; | ||
| 10 | (check-field) New function, extracted from code in | ||
| 11 | rmail-spam-filter to ease addition of header fields like | ||
| 12 | content-type:; | ||
| 13 | (message-content-type) New variable. The content-type: field was | ||
| 14 | added also in defcustom of rsf-definitions-alist; | ||
| 15 | (rmail-spam-filter): Replace repeated test code for header fields | ||
| 16 | by calls to check-field; change the call to | ||
| 17 | rmail-output-to-rmail-file such that rmail-current-message stays | ||
| 18 | the same to avoid wrong deletion of unseen flags. | ||
| 19 | (rmail-use-spam-filter): Add autoload cookie. | ||
| 20 | |||
| 21 | 2004-01-27 Sat Jari Aalto <jari.aalto@poboxes.com> | ||
| 22 | |||
| 23 | * filecache.el | ||
| 24 | (file-cache-find-posix-p): New function. Detect Cygwin. | ||
| 25 | (file-cache-add-directory-using-find): Added Cygwin support. | ||
| 26 | (file-cache-find-command-posix-flag): New user variable. | ||
| 27 | |||
| 28 | * filecache.el (file-cache-add-directory): Check for | ||
| 29 | directories an remove them from dir-files. | ||
| 30 | |||
| 31 | 2004-01-27 Richard M. Stallman <rms@gnu.org> | ||
| 32 | |||
| 33 | * man.el (Man-fontify-manpage): Clean up message. | ||
| 34 | |||
| 1 | 2004-01-27 Kenichi Handa <handa@m17n.org> | 35 | 2004-01-27 Kenichi Handa <handa@m17n.org> |
| 2 | 36 | ||
| 3 | * textmodes/paragraphs.el (sentence-end-without-space): New variable. | 37 | * textmodes/paragraphs.el (sentence-end-without-space): New variable. |
diff --git a/lisp/mail/rmail-spam-filter.el b/lisp/mail/rmail-spam-filter.el index d5a45fe5d87..b811e5991e7 100644 --- a/lisp/mail/rmail-spam-filter.el +++ b/lisp/mail/rmail-spam-filter.el | |||
| @@ -1,9 +1,9 @@ | |||
| 1 | ;;; rmail-spam-filter.el --- spam filter for RMAIL | 1 | ;;; rmail-spam-filter.el --- spam filter for rmail, the emacs mail reader. |
| 2 | |||
| 3 | ;; Copyright (C) 2002 Free Software Foundation, Inc. | ||
| 2 | 4 | ||
| 3 | ;; Copyright (C) 2002 | ||
| 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 AT deas.harvard.edu> |
| 7 | 7 | ||
| 8 | ;; This file is part of GNU Emacs. | 8 | ;; This file is part of GNU Emacs. |
| 9 | 9 | ||
| @@ -23,62 +23,69 @@ | |||
| 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://deas.harvard.edu/climate/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 rsf-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 | ;;; `rsf-autosave-newly-added-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 rsf-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 rsf-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 | ;;; rsf-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 is best used with a general purpose spam |
| 70 | ;; from entering into the .bbdb file. See variable | 71 | ;;; filter such as the procmail-based http://www.spambouncer.org/. |
| 71 | ;; "rmail-spam-filter-auto-delete-spam-bbdb-entries". This is done | 72 | ;;; Spambouncer is set to only mark messages as spam/blocked/bulk/OK |
| 72 | ;; in two ways: (a) bbdb is made not to auto-create entries for | 73 | ;;; via special headers, and these headers may then be defined in |
| 73 | ;; messages that are deleted by the rmail-spam-filter, (b) when a | 74 | ;;; rmail-spam-filter such that the spam is rejected by |
| 74 | ;; message is deleted in rmail, the user is offered to delete the | 75 | ;;; rmail-spam-filter itself. |
| 75 | ;; sender's bbdb entry as well _if_ it was created at the same day. | ||
| 76 | 76 | ||
| 77 | ;;; Code: | 77 | ;;; (*) rmail spam filter also works with bbdb to prevent spam senders |
| 78 | ;;; from entering into the .bbdb file. See variable | ||
| 79 | ;;; "rsf-auto-delete-spam-bbdb-entries". This is done | ||
| 80 | ;;; in two ways: (a) bbdb is made not to auto-create entries for | ||
| 81 | ;;; messages that are deleted by the rmail-spam-filter, (b) when a | ||
| 82 | ;;; message is deleted in rmail, the user is offered to delete the | ||
| 83 | ;;; sender's bbdb entry as well _if_ it was created at the same day. | ||
| 78 | 84 | ||
| 79 | (require 'rmail) | 85 | (require 'rmail) |
| 86 | (require 'rmailsum) | ||
| 80 | 87 | ||
| 81 | ;; For find-if and other cool common lisp functions we may want to use. (EDB) | 88 | ;; For find-if and other cool common lisp functions we may want to use. |
| 82 | (eval-when-compile | 89 | (eval-when-compile |
| 83 | (require 'cl)) | 90 | (require 'cl)) |
| 84 | 91 | ||
| @@ -89,41 +96,51 @@ | |||
| 89 | ;;;###autoload | 96 | ;;;###autoload |
| 90 | (defcustom rmail-use-spam-filter nil | 97 | (defcustom rmail-use-spam-filter nil |
| 91 | "*Non-nil to activate the rmail spam filter. | 98 | "*Non-nil to activate the rmail spam filter. |
| 92 | Specify `rmail-spam-definitions-alist' to define what you consider spam | 99 | Specify `rsf-definitions-alist' to define what you consider spam |
| 93 | emails." | 100 | emails." |
| 94 | :type 'boolean | 101 | :type 'boolean |
| 95 | :group 'rmail-spam-filter ) | 102 | :group 'rmail-spam-filter ) |
| 96 | 103 | ||
| 97 | (defcustom rmail-spam-file "~/XRMAIL-SPAM" | 104 | (defcustom rsf-file "~/XRMAIL-SPAM" |
| 98 | "*Name of rmail file for optionally saving some of the spam. | 105 | "*Name of rmail file for optionally saving some of the spam. |
| 99 | Spam may be either just deleted, or saved in a separate spam file to | 106 | Spam may be either just deleted, or saved in a separate spam file to |
| 100 | be looked at at a later time. Whether the spam is just deleted or | 107 | be looked at at a later time. Whether the spam is just deleted or |
| 101 | also saved in a separete spam file is specified for each definition of | 108 | also saved in a separete spam file is specified for each definition of |
| 102 | spam, as one of the fields of `rmail-spam-definitions-alist'" | 109 | spam, as one of the fields of `rsf-definitions-alist'" |
| 103 | :type 'string | 110 | :type 'string |
| 104 | :group 'rmail-spam-filter ) | 111 | :group 'rmail-spam-filter ) |
| 105 | 112 | ||
| 106 | (defcustom rmail-spam-no-blind-cc nil | 113 | (defcustom rsf-no-blind-cc nil |
| 107 | "*Non-nil to treat blind CC (no To: header) as spam." | 114 | "*Non-nil to treat blind CC (no To: header) as spam." |
| 108 | :type 'boolean | 115 | :type 'boolean |
| 109 | :group 'rmail-spam-filter ) | 116 | :group 'rmail-spam-filter ) |
| 110 | 117 | ||
| 111 | (defcustom rmail-spam-filter-ignore-case nil | 118 | (defcustom rsf-ignore-case nil |
| 112 | "*Non-nil to ignore case in `rmail-spam-definitions-alist'." | 119 | "*Non-nil to ignore case in `rsf-definitions-alist'." |
| 113 | :type 'boolean | 120 | :type 'boolean |
| 114 | :group 'rmail-spam-filter ) | 121 | :group 'rmail-spam-filter ) |
| 115 | 122 | ||
| 116 | (defcustom rmail-spam-filter-beep nil | 123 | (defcustom rsf-beep nil |
| 117 | "*Non-nil to beep if spam is found." | 124 | "*Non-nil to beep if spam is found." |
| 118 | :type 'boolean | 125 | :type 'boolean |
| 119 | :group 'rmail-spam-filter ) | 126 | :group 'rmail-spam-filter ) |
| 120 | 127 | ||
| 121 | (defcustom rmail-spam-sleep-after-message 2.0 | 128 | (defcustom rsf-sleep-after-message 2.0 |
| 122 | "*Seconds to wait after display of message that spam was found." | 129 | "*Seconds to wait after display of message that spam was found." |
| 123 | :type 'number | 130 | :type 'number |
| 124 | :group 'rmail-spam-filter ) | 131 | :group 'rmail-spam-filter ) |
| 125 | 132 | ||
| 126 | (defcustom rmail-spam-filter-auto-delete-spam-bbdb-entries nil | 133 | (defcustom rsf-min-region-to-spam-list 7 |
| 134 | "*User may highlight a region in an incomming message and use | ||
| 135 | the menubar to add this region to the spam definitions. This | ||
| 136 | variable specifies the minimum size of region that may be added | ||
| 137 | to spam list, to avoid accidentally adding a too short region | ||
| 138 | which would result in false positive identification of spam | ||
| 139 | messages." | ||
| 140 | :type 'integer | ||
| 141 | :group 'rmail-spam-filter ) | ||
| 142 | |||
| 143 | (defcustom rsf-auto-delete-spam-bbdb-entries nil | ||
| 127 | "*Non-nil to make sure no entries are made in bbdb for spam emails. | 144 | "*Non-nil to make sure no entries are made in bbdb for spam emails. |
| 128 | This is done in two ways: (1) bbdb is made not to auto-create entries | 145 | This is done in two ways: (1) bbdb is made not to auto-create entries |
| 129 | for messages that are deleted by the `rmail-spam-filter', (2) when a | 146 | for messages that are deleted by the `rmail-spam-filter', (2) when a |
| @@ -134,7 +151,7 @@ take an effect." | |||
| 134 | :type 'boolean | 151 | :type 'boolean |
| 135 | :group 'rmail-spam-filter ) | 152 | :group 'rmail-spam-filter ) |
| 136 | 153 | ||
| 137 | (defcustom rmail-spam-filter-autosave-newly-added-spam-definitions nil | 154 | (defcustom rsf-autosave-newly-added-definitions nil |
| 138 | "*Non-nil to auto save new spam entries. | 155 | "*Non-nil to auto save new spam entries. |
| 139 | New entries entered via the spam menu bar item are then saved to | 156 | New entries entered via the spam menu bar item are then saved to |
| 140 | customization file immediately after being added via the menu bar, and | 157 | customization file immediately after being added via the menu bar, and |
| @@ -143,17 +160,17 @@ entries." | |||
| 143 | :type 'boolean | 160 | :type 'boolean |
| 144 | :group 'rmail-spam-filter ) | 161 | :group 'rmail-spam-filter ) |
| 145 | 162 | ||
| 146 | (defcustom rmail-spam-white-list nil | 163 | (defcustom rsf-white-list nil |
| 147 | "*List of strings to identify valid senders. | 164 | "*List of strings to identify valid senders. |
| 148 | If any rmail-spam-white-list string matches a substring of the 'From' | 165 | If any rsf-white-list string matches a substring of the 'From' |
| 149 | header, the message is flagged as a valid, non-spam message. Example: | 166 | header, the message is flagged as a valid, non-spam message. Example: |
| 150 | If your domain is emacs.com then including 'emacs.com' in your | 167 | If your domain is emacs.com then including 'emacs.com' in your |
| 151 | rmail-spam-white-list would flag all mail from your colleagues as | 168 | rsf-white-list would flag all mail from your colleagues as |
| 152 | valid." | 169 | valid." |
| 153 | :type '(repeat string) | 170 | :type '(repeat string) |
| 154 | :group 'rmail-spam-filter ) | 171 | :group 'rmail-spam-filter ) |
| 155 | 172 | ||
| 156 | (defcustom rmail-spam-definitions-alist nil | 173 | (defcustom rsf-definitions-alist nil |
| 157 | "*Alist matching strings defining what messages are considered spam. | 174 | "*Alist matching strings defining what messages are considered spam. |
| 158 | Each definition may contain specifications of one or more of the | 175 | Each definition may contain specifications of one or more of the |
| 159 | elements {subject, sender, recipients or contents}, as well as a | 176 | elements {subject, sender, recipients or contents}, as well as a |
| @@ -162,8 +179,10 @@ is defined as one that fits all of the specified elements of any one | |||
| 162 | of the spam definitions. The strings that specify spam subject, | 179 | of the spam definitions. The strings that specify spam subject, |
| 163 | sender, etc, may be regexp. For example, to specify that the subject | 180 | sender, etc, may be regexp. For example, to specify that the subject |
| 164 | may be either 'this is spam' or 'another spam', use the regexp: 'this | 181 | may be either 'this is spam' or 'another spam', use the regexp: 'this |
| 165 | is spam\|another spam' (without the single quotes)." | 182 | is spam\\|another spam' (without the single quotes). To specify that |
| 166 | :type '(repeat | 183 | if the contents contain both this and that the message is spam, |
| 184 | specify 'this\\&that' in the appropriate spam definition field." | ||
| 185 | :type '(repeat | ||
| 167 | (list :format "%v" | 186 | (list :format "%v" |
| 168 | (cons :format "%v" :value (from . "") | 187 | (cons :format "%v" :value (from . "") |
| 169 | (const :format "" from) | 188 | (const :format "" from) |
| @@ -174,25 +193,53 @@ is spam\|another spam' (without the single quotes)." | |||
| 174 | (cons :format "%v" :value (subject . "") | 193 | (cons :format "%v" :value (subject . "") |
| 175 | (const :format "" subject) | 194 | (const :format "" subject) |
| 176 | (string :tag "Subject" "")) | 195 | (string :tag "Subject" "")) |
| 196 | (cons :format "%v" :value (content-type . "") | ||
| 197 | (const :format "" content-type) | ||
| 198 | (string :tag "Content-Type" "")) | ||
| 177 | (cons :format "%v" :value (contents . "") | 199 | (cons :format "%v" :value (contents . "") |
| 178 | (const :format "" contents) | 200 | (const :format "" contents) |
| 179 | (string :tag "Contents" "")) | 201 | (string :tag "Contents" "")) |
| 180 | (cons :format "%v" :value (action . output-and-delete) | 202 | (cons :format "%v" :value (action . output-and-delete) |
| 181 | (const :format "" action) | 203 | (const :format "" action) |
| 182 | (choice :tag "Action selection" | 204 | (choice :tag "Action selection" |
| 183 | (const :tag "output to spam folder and delete" output-and-delete) | 205 | (const :tag "output to spam folder and delete" output-and-delete) |
| 184 | (const :tag "delete spam" delete-spam) | 206 | (const :tag "delete spam" delete-spam) |
| 185 | )) | 207 | )) |
| 186 | )) | 208 | )) |
| 187 | :group 'rmail-spam-filter) | 209 | :group 'rmail-spam-filter) |
| 188 | 210 | ||
| 189 | (defvar rmail-spam-filter-scanning-messages-now nil | 211 | (defvar rsf-scanning-messages-now nil |
| 190 | "Non nil when rmail-spam-filter scans messages, | 212 | "Non nil when rmail-spam-filter scans messages, |
| 191 | for interaction with `rmail-bbdb-auto-delete-spam-entries'") | 213 | for interaction with `rsf-bbdb-auto-delete-spam-entries'") |
| 214 | |||
| 215 | ;; the advantage over the automatic filter definitions is the AND conjunction | ||
| 216 | ;; of in-one-definition-elements | ||
| 217 | (defun rsf-check-field (field-symbol message-data definition result) | ||
| 218 | "Check if field-symbol is in `rsf-definitions-alist'. | ||
| 219 | Capture maybe-spam and this-is-a-spam-email in a cons in result, | ||
| 220 | where maybe-spam is in first and this-is-a-spam-email is in rest. | ||
| 221 | The values are returned by destructively changing result. | ||
| 222 | If FIELD-SYMBOL field does not exist AND is not specified, | ||
| 223 | this may still be spam due to another element... | ||
| 224 | if (first result) is nil, we already have a contradiction in another | ||
| 225 | field" | ||
| 226 | (let ((definition-field (cdr (assoc field-symbol definition)))) | ||
| 227 | (if (and (first result) (> (length definition-field) 0)) | ||
| 228 | ;; only in this case can maybe-spam change from t to nil | ||
| 229 | ;; ... else, if FIELD-SYMBOL field does appear in the message, | ||
| 230 | ;; and it also appears in spam definition list, this | ||
| 231 | ;; is potentially a spam: | ||
| 232 | (if (and message-data | ||
| 233 | (string-match definition-field message-data)) | ||
| 234 | ;; if we do not get a contradiction from another field, this is | ||
| 235 | ;; spam | ||
| 236 | (setf (rest result) t) | ||
| 237 | ;; the message data contradicts the specification, this is no spam | ||
| 238 | (setf (first result) nil))))) | ||
| 192 | 239 | ||
| 193 | (defun rmail-spam-filter (msg) | 240 | (defun rmail-spam-filter (msg) |
| 194 | "Return nil if msg is spam based on rmail-spam-definitions-alist. | 241 | "Return nil if msg is spam based on rsf-definitions-alist. |
| 195 | If spam, optionally output msg to a file `rmail-spam-file' and delete | 242 | If spam, optionally output msg to a file `rsf-file' and delete |
| 196 | it from rmail file. Called for each new message retrieved by | 243 | it from rmail file. Called for each new message retrieved by |
| 197 | `rmail-get-new-mail'." | 244 | `rmail-get-new-mail'." |
| 198 | 245 | ||
| @@ -203,22 +250,23 @@ it from rmail file. Called for each new message retrieved by | |||
| 203 | (message-sender) | 250 | (message-sender) |
| 204 | (message-recipients) | 251 | (message-recipients) |
| 205 | (message-subject) | 252 | (message-subject) |
| 253 | (message-content-type) | ||
| 206 | (num-spam-definition-elements) | 254 | (num-spam-definition-elements) |
| 207 | (num-element 0) | 255 | (num-element 0) |
| 208 | (exit-while-loop nil) | 256 | (exit-while-loop nil) |
| 209 | (saved-case-fold-search case-fold-search) | 257 | (saved-case-fold-search case-fold-search) |
| 210 | (save-current-msg) | 258 | (save-current-msg) |
| 211 | (rmail-spam-filter-saved-bbdb/mail_auto_create_p nil) | 259 | (rsf-saved-bbdb/mail_auto_create_p nil) |
| 212 | ) | 260 | ) |
| 213 | 261 | ||
| 214 | ;; make sure bbdb does not create entries for messages while spam | 262 | ;; make sure bbdb does not create entries for messages while spam |
| 215 | ;; filter is scanning the rmail file: | 263 | ;; filter is scanning the rmail file: |
| 216 | (setq rmail-spam-filter-saved-bbdb/mail_auto_create_p 'bbdb/mail_auto_create_p) | 264 | (setq rsf-saved-bbdb/mail_auto_create_p 'bbdb/mail_auto_create_p) |
| 217 | (setq bbdb/mail_auto_create_p nil) | 265 | (setq bbdb/mail_auto_create_p nil) |
| 218 | ;; let `rmail-bbdb-auto-delete-spam-entries' know that rmail spam | 266 | ;; let `rsf-bbdb-auto-delete-spam-entries' know that rmail spam |
| 219 | ;; filter is running, so that deletion of rmail messages should be | 267 | ;; filter is running, so that deletion of rmail messages should be |
| 220 | ;; ignored for now: | 268 | ;; ignored for now: |
| 221 | (setq rmail-spam-filter-scanning-messages-now t) | 269 | (setq rsf-scanning-messages-now t) |
| 222 | (save-excursion | 270 | (save-excursion |
| 223 | (save-restriction | 271 | (save-restriction |
| 224 | (setq this-is-a-spam-email nil) | 272 | (setq this-is-a-spam-email nil) |
| @@ -228,166 +276,111 @@ it from rmail file. Called for each new message retrieved by | |||
| 228 | (goto-char (rmail-msgbeg msg)) | 276 | (goto-char (rmail-msgbeg msg)) |
| 229 | (narrow-to-region (point) (progn (search-forward "\n\n") (point))) | 277 | (narrow-to-region (point) (progn (search-forward "\n\n") (point))) |
| 230 | (setq message-sender (mail-fetch-field "From")) | 278 | (setq message-sender (mail-fetch-field "From")) |
| 231 | (setq message-recipients (mail-fetch-field "To")) | 279 | (setq message-recipients |
| 280 | (concat (mail-fetch-field "To") | ||
| 281 | (if (mail-fetch-field "Cc") | ||
| 282 | (concat ", " (mail-fetch-field "Cc"))))) | ||
| 232 | (setq message-subject (mail-fetch-field "Subject")) | 283 | (setq message-subject (mail-fetch-field "Subject")) |
| 284 | (setq message-content-type (mail-fetch-field "Content-Type")) | ||
| 233 | ) | 285 | ) |
| 234 | ;; Find number of spam-definition elements in the list | 286 | ;; Find number of spam-definition elements in the list |
| 235 | ;; rmail-spam-definitions-alist specified by user: | 287 | ;; rsf-definitions-alist specified by user: |
| 236 | (setq num-spam-definition-elements (safe-length | 288 | (setq num-spam-definition-elements (safe-length |
| 237 | rmail-spam-definitions-alist)) | 289 | rsf-definitions-alist)) |
| 238 | 290 | ||
| 239 | ;;; do we want to ignore case in spam definitions: | 291 | ;;; do we want to ignore case in spam definitions: |
| 240 | (setq case-fold-search rmail-spam-filter-ignore-case) | 292 | (setq case-fold-search rsf-ignore-case) |
| 241 | 293 | ||
| 242 | ;; Check for blind CC condition. Set vars such that while | 294 | ;; Check for blind CC condition. Set vars such that while |
| 243 | ;; loop will be bypassed and spam condition will trigger (EDB) | 295 | ;; loop will be bypassed and spam condition will trigger |
| 244 | (if (and rmail-spam-no-blind-cc | 296 | (if (and rsf-no-blind-cc |
| 245 | (null message-recipients)) | 297 | (null message-recipients)) |
| 246 | (progn | 298 | (setq exit-while-loop t |
| 247 | (setq exit-while-loop t) | 299 | maybe-spam t |
| 248 | (setq maybe-spam t) | 300 | this-is-a-spam-email t)) |
| 249 | (setq this-is-a-spam-email t))) | 301 | |
| 250 | 302 | ;; Check white list, and likewise cause while loop | |
| 251 | ;; Check white list, and likewise cause while loop | 303 | ;; bypass. |
| 252 | ;; bypass. (EDB) | 304 | (if (let ((white-list rsf-white-list) |
| 253 | (if (find-if '(lambda (white-str) | 305 | (found nil)) |
| 254 | (string-match white-str message-sender)) | 306 | (while (and (not found) white-list) |
| 255 | rmail-spam-white-list) | 307 | (if (string-match (car white-list) message-sender) |
| 256 | (progn | 308 | (setq found t) |
| 257 | (setq exit-while-loop t) | 309 | (setq white-list (cdr white-list)))) |
| 258 | (setq maybe-spam nil) | 310 | found) |
| 259 | (setq this-is-a-spam-email nil))) | 311 | (setq exit-while-loop t |
| 260 | 312 | maybe-spam nil | |
| 261 | ;; scan all elements of the list rmail-spam-definitions-alist | 313 | this-is-a-spam-email nil)) |
| 314 | |||
| 315 | ;; maybe-spam is in first, this-is-a-spam-email in rest, this | ||
| 316 | ;; simplifies the call to rsf-check-field | ||
| 317 | (setq maybe-spam (cons maybe-spam this-is-a-spam-email)) | ||
| 318 | |||
| 319 | ;; scan all elements of the list rsf-definitions-alist | ||
| 262 | (while (and | 320 | (while (and |
| 263 | (< num-element num-spam-definition-elements) | 321 | (< num-element num-spam-definition-elements) |
| 264 | (not exit-while-loop)) | 322 | (not exit-while-loop)) |
| 265 | (progn | 323 | (let ((definition (nth num-element rsf-definitions-alist))) |
| 266 | ;; Initialize maybe-spam which is set to t in one of two | 324 | ;; Initialize maybe-spam which is set to t in one of two |
| 267 | ;; cases: (1) unspecified definition-elements are found in | 325 | ;; cases: (1) unspecified definition-elements are found in |
| 268 | ;; rmail-spam-definitions-alist, (2) empty field is found | 326 | ;; rsf-definitions-alist, (2) empty field is found |
| 269 | ;; in the message being scanned (e.g. empty subject, | 327 | ;; in the message being scanned (e.g. empty subject, |
| 270 | ;; sender, recipients, etc). The variable is set to nil | 328 | ;; sender, recipients, etc). The variable is set to nil |
| 271 | ;; if a non empty field of the scanned message does not | 329 | ;; if a non empty field of the scanned message does not |
| 272 | ;; match a specified field in | 330 | ;; match a specified field in |
| 273 | ;; rmail-spam-definitions-alist. | 331 | ;; rsf-definitions-alist. |
| 274 | (setq maybe-spam t) | 332 | |
| 275 | ;; initialize this-is-a-spam-email to nil. This variable | 333 | ;; initialize this-is-a-spam-email to nil. This variable |
| 276 | ;; is set to t if one of the spam definitions matches a | 334 | ;; is set to t if one of the spam definitions matches a |
| 277 | ;; field in the scanned message. | 335 | ;; field in the scanned message. |
| 278 | (setq this-is-a-spam-email nil) | 336 | (setq maybe-spam (cons t nil)) |
| 279 | 337 | ||
| 280 | ;; start scanning incoming message: | 338 | ;; start scanning incoming message: |
| 281 | ;;--------------------------------- | 339 | ;;--------------------------------- |
| 282 | 340 | ||
| 283 | ;; if sender field is not specified in message being | 341 | ;; Maybe the different fields should also be done in a |
| 342 | ;; loop to make the whole thing more flexible | ||
| 343 | ;; if sender field is not specified in message being | ||
| 284 | ;; scanned, AND if "from" field does not appear in spam | 344 | ;; scanned, AND if "from" field does not appear in spam |
| 285 | ;; definitions for this element, this may still be spam | 345 | ;; definitions for this element, this may still be spam |
| 286 | ;; due to another element... | 346 | ;; due to another element... |
| 287 | (if (and (not message-sender) | 347 | (rsf-check-field 'from message-sender definition maybe-spam) |
| 288 | (string-match | 348 | ;; next, if spam was not ruled out already, check recipients: |
| 289 | (cdr (assoc 'from (nth num-element | 349 | (rsf-check-field 'to message-recipients definition maybe-spam) |
| 290 | rmail-spam-definitions-alist))) "")) | 350 | ;; next, if spam was not ruled out already, check subject: |
| 291 | (setq maybe-spam t) | 351 | (rsf-check-field 'subject message-subject definition maybe-spam) |
| 292 | ;; ... else, if message-sender does appear in the | 352 | ;; next, if spam was not ruled out already, check content-type: |
| 293 | ;; message, and it also appears in the spam definition | 353 | (rsf-check-field 'content-type message-content-type |
| 294 | ;; list, it is potentially spam: | 354 | definition maybe-spam) |
| 295 | (if (and message-sender | ||
| 296 | (string-match | ||
| 297 | (cdr (assoc 'from (nth num-element | ||
| 298 | rmail-spam-definitions-alist))) | ||
| 299 | message-sender) | ||
| 300 | ) | ||
| 301 | (setq this-is-a-spam-email t) | ||
| 302 | (setq maybe-spam nil) | ||
| 303 | ) | ||
| 304 | ) | ||
| 305 | ;; next, if spam was not ruled out already, check recipients: | ||
| 306 | (if maybe-spam | ||
| 307 | ;; if To field does not exist AND is not specified, | ||
| 308 | ;; this may still be spam due to another element... | ||
| 309 | (if (and (not message-recipients) | ||
| 310 | (string-match | ||
| 311 | (cdr (assoc 'to | ||
| 312 | (nth num-element | ||
| 313 | rmail-spam-definitions-alist))) "")) | ||
| 314 | (setq maybe-spam t) | ||
| 315 | ;; ... else, if To field does appear in the message, | ||
| 316 | ;; and it also appears in spam definition list, this | ||
| 317 | ;; is potentially a spam: | ||
| 318 | (if (and message-recipients | ||
| 319 | (string-match | ||
| 320 | (cdr (assoc 'to (nth num-element | ||
| 321 | rmail-spam-definitions-alist))) | ||
| 322 | message-recipients) | ||
| 323 | ) | ||
| 324 | (setq this-is-a-spam-email t) | ||
| 325 | (setq maybe-spam nil) | ||
| 326 | ) | ||
| 327 | ) | ||
| 328 | ) | ||
| 329 | ;; next, if spam was not ruled out already, check subject: | ||
| 330 | (if maybe-spam | ||
| 331 | ;; if subject field does not exist AND is not | ||
| 332 | ;; specified, this may still be spam due to another | ||
| 333 | ;; element... | ||
| 334 | (if (and (not message-subject) | ||
| 335 | (string-match | ||
| 336 | (cdr (assoc 'subject | ||
| 337 | (nth num-element | ||
| 338 | rmail-spam-definitions-alist))) | ||
| 339 | "")) | ||
| 340 | (setq maybe-spam t) | ||
| 341 | ;; ... else, if subject field does appear in the | ||
| 342 | ;; message, and it also appears in the spam | ||
| 343 | ;; definition list, this is potentially a spam: | ||
| 344 | (if (and message-subject | ||
| 345 | (string-match | ||
| 346 | (cdr (assoc 'subject (nth num-element | ||
| 347 | rmail-spam-definitions-alist))) | ||
| 348 | message-subject) | ||
| 349 | ) | ||
| 350 | (setq this-is-a-spam-email t) | ||
| 351 | (setq maybe-spam nil) | ||
| 352 | ) | ||
| 353 | ) | ||
| 354 | ) | ||
| 355 | ;; next, if spam was not ruled out already, check | 355 | ;; next, if spam was not ruled out already, check |
| 356 | ;; contents: if contents field is not specified, this may | 356 | ;; contents: if contents field is not specified, this may |
| 357 | ;; still be spam due to another element... | 357 | ;; still be spam due to another element... |
| 358 | (if maybe-spam | 358 | (rsf-check-field 'contents |
| 359 | (if (string-match | 359 | (buffer-substring |
| 360 | (cdr (assoc 'contents | 360 | (rmail-msgbeg msg) (rmail-msgend msg)) |
| 361 | (nth num-element | 361 | definition maybe-spam) |
| 362 | rmail-spam-definitions-alist))) "") | 362 | |
| 363 | (setq maybe-spam t) | 363 | ;; if the search in rsf-definitions-alist found |
| 364 | ;; ... else, check to see if it appears in spam | ||
| 365 | ;; definition: | ||
| 366 | (if (string-match | ||
| 367 | (cdr (assoc 'contents | ||
| 368 | (nth num-element | ||
| 369 | rmail-spam-definitions-alist))) | ||
| 370 | (buffer-substring | ||
| 371 | (rmail-msgbeg msg) (rmail-msgend msg))) | ||
| 372 | (setq this-is-a-spam-email t) | ||
| 373 | (setq maybe-spam nil))) | ||
| 374 | ) | ||
| 375 | ;; if the search in rmail-spam-definitions-alist found | ||
| 376 | ;; that this email is spam, output the email to the spam | 364 | ;; that this email is spam, output the email to the spam |
| 377 | ;; rmail file, mark the email for deletion, leave the | 365 | ;; rmail file, mark the email for deletion, leave the |
| 378 | ;; while loop and return nil so that an rmail summary line | 366 | ;; while loop and return nil so that an rmail summary line |
| 379 | ;; wont be displayed for this message: | 367 | ;; wont be displayed for this message: |
| 380 | (if (and this-is-a-spam-email maybe-spam) | 368 | (if (and (first maybe-spam) (rest maybe-spam)) |
| 381 | ;; found that this is spam, no need to look at the | 369 | ;; found that this is spam, no need to look at the |
| 382 | ;; rest of the rmail-spam-definitions-alist, exit | 370 | ;; rest of the rsf-definitions-alist, exit |
| 383 | ;; loop: | 371 | ;; loop: |
| 384 | (setq exit-while-loop t) | 372 | (setq exit-while-loop t) |
| 385 | ;; else, spam was not yet found, increment number of | 373 | ;; else, spam was not yet found, increment number of |
| 386 | ;; element in rmail-spam-definitions-alist and proceed | 374 | ;; element in rsf-definitions-alist and proceed |
| 387 | ;; to next element: | 375 | ;; to next element: |
| 388 | (setq num-element (+ num-element 1))) | 376 | (setq num-element (+ num-element 1))) |
| 389 | ) | 377 | ) |
| 390 | ) | 378 | ) |
| 379 | |||
| 380 | ;; (BK) re-set originally used variables | ||
| 381 | (setq this-is-a-spam-email (rest maybe-spam) | ||
| 382 | maybe-spam (first maybe-spam)) | ||
| 383 | |||
| 391 | (if (and this-is-a-spam-email maybe-spam) | 384 | (if (and this-is-a-spam-email maybe-spam) |
| 392 | (progn | 385 | (progn |
| 393 | ;;(message "Found spam!") | 386 | ;;(message "Found spam!") |
| @@ -397,39 +390,42 @@ it from rmail file. Called for each new message retrieved by | |||
| 397 | ;; output and delete the spam msg if needed: | 390 | ;; output and delete the spam msg if needed: |
| 398 | (setq save-current-msg rmail-current-message) | 391 | (setq save-current-msg rmail-current-message) |
| 399 | (setq rmail-current-message msg) | 392 | (setq rmail-current-message msg) |
| 400 | ;; check action item and rmail-spam-definitions-alist | 393 | ;; check action item and rsf-definitions-alist |
| 401 | ;; and do it: | 394 | ;; and do it: |
| 402 | (cond | 395 | (cond |
| 403 | ((equal (cdr (assoc 'action | 396 | ((equal (cdr (assoc 'action |
| 404 | (nth num-element rmail-spam-definitions-alist))) | 397 | (nth num-element rsf-definitions-alist))) |
| 405 | 'output-and-delete) | 398 | 'output-and-delete) |
| 406 | (progn | 399 | (progn |
| 407 | (rmail-output-to-rmail-file rmail-spam-file) | 400 | (rmail-output-to-rmail-file rsf-file 1 t) |
| 408 | (rmail-delete-message) | 401 | ;; Don't delete if automatic deletion after output |
| 402 | ;; is turned on | ||
| 403 | (unless rmail-delete-after-output (rmail-delete-message)) | ||
| 409 | )) | 404 | )) |
| 410 | ((equal (cdr (assoc 'action | 405 | ((equal (cdr (assoc 'action |
| 411 | (nth num-element rmail-spam-definitions-alist))) | 406 | (nth num-element rsf-definitions-alist))) |
| 412 | 'delete-spam) | 407 | 'delete-spam) |
| 413 | (progn | 408 | (progn |
| 414 | (rmail-delete-message) | 409 | (rmail-delete-message) |
| 415 | )) | 410 | )) |
| 416 | ) | 411 | ) |
| 417 | (setq rmail-current-message save-current-msg) | 412 | (setq rmail-current-message save-current-msg) |
| 418 | (setq bbdb/mail_auto_create_p 'rmail-spam-filter-saved-bbdb/mail_auto_create_p) | 413 | (setq bbdb/mail_auto_create_p |
| 414 | 'rsf-saved-bbdb/mail_auto_create_p) | ||
| 419 | ;; set return value. These lines must be last in the | 415 | ;; set return value. These lines must be last in the |
| 420 | ;; function, so that they will determine the value | 416 | ;; function, so that they will determine the value |
| 421 | ;; returned by rmail-spam-filter: | 417 | ;; returned by rmail-spam-filter: |
| 422 | (setq return-value nil)) | 418 | (setq return-value nil)) |
| 423 | (setq return-value t)))) | 419 | (setq return-value t)))) |
| 424 | (setq case-fold-search saved-case-fold-search) | 420 | (setq case-fold-search saved-case-fold-search) |
| 425 | (setq rmail-spam-filter-scanning-messages-now nil) | 421 | (setq rsf-scanning-messages-now nil) |
| 426 | return-value)) | 422 | return-value)) |
| 427 | 423 | ||
| 428 | 424 | ||
| 429 | ;; define functions for interactively adding sender/subject of a | 425 | ;; define functions for interactively adding sender/subject of a |
| 430 | ;; specific message to the spam definitions while reading it, using | 426 | ;; specific message to the spam definitions while reading it, using |
| 431 | ;; the menubar: | 427 | ;; the menubar: |
| 432 | (defun rmail-spam-filter-add-subject-to-spam-list () | 428 | (defun rsf-add-subject-to-spam-list () |
| 433 | (interactive) | 429 | (interactive) |
| 434 | (set-buffer rmail-buffer) | 430 | (set-buffer rmail-buffer) |
| 435 | (let ((message-subject)) | 431 | (let ((message-subject)) |
| @@ -437,15 +433,16 @@ it from rmail file. Called for each new message retrieved by | |||
| 437 | ;; note the use of a backquote and comma on the subject line here, | 433 | ;; note the use of a backquote and comma on the subject line here, |
| 438 | ;; to make sure message-subject is actually evaluated and its value | 434 | ;; to make sure message-subject is actually evaluated and its value |
| 439 | ;; substituted: | 435 | ;; substituted: |
| 440 | (add-to-list 'rmail-spam-definitions-alist | 436 | (add-to-list 'rsf-definitions-alist |
| 441 | (list '(from . "") | 437 | (list '(from . "") |
| 442 | '(to . "") | 438 | '(to . "") |
| 443 | `(subject . ,message-subject) | 439 | `(subject . ,message-subject) |
| 440 | '(content-type . "") | ||
| 444 | '(contents . "") | 441 | '(contents . "") |
| 445 | '(action . output-and-delete)) | 442 | '(action . output-and-delete)) |
| 446 | t) | 443 | t) |
| 447 | (customize-mark-to-save 'rmail-spam-definitions-alist) | 444 | (customize-mark-to-save 'rsf-definitions-alist) |
| 448 | (if rmail-spam-filter-autosave-newly-added-spam-definitions | 445 | (if rsf-autosave-newly-added-definitions |
| 449 | (progn | 446 | (progn |
| 450 | (custom-save-all) | 447 | (custom-save-all) |
| 451 | (message (concat "added subject \n <<< \n" message-subject | 448 | (message (concat "added subject \n <<< \n" message-subject |
| @@ -453,10 +450,11 @@ it from rmail file. Called for each new message retrieved by | |||
| 453 | "and saved the spam definitions to file."))) | 450 | "and saved the spam definitions to file."))) |
| 454 | (message (concat "added subject \n <<< \n" message-subject | 451 | (message (concat "added subject \n <<< \n" message-subject |
| 455 | " \n >>> \n to list of spam definitions. \n" | 452 | " \n >>> \n to list of spam definitions. \n" |
| 456 | "Don't forget to save the spam definitions to file using the spam menu")) | 453 | "Don't forget to save the spam definitions to file using the spam |
| 454 | menu")) | ||
| 457 | ))) | 455 | ))) |
| 458 | 456 | ||
| 459 | (defun rmail-spam-filter-add-sender-to-spam-list () | 457 | (defun rsf-add-sender-to-spam-list () |
| 460 | (interactive) | 458 | (interactive) |
| 461 | (set-buffer rmail-buffer) | 459 | (set-buffer rmail-buffer) |
| 462 | (let ((message-sender)) | 460 | (let ((message-sender)) |
| @@ -464,15 +462,16 @@ it from rmail file. Called for each new message retrieved by | |||
| 464 | ;; note the use of a backquote and comma on the "from" line here, | 462 | ;; note the use of a backquote and comma on the "from" line here, |
| 465 | ;; to make sure message-sender is actually evaluated and its value | 463 | ;; to make sure message-sender is actually evaluated and its value |
| 466 | ;; substituted: | 464 | ;; substituted: |
| 467 | (add-to-list 'rmail-spam-definitions-alist | 465 | (add-to-list 'rsf-definitions-alist |
| 468 | (list `(from . ,message-sender) | 466 | (list `(from . ,message-sender) |
| 469 | '(to . "") | 467 | '(to . "") |
| 470 | '(subject . "") | 468 | '(subject . "") |
| 469 | '(content-type . "") | ||
| 471 | '(contents . "") | 470 | '(contents . "") |
| 472 | '(action . output-and-delete)) | 471 | '(action . output-and-delete)) |
| 473 | t) | 472 | t) |
| 474 | (customize-mark-to-save 'rmail-spam-definitions-alist) | 473 | (customize-mark-to-save 'rsf-definitions-alist) |
| 475 | (if rmail-spam-filter-autosave-newly-added-spam-definitions | 474 | (if rsf-autosave-newly-added-definitions |
| 476 | (progn | 475 | (progn |
| 477 | (custom-save-all) | 476 | (custom-save-all) |
| 478 | (message (concat "added sender \n <<< \n" message-sender | 477 | (message (concat "added sender \n <<< \n" message-sender |
| @@ -480,13 +479,14 @@ it from rmail file. Called for each new message retrieved by | |||
| 480 | "and saved the spam definitions to file."))) | 479 | "and saved the spam definitions to file."))) |
| 481 | (message (concat "added sender \n <<< \n " message-sender | 480 | (message (concat "added sender \n <<< \n " message-sender |
| 482 | " \n >>> \n to list of spam definitions." | 481 | " \n >>> \n to list of spam definitions." |
| 483 | "Don't forget to save the spam definitions to file using the spam menu")) | 482 | "Don't forget to save the spam definitions to file using the spam |
| 483 | menu")) | ||
| 484 | ))) | 484 | ))) |
| 485 | 485 | ||
| 486 | 486 | ||
| 487 | (defun rmail-spam-filter-add-region-to-spam-list () | 487 | (defun rsf-add-region-to-spam-list () |
| 488 | "Add the region makred by user in the rmail buffer to the list of | 488 | "Add the region makred by user in the rmail buffer to spam list. |
| 489 | spam definitions as a contents field." | 489 | Added to spam definitions as a contents field." |
| 490 | (interactive) | 490 | (interactive) |
| 491 | (set-buffer rmail-buffer) | 491 | (set-buffer rmail-buffer) |
| 492 | (let ((region-to-spam-list)) | 492 | (let ((region-to-spam-list)) |
| @@ -494,41 +494,48 @@ it from rmail file. Called for each new message retrieved by | |||
| 494 | (if (not (and mark-active (not (= (region-beginning) (region-end))))) | 494 | (if (not (and mark-active (not (= (region-beginning) (region-end))))) |
| 495 | ;; if inactive, print error message: | 495 | ;; if inactive, print error message: |
| 496 | (message "you need to first highlight some text in the rmail buffer") | 496 | (message "you need to first highlight some text in the rmail buffer") |
| 497 | ;; if active, add to list of spam definisions: | 497 | (if (< (- (region-end) (region-beginning)) rsf-min-region-to-spam-list) |
| 498 | (progn | 498 | (message |
| 499 | (setq region-to-spam-list (buffer-substring (region-beginning) (region-end))) | 499 | (concat "highlighted region is too small; min length set by variable \n" |
| 500 | ;; note the use of a backquote and comma on the "from" line here, | 500 | "rsf-min-region-to-spam-list" |
| 501 | ;; to make sure message-sender is actually evaluated and its value | 501 | " is " (number-to-string rsf-min-region-to-spam-list))) |
| 502 | ;; substituted: | 502 | ;; if region active and long enough, add to list of spam definisions: |
| 503 | (add-to-list 'rmail-spam-definitions-alist | 503 | (progn |
| 504 | (list '(from . "") | 504 | (setq region-to-spam-list (buffer-substring (region-beginning) (region-end))) |
| 505 | '(to . "") | 505 | ;; note the use of a backquote and comma on the "from" line here, |
| 506 | '(subject . "") | 506 | ;; to make sure message-sender is actually evaluated and its value |
| 507 | `(contents . ,region-to-spam-list) | 507 | ;; substituted: |
| 508 | '(action . output-and-delete)) | 508 | (add-to-list 'rsf-definitions-alist |
| 509 | t) | 509 | (list '(from . "") |
| 510 | (customize-mark-to-save 'rmail-spam-definitions-alist) | 510 | '(to . "") |
| 511 | (if rmail-spam-filter-autosave-newly-added-spam-definitions | 511 | '(subject . "") |
| 512 | (progn | 512 | '(content-type . "") |
| 513 | (custom-save-all) | 513 | `(contents . ,region-to-spam-list) |
| 514 | (message (concat "added highlighted text \n <<< \n" region-to-spam-list | 514 | '(action . output-and-delete)) |
| 515 | " \n >>> \n to list of spam definitions. \n" | 515 | t) |
| 516 | "and saved the spam definitions to file."))) | 516 | (customize-mark-to-save 'rsf-definitions-alist) |
| 517 | (message (concat "added highlighted text \n <<< \n " region-to-spam-list | 517 | (if rsf-autosave-newly-added-definitions |
| 518 | " \n >>> \n to list of spam definitions." | 518 | (progn |
| 519 | "Don't forget to save the spam definitions to file using the spam menu")) | 519 | (custom-save-all) |
| 520 | ))))) | 520 | (message (concat "added highlighted text \n <<< \n" region-to-spam-list |
| 521 | 521 | " \n >>> \n to list of spam definitions. \n" | |
| 522 | 522 | "and saved the spam definitions to file."))) | |
| 523 | (defun rmail-spam-filter-customize-spam-definitions () | 523 | (message (concat "added highlighted text \n <<< \n " region-to-spam-list |
| 524 | " \n >>> \n to list of spam definitions." | ||
| 525 | "Don't forget to save the spam definitions to file using the | ||
| 526 | spam menu")) | ||
| 527 | )))))) | ||
| 528 | |||
| 529 | |||
| 530 | (defun rsf-customize-spam-definitions () | ||
| 524 | (interactive) | 531 | (interactive) |
| 525 | (customize-variable (quote rmail-spam-definitions-alist))) | 532 | (customize-variable (quote rsf-definitions-alist))) |
| 526 | 533 | ||
| 527 | (defun rmail-spam-filter-customize-group () | 534 | (defun rsf-customize-group () |
| 528 | (interactive) | 535 | (interactive) |
| 529 | (customize-group (quote rmail-spam-filter))) | 536 | (customize-group (quote rmail-spam-filter))) |
| 530 | 537 | ||
| 531 | (defun rmail-spam-custom-save-all () | 538 | (defun rsf-custom-save-all () |
| 532 | (interactive) | 539 | (interactive) |
| 533 | (custom-save-all)) | 540 | (custom-save-all)) |
| 534 | 541 | ||
| @@ -540,97 +547,89 @@ it from rmail file. Called for each new message retrieved by | |||
| 540 | (cons "Spam" (make-sparse-keymap "Spam"))) | 547 | (cons "Spam" (make-sparse-keymap "Spam"))) |
| 541 | 548 | ||
| 542 | (define-key rmail-summary-mode-map [menu-bar spam customize-group] | 549 | (define-key rmail-summary-mode-map [menu-bar spam customize-group] |
| 543 | '("Browse customizations of rmail spam filter" . rmail-spam-filter-customize-group)) | 550 | '("Browse customizations of rmail spam filter" . rsf-customize-group)) |
| 544 | (define-key rmail-mode-map [menu-bar spam customize-group] | 551 | (define-key rmail-mode-map [menu-bar spam customize-group] |
| 545 | '("Browse customizations of rmail spam filter" . rmail-spam-filter-customize-group)) | 552 | '("Browse customizations of rmail spam filter" . rsf-customize-group)) |
| 546 | (define-key rmail-summary-mode-map "\C-cSg" 'rmail-spam-filter-customize-group) | 553 | (define-key rmail-summary-mode-map "\C-cSg" 'rsf-customize-group) |
| 547 | (define-key rmail-mode-map "\C-cSg" 'rmail-spam-filter-customize-group) | 554 | (define-key rmail-mode-map "\C-cSg" 'rsf-customize-group) |
| 548 | 555 | ||
| 549 | (define-key rmail-summary-mode-map [menu-bar spam customize-spam-list] | 556 | (define-key rmail-summary-mode-map [menu-bar spam customize-spam-list] |
| 550 | '("Customize list of spam definitions" . rmail-spam-filter-customize-spam-definitions)) | 557 | '("Customize list of spam definitions" . rsf-customize-spam-definitions)) |
| 551 | (define-key rmail-mode-map [menu-bar spam customize-spam-list] | 558 | (define-key rmail-mode-map [menu-bar spam customize-spam-list] |
| 552 | '("Customize list of spam definitions" . rmail-spam-filter-customize-spam-definitions)) | 559 | '("Customize list of spam definitions" . rsf-customize-spam-definitions)) |
| 553 | (define-key rmail-summary-mode-map "\C-cSd" 'rmail-spam-filter-customize-spam-definitions) | 560 | (define-key rmail-summary-mode-map "\C-cSd" 'rsf-customize-spam-definitions) |
| 554 | (define-key rmail-mode-map "\C-cSd" 'rmail-spam-filter-customize-spam-definitions) | 561 | (define-key rmail-mode-map "\C-cSd" 'rsf-customize-spam-definitions) |
| 555 | 562 | ||
| 556 | (define-key rmail-summary-mode-map [menu-bar spam lambda] '("----")) | 563 | (define-key rmail-summary-mode-map [menu-bar spam lambda] '("----")) |
| 557 | (define-key rmail-mode-map [menu-bar spam lambda] '("----")) | 564 | (define-key rmail-mode-map [menu-bar spam lambda] '("----")) |
| 558 | 565 | ||
| 559 | (define-key rmail-summary-mode-map [menu-bar spam my-custom-save-all] | 566 | (define-key rmail-summary-mode-map [menu-bar spam my-custom-save-all] |
| 560 | '("save newly added spam definitions to customization file" . rmail-spam-custom-save-all)) | 567 | '("save newly added spam definitions to customization file" . rsf-custom-save-all)) |
| 561 | (define-key rmail-mode-map [menu-bar spam my-custom-save-all] | 568 | (define-key rmail-mode-map [menu-bar spam my-custom-save-all] |
| 562 | '("save newly added spam definitions to customization file" . rmail-spam-custom-save-all)) | 569 | '("save newly added spam definitions to customization file" . rsf-custom-save-all)) |
| 563 | (define-key rmail-summary-mode-map "\C-cSa" 'rmail-spam-custom-save-all) | 570 | (define-key rmail-summary-mode-map "\C-cSa" 'rsf-custom-save-all) |
| 564 | (define-key rmail-mode-map "\C-cSa" 'rmail-spam-custom-save-all) | 571 | (define-key rmail-mode-map "\C-cSa" 'rsf-custom-save-all) |
| 565 | 572 | ||
| 566 | (define-key rmail-summary-mode-map [menu-bar spam add-region-to-spam-list] | 573 | (define-key rmail-summary-mode-map [menu-bar spam add-region-to-spam-list] |
| 567 | '("add region to spam list" . rmail-spam-filter-add-region-to-spam-list)) | 574 | '("add region to spam list" . rsf-add-region-to-spam-list)) |
| 568 | (define-key rmail-mode-map [menu-bar spam add-region-to-spam-list] | 575 | (define-key rmail-mode-map [menu-bar spam add-region-to-spam-list] |
| 569 | '("add region to spam list" . rmail-spam-filter-add-region-to-spam-list)) | 576 | '("add region to spam list" . rsf-add-region-to-spam-list)) |
| 570 | (define-key rmail-summary-mode-map "\C-cSn" 'rmail-spam-filter-add-region-to-spam-list) | 577 | (define-key rmail-summary-mode-map "\C-cSn" 'rsf-add-region-to-spam-list) |
| 571 | (define-key rmail-mode-map "\C-cSn" 'rmail-spam-filter-add-region-to-spam-list) | 578 | (define-key rmail-mode-map "\C-cSn" 'rsf-add-region-to-spam-list) |
| 572 | 579 | ||
| 573 | (define-key rmail-summary-mode-map [menu-bar spam add-sender-to-spam-list] | 580 | (define-key rmail-summary-mode-map [menu-bar spam add-sender-to-spam-list] |
| 574 | '("add sender to spam list" . rmail-spam-filter-add-sender-to-spam-list)) | 581 | '("add sender to spam list" . rsf-add-sender-to-spam-list)) |
| 575 | (define-key rmail-mode-map [menu-bar spam add-sender-to-spam-list] | 582 | (define-key rmail-mode-map [menu-bar spam add-sender-to-spam-list] |
| 576 | '("add sender to spam list" . rmail-spam-filter-add-sender-to-spam-list)) | 583 | '("add sender to spam list" . rsf-add-sender-to-spam-list)) |
| 577 | (define-key rmail-summary-mode-map "\C-cSr" 'rmail-spam-filter-add-sender-to-spam-list) | 584 | (define-key rmail-summary-mode-map "\C-cSr" 'rsf-add-sender-to-spam-list) |
| 578 | (define-key rmail-mode-map "\C-cSr" 'rmail-spam-filter-add-sender-to-spam-list) | 585 | (define-key rmail-mode-map "\C-cSr" 'rsf-add-sender-to-spam-list) |
| 579 | 586 | ||
| 580 | (define-key rmail-summary-mode-map [menu-bar spam add-subject-to-spam-list] | 587 | (define-key rmail-summary-mode-map [menu-bar spam add-subject-to-spam-list] |
| 581 | '("add subject to spam list" . rmail-spam-filter-add-subject-to-spam-list)) | 588 | '("add subject to spam list" . rsf-add-subject-to-spam-list)) |
| 582 | (define-key rmail-mode-map [menu-bar spam add-subject-to-spam-list] | 589 | (define-key rmail-mode-map [menu-bar spam add-subject-to-spam-list] |
| 583 | '("add subject to spam list" . rmail-spam-filter-add-subject-to-spam-list)) | 590 | '("add subject to spam list" . rsf-add-subject-to-spam-list)) |
| 584 | (define-key rmail-summary-mode-map "\C-cSt" 'rmail-spam-filter-add-subject-to-spam-list) | 591 | (define-key rmail-summary-mode-map "\C-cSt" 'rsf-add-subject-to-spam-list) |
| 585 | (define-key rmail-mode-map "\C-cSt" 'rmail-spam-filter-add-subject-to-spam-list) | 592 | (define-key rmail-mode-map "\C-cSt" 'rsf-add-subject-to-spam-list) |
| 586 | 593 | ||
| 587 | 594 | (defun rsf-add-content-type-field () | |
| 588 | (defun rmail-bbdb-auto-delete-spam-entries () | 595 | "Maintain backward compatibility with previous versions of rmail-spam-filter. |
| 589 | "When deleting a message in RMAIL, check to see if the bbdb entry | 596 | The most recent version of rmai-spam-filter checks the contents |
| 590 | was created today, and if it was, prompt to delete it too. This function | 597 | field of the incoming mail to see if it spam. The format of |
| 591 | needs to be called via the `rmail-delete-message-hook' like this: | 598 | `rsf-definitions-alist' has therefore changed. This function |
| 592 | \(add-hook 'rmail-delete-message-hook 'rmail-bbdb-auto-delete-spam-entries)" | 599 | checks to see if old format is used, and if it is, it converts |
| 593 | (interactive) | 600 | `rsf-definitions-alist' to the new format. Invoked |
| 594 | (require 'bbdb-hooks) | 601 | automatically, no user input is required." |
| 595 | (if (not rmail-spam-filter-scanning-messages-now) | ||
| 596 | (if (get-buffer "*BBDB*") | ||
| 597 | (save-excursion | ||
| 598 | (set-buffer (get-buffer "*BBDB*")) | ||
| 599 | (if (bbdb-current-record) | ||
| 600 | (if (equal | ||
| 601 | (format-time-string bbdb-time-internal-format (current-time)) | ||
| 602 | (bbdb-record-getprop (bbdb-current-record) 'creation-date)) | ||
| 603 | (bbdb-delete-current-record (bbdb-current-record)))))))) | ||
| 604 | |||
| 605 | (defun rmail-spam-filter-bbdb-dont-create-entries-for-spam () | ||
| 606 | "Make sure senderes of rmail messages marked as deleted are not added to bbdb. | ||
| 607 | Need to add this as a hook like this: | ||
| 608 | \(setq bbdb/mail-auto-create-p 'rmail-spam-filter-bbdb-dont-create-entries-for-spam) | ||
| 609 | and this is also used in conjunction with rmail-bbdb-auto-delete-spam-entries. | ||
| 610 | More doc: rmail-bbdb-auto-delete-spam-entries will delete newly created bbdb | ||
| 611 | entries of mail that is deleted. However, if one scrolls back to the deleted | ||
| 612 | messages, then the sender is again added to the bbdb. This function | ||
| 613 | prevents this. Also, don't create entries for messages in the `rmail-spam-file'." | ||
| 614 | (interactive) | 602 | (interactive) |
| 615 | (not | 603 | (if (and rsf-definitions-alist |
| 616 | ;; don't create a bbdb entry if one of the following conditions is satisfied: | 604 | (not (assoc 'content-type (car rsf-definitions-alist)))) |
| 617 | (or | 605 | (let ((result nil) |
| 618 | ;; 1) looking at a deleted message: | 606 | (current nil) |
| 619 | (rmail-message-deleted-p rmail-current-message) | 607 | (definitions rsf-definitions-alist)) |
| 620 | ;; 2) looking at messages in rmail-spam-file: | 608 | (while definitions |
| 621 | (string-match | 609 | (setq current (car definitions)) |
| 622 | (expand-file-name rmail-spam-file) | 610 | (setq definitions (cdr definitions)) |
| 623 | (expand-file-name (buffer-file-name rmail-buffer))) | 611 | (setq result |
| 624 | ))) | 612 | (append result |
| 625 | 613 | (list | |
| 626 | ;; activate bbdb-anti-spam measures: | 614 | (list (assoc 'from current) |
| 627 | (if rmail-spam-filter-auto-delete-spam-bbdb-entries | 615 | (assoc 'to current) |
| 628 | (progn | 616 | (assoc 'subject current) |
| 629 | (add-hook 'rmail-delete-message-hook 'rmail-bbdb-auto-delete-spam-entries) | 617 | (cons 'content-type "") |
| 630 | (setq bbdb/mail-auto-create-p 'rmail-spam-filter-bbdb-dont-create-entries-for-spam) | 618 | (assoc 'contents current) |
| 631 | )) | 619 | (assoc 'action current)))))) |
| 620 | (setq rsf-definitions-alist result) | ||
| 621 | (customize-mark-to-save 'rsf-definitions-alist) | ||
| 622 | (if rsf-autosave-newly-added-definitions | ||
| 623 | (progn | ||
| 624 | (custom-save-all) | ||
| 625 | (message (concat "converted spam definitions to new format\n" | ||
| 626 | "and saved the spam definitions to file."))) | ||
| 627 | (message (concat "converted spam definitions to new format\n" | ||
| 628 | "Don't forget to save the spam definitions to file using the | ||
| 629 | spam menu")) | ||
| 630 | )))) | ||
| 632 | 631 | ||
| 633 | (provide 'rmail-spam-filter) | 632 | (provide 'rmail-spam-filter) |
| 634 | 633 | ||
| 635 | ;;; arch-tag: 03e1d45d-b72f-4dd7-8f04-e7fd78249746 | 634 | ;;; arch-tag: 03e1d45d-b72f-4dd7-8f04-e7fd78249746 |
| 636 | ;;; rmail-spam-filter.el ends here | 635 | ;;; rmail-spam-fitler ends here |