Initial Commit
[packages] / xemacs-packages / zenirc / src / zenirc-notify.el
1 ;;; zenirc-notify.el --- Notifies you when people signon/off
2
3 ;; Copyright (C) 1995, 1996, 1997, 1998 Per Persson
4
5 ;; Author: Per Persson <pp@sno.pp.se>
6 ;; Maintainer: pp@sno.pp.se
7 ;; Keywords: zenirc, notify, extensions
8 ;; Created: 1995-03-30
9
10 ;; This program 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 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; This program 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 this program; if not, you can either send email to this
22 ;; program's maintainer or write to: The Free Software Foundation,
23 ;; Inc.; 675 Massachusetts Avenue; Cambridge, MA 02139, USA.
24
25 ;;; Commentary:
26
27 ;; TODO: If notifee joins channel, don't show notification.
28
29 ;;; Code:
30
31 (require 'zenirc)
32
33 (defvar zenirc-notify-list '()
34   "*A list of nicknames that you want to watch for on IRC.")
35
36 (defvar zenirc-notify-interval '(0 60)
37   "*Time between ISON's sent to server.")
38
39 (defvar zenirc-last-notify '(0 0)
40   "Time previous ISON sent.")
41 (make-variable-buffer-local 'zenirc-last-notify)
42
43 (zenirc-add-hook 'zenirc-timer-hook 'zenirc-notify-timer)
44
45 ;; used with notify code to see if we did /ison or not
46 (defvar zenirc-manual-ison nil)
47 (make-variable-buffer-local 'zenirc-manual-ison)
48
49 ;; people you previously recieved notification of
50 (defvar zenirc-previous-ison nil)
51 (make-variable-buffer-local 'zenirc-previous-ison)
52
53 ;; should you get a user@host reply on notify?
54 (defvar zenirc-userhost-on-notify t)
55 (make-variable-buffer-local 'zenirc-userhost-on-notify)
56
57 (defvar zenirc-userhost-by-notify nil)
58 (make-variable-buffer-local 'zenirc-userhost-by-notify)
59
60 (defvar zenirc-command-notify-hook '(zenirc-command-notify)
61   "*Hook to call when a /notify command is issued in ZeniIRC.
62
63 The syntax of the command is: /notify victim.
64 This toggles the presence of `victim' in your notify-list.
65 If no victim is specified, you will see your notify-list instead.")
66
67 ; hooks to make zenirc aware of the notify code.
68 (defvar zenirc-command-ison-hook '(zenirc-command-ison))
69 (defvar zenirc-command-userhost-hook '(zenirc-command-userhost))
70
71 (defun zenirc-notify-install-message-catalogs ()
72   (zenirc-lang-define-catalog 'english
73    '((notify_list . "[info] Your current notify list: %s")
74      (notify_on . "[info] detected %s wasting time.")
75      (notify_off . "[info] detected that %s stopped wasting time.")
76      (notify_current . "[info] Notificated people wasting time: %s")
77      )))
78
79 (defun zenirc-notify-timer (proc now)
80   "Call zenirc-command-notify-hook with arguments that cause it to send an
81 ISON message to the server. This is used to notice when people in the notify
82 list have come on or off of IRC."
83   (if (zenirc-time< zenirc-notify-interval
84                     (zenirc-time-diff now zenirc-last-notify))
85       (progn
86         (zenirc-run-hook 'zenirc-command-notify-hook proc 
87                          '("notify" . "%auto"))
88         (setq zenirc-last-notify now))))
89
90 \f
91 ;; /notify handler
92 ;;
93 ;; *** NOTE ***
94 ;; this is also called from the zenirc event handling code
95 ;;
96 (defun zenirc-command-notify (proc parsedcmd)
97   (let ((arg (cdr parsedcmd)))
98     (if (string-equal "" arg)
99         ; output list of notificated people (online)
100         (progn 
101           (if (not zenirc-previous-ison)
102               (zenirc-message proc 'notify_current "")
103             (zenirc-message proc 'notify_current zenirc-previous-ison))
104           (zenirc-message proc 'notify_list
105                           (mapconcat 'identity zenirc-notify-list " ")))
106       (if (not (string-match "%" arg))
107           ; add or remove nick from zenirc-notify-list
108           (progn
109             (setq arg (zenirc-parse-words arg))
110             (while arg
111               (if (zenirc-string-match-list (car arg) zenirc-notify-list)
112                   (setq zenirc-notify-list (zenirc-delete-case-insensitive 
113                                             (car arg) zenirc-notify-list))
114                 (setq zenirc-notify-list (cons (car arg) zenirc-notify-list)))
115               (setq arg (cdr arg)))
116             ; output new list of notificated people
117             (zenirc-message proc 'notify_list
118                             (mapconcat 'identity zenirc-notify-list " "))))
119       (if zenirc-notify-list
120           ; if automated, check to see if anything has changed
121           (process-send-string
122            proc
123            (concat "ISON " 
124                    (mapconcat 'identity zenirc-notify-list " ") "\n"))))))
125
126 ;; /ison nick1 [nick2 [nick3...]]
127 (defun zenirc-command-ison (proc parsedcmd)
128   (process-send-string proc
129                        (concat "ISON " (cdr parsedcmd) "\n"))
130   (setq zenirc-manual-ison 1))
131
132 ;; /userhost nick1 [nick2 [nick3...]]
133 (defun zenirc-command-userhost (proc parsedcmd)
134   (process-send-string proc (concat "USERHOST " (cdr parsedcmd) "\n"))
135   (setq zenirc-userhost-by-notify nil))
136
137 (defun zenirc-server-303-notify (proc parsedmsg)
138   (let* ((ison-list (zenirc-parse-words (aref parsedmsg 3))))
139     ; check if user issued /ison and don't want the notify code to execute
140     (if zenirc-manual-ison
141         (progn
142           (zenirc-message proc 's303 (aref parsedmsg 3))
143           (setq zenirc-manual-ison nil))
144       (let ((new-list ison-list)
145             (old-list zenirc-previous-ison))
146         ; check if a certain nick wasn't seen the last time
147         (while new-list
148           (if (not (member (car new-list)
149                            zenirc-previous-ison))
150               ; check if user wants user@host displayed.
151               (if zenirc-userhost-on-notify
152                   (progn
153                     (process-send-string 
154                      proc 
155                      (concat "USERHOST " (car new-list) "\n"))
156                     (setq zenirc-userhost-by-notify t))
157                 (zenirc-message proc 'notify_on (car new-list))))
158           (setq new-list (cdr new-list)))
159         ; check if a certain nick was seen the last time
160         (while old-list
161           (if (not (member (car old-list)
162                            ison-list))
163               (zenirc-message proc 'notify_off (car old-list)))
164           (setq old-list (cdr old-list))))
165       (setq zenirc-previous-ison ison-list))))
166
167 (defun zenirc-server-302-notify (proc parsedmsg)
168   (if zenirc-userhost-by-notify
169       ; go on, sue me for being lazy and using @ for this check.
170       ; --pp
171       ; if you understand why I do this check, you deserve a nice
172       ; reward. took me about 10 minutes to figure it out myself.
173       ; --pp
174       (if (string-match "@" (aref parsedmsg 3))
175           (zenirc-message proc 'notify_on (aref parsedmsg 3)))
176     (zenirc-message proc 's302 (aref parsedmsg 3))))
177
178 \f
179 (provide 'zenirc-notify)
180
181 (zenirc-notify-install-message-catalogs)
182
183 (zenirc-remove-hook 'zenirc-server-303-hook 'zenirc-server-303)
184 (zenirc-add-hook 'zenirc-server-303-hook 'zenirc-server-303-notify)
185 (zenirc-remove-hook 'zenirc-server-302-hook 'zenirc-server-302)
186 (zenirc-add-hook 'zenirc-server-302-hook 'zenirc-server-302-notify)
187
188 ;;; zenirc-notify.el ends here