root/trunk/lisp/erc/erc-notify.el

Revision 4220, 8.5 kB (checked in by miyoshi, 9 months ago)

Sync up with Emacs22.2.

Line 
1 ;;; erc-notify.el --- Online status change notification
2
3 ;; Copyright (C) 2002, 2003, 2004, 2006, 2007, 2008 Free Software Foundation, Inc.
4
5 ;; Author: Mario Lang <mlang@lexx.delysid.org>
6 ;; Keywords: comm
7
8 ;; This file is part of GNU Emacs.
9
10 ;; GNU Emacs is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14
15 ;; GNU Emacs is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
22 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.
24
25 ;;; Commentary:
26
27 ;; This module defines a new command, /NOTIFY
28 ;; See the docstring of `erc-cmd-NOTIFY' for details.
29
30 ;;; Code:
31
32 (require 'erc)
33 (require 'erc-networks)
34 (eval-when-compile
35  (require 'cl)
36  (require 'pcomplete))
37
38 ;;;; Customizable variables
39
40 (defgroup erc-notify nil
41   "Track online status of certain nicknames."
42   :group 'erc)
43
44 (defcustom erc-notify-list nil
45   "*List of nicknames you want to be notified about online/offline
46 status change."
47   :group 'erc-notify
48   :type '(repeat string))
49
50 (defcustom erc-notify-interval 60
51   "*Time interval (in seconds) for checking online status of notificated
52 people."
53   :group 'erc-notify
54   :type 'integer)
55
56 (defcustom erc-notify-signon-hook nil
57   "*Hook run after someone on `erc-notify-list' has signed on.
58 Two arguments are passed to the function, SERVER and NICK, both
59 strings."
60   :group 'erc-notify
61   :type 'hook
62   :options '(erc-notify-signon))
63
64 (defcustom erc-notify-signoff-hook nil
65   "*Hook run after someone on `erc-notify-list' has signed off.
66 Two arguments are passed to the function, SERVER and NICK, both
67 strings."
68   :group 'erc-notify
69   :type 'hook
70   :options '(erc-notify-signoff))
71
72 (defun erc-notify-signon (server nick)
73   (message "%s signed on at %s" nick server))
74
75 (defun erc-notify-signoff (server nick)
76   (message "%s signed off from %s" nick server))
77
78 ;;;; Internal variables
79
80 (defvar erc-last-ison nil
81   "Last ISON information received through `erc-notify-timer'.")
82 (make-variable-buffer-local 'erc-last-ison)
83
84 (defvar erc-last-ison-time 0
85   "Last time ISON was sent to the server in `erc-notify-timer'.")
86 (make-variable-buffer-local 'erc-last-ison-time)
87
88 ;;;; Setup
89
90 (defun erc-notify-install-message-catalogs ()
91   (erc-define-catalog
92    'english
93    '((notify_current . "Notificated people online: %l")
94      (notify_list    . "Current notify list: %l")
95      (notify_on      . "Detected %n on IRC network %m")
96      (notify_off     . "%n has left IRC network %m"))))
97
98 ;;;###autoload (autoload 'erc-notify-mode "erc-notify" nil t)
99 (define-erc-module notify nil
100   "Periodically check for the online status of certain users and report
101 changes."
102   ((add-hook 'erc-timer-hook 'erc-notify-timer)
103    (add-hook 'erc-server-JOIN-functions 'erc-notify-JOIN)
104    (add-hook 'erc-server-NICK-functions 'erc-notify-NICK)
105    (add-hook 'erc-server-QUIT-functions 'erc-notify-QUIT))
106   ((remove-hook 'erc-timer-hook 'erc-notify-timer)
107    (remove-hook 'erc-server-JOIN-functions 'erc-notify-JOIN)
108    (remove-hook 'erc-server-NICK-functions 'erc-notify-NICK)
109    (remove-hook 'erc-server-QUIT-functions 'erc-notify-QUIT)))
110
111 ;;;; Timer handler
112
113 (defun erc-notify-timer (now)
114   (when (and erc-notify-list
115              (> (erc-time-diff
116                  erc-last-ison-time now)
117                 erc-notify-interval))
118     (erc-once-with-server-event
119      303
120      '(let* ((server (erc-response.sender parsed))
121              (ison-list (delete "" (split-string
122                                     (erc-response.contents parsed))))
123              (new-list ison-list)
124              (old-list (erc-with-server-buffer erc-last-ison)))
125         (while new-list
126           (when (not (erc-member-ignore-case (car new-list) old-list))
127             (run-hook-with-args 'erc-notify-signon-hook server (car new-list))
128             (erc-display-message
129              parsed 'notice proc
130              'notify_on ?n (car new-list) ?m (erc-network-name)))
131           (setq new-list (cdr new-list)))
132         (while old-list
133           (when (not (erc-member-ignore-case (car old-list) ison-list))
134             (run-hook-with-args 'erc-notify-signoff-hook server (car old-list))
135             (erc-display-message
136              parsed 'notice proc
137              'notify_off ?n (car old-list) ?m (erc-network-name)))
138           (setq old-list (cdr old-list)))
139         (setq erc-last-ison ison-list)
140         t))
141     (erc-server-send
142      (concat "ISON " (mapconcat 'identity erc-notify-list " ")))
143     (setq erc-last-ison-time now)))
144
145 (defun erc-notify-JOIN (proc parsed)
146   "Check if channel joiner is on `erc-notify-list' and not on `erc-last-ison'.
147 If this condition is satisfied, produce a notify_on message and add the nick
148 to `erc-last-ison' to prevent any further notifications."
149   (let ((nick (erc-extract-nick (erc-response.sender parsed))))
150     (when (and (erc-member-ignore-case nick erc-notify-list)
151                (not (erc-member-ignore-case nick erc-last-ison)))
152       (add-to-list 'erc-last-ison nick)
153       (run-hook-with-args 'erc-notify-signon-hook
154                           (or erc-server-announced-name erc-session-server)
155                           nick)
156       (erc-display-message
157        parsed 'notice proc
158        'notify_on ?n nick ?m (erc-network-name)))
159     nil))
160
161 (defun erc-notify-NICK (proc parsed)
162   "Check if new nick is on `erc-notify-list' and not on `erc-last-ison'.
163 If this condition is satisfied, produce a notify_on message and add the nick
164 to `erc-last-ison' to prevent any further notifications."
165   (let ((nick (erc-response.contents parsed)))
166     (when (and (erc-member-ignore-case nick erc-notify-list)
167                (not (erc-member-ignore-case nick erc-last-ison)))
168       (add-to-list 'erc-last-ison nick)
169       (run-hook-with-args 'erc-notify-signon-hook
170                           (or erc-server-announced-name erc-session-server)
171                           nick)
172       (erc-display-message
173        parsed 'notice proc
174        'notify_on ?n nick ?m (erc-network-name)))
175     nil))
176
177 (defun erc-notify-QUIT (proc parsed)
178   "Check if quitter is on `erc-notify-list' and on `erc-last-ison'.
179 If this condition is satisfied, produce a notify_off message and remove the
180 nick from `erc-last-ison' to prevent any further notifications."
181   (let ((nick (erc-extract-nick (erc-response.sender parsed))))
182     (when (and (erc-member-ignore-case nick erc-notify-list)
183                (erc-member-ignore-case nick erc-last-ison))
184       (setq erc-last-ison (erc-delete-if `(lambda (el)
185                                             (string= ,(erc-downcase nick)
186                                                      (erc-downcase el)))
187                                          erc-last-ison))
188       (run-hook-with-args 'erc-notify-signoff-hook
189                           (or erc-server-announced-name erc-session-server)
190                           nick)
191       (erc-display-message
192        parsed 'notice proc
193        'notify_off ?n nick ?m (erc-network-name)))
194     nil))
195
196 ;;;; User level command
197
198 ;;;###autoload
199 (defun erc-cmd-NOTIFY (&rest args)
200   "Change `erc-notify-list' or list current notify-list members online.
201 Without args, list the current list of notificated people online,
202 with args, toggle notify status of people."
203   (cond
204    ((null args)
205     ;; Print current notificated people (online)
206     (let ((ison (erc-with-server-buffer erc-last-ison)))
207       (if (not ison)
208           (erc-display-message
209            nil 'notice 'active "No ison-list yet!")
210         (erc-display-message
211          nil 'notice 'active
212          'notify_current ?l ison))))
213    ((string= (car args) "-l")
214     (erc-display-message nil 'notice 'active
215                          'notify_list ?l (mapconcat 'identity erc-notify-list
216                                                     " ")))
217    (t
218     (while args
219       (if (erc-member-ignore-case (car args) erc-notify-list)
220           (progn
221             (setq erc-notify-list (delete (car args) erc-notify-list))
222             ;; Remove the nick from the value of erc-last-ison in
223             ;; every server buffer.  This prevents seeing a signoff
224             ;; notification for a nick that you have just _removed_
225             ;; from your notify list.
226             (dolist (buf (erc-buffer-list))
227               (with-current-buffer buf
228                 (if (erc-server-buffer-p)
229                     (setq erc-last-ison (delete (car args) erc-last-ison))))))
230         (setq erc-notify-list (cons (erc-string-no-properties (car args))
231                                     erc-notify-list)))
232       (setq args (cdr args)))
233     (erc-display-message
234      nil 'notice 'active
235      'notify_list ?l (mapconcat 'identity erc-notify-list " "))))
236   t)
237
238 ;;;###autoload
239 (defun pcomplete/erc-mode/NOTIFY ()
240   (pcomplete-here (pcomplete-erc-all-nicks)))
241
242 (erc-notify-install-message-catalogs)
243
244 (provide 'erc-notify)
245
246 ;;; erc-notify.el ends here
247 ;;
248 ;; Local Variables:
249 ;; indent-tabs-mode: t
250 ;; tab-width: 8
251 ;; End:
252
253 ;; arch-tag: 0fb19dd0-1359-458a-89b7-81dc195a588e
254
Note: See TracBrowser for help on using the browser.