(gnus-offline-menu): New variable.
[elisp/gnus.git-] / lisp / gnus-offline.el
1 ;;; gnus-offline.el --- To process mail & news at offline environment.
2 ;;; $Id: gnus-offline.el,v 1.1.2.5.2.36.4.6 1999-09-11 19:30:33 czkmt Exp $
3
4 ;;; Copyright (C) 1998 Tatsuya Ichikawa
5 ;;;                    Yukihiro Ito
6 ;;; Author: Tatsuya Ichikawa <t-ichi@po.shiojiri.ne.jp>
7 ;;;         Yukihiro Ito <ito@rs.civil.tohoku.ac.jp>
8 ;;;         Hidekazu Nakamura <u90121@uis-inf.co.jp>
9 ;;;         Tsukamoto Tetsuo <czkmt@remus.dti.ne.jp>
10
11 ;;; Version: 2.20
12 ;;; Keywords: news , mail , offline , gnus
13 ;;;
14 ;;; SPECIAL THANKS
15 ;;;    Keiichi Suzuki <kei-suzu@mail.wbs.or.jp>
16 ;;;    KORIYAMA Naohiro <kory@ba2.so-net.or.jp>
17 ;;;    Katsumi Yamaoka <yamaoka@jpl.org>
18
19 ;;; This file is part of Semi-gnus.
20 ;;;
21 ;;; GNU Emacs is free software; you can redistribute it and/or modify
22 ;;; it under the terms of the GNU General Public License as published by
23 ;;; the Free Software Foundation; either version 2, or (at your option)
24 ;;; any later version.
25
26 ;;; GNU Emacs is distributed in the hope that it will be useful,
27 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
28 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 ;;; GNU General Public License for more details.
30
31 ;;; You should have received a copy of the GNU General Public License
32 ;;; along with GNU Emacs; see the file COPYING.  If not, write to the
33 ;;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
34 ;;; Boston, MA 02111-1307, USA.
35 ;;;
36 ;;;; Commentary:
37 ;;; Note.
38 ;;;   This file works only with after version of Emacs 19.30.
39 ;;;   This file needs miee.el and SEMI.
40 ;;;   If you set gnus-offline-drafts-queue-type to 'agent , you don't need 
41 ;;;   miee.el
42 ;;;   You must use T-gnus 6.12.0 or later.
43 ;;;
44 ;;; How to use.
45 ;;;
46 ;;; Add following code at the end in your .emacs
47 ;;;
48 ;;;    (load "gnus-ofsetup")
49 ;;;    (gnus-setup-for-offline)
50 ;;;
51 ;;; If you use gnus-agent as souper , put gnus-agent setup code in you .gnus.el
52 ;;;
53 ;;; If you use nnspool as souper , put following code in your .emacs before
54 ;;; gnus-offline setting.
55 ;;;
56 ;;; Then , put hang.exe in exec-path directory.
57 ;;;
58 ;;; In Gnus group buffer , type g to get all news and mail.
59 ;;; Then send mail and news in spool directory.
60 ;;;
61 ;;; Variables.
62 ;;;  gnus-offline-dialup-program-arguments
63 ;;;                                   ... List of dialup program arguments.
64 ;;;  gnus-offline-hangup-program-arguments
65 ;;;                                   ... List of hangup program arguments.
66 ;;;  gnus-offline-mail-treat-environ  ... toggle sending mail online/offline.
67 ;;;  gnus-offline-articles-to-fetch   ... toggle fetch articles.
68 ;;;                                        both->mail->news->both...
69 ;;;  gnus-offline-load-hook           ... hook before gnus-offline load.
70 ;;;  gnus-offline-before-online-hook  ... hook before all online jobs.
71 ;;;  gnus-offline-after-online-hook   ... hook after all online jobs.
72 ;;;  gnus-offline-interval-time       ... Interval time to do all online jobs.
73 ;;;                                        (minutes)
74 ;;;  gnus-offline-dialup-function     ... Function to diualup.
75 ;;;  gnus-offline-hangup-function     ... Function to hangup.
76
77 ;;; Code:
78
79 (eval '(run-hooks 'gnus-offline-load-hook))
80
81 (require 'cl)
82 (require 'custom)
83 (require 'easymenu)
84 (provide 'gnus-offline)
85
86 (defgroup gnus-offline nil
87   "Offline backend utility for Gnus."
88   :prefix "gnus-offline-"
89   :group 'gnus
90   :group 'mail
91   :group 'news)
92
93 (defconst gnus-offline-version-number "2.20")
94 (defconst gnus-offline-codename
95 ;;  "Beta5"                     ; Beta
96 ;;  "This is the time"          ; 2.00
97 ;;  "A matter of trust"
98 ;;  "Modern Woman"
99 ;;  "Ahhhhhhh!!"                ; 2.10b1
100   "Cup of life"                 ; 2.20
101 ;;  "Code of silence"
102   )
103
104 (defconst gnus-offline-version (format "Gnus offline backend utiliy v%s"
105                                        gnus-offline-version-number))
106
107 (eval-when-compile
108   (mapc
109    #'(lambda (symbol)
110        (unless (boundp symbol)
111          (make-local-variable symbol)
112          (eval (list 'setq symbol nil))))
113    '(nnagent-version
114      nnspool-version
115      msspool-news-server
116      msspool-news-service
117      miee-popup-menu
118      gnus-group-toolbar))
119   (mapc
120    #'(lambda (symbol)
121        (unless (fboundp symbol)
122          (defalias symbol 'ignore)))
123    '(general-process-argument-editing-function
124      define-process-argument-editing
125      gnspool-get-news
126      mail-spool-send
127      news-spool-post)))
128
129 (put 'gnus-offline-set-unplugged-state 'menu-enable 'gnus-offline-connected)
130 (if (eq system-type 'windows-nt)
131     (define-process-argument-editing "/hang\\.exe\\'"
132       (lambda (x)
133         (general-process-argument-editing-function
134          x nil t t nil t t))))
135
136 (defcustom gnus-offline-auto-hangup t
137   "*Whether dialup-network automatically hang up when all online jobs has done."
138   :group 'gnus-offline
139   :type 'boolean)
140
141 (defcustom gnus-offline-load-hook nil
142   "*Hook to be run after the gnus-offline package has been loaded."
143   :group 'gnus-offline
144   :type 'hook)
145
146 (defcustom gnus-offline-before-online-hook nil
147   "*Hook to be run before all online jobs."
148   :group 'gnus-offline
149   :type 'hook)
150
151 (defcustom gnus-offline-after-online-hook nil
152   "*Hook to be run after all online jobs."
153   :group 'gnus-offline
154   :type 'hook)
155
156 (defcustom gnus-offline-mail-treat-environ 'offline
157   "*If online , gnus-offline send all mail under online environ.
158 If offline , gnus-offline send all mail temporary to spool dir."
159   :group 'gnus-offline
160   :type '(choice (const offline)
161                  (const online)))
162
163 (defcustom gnus-offline-articles-to-fetch 'both
164   "*If both , gnus-offline fetch mail and news articles.
165 If mail , gnus-offline only fetch mail articles.
166  If news , gnus-offline only fetch news articles."
167   :group 'gnus-offline
168   :type '(choice (const both)
169                  (const mail)
170                  (const news)))
171
172 (defcustom gnus-offline-mail-group-level 1
173   "*Group level for mail group."
174   :group 'gnus-offline
175   :type 'integer)
176
177 (defcustom gnus-offline-after-empting-spool-hook nil
178   "*Hook to be run before empting spool."
179   :group 'gnus-offline
180   :type 'hook)
181
182 (defcustom gnus-offline-before-empting-spool-hook nil
183   "*Hook to be run after empting spool."
184   :group 'gnus-offline
185   :type 'hook)
186
187 (defcustom gnus-offline-dialup-function 'gnus-offline-connect-server
188   "*Function to dialup."
189   :group 'gnus-offline
190   :type 'function)
191
192 (defcustom gnus-offline-hangup-function 'gnus-offline-hangup-line
193   "*Function to hangup."
194   :group 'gnus-offline
195   :type 'function)
196
197 (defcustom gnus-offline-agent-automatic-expire t
198   "*Non-nil means expire articles on every session."
199   :group 'gnus-offline
200   :type 'boolean)
201
202 ;; These variables should be customized using `gnus-offline-customize',
203 ;; not by `customize'.
204
205 (defvar gnus-offline-dialup-program nil
206   "*Program name for dialup.")
207
208 (defvar gnus-offline-hangup-program nil
209   "*Program name for hangup.")
210
211 (defvar gnus-offline-dialup-program-arguments nil
212   "*Program arguments of gnus-offline-dialup-program.")
213
214 (defvar gnus-offline-hangup-program-arguments nil
215   "*Program arguments of gnus-offline-hangup-program.")
216
217 (defvar gnus-offline-interval-time 0
218   "*Interval time(minutes) to do online jobs.
219 If set to 0 , timer call is disabled.")
220
221 (defvar gnus-offline-drafts-queue-type 'agent
222   "*Queuing function used for draft messages.")
223
224 (defvar gnus-offline-MTA-type 'smtp
225   "*Type of MTA, sendmail or smtp.el.")
226
227 ;;; Internal variables.
228 (defvar gnus-offline-connected nil
229   "*If value is t , dialup line is connected status.
230 If value is nil , dialup line is disconnected status.")
231
232 (defvar gnus-offline-news-fetch-method nil
233   "*Method to fetch news articles.")
234
235 (defvar gnus-offline-mail-fetch-method nil
236   "*Method to fetch mail articles.")
237
238 (defvar gnus-offline-header-string
239   (format "%s - \"%s\""
240           gnus-offline-version
241           gnus-offline-codename)
242   "*Header string for gnus-offline.")
243
244 (defvar gnus-offline-stored-group-level nil
245   "*Mail Group level before changing.")
246
247 (defvar gnus-offline-mail-source nil
248   "*mail-sources save variable.")
249
250 (defvar gnus-offline-lang)
251
252 (defvar gnus-offline-resource-en
253   '((error-check-1
254      . "WARNING!!: gnus-agent.el or nnagent.el is not loaded.
255 Please check your .emacs or .gnus.el to work gnus-agent fine.")
256     (error-check-2 ."WARNING!!: nnspool.el is not loaded.
257 Please check your .emacs or .gnus.el to work nnspool fine.")
258     (connect-server-1 . "Dialing ...")
259     (connect-server-2 . "Dialing ... done.")
260     (get-new-news-function-1 . "Set to online status.")
261     (hangup-line-1 . "Hang up line ... ")
262     (hangup-line-2 . "Hang up line ... done.")
263     (after-jobs-done-1 . "All online jobs has done.")
264     (toggle-auto-hangup-1 . "Auto hang up logic")
265     (toggle-auto-hangup-2 . "disabled.")
266     (toggle-auto-hangup-3 . "enabled.")
267     (toggle-on/off-send-mail-1 . "Sending mail immidiately.")
268     (toggle-on/off-send-mail-2 . "Sending mail temporary to spool directory.")
269     (toggle-articles-to-fetch-1 . "Articles fetch from server.")
270     (toggle-articles-to-fetch-2 . "Only Mail")
271     (toggle-articles-to-fetch-3 . "Only News")
272     (toggle-articles-to-fetch-4 . "Mail/News both")
273     (empting-spool-1 . "Sending mails in spool ...")
274     (empting-spool-2 . "Sending mails in spool ... done.")
275     (empting-spool-3 . "Posting news in spool ...")
276     (empting-spool-4 . "Posting news in spool ... done.")
277     (empting-spool-5 . "Sending messages in spool ...")
278     (empting-spool-6 . "Sending messages in spool ... done.")
279     (interval-time-1 . "Interval time (now %d minutes) : ")
280     (interval-time-2 . "Retrieving message logic by timer is disabled.")
281     (interval-time-3 . "Interval time set to %d minutes")
282     (menu-miee-1 . "Post news in spool")
283     (menu-miee-2 . "Send mails in spool")
284     (menu-miee-3 . "Message Offline")
285     (menu-miee-4 . "Message Online")
286     (menu-1 . "Toggle articles to fetch")
287     (menu-2 . "Toggle online/offline send mail")
288     (menu-3 . "Toggle auto hangup")
289     (menu-4 . "Expire articles")
290     (menu-5 . "Set interval time")
291     (menu-6 . "Hang up Line.")
292     (menu-7 . "Customize options...")))
293
294 (defvar gnus-offline-resource-ja
295   '((error-check-1
296      . "\e$B7Y9p\e(B!!: gnus-agent.el \e$B$^$?$O\e(B nnagent.el \e$B$,%m!<%I$5$l$F$$$^$;$s!#\e(B
297 .emacs \e$B$^$?$O\e(B .gnus.el \e$B$N\e(B gnus-agent \e$B$N@_Dj$r@5$7$/$7$F$/$@$5$$!#\e(B")
298     (error-check-2 ."\e$B7Y9p\e(B!!: nnspool.el \e$B$,%m!<%I$5$l$F$$$^$;$s!#\e(B
299 .emacs \e$B$^$?$O\e(B .gnus.el \e$B$N\e(B nnspool \e$B$N@_Dj$r@5$7$/$7$F$/$@$5$$!#\e(B")
300     (connect-server-1 . "\e$B%@%$%d%k$7$F$$$^$9\e(B...")
301     (connect-server-2 . "\e$B%@%$%d%k$7$F$$$^$9\e(B...\e$B40N;!#\e(B")
302     (get-new-news-function-1 . "\e$B%*%s%i%$%s>uBV$G$9!#\e(B")
303     (hangup-line-1 . "\e$B@ZCG$7$F$$$^$9\e(B...")
304     (hangup-line-2 . "\e$B@ZCG$7$F$$$^$9\e(B...\e$B40N;!#\e(B")
305     (after-jobs-done-1 . "\e$BA4$F$N%*%s%i%$%s=hM}$r40N;$7$^$7$?!#\e(B")
306     (toggle-auto-hangup-1 . "\e$B<+F0@ZCG5!G=$r\e(B ")
307     (toggle-auto-hangup-2 . "\e$B%*%U\e(B \e$B$K$7$^$7$?!#\e(B")
308     (toggle-auto-hangup-3 . "\e$B%*%s\e(B \e$B$K$7$^$7$?!#\e(B")
309     (toggle-on/off-send-mail-1 . "\e$B%a!<%k$rD>@\Aw?.$7$^$9!#\e(B")
310     (toggle-on/off-send-mail-2 . "\e$B%a!<%k$O%-%e!<$KAw$i$l$^$9!#\e(B")
311     (toggle-articles-to-fetch-1 . "\e$B<u?.$9$k%a%C%;!<%8$O\e(B... ")
312     (toggle-articles-to-fetch-2 . "\e$B%a!<%k$N$_$G$9!#\e(B")
313     (toggle-articles-to-fetch-3 . "\e$B%K%e!<%9$N$_$G$9!#\e(B")
314     (toggle-articles-to-fetch-4 . "\e$B%a!<%k$H%K%e!<%9$NN>J}$G$9!#\e(B")
315     (empting-spool-1 . "\e$B%-%e!<$N%a!<%k$rAw?.Cf\e(B...")
316     (empting-spool-2 . "\e$B%-%e!<$N%a!<%k$rAw?.Cf\e(B... \e$B40N;!#\e(B")
317     (empting-spool-3 . "\e$B%-%e!<$N%K%e!<%95-;v$rAw?.Cf\e(B...")
318     (empting-spool-4 . "\e$B%-%e!<$N%K%e!<%95-;v$rAw?.Cf\e(B... \e$B40N;!#\e(B")
319     (empting-spool-5 . "\e$B%-%e!<$N%a%C%;!<%8$rAw?.Cf\e(B...")
320     (empting-spool-6 . "\e$B%-%e!<$N%a%C%;!<%8$rAw?.Cf\e(B... \e$B40N;!#\e(B")
321     (interval-time-1 . "\e$BAw<u?.%8%g%V$N4V3V\e(B (\e$B8=:_$N@_Dj$O\e(B %d \e$BJ,$G$9\e(B) : ")
322     (interval-time-2 . "\e$B<+F0Aw<u?.5!G=$r\e(B \e$B%*%U\e(B \e$B$K$7$^$7$?!#\e(B")
323     (interval-time-3 . "\e$B<+F0Aw<u?.$N4V3V$r\e(B %d \e$BJ,$K@_Dj$7$^$7$?!#\e(B")))
324
325 (defvar gnus-offline-resource-ja_complete
326   (append
327    gnus-offline-resource-ja
328    '((menu-miee-1 . "Spool \e$B$K$"$k5-;v$NAw?.\e(B")
329      (menu-miee-2 . "Spool \e$B$K$"$k\e(B Mail \e$B$NAw?.\e(B")
330      (menu-miee-3 . "Offline \e$B>uBV$X\e(B")
331      (menu-miee-4 . "Online \e$B>uBV$X\e(B")
332      (menu-1 . "\e$B<hF@5-;v<oN`$NJQ99\e(B")
333      (menu-2 . "Mail \e$BAw?.J}K!\e(B(On/Off)\e$B$N@ZBX$(\e(B")
334      (menu-3 . "\e$B<+F0@ZCG$N@ZBX$(\e(B")
335      (menu-4 . "\e$B<hF@:Q5-;v$r>C$9\e(B")
336      (menu-5 . "\e$B5-;v<hF@4V3V;~4V$N@_Dj\e(B")
337      (menu-6 . "\e$B2s@~$N@ZCG\e(B")
338      (menu-7 . "\e$B%W%m%Q%F%#\e(B..."))))
339
340 ;;; Functions
341
342 (defun gnus-offline-get-message (symbol &optional lang)
343   (setq lang (or lang gnus-offline-lang))
344   (or
345    (cdr (assq symbol (symbol-value
346                       (intern (format "gnus-offline-resource-%s" lang)))))
347    (cdr (assq symbol gnus-offline-resource-en))))
348
349 ;;
350 ;; Setting up...
351 ;;
352 (defun gnus-offline-setup ()
353   "*Initialize gnus-offline function"
354
355   ;; Menu and keymap
356   (gnus-offline-define-menu-and-key)
357   
358   ;; To transfer Mail/News function.
359   (cond ((eq gnus-offline-mail-treat-environ 'offline)
360          ;; send mail under offline environ.
361          (gnus-offline-set-offline-sendmail-function))
362         ((eq gnus-offline-mail-treat-environ 'online)
363          ;; send mail under offline environ.
364          (gnus-offline-set-online-sendmail-function))))
365
366 ;;
367 ;; Setting Error check.
368 (defun gnus-offline-error-check ()
369   ;; Check gnus-agent and nnspool setting.
370   (let ((buffer " *Offline Error*"))
371     (cond ((eq gnus-offline-news-fetch-method 'nnagent)
372            ;; nnagent and gnus-agent loaded ??
373            (unless (and (featurep 'gnus-agent)
374                         (featurep 'nnagent))
375              (set-buffer (gnus-get-buffer-create buffer))
376              (erase-buffer)
377              (insert (gnus-offline-get-message 'error-check-1))
378              (pop-to-buffer buffer)))
379         
380           ((eq gnus-offline-news-fetch-method 'nnspool)
381            (unless (featurep 'nnspool)
382              (set-buffer (gnus-get-buffer-create buffer))
383              (erase-buffer)
384              (insert (gnus-offline-get-message 'error-check-2))
385              (pop-to-buffer buffer)))
386           (t
387            nil))))
388 ;;
389 ;;
390 (defun gnus-offline-set-offline-sendmail-function ()
391   "*Initialize sendmail-function when unplugged status."
392   (cond ((eq gnus-offline-drafts-queue-type 'miee)
393          (if (eq gnus-offline-news-fetch-method 'nnagent)
394              (setq gnus-agent-send-mail-function
395                    'sendmail-to-spool-in-gnspool-format))
396          (setq message-send-mail-function 'sendmail-to-spool-in-gnspool-format))
397         (t
398          (setq gnus-agent-send-mail-function
399                (gnus-offline-set-online-sendmail-function)
400                message-send-mail-function 'gnus-agent-send-mail))))
401 ;;
402 (defun gnus-offline-set-online-sendmail-function ()
403   "*Initialize sendmail-function when plugged status."
404   (if (eq gnus-offline-MTA-type 'smtp)
405       (setq message-send-mail-function 'message-send-mail-with-smtp)
406     (setq message-send-mail-function 'message-send-mail-with-sendmail)))
407 ;;
408 (defun gnus-offline-set-offline-post-news-function ()
409   "*Initialize sendnews-function when unplugged status."
410   (if (eq gnus-offline-drafts-queue-type 'miee)
411       (setq message-send-news-function 'gnspool-request-post)))
412 ;;
413 (defun gnus-offline-set-online-post-news-function ()
414   "*Initialize sendnews-function when plugged status."
415   (setq message-send-news-function 'message-send-news-with-gnus))
416 ;;
417 ;; Get new news jobs. (gnus-agent and nnspool)
418 ;;
419 (defun gnus-offline-gnus-get-new-news (&optional arg)
420   "*Override function \"gnus-group-get-new-news\"."
421   (interactive "P")
422   (run-hooks 'gnus-offline-before-online-hook)
423   (if (functionp gnus-offline-dialup-function)
424       (funcall gnus-offline-dialup-function))
425   (gnus-offline-get-new-news-function)
426   (gnus-group-get-new-news arg))
427
428 ;;
429 ;; dialup...
430 ;;
431 (defun gnus-offline-connect-server ()
432   "*Dialup function."
433   ;; Dialup if gnus-offline-dialup-program is specified
434   (if (stringp gnus-offline-dialup-program)
435       (progn
436         (message (gnus-offline-get-message 'connect-server-1))
437         (apply 'call-process gnus-offline-dialup-program nil nil nil
438                gnus-offline-dialup-program-arguments)
439         (sleep-for 1)
440         (message (gnus-offline-get-message 'connect-server-2)))))
441
442 ;;
443 ;; Jobs before get new news , send mail and post news.
444 ;;
445 (defun gnus-offline-get-new-news-function ()
446   "*Prepare to get new news/mail."
447   ;; Set mail group level
448   (if (eq gnus-offline-articles-to-fetch 'mail)
449       (gnus-offline-set-mail-group-level gnus-offline-mail-group-level))
450
451   ;; Set to online environ.
452   (setq gnus-offline-connected t)
453
454   ;; Set send mail/news functions to online functions.
455   (gnus-offline-set-online-sendmail-function)
456   (gnus-offline-set-online-post-news-function)
457   (message (gnus-offline-get-message 'get-new-news-function-1))
458
459   ;; fetch only news
460   (if (eq gnus-offline-articles-to-fetch 'news)
461       (gnus-offline-disable-fetch-mail))
462
463   ;; fetch both mail and news. or Only mail.
464   (gnus-offline-enable-fetch-news)
465   (if (memq gnus-offline-articles-to-fetch '(both mail))
466       (gnus-offline-enable-fetch-mail))
467
468   ;; fetch only mail for gnus-agent
469   (if (and (eq gnus-offline-news-fetch-method 'nnagent)
470            (eq gnus-offline-articles-to-fetch 'mail))
471           (setq gnus-agent-handle-level gnus-offline-mail-group-level)))
472
473 ;;
474 ;; Change mail group level to handle only mail.
475 ;;
476 (defun gnus-offline-set-mail-group-level (level)
477   "*Set nnm* group level."
478   (switch-to-buffer gnus-group-buffer)
479   (goto-char (point-min))
480   
481   ;; Save current level
482   (if (not gnus-offline-stored-group-level)
483       (while (re-search-forward " nnm" nil t)
484         (setq gnus-offline-stored-group-level
485               (append gnus-offline-stored-group-level
486                       (list (gnus-group-group-level)))))
487     (forward-line 1)
488     (beginning-of-line))
489   ;;
490   (goto-char (point-min))
491   (while (re-search-forward " nnm" nil t)
492     (gnus-group-set-current-level 1 level)
493     (forward-line 1)
494     (beginning-of-line))
495   t)
496 ;;
497 ;; Restore mail group level
498 ;;
499 (defun gnus-offline-restore-mail-group-level ()
500   "*Restore nnm* group level."
501   (switch-to-buffer gnus-group-buffer)
502   (goto-char (point-min))
503   (let ((num 0))
504     (while (re-search-forward " nnm" nil t)
505       (gnus-group-set-current-level 1 (nth num gnus-offline-stored-group-level))
506       (forward-line 1)
507       (setq num (+ num 1))
508       (beginning-of-line))))
509 ;;
510 ;; Jobs after getting new news.
511 ;;
512 (defun gnus-offline-after-get-new-news ()
513   "*After getting news and mail jobs."
514   (if (memq gnus-offline-articles-to-fetch '(both mail))
515       (progn
516         ;; Mail/both
517         ;; send mail/news in spool
518         (gnus-offline-empting-spool)
519         (if (eq gnus-offline-articles-to-fetch 'mail)
520             (progn
521               ;; Send only mail and hang up...
522               (if (and gnus-offline-connected
523                        gnus-offline-auto-hangup)
524                   (gnus-offline-set-unplugged-state))
525               ;; Disable fetch mail.
526               (gnus-offline-disable-fetch-mail)
527               (gnus-offline-after-jobs-done)))))
528   
529   ;; News/Both
530   (if (memq gnus-offline-articles-to-fetch '(both news))
531       (progn
532         (if gnus-offline-connected
533             (cond ((eq gnus-offline-news-fetch-method 'nnagent)
534                    ;; Get New News (gnus-agent)
535                    (gnus-agent-toggle-plugged t)
536                   
537                    ;; fetch articles
538                    (gnus-agent-fetch-session)
539                   
540                    ;; Hang Up line. then set to offline status.
541                    (if (and gnus-offline-connected
542                             gnus-offline-auto-hangup)
543                        (gnus-offline-set-unplugged-state))
544                    
545                    ;; All online jobs has done.
546                    (gnus-offline-after-jobs-done))
547                   (t
548                    (if (eq gnus-offline-news-fetch-method 'nnspool)
549                        ;; Get New News (nnspool)
550                        (gnspool-get-news))))))))
551 ;;
552 ;; Disable fetch mail
553 ;;
554 (defun gnus-offline-disable-fetch-mail ()
555   "*Set do not fetch mail."
556   (setq mail-sources nil
557         nnmail-spool-file nil))
558 ;;
559 ;; Enable fetch mail
560 ;;
561 (defun gnus-offline-enable-fetch-mail ()
562   "*Set to fetch mail."
563   (setq gnus-offline-mail-fetch-method 'nnmail)
564   (setq mail-sources gnus-offline-mail-source))
565 ;;
566 ;; Enable fetch news
567 ;;
568 (defun gnus-offline-enable-fetch-news ()
569   "*Set to fetch news."
570   (if (eq gnus-offline-news-fetch-method 'nnagent)
571       (progn
572         (setq gnus-agent-handle-level gnus-level-subscribed)
573         (gnus-agent-toggle-plugged t))))
574 \f
575 ;;
576 ;; Add your custom header.
577 ;;
578 (defun gnus-offline-add-custom-header (header string)
579   "*Add X-Gnus-Offline-Backend header to Mail/News message."
580   (let ((delimline
581          (progn (goto-char (point-min))
582                 (re-search-forward
583                  (concat "^" (regexp-quote mail-header-separator) "\n"))
584                 (point-marker)))
585         hdr str)
586     (goto-char (point-min))
587     (unless (re-search-forward (concat "^" header) delimline t)
588       (goto-char delimline)
589       (forward-line -1)
590       (beginning-of-line)
591       (setq hdr (concat header " "))
592       (setq str (concat hdr string))
593       (setq hdr (concat str "\n"))
594       (insert-string hdr))))
595 ;;
596 ;; Add X-Offline-Backend header.
597 ;;
598 (defun gnus-offline-message-add-header ()
599   "*Add X-Gnus-Offline-Backend header to Mail/News message."
600   (when (eq gnus-offline-mail-treat-environ 'offline)
601     (let* ((ver (if (eq gnus-offline-news-fetch-method 'nnagent)
602                     nnagent-version
603                   nnspool-version))
604            (str (format "\n                        with %s" ver)))
605     (gnus-offline-add-custom-header
606      "X-Gnus-Offline-Backend:" (concat gnus-offline-header-string str)))))
607
608 \f
609 ;;
610 ;; Toggle plugged/unplugged
611 ;;
612 (defun gnus-offline-toggle-plugged (plugged)
613   "*Override function \"Jj\" - gnus-agent-toggle-plugged."
614   (interactive (list (not gnus-offline-connected)))
615   (if plugged
616       (progn
617         (setq gnus-offline-connected plugged)
618         (gnus-agent-toggle-plugged plugged)
619         ;; Set send mail/news function to offline functions.
620         (gnus-offline-set-online-sendmail-function)
621         (gnus-offline-set-online-post-news-function))
622     ;; Set to offline status
623     (gnus-offline-set-unplugged-state)))
624 ;;
625 ;; Function of hang up line.
626 ;;
627 (defun gnus-offline-set-unplugged-state ()
628   "*Set to unplugged state."
629   (interactive)
630   ;; Hang Up Line.
631   (if (functionp gnus-offline-hangup-function)
632       (funcall gnus-offline-hangup-function))
633   (setq gnus-offline-connected nil)
634   (if (eq gnus-offline-news-fetch-method 'nnagent)
635       (gnus-agent-toggle-plugged nil))
636
637   ;; Set send mail/news function to offline functions.
638   (gnus-offline-set-offline-sendmail-function)
639   (gnus-offline-set-offline-post-news-function)
640   ;;
641   (setenv "MAILHOST" nil))
642 ;;
643 ;; Hangup line function 
644 ;;
645 (defun gnus-offline-hangup-line ()
646   "*Hangup line function."
647   (message (gnus-offline-get-message 'hangup-line-1))
648   (if (stringp gnus-offline-hangup-program)
649       (apply 'start-process "hup" nil gnus-offline-hangup-program
650              gnus-offline-hangup-program-arguments))
651   (message (gnus-offline-get-message 'hangup-line-2)))
652 ;;
653 ;; Hang Up line routine whe using nnspool
654 ;;
655 (defun gnus-offline-nnspool-hangup-line ()
656   (if (and gnus-offline-connected
657            gnus-offline-auto-hangup)
658       (gnus-offline-set-unplugged-state))
659   (gnus-offline-after-jobs-done))
660 ;;
661 ;; Function of all jobs has done.
662 ;;
663 (defun gnus-offline-after-jobs-done ()
664   "*Jobs after all online jobs."
665   (run-hooks 'gnus-offline-after-online-hook)
666   (if (eq gnus-offline-articles-to-fetch 'mail)
667       (gnus-offline-restore-mail-group-level))
668   (if (eq gnus-offline-news-fetch-method 'nnagent)
669       (gnus-offline-agent-expire))
670   (if (and (featurep 'xemacs)
671            (fboundp 'play-sound-file))
672       (ding nil 'drum)
673     (ding))
674   (gnus-group-save-newsrc)
675   (message (gnus-offline-get-message 'after-jobs-done-1)))
676
677 \f
678 ;;
679 ;; Toggle auto hang up
680 ;;
681 (defun gnus-offline-toggle-auto-hangup ()
682   "*Toggle auto hangup flag."
683   (interactive)
684   (let ((string (gnus-offline-get-message 'toggle-auto-hangup-1)) str)
685     (if gnus-offline-auto-hangup
686         (progn
687           (setq gnus-offline-auto-hangup nil
688                 str (gnus-offline-get-message 'toggle-auto-hangup-2)))
689       (setq gnus-offline-auto-hangup t
690             str (gnus-offline-get-message 'toggle-auto-hangup-3)))
691     (message (format "%s %s" string str))))
692 ;;
693 ;; Toggle offline/online to send mail.
694 ;;
695 (defun gnus-offline-toggle-on/off-send-mail ()
696   "*Toggel online/offline sendmail."
697   (interactive)
698   (if (eq gnus-offline-mail-treat-environ 'offline)
699       (progn
700         ;; Sending mail under online environ.
701         (gnus-offline-set-online-sendmail-function)
702         (setq gnus-offline-mail-treat-environ 'online)
703         (message (gnus-offline-get-message 'toggle-on/off-send-mail-1)))
704     ;; Sending mail under offline environ.
705     (gnus-offline-set-offline-sendmail-function)
706     (setq gnus-offline-mail-treat-environ 'offline)
707     (message (gnus-offline-get-message 'toggle-on/off-send-mail-2))))
708 ;;
709 ;; Toggle articles to fetch ... both -> mail -> news -> both
710 ;;
711 (defun gnus-offline-toggle-articles-to-fetch ()
712   "*Set articles to fetch... both(Mail/News) -> mail only -> News only -> both"
713   (interactive)
714   (let ((string (gnus-offline-get-message 'toggle-articles-to-fetch-1))
715         str)
716     (cond ((eq gnus-offline-articles-to-fetch 'both)
717            (setq gnus-offline-articles-to-fetch 'mail
718                  str (gnus-offline-get-message 'toggle-articles-to-fetch-2)))
719           ((eq gnus-offline-articles-to-fetch 'mail)
720            (setq gnus-offline-articles-to-fetch 'news
721                  str (gnus-offline-get-message 'toggle-articles-to-fetch-3)))
722           (t
723            (setq gnus-offline-articles-to-fetch 'both
724                  str (gnus-offline-get-message 'toggle-articles-to-fetch-4))))
725     (message (format "%s %s" string str))))
726 ;;
727 ;; Send mail and Post news using Miee or gnus-agent.
728 ;;
729 (defun gnus-offline-empting-spool ()
730   "*Send all drafts on queue."
731   (run-hooks 'gnus-offline-before-empting-spool-hook)
732   (if (eq gnus-offline-drafts-queue-type 'miee)
733       ;; Send queued message by miee.el.
734       (progn
735         (if (eq gnus-offline-mail-treat-environ 'offline)
736             (progn
737               (message (gnus-offline-get-message 'empting-spool-1))
738               ;; Using miee to send mail.
739               (mail-spool-send)
740               (message (gnus-offline-get-message 'empting-spool-2))))
741         (message (gnus-offline-get-message 'empting-spool-3))
742         ;; Using miee to post news.
743         (if (and (not (stringp msspool-news-server))
744                  (not msspool-news-service))
745             (progn
746               (setq msspool-news-server (nth 1 gnus-select-method))
747               (setq msspool-news-service 119)))
748         (news-spool-post)
749         (message (gnus-offline-get-message 'empting-spool-4)))
750     ;; Send queued message by gnus-agent
751     (message (gnus-offline-get-message 'empting-spool-5))
752     (gnus-group-send-drafts)
753     (message (gnus-offline-get-message 'empting-spool-6)))
754   ;;
755   (run-hooks 'gnus-offline-after-empting-spool-hook))
756 ;;
757 ;; Set interval time
758 ;;
759 (defun gnus-offline-set-interval-time ()
760   "*Set interval time for gnus-daemon."
761   (interactive)
762   (setq gnus-offline-interval-time
763         (string-to-int (read-from-minibuffer
764                         (format (gnus-offline-get-message 'interval-time-1)
765                                 gnus-offline-interval-time)
766                         nil)))
767   (if (< gnus-offline-interval-time 2)
768       (progn
769         (message (gnus-offline-get-message 'interval-time-2))
770         (setq gnus-offline-interval-time 0))
771     (message
772      (format (gnus-offline-get-message 'interval-time-3)
773              gnus-offline-interval-time)))
774   (gnus-offline-processed-by-timer))
775 ;;
776 ;; Expire articles using gnus-agent.
777 ;;
778 (defun gnus-offline-agent-expire ()
779   "*Expire expirable article on News group."
780   (interactive)
781   (and gnus-offline-agent-automatic-expire
782        (if (eq 0 gnus-agent-expire-days)
783            (let (gnus-agent-expire-all)
784              (gnus-agent-expire))
785          (gnus-agent-expire))))
786 ;;
787 ;; Menu.
788 ;;
789 (defun gnus-offline-define-menu-and-key ()
790   "*Set key and menu."
791   (if (eq gnus-offline-drafts-queue-type 'miee)
792       (if (featurep 'xemacs)
793           (add-hook 'gnus-group-mode-hook 'gnus-offline-define-menu-on-miee)
794         (gnus-offline-define-menu-on-miee))
795     (add-hook 'gnus-group-mode-hook 'gnus-offline-define-menu-on-agent))
796   (add-hook 'gnus-group-mode-hook
797             '(lambda ()
798                (local-set-key "\C-coh" 'gnus-offline-set-unplugged-state)
799                (local-set-key "\C-cof" 'gnus-offline-toggle-articles-to-fetch)
800                (local-set-key "\C-coo" 'gnus-offline-toggle-on/off-send-mail)
801                (local-set-key "\C-cox" 'gnus-offline-toggle-auto-hangup)
802                (local-set-key "\C-cos" 'gnus-offline-set-interval-time)
803                (substitute-key-definition
804                 'gnus-group-get-new-news 'gnus-offline-gnus-get-new-news
805                 gnus-group-mode-map)
806                (if (eq gnus-offline-news-fetch-method 'nnagent)
807                    (progn
808                      (substitute-key-definition
809                       'gnus-agent-toggle-plugged 'gnus-offline-toggle-plugged
810                       gnus-agent-group-mode-map)
811                      (local-set-key "\C-coe" 'gnus-offline-agent-expire)))
812                (or (featurep 'xemacs)
813                    (define-key gnus-group-mode-map 
814                      (if (eq system-type 'windows-nt) [S-mouse-2] [mouse-3])
815                      'gnus-offline-popup-menu))))
816   (if (eq gnus-offline-news-fetch-method 'nnagent)
817       (add-hook 'gnus-summary-mode-hook
818                 '(lambda ()
819                    (substitute-key-definition
820                     'gnus-agent-toggle-plugged 'gnus-offline-toggle-plugged
821                     gnus-agent-summary-mode-map))))
822   (if (featurep 'xemacs)
823       ;; Overwrite the toolbar spec for gnus-group-mode.
824       (add-hook 'gnus-startup-hook
825                 (lambda ()
826                   (catch 'tag
827                     (mapc (lambda (but)
828                             (when (eq 'gnus-group-get-new-news (aref but 1))
829                               (aset but 1 'gnus-offline-gnus-get-new-news)
830                               (throw 'tag nil)))
831                           gnus-group-toolbar))))))
832 ;;
833 ;;
834 (defun gnus-offline-get-menu-items (list)
835   (mapcar
836    #'(lambda (el)
837        (if (listp el)
838            (apply
839             'vector
840             (cons (gnus-offline-get-message (car el)) (cdr el)))
841          el))
842    list))
843
844 (defvar gnus-offline-menu
845   (gnus-offline-get-menu-items
846    '((menu-1 gnus-offline-toggle-articles-to-fetch t)
847      (menu-2 gnus-offline-toggle-on/off-send-mail t)
848      (menu-3 gnus-offline-toggle-auto-hangup t)
849      "----"
850      (menu-4 gnus-offline-agent-expire
851              (eq gnus-offline-news-fetch-method 'nnagent))
852      (menu-5 gnus-offline-set-interval-time t)
853      "----"
854      (menu-6 gnus-offline-set-unplugged-state gnus-offline-connected)
855      "----"
856      (menu-7 gnus-ofsetup-customize t))))
857
858 (defun gnus-offline-define-menu-on-miee ()
859   "*Set and change menu bar on MIEE menu."
860   (let ((miee-menu
861          (gnus-offline-get-menu-items
862           '((menu-miee-1 news-spool-post t)
863             (menu-miee-2 mail-spool-send t)
864             "----"
865             (menu-miee-3 message-offline-state (not message-offline-state))
866             (menu-miee-4 message-online-state message-offline-state)
867             "----")))
868         menu)
869     (setq menu
870           (easy-menu-change
871            nil "Miee"
872            (append miee-menu
873                    (list (cons "Gnus Offline" gnus-offline-menu)))))
874     (and (featurep 'xemacs)
875          (easy-menu-add menu))))
876 ;;
877 ;; define menu without miee.
878 ;;
879 (defun gnus-offline-define-menu-on-agent ()
880   "*Set menu bar on OFFLINE menu."
881   (easy-menu-define
882    gnus-offline-menu-on-agent gnus-group-mode-map "Gnus offline Menu"
883    (cons "Offline" gnus-offline-menu))
884   (and (featurep 'xemacs)
885        (easy-menu-add gnus-offline-menu-on-agent)))
886 ;;
887 ;; Popup menu within the group buffer (under Emacs).
888 ;;
889 (defvar gnus-offline-popup-menu nil)
890 (defun gnus-offline-popup-menu (event)
891   "Popup menu for Gnus Offline."
892   (interactive "e")
893   (unless gnus-offline-popup-menu
894     (setq gnus-offline-popup-menu
895           (let ((menu
896                  (if (boundp 'miee-popup-menu)
897                      (or (assq 'keymap
898                                 (assq 'Miee (assq 'menu-bar global-map)))
899                          miee-popup-menu)
900                    (symbol-value 'gnus-offline-menu-on-agent))))
901             (if (string< emacs-version "20")
902                 (append (list 'keymap
903                               (if (boundp 'miee-popup-menu)
904                                   '(nil "Miee")
905                                 '(nil "Offline"))
906                               '(nil "")
907                               '(nil ""))
908                         (cdr menu))
909               menu))))
910   (let* ((pop (x-popup-menu t gnus-offline-popup-menu))
911          (func (and pop (lookup-key gnus-offline-popup-menu
912                                     (apply 'vector pop)))))
913     (and pop func (funcall func))))
914 \f
915 ;;
916 ;; Timer Function
917 (defun gnus-offline-processed-by-timer ()
918   "*Set timer interval."
919   (if (and (> gnus-offline-interval-time 0)
920            (not gnus-offline-connected))
921       ;; Timer call
922       (gnus-demon-add-handler 'gnus-offline-gnus-get-new-news
923                               gnus-offline-interval-time
924                               gnus-offline-interval-time))
925   (if (= gnus-offline-interval-time 0)
926       (gnus-demon-remove-handler 'gnus-offline-gnus-get-new-news t)))
927 ;;
928 ;;
929 ;;; gnus-offline.el ends here