| 1 |
|
|---|
| 2 |
|
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 |
|
|---|
| 6 |
|
|---|
| 7 |
|
|---|
| 8 |
|
|---|
| 9 |
|
|---|
| 10 |
|
|---|
| 11 |
|
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 |
|
|---|
| 15 |
|
|---|
| 16 |
|
|---|
| 17 |
|
|---|
| 18 |
|
|---|
| 19 |
|
|---|
| 20 |
|
|---|
| 21 |
|
|---|
| 22 |
|
|---|
| 23 |
|
|---|
| 24 |
|
|---|
| 25 |
|
|---|
| 26 |
|
|---|
| 27 |
|
|---|
| 28 |
|
|---|
| 29 |
|
|---|
| 30 |
|
|---|
| 31 |
|
|---|
| 32 |
(require 'erc) |
|---|
| 33 |
(require 'erc-networks) |
|---|
| 34 |
(eval-when-compile |
|---|
| 35 |
(require 'cl) |
|---|
| 36 |
(require 'pcomplete)) |
|---|
| 37 |
|
|---|
| 38 |
|
|---|
| 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 |
|
|---|
| 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 |
|
|---|
| 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 |
|
|---|
| 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 |
|
|---|
| 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 |
|
|---|
| 197 |
|
|---|
| 198 |
|
|---|
| 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 |
|
|---|
| 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 |
|
|---|
| 223 |
|
|---|
| 224 |
|
|---|
| 225 |
|
|---|
| 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 |
|
|---|
| 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 |
|
|---|
| 247 |
|
|---|
| 248 |
|
|---|
| 249 |
|
|---|
| 250 |
|
|---|
| 251 |
|
|---|
| 252 |
|
|---|
| 253 |
|
|---|
| 254 |
|
|---|