From: Katsumi Yamaoka Date: Fri, 20 Jul 2007 11:30:51 +0000 (+0000) Subject: * gnus-agent.el (gnus-agent-group-pathname): Take notice of the method. X-Git-Url: http://cgit.sxemacs.org/?p=gnus;a=commitdiff_plain;h=7693ad423659f409f95c3faea25a601c954375e6 * gnus-agent.el (gnus-agent-group-pathname): Take notice of the method. * gnus-art.el (article-decode-group-name): Decode Xref header too. * gnus-group.el (gnus-group-make-group): Encode group name here unless the new optional argument ENCODED is non-nil. (gnus-group-make-doc-group): Use gnus-group-name-charset to determine coding system for encoding group name. (gnus-group-make-rss-group): Pass un-encoded group name to gnus-group-make-group. (gnus-group-set-info): Tell gnus-group-make-group that group name is encoded. * gnus-sum.el (gnus-summary-move-article, gnus-read-move-group-name): Encode group name to which articles are moved or copied. (gnus-summary-edit-article): Use gnus-group-name-charset to determine coding system for encoding Newsgroup, Followup-To and Xref headers. * nnagent.el (nnagent-request-set-mark): Use unibyte buffer to compose marks; use nnheader-file-coding-system to write a file. (nnagent-retrieve-headers): Bind file-name-coding-system to nnmail-pathname-coding-system. * nnmail.el (nnmail-insert-xref): Don't break non-ASCII group name. * nnml.el (nnml-decoded-group-name, nnml-group-pathname): New functions. (nnml-request-article, nnml-request-create-group) (nnml-request-rename-group, nnml-find-id) (nnml-possibly-change-directory, nnml-possibly-create-directory) (nnml-save-mail, nnml-active-number, nnml-marks-changed-p) (nnml-save-marks): Use nnml-group-pathname instead of nnmail-group-pathname. (nnml-request-create-group, nnml-request-expire-articles) (nnml-request-move-article, nnml-request-delete-group) (nnml-deletable-article-p, nnml-possibly-create-directory) (nnml-get-nov-buffer, nnml-generate-nov-databases-directory) (nnml-open-marks): Bind file-name-coding-system to nnmail-pathname-coding-system. (nnml-request-article): Pass server argument to nnml-find-group-number. (nnml-request-create-group, nnml-active-number, nnml-save-marks): Pass server argument to nnml-possibly-create-directory. (nnml-request-accept-article): Pass server argument to nnml-active-number and nnml-save-mail. (nnml-find-group-number): Pass server argument to nnml-find-id. (nnml-request-update-info): Pass server argument to nnml-marks-changed-p. (nnml-find-id, nnml-find-group-number, nnml-possibly-create-directory) (nnml-save-mail, nnml-active-number): Add server argument. (nnml-request-delete-group): Warn if group is missing. (nnml-get-nov-buffer): Decode group name. (nnml-generate-active-info): Encode group name. (nnml-open-marks): Decode group name in messages. --- diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 97f18b356..dd3fad083 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,62 @@ +2007-07-20 Katsumi Yamaoka + + * gnus-agent.el (gnus-agent-group-pathname): Take notice of the method. + + * gnus-art.el (article-decode-group-name): Decode Xref header too. + + * gnus-group.el (gnus-group-make-group): Encode group name here unless + the new optional argument ENCODED is non-nil. + (gnus-group-make-doc-group): Use gnus-group-name-charset to determine + coding system for encoding group name. + (gnus-group-make-rss-group): Pass un-encoded group name to + gnus-group-make-group. + (gnus-group-set-info): Tell gnus-group-make-group that group name is + encoded. + + * gnus-sum.el (gnus-summary-move-article, gnus-read-move-group-name): + Encode group name to which articles are moved or copied. + (gnus-summary-edit-article): Use gnus-group-name-charset to determine + coding system for encoding Newsgroup, Followup-To and Xref headers. + + * nnagent.el (nnagent-request-set-mark): Use unibyte buffer to compose + marks; use nnheader-file-coding-system to write a file. + (nnagent-retrieve-headers): Bind file-name-coding-system to + nnmail-pathname-coding-system. + + * nnmail.el (nnmail-insert-xref): Don't break non-ASCII group name. + + * nnml.el (nnml-decoded-group-name, nnml-group-pathname): New functions. + (nnml-request-article, nnml-request-create-group) + (nnml-request-rename-group, nnml-find-id) + (nnml-possibly-change-directory, nnml-possibly-create-directory) + (nnml-save-mail, nnml-active-number, nnml-marks-changed-p) + (nnml-save-marks): Use nnml-group-pathname instead of + nnmail-group-pathname. + + (nnml-request-create-group, nnml-request-expire-articles) + (nnml-request-move-article, nnml-request-delete-group) + (nnml-deletable-article-p, nnml-possibly-create-directory) + (nnml-get-nov-buffer, nnml-generate-nov-databases-directory) + (nnml-open-marks): Bind file-name-coding-system to + nnmail-pathname-coding-system. + + (nnml-request-article): Pass server argument to nnml-find-group-number. + (nnml-request-create-group, nnml-active-number, nnml-save-marks): Pass + server argument to nnml-possibly-create-directory. + (nnml-request-accept-article): Pass server argument to + nnml-active-number and nnml-save-mail. + (nnml-find-group-number): Pass server argument to nnml-find-id. + (nnml-request-update-info): Pass server argument to + nnml-marks-changed-p. + + (nnml-find-id, nnml-find-group-number, nnml-possibly-create-directory) + (nnml-save-mail, nnml-active-number): Add server argument. + + (nnml-request-delete-group): Warn if group is missing. + (nnml-get-nov-buffer): Decode group name. + (nnml-generate-active-info): Encode group name. + (nnml-open-marks): Decode group name in messages. + 2007-07-19 Katsumi Yamaoka * gnus-art.el (gnus-article-part-wrapper): Work with the nearest part diff --git a/lisp/gnus-agent.el b/lisp/gnus-agent.el index 6681b71e8..d2dd0552b 100644 --- a/lisp/gnus-agent.el +++ b/lisp/gnus-agent.el @@ -1451,9 +1451,11 @@ downloaded into the agent." ;; while plugged. (let ((gnus-command-method (or gnus-command-method (gnus-find-method-for-group group)))) - (nnmail-group-pathname (gnus-group-real-name - (gnus-group-decoded-name group)) - (gnus-agent-directory)))) + (nnmail-group-pathname + (gnus-group-real-name + (mm-decode-coding-string + group (gnus-group-name-charset gnus-command-method group))) + (gnus-agent-directory)))) (defun gnus-agent-get-function (method) (if (gnus-online method) diff --git a/lisp/gnus-art.el b/lisp/gnus-art.el index 25db92bdd..95608860f 100644 --- a/lisp/gnus-art.el +++ b/lisp/gnus-art.el @@ -2525,44 +2525,31 @@ If PROMPT (the prefix), prompt for a coding system to use." (goto-char (setq end start))))) (defun article-decode-group-name () - "Decode group names in `Newsgroups:'." + "Decode group names in Newsgroups, Followup-To and Xref headers." (let ((inhibit-point-motion-hooks t) (inhibit-read-only t) - (method (gnus-find-method-for-group gnus-newsgroup-name))) + (method (gnus-find-method-for-group gnus-newsgroup-name)) + regexp) (when (and (or gnus-group-name-charset-method-alist gnus-group-name-charset-group-alist) (gnus-buffer-live-p gnus-original-article-buffer)) (save-restriction (article-narrow-to-head) - (with-current-buffer gnus-original-article-buffer - (goto-char (point-min))) - (while (re-search-forward - "^Newsgroups:\\(\\(.\\|\n[\t ]\\)*\\)\n[^\t ]" nil t) - (replace-match (save-match-data - (gnus-decode-newsgroups - ;; XXX how to use data in article buffer? - (with-current-buffer gnus-original-article-buffer - (re-search-forward - "^Newsgroups:\\(\\(.\\|\n[\t ]\\)*\\)\n[^\t ]" - nil t) - (match-string 1)) - gnus-newsgroup-name method)) - t t nil 1)) - (goto-char (point-min)) - (with-current-buffer gnus-original-article-buffer - (goto-char (point-min))) - (while (re-search-forward - "^Followup-To:\\(\\(.\\|\n[\t ]\\)*\\)\n[^\t ]" nil t) - (replace-match (save-match-data - (gnus-decode-newsgroups - ;; XXX how to use data in article buffer? - (with-current-buffer gnus-original-article-buffer - (re-search-forward - "^Followup-To:\\(\\(.\\|\n[\t ]\\)*\\)\n[^\t ]" - nil t) - (match-string 1)) - gnus-newsgroup-name method)) - t t nil 1)))))) + (dolist (header '("Newsgroups" "Followup-To" "Xref")) + (with-current-buffer gnus-original-article-buffer + (goto-char (point-min))) + (setq regexp (concat "^" header + ":\\([^\n]*\\(?:\n[\t ]+[^\n]+\\)*\\)\n")) + (while (re-search-forward regexp nil t) + (replace-match (save-match-data + (gnus-decode-newsgroups + ;; XXX how to use data in article buffer? + (with-current-buffer gnus-original-article-buffer + (re-search-forward regexp nil t) + (match-string 1)) + gnus-newsgroup-name method)) + t t nil 1)) + (goto-char (point-min))))))) (autoload 'idna-to-unicode "idna") diff --git a/lisp/gnus-group.el b/lisp/gnus-group.el index e0bfd9c6f..c647bfc47 100644 --- a/lisp/gnus-group.el +++ b/lisp/gnus-group.el @@ -2457,10 +2457,11 @@ The user will be prompted for GROUP." (gnus-group-real-name group) (gnus-group-server group))) -(defun gnus-group-make-group (name &optional method address args) +(defun gnus-group-make-group (name &optional method address args encoded) "Add a new newsgroup. The user will be prompted for a NAME, for a select METHOD, and an -ADDRESS." +ADDRESS. NAME should be a human-readable string (i.e., not be encoded +even if it contains non-ASCII characters) unless ENCODED is non-nil." (interactive (list (gnus-read-group "Group name: ") @@ -2468,6 +2469,10 @@ ADDRESS." (when (stringp method) (setq method (or (gnus-server-to-method method) method))) + (unless encoded + (setq name (mm-encode-coding-string + name + (gnus-group-name-charset method name)))) (let* ((meth (gnus-method-simplify (when (and method (not (gnus-server-equal method gnus-select-method))) @@ -2759,19 +2764,17 @@ If called with a prefix argument, ask for the file type." nil)))) (setq type found))) (setq file (expand-file-name file)) - (let ((name (gnus-generate-new-group-name - (gnus-group-prefixed-name - (file-name-nondirectory file) '(nndoc "")))) - (encodable (mm-coding-system-p 'utf-8))) + (let* ((name (gnus-generate-new-group-name + (gnus-group-prefixed-name + (file-name-nondirectory file) '(nndoc "")))) + (method (list 'nndoc file + (list 'nndoc-address file) + (list 'nndoc-article-type (or type 'guess)))) + (coding (gnus-group-name-charset method name))) + (setcar (cdr method) (mm-encode-coding-string file coding)) (gnus-group-make-group - (if encodable - (mm-encode-coding-string (gnus-group-real-name name) 'utf-8) - (gnus-group-real-name name)) - (list 'nndoc (if encodable - (mm-encode-coding-string file 'utf-8) - file) - (list 'nndoc-address file) - (list 'nndoc-article-type (or type 'guess)))))) + (mm-encode-coding-string (gnus-group-real-name name) coding) + method nil nil t))) (defvar nnweb-type-definition) (defvar gnus-group-web-type-history nil) @@ -2825,25 +2828,23 @@ If there is, use Gnus to create an nnrss group" (setq url (read-from-minibuffer "URL to Search for RSS: "))) (let ((feedinfo (nnrss-discover-feed url))) (if feedinfo - (let ((title (gnus-newsgroup-savable-name - (read-from-minibuffer "Title: " - (gnus-newsgroup-savable-name - (or (cdr (assoc 'title - feedinfo)) - ""))))) - (desc (read-from-minibuffer "Description: " - (cdr (assoc 'description - feedinfo)))) - (href (cdr (assoc 'href feedinfo))) - (encodable (mm-coding-system-p 'utf-8))) - (when encodable + (let* ((title (gnus-newsgroup-savable-name + (read-from-minibuffer "Title: " + (gnus-newsgroup-savable-name + (or (cdr (assoc 'title + feedinfo)) + ""))))) + (desc (read-from-minibuffer "Description: " + (cdr (assoc 'description + feedinfo)))) + (href (cdr (assoc 'href feedinfo))) + (coding (gnus-group-name-charset '(nnrss "") title))) + (when coding ;; Unify non-ASCII text. (setq title (mm-decode-coding-string - (mm-encode-coding-string title 'utf-8) 'utf-8))) - (gnus-group-make-group (if encodable - (mm-encode-coding-string title 'utf-8) - title) - '(nnrss "")) + (mm-encode-coding-string title coding) + coding))) + (gnus-group-make-group title '(nnrss "")) (push (list title href desc) nnrss-group-alist) (nnrss-save-server-data nil)) (error "No feeds found for %s" url)))) @@ -4313,9 +4314,10 @@ and the second element is the address." (if (stringp method) method (prin1-to-string (car method))) (and (consp method) - (nth 1 (gnus-info-method info)))) + (nth 1 (gnus-info-method info))) + nil t) ;; It's a native group. - (gnus-group-make-group (gnus-info-group info)))) + (gnus-group-make-group (gnus-info-group info) nil nil nil t))) (gnus-message 6 "Note: New group created") (setq entry (gnus-group-entry (gnus-group-prefixed-name diff --git a/lisp/gnus-sum.el b/lisp/gnus-sum.el index d9fa84f74..707ad3b82 100644 --- a/lisp/gnus-sum.el +++ b/lisp/gnus-sum.el @@ -9502,7 +9502,8 @@ ACTION can be either `move' (the default), `crosspost' or `copy'." (crosspost "Crosspost" "Crossposting"))) (copy-buf (save-excursion (nnheader-set-temp-buffer " *copy article*"))) - art-group to-method new-xref article to-groups articles-to-update-marks) + art-group to-method new-xref article to-groups + articles-to-update-marks encoded) (unless (assq action names) (error "Unknown action %s" action)) ;; Read the newsgroup name. @@ -9520,15 +9521,25 @@ ACTION can be either `move' (the default), `crosspost' or `copy'." (gnus-article-prepare-hook nil) (gnus-mark-article-hook nil)) (gnus-summary-select-article nil nil nil (car articles)))) - (setq to-newsgroup - (gnus-read-move-group-name - (cadr (assq action names)) - (symbol-value (intern (format "gnus-current-%s-group" action))) - articles prefix)) - (set (intern (format "gnus-current-%s-group" action)) to-newsgroup)) - (setq to-method (or select-method - (gnus-server-to-method - (gnus-group-method to-newsgroup)))) + (setq to-newsgroup (gnus-read-move-group-name + (cadr (assq action names)) + (symbol-value + (intern (format "gnus-current-%s-group" action))) + articles prefix) + encoded to-newsgroup + to-method (gnus-server-to-method (gnus-group-method to-newsgroup))) + (set (intern (format "gnus-current-%s-group" action)) + (mm-decode-coding-string + to-newsgroup + (gnus-group-name-charset to-method to-newsgroup)))) + (unless to-method + (setq to-method (or select-method + (gnus-server-to-method + (gnus-group-method to-newsgroup))))) + (setq to-newsgroup (or encoded + (mm-encode-coding-string + to-newsgroup + (gnus-group-name-charset to-method to-newsgroup)))) ;; Check the method we are to move this article to... (unless (gnus-check-backend-function 'request-accept-article (car to-method)) @@ -9537,7 +9548,9 @@ ACTION can be either `move' (the default), `crosspost' or `copy'." (error "Can't open server %s" (car to-method))) (gnus-message 6 "%s to %s: %s..." (caddr (assq action names)) - (or (car select-method) to-newsgroup) articles) + (or (car select-method) + (gnus-group-decoded-name to-newsgroup)) + articles) (while articles (setq article (pop articles)) (setq @@ -10069,7 +10082,16 @@ groups." (message-options message-options) (message-options-set-recipient) (mail-parse-ignored-charsets - ',gnus-newsgroup-ignored-charsets)) + ',gnus-newsgroup-ignored-charsets) + (rfc2047-header-encoding-alist + ',(let ((charset (gnus-group-name-charset + (gnus-find-method-for-group + gnus-newsgroup-name) + gnus-newsgroup-name))) + (append (list (cons "Newsgroups" charset) + (cons "Followup-To" charset) + (cons "Xref" charset)) + rfc2047-header-encoding-alist)))) ,(if (not raw) '(progn (mml-to-mime) (mml-destroy-buffers) @@ -11699,24 +11721,27 @@ save those articles instead." (mapcar 'list (nreverse split-name)) nil nil nil 'gnus-group-history)))) - (to-method (gnus-server-to-method (gnus-group-method to-newsgroup)))) + (to-method (gnus-server-to-method (gnus-group-method to-newsgroup))) + encoded) (when to-newsgroup (if (or (string= to-newsgroup "") (string= to-newsgroup prefix)) (setq to-newsgroup default)) (unless to-newsgroup (error "No group name entered")) - (or (gnus-active to-newsgroup) - (gnus-activate-group to-newsgroup nil nil to-method) + (setq encoded (mm-encode-coding-string + to-newsgroup + (gnus-group-name-charset to-method to-newsgroup))) + (or (gnus-active encoded) + (gnus-activate-group encoded nil nil to-method) (if (gnus-y-or-n-p (format "No such group: %s. Create it? " to-newsgroup)) - (or (and (gnus-request-create-group to-newsgroup to-method) - (gnus-activate-group - to-newsgroup nil nil to-method) - (gnus-subscribe-group to-newsgroup)) + (or (and (gnus-request-create-group encoded to-method) + (gnus-activate-group encoded nil nil to-method) + (gnus-subscribe-group encoded)) (error "Couldn't create group %s" to-newsgroup))) - (error "No such group: %s" to-newsgroup))) - to-newsgroup)) + (error "No such group: %s" to-newsgroup)) + encoded))) (defvar gnus-summary-save-parts-counter) diff --git a/lisp/nnagent.el b/lisp/nnagent.el index 6f53528b4..62bb398b4 100644 --- a/lisp/nnagent.el +++ b/lisp/nnagent.el @@ -121,7 +121,7 @@ (gnus-request-accept-article "nndraft:queue" nil t t)) (deffoo nnagent-request-set-mark (group action server) - (with-temp-buffer + (mm-with-unibyte-buffer (insert "(gnus-agent-synchronize-group-flags \"" group "\" '") @@ -130,8 +130,9 @@ (gnus-method-to-server gnus-command-method) "\"") (insert ")\n") - (write-region (point-min) (point-max) (gnus-agent-lib-file "flags") - t 'silent)) + (let ((coding-system-for-write nnheader-file-coding-system)) + (write-region (point-min) (point-max) (gnus-agent-lib-file "flags") + t 'silent))) ;; Also set the marks for the original back end that keeps marks in ;; the local system. (let ((gnus-agent nil)) @@ -157,7 +158,8 @@ (pop arts))) (set-buffer nntp-server-buffer) (erase-buffer) - (nnheader-insert-nov-file file (car articles)) + (let ((file-name-coding-system nnmail-pathname-coding-system)) + (nnheader-insert-nov-file file (car articles))) (goto-char (point-min)) (gnus-parse-without-error (while (and arts (not (eobp))) diff --git a/lisp/nnmail.el b/lisp/nnmail.el index 52623c0d6..48905a38a 100644 --- a/lisp/nnmail.el +++ b/lisp/nnmail.el @@ -1244,11 +1244,11 @@ Return the number of characters in the body." (progn (forward-line 1) (point)))) (insert (format "Xref: %s" (system-name))) (while group-alist - (insert (format " %s:%d" - (mm-encode-coding-string - (caar group-alist) - nnmail-pathname-coding-system) - (cdar group-alist))) + (insert (if (mm-multibyte-p) + (mm-string-as-multibyte + (format " %s:%d" (caar group-alist) (cdar group-alist))) + (mm-string-as-unibyte + (format " %s:%d" (caar group-alist) (cdar group-alist))))) (setq group-alist (cdr group-alist))) (insert "\n"))) diff --git a/lisp/nnml.el b/lisp/nnml.el index 08610c1fb..d85a17ca1 100644 --- a/lisp/nnml.el +++ b/lisp/nnml.el @@ -129,6 +129,25 @@ non-nil.") (nnoo-define-basics nnml) +(defun nnml-decoded-group-name (group &optional server-or-method) + "Return a decoded group name of GROUP on SERVER-OR-METHOD." + (mm-decode-coding-string + group + (gnus-group-name-charset + (if (stringp server-or-method) + (gnus-server-to-method + (if (string-match "\\+" server-or-method) + (concat (substring server-or-method 0 (match-beginning 0)) + ":" (substring server-or-method (match-end 0))) + (concat "nnml:" server-or-method))) + (or server-or-method gnus-command-method '(nnml ""))) + group))) + +(defun nnml-group-pathname (group &optional file server) + "Return an absolute file name of FILE for GROUP on SERVER." + (nnmail-group-pathname (nnml-decoded-group-name group server) + nnml-directory file)) + (deffoo nnml-retrieve-headers (sequence &optional group server fetch-old) (when (nnml-possibly-change-directory group server) (save-excursion @@ -201,14 +220,12 @@ non-nil.") (file-name-coding-system nnmail-pathname-coding-system) path gpath group-num) (if (stringp id) - (when (and (setq group-num (nnml-find-group-number id)) + (when (and (setq group-num (nnml-find-group-number id server)) (cdr (assq (cdr group-num) (nnheader-article-to-file-alist - (setq gpath - (nnmail-group-pathname - (car group-num) - nnml-directory)))))) + (setq gpath (nnml-group-pathname (car group-num) + nil server)))))) (setq path (concat gpath (int-to-string (cdr group-num))))) (setq path (nnml-article-to-file id))) (cond @@ -265,23 +282,23 @@ non-nil.") (nnml-possibly-change-directory nil server) (nnmail-activate 'nnml) (cond - ((let ((file (directory-file-name - (nnmail-group-pathname group nnml-directory)))) + ((let ((file (directory-file-name (nnml-group-pathname group nil server))) + (file-name-coding-system nnmail-pathname-coding-system)) (and (file-exists-p file) (not (file-directory-p file)))) (nnheader-report 'nnml "%s is a file" - (directory-file-name - (let ((nnmail-pathname-coding-system nil)) - (nnmail-group-pathname group nnml-directory))))) + (directory-file-name (nnml-group-pathname group + nil server)))) ((assoc group nnml-group-alist) t) (t (let (active) (push (list group (setq active (cons 1 0))) nnml-group-alist) - (nnml-possibly-create-directory group) + (nnml-possibly-create-directory group server) (nnml-possibly-change-directory group server) - (let ((articles (nnml-directory-articles nnml-current-directory))) + (let* ((file-name-coding-system nnmail-pathname-coding-system) + (articles (nnml-directory-articles nnml-current-directory))) (when articles (setcar active (apply 'min articles)) (setcdr active (apply 'max articles)))) @@ -305,10 +322,11 @@ non-nil.") (deffoo nnml-request-expire-articles (articles group &optional server force) (nnml-possibly-change-directory group server) - (let ((active-articles - (nnml-directory-articles nnml-current-directory)) - (is-old t) - article rest mod-time number target) + (let* ((file-name-coding-system nnmail-pathname-coding-system) + (active-articles + (nnml-directory-articles nnml-current-directory)) + (is-old t) + article rest mod-time number target) (nnmail-activate 'nnml) (setq active-articles (sort active-articles '<)) @@ -365,6 +383,7 @@ non-nil.") (deffoo nnml-request-move-article (article group server accept-form &optional last move-is-internal) (let ((buf (get-buffer-create " *nnml move*")) + (file-name-coding-system nnmail-pathname-coding-system) result) (nnml-possibly-change-directory group server) (nnml-update-file-alist) @@ -405,16 +424,20 @@ non-nil.") (and (nnmail-activate 'nnml) (setq result (car (nnml-save-mail - (list (cons group (nnml-active-number group)))))) + (list (cons group (nnml-active-number group + server))) + server))) (progn (nnmail-save-active nnml-group-alist nnml-active-file) (and last (nnml-save-nov)))) (and (nnmail-activate 'nnml) - (if (and (not (setq result (nnmail-article-group 'nnml-active-number))) + (if (and (not (setq result (nnmail-article-group + `(lambda (group) + (nnml-active-number group ,server))))) (yes-or-no-p "Moved to `junk' group; delete article? ")) (setq result 'junk) - (setq result (car (nnml-save-mail result)))) + (setq result (car (nnml-save-mail result server)))) (when last (nnmail-save-active nnml-group-alist nnml-active-file) (when nnmail-cache-accepted-message-ids @@ -466,33 +489,42 @@ non-nil.") (deffoo nnml-request-delete-group (group &optional force server) (nnml-possibly-change-directory group server) - (when force - ;; Delete all articles in GROUP. - (let ((articles - (directory-files - nnml-current-directory t - (concat nnheader-numerical-short-files - "\\|" (regexp-quote nnml-nov-file-name) "$" - "\\|" (regexp-quote nnml-marks-file-name) "$")))) - (dolist (article articles) - (when (file-writable-p article) - (nnheader-message 5 "Deleting article %s in %s..." article group) - (funcall nnmail-delete-file-function article)))) - ;; Try to delete the directory itself. - (ignore-errors (delete-directory nnml-current-directory))) - ;; Remove the group from all structures. - (setq nnml-group-alist - (delq (assoc group nnml-group-alist) nnml-group-alist) - nnml-current-group nil - nnml-current-directory nil) - ;; Save the active file. - (nnmail-save-active nnml-group-alist nnml-active-file) + (let ((file (directory-file-name nnml-current-directory)) + (file-name-directory nnmail-pathname-coding-system)) + (if (file-exists-p file) + (if (file-directory-p file) + (progn + (when force + ;; Delete all articles in GROUP. + (let ((articles + (directory-files + nnml-current-directory t + (concat + nnheader-numerical-short-files + "\\|" (regexp-quote nnml-nov-file-name) "$" + "\\|" (regexp-quote nnml-marks-file-name) "$")))) + (dolist (article articles) + (when (file-writable-p article) + (nnheader-message 5 "Deleting article %s in %s..." + article group) + (funcall nnmail-delete-file-function article)))) + ;; Try to delete the directory itself. + (ignore-errors (delete-directory nnml-current-directory)))) + (nnheader-report 'nnml "%s is not a directory" file)) + (nnheader-report 'nnml "No such directory: %s/" file)) + ;; Remove the group from all structures. + (setq nnml-group-alist + (delq (assoc group nnml-group-alist) nnml-group-alist) + nnml-current-group nil + nnml-current-directory nil) + ;; Save the active file. + (nnmail-save-active nnml-group-alist nnml-active-file)) t) (deffoo nnml-request-rename-group (group new-name &optional server) (nnml-possibly-change-directory group server) - (let ((new-dir (nnmail-group-pathname new-name nnml-directory)) - (old-dir (nnmail-group-pathname group nnml-directory))) + (let ((new-dir (nnml-group-pathname new-name nil server)) + (old-dir (nnml-group-pathname group nil server))) (when (ignore-errors (make-directory new-dir t) t) @@ -557,7 +589,8 @@ non-nil.") (defun nnml-deletable-article-p (group article) "Say whether ARTICLE in GROUP can be deleted." - (let (path) + (let ((file-name-coding-system nnmail-pathname-coding-system) + path) (when (setq path (nnml-article-to-file article)) (when (file-writable-p path) (or (not nnmail-keep-last-article) @@ -565,7 +598,7 @@ non-nil.") article))))))) ;; Find an article number in the current group given the Message-ID. -(defun nnml-find-group-number (id) +(defun nnml-find-group-number (id server) (save-excursion (set-buffer (get-buffer-create " *nnml id*")) (let ((alist nnml-group-alist) @@ -573,22 +606,21 @@ non-nil.") ;; We want to look through all .overview files, but we want to ;; start with the one in the current directory. It seems most ;; likely that the article we are looking for is in that group. - (if (setq number (nnml-find-id nnml-current-group id)) + (if (setq number (nnml-find-id nnml-current-group id server)) (cons nnml-current-group number) ;; It wasn't there, so we look through the other groups as well. (while (and (not number) alist) (or (string= (caar alist) nnml-current-group) - (setq number (nnml-find-id (caar alist) id))) + (setq number (nnml-find-id (caar alist) id server))) (or number (setq alist (cdr alist)))) (and number (cons (caar alist) number)))))) -(defun nnml-find-id (group id) +(defun nnml-find-id (group id server) (erase-buffer) - (let ((nov (expand-file-name nnml-nov-file-name - (nnmail-group-pathname group nnml-directory))) + (let ((nov (nnml-group-pathname group nnml-nov-file-name server)) number found) (when (file-exists-p nov) (nnheader-insert-file-contents nov) @@ -629,7 +661,7 @@ non-nil.") (nnml-open-server server)) (if (not group) t - (let ((pathname (nnmail-group-pathname group nnml-directory)) + (let ((pathname (nnml-group-pathname group nil server)) (file-name-coding-system nnmail-pathname-coding-system)) (when (not (equal pathname nnml-current-directory)) (setq nnml-current-directory pathname @@ -637,13 +669,14 @@ non-nil.") nnml-article-file-alist nil)) (file-exists-p nnml-current-directory)))) -(defun nnml-possibly-create-directory (group) - (let ((dir (nnmail-group-pathname group nnml-directory))) +(defun nnml-possibly-create-directory (group &optional server) + (let ((dir (nnml-group-pathname group nil server)) + (file-name-coding-system nnmail-pathname-coding-system)) (unless (file-exists-p dir) (make-directory (directory-file-name dir) t) (nnheader-message 5 "Creating mail directory %s" dir)))) -(defun nnml-save-mail (group-art) +(defun nnml-save-mail (group-art &optional server) "Called narrowed to an article." (let (chars headers extension) (setq chars (nnmail-insert-lines)) @@ -664,11 +697,10 @@ non-nil.") (let ((ga group-art) first) (while ga - (nnml-possibly-create-directory (caar ga)) - (let ((file (concat (nnmail-group-pathname - (caar ga) nnml-directory) - (int-to-string (cdar ga)) - extension))) + (nnml-possibly-create-directory (caar ga) server) + (let ((file (nnml-group-pathname + (caar ga) (concat (int-to-string (cdar ga)) extension) + server))) (if first ;; It was already saved, so we just make a hard link. (funcall nnmail-crosspost-link-function first file t) @@ -688,7 +720,7 @@ non-nil.") (setq ga (cdr ga)))) group-art)) -(defun nnml-active-number (group) +(defun nnml-active-number (group &optional server) "Compute the next article number in GROUP." (let ((active (cadr (assoc group nnml-group-alist)))) ;; The group wasn't known to nnml, so we just create an active @@ -696,7 +728,7 @@ non-nil.") (unless active ;; Perhaps the active file was corrupt? See whether ;; there are any articles in this group. - (nnml-possibly-create-directory group) + (nnml-possibly-create-directory group server) (nnml-possibly-change-directory group) (unless nnml-article-file-alist (setq nnml-article-file-alist @@ -711,8 +743,7 @@ non-nil.") (push (list group active) nnml-group-alist)) (setcdr active (1+ (cdr active))) (while (file-exists-p - (expand-file-name (int-to-string (cdr active)) - (nnmail-group-pathname group nnml-directory))) + (nnml-group-pathname group (int-to-string (cdr active)) server)) (setcdr active (1+ (cdr active)))) (cdr active))) @@ -743,13 +774,13 @@ non-nil.") headers)))) (defun nnml-get-nov-buffer (group) - (let ((buffer (get-buffer-create (format " *nnml overview %s*" group)))) + (let* ((decoded (nnml-decoded-group-name group)) + (buffer (get-buffer-create (format " *nnml overview %s*" decoded))) + (file-name-coding-system nnmail-pathname-coding-system)) (save-excursion (set-buffer buffer) (set (make-local-variable 'nnml-nov-buffer-file-name) - (expand-file-name - nnml-nov-file-name - (nnmail-group-pathname group nnml-directory))) + (nnmail-group-pathname decoded nnml-directory nnml-nov-file-name)) (erase-buffer) (when (file-exists-p nnml-nov-buffer-file-name) (nnheader-insert-file-contents nnml-nov-buffer-file-name))) @@ -792,39 +823,48 @@ non-nil.") "Regenerate the NOV database in DIR. Unless no-active is non-nil, update the active file too." - (interactive "DRegenerate NOV in: ") + (interactive (list (let ((file-name-coding-system + nnmail-pathname-coding-system)) + (read-directory-name "Regenerate NOV in: " + nnml-directory nil t)))) (setq dir (file-name-as-directory dir)) - ;; Only scan this sub-tree if we haven't been here yet. - (unless (member (file-truename dir) seen) - (push (file-truename dir) seen) - ;; We descend recursively - (dolist (dir (directory-files dir t nil t)) - (when (and (not (string-match "^\\." (file-name-nondirectory dir))) - (file-directory-p dir)) - (nnml-generate-nov-databases-directory dir seen))) - ;; Do this directory. - (let ((files (sort (nnheader-article-to-file-alist dir) - 'car-less-than-car))) - (if (not files) - (let* ((group (nnheader-file-to-group - (directory-file-name dir) nnml-directory)) - (info (cadr (assoc group nnml-group-alist)))) - (when info - (setcar info (1+ (cdr info))))) - (funcall nnml-generate-active-function dir) - ;; Generate the nov file. - (nnml-generate-nov-file dir files) - (unless no-active - (nnmail-save-active nnml-group-alist nnml-active-file)))))) + (let ((file-name-coding-system nnmail-pathname-coding-system)) + ;; Only scan this sub-tree if we haven't been here yet. + (unless (member (file-truename dir) seen) + (push (file-truename dir) seen) + ;; We descend recursively + (dolist (dir (directory-files dir t nil t)) + (when (and (not (string-match "^\\." (file-name-nondirectory dir))) + (file-directory-p dir)) + (nnml-generate-nov-databases-directory dir seen))) + ;; Do this directory. + (let ((files (sort (nnheader-article-to-file-alist dir) + 'car-less-than-car))) + (if (not files) + (let* ((group (nnheader-file-to-group + (directory-file-name dir) nnml-directory)) + (info (cadr (assoc group nnml-group-alist)))) + (when info + (setcar info (1+ (cdr info))))) + (funcall nnml-generate-active-function dir) + ;; Generate the nov file. + (nnml-generate-nov-file dir files) + (unless no-active + (nnmail-save-active nnml-group-alist nnml-active-file))))))) (eval-when-compile (defvar files)) (defun nnml-generate-active-info (dir) ;; Update the active info for this group. - (let* ((group (nnheader-file-to-group - (directory-file-name dir) nnml-directory)) - (entry (assoc group nnml-group-alist)) - (last (or (caadr entry) 0))) - (setq nnml-group-alist (delq entry nnml-group-alist)) + (let ((group (directory-file-name dir)) + entry last) + (setq group (nnheader-file-to-group + (mm-encode-coding-string + group + (gnus-group-name-charset '(nnml "") group)) + nnml-directory) + entry (assoc group nnml-group-alist) + last (or (caadr entry) 0) + nnml-group-alist (delq entry nnml-group-alist)) (push (list group (cons (or (caar files) (1+ last)) (max last @@ -961,7 +1001,7 @@ Use the nov database for the current group if available." (deffoo nnml-request-update-info (group info &optional server) (nnml-possibly-change-directory group server) - (when (and (not nnml-marks-is-evil) (nnml-marks-changed-p group)) + (when (and (not nnml-marks-is-evil) (nnml-marks-changed-p group server)) (nnheader-message 8 "Updating marks for %s..." group) (nnml-open-marks group server) ;; Update info using `nnml-marks'. @@ -984,9 +1024,8 @@ Use the nov database for the current group if available." (nnheader-message 8 "Updating marks for %s...done" group)) info) -(defun nnml-marks-changed-p (group) - (let ((file (expand-file-name nnml-marks-file-name - (nnmail-group-pathname group nnml-directory)))) +(defun nnml-marks-changed-p (group server) + (let ((file (nnml-group-pathname group nnml-marks-file-name server))) (if (null (gnus-gethash file nnml-marks-modtime)) t ;; never looked at marks file, assume it has changed (not (equal (gnus-gethash file nnml-marks-modtime) @@ -994,11 +1033,10 @@ Use the nov database for the current group if available." (defun nnml-save-marks (group server) (let ((file-name-coding-system nnmail-pathname-coding-system) - (file (expand-file-name nnml-marks-file-name - (nnmail-group-pathname group nnml-directory)))) + (file (nnml-group-pathname group nnml-marks-file-name server))) (condition-case err (progn - (nnml-possibly-create-directory group) + (nnml-possibly-create-directory group server) (with-temp-file file (erase-buffer) (gnus-prin1 nnml-marks) @@ -1011,9 +1049,10 @@ Use the nov database for the current group if available." (error "Cannot write to %s (%s)" file err)))))) (defun nnml-open-marks (group server) - (let ((file (expand-file-name - nnml-marks-file-name - (nnmail-group-pathname group nnml-directory)))) + (let* ((decoded (nnml-decoded-group-name group server)) + (file (nnmail-group-pathname decoded nnml-directory + nnml-marks-file-name)) + (file-name-coding-system nnmail-pathname-coding-system)) (if (file-exists-p file) (condition-case err (with-temp-buffer @@ -1031,14 +1070,18 @@ Use the nov database for the current group if available." (let ((info (gnus-get-info (gnus-group-prefixed-name group - (gnus-server-to-method (format "nnml:%s" server)))))) - (nnheader-message 7 "Bootstrapping marks for %s..." group) + (gnus-server-to-method + (format "nnml:%s" (or server ""))))))) + (setq decoded (if (member server '(nil "")) + (concat "nnml:" decoded) + (format "nnml+%s:%s" server decoded))) + (nnheader-message 7 "Bootstrapping marks for %s..." decoded) (setq nnml-marks (gnus-info-marks info)) (push (cons 'read (gnus-info-read info)) nnml-marks) (dolist (el gnus-article-unpropagated-mark-lists) (setq nnml-marks (gnus-remassoc el nnml-marks))) (nnml-save-marks group server) - (nnheader-message 7 "Bootstrapping marks for %s...done" group))))) + (nnheader-message 7 "Bootstrapping marks for %s...done" decoded))))) ;;;