X-Git-Url: http://cgit.sxemacs.org/?p=gnus;a=blobdiff_plain;f=lisp%2Fnnml.el;h=c42ad58c1338c1b2259f0fe1f0708608b5182e0c;hp=89c97ee9b95edc4883104726baa08e30604f044e;hb=d0498ec691ac9cc3f6bdd9f4ba3ac26457cc3d8a;hpb=a3628c5a6916f7584ac6c1e8177140dd5cbd9680 diff --git a/lisp/nnml.el b/lisp/nnml.el index 89c97ee9b..c42ad58c1 100644 --- a/lisp/nnml.el +++ b/lisp/nnml.el @@ -54,11 +54,11 @@ (defvoo nnml-nov-is-evil nil "If non-nil, Gnus will never generate and use nov databases for mail groups. Using nov databases will speed up header fetching considerably. -This variable shouldn't be flipped much. If you have, for some reason, +This variable shouldn't be flipped much. If you have, for some reason, set this to t, and want to set it to nil again, you should always run -the `nnml-generate-nov-databases' command. The function will go +the `nnml-generate-nov-databases' command. The function will go through all nnml directories and generate nov databases for them -all. This may very well take some time.") +all. This may very well take some time.") (defvoo nnml-prepare-save-mail-hook nil "Hook run narrowed to an article before saving.") @@ -161,22 +161,18 @@ all. This may very well take some time.") (deffoo nnml-request-article (id &optional newsgroup server buffer) (nnml-possibly-change-directory newsgroup server) (let* ((nntp-server-buffer (or buffer nntp-server-buffer)) - file path gpath group-num) + path gpath group-num) (if (stringp id) (when (and (setq group-num (nnml-find-group-number id)) - (setq file (cdr - (assq (cdr group-num) - (nnheader-article-to-file-alist - (setq gpath - (nnmail-group-pathname - (car group-num) - nnml-directory))))))) + (cdr + (assq (cdr group-num) + (nnheader-article-to-file-alist + (setq gpath + (nnmail-group-pathname + (car group-num) + nnml-directory)))))) (setq path (concat gpath (int-to-string (cdr group-num))))) - (unless nnml-article-file-alist - (setq nnml-article-file-alist - (nnheader-article-to-file-alist nnml-current-directory))) - (when (setq file (cdr (assq id nnml-article-file-alist))) - (setq path (concat nnml-current-directory file)))) + (setq path (nnml-article-to-file id))) (cond ((not path) (nnheader-report 'nnml "No such article: %s" id)) @@ -195,6 +191,9 @@ all. This may very well take some time.") (cond ((not (nnml-possibly-change-directory group server)) (nnheader-report 'nnml "Invalid group (no such directory)")) + ((not (file-exists-p nnml-current-directory)) + (nnheader-report 'nnml "Directory %s does not exist" + nnml-current-directory)) ((not (file-directory-p nnml-current-directory)) (nnheader-report 'nnml "%s is not a directory" nnml-current-directory)) (dont-check @@ -218,21 +217,19 @@ all. This may very well take some time.") (setq nnml-article-file-alist nil) t) -(deffoo nnml-request-create-group (group &optional server) +(deffoo nnml-request-create-group (group &optional server args) (nnmail-activate 'nnml) - (or (assoc group nnml-group-alist) - (let (active) - (setq nnml-group-alist (cons (list group (setq active (cons 1 0))) - nnml-group-alist)) - (nnml-possibly-create-directory group) - (nnml-possibly-change-directory group server) - (let ((articles - (nnheader-directory-articles nnml-current-directory ))) - (and articles - (progn - (setcar active (apply 'min articles)) - (setcdr active (apply 'max articles))))) - (nnmail-save-active nnml-group-alist nnml-active-file))) + (unless (assoc group nnml-group-alist) + (let (active) + (push (list group (setq active (cons 1 0))) + nnml-group-alist) + (nnml-possibly-create-directory group) + (nnml-possibly-change-directory group server) + (let ((articles (nnheader-directory-articles nnml-current-directory))) + (when articles + (setcar active (apply 'min articles)) + (setcdr active (apply 'max articles)))) + (nnmail-save-active nnml-group-alist nnml-active-file))) t) (deffoo nnml-request-list (&optional server) @@ -323,16 +320,15 @@ all. This may very well take some time.") (if (stringp group) (and (nnmail-activate 'nnml) - ;; We trick the choosing function into believing that only one - ;; group is available. - (let ((nnmail-split-methods (list (list group "")))) - (setq result (car (nnml-save-mail)))) + (setq result (car (nnml-save-mail + (list (cons group (nnml-active-number group)))))) (progn (nnmail-save-active nnml-group-alist nnml-active-file) (and last (nnml-save-nov)))) (and (nnmail-activate 'nnml) - (setq result (car (nnml-save-mail))) + (setq result (car (nnml-save-mail + (nnmail-article-group 'nnml-active-number)))) (progn (nnmail-save-active nnml-group-alist nnml-active-file) (and last (nnml-save-nov))))) @@ -348,9 +344,10 @@ all. This may very well take some time.") headers) (when (condition-case () (progn - (write-region + (nnmail-write-region (point-min) (point-max) - (concat nnml-current-directory (int-to-string article)) + (concat nnml-current-directory + (int-to-string article)) nil (if (nnheader-be-verbose 5) nil 'nomesg)) t) (error nil)) @@ -365,7 +362,7 @@ all. This may very well take some time.") (delete-region (progn (beginning-of-line) (point)) (progn (forward-line 1) (point))) ;; The line isn't here, so we have to find out where - ;; we should insert it. (This situation should never + ;; we should insert it. (This situation should never ;; occur, but one likes to make sure...) (while (and (looking-at "[0-9]+\t") (< (string-to-int @@ -408,33 +405,62 @@ all. This may very well take some time.") (deffoo nnml-request-rename-group (group new-name &optional server) (nnml-possibly-change-directory group server) - ;; Rename directory. - (and (file-writable-p nnml-current-directory) - (condition-case () - (let ((parent - (file-name-directory - (directory-file-name - (nnmail-group-pathname new-name nnml-directory))))) - (unless (file-exists-p parent) - (make-directory parent t)) - (rename-file - (directory-file-name nnml-current-directory) - (directory-file-name - (nnmail-group-pathname new-name nnml-directory))) - t) - (error nil)) - ;; That went ok, so we change the internal structures. - (let ((entry (assoc group nnml-group-alist))) - (and entry (setcar entry new-name)) - (setq nnml-current-directory nil - nnml-current-group nil) - ;; Save the new group alist. - (nnmail-save-active nnml-group-alist nnml-active-file) - t))) + (let ((new-dir (nnmail-group-pathname new-name nnml-directory)) + (old-dir (nnmail-group-pathname group nnml-directory))) + (when (condition-case () + (progn + (make-directory new-dir t) + t) + (error nil)) + ;; We move the articles file by file instead of renaming + ;; the directory -- there may be subgroups in this group. + ;; One might be more clever, I guess. + (let ((files (nnheader-article-to-file-alist old-dir))) + (while files + (rename-file + (concat old-dir (cdar files)) + (concat new-dir (cdar files))) + (pop files))) + ;; Move .overview file. + (let ((overview (concat old-dir nnml-nov-file-name))) + (when (file-exists-p overview) + (rename-file overview (concat new-dir nnml-nov-file-name)))) + (when (<= (length (directory-files old-dir)) 2) + (condition-case () + (delete-directory old-dir) + (error nil))) + ;; That went ok, so we change the internal structures. + (let ((entry (assoc group nnml-group-alist))) + (and entry (setcar entry new-name)) + (setq nnml-current-directory nil + nnml-current-group nil) + ;; Save the new group alist. + (nnmail-save-active nnml-group-alist nnml-active-file) + t)))) + +(deffoo nnml-set-status (article name value &optional group server) + (nnml-possibly-change-directory group server) + (let ((file (nnml-article-to-file article))) + (cond + ((not (file-exists-p file)) + (nnheader-report 'nnml "File %s does not exist" file)) + (t + (nnheader-temp-write file + (nnheader-insert-file-contents-literally file) + (nnmail-replace-status name value)) + t)))) ;;; Internal functions. +(defun nnml-article-to-file (article) + (unless nnml-article-file-alist + (setq nnml-article-file-alist + (nnheader-article-to-file-alist nnml-current-directory))) + (let (file) + (when (setq file (cdr (assq article nnml-article-file-alist))) + (concat nnml-current-directory file)))) + (defun nnml-deletable-article-p (group article) "Say whether ARTICLE in GROUP can be deleted." (let (file path) @@ -540,10 +566,9 @@ all. This may very well take some time.") (nnheader-message 5 "Creating mail directory %s" (car dirs)) (setq dirs (cdr dirs))))) -(defun nnml-save-mail () +(defun nnml-save-mail (group-art) "Called narrowed to an article." - (let ((group-art (nreverse (nnmail-article-group 'nnml-active-number))) - chars headers) + (let (chars headers) (setq chars (nnmail-insert-lines)) (nnmail-insert-xref group-art) (run-hooks 'nnmail-prepare-save-mail-hook) @@ -564,11 +589,11 @@ all. This may very well take some time.") ;; It was already saved, so we just make a hard link. (funcall nnmail-crosspost-link-function first file t) ;; Save the article. - (write-region (point-min) (point-max) file nil - (if (nnheader-be-verbose 5) nil 'nomesg)) + (nnmail-write-region (point-min) (point-max) file nil + (if (nnheader-be-verbose 5) nil 'nomesg)) (setq first file))) (setq ga (cdr ga)))) - ;; Generate a nov line for this article. We generate the nov + ;; Generate a nov line for this article. We generate the nov ;; line after saving, because nov generation destroys the ;; header. (setq headers (nnml-parse-head chars)) @@ -654,9 +679,8 @@ all. This may very well take some time.") (while nnml-nov-buffer-alist (when (buffer-name (cdar nnml-nov-buffer-alist)) (set-buffer (cdar nnml-nov-buffer-alist)) - (and (buffer-modified-p) - (write-region - 1 (point-max) (buffer-file-name) nil 'nomesg)) + (when (buffer-modified-p) + (nnmail-write-region 1 (point-max) (buffer-file-name) nil 'nomesg)) (set-buffer-modified-p nil) (kill-buffer (current-buffer))) (setq nnml-nov-buffer-alist (cdr nnml-nov-buffer-alist))))) @@ -714,7 +738,7 @@ all. This may very well take some time.") (let* ((dir (file-name-as-directory dir)) (nov (concat dir nnml-nov-file-name)) (nov-buffer (get-buffer-create " *nov*")) - nov-line chars file headers) + chars file headers) (save-excursion ;; Init the nov buffer. (set-buffer nov-buffer) @@ -747,8 +771,7 @@ all. This may very well take some time.") (setq files (cdr files))) (save-excursion (set-buffer nov-buffer) - (write-region 1 (point-max) (expand-file-name nov) nil - 'nomesg) + (nnmail-write-region 1 (point-max) nov nil 'nomesg) (kill-buffer (current-buffer)))))) (defun nnml-nov-delete-article (group article)