comparison lisp/gnus/nnml.el @ 110468:8ceac426a2d7

merge trunk
author Kenichi Handa <handa@m17n.org>
date Tue, 21 Sep 2010 20:45:10 +0900
parents cd99c4421df9
children b7b7e970d807
comparison
equal deleted inserted replaced
110384:8d0ea2f29215 110468:8ceac426a2d7
158 (nnmail-group-pathname (inline (nnml-decoded-group-name group server)) 158 (nnmail-group-pathname (inline (nnml-decoded-group-name group server))
159 nnml-directory file)) 159 nnml-directory file))
160 160
161 (deffoo nnml-retrieve-headers (sequence &optional group server fetch-old) 161 (deffoo nnml-retrieve-headers (sequence &optional group server fetch-old)
162 (when (nnml-possibly-change-directory group server) 162 (when (nnml-possibly-change-directory group server)
163 (save-excursion 163 (with-current-buffer nntp-server-buffer
164 (set-buffer nntp-server-buffer)
165 (erase-buffer) 164 (erase-buffer)
166 (let* ((file nil) 165 (let* ((file nil)
167 (number (length sequence)) 166 (number (length sequence))
168 (count 0) 167 (count 0)
169 (file-name-coding-system nnmail-pathname-coding-system) 168 (file-name-coding-system nnmail-pathname-coding-system)
253 (nnheader-report 'nnml "Article %s retrieved" id) 252 (nnheader-report 'nnml "Article %s retrieved" id)
254 ;; We return the article number. 253 ;; We return the article number.
255 (cons (if group-num (car group-num) group) 254 (cons (if group-num (car group-num) group)
256 (string-to-number (file-name-nondirectory path))))))) 255 (string-to-number (file-name-nondirectory path)))))))
257 256
258 (deffoo nnml-request-group (group &optional server dont-check) 257 (deffoo nnml-request-group (group &optional server dont-check info)
259 (let ((file-name-coding-system nnmail-pathname-coding-system) 258 (let ((file-name-coding-system nnmail-pathname-coding-system)
260 (decoded (nnml-decoded-group-name group server))) 259 (decoded (nnml-decoded-group-name group server)))
261 (cond 260 (cond
262 ((not (nnml-possibly-change-directory group server)) 261 ((not (nnml-possibly-change-directory group server))
263 (nnheader-report 'nnml "Invalid group (no such directory)")) 262 (nnheader-report 'nnml "Invalid group (no such directory)"))
403 (nnml-deletable-article-p group article) 402 (nnml-deletable-article-p group article)
404 (nnml-request-article article group server) 403 (nnml-request-article article group server)
405 (let (nnml-current-directory 404 (let (nnml-current-directory
406 nnml-current-group 405 nnml-current-group
407 nnml-article-file-alist) 406 nnml-article-file-alist)
408 (save-excursion 407 (with-current-buffer buf
409 (set-buffer buf)
410 (insert-buffer-substring nntp-server-buffer) 408 (insert-buffer-substring nntp-server-buffer)
411 (setq result (eval accept-form)) 409 (setq result (eval accept-form))
412 (kill-buffer (current-buffer)) 410 (kill-buffer (current-buffer))
413 result)) 411 result))
414 (progn 412 (progn
460 (deffoo nnml-request-post (&optional server) 458 (deffoo nnml-request-post (&optional server)
461 (nnmail-do-request-post 'nnml-request-accept-article server)) 459 (nnmail-do-request-post 'nnml-request-accept-article server))
462 460
463 (deffoo nnml-request-replace-article (article group buffer) 461 (deffoo nnml-request-replace-article (article group buffer)
464 (nnml-possibly-change-directory group) 462 (nnml-possibly-change-directory group)
465 (save-excursion 463 (with-current-buffer buffer
466 (set-buffer buffer)
467 (nnml-possibly-create-directory group) 464 (nnml-possibly-create-directory group)
468 (let ((chars (nnmail-insert-lines)) 465 (let ((chars (nnmail-insert-lines))
469 (art (concat (int-to-string article) "\t")) 466 (art (concat (int-to-string article) "\t"))
470 headers) 467 headers)
471 (when (ignore-errors 468 (when (ignore-errors
476 nnml-current-directory)) 473 nnml-current-directory))
477 nil (if (nnheader-be-verbose 5) nil 'nomesg)) 474 nil (if (nnheader-be-verbose 5) nil 'nomesg))
478 t) 475 t)
479 (setq headers (nnml-parse-head chars article)) 476 (setq headers (nnml-parse-head chars article))
480 ;; Replace the NOV line in the NOV file. 477 ;; Replace the NOV line in the NOV file.
481 (save-excursion 478 (with-current-buffer (nnml-open-nov group)
482 (set-buffer (nnml-open-nov group))
483 (goto-char (point-min)) 479 (goto-char (point-min))
484 (if (or (looking-at art) 480 (if (or (looking-at art)
485 (search-forward (concat "\n" art) nil t)) 481 (search-forward (concat "\n" art) nil t))
486 ;; Delete the old NOV line. 482 ;; Delete the old NOV line.
487 (gnus-delete-line) 483 (gnus-delete-line)
612 (not (eq (cdr (nth 1 (assoc group nnml-group-alist))) 608 (not (eq (cdr (nth 1 (assoc group nnml-group-alist)))
613 article))))))) 609 article)))))))
614 610
615 ;; Find an article number in the current group given the Message-ID. 611 ;; Find an article number in the current group given the Message-ID.
616 (defun nnml-find-group-number (id server) 612 (defun nnml-find-group-number (id server)
617 (save-excursion 613 (with-current-buffer (get-buffer-create " *nnml id*")
618 (set-buffer (get-buffer-create " *nnml id*"))
619 (let ((alist nnml-group-alist) 614 (let ((alist nnml-group-alist)
620 number) 615 number)
621 ;; We want to look through all .overview files, but we want to 616 ;; We want to look through all .overview files, but we want to
622 ;; start with the one in the current directory. It seems most 617 ;; start with the one in the current directory. It seems most
623 ;; likely that the article we are looking for is in that group. 618 ;; likely that the article we are looking for is in that group.
655 (defun nnml-retrieve-headers-with-nov (articles &optional fetch-old) 650 (defun nnml-retrieve-headers-with-nov (articles &optional fetch-old)
656 (if (or gnus-nov-is-evil nnml-nov-is-evil) 651 (if (or gnus-nov-is-evil nnml-nov-is-evil)
657 nil 652 nil
658 (let ((nov (expand-file-name nnml-nov-file-name nnml-current-directory))) 653 (let ((nov (expand-file-name nnml-nov-file-name nnml-current-directory)))
659 (when (file-exists-p nov) 654 (when (file-exists-p nov)
660 (save-excursion 655 (with-current-buffer nntp-server-buffer
661 (set-buffer nntp-server-buffer)
662 (erase-buffer) 656 (erase-buffer)
663 (nnheader-insert-file-contents nov) 657 (nnheader-insert-file-contents nov)
664 (if (and fetch-old 658 (if (and fetch-old
665 (not (numberp fetch-old))) 659 (not (numberp fetch-old)))
666 t ; Don't remove anything. 660 t ; Don't remove anything.
802 (push (cons group buffer) nnml-incremental-nov-buffer-alist) 796 (push (cons group buffer) nnml-incremental-nov-buffer-alist)
803 buffer))) 797 buffer)))
804 798
805 (defun nnml-add-incremental-nov (group article headers) 799 (defun nnml-add-incremental-nov (group article headers)
806 "Add a nov line for the GROUP nov headers, incrementally." 800 "Add a nov line for the GROUP nov headers, incrementally."
807 (save-excursion 801 (with-current-buffer (nnml-open-incremental-nov group)
808 (set-buffer (nnml-open-incremental-nov group))
809 (goto-char (point-max)) 802 (goto-char (point-max))
810 (mail-header-set-number headers article) 803 (mail-header-set-number headers article)
811 (nnheader-insert-nov headers))) 804 (nnheader-insert-nov headers)))
812 805
813 (defun nnml-add-nov (group article headers) 806 (defun nnml-add-nov (group article headers)
814 "Add a nov line for the GROUP base." 807 "Add a nov line for the GROUP base."
815 (save-excursion 808 (with-current-buffer (nnml-open-nov group)
816 (set-buffer (nnml-open-nov group))
817 (goto-char (point-max)) 809 (goto-char (point-max))
818 (mail-header-set-number headers article) 810 (mail-header-set-number headers article)
819 (nnheader-insert-nov headers))) 811 (nnheader-insert-nov headers)))
820 812
821 (defsubst nnml-header-value () 813 (defsubst nnml-header-value ()
842 (if incrementalp 834 (if incrementalp
843 "incremental " 835 "incremental "
844 "") 836 "")
845 decoded))) 837 decoded)))
846 (file-name-coding-system nnmail-pathname-coding-system)) 838 (file-name-coding-system nnmail-pathname-coding-system))
847 (save-excursion 839 (with-current-buffer buffer
848 (set-buffer buffer)
849 (set (make-local-variable 'nnml-nov-buffer-file-name) 840 (set (make-local-variable 'nnml-nov-buffer-file-name)
850 (nnmail-group-pathname decoded nnml-directory nnml-nov-file-name)) 841 (nnmail-group-pathname decoded nnml-directory nnml-nov-file-name))
851 (erase-buffer) 842 (erase-buffer)
852 (when (and (not incrementalp) 843 (when (and (not incrementalp)
853 (file-exists-p nnml-nov-buffer-file-name)) 844 (file-exists-p nnml-nov-buffer-file-name))
885 ;; Recurse down the directories. 876 ;; Recurse down the directories.
886 (nnml-generate-nov-databases-directory nnml-directory nil t) 877 (nnml-generate-nov-databases-directory nnml-directory nil t)
887 ;; Save the active file. 878 ;; Save the active file.
888 (nnmail-save-active nnml-group-alist nnml-active-file)) 879 (nnmail-save-active nnml-group-alist nnml-active-file))
889 880
881 (defvar nnml-files)
890 (defun nnml-generate-nov-databases-directory (dir &optional seen no-active) 882 (defun nnml-generate-nov-databases-directory (dir &optional seen no-active)
891 "Regenerate the NOV database in DIR. 883 "Regenerate the NOV database in DIR.
892 884
893 Unless no-active is non-nil, update the active file too." 885 Unless no-active is non-nil, update the active file too."
894 (interactive (list (let ((file-name-coding-system 886 (interactive (list (let ((file-name-coding-system
904 (dolist (dir (directory-files dir t nil t)) 896 (dolist (dir (directory-files dir t nil t))
905 (when (and (not (string-match "^\\." (file-name-nondirectory dir))) 897 (when (and (not (string-match "^\\." (file-name-nondirectory dir)))
906 (file-directory-p dir)) 898 (file-directory-p dir))
907 (nnml-generate-nov-databases-directory dir seen))) 899 (nnml-generate-nov-databases-directory dir seen)))
908 ;; Do this directory. 900 ;; Do this directory.
909 (let ((files (sort (nnheader-article-to-file-alist dir) 901 (let ((nnml-files (sort (nnheader-article-to-file-alist dir)
910 'car-less-than-car))) 902 'car-less-than-car)))
911 (if (not files) 903 (if (not nnml-files)
912 (let* ((group (nnheader-file-to-group 904 (let* ((group (nnheader-file-to-group
913 (directory-file-name dir) nnml-directory)) 905 (directory-file-name dir) nnml-directory))
914 (info (cadr (assoc group nnml-group-alist)))) 906 (info (cadr (assoc group nnml-group-alist))))
915 (when info 907 (when info
916 (setcar info (1+ (cdr info))))) 908 (setcar info (1+ (cdr info)))))
917 (funcall nnml-generate-active-function dir) 909 (funcall nnml-generate-active-function dir)
918 ;; Generate the nov file. 910 ;; Generate the nov file.
919 (nnml-generate-nov-file dir files) 911 (nnml-generate-nov-file dir nnml-files)
920 (unless no-active 912 (unless no-active
921 (nnmail-save-active nnml-group-alist nnml-active-file))))))) 913 (nnmail-save-active nnml-group-alist nnml-active-file)))))))
922 914
923 (defvar files)
924 (defun nnml-generate-active-info (dir) 915 (defun nnml-generate-active-info (dir)
925 ;; Update the active info for this group. 916 ;; Update the active info for this group.
926 (let ((group (directory-file-name dir)) 917 (let ((group (directory-file-name dir))
927 entry last) 918 entry last)
928 (setq group (nnheader-file-to-group (nnml-encoded-group-name group) 919 (setq group (nnheader-file-to-group (nnml-encoded-group-name group)
929 nnml-directory) 920 nnml-directory)
930 entry (assoc group nnml-group-alist) 921 entry (assoc group nnml-group-alist)
931 last (or (caadr entry) 0) 922 last (or (caadr entry) 0)
932 nnml-group-alist (delq entry nnml-group-alist)) 923 nnml-group-alist (delq entry nnml-group-alist))
933 (push (list group 924 (push (list group
934 (cons (or (caar files) (1+ last)) 925 (cons (or (caar nnml-files) (1+ last))
935 (max last 926 (max last
936 (or (caar (last files)) 927 (or (caar (last nnml-files))
937 0)))) 928 0))))
938 nnml-group-alist))) 929 nnml-group-alist)))
939 930
940 (defun nnml-generate-nov-file (dir files) 931 (defun nnml-generate-nov-file (dir files)
941 (let* ((dir (file-name-as-directory dir)) 932 (let* ((dir (file-name-as-directory dir))
942 (nov (concat dir nnml-nov-file-name)) 933 (nov (concat dir nnml-nov-file-name))
943 (nov-buffer (get-buffer-create " *nov*")) 934 (nov-buffer (get-buffer-create " *nov*"))
944 chars file headers) 935 chars file headers)
945 (save-excursion 936 (with-current-buffer nov-buffer
946 ;; Init the nov buffer. 937 ;; Init the nov buffer.
947 (set-buffer nov-buffer)
948 (buffer-disable-undo) 938 (buffer-disable-undo)
949 (erase-buffer) 939 (erase-buffer)
950 (set-buffer nntp-server-buffer) 940 (set-buffer nntp-server-buffer)
951 ;; Delete the old NOV file. 941 ;; Delete the old NOV file.
952 (when (file-exists-p nov) 942 (when (file-exists-p nov)
953 (funcall nnmail-delete-file-function nov)) 943 (funcall nnmail-delete-file-function nov))
954 (while files 944 (dolist (file files)
955 (unless (file-directory-p (setq file (concat dir (cdar files)))) 945 (unless (file-directory-p (setq file (concat dir (cdr file))))
956 (erase-buffer) 946 (erase-buffer)
957 (nnheader-insert-file-contents file) 947 (nnheader-insert-file-contents file)
958 (narrow-to-region 948 (narrow-to-region
959 (goto-char (point-min)) 949 (goto-char (point-min))
960 (progn 950 (progn
961 (re-search-forward "\n\r?\n" nil t) 951 (re-search-forward "\n\r?\n" nil t)
962 (setq chars (- (point-max) (point))) 952 (setq chars (- (point-max) (point)))
963 (max (point-min) (1- (point))))) 953 (max (point-min) (1- (point)))))
964 (unless (zerop (buffer-size)) 954 (unless (zerop (buffer-size))
965 (goto-char (point-min)) 955 (goto-char (point-min))
966 (setq headers (nnml-parse-head chars (caar files))) 956 (setq headers (nnml-parse-head chars (car file)))
967 (save-excursion 957 (with-current-buffer nov-buffer
968 (set-buffer nov-buffer)
969 (goto-char (point-max)) 958 (goto-char (point-max))
970 (nnheader-insert-nov headers))) 959 (nnheader-insert-nov headers)))
971 (widen)) 960 (widen)))
972 (setq files (cdr files))) 961 (with-current-buffer nov-buffer
973 (save-excursion
974 (set-buffer nov-buffer)
975 (nnmail-write-region (point-min) (point-max) nov nil 'nomesg) 962 (nnmail-write-region (point-min) (point-max) nov nil 'nomesg)
976 (kill-buffer (current-buffer)))))) 963 (kill-buffer (current-buffer))))))
977 964
978 (defun nnml-nov-delete-article (group article) 965 (defun nnml-nov-delete-article (group article)
979 (save-excursion 966 (with-current-buffer (nnml-open-nov group)
980 (set-buffer (nnml-open-nov group))
981 (when (nnheader-find-nov-line article) 967 (when (nnheader-find-nov-line article)
982 (delete-region (point) (progn (forward-line 1) (point))) 968 (delete-region (point) (progn (forward-line 1) (point)))
983 (when (bobp) 969 (when (bobp)
984 (let ((active (cadr (assoc group nnml-group-alist))) 970 (let ((active (cadr (assoc group nnml-group-alist)))
985 num) 971 num)
1006 (expand-file-name nnml-nov-file-name dir)))) 992 (expand-file-name nnml-nov-file-name dir))))
1007 (nnheader-directory-articles dir) 993 (nnheader-directory-articles dir)
1008 ;; build list from .overview if available 994 ;; build list from .overview if available
1009 ;; We would use nnml-open-nov, except that nnml-nov-buffer-alist is 995 ;; We would use nnml-open-nov, except that nnml-nov-buffer-alist is
1010 ;; defvoo'd, and we might get called when it hasn't been swapped in. 996 ;; defvoo'd, and we might get called when it hasn't been swapped in.
1011 (save-excursion 997 (with-current-buffer (nnml-get-nov-buffer nnml-current-group)
1012 (let ((list nil) 998 (let ((list nil)
1013 art 999 art)
1014 (buffer (nnml-get-nov-buffer nnml-current-group)))
1015 (set-buffer buffer)
1016 (goto-char (point-min)) 1000 (goto-char (point-min))
1017 (while (not (eobp)) 1001 (while (not (eobp))
1018 (setq art (read (current-buffer))) 1002 (setq art (read (current-buffer)))
1019 (push art list) 1003 (push art list)
1020 (forward-line 1)) 1004 (forward-line 1))
1029 (not (file-exists-p 1013 (not (file-exists-p
1030 (expand-file-name nnml-nov-file-name 1014 (expand-file-name nnml-nov-file-name
1031 nnml-current-directory)))) 1015 nnml-current-directory))))
1032 (nnheader-article-to-file-alist nnml-current-directory) 1016 (nnheader-article-to-file-alist nnml-current-directory)
1033 ;; build list from .overview if available 1017 ;; build list from .overview if available
1034 (save-excursion 1018 (with-current-buffer (nnml-get-nov-buffer nnml-current-group)
1035 (let ((alist nil) 1019 (let ((alist nil)
1036 (buffer (nnml-get-nov-buffer nnml-current-group))
1037 art) 1020 art)
1038 (set-buffer buffer)
1039 (goto-char (point-min)) 1021 (goto-char (point-min))
1040 (while (not (eobp)) 1022 (while (not (eobp))
1041 (setq art (read (current-buffer))) 1023 (setq art (read (current-buffer)))
1042 ;; assume file name is unadorned (ie. not compressed etc) 1024 ;; assume file name is unadorned (ie. not compressed etc)
1043 (push (cons art (int-to-string art)) alist) 1025 (push (cons art (int-to-string art)) alist)
1258 (list new-number)))) 1240 (list new-number))))
1259 (push mark newmarks)) 1241 (push mark newmarks))
1260 (gnus-info-set-marks info newmarks)) 1242 (gnus-info-set-marks info newmarks))
1261 ;; 3/ Update the NOV entry for this article: 1243 ;; 3/ Update the NOV entry for this article:
1262 (unless nnml-nov-is-evil 1244 (unless nnml-nov-is-evil
1263 (save-excursion 1245 (with-current-buffer (nnml-open-nov group)
1264 (set-buffer (nnml-open-nov group))
1265 (when (nnheader-find-nov-line old-number) 1246 (when (nnheader-find-nov-line old-number)
1266 ;; Replace the article number: 1247 ;; Replace the article number:
1267 (looking-at old-number-string) 1248 (looking-at old-number-string)
1268 (replace-match new-number-string nil t) 1249 (replace-match new-number-string nil t)
1269 ;; Update the Xref header: 1250 ;; Update the Xref header: