aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorPaul Eggert2011-04-16 15:30:01 -0700
committerPaul Eggert2011-04-16 15:30:01 -0700
commitc7b7425e227a08bb85565498e517364fbc96dd2d (patch)
tree2c8fc8e79bfdb4450b9c1df49fb652e6c1443d5d /lisp
parent5c1ccb01541c438e596ce2d819d703d67bab25c0 (diff)
parentc4354cb4f4a3982331180439120ca72734d49cc5 (diff)
downloademacs-c7b7425e227a08bb85565498e517364fbc96dd2d.tar.gz
emacs-c7b7425e227a08bb85565498e517364fbc96dd2d.zip
Merge from mainline.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/ChangeLog2
-rw-r--r--lisp/gnus/ChangeLog20
-rw-r--r--lisp/gnus/gnus-registry.el167
-rw-r--r--lisp/gnus/registry.el24
-rw-r--r--lisp/url/ChangeLog5
-rw-r--r--lisp/url/url-http.el4
6 files changed, 189 insertions, 33 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 9f3c8e6c498..da2995840da 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -228,7 +228,7 @@
2282011-04-06 Juanma Barranquero <lekktu@gmail.com> 2282011-04-06 Juanma Barranquero <lekktu@gmail.com>
229 229
230 * files.el (after-find-file-from-revert-buffer): Remove variable. 230 * files.el (after-find-file-from-revert-buffer): Remove variable.
231 (after-find-file): Dont' bind it. 231 (after-find-file): Don't bind it.
232 (revert-buffer-in-progress-p): New variable. 232 (revert-buffer-in-progress-p): New variable.
233 (revert-buffer): Bind it. 233 (revert-buffer): Bind it.
234 Pass nil for `after-find-file-from-revert-buffer'. 234 Pass nil for `after-find-file-from-revert-buffer'.
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog
index be6f3737ae1..eac53d413cc 100644
--- a/lisp/gnus/ChangeLog
+++ b/lisp/gnus/ChangeLog
@@ -1,3 +1,23 @@
12011-04-16 Teodor Zlatanov <tzz@lifelogs.com>
2
3 * registry.el (registry-reindex): New method to recreate the secondary
4 registry indices.
5
6 * gnus-registry.el (gnus-registry-fixup-registry): Use it if the
7 tracked field changes.
8 (gnus-registry-unfollowed-addresses, gnus-registry-track-extra)
9 (gnus-registry-action, gnus-registry-spool-action)
10 (gnus-registry-handle-action)
11 (gnus-registry--split-fancy-with-parent-internal)
12 (gnus-registry-split-fancy-with-parent)
13 (gnus-registry-register-message-ids): Add recipient tracking on spool,
14 move, and delete actions, and for fancy splitting with parent.
15 (gnus-registry-extract-addresses)
16 (gnus-registry-fetch-recipients-fast)
17 (gnus-registry-fetch-header-fast): Convenience functions.
18 (gnus-registry-misc-test): ERT test of
19 `gnus-registry-extract-addresses'.
20
12011-04-15 Teodor Zlatanov <tzz@lifelogs.com> 212011-04-15 Teodor Zlatanov <tzz@lifelogs.com>
2 22
3 * gnus-registry.el (gnus-registry--split-fancy-with-parent-internal): 23 * gnus-registry.el (gnus-registry--split-fancy-with-parent-internal):
diff --git a/lisp/gnus/gnus-registry.el b/lisp/gnus/gnus-registry.el
index 77ed5a55aed..eab4403c34b 100644
--- a/lisp/gnus/gnus-registry.el
+++ b/lisp/gnus/gnus-registry.el
@@ -36,7 +36,7 @@
36;; Put this in your startup file (~/.gnus.el for instance) or use Customize: 36;; Put this in your startup file (~/.gnus.el for instance) or use Customize:
37 37
38;; (setq gnus-registry-max-entries 2500 38;; (setq gnus-registry-max-entries 2500
39;; gnus-registry-track-extra '(sender subject)) 39;; gnus-registry-track-extra '(sender subject recipient))
40 40
41;; (gnus-registry-initialize) 41;; (gnus-registry-initialize)
42 42
@@ -119,7 +119,9 @@ display.")
119(defcustom gnus-registry-unfollowed-addresses 119(defcustom gnus-registry-unfollowed-addresses
120 (list (regexp-quote user-mail-address)) 120 (list (regexp-quote user-mail-address))
121 "List of addresses that gnus-registry-split-fancy-with-parent won't trace. 121 "List of addresses that gnus-registry-split-fancy-with-parent won't trace.
122The addresses are matched, they don't have to be fully qualified." 122The addresses are matched, they don't have to be fully qualified.
123In the messages, these addresses can be the sender or the
124recipients."
123 :group 'gnus-registry 125 :group 'gnus-registry
124 :type '(repeat regexp)) 126 :type '(repeat regexp))
125 127
@@ -152,14 +154,15 @@ nnmairix groups are specifically excluded because they are ephemeral."
152(make-obsolete-variable 'gnus-registry-entry-caching nil "23.4") 154(make-obsolete-variable 'gnus-registry-entry-caching nil "23.4")
153(make-obsolete-variable 'gnus-registry-trim-articles-without-groups nil "23.4") 155(make-obsolete-variable 'gnus-registry-trim-articles-without-groups nil "23.4")
154 156
155(defcustom gnus-registry-track-extra '(subject sender) 157(defcustom gnus-registry-track-extra '(subject sender recipient)
156 "Whether the registry should track extra data about a message. 158 "Whether the registry should track extra data about a message.
157The Subject and Sender (From:) headers are tracked this way by 159The subject, recipients (To: and Cc:), and Sender (From:) headers
158default." 160are tracked this way by default."
159 :group 'gnus-registry 161 :group 'gnus-registry
160 :type 162 :type
161 '(set :tag "Tracking choices" 163 '(set :tag "Tracking choices"
162 (const :tag "Track by subject (Subject: header)" subject) 164 (const :tag "Track by subject (Subject: header)" subject)
165 (const :tag "Track by recipient (To: and Cc: headers)" recipient)
163 (const :tag "Track by sender (From: header)" sender))) 166 (const :tag "Track by sender (From: header)" sender)))
164 167
165(defcustom gnus-registry-split-strategy nil 168(defcustom gnus-registry-split-strategy nil
@@ -224,18 +227,22 @@ the Bit Bucket."
224 227
225(defun gnus-registry-fixup-registry (db) 228(defun gnus-registry-fixup-registry (db)
226 (when db 229 (when db
227 (oset db :precious 230 (let ((old (oref db :tracked)))
228 (append gnus-registry-extra-entries-precious 231 (oset db :precious
229 '())) 232 (append gnus-registry-extra-entries-precious
230 (oset db :max-hard 233 '()))
231 (or gnus-registry-max-entries 234 (oset db :max-hard
232 most-positive-fixnum)) 235 (or gnus-registry-max-entries
233 (oset db :max-soft 236 most-positive-fixnum))
234 (or gnus-registry-max-pruned-entries 237 (oset db :max-soft
235 most-positive-fixnum)) 238 (or gnus-registry-max-pruned-entries
236 (oset db :tracked 239 most-positive-fixnum))
237 (append gnus-registry-track-extra 240 (oset db :tracked
238 '(mark group keyword)))) 241 (append gnus-registry-track-extra
242 '(mark group keyword)))
243 (when (not (equal old (oref db :tracked)))
244 (gnus-message 4 "Reindexing the Gnus registry (tracked change)")
245 (registry-reindex db))))
239 db) 246 db)
240 247
241(defun gnus-registry-make-db (&optional file) 248(defun gnus-registry-make-db (&optional file)
@@ -296,7 +303,17 @@ This is not required after changing `gnus-registry-cache-file'."
296(defun gnus-registry-action (action data-header from &optional to method) 303(defun gnus-registry-action (action data-header from &optional to method)
297 (let* ((id (mail-header-id data-header)) 304 (let* ((id (mail-header-id data-header))
298 (subject (mail-header-subject data-header)) 305 (subject (mail-header-subject data-header))
299 (sender (mail-header-from data-header)) 306 (recipients (sort (mapcan 'gnus-registry-extract-addresses
307 (list
308 (or (ignore-errors
309 (mail-header "Cc" data-header))
310 "")
311 (or (ignore-errors
312 (mail-header "To" data-header))
313 "")))
314 'string-lessp))
315 (sender (nth 0 (gnus-registry-extract-addresses
316 (mail-header-from data-header))))
300 (from (gnus-group-guess-full-name-from-command-method from)) 317 (from (gnus-group-guess-full-name-from-command-method from))
301 (to (if to (gnus-group-guess-full-name-from-command-method to) nil)) 318 (to (if to (gnus-group-guess-full-name-from-command-method to) nil))
302 (to-name (if to to "the Bit Bucket"))) 319 (to-name (if to to "the Bit Bucket")))
@@ -307,10 +324,16 @@ This is not required after changing `gnus-registry-cache-file'."
307 id 324 id
308 ;; unless copying, remove the old "from" group 325 ;; unless copying, remove the old "from" group
309 (if (not (equal 'copy action)) from nil) 326 (if (not (equal 'copy action)) from nil)
310 to subject sender))) 327 to subject sender recipients)))
311 328
312(defun gnus-registry-spool-action (id group &optional subject sender) 329(defun gnus-registry-spool-action (id group &optional subject sender recipients)
313 (let ((to (gnus-group-guess-full-name-from-command-method group)) 330 (let ((to (gnus-group-guess-full-name-from-command-method group))
331 (recipients (or recipients
332 (sort (mapcan 'gnus-registry-extract-addresses
333 (list
334 (or (message-fetch-field "cc") "")
335 (or (message-fetch-field "to") "")))
336 'string-lessp)))
314 (subject (or subject (message-fetch-field "subject"))) 337 (subject (or subject (message-fetch-field "subject")))
315 (sender (or sender (message-fetch-field "from")))) 338 (sender (or sender (message-fetch-field "from"))))
316 (when (and (stringp id) (string-match "\r$" id)) 339 (when (and (stringp id) (string-match "\r$" id))
@@ -318,12 +341,13 @@ This is not required after changing `gnus-registry-cache-file'."
318 (gnus-message 7 "Gnus registry: article %s spooled to %s" 341 (gnus-message 7 "Gnus registry: article %s spooled to %s"
319 id 342 id
320 to) 343 to)
321 (gnus-registry-handle-action id nil to subject sender))) 344 (gnus-registry-handle-action id nil to subject sender recipients)))
322 345
323(defun gnus-registry-handle-action (id from to subject sender) 346(defun gnus-registry-handle-action (id from to subject sender
347 &optional recipients)
324 (gnus-message 348 (gnus-message
325 10 349 10
326 "gnus-registry-handle-action %S" (list id from to subject sender)) 350 "gnus-registry-handle-action %S" (list id from to subject sender recipients))
327 (let ((db gnus-registry-db) 351 (let ((db gnus-registry-db)
328 ;; safe if not found 352 ;; safe if not found
329 (entry (gnus-registry-get-or-make-entry id)) 353 (entry (gnus-registry-get-or-make-entry id))
@@ -340,11 +364,15 @@ This is not required after changing `gnus-registry-cache-file'."
340 (setq entry (cons (delete from (assoc 'group entry)) 364 (setq entry (cons (delete from (assoc 'group entry))
341 (assq-delete-all 'group entry)))) 365 (assq-delete-all 'group entry))))
342 366
343 (dolist (kv `((group ,to) (sender ,sender) (subject ,subject))) 367 (dolist (kv `((group ,to)
368 (sender ,sender)
369 (recipient ,@recipients)
370 (subject ,subject)))
344 (when (second kv) 371 (when (second kv)
345 (let ((new (or (assq (first kv) entry) 372 (let ((new (or (assq (first kv) entry)
346 (list (first kv))))) 373 (list (first kv)))))
347 (add-to-list 'new (second kv) t) 374 (dolist (toadd (cdr kv))
375 (add-to-list 'new toadd t))
348 (setq entry (cons new 376 (setq entry (cons new
349 (assq-delete-all (first kv) entry)))))) 377 (assq-delete-all (first kv) entry))))))
350 (gnus-message 10 "Gnus registry: new entry for %s is %S" 378 (gnus-message 10 "Gnus registry: new entry for %s is %S"
@@ -381,6 +409,11 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details."
381 ;; these may not be used, but the code is cleaner having them up here 409 ;; these may not be used, but the code is cleaner having them up here
382 (sender (gnus-string-remove-all-properties 410 (sender (gnus-string-remove-all-properties
383 (message-fetch-field "from"))) 411 (message-fetch-field "from")))
412 (recipients (sort (mapcan 'gnus-registry-extract-addresses
413 (list
414 (or (message-fetch-field "cc") "")
415 (or (message-fetch-field "to") "")))
416 'string-lessp))
384 (subject (gnus-string-remove-all-properties 417 (subject (gnus-string-remove-all-properties
385 (gnus-registry-simplify-subject 418 (gnus-registry-simplify-subject
386 (message-fetch-field "subject")))) 419 (message-fetch-field "subject"))))
@@ -393,12 +426,13 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details."
393 :references references 426 :references references
394 :refstr refstr 427 :refstr refstr
395 :sender sender 428 :sender sender
429 :recipients recipients
396 :subject subject 430 :subject subject
397 :log-agent "Gnus registry fancy splitting with parent"))) 431 :log-agent "Gnus registry fancy splitting with parent")))
398 432
399(defun* gnus-registry--split-fancy-with-parent-internal 433(defun* gnus-registry--split-fancy-with-parent-internal
400 (&rest spec 434 (&rest spec
401 &key references refstr sender subject log-agent 435 &key references refstr sender subject recipients log-agent
402 &allow-other-keys) 436 &allow-other-keys)
403 (gnus-message 437 (gnus-message
404 10 438 10
@@ -478,6 +512,36 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details."
478 (setq found (gnus-registry-post-process-groups 512 (setq found (gnus-registry-post-process-groups
479 "sender" sender found))) 513 "sender" sender found)))
480 514
515 ;; else: there were no matches, try the extra tracking by recipient
516 (when (and (null found)
517 (memq 'recipient gnus-registry-track-extra)
518 recipients)
519 (dolist (recp recipients)
520 (when (and (null found)
521 (not (gnus-grep-in-list
522 recp
523 gnus-registry-unfollowed-addresses)))
524 (let ((groups (apply 'append
525 (mapcar
526 (lambda (reference)
527 (gnus-registry-get-id-key reference 'group))
528 (registry-lookup-secondary-value
529 db 'recipient recp)))))
530 (setq found
531 (loop for group in groups
532 when (gnus-registry-follow-group-p group)
533 do (gnus-message
534 ;; warn more if gnus-registry-track-extra
535 (if gnus-registry-track-extra 7 9)
536 "%s (extra tracking) traced recipient '%s' to %s"
537 log-agent recp group)
538 collect group)))))
539
540 ;; filter the found groups and return them
541 ;; the found groups are NOT the full groups
542 (setq found (gnus-registry-post-process-groups
543 "recipients" (mapconcat 'identity recipients ", ") found)))
544
481 ;; after the (cond) we extract the actual value safely 545 ;; after the (cond) we extract the actual value safely
482 (car-safe found))) 546 (car-safe found)))
483 547
@@ -629,7 +693,8 @@ Overrides existing keywords with FORCE set non-nil."
629 article gnus-newsgroup-name) 693 article gnus-newsgroup-name)
630 (gnus-registry-handle-action id nil gnus-newsgroup-name 694 (gnus-registry-handle-action id nil gnus-newsgroup-name
631 (gnus-registry-fetch-simplified-message-subject-fast article) 695 (gnus-registry-fetch-simplified-message-subject-fast article)
632 (gnus-registry-fetch-sender-fast article))))))) 696 (gnus-registry-fetch-sender-fast article)
697 (gnus-registry-fetch-recipients-fast article)))))))
633 698
634;; message field fetchers 699;; message field fetchers
635(defun gnus-registry-fetch-message-id-fast (article) 700(defun gnus-registry-fetch-message-id-fast (article)
@@ -639,6 +704,21 @@ Overrides existing keywords with FORCE set non-nil."
639 (mail-header-id (gnus-data-header (assoc article (gnus-data-list nil)))) 704 (mail-header-id (gnus-data-header (assoc article (gnus-data-list nil))))
640 nil)) 705 nil))
641 706
707(defun gnus-registry-extract-addresses (text)
708 "Extract all the addresses in a normalized way from TEXT.
709Returns an unsorted list of strings in the name <address> format.
710Addresses without a name will say \"noname\"."
711 (mapcar (lambda (add)
712 (gnus-string-remove-all-properties
713 (let* ((name (or (nth 0 add) "noname"))
714 (addr (nth 1 add))
715 (addr (if (bufferp addr)
716 (with-current-buffer addr
717 (buffer-string))
718 addr)))
719 (format "%s <%s>" name addr))))
720 (mail-extract-address-components text t)))
721
642(defun gnus-registry-simplify-subject (subject) 722(defun gnus-registry-simplify-subject (subject)
643 (if (stringp subject) 723 (if (stringp subject)
644 (gnus-simplify-subject subject) 724 (gnus-simplify-subject subject)
@@ -655,12 +735,26 @@ Overrides existing keywords with FORCE set non-nil."
655 nil)) 735 nil))
656 736
657(defun gnus-registry-fetch-sender-fast (article) 737(defun gnus-registry-fetch-sender-fast (article)
658 "Fetch the Sender quickly, using the internal gnus-data-list function" 738 (gnus-registry-fetch-header-fast "from" article))
739
740(defun gnus-registry-fetch-recipients-fast (article)
741 (sort (mapcan 'gnus-registry-extract-addresses
742 (list
743 (or (ignore-errors
744 (gnus-registry-fetch-header-fast "Cc" article))
745 "")
746 (or (ignore-errors
747 (gnus-registry-fetch-header-fast "To" article))
748 "")))
749 'string-lessp))
750
751(defun gnus-registry-fetch-header-fast (article header)
752 "Fetch the HEADER quickly, using the internal gnus-data-list function"
659 (if (and (numberp article) 753 (if (and (numberp article)
660 (assoc article (gnus-data-list nil))) 754 (assoc article (gnus-data-list nil)))
661 (gnus-string-remove-all-properties 755 (gnus-string-remove-all-properties
662 (mail-header-from (gnus-data-header 756 (mail-header header (gnus-data-header
663 (assoc article (gnus-data-list nil))))) 757 (assoc article (gnus-data-list nil)))))
664 nil)) 758 nil))
665 759
666;; registry marks glue 760;; registry marks glue
@@ -902,6 +996,19 @@ only the last one's marks are returned."
902 (gnus-registry-set-id-key id key val)))) 996 (gnus-registry-set-id-key id key val))))
903 (message "Import done, collected %d entries" count)))) 997 (message "Import done, collected %d entries" count))))
904 998
999(ert-deftest gnus-registry-misc-test ()
1000 (should-error (gnus-registry-extract-addresses '("" "")))
1001
1002 (should (equal '("Ted Zlatanov <tzz@lifelogs.com>"
1003 "noname <ed@you.me>"
1004 "noname <cyd@stupidchicken.com>"
1005 "noname <tzz@lifelogs.com>")
1006 (gnus-registry-extract-addresses
1007 (concat "Ted Zlatanov <tzz@lifelogs.com>, "
1008 "ed <ed@you.me>, " ; "ed" is not a valid name here
1009 "cyd@stupidchicken.com, "
1010 "tzz@lifelogs.com")))))
1011
905(ert-deftest gnus-registry-usage-test () 1012(ert-deftest gnus-registry-usage-test ()
906 (let* ((n 100) 1013 (let* ((n 100)
907 (tempfile (make-temp-file "gnus-registry-persist")) 1014 (tempfile (make-temp-file "gnus-registry-persist"))
diff --git a/lisp/gnus/registry.el b/lisp/gnus/registry.el
index 23e75815979..3e638427897 100644
--- a/lisp/gnus/registry.el
+++ b/lisp/gnus/registry.el
@@ -281,6 +281,25 @@ Errors out if the key exists already."
281 (registry-lookup-secondary-value db tr val value-keys)))) 281 (registry-lookup-secondary-value db tr val value-keys))))
282 entry) 282 entry)
283 283
284(defmethod registry-reindex ((db registry-db))
285 "Rebuild the secondary indices of registry-db THIS."
286 (let ((count 0)
287 (expected (* (length (oref db :tracked)) (registry-size db))))
288 (dolist (tr (oref db :tracked))
289 (let (values)
290 (maphash
291 (lambda (key v)
292 (incf count)
293 (when (and (< 0 expected)
294 (= 0 (mod count 1000)))
295 (message "reindexing: %d of %d (%.2f%%)"
296 count expected (/ (* 1000 count) expected)))
297 (dolist (val (cdr-safe (assq tr v)))
298 (let* ((value-keys (registry-lookup-secondary-value db tr val)))
299 (push key value-keys)
300 (registry-lookup-secondary-value db tr val value-keys))))
301 (oref db :data))))))
302
284(defmethod registry-size ((db registry-db)) 303(defmethod registry-size ((db registry-db))
285 "Returns the size of the registry-db object THIS. 304 "Returns the size of the registry-db object THIS.
286This is the key count of the :data slot." 305This is the key count of the :data slot."
@@ -360,10 +379,11 @@ Removes only entries without the :precious keys."
360 (when (boundp 'lexical-binding) 379 (when (boundp 'lexical-binding)
361 (message "Individual lookup (breaks before lexbind)") 380 (message "Individual lookup (breaks before lexbind)")
362 (should (= 58 381 (should (= 58
363 (caadr (registry-lookup-breaks-before-lexbind db '(1 58 99))))) 382 (caadr (registry-lookup-breaks-before-lexbind db '(1 58 99)))))
364 (message "Grouped individual lookup (breaks before lexbind)") 383 (message "Grouped individual lookup (breaks before lexbind)")
365 (should (= 3 384 (should (= 3
366 (length (registry-lookup-breaks-before-lexbind db '(1 58 99)))))) 385 (length (registry-lookup-breaks-before-lexbind db
386 '(1 58 99))))))
367 (message "Search") 387 (message "Search")
368 (should (= n (length (registry-search db :all t)))) 388 (should (= n (length (registry-search db :all t))))
369 (should (= n (length (registry-search db :member '((sender "me")))))) 389 (should (= n (length (registry-search db :member '((sender "me"))))))
diff --git a/lisp/url/ChangeLog b/lisp/url/ChangeLog
index f75a3444e0c..528b63a6448 100644
--- a/lisp/url/ChangeLog
+++ b/lisp/url/ChangeLog
@@ -1,3 +1,8 @@
12011-04-16 Lars Magne Ingebrigtsen <larsi@gnus.org>
2
3 * url-http.el (url-http-wait-for-headers-change-function): Protect
4 against malformed headerless responses from servers.
5
12011-04-02 Chong Yidong <cyd@stupidchicken.com> 62011-04-02 Chong Yidong <cyd@stupidchicken.com>
2 7
3 * url-gw.el (url-open-stream): Use new open-network-stream 8 * url-gw.el (url-open-stream): Use new open-network-stream
diff --git a/lisp/url/url-http.el b/lisp/url/url-http.el
index 07e57cf3301..28071e7165a 100644
--- a/lisp/url/url-http.el
+++ b/lisp/url/url-http.el
@@ -1077,6 +1077,10 @@ the end of the document."
1077 (downcase url-http-transfer-encoding))) 1077 (downcase url-http-transfer-encoding)))
1078 1078
1079 (cond 1079 (cond
1080 ((null url-http-response-status)
1081 ;; We got back a headerless malformed response from the
1082 ;; server.
1083 (url-http-activate-callback))
1080 ((or (= url-http-response-status 204) 1084 ((or (= url-http-response-status 204)
1081 (= url-http-response-status 205)) 1085 (= url-http-response-status 205))
1082 (url-http-debug "%d response must have headers only (%s)." 1086 (url-http-debug "%d response must have headers only (%s)."