*** empty log message ***
[gnus] / lisp / nnmh.el
index 4e5017f..25974a2 100644 (file)
@@ -48,7 +48,7 @@
 
 \f
 
-(defconst nnmh-version "nnmh 0.1"
+(defconst nnmh-version "nnmh 1.0"
   "nnmh version.")
 
 (defvar nnmh-current-directory nil
@@ -73,7 +73,7 @@
 
 ;;; Interface functions.
 
-(defun nnmh-retrieve-headers (sequence &optional newsgroup server)
+(defun nnmh-retrieve-headers (sequence &optional newsgroup server fetch-old)
   (save-excursion
     (set-buffer nntp-server-buffer)
     (erase-buffer)
     (setq nnmh-current-server server)))
 
 (defun nnmh-close-server (&optional server)
+  (setq nnmh-current-server nil)
   t)
 
 (defun nnmh-server-opened (&optional server)
     (and (stringp file)
         (file-exists-p file)
         (not (file-directory-p file))
-        (save-excursion (nnmail-find-file file)))))
+        (save-excursion (nnmail-find-file file))
+        (string-to-int (file-name-nondirectory file)))))
 
 (defun nnmh-request-group (group &optional server dont-check)
-  (and nnmh-get-new-mail (or dont-check (nnmh-get-new-mail group)))
-  (let ((pathname (nnmh-article-pathname group nnmh-directory))
+  (let ((pathname (nnmail-group-pathname group nnmh-directory))
        dir)
     (if (file-directory-p pathname)
        (progn
                                             (car dir))
                                      group))
                    (insert (format "211 0 1 0 %s\n" group))))))
-         t))))
+         t)
+      (setq nnmh-status-string "No such group")
+      nil)))
+
+(defun nnmh-request-scan (&optional group server)
+  (nnmail-get-new-mail 'nnmh nil nnmh-directory group))      
 
 (defun nnmh-request-list (&optional server dir)
   (or dir
       (save-excursion
        (set-buffer nntp-server-buffer)
        (erase-buffer)
-       (setq dir (file-name-as-directory nnmh-directory))))
+       (setq dir (file-truename (file-name-as-directory nnmh-directory)))))
   (setq dir (expand-file-name dir))
   ;; Recurse down all directories.
   (let ((dirs (and (file-readable-p dir)
             (format 
              "%s %d %d y\n" 
              (progn
-               (string-match (file-name-as-directory 
-                              (expand-file-name nnmh-directory)) dir)
+               (string-match 
+                (file-truename (file-name-as-directory 
+                                (expand-file-name nnmh-directory))) dir)
                (nnmail-replace-chars-in-string
                 (substring dir (match-end 0)) ?/ ?.))
              (apply (function max) files) 
              (apply (function min) files)))))))
   (setq nnmh-group-alist (nnmail-get-active))
-  (and server nnmh-get-new-mail (nnmh-get-new-mail))
   t)
 
 (defun nnmh-request-newgroups (date &optional server)
 (defun nnmh-request-post (&optional server)
   (mail-send-and-exit nil))
 
-(defalias 'nnmh-request-post-buffer 'nnmail-request-post-buffer)
-
 (defun nnmh-request-expire-articles (articles newsgroup &optional server force)
   (nnmh-possibly-change-directory newsgroup)
-  (let* ((days (or (and nnmail-expiry-wait-function
-                       (funcall nnmail-expiry-wait-function newsgroup))
-                  nnmail-expiry-wait))
-        (active-articles 
+  (let* ((active-articles 
          (mapcar
           (function
            (lambda (name)
              (string-to-int name)))
           (directory-files nnmh-current-directory nil "^[0-9]+$" t)))
         (max-article (and active-articles (apply 'max active-articles)))
+        (is-old t)
         article rest mod-time)
-    (while articles
+    (nnmail-activate 'nnmh)
+
+    (while (and articles is-old)
       (setq article (concat nnmh-current-directory 
                            (int-to-string (car articles))))
       (if (setq mod-time (nth 5 (file-attributes article)))
-         (if (and (or (not nnmail-keep-last-article)
-                      (not max-article)
-                      (not (= (car articles) max-article)))
-                  (or force
-                      (> (nnmail-days-between
-                          (current-time-string)
-                          (current-time-string mod-time))
-                         days)))
+         (if (and (nnmh-deletable-article-p newsgroup (car articles))
+                  (setq is-old
+                        (nnmail-expired-article-p newsgroup mod-time force)))
              (progn
-               (and gnus-verbose-backends (message "Deleting %s..." article))
+               (and gnus-verbose-backends 
+                    (message "Deleting article %s in %s..." 
+                             article newsgroup))
                (condition-case ()
-                   (delete-file article)
+                   (funcall nnmail-delete-file-function article)
                  (file-error
                   (setq rest (cons (car articles) rest)))))
            (setq rest (cons (car articles) rest))))
       (setq articles (cdr articles)))
     (message "")
-    rest))
+    (nconc rest articles)))
 
 (defun nnmh-close-group (group &optional server)
   t)
   (let ((buf (get-buffer-create " *nnmh move*"))
        result)
     (and 
+     (nnmh-deletable-article-p group article)
      (nnmh-request-article article group server)
      (save-excursion
        (set-buffer buf)
        (kill-buffer (current-buffer))
        result)
      (condition-case ()
-        (delete-file (concat nnmh-current-directory 
-                             (int-to-string article)))
+        (funcall nnmail-delete-file-function
+                 (concat nnmh-current-directory (int-to-string article)))
        (file-error nil)))
- result))
   result))
 
 (defun nnmh-request-accept-article (group &optional last)
   (if (stringp group)
       (and 
-       (nnmh-request-list)
-       (setq nnmh-group-alist (nnmail-get-active))
+       (nnmail-activate 'nnmh)
        ;; We trick the choosing function into believing that only one
        ;; group is availiable.  
        (let ((nnmail-split-methods (list (list group ""))))
         (car (nnmh-save-mail))))
     (and
-     (nnmh-request-list)
-     (setq nnmh-group-alist (nnmail-get-active))
+     (nnmail-activate 'nnmh)
      (car (nnmh-save-mail)))))
 
 (defun nnmh-request-replace-article (article group buffer)
          t)
       (error nil))))
 
+(defun nnmh-request-create-group (group &optional server) 
+  (nnmail-activate 'nnmh)
+  (or (assoc group nnmh-group-alist)
+      (let (active)
+       (setq nnmh-group-alist (cons (list group (setq active (cons 1 0)))
+                                    nnmh-group-alist))
+       (nnmh-possibly-create-directory group)
+       (nnmh-possibly-change-directory group)
+       (let ((articles (mapcar
+                        (lambda (file)
+                          (string-to-int file))
+                        (directory-files 
+                         nnmh-current-directory nil "^[0-9]+$"))))
+         (and articles
+              (progn
+                (setcar active (apply 'min articles))
+                (setcdr active (apply 'max articles)))))))
+  t)
+
+(defun nnmh-request-delete-group (group &optional force server)
+  (nnmh-possibly-change-directory group)
+  ;; Delete all articles in GROUP.
+  (if (not force)
+      ()                               ; Don't delete the articles.
+    (let ((articles (directory-files nnmh-current-directory t "^[0-9]+$")))
+      (while articles 
+       (and (file-writable-p (car articles))
+            (progn
+              (and gnus-verbose-backends
+                   (message (message "Deleting article %s in %s..."
+                                     (car articles) group)))
+              (funcall nnmail-delete-file-function (car articles))))
+       (setq articles (cdr articles))))
+    ;; Try to delete the directory itself.
+    (condition-case ()
+       (delete-directory nnmh-current-directory)
+      (error nil)))
+  ;; Remove the group from all structures.
+  (setq nnmh-group-alist 
+       (delq (assoc group nnmh-group-alist) nnmh-group-alist)
+       nnmh-current-directory nil)
+  t)
+
+(defun nnmh-request-rename-group (group new-name &optional server)
+  (nnmh-possibly-change-directory group)
+  ;; Rename directory.
+  (and (file-writable-p nnmh-current-directory)
+       (condition-case ()
+          (progn
+            (rename-file 
+             (directory-file-name nnmh-current-directory)
+             (directory-file-name 
+              (nnmail-group-pathname new-name nnmh-directory)))
+            t)
+        (error nil))
+       ;; That went ok, so we change the internal structures.
+       (let ((entry (assoc group nnmh-group-alist)))
+        (and entry (setcar entry new-name))
+        (setq nnmh-current-directory nil)
+        t)))
+
 \f
 ;;; Internal functions.
 
 (defun nnmh-possibly-change-directory (newsgroup)
   (if newsgroup
-      (let ((pathname (nnmh-article-pathname newsgroup nnmh-directory)))
+      (let ((pathname (nnmail-group-pathname newsgroup nnmh-directory)))
        (if (file-directory-p pathname)
            (setq nnmh-current-directory pathname)
          (error "No such newsgroup: %s" newsgroup)))))
 
 (defun nnmh-possibly-create-directory (group)
   (let (dir dirs)
-    (setq dir (nnmail-article-pathname group nnmh-directory))
+    (setq dir (nnmail-group-pathname group nnmh-directory))
     (while (not (file-directory-p dir))
       (setq dirs (cons dir dirs))
       (setq dir (file-name-directory (directory-file-name dir))))
             
 (defun nnmh-save-mail ()
   "Called narrowed to an article."
-  (let ((group-art (nreverse (nnmail-article-group 'nnmh-active-number)))
-       chars nov-line lines hbeg hend)
-    (setq chars (nnmail-insert-lines))
+  (let ((group-art (nreverse (nnmail-article-group 'nnmh-active-number))))
+    (nnmail-insert-lines)
     (nnmail-insert-xref group-art)
     (run-hooks 'nnmh-prepare-save-mail-hook)
     (goto-char (point-min))
          first)
       (while ga
        (nnmh-possibly-create-directory (car (car ga)))
-       (let ((file (concat (nnmh-article-pathname 
+       (let ((file (concat (nnmail-group-pathname 
                             (car (car ga)) nnmh-directory) 
                            (int-to-string (cdr (car ga))))))
          (if first
 (defun nnmh-active-number (group)
   "Compute the next article number in GROUP."
   (let ((active (car (cdr (assoc group nnmh-group-alist)))))
+    ;; The group wasn't known to nnmh, so we just create an active
+    ;; entry for it.   
+    (or active
+       (progn
+         (setq active (cons 1 0))
+         (setq nnmh-group-alist (cons (list group active) nnmh-group-alist))))
     (setcdr active (1+ (cdr active)))
-    (let (file)
-      (while (file-exists-p
-             (setq file (concat (nnmh-article-pathname 
-                                 group nnmh-directory)
-                                (int-to-string (cdr active)))))
-       (setcdr active (1+ (cdr active)))))
+    (while (file-exists-p
+           (concat (nnmail-group-pathname group nnmh-directory)
+                   (int-to-string (cdr active))))
+      (setcdr active (1+ (cdr active))))
     (cdr active)))
 
-(defun nnmh-article-pathname (group mail-dir)
-  "Make pathname for GROUP."
-  (let ((mail-dir (file-name-as-directory (expand-file-name mail-dir))))
-    (if (file-directory-p (concat mail-dir group))
-       (concat mail-dir group "/")
-      (concat mail-dir (nnmail-replace-chars-in-string group ?. ?/) "/"))))
-
-(defun nnmh-get-new-mail (&optional group)
-  "Read new incoming mail."
-  (let* ((spools (nnmail-get-spool-files group))
-        (all-spools spools)
-        (group-in group)
-        incoming incomings)
-    (if (or (not nnmh-get-new-mail) (not nnmail-spool-file))
-       ()
-      ;; We first activate all the groups.
-      (or nnmh-group-alist
-         (nnmh-request-list))
-      ;; The we go through all the existing spool files and split the
-      ;; mail from each.
-      (while spools
-       (and
-        (file-exists-p (car spools))
-        (> (nth 7 (file-attributes (car spools))) 0)
-        (progn
-          (and gnus-verbose-backends 
-               (message "nnmh: Reading incoming mail..."))
-          (setq incoming 
-                (nnmail-move-inbox 
-                 (car spools) (concat nnmh-directory "Incoming")))
-          (setq incomings (cons incoming incomings))
-          (setq group (nnmail-get-split-group (car spools) group-in))
-          (nnmail-split-incoming incoming 'nnmh-save-mail nil group)))
-       (setq spools (cdr spools)))
-      ;; If we did indeed read any incoming spools, we save all info. 
-      (if incoming 
-         (message "nnmh: Reading incoming mail...done"))
-      (while incomings
-       (and nnmail-delete-incoming
-            (file-writable-p incoming)
-            (delete-file incoming))
-       (setq incomings (cdr incomings))))))
-      
-
 (defun nnmh-update-gnus-unreads (group)
   ;; Go through the .nnmh-articles file and compare with the actual
   ;; articles in this folder. The articles that are "new" will be
       (write-region (point-min) (point-max) nnmh-file nil 'nomesg)
       (kill-buffer (current-buffer)))))
 
+(defun nnmh-deletable-article-p (group article)
+  "Say whether ARTICLE in GROUP can be deleted."
+  (or (not nnmail-keep-last-article)
+      (not (eq (cdr (nth 1 (assoc group nnmh-group-alist))) article))))
+
 (provide 'nnmh)
 
 ;;; nnmh.el ends here