comparison lisp/gnus/nneething.el @ 88155:d7ddb3e565de

sync with trunk
author Henrik Enberg <henrik.enberg@telia.com>
date Mon, 16 Jan 2006 00:03:54 +0000
parents 7782e54757bb
children
comparison
equal deleted inserted replaced
88154:8ce476d3ba36 88155:d7ddb3e565de
1 ;;; nneething.el --- arbitrary file access for Gnus 1 ;;; nneething.el --- arbitrary file access for Gnus
2 2
3 ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000 3 ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
4 ;; Free Software Foundation, Inc. 4 ;; 2004, 2005 Free Software Foundation, Inc.
5 5
6 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org> 6 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
7 ;; Masanobu UMEDA <umerin@flab.flab.fujitsu.junet> 7 ;; Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
8 ;; Keywords: news, mail 8 ;; Keywords: news, mail
9 9
10 ;; This file is part of GNU Emacs. 10 ;; This file is part of GNU Emacs.
11 11
12 ;; GNU Emacs is free software; you can redistribute it and/or modify 12 ;; GNU Emacs is free software; you can redistribute it and/or modify
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ;; GNU General Public License for more details. 20 ;; GNU General Public License for more details.
21 21
22 ;; You should have received a copy of the GNU General Public License 22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs; see the file COPYING. If not, write to the 23 ;; along with GNU Emacs; see the file COPYING. If not, write to the
24 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, 24 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25 ;; Boston, MA 02111-1307, USA. 25 ;; Boston, MA 02110-1301, USA.
26 26
27 ;;; Commentary: 27 ;;; Commentary:
28 28
29 ;;; Code: 29 ;;; Code:
30 30
35 (require 'nnoo) 35 (require 'nnoo)
36 (require 'gnus-util) 36 (require 'gnus-util)
37 37
38 (nnoo-declare nneething) 38 (nnoo-declare nneething)
39 39
40 (defvoo nneething-map-file-directory "~/.nneething/" 40 (defvoo nneething-map-file-directory
41 (nnheader-concat gnus-directory ".nneething/")
41 "Where nneething stores the map files.") 42 "Where nneething stores the map files.")
42 43
43 (defvoo nneething-map-file ".nneething" 44 (defvoo nneething-map-file ".nneething"
44 "Name of the map files.") 45 "Name of the map files.")
45 46
62 (defvoo nneething-current-directory nil 63 (defvoo nneething-current-directory nil
63 "Current news group directory.") 64 "Current news group directory.")
64 65
65 (defvoo nneething-status-string "") 66 (defvoo nneething-status-string "")
66 67
67 (defvoo nneething-message-id-number 0)
68 (defvoo nneething-work-buffer " *nneething work*") 68 (defvoo nneething-work-buffer " *nneething work*")
69 69
70 (defvoo nneething-group nil) 70 (defvoo nneething-group nil)
71 (defvoo nneething-map nil) 71 (defvoo nneething-map nil)
72 (defvoo nneething-read-only nil) 72 (defvoo nneething-read-only nil)
120 (deffoo nneething-request-article (id &optional group server buffer) 120 (deffoo nneething-request-article (id &optional group server buffer)
121 (nneething-possibly-change-directory group) 121 (nneething-possibly-change-directory group)
122 (let ((file (unless (stringp id) 122 (let ((file (unless (stringp id)
123 (nneething-file-name id))) 123 (nneething-file-name id)))
124 (nntp-server-buffer (or buffer nntp-server-buffer))) 124 (nntp-server-buffer (or buffer nntp-server-buffer)))
125 (and (stringp file) ; We did not request by Message-ID. 125 (and (stringp file) ; We did not request by Message-ID.
126 (file-exists-p file) ; The file exists. 126 (file-exists-p file) ; The file exists.
127 (not (file-directory-p file)) ; It's not a dir. 127 (not (file-directory-p file)) ; It's not a dir.
128 (save-excursion 128 (save-excursion
129 (nnmail-find-file file) ; Insert the file in the nntp buf. 129 (let ((nnmail-file-coding-system 'binary))
130 (nnmail-find-file file)) ; Insert the file in the nntp buf.
130 (unless (nnheader-article-p) ; Either it's a real article... 131 (unless (nnheader-article-p) ; Either it's a real article...
131 (goto-char (point-min)) 132 (let ((type
132 (nneething-make-head 133 (unless (file-directory-p file)
133 file (current-buffer)) ; ... or we fake some headers. 134 (or (cdr (assoc (concat "." (file-name-extension file))
135 mailcap-mime-extensions))
136 "text/plain")))
137 (charset
138 (mm-detect-mime-charset-region (point-min) (point-max)))
139 (encoding))
140 (unless (string-match "\\`text/" type)
141 (base64-encode-region (point-min) (point-max))
142 (setq encoding "base64"))
143 (goto-char (point-min))
144 (nneething-make-head file (current-buffer)
145 nil type charset encoding))
134 (insert "\n")) 146 (insert "\n"))
135 t)))) 147 t))))
136 148
137 (deffoo nneething-request-group (group &optional server dont-check) 149 (deffoo nneething-request-group (group &optional server dont-check)
138 (nneething-possibly-change-directory group server) 150 (nneething-possibly-change-directory group server)
232 ;; Remove deleted files from the map. 244 ;; Remove deleted files from the map.
233 (let ((map nneething-map) 245 (let ((map nneething-map)
234 prev) 246 prev)
235 (while map 247 (while map
236 (if (and (member (cadr (car map)) files) 248 (if (and (member (cadr (car map)) files)
237 ;; We also remove files that have changed mod times. 249 ;; We also remove files that have changed mod times.
238 (equal (nth 5 (file-attributes 250 (equal (nth 5 (file-attributes
239 (nneething-file-name (cadr (car map))))) 251 (nneething-file-name (cadr (car map)))))
240 (cadr (cdar map)))) 252 (cadr (cdar map))))
241 (progn 253 (progn
242 (push (cadr (car map)) map-files) 254 (push (cadr (car map)) map-files)
270 "Insert the head of FILE." 282 "Insert the head of FILE."
271 (when (nneething-get-head file) 283 (when (nneething-get-head file)
272 (insert-buffer-substring nneething-work-buffer) 284 (insert-buffer-substring nneething-work-buffer)
273 (goto-char (point-max)))) 285 (goto-char (point-max))))
274 286
275 (defun nneething-make-head (file &optional buffer) 287 (defun nneething-encode-file-name (file &optional coding-system)
288 "Encode the name of the FILE in CODING-SYSTEM."
289 (let ((pos 0) buf)
290 (setq file (mm-encode-coding-string
291 file (or coding-system nnmail-pathname-coding-system)))
292 (while (string-match "[^-0-9a-zA-Z_:/.]" file pos)
293 (setq buf (cons (format "%%%02x" (aref file (match-beginning 0)))
294 (cons (substring file pos (match-beginning 0)) buf))
295 pos (match-end 0)))
296 (apply (function concat)
297 (nreverse (cons (substring file pos) buf)))))
298
299 (defun nneething-decode-file-name (file &optional coding-system)
300 "Decode the name of the FILE is encoded in CODING-SYSTEM."
301 (let ((pos 0) buf)
302 (while (string-match "%\\([0-9a-fA-F][0-9a-fA-F]\\)" file pos)
303 (setq buf (cons (string (string-to-number (match-string 1 file) 16))
304 (cons (substring file pos (match-beginning 0)) buf))
305 pos (match-end 0)))
306 (decode-coding-string
307 (apply (function concat)
308 (nreverse (cons (substring file pos) buf)))
309 (or coding-system nnmail-pathname-coding-system))))
310
311 (defun nneething-get-file-name (id)
312 "Extract the file name from the message ID string."
313 (when (string-match "\\`<nneething-\\([^@]+\\)@.*>\\'" id)
314 (nneething-decode-file-name (match-string 1 id))))
315
316 (defun nneething-make-head (file &optional buffer extra-msg
317 mime-type mime-charset mime-encoding)
276 "Create a head by looking at the file attributes of FILE." 318 "Create a head by looking at the file attributes of FILE."
277 (let ((atts (file-attributes file))) 319 (let ((atts (file-attributes file)))
278 (insert 320 (insert
279 "Subject: " (file-name-nondirectory file) "\n" 321 "Subject: " (file-name-nondirectory file) (or extra-msg "") "\n"
280 "Message-ID: <nneething-" 322 "Message-ID: <nneething-" (nneething-encode-file-name file)
281 (int-to-string (incf nneething-message-id-number))
282 "@" (system-name) ">\n" 323 "@" (system-name) ">\n"
283 (if (equal '(0 0) (nth 5 atts)) "" 324 (if (equal '(0 0) (nth 5 atts)) ""
284 (concat "Date: " (current-time-string (nth 5 atts)) "\n")) 325 (concat "Date: " (current-time-string (nth 5 atts)) "\n"))
285 (or (when buffer 326 (or (when buffer
286 (save-excursion 327 (save-excursion
287 (set-buffer buffer) 328 (set-buffer buffer)
288 (when (re-search-forward "<[a-zA-Z0-9_]@[-a-zA-Z0-9_]>" 1000 t) 329 (when (re-search-forward "<[a-zA-Z0-9_]@[-a-zA-Z0-9_]>" 1000 t)
289 (concat "From: " (match-string 0) "\n")))) 330 (concat "From: " (match-string 0) "\n"))))
290 (nneething-from-line (nth 2 atts) file)) 331 (nneething-from-line (nth 2 atts) file))
291 (if (> (string-to-int (int-to-string (nth 7 atts))) 0) 332 (if (> (string-to-number (int-to-string (nth 7 atts))) 0)
292 (concat "Chars: " (int-to-string (nth 7 atts)) "\n") 333 (concat "Chars: " (int-to-string (nth 7 atts)) "\n")
293 "") 334 "")
294 (if buffer 335 (if buffer
295 (save-excursion 336 (save-excursion
296 (set-buffer buffer) 337 (set-buffer buffer)
297 (concat "Lines: " (int-to-string 338 (concat "Lines: " (int-to-string
298 (count-lines (point-min) (point-max))) 339 (count-lines (point-min) (point-max)))
299 "\n")) 340 "\n"))
341 "")
342 (if mime-type
343 (concat "Content-Type: " mime-type
344 (if mime-charset
345 (concat "; charset="
346 (if (stringp mime-charset)
347 mime-charset
348 (symbol-name mime-charset)))
349 "")
350 (if mime-encoding
351 (concat "\nContent-Transfer-Encoding: " mime-encoding)
352 "")
353 "\nMIME-Version: 1.0\n")
300 "")))) 354 ""))))
301 355
302 (defun nneething-from-line (uid &optional file) 356 (defun nneething-from-line (uid &optional file)
303 "Return a From header based of UID." 357 "Return a From header based of UID."
304 (let* ((login (condition-case nil 358 (let* ((login (condition-case nil
342 (file-symlink-p file)) 396 (file-symlink-p file))
343 ;; It's a dir, so we fudge a head. 397 ;; It's a dir, so we fudge a head.
344 (nneething-make-head file) t) 398 (nneething-make-head file) t)
345 (t 399 (t
346 ;; We examine the file. 400 ;; We examine the file.
347 (nnheader-insert-head file) 401 (condition-case ()
348 (if (nnheader-article-p) 402 (progn
349 (delete-region 403 (nnheader-insert-head file)
350 (progn 404 (if (nnheader-article-p)
351 (goto-char (point-min)) 405 (delete-region
352 (or (and (search-forward "\n\n" nil t) 406 (progn
353 (1- (point))) 407 (goto-char (point-min))
354 (point-max))) 408 (or (and (search-forward "\n\n" nil t)
355 (point-max)) 409 (1- (point)))
356 (goto-char (point-min)) 410 (point-max)))
357 (nneething-make-head file (current-buffer)) 411 (point-max))
358 (delete-region (point) (point-max))) 412 (goto-char (point-min))
413 (nneething-make-head file (current-buffer))
414 (delete-region (point) (point-max))))
415 (file-error
416 (nneething-make-head file (current-buffer) " (unreadable)")))
359 t)))) 417 t))))
360 418
361 (defun nneething-file-name (article) 419 (defun nneething-file-name (article)
362 "Return the file name of ARTICLE." 420 "Return the file name of ARTICLE."
363 (let ((dir (file-name-as-directory nneething-address)) 421 (let ((dir (file-name-as-directory nneething-address))
364 fname) 422 fname)
365 (if (numberp article) 423 (if (numberp article)
366 (if (setq fname (cadr (assq article nneething-map))) 424 (if (setq fname (cadr (assq article nneething-map)))
367 (expand-file-name fname dir) 425 (expand-file-name fname dir)
368 (mm-make-temp-file (expand-file-name "nneething" dir))) 426 (mm-make-temp-file (expand-file-name "nneething" dir)))
369 (expand-file-name article dir)))) 427 (expand-file-name article dir))))
370 428
371 (provide 'nneething) 429 (provide 'nneething)
372 430
431 ;;; arch-tag: 1277f386-88f2-4459-bb24-f3f45962a6c5
373 ;;; nneething.el ends here 432 ;;; nneething.el ends here