diff lisp/gnus/nndraft.el @ 0:376386a54a3c r19-14

Import from CVS: tag r19-14
author cvs
date Mon, 13 Aug 2007 08:45:50 +0200
parents
children 0293115a14e9
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/gnus/nndraft.el	Mon Aug 13 08:45:50 2007 +0200
@@ -0,0 +1,248 @@
+;;; nndraft.el --- draft article access for Gnus
+;; Copyright (C) 1995,96 Free Software Foundation, Inc.
+
+;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+;; Keywords: news
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'nnheader)
+(require 'nnmh)
+(require 'nnoo)
+(eval-and-compile (require 'cl))
+
+(nnoo-declare nndraft)
+
+(eval-and-compile
+  (autoload 'mail-send-and-exit "sendmail"))
+
+(defvoo nndraft-directory nil
+  "Where nndraft will store its directory.")
+
+
+
+(defconst nndraft-version "nndraft 1.0")
+(defvoo nndraft-status-string "")
+
+
+
+;;; Interface functions.
+
+(nnoo-define-basics nndraft)
+
+(deffoo nndraft-retrieve-headers (articles &optional group server fetch-old)
+  (save-excursion
+    (set-buffer nntp-server-buffer)
+    (erase-buffer)
+    (let* ((buf (get-buffer-create " *draft headers*"))
+	   article)
+      (set-buffer buf)
+      (buffer-disable-undo (current-buffer))
+      (erase-buffer)
+      ;; We don't support fetching by Message-ID.
+      (if (stringp (car articles))
+	  'headers
+	(while articles
+	  (set-buffer buf)
+	  (when (nndraft-request-article 
+		 (setq article (pop articles)) group server (current-buffer))
+	    (goto-char (point-min))
+	    (if (search-forward "\n\n" nil t)
+		(forward-line -1)
+	      (goto-char (point-max)))
+	    (delete-region (point) (point-max))
+	    (set-buffer nntp-server-buffer)
+	    (goto-char (point-max))
+	    (insert (format "221 %d Article retrieved.\n" article))
+	    (insert-buffer-substring buf)
+	    (insert ".\n")))
+
+	(nnheader-fold-continuation-lines)
+	'headers))))
+
+(deffoo nndraft-open-server (server &optional defs)
+  (nnoo-change-server 'nndraft server defs)
+  (unless (assq 'nndraft-directory defs)
+    (setq nndraft-directory server))
+  (cond 
+   ((not (file-exists-p nndraft-directory))
+    (nndraft-close-server)
+    (nnheader-report 'nndraft "No such file or directory: %s"
+		     nndraft-directory))
+   ((not (file-directory-p (file-truename nndraft-directory)))
+    (nndraft-close-server)
+    (nnheader-report 'nndraft "Not a directory: %s" nndraft-directory))
+   (t
+    (nnheader-report 'nndraft "Opened server %s using directory %s"
+		     server nndraft-directory)
+    t)))
+
+(deffoo nndraft-request-article (id &optional group server buffer)
+  (when (numberp id)
+    ;; We get the newest file of the auto-saved file and the 
+    ;; "real" file.
+    (let* ((file (nndraft-article-filename id))
+	   (auto (nndraft-auto-save-file-name file))
+	   (newest (if (file-newer-than-file-p file auto) file auto))
+	   (nntp-server-buffer (or buffer nntp-server-buffer)))
+      (when (and (file-exists-p newest)
+		 (nnmail-find-file newest))
+	(save-excursion 
+	  (set-buffer nntp-server-buffer)
+	  (goto-char (point-min))
+	  ;; If there's a mail header separator in this file, 
+	  ;; we remove it.
+	  (when (re-search-forward
+		 (concat "^" mail-header-separator "$") nil t)
+	    (replace-match "" t t)))
+	t))))
+
+(deffoo nndraft-request-restore-buffer (article &optional group server)
+  "Request a new buffer that is restored to the state of ARTICLE."
+  (let ((file (nndraft-article-filename article ".state"))
+	nndraft-point nndraft-mode nndraft-buffer-name)
+    (when (file-exists-p file)
+      (load file t t t)
+      (when nndraft-buffer-name
+	(set-buffer (get-buffer-create
+		     (generate-new-buffer-name nndraft-buffer-name)))
+	(nndraft-request-article article group server (current-buffer))
+	(funcall nndraft-mode)
+	(let ((gnus-verbose-backends nil))
+	  (nndraft-request-expire-articles (list article) group server t))
+	(goto-char nndraft-point))
+      nndraft-buffer-name)))
+
+(deffoo nndraft-request-update-info (group info &optional server)
+  (setcar (cddr info) nil)
+  (when (nth 3 info)
+    (setcar (nthcdr 3 info) nil))
+  t)
+
+(deffoo nndraft-request-associate-buffer (group)
+  "Associate the current buffer with some article in the draft group."
+  (let* ((gnus-verbose-backends nil)
+	 (article (cdr (nndraft-request-accept-article
+			group (nnoo-current-server 'nndraft) t 'noinsert)))
+	 (file (nndraft-article-filename article)))
+    (setq buffer-file-name file)
+    (setq buffer-auto-save-file-name (make-auto-save-file-name))
+    (clear-visited-file-modtime)
+    article))
+
+(deffoo nndraft-request-group (group &optional server dont-check)
+  (prog1
+      (nndraft-execute-nnmh-command
+       `(nnmh-request-group group "" ,dont-check))
+    (nnheader-report 'nndraft nnmh-status-string)))
+
+(deffoo nndraft-request-list (&optional server dir)
+  (nndraft-execute-nnmh-command
+   `(nnmh-request-list nil ,dir)))
+
+(deffoo nndraft-request-newgroups (date &optional server)
+  (nndraft-execute-nnmh-command
+   `(nnmh-request-newgroups ,date ,server)))
+
+(deffoo nndraft-request-expire-articles 
+  (articles group &optional server force)
+  (let ((res (nndraft-execute-nnmh-command
+	      `(nnmh-request-expire-articles
+		',articles group ,server ,force)))
+	article)
+    ;; Delete all the "state" files of articles that have been expired.
+    (while articles
+      (unless (memq (setq article (pop articles)) res)
+	(let ((file (nndraft-article-filename article ".state"))
+	      (auto (nndraft-auto-save-file-name
+		     (nndraft-article-filename article))))
+	  (when (file-exists-p file)
+	    (funcall nnmail-delete-file-function file))
+	  (when (file-exists-p auto)
+	    (funcall nnmail-delete-file-function auto)))))
+    res))
+
+(deffoo nndraft-request-accept-article (group &optional server last noinsert)
+  (let* ((point (point))
+	 (mode major-mode)
+	 (name (buffer-name))
+	 (gnus-verbose-backends nil)
+	 (gart (nndraft-execute-nnmh-command
+		`(nnmh-request-accept-article group ,server ,last noinsert)))
+	 (state
+	  (nndraft-article-filename (cdr gart) ".state")))
+    ;; Write the "state" file.
+    (save-excursion
+      (nnheader-set-temp-buffer " *draft state*")
+      (insert (format "%S\n" `(setq nndraft-mode (quote ,mode)
+				    nndraft-point ,point
+				    nndraft-buffer-name ,name)))
+      (write-region (point-min) (point-max) state nil 'silent)
+      (kill-buffer (current-buffer)))
+    gart))
+
+(deffoo nndraft-close-group (group &optional server)
+  t)
+
+(deffoo nndraft-request-create-group (group &optional server)
+  (if (file-exists-p nndraft-directory)
+      (if (file-directory-p nndraft-directory)
+	  t
+	nil)
+    (condition-case ()
+	(progn
+	  (make-directory nndraft-directory t)
+	  t)
+      (file-error nil))))
+
+
+;;; Low-Level Interface
+
+(defun nndraft-execute-nnmh-command (command)
+  (let ((dir (expand-file-name nndraft-directory)))
+    (and (string-match "/$" dir)
+	 (setq dir (substring dir 0 (match-beginning 0))))
+    (string-match "/[^/]+$" dir)
+    (let ((group (substring dir (1+ (match-beginning 0))))
+          (nnmh-directory (substring dir 0 (1+ (match-beginning 0))))
+	  (nnmail-keep-last-article nil)
+	  (nnmh-get-new-mail nil))
+      (eval command))))
+
+(defun nndraft-article-filename (article &rest args)
+  (apply 'concat
+	 (file-name-as-directory nndraft-directory)
+	 (int-to-string article)
+	 args))
+
+(defun nndraft-auto-save-file-name (file)
+  (save-excursion
+    (prog1
+	(progn
+	  (set-buffer (get-buffer-create " *draft tmp*"))
+	  (setq buffer-file-name file)
+	  (make-auto-save-file-name))
+      (kill-buffer (current-buffer)))))
+
+(provide 'nndraft)
+
+;;; nndraft.el ends here