ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/server/uk/org/iscream/cms/server/client/alerters/IRC__Alerter.java
Revision: 1.24
Committed: Thu Mar 22 22:07:58 2001 UTC (23 years, 1 month ago) by ajm
Branch: MAIN
Changes since 1.23: +36 -4 lines
Log Message:
Rejigged to use the same queuing structure as the Monitors.

Changed all the alerters to use new structire.

Possibly need to create an alerter skeleton...

File Contents

# User Rev Content
1 tdb 1.1 //---PACKAGE DECLARATION---
2 tdb 1.20 package uk.org.iscream.client.alerters;
3 tdb 1.1
4     //---IMPORTS---
5 tdb 1.20 import uk.org.iscream.client.*;
6     import uk.org.iscream.core.*;
7     import uk.org.iscream.util.*;
8     import uk.org.iscream.componentmanager.*;
9 tdb 1.1
10     import java.io.*;
11     import java.net.*;
12 tdb 1.9 import java.util.*;
13 tdb 1.11 import java.text.*;
14 tdb 1.1
15     /**
16     * This Alert sends an IRC message.
17     *
18 tdb 1.9 * Clean shutdown could be achieved by stopping the run() method in the
19     * IRCBot inner class.
20     *
21 tdb 1.19 * @author $Author: tdb1 $
22 ajm 1.24 * @version $Id: IRC__Alerter.java,v 1.23 2001/03/16 17:13:49 tdb1 Exp $
23 tdb 1.1 */
24 ajm 1.24 public class IRC__Alerter extends Thread implements PluginAlerter {
25 tdb 1.1
26     //---FINAL ATTRIBUTES---
27    
28     /**
29     * The current CVS revision of this class
30     */
31 ajm 1.24 public final String REVISION = "$Revision: 1.23 $";
32 tdb 1.1
33 tdb 1.9 /**
34     * A description of this alerter
35     */
36 tdb 1.1 public final String DESC = "Sends alerts on an IRC channel";
37    
38 tdb 1.9 /**
39     * The default reconnect delay in seconds
40     */
41     public final int DEFAULT_RECONNECT_DELAY = 30;
42    
43 tdb 1.16 public final String DEFAULT_LEVEL = Alert.alertLevels[0];
44    
45     public final String NOT_CONFIGURED = "<NOT CONFIGURED>";
46    
47 tdb 1.1 //---STATIC METHODS---
48    
49     //---CONSTRUCTORS---
50    
51     public IRC__Alerter() {
52 tdb 1.7
53 tdb 1.1 // connect to the IRC server
54 tdb 1.9 _ircbot = new IRCBot();
55 tdb 1.19 // set it's name and start it
56     _ircbot.setName("client.IRC__Alerter$IRCBot");
57 tdb 1.9 _ircbot.start();
58 tdb 1.11 _startTime = System.currentTimeMillis();
59 ajm 1.24 this.start();
60 tdb 1.5 _logger.write(toString(), Logger.SYSINIT, "IRC Alerter started");
61 tdb 1.1 }
62    
63     //---PUBLIC METHODS---
64    
65 ajm 1.24 public void run() {
66     while(_running) {
67     try {
68     sendAlert((Alert) getQueue().get(getQueueId()));
69     } catch (InvalidQueueException e) {
70     _logger.write(this.toString(), Logger.ERROR, "Unable to get queue.");
71     }
72     }
73     }
74    
75 tdb 1.1 public void sendAlert(Alert alert) {
76 tdb 1.9 // only send alerts if we're active
77     if(_active) {
78     ConfigurationProxy cp = ConfigurationProxy.getInstance();
79 tdb 1.16
80     String levelName;
81     try {
82     levelName = cp.getProperty(_name, "Alerter.IRC.level");
83     } catch (PropertyNotFoundException e) {
84     levelName = DEFAULT_LEVEL;
85     _logger.write(toString(), Logger.WARNING, "Alerter.IRC.level value unavailable using default of " + levelName);
86     }
87 tdb 1.9 int level = StringUtils.getStringPos(levelName, Alert.alertLevels);
88     // only send if it's equal (or above) our level
89 ajm 1.15 if(((alert.getLevel() == 0) && (alert.getLastLevel() >= level)) || (alert.getLevel() >= level)) {
90 tdb 1.9 String alertType = Alert.alertLevels[alert.getLevel()];
91     String thresholdType = Alert.thresholdLevels[alert.getThreshold()];
92 tdb 1.22 String timeFirstSince = DateUtils.formatTime((System.currentTimeMillis() - alert.getInitialAlertTime())/1000, "%DAYS% days, %HOURS% hours, %MINS% mins, and %SECS% secs");
93 ajm 1.17 String timeFirstOccured = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.UK).format(new Date(alert.getInitialAlertTime()));
94 tdb 1.16 // sort out the message
95     String message;
96     try {
97     message = cp.getProperty(_name, "Alerter.IRC.message");
98     } catch (PropertyNotFoundException e) {
99     message = NOT_CONFIGURED;
100     _logger.write(toString(), Logger.WARNING, "Alerter.IRC.message value unavailable using default of " + message);
101     }
102    
103 tdb 1.9 message = StringUtils.replaceText(message, "%level%", alertType);
104     message = StringUtils.replaceText(message, "%threshold%", thresholdType);
105     message = StringUtils.replaceText(message, "%source%", alert.getSource());
106     message = StringUtils.replaceText(message, "%value%", alert.getValue());
107     message = StringUtils.replaceText(message, "%thresholdValue%", alert.getThresholdValue());
108     message = StringUtils.replaceText(message, "%attributeName%", alert.getAttributeName());
109 tdb 1.23 message = StringUtils.replaceText(message, "%timeTillNextAlert%", DateUtils.getTimeString(Long.parseLong(alert.getTimeTillNextAlert())));
110 ajm 1.17 message = StringUtils.replaceText(message, "%timeSinceFirstAlert%", timeFirstSince);
111     message = StringUtils.replaceText(message, "%timeOfFirstAlert%", timeFirstOccured);
112 tdb 1.9
113     // send the message
114 ajm 1.10 _logger.write(toString(), Logger.DEBUG, "Sending " + _name + " at "+ alertType + " level");
115 tdb 1.9 _ircbot.sendMsg(message);
116     _lastAlert = message;
117 tdb 1.11 _lastAlertTime = System.currentTimeMillis();
118     _alertCount ++;
119 tdb 1.9 }
120 tdb 1.1 }
121 tdb 1.18 else {
122     _ignoredCount ++;
123     }
124 tdb 1.1 }
125    
126     /**
127     * Overrides the {@link java.lang.Object#toString() Object.toString()}
128     * method to provide clean logging (every class should have this).
129     *
130 tdb 1.20 * This uses the uk.org.iscream.util.NameFormat class
131 tdb 1.1 * to format the toString()
132     *
133     * @return the name of this class and its CVS revision
134     */
135     public String toString() {
136     return FormatName.getName(
137     _name,
138     getClass().getName(),
139     REVISION);
140     }
141    
142     /**
143     * return the String representation of what the filter does
144     */
145     public String getDescription(){
146     return DESC;
147     }
148    
149     //---PRIVATE METHODS---
150 ajm 1.8
151 tdb 1.1 //---ACCESSOR/MUTATOR METHODS---
152    
153 ajm 1.24 protected Queue getQueue() {
154     return AlerterManager.getInstance().getQueue();
155     }
156    
157     protected int getQueueId() {
158     if (_qID == -1) {
159     _qID = getQueue().getQueue();
160     _logger.write(toString(), Logger.DEBUG, "Assigned Queue - " + _qID);
161     }
162     return _qID;
163     }
164    
165 tdb 1.1 //---ATTRIBUTES---
166    
167 tdb 1.7 /**
168     * A reference to the IRCBot
169     */
170 tdb 1.1 private IRCBot _ircbot;
171    
172     /**
173 tdb 1.9 * Are we "active"
174     */
175     private boolean _active = false;
176    
177     /**
178     * The last alert that was sent
179     */
180     private String _lastAlert = "no alerts have been sent";
181    
182     /**
183 tdb 1.11 * The time of the last alert
184     */
185     private long _lastAlertTime = -1;
186    
187     /**
188     * Number of alerts sent
189     */
190 tdb 1.18 private int _alertCount = 0;
191    
192     /**
193     * Number of alerts ignored when in "stopped" mode
194     */
195     private int _ignoredCount = 0;
196 tdb 1.11
197     /**
198     * Time of IRCBot startup
199     */
200     private long _startTime;
201    
202     /**
203 ajm 1.24 * The running status of the alerter
204     */
205     private boolean _running = true;
206    
207     /**
208 tdb 1.1 * This is the friendly identifier of the
209     * component this class is running in.
210     * eg, a Filter may be called "filter1",
211     * If this class does not have an owning
212     * component, a name from the configuration
213     * can be placed here. This name could also
214     * be changed to null for utility classes.
215     */
216 ajm 1.8 private String _name = "IRC Alert";
217 tdb 1.1
218     /**
219     * This holds a reference to the
220     * system logger that is being used.
221     */
222     private Logger _logger = ReferenceManager.getInstance().getLogger();
223 ajm 1.24
224     /**
225     * The queue id for this alerters queue in the alert queue
226     */
227     private int _qID = -1;
228 tdb 1.1
229     //---STATIC ATTRIBUTES---
230    
231     //---INNER CLASSES---
232    
233     /**
234     * This class provides some basic IRCBot functionality. It connects
235     * to a specified server, and will remain there until told to
236     * leave. Whilst connected it can send a message or a notice to
237     * the server.
238     */
239     class IRCBot extends Thread {
240    
241 tdb 1.16 public static final String DEFAULT_STARTUP_NOTICE = "i-scream ircbot starting...";
242    
243 tdb 1.1 /**
244     * Main thread loop, this part of the class listens for
245     * messages from the server, and acts accordingly. At the
246     * present moment it only responds to pings.
247     */
248     public void run() {
249 tdb 1.9 // so we can stop if required
250 tdb 1.1 boolean run = true;
251     while(run) {
252 tdb 1.9 // flag so we can stop the loop
253     boolean doRead = true;
254 tdb 1.16 // get the startup notice
255     String startupNotice;
256     try {
257     startupNotice = ConfigurationProxy.getInstance().getProperty(_name, "Alerter.IRC.startupNotice");
258     } catch (PropertyNotFoundException e) {
259     startupNotice = DEFAULT_STARTUP_NOTICE;
260     _logger.write(this.toString(), Logger.WARNING, "Configuration error: "+e);
261     }
262 tdb 1.9 // connect to the IRC server
263 tdb 1.1 try {
264 tdb 1.9 connect();
265 tdb 1.16 sendNotice(startupNotice);
266 tdb 1.9 } catch(IOException e) {
267     doRead=false;
268     _logger.write(this.toString(), Logger.ERROR, "Error connecting: "+e);
269     }
270     while(doRead) {
271     try {
272     // read a command
273     String cmd = _socketIn.readLine();
274     // if we have a null, we've lost contact
275     if(cmd == null) {
276     throw new IOException("End of stream reached");
277     }
278     // let another method deal with the input
279     handleInput(cmd);
280     } catch (IOException e) {
281     // comms failure, maybe our link is dead.
282     _logger.write(this.toString(), Logger.ERROR, "Communication error: "+e);
283     // stop, and loop round for a reconnect.
284     doRead = false;
285 tdb 1.1 }
286 tdb 1.9 }
287     // make sure we're disconnected
288     try {
289     disconnect();
290 tdb 1.1 } catch (IOException e) {
291 tdb 1.9 _logger.write(this.toString(), Logger.ERROR, "Communication error: "+e);
292     }
293    
294     // comms have failed, so wait a while and reconnect
295     int delayTime = 0;
296     try {
297     delayTime = Integer.parseInt(ConfigurationProxy.getInstance().getProperty(_name, "Alerter.IRC.reconnectDelay"));
298     } catch (NumberFormatException e) {
299     delayTime = DEFAULT_RECONNECT_DELAY;
300     _logger.write(this.toString(), Logger.WARNING, "Erronous Alerter.IRC.reconnectDelay value in configuration using default of " + delayTime + " seconds");
301 tdb 1.16 } catch (PropertyNotFoundException e) {
302 tdb 1.9 delayTime = DEFAULT_RECONNECT_DELAY;
303     _logger.write(this.toString(), Logger.WARNING, "Alerter.IRC.reconnectDelay value unavailable using default of " + delayTime + " seconds");
304 tdb 1.1 }
305 tdb 1.9 try {
306     Thread.sleep(delayTime * 1000);
307     } catch (InterruptedException e) {}
308 tdb 1.1 }
309 tdb 1.9 // maybe disconnect here ? - shutdown method not implemented yet
310     //disconnect();
311 tdb 1.1 }
312    
313     /**
314     * Sends a message to the channel.
315     *
316     * @param msg The message to send
317     */
318     public void sendMsg(String msg) {
319     _socketOut.println("PRIVMSG "+_channel+" :"+msg);
320 tdb 1.13 // wait a second before returning...
321     // this ensures messages can't be sent too fast
322     try {Thread.sleep(1000);} catch (InterruptedException e) {}
323 tdb 1.1 }
324    
325     /**
326 tdb 1.9 * Sends a message to the channel.
327     *
328     * @param user The user to send to
329     * @param msg The message to send
330     */
331     public void sendPrivMsg(String user, String msg) {
332     _socketOut.println("PRIVMSG "+user+" :"+msg);
333 tdb 1.13 // wait a second before returning...
334     // this ensures messages can't be sent too fast
335     try {Thread.sleep(1000);} catch (InterruptedException e) {}
336 tdb 1.9 }
337    
338     /**
339     * Sends an action to the channel.
340     *
341     * @param msg the action message
342     */
343     public void sendAction(String msg) {
344     char esc = 001;
345     sendMsg(esc+"ACTION "+msg+esc);
346 tdb 1.13 // wait a second before returning...
347     // this ensures messages can't be sent too fast
348     try {Thread.sleep(1000);} catch (InterruptedException e) {}
349 tdb 1.9 }
350    
351     /**
352 tdb 1.1 * Sends a notice to the channel.
353     *
354     * @param msg The notice to send
355     */
356     public void sendNotice(String msg) {
357     _socketOut.println("NOTICE "+_channel+" :"+msg);
358 tdb 1.13 // wait a second before returning...
359     // this ensures messages can't be sent too fast
360     try {Thread.sleep(1000);} catch (InterruptedException e) {}
361 tdb 1.1 }
362    
363     /**
364     * Connect to the IRC server, log in, and join the channel.
365     *
366     * @throws IOException if the connection fails
367     */
368     public void connect() throws IOException {
369 tdb 1.7 ConfigurationProxy cp = ConfigurationProxy.getInstance();
370 tdb 1.1 // setup the socket, reader and writer
371 tdb 1.16 String server;
372     int port;
373     try {
374     server = cp.getProperty(_name, "Alerter.IRC.IRCServer");
375     port = Integer.parseInt(cp.getProperty(_name, "Alerter.IRC.IRCPort"));
376     } catch (PropertyNotFoundException e) {
377     _logger.write(this.toString(), Logger.ERROR, "Configuration error: "+e);
378     throw new IOException("Can't get irc server details due to configuration error");
379     } catch (NumberFormatException e) {
380     _logger.write(this.toString(), Logger.ERROR, "Configuration error: "+e);
381     throw new IOException("Can't get irc server details due to malformed configuration");
382     }
383 tdb 1.7 _socket = new Socket(server, port);
384 tdb 1.1 _socketIn = new BufferedReader(new InputStreamReader(_socket.getInputStream()));
385     _socketOut = new PrintWriter(_socket.getOutputStream(), true);
386 tdb 1.9 //_socketOut.println("PASS");
387     // send USER details
388 tdb 1.16 String user, comment;
389     try {
390     user = cp.getProperty(_name, "Alerter.IRC.user");
391     comment = cp.getProperty(_name, "Alerter.IRC.comment");
392     } catch (PropertyNotFoundException e) {
393     _logger.write(this.toString(), Logger.ERROR, "Configuration error: "+e);
394     throw new IOException("Can't get user details due to configuration error");
395     }
396 tdb 1.9 _socketOut.println("USER "+user+" 8 * :"+comment);
397     // attempt to get a nick
398 tdb 1.16 String nickList;
399     try {
400     nickList = cp.getProperty(_name, "Alerter.IRC.nickList");
401     } catch (PropertyNotFoundException e) {
402     _logger.write(this.toString(), Logger.ERROR, "Configuration error: "+e);
403     throw new IOException("Can't get nickname due to configuration error");
404     }
405 tdb 1.9 StringTokenizer st = new StringTokenizer(nickList, ";");
406     boolean ok = false;
407     // try until we exhaust our list
408     while(!ok && st.hasMoreTokens()) {
409     String nick = st.nextToken();
410     _socketOut.println("NICK "+nick);
411     // get a "yes" or "no" response back
412     String response = "";
413     do {
414     response = _socketIn.readLine();
415     if(response==null) {
416     throw new IOException("Communication error whilst logging in");
417     }
418     } while(response.indexOf("001")==-1 && response.indexOf("433")==-1);
419     // see if it was a yes
420     if(response.indexOf("001")!=-1) {
421     // great, we're logged in !
422     ok = true;
423     // store the name we're using
424     _nickname = nick;
425     }
426     else {
427     // log we couldn't get the name
428     _logger.write(this.toString(), Logger.WARNING, "Nickname in use: "+nick);
429     }
430     }
431     if(!ok) {
432     // oh dear, we couldn't get on.
433     throw new IOException("All nicknames in use");
434     }
435 tdb 1.1 // join the channel
436 tdb 1.16 try {
437     _channel = cp.getProperty(_name, "Alerter.IRC.channel");
438     } catch (PropertyNotFoundException e) {
439     _logger.write(this.toString(), Logger.ERROR, "Configuration error: "+e);
440     throw new IOException("Can't get channel name due to configuration error");
441     }
442 tdb 1.1 _socketOut.println("JOIN "+_channel);
443 tdb 1.9 // allow alerts
444     _active = true;
445 tdb 1.1 }
446    
447     /**
448     * Disconnect "nicely" from the IRC server.
449     *
450     * @throws IOException if the disconnection fails
451     */
452     public void disconnect() throws IOException {
453 tdb 1.9 // stop alerts
454     _active = false;
455 tdb 1.6 // send proper QUIT
456 tdb 1.1 _socketOut.println("QUIT : iscreamBot component shutting down...");
457     // close the socket
458     _socketOut.close();
459     _socketIn.close();
460     _socket.close();
461     }
462 tdb 1.7
463 tdb 1.1 /**
464 tdb 1.9 * Overrides the {@link java.lang.Object#toString() Object.toString()}
465     * method to provide clean logging (every class should have this).
466     *
467 tdb 1.20 * This uses the uk.org.iscream.util.NameFormat class
468 tdb 1.9 * to format the toString()
469     *
470     * @return the name of this class and its CVS revision
471     */
472     public String toString() {
473     return FormatName.getName(
474     _name,
475     getClass().getName(),
476     REVISION);
477     }
478    
479     /**
480     * Deals with incoming lines from the server.
481     *
482     * @param line the line to deal with
483     */
484     private void handleInput(String line) {
485     ConfigurationProxy cp = ConfigurationProxy.getInstance();
486     // if it's a PING...
487     if(line.startsWith("PING")) {
488     // ...send a PONG
489     _socketOut.println("PONG" + line.substring(4));
490     }
491     // see if it's for us
492 tdb 1.16 else if(getMsg(line).startsWith(_nickname+",") || getMsg(line).startsWith(_nickname+":") || getMsg(line).startsWith(_nickname+" ")) {
493     // setup some String's
494     String stopCommand, startCommand, timeSinceLastAlertCommand, lastAlertCommand, joinCommand;
495     String nickChangeCommand, versionCommand, helpCommand, statCommand, uptimeCommand;
496     // get the command set
497     try {
498     stopCommand = cp.getProperty(_name, "Alerter.IRC.stopCommand");
499     startCommand = cp.getProperty(_name, "Alerter.IRC.startCommand");
500     timeSinceLastAlertCommand = cp.getProperty(_name, "Alerter.IRC.timeSinceLastAlertCommand");
501     lastAlertCommand = cp.getProperty(_name, "Alerter.IRC.lastAlertCommand");
502     joinCommand = cp.getProperty(_name, "Alerter.IRC.joinCommand");
503     nickChangeCommand = cp.getProperty(_name, "Alerter.IRC.nickChangeCommand");
504     versionCommand = cp.getProperty(_name, "Alerter.IRC.versionCommand");
505     helpCommand = cp.getProperty(_name, "Alerter.IRC.helpCommand");
506     statCommand = cp.getProperty(_name, "Alerter.IRC.statCommand");
507     uptimeCommand = cp.getProperty(_name, "Alerter.IRC.uptimeCommand");
508     } catch (PropertyNotFoundException e) {
509     _logger.write(this.toString(), Logger.ERROR, "Configuration error: "+e);
510     // lets bail from handling this line...
511     // ...it's gonna be hard without a command set!
512     return;
513     }
514    
515 tdb 1.9 // we have a message for us
516     String message = getMsg(line).substring(_nickname.length());
517 tdb 1.16 if(message.indexOf(stopCommand)!=-1) {
518 tdb 1.9 _active = false;
519     sendMsg(getMsgSender(line)+", alerts have been stopped");
520     }
521 tdb 1.16 else if(message.indexOf(startCommand)!=-1) {
522 tdb 1.9 _active = true;
523     sendMsg(getMsgSender(line)+", alerts have been activated");
524     }
525 tdb 1.11 // this needs to go here if it contains the same words as the lastAlertCommand
526 tdb 1.16 else if(message.indexOf(timeSinceLastAlertCommand)!=-1) {
527 tdb 1.11 if(_lastAlertTime != -1) {
528     long uptime = (System.currentTimeMillis() - _lastAlertTime) / 1000;
529     String uptimeText = DateUtils.formatTime(uptime, "%DAYS% days, %HOURS% hours, %MINS% mins, and %SECS% secs");
530     sendMsg(getMsgSender(line)+", I last sent an alert "+uptimeText+ " ago");
531     }
532     else {
533     sendMsg(getMsgSender(line)+", I've never sent an alert!");
534     }
535     }
536 tdb 1.16 else if(message.indexOf(lastAlertCommand)!=-1) {
537 tdb 1.11 if(_lastAlertTime != -1) {
538     String date = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.UK).format(new Date(_lastAlertTime));
539     sendMsg(getMsgSender(line)+", last alert was at "+date+"; "+_lastAlert);
540     }
541     else {
542     sendMsg(getMsgSender(line)+", I've never sent an alert!");
543     }
544    
545 tdb 1.9 }
546 tdb 1.16 else if(message.indexOf(joinCommand)!=-1) {
547     String joinCmd = joinCommand;
548 tdb 1.9 String newChan = message.substring(message.indexOf(joinCmd) + joinCmd.length() + 1);
549     int endOfChan = newChan.indexOf(" ");
550     if(endOfChan == -1) {
551     endOfChan = newChan.length();
552     }
553     newChan = newChan.substring(0, endOfChan);
554 tdb 1.21 if(newChan.equals(_channel)) {
555     sendMsg(getMsgSender(line)+", I'm already on "+newChan+"!");
556     } else {
557     sendMsg(getMsgSender(line)+", okay, I'm off to "+newChan);
558     _socketOut.println("PART "+_channel);
559     _socketOut.println("JOIN "+newChan);
560     _channel = newChan;
561     }
562 tdb 1.9 }
563 tdb 1.16 else if(message.indexOf(nickChangeCommand)!=-1) {
564     String nickChangeCmd = nickChangeCommand;
565 tdb 1.11 String newNick = message.substring(message.indexOf(nickChangeCmd) + nickChangeCmd.length() + 1);
566     int endOfNick = newNick.indexOf(" ");
567     if(endOfNick == -1) {
568     endOfNick = newNick.length();
569     }
570     newNick = newNick.substring(0, endOfNick);
571     sendMsg(getMsgSender(line)+", okay, changing my nickname to "+newNick);
572     _socketOut.println("NICK "+newNick);
573     _nickname = newNick;
574     }
575 tdb 1.16 else if(message.indexOf(versionCommand)!=-1) {
576 tdb 1.12 sendMsg(getMsgSender(line)+", I am version "+REVISION.substring(11, REVISION.length() -2)+" of the i-scream alerting bot");
577     }
578 tdb 1.16 else if(message.indexOf(helpCommand)!=-1) {
579 tdb 1.12 sendPrivMsg(getMsgSender(line), "Hello, I am the i-scream alerting bot version "+REVISION.substring(11, REVISION.length() -2));
580 tdb 1.9 sendPrivMsg(getMsgSender(line), "I understand the following commands;");
581 tdb 1.16 sendPrivMsg(getMsgSender(line), stopCommand);
582     sendPrivMsg(getMsgSender(line), startCommand);
583     sendPrivMsg(getMsgSender(line), lastAlertCommand);
584     sendPrivMsg(getMsgSender(line), joinCommand);
585     sendPrivMsg(getMsgSender(line), nickChangeCommand);
586     sendPrivMsg(getMsgSender(line), statCommand);
587     sendPrivMsg(getMsgSender(line), uptimeCommand);
588     sendPrivMsg(getMsgSender(line), timeSinceLastAlertCommand);
589     sendPrivMsg(getMsgSender(line), helpCommand);
590 tdb 1.11 }
591 tdb 1.16 else if(message.indexOf(statCommand)!=-1) {
592 tdb 1.18 sendMsg(getMsgSender(line)+", I have sent a total of "+_alertCount+" alerts, and ignored a total of "+_ignoredCount+"!");
593 tdb 1.11 }
594 tdb 1.16 else if(message.indexOf(uptimeCommand)!=-1) {
595 tdb 1.11 long uptime = (System.currentTimeMillis() - _startTime) / 1000;
596     String uptimeText = DateUtils.formatTime(uptime, "%DAYS% days, %HOURS% hours, %MINS% mins, and %SECS% secs");
597     sendMsg(getMsgSender(line)+", I have been running for "+uptimeText);
598 tdb 1.18 }
599     else if(message.indexOf("ping")!=-1) {
600     sendMsg("pong");
601 tdb 1.9 }
602     else if(message.indexOf("do a jibble dance")!=-1) {
603     // little joke :)
604     sendAction("jives to the funky beat shouting \"ii--screeeaaammm\"");
605     }
606     else {
607 tdb 1.16 String rejectMessage = NOT_CONFIGURED;
608     try {
609     rejectMessage = cp.getProperty(_name, "Alerter.IRC.rejectMessage");
610     } catch(PropertyNotFoundException e) {
611     _logger.write(this.toString(), Logger.ERROR, "Configuration error: "+e);
612     }
613     sendMsg(getMsgSender(line)+", "+rejectMessage);
614 tdb 1.9 }
615     }
616     else if(line.indexOf(_nickname)!=-1 && line.indexOf(_channel)!=-1 && line.indexOf("KICK")!=-1) {
617     sendPrivMsg(getMsgSender(line), "That wasn't a nice thing to do...");
618 tdb 1.16 try {
619     _channel = cp.getProperty(_name, "Alerter.IRC.channel");
620     } catch(PropertyNotFoundException e) {
621     _logger.write(this.toString(), Logger.ERROR, "Configuration error: "+e);
622     }
623 tdb 1.9 _socketOut.println("JOIN "+_channel);
624     }
625     }
626    
627     /**
628     * Strips the header from a message line
629     *
630     * @param line the line to strip
631     * @return the message from the line
632     */
633     private String getMsg(String line) {
634     String result = "";
635     if(line.indexOf("PRIVMSG")!=-1) {
636     int firstColon = line.indexOf(":");
637     if(firstColon != -1) {
638     int secondColon = line.indexOf(":", firstColon+1);
639     if(secondColon != -1) {
640     result = line.substring(secondColon+1);
641     }
642     }
643     }
644     return result;
645     }
646    
647     /**
648     * Finds out the sender of the message
649     *
650     * @param line the line to look for a sender in
651     * @return the sender
652     */
653     private String getMsgSender(String line) {
654     String result = "";
655     int colon = line.indexOf(":");
656     int excl = line.indexOf("!");
657     if(colon!=-1 && excl!=-1) {
658     result = line.substring(colon+1, excl);
659     }
660     return result;
661     }
662    
663     /**
664 tdb 1.1 * The socket connected to the server
665     */
666     private Socket _socket;
667    
668     /**
669     * The writer
670     */
671     private PrintWriter _socketOut;
672    
673     /**
674     * The reader
675     */
676     private BufferedReader _socketIn;
677    
678 tdb 1.7 /**
679     * Just a reminder to what channel we're on...
680     * this can't be dynamic :)
681     */
682     private String _channel;
683 tdb 1.9
684     /**
685     * A reminder of our current nickname...
686     */
687     private String _nickname;
688    
689 tdb 1.1 }
690    
691     }