1 ;;; wl-expire.el --- Message expire modules for Wanderlust.
3 ;; Copyright (C) 1998,1999,2000 Masahiro MURATA <muse@ba2.so-net.ne.jp>
4 ;; Copyright (C) 1998,1999,2000 Yuuichi Teranishi <teranisi@gohome.org>
6 ;; Author: Masahiro MURATA <muse@ba2.so-net.ne.jp>
7 ;; Keywords: mail, net news
9 ;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen).
11 ;; This program is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 2, or (at your option)
16 ;; This program is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs; see the file COPYING. If not, write to the
23 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 ;; Boston, MA 02111-1307, USA.
39 (require 'elmo-archive
))
43 (defvar wl-expired-alist nil
)
44 (defvar wl-expired-alist-file-name
"expired-alist")
45 (defvar wl-expired-log-alist nil
)
46 (defvar wl-expired-log-alist-file-name
"expired-log")
47 (defvar wl-expire-test nil
) ;; for debug (no execute)
49 (defun wl-expired-alist-load ()
50 (elmo-object-load (expand-file-name
51 wl-expired-alist-file-name
52 elmo-msgdb-directory
)))
54 (defun wl-expired-alist-save (&optional alist
)
55 (elmo-object-save (expand-file-name
56 wl-expired-alist-file-name
58 (or alist wl-expired-alist
)))
60 (defsubst wl-expire-msg-p
(msg-num mark-alist
)
61 (cond ((consp wl-summary-expire-reserve-marks
)
62 (let ((mark (nth 1 (assq msg-num mark-alist
))))
63 (not (or (member mark wl-summary-expire-reserve-marks
)
64 (and wl-summary-buffer-disp-msg
65 (eq msg-num wl-summary-buffer-current-msg
))))))
66 ((eq wl-summary-expire-reserve-marks
'all
)
67 (not (or (assq msg-num mark-alist
)
68 (and wl-summary-buffer-disp-msg
69 (eq msg-num wl-summary-buffer-current-msg
)))))
70 ((eq wl-summary-expire-reserve-marks
'none
)
73 (error "Invalid marks: %s" wl-summary-expire-reserve-marks
))))
75 (defmacro wl-expire-make-sortable-date
(date)
76 `(timezone-make-sortable-date
77 (aref ,date
0) (aref ,date
1) (aref ,date
2)
78 (timezone-make-time-string
79 (aref ,date
3) (aref ,date
4) (aref ,date
5))))
81 ;; New functions to avoid accessing to the msgdb directly.
82 (defsubst wl-expire-message-p
(folder number
)
83 "Return non-nil when a message in the FOLDER with NUMBER can be expired."
84 (cond ((consp wl-summary-expire-reserve-marks
)
85 (let ((mark (wl-summary-message-mark folder number
)))
86 (not (or (member mark wl-summary-expire-reserve-marks
)
87 (and wl-summary-buffer-disp-msg
88 (eq number wl-summary-buffer-current-msg
))))))
89 ((eq wl-summary-expire-reserve-marks
'all
)
90 (not (or (wl-summary-message-mark folder number
)
91 (and wl-summary-buffer-disp-msg
92 (eq number wl-summary-buffer-current-msg
)))))
93 ((eq wl-summary-expire-reserve-marks
'none
)
96 (error "Invalid marks: %s" wl-summary-expire-reserve-marks
))))
98 (defun wl-expire-delete-reserved-messages (msgs folder
)
99 "Delete a number from NUMBERS when a message with the number is reserved."
100 (remove-if-not #'(lambda (x) (wl-expire-message-p folder x
)) msgs
))
102 ;; End New functions.
104 (defun wl-expire-delete (folder delete-list
&optional no-reserve-marks
)
105 "Delete message for expire."
106 (unless no-reserve-marks
108 (wl-expire-delete-reserved-messages delete-list folder
)))
111 (format "Expiring (delete) %s msgs..."
112 (length delete-list
))))
114 (if (elmo-folder-move-messages folder delete-list
'null
)
116 (wl-expire-append-log
117 (elmo-folder-name-internal folder
)
118 delete-list nil
'delete
)
119 (message "%sdone" mess
))
120 (error "%sfailed!" mess
))))
121 (cons delete-list
(length delete-list
)))
123 (defun wl-expire-refile (folder refile-list dst-folder
124 &optional no-reserve-marks preserve-number copy
)
125 "Refile message for expire. If COPY is non-nil, copy message."
126 (when (not (string= (elmo-folder-name-internal folder
) dst-folder
))
127 (unless no-reserve-marks
129 (wl-expire-delete-reserved-messages refile-list folder
)))
131 (let* ((dst-name dst-folder
)
132 (dst-folder (wl-folder-get-elmo-folder dst-folder
))
133 (action (format (if copy
"Copying to %s" "Expiring (move to %s)")
135 (elmo-with-progress-display
136 (elmo-folder-move-messages (length refile-list
))
140 (unless (or (elmo-folder-exists-p dst-folder
)
141 (elmo-folder-create dst-folder
))
142 (error "Create folder failed: %s" dst-name
))
143 (unless (elmo-folder-move-messages folder
148 (error "%s is failed" action
))
149 (wl-expire-append-log
150 (elmo-folder-name-internal folder
)
153 (if copy
'copy
'move
))))))
154 (cons refile-list
(length refile-list
))))
156 (defun wl-expire-refile-with-copy-reserve-msg
157 (folder refile-list dst-folder
158 &optional no-reserve-marks preserve-number copy
)
159 "Refile message for expire.
160 If REFILE-LIST includes reserve mark message, so copy."
161 (when (not (string= (elmo-folder-name-internal folder
) dst-folder
))
162 (let ((msglist refile-list
)
163 (dst-folder (wl-folder-get-elmo-folder dst-folder
))
165 (copy-reserve-message)
168 (message "Expiring (move %s) %s msgs..."
169 (elmo-folder-name-internal dst-folder
) (length refile-list
))
171 (setq copy-len
(length refile-list
))
172 (unless (or (elmo-folder-exists-p dst-folder
)
173 (elmo-folder-create dst-folder
))
174 (error "%s: create folder failed" (elmo-folder-name-internal
176 (while (setq msg
(wl-pop msglist
))
177 (unless (wl-expire-message-p folder msg
)
178 (setq msg-id
(elmo-message-field folder msg
'message-id
))
179 (if (assoc msg-id wl-expired-alist
)
180 ;; reserve mark message already refiled or expired
181 (setq refile-list
(delq msg refile-list
))
182 ;; reserve mark message not refiled
183 (wl-append wl-expired-alist
(list
185 (elmo-folder-name-internal
187 (setq copy-reserve-message t
))))
191 (elmo-folder-move-messages folder
196 (error "Expire: move msgs to %s failed"
197 (elmo-folder-name-internal dst-folder
)))
198 (wl-expire-append-log (elmo-folder-name-internal folder
)
200 (elmo-folder-name-internal dst-folder
)
201 (if copy-reserve-message
'copy
'move
))
202 (setq copy-len
(length refile-list
))
203 (when copy-reserve-message
205 (wl-expire-delete-reserved-messages refile-list folder
))
208 (elmo-folder-move-messages folder refile-list
'null
))
210 (wl-expire-append-log
211 (elmo-folder-name-internal folder
)
212 refile-list nil
'delete
))))))
213 (let ((mes (format "Expiring (move %s) %s msgs..."
214 (elmo-folder-name-internal dst-folder
)
215 (length refile-list
))))
217 (message "%sdone" mes
)
218 (error "%sfailed!" mes
))))
219 (cons refile-list copy-len
))))
221 (defun wl-expire-archive-get-folder (src-folder &optional fmt dst-folder-arg
)
222 "Get archive folder name from SRC-FOLDER."
223 (let* ((fmt (or fmt wl-expire-archive-folder-name-fmt
))
224 (src-folde-name (substring
225 (elmo-folder-name-internal src-folder
)
226 (length (elmo-folder-prefix-internal src-folder
))))
227 (archive-spec (char-to-string
228 (car (rassq 'archive elmo-folder-type-alist
))))
229 dst-folder-base dst-folder-fmt prefix
)
230 (cond (dst-folder-arg
231 (setq dst-folder-base
(concat archive-spec dst-folder-arg
)))
232 ((eq (elmo-folder-type-internal src-folder
) 'localdir
)
233 (setq dst-folder-base
234 (concat archive-spec src-folde-name
)))
236 (setq dst-folder-base
238 (format "%s%s" archive-spec
(elmo-folder-type-internal
241 (setq dst-folder-fmt
(format fmt
243 wl-expire-archive-folder-type
))
244 (setq dst-folder-base
(format "%s;%s"
246 wl-expire-archive-folder-type
))
247 (when wl-expire-archive-folder-prefix
248 (cond ((eq wl-expire-archive-folder-prefix
'short
)
249 (setq prefix
(file-name-nondirectory
252 (setq prefix src-folde-name
)))
253 (setq dst-folder-fmt
(concat dst-folder-fmt
";" prefix
))
254 (setq dst-folder-base
(concat dst-folder-base
";" prefix
)))
255 (cons dst-folder-base dst-folder-fmt
)))
257 (defsubst wl-expire-archive-get-max-number
(dst-folder-base &optional regexp
)
258 (let ((files (reverse (sort (elmo-folder-list-subfolders
259 (elmo-make-folder dst-folder-base
))
261 (regexp (or regexp wl-expire-archive-folder-num-regexp
))
265 (when (string-match regexp
(car files
))
266 (setq filenum
(elmo-match-string 1 (car files
)))
267 (setq in-folder
(elmo-folder-status
268 (wl-folder-get-elmo-folder (car files
))))
269 (throw 'done
(cons in-folder filenum
)))
270 (setq files
(cdr files
))))))
272 (defun wl-expire-archive-number-delete-old (dst-folder-base
273 preserve-number msgs folder
274 &optional no-confirm regexp file
)
275 (let ((len 0) (max-num 0)
277 (if (or (and file
(setq folder-info
278 (cons (elmo-folder-status
279 (wl-folder-get-elmo-folder file
))
281 (setq folder-info
(wl-expire-archive-get-max-number
285 (setq len
(cdar folder-info
))
286 (when preserve-number
287 ;; delete small number than max number of dst-folder
288 (setq max-num
(caar folder-info
))
289 (while (and msgs
(>= max-num
(car msgs
)))
290 (wl-append dels
(list (car msgs
)))
291 (setq msgs
(cdr msgs
)))
292 (setq dels
(wl-expire-delete-reserved-messages dels folder
))
294 (or (or no-confirm
(not
295 wl-expire-delete-oldmsg-confirm
))
297 (if (eq major-mode
'wl-summary-mode
)
298 (wl-thread-jump-to-msg (car dels
)))
299 (y-or-n-p (format "Delete old messages %s? "
302 (list msgs dels max-num
(cdr folder-info
) len
))
303 (list msgs dels
0 "0" 0))))
305 (defun wl-expire-archive-number1 (folder delete-list
306 &optional preserve-number dst-folder-arg
308 "Standard function for `wl-summary-expire'.
309 Refile to archive folder followed message number."
310 (let* ((elmo-archive-treat-file t
) ;; treat archive folder as a file.
311 (dst-folder-expand (and dst-folder-arg
314 (elmo-folder-name-internal folder
))))
315 (dst-folder-fmt (funcall
316 wl-expire-archive-get-folder-function
317 folder nil dst-folder-expand
))
318 (dst-folder-base (car dst-folder-fmt
))
319 (dst-folder-fmt (cdr dst-folder-fmt
))
320 (refile-func (if no-delete
322 'wl-expire-refile-with-copy-reserve-msg
))
324 prev-arcnum arcnum msg arcmsg-list
325 deleted-list ret-val
)
326 (setq tmp
(wl-expire-archive-number-delete-old
327 dst-folder-base preserve-number delete-list
330 (when (and (not no-delete
)
331 (setq dels
(nth 1 tmp
)))
332 (wl-append deleted-list
(car (wl-expire-delete folder dels
))))
333 (setq delete-list
(car tmp
))
336 (if (setq msg
(wl-pop delete-list
))
337 (setq arcnum
(/ msg wl-expire-archive-files
))
339 (when (and prev-arcnum
340 (not (eq arcnum prev-arcnum
)))
341 (setq dst-folder
(format dst-folder-fmt
342 (* prev-arcnum wl-expire-archive-files
)))
346 folder arcmsg-list dst-folder t preserve-number
348 (wl-append deleted-list
(car ret-val
)))
349 (setq arcmsg-list nil
))
352 (wl-append arcmsg-list
(list msg
))
353 (setq prev-arcnum arcnum
)))
356 (defun wl-expire-archive-number2 (folder delete-list
357 &optional preserve-number dst-folder-arg
359 "Standard function for `wl-summary-expire'.
360 Refile to archive folder followed the number of message in one archive folder."
361 (let* ((elmo-archive-treat-file t
) ;; treat archive folder as a file.
362 (dst-folder-expand (and dst-folder-arg
365 (elmo-folder-name-internal folder
))))
366 (dst-folder-fmt (funcall
367 wl-expire-archive-get-folder-function
368 folder nil dst-folder-expand
))
369 (dst-folder-base (car dst-folder-fmt
))
370 (dst-folder-fmt (cdr dst-folder-fmt
))
371 (refile-func (if no-delete
373 'wl-expire-refile-with-copy-reserve-msg
))
376 arc-len msg arcmsg-list
377 deleted-list ret-val
)
378 (setq tmp
(wl-expire-archive-number-delete-old
379 dst-folder-base preserve-number delete-list
382 (when (and (not no-delete
)
383 (setq dels
(nth 1 tmp
)))
384 (wl-append deleted-list
(car (wl-expire-delete folder dels
))))
385 (setq delete-list
(car tmp
)
386 filenum
(string-to-number (nth 3 tmp
))
391 (if (setq msg
(wl-pop delete-list
))
393 (setq len
(1+ wl-expire-archive-files
)))
394 (when (> len wl-expire-archive-files
)
396 (setq dst-folder
(format dst-folder-fmt filenum
))
400 folder arcmsg-list dst-folder t preserve-number
402 (wl-append deleted-list
(car ret-val
)))
403 (setq arc-len
(+ arc-len
(cdr ret-val
))))
404 (setq arcmsg-list nil
)
405 (if (< arc-len wl-expire-archive-files
)
406 (setq len
(1+ arc-len
))
407 (setq filenum
(+ filenum wl-expire-archive-files
)
408 len
(- len arc-len
) ;; maybe 1
409 arc-len
(1- len
) ;; maybe 0
413 (wl-append arcmsg-list
(list msg
))))
416 (defun wl-expire-archive-date (folder delete-list
417 &optional preserve-number dst-folder-arg
419 "Standard function for `wl-summary-expire'.
420 Refile to archive folder followed message date."
421 (let* ((elmo-archive-treat-file t
) ;; treat archive folder as a file.
422 (dst-folder-expand (and dst-folder-arg
425 (elmo-folder-name-internal folder
))))
426 (dst-folder-fmt (funcall
427 wl-expire-archive-get-folder-function
429 wl-expire-archive-date-folder-name-fmt
432 (dst-folder-base (car dst-folder-fmt
))
433 (dst-folder-fmt (cdr dst-folder-fmt
))
434 (refile-func (if no-delete
436 'wl-expire-refile-with-copy-reserve-msg
))
437 tmp dels dst-folder date time
438 msg arcmsg-alist arcmsg-list
439 deleted-list ret-val
)
440 (setq tmp
(wl-expire-archive-number-delete-old
441 dst-folder-base preserve-number delete-list
444 wl-expire-archive-date-folder-num-regexp
))
445 (when (and (not no-delete
)
446 (setq dels
(nth 1 tmp
)))
447 (wl-append deleted-list
(car (wl-expire-delete folder dels
))))
448 (setq delete-list
(car tmp
))
449 (while (setq msg
(wl-pop delete-list
))
450 (setq time
(or (elmo-time-to-datevec
451 (elmo-message-field folder msg
'date
))
453 (if (= (aref time
1) 0) ;; if (month == 0)
454 (aset time
0 0)) ;; year = 0
455 (setq dst-folder
(format dst-folder-fmt
456 (aref time
0) ;; year
457 (aref time
1) ;; month
460 (wl-append-assoc-list
465 (setq dst-folder
(caar arcmsg-alist
))
466 (setq arcmsg-list
(cdar arcmsg-alist
))
470 folder arcmsg-list dst-folder t preserve-number
472 (wl-append deleted-list
(car ret-val
)))
473 (setq arcmsg-alist
(cdr arcmsg-alist
)))
476 ;;; wl-expire-localdir-date
477 (defvar wl-expire-localdir-date-folder-name-fmt
"%s/%%04d_%%02d")
479 (defcustom wl-expire-localdir-get-folder-function
480 'wl-expire-localdir-get-folder
481 "*A function to get localdir folder name."
485 (defun wl-expire-localdir-get-folder (src-folder fmt dst-folder-arg
)
486 "Get localdir folder name from src-folder."
487 (let* ((src-folder-name (substring
488 (elmo-folder-name-internal src-folder
)
489 (length (elmo-folder-prefix-internal src-folder
))))
490 (dst-folder-spec (char-to-string
491 (car (rassq 'localdir elmo-folder-type-alist
))))
492 dst-folder-base dst-folder-fmt
)
493 (cond (dst-folder-arg
494 (setq dst-folder-base
(concat dst-folder-spec dst-folder-arg
)))
495 ((eq (elmo-folder-type-internal src-folder
) 'localdir
)
496 (setq dst-folder-base
(concat dst-folder-spec src-folder-name
)))
498 (setq dst-folder-base
502 (elmo-folder-type-internal src-folder
))
505 (format fmt dst-folder-base
))
506 (cons dst-folder-base dst-folder-fmt
)))
508 (defun wl-expire-localdir-date (folder delete-list
509 &optional preserve-number dst-folder-arg
511 "Function for `wl-summary-expire'.
512 Refile to localdir folder by message date.
513 ex. +ml/wl/1999_11/, +ml/wl/1999_12/."
514 (let* ((dst-folder-expand (and dst-folder-arg
517 (elmo-folder-name-internal folder
))))
518 (dst-folder-fmt (funcall
519 wl-expire-localdir-get-folder-function
521 wl-expire-localdir-date-folder-name-fmt
523 (dst-folder-base (car dst-folder-fmt
))
524 (dst-folder-fmt (cdr dst-folder-fmt
))
525 (refile-func (if no-delete
527 'wl-expire-refile-with-copy-reserve-msg
))
528 tmp dels dst-folder date time
529 msg arcmsg-alist arcmsg-list
530 deleted-list ret-val
)
531 (while (setq msg
(wl-pop delete-list
))
532 (setq time
(or (elmo-time-to-datevec
533 (elmo-message-field folder msg
'date
))
535 (if (= (aref time
1) 0) ;; if (month == 0)
536 (aset time
0 0)) ;; year = 0
537 (setq dst-folder
(format dst-folder-fmt
539 (aref time
1);; month
542 (wl-append-assoc-list
547 (setq dst-folder
(caar arcmsg-alist
))
548 (setq arcmsg-list
(cdar arcmsg-alist
))
552 folder arcmsg-list dst-folder t preserve-number
554 (wl-append deleted-list
(car ret-val
)))
555 (setq arcmsg-alist
(cdr arcmsg-alist
)))
558 (defun wl-expire-hide (folder hide-list
&optional no-reserve-marks
)
559 "Hide message for expire."
560 (unless no-reserve-marks
562 (wl-expire-delete-reserved-messages hide-list folder
)))
563 (let ((mess (format "Hiding %s msgs..." (length hide-list
))))
565 (elmo-folder-detach-messages folder hide-list
)
566 (elmo-folder-kill-messages folder hide-list
)
567 (elmo-folder-commit folder
)
568 (message "%sdone" mess
)
569 (cons hide-list
(length hide-list
))))
571 (defsubst wl-expire-folder-p
(entity)
572 "Return non-nil, when ENTITY matched `wl-expire-alist'."
573 (wl-get-assoc-list-value wl-expire-alist entity
))
575 (defsubst wl-archive-folder-p
(entity)
576 "Return non-nil, when ENTITY matched `wl-archive-alist'."
577 (wl-get-assoc-list-value wl-archive-alist entity
))
579 (defun wl-summary-expire (&optional folder notsummary all
)
580 "Expire messages of current summary."
582 (list wl-summary-buffer-elmo-folder
585 (let* ((folder (or folder wl-summary-buffer-elmo-folder
))
586 (folder-name (elmo-folder-name-internal folder
))
587 (rule (wl-expire-folder-p folder-name
)))
590 (error "No match %s in `wl-expire-alist'" folder-name
))
591 (when (or (not (interactive-p))
592 (y-or-n-p (format "Expire %s? " folder-name
)))
594 (run-hooks 'wl-summary-expire-pre-hook
)
595 (let* ((keep-reserved (or (not (interactive-p))
596 (y-or-n-p (format "Keep reserved marks?"))))
597 (expireable (apply #'wl-expireable-messages-list folder
599 (expired (and expireable
600 (or (not (interactive-p))
601 (y-or-n-p (format "Expire %d messages?"
602 (length expireable
))))
603 (wl-expire-folder folder expireable
(car rule
)
604 (cadr rule
) (not keep-reserved
)))))
605 (when (and (not wl-expire-test
)
608 (wl-summary-delete-messages-on-buffer expired
)
609 (wl-summary-folder-info-update)
610 (wl-summary-set-message-modified)
612 (set-buffer-modified-p nil
))
613 (run-hooks 'wl-summary-expire-hook
)
615 (message "Expiring %s is done" folder-name
)
617 (message "No expire")))
620 (defun wl-expireable-messages-list (folder all condition action
&rest args
)
621 (let ((val-type (car condition
))
622 (value (nth 1 condition
))
626 ((eq val-type
'number
)
627 (let* ((msgs (elmo-folder-list-messages folder
(not all
) (not all
)))
628 (msglen (length msgs
))
630 (when (>= msglen
(or (nth 2 condition
) (1+ value
)))
631 (setq count
(- msglen value
))
632 (while (and msgs
(> count
0))
633 (when (elmo-message-entity folder
(car msgs
))
634 ;; don't expire new message
635 (wl-append targets
(list (car msgs
)))
636 (when (or (not wl-expire-number-with-reserve-marks
)
637 (wl-expire-message-p folder
(car msgs
)))
638 (setq count
(1- count
))))
639 (setq msgs
(cdr msgs
))))))
641 (let ((key-date (elmo-datevec-to-time
642 (elmo-date-get-offset-datevec
643 (timezone-fix-time (current-time-string)
644 (current-time-zone) nil
)
646 (elmo-folder-do-each-message-entity (entity folder
)
648 (elmo-message-entity-field entity
'date
)
651 (list (elmo-message-entity-number entity
)))))))
653 (error "%s: not supported" val-type
)))
656 (defun wl-expire-folder (folder targets condition action
&rest args
)
657 (let ((folder-name (elmo-folder-name-internal folder
)))
660 (setq wl-expired-alist
(wl-expired-alist-load)))
661 ;; evaluate string-match for wl-expand-newtext
662 (wl-expire-folder-p folder-name
)
664 (cond ((eq action nil
) nil
)
666 (car (wl-expire-delete folder targets
(car args
))))
668 (car (wl-expire-refile folder targets wl-trash-folder
)))
670 (car (wl-expire-hide folder targets
)))
672 (car (wl-expire-refile
675 (wl-expand-newtext action folder-name
))))
677 (apply action folder targets args
))
679 (error "%s: invalid type" action
)))
680 (wl-expired-alist-save)))))
682 (defun wl-folder-expire-entity (entity)
685 (let ((flist (nth 2 entity
)))
687 (wl-folder-expire-entity (car flist
))
688 (setq flist
(cdr flist
)))))
690 (when (wl-expire-folder-p entity
)
691 (let ((folder (wl-folder-get-elmo-folder entity
))
692 (summary (wl-summary-get-buffer entity
))
694 ((consp wl-expire-folder-update-msgdb
)
695 (wl-string-match-member
697 wl-expire-folder-update-msgdb
))
699 wl-expire-folder-update-msgdb
))))
701 (wl-folder-sync-entity entity
))
703 (save-selected-window
704 (with-current-buffer summary
705 (let ((win (get-buffer-window summary t
)))
707 (select-window win
)))
708 (when (wl-summary-expire folder
)
709 (wl-summary-save-status))))
710 (when (wl-summary-expire folder
'no-summary
)
711 (wl-folder-check-entity entity
))))))))
715 (defun wl-folder-expire-current-entity ()
717 (let ((entity-name (wl-folder-get-entity-from-buffer))
718 (type (if (wl-folder-buffer-group-p)
721 (when (and entity-name
722 (or (not (interactive-p))
723 (y-or-n-p (format "Expire %s? " entity-name
))))
724 (wl-folder-expire-entity
725 (wl-folder-search-entity-by-name entity-name
728 (message "Expiring %s is done" entity-name
))))
732 (defun wl-folder-archive-current-entity ()
734 (let ((entity-name (wl-folder-get-entity-from-buffer))
735 (type (if (wl-folder-buffer-group-p)
738 (when (and entity-name
739 (or (not (interactive-p))
740 (y-or-n-p (format "Archive %s? " entity-name
))))
741 (wl-folder-archive-entity
742 (wl-folder-search-entity-by-name entity-name
745 (message "Archiving %s is done" entity-name
))))
747 (defun wl-archive-number1 (folder archive-list
&optional dst-folder-arg
)
748 (wl-expire-archive-number1 folder archive-list t dst-folder-arg t
))
750 (defun wl-archive-number2 (folder archive-list
&optional dst-folder-arg
)
751 (wl-expire-archive-number2 folder archive-list t dst-folder-arg t
))
753 (defun wl-archive-date (folder archive-list
&optional dst-folder-arg
)
754 (wl-expire-archive-date folder archive-list t dst-folder-arg t
))
756 (defun wl-archive-folder (folder archive-list dst-folder
)
757 (let* ((elmo-archive-treat-file t
) ;; treat archive folder as a file.
760 (car (wl-expire-archive-number-delete-old
768 folder archive-list dst-folder t t t
)) ;; copy!!
769 (wl-append copied-list ret-val
)))
772 (defun wl-summary-archive (&optional arg folder notsummary nolist
)
775 (let* ((folder (or folder wl-summary-buffer-elmo-folder
))
776 (msgs (if (not nolist
)
777 (elmo-folder-list-messages folder
)
778 (elmo-folder-list-messages folder
'visible
'in-msgdb
)))
779 (alist wl-archive-alist
)
780 archives func args dst-folder archive-list
)
782 (let ((wl-default-spec (char-to-string
784 elmo-folder-type-alist
)))))
785 (setq dst-folder
(wl-summary-read-folder
786 (concat wl-default-spec
788 (elmo-folder-name-internal folder
) 1))
790 (run-hooks 'wl-summary-archive-pre-hook
)
792 (wl-archive-folder folder msgs dst-folder
)
793 (when (and (or (setq archives
(wl-archive-folder-p
794 (elmo-folder-name-internal folder
)))
795 (progn (and (interactive-p)
796 (message "No match %s in wl-archive-alist"
797 (elmo-folder-name-internal folder
)))
799 (or (not (interactive-p))
800 (y-or-n-p (format "Archive %s? "
801 (elmo-folder-name-internal folder
)))))
802 (setq func
(car archives
)
805 (apply func
(append (list folder msgs
) args
)))
806 (run-hooks 'wl-summary-archive-hook
)
808 (message "Archiving %s is done" (elmo-folder-name-internal folder
))
810 (message "No archive")))))))
812 (defun wl-folder-archive-entity (entity)
815 (let ((flist (nth 2 entity
)))
817 (wl-folder-archive-entity (car flist
))
818 (setq flist
(cdr flist
)))))
820 (wl-summary-archive nil
(wl-folder-get-elmo-folder entity
) t
))))
824 (defun wl-expire-append-log (src-folder msgs dst-folder action
)
825 (when wl-expire-use-log
827 (let ((tmp-buf (get-buffer-create " *wl-expire work*"))
828 (filename (expand-file-name wl-expired-log-alist-file-name
829 elmo-msgdb-directory
)))
833 (insert (format "%s\t%s -> %s\t%s\n"
835 src-folder dst-folder msgs
))
836 (insert (format "%s\t%s\t%s\n"
839 (if (file-writable-p filename
)
840 (write-region (point-min) (point-max)
842 (message "%s is not writable." filename
))
843 (kill-buffer tmp-buf
)))))
846 (product-provide (provide 'wl-expire
) (require 'wl-version
))
848 ;;; wl-expire.el ends here