Mercurial > hg > xemacs-beta
comparison lisp/gnus/gnus-soup.el @ 70:131b0175ea99 r20-0b30
Import from CVS: tag r20-0b30
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:02:59 +0200 |
parents | e04119814345 |
children | 0d2f883870bc |
comparison
equal
deleted
inserted
replaced
69:804d1389bcd6 | 70:131b0175ea99 |
---|---|
1 ;;; gnus-soup.el --- SOUP packet writing support for Gnus | 1 ;;; gnus-soup.el --- SOUP packet writing support for Gnus |
2 ;; Copyright (C) 1995,96,97 Free Software Foundation, Inc. | 2 ;; Copyright (C) 1995,96 Free Software Foundation, Inc. |
3 | 3 |
4 ;; Author: Per Abrahamsen <abraham@iesd.auc.dk> | 4 ;; Author: Per Abrahamsen <abraham@iesd.auc.dk> |
5 ;; Lars Magne Ingebrigtsen <larsi@ifi.uio.no> | 5 ;; Lars Magne Ingebrigtsen <larsi@ifi.uio.no> |
6 ;; Keywords: news, mail | 6 ;; Keywords: news, mail |
7 | 7 |
24 | 24 |
25 ;;; Commentary: | 25 ;;; Commentary: |
26 | 26 |
27 ;;; Code: | 27 ;;; Code: |
28 | 28 |
29 (require 'gnus-msg) | |
29 (require 'gnus) | 30 (require 'gnus) |
30 (require 'gnus-art) | 31 (eval-when-compile (require 'cl)) |
31 (require 'message) | |
32 (require 'gnus-start) | |
33 (require 'gnus-range) | |
34 | 32 |
35 ;;; User Variables: | 33 ;;; User Variables: |
36 | 34 |
37 (defvar gnus-soup-directory (nnheader-concat gnus-home-directory "SoupBrew/") | 35 (defvar gnus-soup-directory "~/SoupBrew/" |
38 "*Directory containing an unpacked SOUP packet.") | 36 "*Directory containing an unpacked SOUP packet.") |
39 | 37 |
40 (defvar gnus-soup-replies-directory | 38 (defvar gnus-soup-replies-directory (concat gnus-soup-directory "SoupReplies/") |
41 (nnheader-concat gnus-soup-directory "SoupReplies/") | |
42 "*Directory where Gnus will do processing of replies.") | 39 "*Directory where Gnus will do processing of replies.") |
43 | 40 |
44 (defvar gnus-soup-prefix-file "gnus-prefix" | 41 (defvar gnus-soup-prefix-file "gnus-prefix" |
45 "*Name of the file where Gnus stores the last used prefix.") | 42 "*Name of the file where Gnus stores the last used prefix.") |
46 | 43 |
47 (defvar gnus-soup-packer "tar cf - %s | gzip > $HOME/Soupout%d.tgz" | 44 (defvar gnus-soup-packer "tar cf - %s | gzip > $HOME/Soupout%d.tgz" |
48 "Format string command for packing a SOUP packet. | 45 "Format string command for packing a SOUP packet. |
49 The SOUP files will be inserted where the %s is in the string. | 46 The SOUP files will be inserted where the %s is in the string. |
50 This string MUST contain both %s and %d. The file number will be | 47 This string MUST contain both %s and %d. The file number will be |
51 inserted where %d appears.") | 48 inserted where %d appears.") |
52 | 49 |
53 (defvar gnus-soup-unpacker "gunzip -c %s | tar xvf -" | 50 (defvar gnus-soup-unpacker "gunzip -c %s | tar xvf -" |
54 "*Format string command for unpacking a SOUP packet. | 51 "*Format string command for unpacking a SOUP packet. |
55 The SOUP packet file name will be inserted at the %s.") | 52 The SOUP packet file name will be inserted at the %s.") |
56 | 53 |
57 (defvar gnus-soup-packet-directory gnus-home-directory | 54 (defvar gnus-soup-packet-directory "~/" |
58 "*Where gnus-soup will look for REPLIES packets.") | 55 "*Where gnus-soup will look for REPLIES packets.") |
59 | 56 |
60 (defvar gnus-soup-packet-regexp "Soupin" | 57 (defvar gnus-soup-packet-regexp "Soupin" |
61 "*Regular expression matching SOUP REPLIES packets in `gnus-soup-packet-directory'.") | 58 "*Regular expression matching SOUP REPLIES packets in `gnus-soup-packet-directory'.") |
62 | 59 |
71 format.") | 68 format.") |
72 | 69 |
73 (defvar gnus-soup-index-type ?c | 70 (defvar gnus-soup-index-type ?c |
74 "*Soup index type. | 71 "*Soup index type. |
75 `n' means no index file and `c' means standard Cnews overview | 72 `n' means no index file and `c' means standard Cnews overview |
76 format.") | 73 format.") |
77 | 74 |
78 (defvar gnus-soup-areas nil) | 75 (defvar gnus-soup-areas nil) |
79 (defvar gnus-soup-last-prefix nil) | 76 (defvar gnus-soup-last-prefix nil) |
80 (defvar gnus-soup-prev-prefix nil) | 77 (defvar gnus-soup-prev-prefix nil) |
81 (defvar gnus-soup-buffers nil) | 78 (defvar gnus-soup-buffers nil) |
117 "Unpack and send all replies in the reply packet." | 114 "Unpack and send all replies in the reply packet." |
118 (interactive) | 115 (interactive) |
119 (let ((packets (directory-files | 116 (let ((packets (directory-files |
120 gnus-soup-packet-directory t gnus-soup-packet-regexp))) | 117 gnus-soup-packet-directory t gnus-soup-packet-regexp))) |
121 (while packets | 118 (while packets |
122 (when (gnus-soup-send-packet (car packets)) | 119 (and (gnus-soup-send-packet (car packets)) |
123 (delete-file (car packets))) | 120 (delete-file (car packets))) |
124 (setq packets (cdr packets))))) | 121 (setq packets (cdr packets))))) |
125 | 122 |
126 (defun gnus-soup-add-article (n) | 123 (defun gnus-soup-add-article (n) |
127 "Add the current article to SOUP packet. | 124 "Add the current article to SOUP packet. |
128 If N is a positive number, add the N next articles. | 125 If N is a positive number, add the N next articles. |
142 ;; Find the header of the article. | 139 ;; Find the header of the article. |
143 (set-buffer gnus-summary-buffer) | 140 (set-buffer gnus-summary-buffer) |
144 (when (setq headers (gnus-summary-article-header (car articles))) | 141 (when (setq headers (gnus-summary-article-header (car articles))) |
145 ;; Put the article in a buffer. | 142 ;; Put the article in a buffer. |
146 (set-buffer tmp-buf) | 143 (set-buffer tmp-buf) |
147 (when (gnus-request-article-this-buffer | 144 (when (gnus-request-article-this-buffer |
148 (car articles) gnus-newsgroup-name) | 145 (car articles) gnus-newsgroup-name) |
149 (save-restriction | 146 (save-restriction |
150 (message-narrow-to-head) | 147 (message-narrow-to-head) |
151 (message-remove-header gnus-soup-ignored-headers t)) | 148 (message-remove-header gnus-soup-ignored-headers t)) |
152 (gnus-soup-store gnus-soup-directory prefix headers | 149 (gnus-soup-store gnus-soup-directory prefix headers |
153 gnus-soup-encoding-type | 150 gnus-soup-encoding-type |
154 gnus-soup-index-type) | 151 gnus-soup-index-type) |
155 (gnus-soup-area-set-number | 152 (gnus-soup-area-set-number |
156 area (1+ (or (gnus-soup-area-number area) 0))))) | 153 area (1+ (or (gnus-soup-area-number area) 0))))) |
157 ;; Mark article as read. | 154 ;; Mark article as read. |
158 (set-buffer gnus-summary-buffer) | 155 (set-buffer gnus-summary-buffer) |
159 (gnus-summary-remove-process-mark (car articles)) | 156 (gnus-summary-remove-process-mark (car articles)) |
160 (gnus-summary-mark-as-read (car articles) gnus-souped-mark) | 157 (gnus-summary-mark-as-read (car articles) gnus-souped-mark) |
161 (setq articles (cdr articles))) | 158 (setq articles (cdr articles))) |
162 (kill-buffer tmp-buf)) | 159 (kill-buffer tmp-buf)) |
164 | 161 |
165 (defun gnus-soup-pack-packet () | 162 (defun gnus-soup-pack-packet () |
166 "Make a SOUP packet from the SOUP areas." | 163 "Make a SOUP packet from the SOUP areas." |
167 (interactive) | 164 (interactive) |
168 (gnus-soup-read-areas) | 165 (gnus-soup-read-areas) |
169 (unless (file-exists-p gnus-soup-directory) | |
170 (message "No such directory: %s" gnus-soup-directory)) | |
171 (when (null (directory-files gnus-soup-directory nil "\\.MSG$")) | |
172 (message "No files to pack.")) | |
173 (gnus-soup-pack gnus-soup-directory gnus-soup-packer)) | 166 (gnus-soup-pack gnus-soup-directory gnus-soup-packer)) |
174 | 167 |
175 (defun gnus-group-brew-soup (n) | 168 (defun gnus-group-brew-soup (n) |
176 "Make a soup packet from the current group. | 169 "Make a soup packet from the current group. |
177 Uses the process/prefix convention." | 170 Uses the process/prefix convention." |
187 "Go through all groups on LEVEL or less and make a soup packet." | 180 "Go through all groups on LEVEL or less and make a soup packet." |
188 (interactive "P") | 181 (interactive "P") |
189 (let ((level (or level gnus-level-subscribed)) | 182 (let ((level (or level gnus-level-subscribed)) |
190 (newsrc (cdr gnus-newsrc-alist))) | 183 (newsrc (cdr gnus-newsrc-alist))) |
191 (while newsrc | 184 (while newsrc |
192 (when (<= (nth 1 (car newsrc)) level) | 185 (and (<= (nth 1 (car newsrc)) level) |
193 (gnus-soup-group-brew (caar newsrc) t)) | 186 (gnus-soup-group-brew (caar newsrc) t)) |
194 (setq newsrc (cdr newsrc))) | 187 (setq newsrc (cdr newsrc))) |
195 (gnus-soup-save-areas))) | 188 (gnus-soup-save-areas))) |
196 | 189 |
197 ;;;###autoload | 190 ;;;###autoload |
198 (defun gnus-batch-brew-soup () | 191 (defun gnus-batch-brew-soup () |
203 For instance, if you want to brew on all the nnml groups, as well as | 196 For instance, if you want to brew on all the nnml groups, as well as |
204 groups with \"emacs\" in the name, you could say something like: | 197 groups with \"emacs\" in the name, you could say something like: |
205 | 198 |
206 $ emacs -batch -f gnus-batch-brew-soup ^nnml \".*emacs.*\"" | 199 $ emacs -batch -f gnus-batch-brew-soup ^nnml \".*emacs.*\"" |
207 (interactive) | 200 (interactive) |
208 nil) | 201 ) |
209 | 202 |
210 ;;; Internal Functions: | 203 ;;; Internal Functions: |
211 | 204 |
212 ;; Store the current buffer. | 205 ;; Store the current buffer. |
213 (defun gnus-soup-store (directory prefix headers format index) | 206 (defun gnus-soup-store (directory prefix headers format index) |
214 ;; Create the directory, if needed. | 207 ;; Create the directory, if needed. |
215 (gnus-make-directory directory) | 208 (or (file-directory-p directory) |
216 (let* ((msg-buf (nnheader-find-file-noselect | 209 (gnus-make-directory directory)) |
210 (let* ((msg-buf (find-file-noselect | |
217 (concat directory prefix ".MSG"))) | 211 (concat directory prefix ".MSG"))) |
218 (idx-buf (if (= index ?n) | 212 (idx-buf (if (= index ?n) |
219 nil | 213 nil |
220 (nnheader-find-file-noselect | 214 (find-file-noselect |
221 (concat directory prefix ".IDX")))) | 215 (concat directory prefix ".IDX")))) |
222 (article-buf (current-buffer)) | 216 (article-buf (current-buffer)) |
223 from head-line beg type) | 217 from head-line beg type) |
224 (setq gnus-soup-buffers (cons msg-buf (delq msg-buf gnus-soup-buffers))) | 218 (setq gnus-soup-buffers (cons msg-buf (delq msg-buf gnus-soup-buffers))) |
225 (buffer-disable-undo msg-buf) | 219 (buffer-disable-undo msg-buf) |
226 (when idx-buf | 220 (and idx-buf |
227 (push idx-buf gnus-soup-buffers) | 221 (progn |
228 (buffer-disable-undo idx-buf)) | 222 (setq gnus-soup-buffers (cons idx-buf gnus-soup-buffers)) |
223 (buffer-disable-undo idx-buf))) | |
229 (save-excursion | 224 (save-excursion |
230 ;; Make sure the last char in the buffer is a newline. | 225 ;; Make sure the last char in the buffer is a newline. |
231 (goto-char (point-max)) | 226 (goto-char (point-max)) |
232 (unless (= (current-column) 0) | 227 (or (= (current-column) 0) |
233 (insert "\n")) | 228 (insert "\n")) |
234 ;; Find the "from". | 229 ;; Find the "from". |
235 (goto-char (point-min)) | 230 (goto-char (point-min)) |
236 (setq from | 231 (setq from |
237 (gnus-mail-strip-quoted-names | 232 (gnus-mail-strip-quoted-names |
238 (or (mail-fetch-field "from") | 233 (or (mail-fetch-field "from") |
239 (mail-fetch-field "really-from") | 234 (mail-fetch-field "really-from") |
240 (mail-fetch-field "sender")))) | 235 (mail-fetch-field "sender")))) |
241 (goto-char (point-min)) | 236 (goto-char (point-min)) |
242 ;; Depending on what encoding is supposed to be used, we make | 237 ;; Depending on what encoding is supposed to be used, we make |
243 ;; a soup header. | 238 ;; a soup header. |
244 (setq head-line | 239 (setq head-line |
245 (cond | 240 (cond |
246 ((= gnus-soup-encoding-type ?n) | 241 ((= gnus-soup-encoding-type ?n) |
247 (format "#! rnews %d\n" (buffer-size))) | 242 (format "#! rnews %d\n" (buffer-size))) |
248 ((= gnus-soup-encoding-type ?m) | 243 ((= gnus-soup-encoding-type ?m) |
249 (while (search-forward "\nFrom " nil t) | 244 (while (search-forward "\nFrom " nil t) |
250 (replace-match "\n>From " t t)) | 245 (replace-match "\n>From " t t)) |
277 (when (or (null entry) | 272 (when (or (null entry) |
278 (eq (car entry) t) | 273 (eq (car entry) t) |
279 (and (car entry) | 274 (and (car entry) |
280 (> (car entry) 0)) | 275 (> (car entry) 0)) |
281 (and (not not-all) | 276 (and (not not-all) |
282 (gnus-range-length (cdr (assq 'tick (gnus-info-marks | 277 (gnus-range-length (cdr (assq 'tick (gnus-info-marks |
283 (nth 2 entry))))))) | 278 (nth 2 entry))))))) |
284 (when (gnus-summary-read-group group nil t) | 279 (when (gnus-summary-read-group group nil t) |
285 (setq gnus-newsgroup-processable | 280 (setq gnus-newsgroup-processable |
286 (reverse | 281 (reverse |
287 (if (not not-all) | 282 (if (not not-all) |
298 offset | 293 offset |
299 (or (mail-header-subject header) "(none)") | 294 (or (mail-header-subject header) "(none)") |
300 (or (mail-header-from header) "(nobody)") | 295 (or (mail-header-from header) "(nobody)") |
301 (or (mail-header-date header) "") | 296 (or (mail-header-date header) "") |
302 (or (mail-header-id header) | 297 (or (mail-header-id header) |
303 (concat "soup-dummy-id-" | 298 (concat "soup-dummy-id-" |
304 (mapconcat | 299 (mapconcat |
305 (lambda (time) (int-to-string time)) | 300 (lambda (time) (int-to-string time)) |
306 (current-time) "-"))) | 301 (current-time) "-"))) |
307 (or (mail-header-references header) "") | 302 (or (mail-header-references header) "") |
308 (or (mail-header-chars header) 0) | 303 (or (mail-header-chars header) 0) |
309 (or (mail-header-lines header) "0")))) | 304 (or (mail-header-lines header) "0")))) |
310 | 305 |
311 (defun gnus-soup-save-areas () | 306 (defun gnus-soup-save-areas () |
312 (gnus-soup-write-areas) | 307 (gnus-soup-write-areas) |
313 (save-excursion | 308 (save-excursion |
316 (setq buf (car gnus-soup-buffers) | 311 (setq buf (car gnus-soup-buffers) |
317 gnus-soup-buffers (cdr gnus-soup-buffers)) | 312 gnus-soup-buffers (cdr gnus-soup-buffers)) |
318 (if (not (buffer-name buf)) | 313 (if (not (buffer-name buf)) |
319 () | 314 () |
320 (set-buffer buf) | 315 (set-buffer buf) |
321 (when (buffer-modified-p) | 316 (and (buffer-modified-p) (save-buffer)) |
322 (save-buffer)) | |
323 (kill-buffer (current-buffer))))) | 317 (kill-buffer (current-buffer))))) |
324 (gnus-soup-write-prefixes))) | 318 (gnus-soup-write-prefixes))) |
325 | 319 |
326 (defun gnus-soup-write-prefixes () | 320 (defun gnus-soup-write-prefixes () |
327 (let ((prefixes gnus-soup-last-prefix) | 321 (let ((prefix gnus-soup-last-prefix)) |
328 prefix) | |
329 (save-excursion | 322 (save-excursion |
330 (gnus-set-work-buffer) | 323 (while prefix |
331 (while (setq prefix (pop prefixes)) | 324 (gnus-set-work-buffer) |
332 (erase-buffer) | 325 (insert (format "(setq gnus-soup-prev-prefix %d)\n" (cdar prefix))) |
333 (insert (format "(setq gnus-soup-prev-prefix %d)\n" (cdr prefix))) | 326 (gnus-make-directory (caar prefix)) |
334 (gnus-write-buffer (concat (car prefix) gnus-soup-prefix-file)))))) | 327 (write-region (point-min) (point-max) |
328 (concat (caar prefix) gnus-soup-prefix-file) | |
329 nil 'nomesg) | |
330 (setq prefix (cdr prefix)))))) | |
335 | 331 |
336 (defun gnus-soup-pack (dir packer) | 332 (defun gnus-soup-pack (dir packer) |
337 (let* ((files (mapconcat 'identity | 333 (let* ((files (mapconcat 'identity |
338 '("AREAS" "*.MSG" "*.IDX" "INFO" | 334 '("AREAS" "*.MSG" "*.IDX" "INFO" |
339 "LIST" "REPLIES" "COMMANDS" "ERRORS") | 335 "LIST" "REPLIES" "COMMANDS" "ERRORS") |
340 " ")) | 336 " ")) |
341 (packer (if (< (string-match "%s" packer) | 337 (packer (if (< (string-match "%s" packer) |
342 (string-match "%d" packer)) | 338 (string-match "%d" packer)) |
343 (format packer files | 339 (format packer files |
344 (string-to-int (gnus-soup-unique-prefix dir))) | 340 (string-to-int (gnus-soup-unique-prefix dir))) |
345 (format packer | 341 (format packer |
346 (string-to-int (gnus-soup-unique-prefix dir)) | 342 (string-to-int (gnus-soup-unique-prefix dir)) |
347 files))) | 343 files))) |
348 (dir (expand-file-name dir))) | 344 (dir (expand-file-name dir))) |
349 (gnus-make-directory dir) | 345 (or (file-directory-p dir) |
346 (gnus-make-directory dir)) | |
350 (setq gnus-soup-areas nil) | 347 (setq gnus-soup-areas nil) |
351 (gnus-message 4 "Packing %s..." packer) | 348 (gnus-message 4 "Packing %s..." packer) |
352 (if (zerop (call-process shell-file-name | 349 (if (zerop (call-process shell-file-name |
353 nil nil nil shell-command-switch | 350 nil nil nil shell-command-switch |
354 (concat "cd " dir " ; " packer))) | 351 (concat "cd " dir " ; " packer))) |
355 (progn | 352 (progn |
356 (call-process shell-file-name nil nil nil shell-command-switch | 353 (call-process shell-file-name nil nil nil shell-command-switch |
357 (concat "cd " dir " ; rm " files)) | 354 (concat "cd " dir " ; rm " files)) |
358 (gnus-message 4 "Packing...done" packer)) | 355 (gnus-message 4 "Packing...done" packer)) |
359 (error "Couldn't pack packet.")))) | 356 (error "Couldn't pack packet.")))) |
360 | 357 |
361 (defun gnus-soup-parse-areas (file) | 358 (defun gnus-soup-parse-areas (file) |
362 "Parse soup area file FILE. | 359 "Parse soup area file FILE. |
363 The result is a of vectors, each containing one entry from the AREA file. | 360 The result is a of vectors, each containing one entry from the AREA file. |
364 The vector contain five strings, | 361 The vector contain five strings, |
365 [prefix name encoding description number] | 362 [prefix name encoding description number] |
366 though the two last may be nil if they are missing." | 363 though the two last may be nil if they are missing." |
367 (let (areas) | 364 (let (areas) |
368 (save-excursion | 365 (save-excursion |
369 (set-buffer (nnheader-find-file-noselect file 'force)) | 366 (set-buffer (find-file-noselect file 'force)) |
370 (buffer-disable-undo (current-buffer)) | 367 (buffer-disable-undo (current-buffer)) |
371 (goto-char (point-min)) | 368 (goto-char (point-min)) |
372 (while (not (eobp)) | 369 (while (not (eobp)) |
373 (push (vector (gnus-soup-field) | 370 (setq areas |
374 (gnus-soup-field) | 371 (cons (vector (gnus-soup-field) |
375 (gnus-soup-field) | 372 (gnus-soup-field) |
376 (and (eq (preceding-char) ?\t) | 373 (gnus-soup-field) |
377 (gnus-soup-field)) | 374 (and (eq (preceding-char) ?\t) |
378 (and (eq (preceding-char) ?\t) | 375 (gnus-soup-field)) |
379 (string-to-int (gnus-soup-field)))) | 376 (and (eq (preceding-char) ?\t) |
380 areas) | 377 (string-to-int (gnus-soup-field)))) |
381 (when (eq (preceding-char) ?\t) | 378 areas)) |
382 (beginning-of-line 2))) | 379 (if (eq (preceding-char) ?\t) |
380 (beginning-of-line 2))) | |
383 (kill-buffer (current-buffer))) | 381 (kill-buffer (current-buffer))) |
384 areas)) | 382 areas)) |
385 | 383 |
386 (defun gnus-soup-parse-replies (file) | 384 (defun gnus-soup-parse-replies (file) |
387 "Parse soup REPLIES file FILE. | 385 "Parse soup REPLIES file FILE. |
388 The result is a of vectors, each containing one entry from the REPLIES | 386 The result is a of vectors, each containing one entry from the REPLIES |
389 file. The vector contain three strings, [prefix name encoding]." | 387 file. The vector contain three strings, [prefix name encoding]." |
390 (let (replies) | 388 (let (replies) |
391 (save-excursion | 389 (save-excursion |
392 (set-buffer (nnheader-find-file-noselect file)) | 390 (set-buffer (find-file-noselect file)) |
393 (buffer-disable-undo (current-buffer)) | 391 (buffer-disable-undo (current-buffer)) |
394 (goto-char (point-min)) | 392 (goto-char (point-min)) |
395 (while (not (eobp)) | 393 (while (not (eobp)) |
396 (push (vector (gnus-soup-field) (gnus-soup-field) | 394 (setq replies |
397 (gnus-soup-field)) | 395 (cons (vector (gnus-soup-field) (gnus-soup-field) |
398 replies) | 396 (gnus-soup-field)) |
399 (when (eq (preceding-char) ?\t) | 397 replies)) |
400 (beginning-of-line 2))) | 398 (if (eq (preceding-char) ?\t) |
399 (beginning-of-line 2))) | |
401 (kill-buffer (current-buffer))) | 400 (kill-buffer (current-buffer))) |
402 replies)) | 401 replies)) |
403 | 402 |
404 (defun gnus-soup-field () | 403 (defun gnus-soup-field () |
405 (prog1 | 404 (prog1 |
418 (nnheader-temp-write (concat gnus-soup-directory "AREAS") | 417 (nnheader-temp-write (concat gnus-soup-directory "AREAS") |
419 (let ((areas gnus-soup-areas) | 418 (let ((areas gnus-soup-areas) |
420 area) | 419 area) |
421 (while (setq area (pop areas)) | 420 (while (setq area (pop areas)) |
422 (insert | 421 (insert |
423 (format | 422 (format |
424 "%s\t%s\t%s%s\n" | 423 "%s\t%s\t%s%s\n" |
425 (gnus-soup-area-prefix area) | 424 (gnus-soup-area-prefix area) |
426 (gnus-soup-area-name area) | 425 (gnus-soup-area-name area) |
427 (gnus-soup-area-encoding area) | 426 (gnus-soup-area-encoding area) |
428 (if (or (gnus-soup-area-description area) | 427 (if (or (gnus-soup-area-description area) |
429 (gnus-soup-area-number area)) | 428 (gnus-soup-area-number area)) |
430 (concat "\t" (or (gnus-soup-area-description | 429 (concat "\t" (or (gnus-soup-area-description |
431 area) "") | 430 area) "") |
432 (if (gnus-soup-area-number area) | 431 (if (gnus-soup-area-number area) |
433 (concat "\t" (int-to-string | 432 (concat "\t" (int-to-string |
434 (gnus-soup-area-number area))) | 433 (gnus-soup-area-number area))) |
435 "")) "")))))))) | 434 "")) "")))))))) |
436 | 435 |
437 (defun gnus-soup-write-replies (dir areas) | 436 (defun gnus-soup-write-replies (dir areas) |
438 "Write a REPLIES file in DIR containing AREAS." | 437 "Write a REPLIES file in DIR containing AREAS." |
439 (nnheader-temp-write (concat dir "REPLIES") | 438 (nnheader-temp-write (concat dir "REPLIES") |
440 (let (area) | 439 (let (area) |
441 (while (setq area (pop areas)) | 440 (while (setq area (pop areas)) |
442 (insert (format "%s\t%s\t%s\n" | 441 (insert (format "%s\t%s\t%s\n" |
443 (gnus-soup-reply-prefix area) | 442 (gnus-soup-reply-prefix area) |
444 (gnus-soup-reply-kind area) | 443 (gnus-soup-reply-kind area) |
445 (gnus-soup-reply-encoding area))))))) | 444 (gnus-soup-reply-encoding area))))))) |
446 | 445 |
447 (defun gnus-soup-area (group) | 446 (defun gnus-soup-area (group) |
448 (gnus-soup-read-areas) | 447 (gnus-soup-read-areas) |
449 (let ((areas gnus-soup-areas) | 448 (let ((areas gnus-soup-areas) |
450 (real-group (gnus-group-real-name group)) | 449 (real-group (gnus-group-real-name group)) |
451 area result) | 450 area result) |
452 (while areas | 451 (while areas |
453 (setq area (car areas) | 452 (setq area (car areas) |
454 areas (cdr areas)) | 453 areas (cdr areas)) |
455 (when (equal (gnus-soup-area-name area) real-group) | 454 (if (equal (gnus-soup-area-name area) real-group) |
456 (setq result area))) | 455 (setq result area))) |
457 (unless result | 456 (or result |
458 (setq result | 457 (setq result |
459 (vector (gnus-soup-unique-prefix) | 458 (vector (gnus-soup-unique-prefix) |
460 real-group | 459 real-group |
461 (format "%c%c%c" | 460 (format "%c%c%c" |
462 gnus-soup-encoding-type | 461 gnus-soup-encoding-type |
463 gnus-soup-index-type | 462 gnus-soup-index-type |
464 (if (gnus-member-of-valid 'mail group) ?m ?n)) | 463 (if (gnus-member-of-valid 'mail group) ?m ?n)) |
465 nil nil) | 464 nil nil) |
466 gnus-soup-areas (cons result gnus-soup-areas))) | 465 gnus-soup-areas (cons result gnus-soup-areas))) |
467 result)) | 466 result)) |
468 | 467 |
469 (defun gnus-soup-unique-prefix (&optional dir) | 468 (defun gnus-soup-unique-prefix (&optional dir) |
470 (let* ((dir (file-name-as-directory (or dir gnus-soup-directory))) | 469 (let* ((dir (file-name-as-directory (or dir gnus-soup-directory))) |
471 (entry (assoc dir gnus-soup-last-prefix)) | 470 (entry (assoc dir gnus-soup-last-prefix)) |
472 gnus-soup-prev-prefix) | 471 gnus-soup-prev-prefix) |
473 (if entry | 472 (if entry |
474 () | 473 () |
475 (when (file-exists-p (concat dir gnus-soup-prefix-file)) | 474 (and (file-exists-p (concat dir gnus-soup-prefix-file)) |
476 (ignore-errors | 475 (condition-case nil |
477 (load (concat dir gnus-soup-prefix-file) nil t t))) | 476 (load (concat dir gnus-soup-prefix-file) nil t t) |
478 (push (setq entry (cons dir (or gnus-soup-prev-prefix 0))) | 477 (error nil))) |
479 gnus-soup-last-prefix)) | 478 (setq gnus-soup-last-prefix |
479 (cons (setq entry (cons dir (or gnus-soup-prev-prefix 0))) | |
480 gnus-soup-last-prefix))) | |
480 (setcdr entry (1+ (cdr entry))) | 481 (setcdr entry (1+ (cdr entry))) |
481 (gnus-soup-write-prefixes) | 482 (gnus-soup-write-prefixes) |
482 (int-to-string (cdr entry)))) | 483 (int-to-string (cdr entry)))) |
483 | 484 |
484 (defun gnus-soup-unpack-packet (dir unpacker packet) | 485 (defun gnus-soup-unpack-packet (dir unpacker packet) |
487 (gnus-make-directory dir) | 488 (gnus-make-directory dir) |
488 (gnus-message 4 "Unpacking: %s" (format unpacker packet)) | 489 (gnus-message 4 "Unpacking: %s" (format unpacker packet)) |
489 (prog1 | 490 (prog1 |
490 (zerop (call-process | 491 (zerop (call-process |
491 shell-file-name nil nil nil shell-command-switch | 492 shell-file-name nil nil nil shell-command-switch |
492 (format "cd %s ; %s" (expand-file-name dir) | 493 (format "cd %s ; %s" (expand-file-name dir) |
493 (format unpacker packet)))) | 494 (format unpacker packet)))) |
494 (gnus-message 4 "Unpacking...done"))) | 495 (gnus-message 4 "Unpacking...done"))) |
495 | 496 |
496 (defun gnus-soup-send-packet (packet) | 497 (defun gnus-soup-send-packet (packet) |
497 (gnus-soup-unpack-packet | 498 (gnus-soup-unpack-packet |
498 gnus-soup-replies-directory gnus-soup-unpacker packet) | 499 gnus-soup-replies-directory gnus-soup-unpacker packet) |
499 (let ((replies (gnus-soup-parse-replies | 500 (let ((replies (gnus-soup-parse-replies |
500 (concat gnus-soup-replies-directory "REPLIES")))) | 501 (concat gnus-soup-replies-directory "REPLIES")))) |
501 (save-excursion | 502 (save-excursion |
502 (while replies | 503 (while replies |
503 (let* ((msg-file (concat gnus-soup-replies-directory | 504 (let* ((msg-file (concat gnus-soup-replies-directory |
504 (gnus-soup-reply-prefix (car replies)) | 505 (gnus-soup-reply-prefix (car replies)) |
505 ".MSG")) | 506 ".MSG")) |
506 (msg-buf (and (file-exists-p msg-file) | 507 (msg-buf (and (file-exists-p msg-file) |
507 (nnheader-find-file-noselect msg-file))) | 508 (find-file-noselect msg-file))) |
508 (tmp-buf (get-buffer-create " *soup send*")) | 509 (tmp-buf (get-buffer-create " *soup send*")) |
509 beg end) | 510 beg end) |
510 (cond | 511 (cond |
511 ((/= (gnus-soup-encoding-format | 512 ((/= (gnus-soup-encoding-format |
512 (gnus-soup-reply-encoding (car replies))) | 513 (gnus-soup-reply-encoding (car replies))) ?n) |
513 ?n) | |
514 (error "Unsupported encoding")) | 514 (error "Unsupported encoding")) |
515 ((null msg-buf) | 515 ((null msg-buf) |
516 t) | 516 t) |
517 (t | 517 (t |
518 (buffer-disable-undo msg-buf) | 518 (buffer-disable-undo msg-buf) |
519 (buffer-disable-undo tmp-buf) | 519 (buffer-disable-undo tmp-buf) |
520 (set-buffer msg-buf) | 520 (set-buffer msg-buf) |
521 (goto-char (point-min)) | 521 (goto-char (point-min)) |
522 (while (not (eobp)) | 522 (while (not (eobp)) |
523 (unless (looking-at "#! *rnews +\\([0-9]+\\)") | 523 (or (looking-at "#! *rnews +\\([0-9]+\\)") |
524 (error "Bad header.")) | 524 (error "Bad header.")) |
525 (forward-line 1) | 525 (forward-line 1) |
526 (setq beg (point) | 526 (setq beg (point) |
527 end (+ (point) (string-to-int | 527 end (+ (point) (string-to-int |
528 (buffer-substring | 528 (buffer-substring |
529 (match-beginning 1) (match-end 1))))) | 529 (match-beginning 1) (match-end 1))))) |
530 (switch-to-buffer tmp-buf) | 530 (switch-to-buffer tmp-buf) |
531 (erase-buffer) | 531 (erase-buffer) |
532 (insert-buffer-substring msg-buf beg end) | 532 (insert-buffer-substring msg-buf beg end) |
533 (goto-char (point-min)) | 533 (goto-char (point-min)) |
534 (search-forward "\n\n") | 534 (search-forward "\n\n") |
535 (forward-char -1) | 535 (forward-char -1) |
536 (insert mail-header-separator) | 536 (insert mail-header-separator) |
537 (setq message-newsreader (setq message-mailer | 537 (setq message-newsreader (setq message-mailer |
538 (gnus-extended-version))) | 538 (gnus-extended-version))) |
539 (cond | 539 (cond |
540 ((string= (gnus-soup-reply-kind (car replies)) "news") | 540 ((string= (gnus-soup-reply-kind (car replies)) "news") |
541 (gnus-message 5 "Sending news message to %s..." | 541 (gnus-message 5 "Sending news message to %s..." |
542 (mail-fetch-field "newsgroups")) | 542 (mail-fetch-field "newsgroups")) |
543 (sit-for 1) | 543 (sit-for 1) |
544 (let ((message-syntax-checks | 544 (funcall message-send-news-function)) |
545 'dont-check-for-anything-just-trust-me)) | |
546 (funcall message-send-news-function))) | |
547 ((string= (gnus-soup-reply-kind (car replies)) "mail") | 545 ((string= (gnus-soup-reply-kind (car replies)) "mail") |
548 (gnus-message 5 "Sending mail to %s..." | 546 (gnus-message 5 "Sending mail to %s..." |
549 (mail-fetch-field "to")) | 547 (mail-fetch-field "to")) |
550 (sit-for 1) | 548 (sit-for 1) |
551 (message-send-mail)) | 549 (message-send-mail)) |
552 (t | 550 (t |
553 (error "Unknown reply kind"))) | 551 (error "Unknown reply kind"))) |
554 (set-buffer msg-buf) | 552 (set-buffer msg-buf) |
557 (kill-buffer msg-buf) | 555 (kill-buffer msg-buf) |
558 (kill-buffer tmp-buf) | 556 (kill-buffer tmp-buf) |
559 (gnus-message 4 "Sent packet")))) | 557 (gnus-message 4 "Sent packet")))) |
560 (setq replies (cdr replies))) | 558 (setq replies (cdr replies))) |
561 t))) | 559 t))) |
562 | 560 |
563 (provide 'gnus-soup) | 561 (provide 'gnus-soup) |
564 | 562 |
565 ;;; gnus-soup.el ends here | 563 ;;; gnus-soup.el ends here |