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