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.30.2.3
Committed: Tue Feb 5 18:00:15 2002 UTC (22 years, 3 months ago) by tdb
Branch: SERVER_PIRCBOT
Changes since 1.30.2.2: +146 -37 lines
Log Message:
Mostly tidying of code and commenting. Now much more complete, although
there are still some issues with the underlying pircbot (sometimes hangs
when the help command is sent, for example).

File Contents

# User Rev Content
1 tdb 1.1 //---PACKAGE DECLARATION---
2 tdb 1.29 package uk.org.iscream.cms.server.client.alerters;
3 tdb 1.1
4     //---IMPORTS---
5 tdb 1.29 import uk.org.iscream.cms.server.client.*;
6     import uk.org.iscream.cms.server.core.*;
7     import uk.org.iscream.cms.server.util.*;
8     import uk.org.iscream.cms.server.componentmanager.*;
9 tdb 1.1 import java.io.*;
10     import java.net.*;
11 tdb 1.9 import java.util.*;
12 ajm 1.25 import java.text.DateFormat;
13 tdb 1.30.2.1 import org.jibble.pircbot.*;
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.30.2.1 * @author $Author: tdb $
22 tdb 1.30.2.3 * @version $Id: IRC__Alerter.java,v 1.30.2.2 2002/02/04 23:14:38 tdb Exp $
23 tdb 1.1 */
24 ajm 1.25 public class IRC__Alerter extends AlerterSkeleton {
25 tdb 1.1
26     //---FINAL ATTRIBUTES---
27    
28     /**
29     * The current CVS revision of this class
30     */
31 tdb 1.30.2.3 public final String REVISION = "$Revision: 1.30.2.2 $";
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     //---STATIC METHODS---
39    
40     //---CONSTRUCTORS---
41 tdb 1.30.2.1
42 tdb 1.1 public IRC__Alerter() {
43 ajm 1.25 super();
44 tdb 1.30.2.1 // construct and initialise the bot
45 tdb 1.9 _ircbot = new IRCBot();
46 tdb 1.30.2.3 _ircbot.setVerbose(false);
47 tdb 1.30.2.1 Thread ircThread = new Thread(_ircbot);
48 tdb 1.19 // set it's name and start it
49 tdb 1.30.2.1 ircThread.setName("client.IRC__Alerter$IRCBot");
50     ircThread.start();
51     // log our start time
52 tdb 1.11 _startTime = System.currentTimeMillis();
53 tdb 1.5 _logger.write(toString(), Logger.SYSINIT, "IRC Alerter started");
54 tdb 1.1 }
55    
56     //---PUBLIC METHODS---
57    
58 ajm 1.25 /**
59     * Implements the abstract method from the skeleton class.
60     * This method will attempt to send an alert
61     * message over the IRC channel.
62     *
63     * @param alert the alert to send
64     */
65 tdb 1.1 public void sendAlert(Alert alert) {
66 tdb 1.27 // sort out the message
67     String alertType = Alert.alertLevels[alert.getLevel()];
68     String message;
69     try {
70     message = _cp.getProperty(_name, "Alerter.IRC.message");
71     } catch (PropertyNotFoundException e) {
72     message = NOT_CONFIGURED;
73     _logger.write(toString(), Logger.WARNING, "Alerter.IRC.message value unavailable using default of " + message);
74     }
75     message = processAlertMessage(message, alert);
76 tdb 1.9 // only send alerts if we're active
77 tdb 1.27 if(_active) {
78 ajm 1.25 // send the message
79     _logger.write(toString(), Logger.DEBUG, "Sending " + _name + " at "+ alertType + " level");
80 tdb 1.30.2.3 _ircbot.sendMessage(message);
81 tdb 1.26 // count sent alerts
82     _alertCount++;
83 ajm 1.25 } else {
84 tdb 1.26 // don't send, but keep a count that we ignored it
85     _ignoredCount++;
86 tdb 1.18 }
87 tdb 1.26 // we'll always store the "last alert", regardless
88     // of whether we actually display it or not
89     _lastAlert = message;
90     _lastAlertTime = System.currentTimeMillis();
91 tdb 1.1 }
92    
93     /**
94     * Overrides the {@link java.lang.Object#toString() Object.toString()}
95     * method to provide clean logging (every class should have this).
96     *
97 tdb 1.29 * This uses the uk.org.iscream.cms.server.util.NameFormat class
98 tdb 1.1 * to format the toString()
99     *
100     * @return the name of this class and its CVS revision
101     */
102     public String toString() {
103     return FormatName.getName(
104     _name,
105     getClass().getName(),
106     REVISION);
107     }
108    
109 ajm 1.25 /**
110     * Return the String representation of what the alerter does
111     *
112     * @return the description
113 tdb 1.1 */
114     public String getDescription(){
115     return DESC;
116     }
117    
118     //---PRIVATE METHODS---
119 ajm 1.8
120 tdb 1.1 //---ACCESSOR/MUTATOR METHODS---
121 tdb 1.28
122     /**
123     * Returns the "friendly" name of this class. This
124     * is simply an accessor for _name, required due to
125     * inheritance issues with extending AlerterSkeleton.
126     *
127     * @return the friendly name
128     */
129     protected String getFName() {
130     return _name;
131     }
132 tdb 1.1
133     //---ATTRIBUTES---
134    
135 tdb 1.7 /**
136     * A reference to the IRCBot
137     */
138 tdb 1.1 private IRCBot _ircbot;
139    
140     /**
141 tdb 1.9 * Are we "active"
142     */
143     private boolean _active = false;
144    
145     /**
146     * The last alert that was sent
147     */
148     private String _lastAlert = "no alerts have been sent";
149    
150     /**
151 tdb 1.11 * The time of the last alert
152     */
153     private long _lastAlertTime = -1;
154    
155     /**
156     * Number of alerts sent
157     */
158 tdb 1.18 private int _alertCount = 0;
159    
160     /**
161     * Number of alerts ignored when in "stopped" mode
162     */
163     private int _ignoredCount = 0;
164 tdb 1.11
165     /**
166     * Time of IRCBot startup
167     */
168     private long _startTime;
169    
170     /**
171 tdb 1.30.2.1 * This holds a reference to the
172     * system logger that is being used.
173     */
174     protected Logger _logger = ReferenceManager.getInstance().getLogger();
175    
176     /**
177 tdb 1.1 * This is the friendly identifier of the
178     * component this class is running in.
179     * eg, a Filter may be called "filter1",
180     * If this class does not have an owning
181     * component, a name from the configuration
182     * can be placed here. This name could also
183     * be changed to null for utility classes.
184     */
185 ajm 1.25 private String _name = "IRC";
186 tdb 1.1
187     //---STATIC ATTRIBUTES---
188    
189     //---INNER CLASSES---
190    
191 tdb 1.30.2.1 class IRCBot extends PircBot implements Runnable {
192 tdb 1.16
193 tdb 1.1 /**
194 tdb 1.30.2.1 * The default reconnect delay in seconds
195 tdb 1.1 */
196 tdb 1.30.2.1 public final int DEFAULT_RECONNECT_DELAY = 30;
197    
198 tdb 1.30.2.3 /**
199     * Attempt to kick-start the IRCBot into action. Will
200     * keep calling init() until it doesn't throw an
201     * an IOException (which will only be thrown if there
202     * is an error initialising). After a successful call
203     * to init() the method finishes.
204     */
205 tdb 1.1 public void run() {
206 tdb 1.30.2.1 while(true) {
207 tdb 1.1 try {
208 tdb 1.30.2.1 init();
209     break;
210 tdb 1.9 }
211 tdb 1.30.2.1 catch (IOException e) {
212     _logger.write(this.toString(), Logger.ERROR, "Error initialising IRCBot: "+e);
213 tdb 1.30.2.3 // wait for a while, defined in the config
214 tdb 1.30.2.1 reconnectSleep();
215 tdb 1.9 }
216 tdb 1.1 }
217 tdb 1.9 }
218    
219 tdb 1.30.2.3 /**
220     * Connects the bot to an irc server and joins a channel,
221     * using details supplied from the i-scream configuration
222     * system. If this method completes without an exception
223     * one can presume the bot is ready for use.
224     *
225     * @throws IOException if there is any problem initialising
226     */
227 tdb 1.30.2.1 public void init() throws IOException {
228     _logger.write(this.toString(), Logger.DEBUG, "Initialising IRCBot...");
229 tdb 1.30.2.3
230     // get a hook on the configuration system
231 tdb 1.7 ConfigurationProxy cp = ConfigurationProxy.getInstance();
232 tdb 1.30.2.3
233     // get hold of the server details
234 tdb 1.16 String server;
235     int port;
236     try {
237     server = cp.getProperty(_name, "Alerter.IRC.IRCServer");
238     port = Integer.parseInt(cp.getProperty(_name, "Alerter.IRC.IRCPort"));
239     } catch (PropertyNotFoundException e) {
240     _logger.write(this.toString(), Logger.ERROR, "Configuration error: "+e);
241     throw new IOException("Can't get irc server details due to configuration error");
242     } catch (NumberFormatException e) {
243     _logger.write(this.toString(), Logger.ERROR, "Configuration error: "+e);
244     throw new IOException("Can't get irc server details due to malformed configuration");
245     }
246 tdb 1.30.2.3
247     // get hold of the user details and nickname list
248     String user, comment, finger, nickList;
249 tdb 1.16 try {
250     user = cp.getProperty(_name, "Alerter.IRC.user");
251     comment = cp.getProperty(_name, "Alerter.IRC.comment");
252 tdb 1.30.2.3 finger = cp.getProperty(_name, "Alerter.IRC.finger");
253     nickList = cp.getProperty(_name, "Alerter.IRC.nickList");
254 tdb 1.16 } catch (PropertyNotFoundException e) {
255     _logger.write(this.toString(), Logger.ERROR, "Configuration error: "+e);
256 tdb 1.30.2.3 throw new IOException("Can't get user/nickname details due to configuration error");
257 tdb 1.16 }
258 tdb 1.30.2.3
259     // put these details into the bot
260 tdb 1.30.2.1 this.setLogin(user);
261     this.setVersion(comment);
262 tdb 1.30.2.3 this.setFinger(finger);
263    
264     // attempt to connect, trying each nickname
265     // in turn until sucessfully connected
266 tdb 1.9 StringTokenizer st = new StringTokenizer(nickList, ";");
267     boolean ok = false;
268     while(!ok && st.hasMoreTokens()) {
269     String nick = st.nextToken();
270 tdb 1.30.2.1 try {
271 tdb 1.30.2.3 // try to connect with a nickname
272 tdb 1.30.2.1 _logger.write(this.toString(), Logger.DEBUG, "Trying nick: "+nick);
273     this.setName(nick);
274     this.connect(server, port);
275 tdb 1.30.2.3 // at this point we know the nickname was accepted
276 tdb 1.9 _nickname = nick;
277 tdb 1.30.2.1 ok = true;
278 tdb 1.9 }
279 tdb 1.30.2.1 catch(IOException e) {
280     _logger.write(this.toString(), Logger.ERROR, "IO error when connecting to server: "+e);
281     throw new IOException("IO error when connecting to server");
282     }
283     catch(IrcException e) {
284     _logger.write(this.toString(), Logger.ERROR, "IRC error when connecting to server: "+e);
285     throw new IOException("IRC error when connecting to server");
286     }
287     catch(NickAlreadyInUseException e) {
288     _logger.write(this.toString(), Logger.ERROR, "Nickname "+nick+" is already in use: "+e);
289 tdb 1.30.2.3 // don't do anything, instead just loop round
290     // and try the next nickname in the list
291 tdb 1.9 }
292     }
293     if(!ok) {
294 tdb 1.30.2.3 // must have tried all the nicknames, best bail out
295 tdb 1.30.2.1 _logger.write(this.toString(), Logger.ERROR, "All nicknames already in use");
296     throw new IOException("All nicknames already in use");
297 tdb 1.9 }
298 tdb 1.30.2.3
299     // get hold of the channel details, and attempt
300     // to join the specified channel
301 tdb 1.16 try {
302     _channel = cp.getProperty(_name, "Alerter.IRC.channel");
303 tdb 1.30.2.1 this.joinChannel(_channel);
304 tdb 1.16 } catch (PropertyNotFoundException e) {
305     _logger.write(this.toString(), Logger.ERROR, "Configuration error: "+e);
306     throw new IOException("Can't get channel name due to configuration error");
307     }
308 tdb 1.30.2.1
309 tdb 1.30.2.3 // get hold of the startup notice, and send
310     // it if it's defined
311 tdb 1.30.2.1 String startupNotice;
312     try {
313     startupNotice = ConfigurationProxy.getInstance().getProperty(_name, "Alerter.IRC.startupNotice");
314     sendNotice(_channel, startupNotice);
315     } catch (PropertyNotFoundException e) {
316     _logger.write(this.toString(), Logger.DEBUG, "Startup notice not defined, so not sending: "+e);
317     }
318    
319 tdb 1.30.2.3 // at this point initialisation is complete, so
320     // we can return and set this flag to allow alerts
321 tdb 1.9 _active = true;
322 tdb 1.1 }
323    
324 tdb 1.30.2.3 /**
325     * Send a message to the current channel.
326     *
327     * @param message The message to send
328     */
329     public void sendMessage(String message) {
330     sendMessage(_channel, message);
331 tdb 1.9 }
332    
333 tdb 1.30.2.3 /**
334     * If we get disconnected this method will be
335     * called, so we must take action. We'll simply
336     * keep trying to reinitialise, and thus
337     * reconnect to the server.
338     */
339 tdb 1.30.2.1 public void onDisconnect() {
340 tdb 1.30.2.3 // stop alerts being sent for now
341 tdb 1.30.2.1 _active = false;
342     while(true) {
343 tdb 1.30.2.3 // wait for a while, defined in the config
344 tdb 1.30.2.1 reconnectSleep();
345 tdb 1.16 try {
346 tdb 1.30.2.1 init();
347     break;
348 tdb 1.16 }
349 tdb 1.30.2.1 catch (IOException e) {
350     _logger.write(this.toString(), Logger.ERROR, "Error initialising IRCBot: "+e);
351 tdb 1.11 }
352 tdb 1.30.2.1 }
353     }
354    
355 tdb 1.30.2.3 /**
356     * If we receive a message this method will
357     * be called. We'll check if the message is
358     * for us, and call handleInput if it is.
359     *
360     * @param channel The channel the message came from
361     * @param sender The sender of the message
362     * @param login The login of the sender
363     * @param hostname The hostname of the sender
364     * @param message The message sent
365     */
366 tdb 1.30.2.1 public void onMessage(String channel, String sender, String login, String hostname, String message) {
367     if(isForMe(message)) {
368 tdb 1.30.2.2 handleInput(message, channel);
369 tdb 1.30.2.1 }
370     }
371    
372 tdb 1.30.2.3 /**
373     * If we receive a private message this method
374     * will be called. No need to check if it's for
375     * us -- it has to be if it's a private message.
376     *
377     * @param sender The sender of the message
378     * @param login The login of the sender
379     * @param hostname The hostname of the sender
380     * @param message The message sent
381     */
382 tdb 1.30.2.1 public void onPrivateMessage(String sender, String login, String hostname, String message) {
383 tdb 1.30.2.2 handleInput(message, sender);
384 tdb 1.30.2.1 }
385    
386 tdb 1.30.2.3 /**
387     * If we receive a nick change message, this
388     * method gets called. We don't care about
389     * other users changing their nick, so we only
390     * take notice if our nick changes. If it does
391     * we need to change our internal nickname
392     * state.
393     *
394     * @param oldNick the old nickname
395     * @param login the login of the nick changer
396     * @param hostname the hostname of the nick changer
397     * @param newNick the new nickname
398     */
399 tdb 1.30.2.1 public void onNickChange(String oldNick, String login, String hostname, String newNick) {
400     if(oldNick.equals(_nickname)) {
401     _nickname = newNick;
402     }
403     }
404    
405 tdb 1.30.2.3 /**
406     * If we receive a kick message this method
407     * gets called. We only take notice if it's
408     * us getting kicked, and then we'll rejoin
409     * the channel after a short wait.
410     *
411     * @param channel the channel the kick happened on
412     * @param kickerNick the person who performed the kick
413     * @param kickerLogin the login of the person who performed the kick
414     * @param kickerHostname the hostname of the person who performed the kick
415     * @param recipientNick the nickname of the person being kicked
416     * @param reason the reason for the kick
417     */
418 tdb 1.30.2.2 public void onKick(String channel, String kickerNick, String kickerLogin, String kickerHostname, String recipientNick, String reason) {
419     if(recipientNick.equals(_nickname) && channel.equals(_channel)) {
420 tdb 1.30.2.3 // remind the person it's not very nice :)
421 tdb 1.30.2.2 sendMessage(kickerNick, "That wasn't a nice thing to do...");
422 tdb 1.30.2.3 // get hold of the channel details, in case they've changed
423 tdb 1.30.2.2 try {
424     _channel = ConfigurationProxy.getInstance().getProperty(_name, "Alerter.IRC.channel");
425     } catch(PropertyNotFoundException e) {
426 tdb 1.30.2.3 _logger.write(this.toString(), Logger.ERROR, "Can't get channel name due to configuration error: "+e);
427 tdb 1.30.2.2 }
428 tdb 1.30.2.3 // wait for a while, defined in the config
429     reconnectSleep();
430     // we'll try and rejoin the channel regardless
431     // otherwise we might end up doing nothing!
432 tdb 1.30.2.2 joinChannel(_channel);
433     }
434     }
435    
436 tdb 1.30.2.3 /**
437     * This method handles input directed to us, and
438     * responds accordingly if required.
439     *
440     * nb. matching user input is quite bad right now,
441     * and should be improved one day.
442     *
443     * @param message the message from someone
444     * @param source where the message came from, so we know where to send the response
445     */
446 tdb 1.30.2.2 private void handleInput(String message, String source) {
447 tdb 1.30.2.3 // get hold of the configuration system
448 tdb 1.30.2.1 ConfigurationProxy cp = ConfigurationProxy.getInstance();
449     // setup some String's
450     String stopCommand, startCommand, timeSinceLastAlertCommand, lastAlertCommand, joinCommand;
451     String nickChangeCommand, versionCommand, helpCommand, statCommand, uptimeCommand;
452 tdb 1.30.2.3 // get the command set from the configuration
453 tdb 1.30.2.1 try {
454     stopCommand = cp.getProperty(_name, "Alerter.IRC.stopCommand");
455     startCommand = cp.getProperty(_name, "Alerter.IRC.startCommand");
456     timeSinceLastAlertCommand = cp.getProperty(_name, "Alerter.IRC.timeSinceLastAlertCommand");
457     lastAlertCommand = cp.getProperty(_name, "Alerter.IRC.lastAlertCommand");
458     joinCommand = cp.getProperty(_name, "Alerter.IRC.joinCommand");
459     nickChangeCommand = cp.getProperty(_name, "Alerter.IRC.nickChangeCommand");
460     versionCommand = cp.getProperty(_name, "Alerter.IRC.versionCommand");
461     helpCommand = cp.getProperty(_name, "Alerter.IRC.helpCommand");
462     statCommand = cp.getProperty(_name, "Alerter.IRC.statCommand");
463     uptimeCommand = cp.getProperty(_name, "Alerter.IRC.uptimeCommand");
464     } catch (PropertyNotFoundException e) {
465     _logger.write(this.toString(), Logger.ERROR, "Configuration error: "+e);
466     // lets bail from handling this line...
467     // ...it's gonna be hard without a command set!
468 tdb 1.30.2.2 return;
469 tdb 1.30.2.1 }
470    
471 tdb 1.30.2.3 // see if the message matches (loosely!) any
472     // of our known commands
473 tdb 1.30.2.2 if(message.indexOf(stopCommand) != -1) {
474 tdb 1.30.2.1 _active = false;
475 tdb 1.30.2.2 sendMessage(source, "alerts have been stopped");
476 tdb 1.30.2.1 }
477 tdb 1.30.2.2 else if(message.indexOf(startCommand) != -1) {
478 tdb 1.30.2.1 _active = true;
479 tdb 1.30.2.2 sendMessage(source, "alerts have been activated");
480 tdb 1.30.2.1 }
481 tdb 1.30.2.3 // this needs to go before lastAlertCommand if it contains
482     // the same words as the lastAlertCommand.
483 tdb 1.30.2.2 else if(message.indexOf(timeSinceLastAlertCommand) != -1) {
484 tdb 1.30.2.1 if(_lastAlertTime != -1) {
485     long uptime = (System.currentTimeMillis() - _lastAlertTime) / 1000;
486 tdb 1.11 String uptimeText = DateUtils.formatTime(uptime, "%DAYS% days, %HOURS% hours, %MINS% mins, and %SECS% secs");
487 tdb 1.30.2.2 sendMessage(source, "I last sent an alert "+uptimeText+ " ago");
488 tdb 1.18 }
489 tdb 1.30.2.1 else {
490 tdb 1.30.2.2 sendMessage(source, "I've never sent an alert!");
491 tdb 1.9 }
492 tdb 1.30.2.1 }
493 tdb 1.30.2.2 else if(message.indexOf(lastAlertCommand) != -1) {
494 tdb 1.30.2.1 if(_lastAlertTime != -1) {
495     String date = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.UK).format(new Date(_lastAlertTime));
496 tdb 1.30.2.2 sendMessage(source, "last alert was at "+date+"; "+_lastAlert);
497 tdb 1.9 }
498     else {
499 tdb 1.30.2.2 sendMessage(source, "I've never sent an alert!");
500 tdb 1.9 }
501 tdb 1.30.2.1
502 tdb 1.9 }
503 tdb 1.30.2.2 else if(message.indexOf(joinCommand) != -1) {
504 tdb 1.30.2.1 String joinCmd = joinCommand;
505     String newChan = message.substring(message.indexOf(joinCmd) + joinCmd.length() + 1);
506     int endOfChan = newChan.indexOf(" ");
507     if(endOfChan == -1) {
508     endOfChan = newChan.length();
509     }
510     newChan = newChan.substring(0, endOfChan);
511     if(newChan.equals(_channel)) {
512 tdb 1.30.2.2 sendMessage(source, "I'm already on "+newChan+"!");
513 tdb 1.30.2.1 } else {
514     partChannel(_channel);
515     joinChannel(newChan);
516     _channel = newChan;
517     }
518     }
519 tdb 1.30.2.2 else if(message.indexOf(nickChangeCommand) != -1) {
520 tdb 1.30.2.1 String nickChangeCmd = nickChangeCommand;
521     String newNick = message.substring(message.indexOf(nickChangeCmd) + nickChangeCmd.length() + 1);
522     int endOfNick = newNick.indexOf(" ");
523     if(endOfNick == -1) {
524     endOfNick = newNick.length();
525     }
526     newNick = newNick.substring(0, endOfNick);
527     changeNick(newNick);
528     }
529 tdb 1.30.2.2 else if(message.indexOf(versionCommand) != -1) {
530     sendMessage(source, "I am version "+REVISION.substring(11, REVISION.length() -2)+" of the i-scream alerting bot");
531 tdb 1.30.2.1 }
532 tdb 1.30.2.2 else if(message.indexOf(helpCommand) != -1) {
533     sendMessage(source, "Hello, I am the i-scream alerting bot version "+REVISION.substring(11, REVISION.length() -2));
534     sendMessage(source, "I understand the following commands;");
535     sendMessage(source, stopCommand);
536     sendMessage(source, startCommand);
537     sendMessage(source, lastAlertCommand);
538     sendMessage(source, joinCommand);
539     sendMessage(source, nickChangeCommand);
540     sendMessage(source, statCommand);
541     sendMessage(source, uptimeCommand);
542     sendMessage(source, timeSinceLastAlertCommand);
543     sendMessage(source, helpCommand);
544 tdb 1.30.2.1 }
545 tdb 1.30.2.2 else if(message.indexOf(statCommand) != -1) {
546     sendMessage(source, "I have sent a total of "+_alertCount+" alerts, and ignored a total of "+_ignoredCount+"!");
547 tdb 1.30.2.1 }
548 tdb 1.30.2.2 else if(message.indexOf(uptimeCommand) != -1) {
549 tdb 1.30.2.1 long uptime = (System.currentTimeMillis() - _startTime) / 1000;
550     String uptimeText = DateUtils.formatTime(uptime, "%DAYS% days, %HOURS% hours, %MINS% mins, and %SECS% secs");
551 tdb 1.30.2.2 sendMessage(source, "I have been running for "+uptimeText);
552 tdb 1.30.2.1 }
553 tdb 1.30.2.2 else if(message.indexOf("ping") != -1) {
554     sendMessage(source, "pong");
555 tdb 1.30.2.1 }
556 tdb 1.30.2.2 else if(message.indexOf("do a jibble dance") != -1) {
557 tdb 1.30.2.1 // little joke :)
558 tdb 1.30.2.2 sendAction(source, "jives to the funky beat shouting \"ii--screeeaaammm\"");
559 tdb 1.30.2.1 }
560     else {
561     String rejectMessage = NOT_CONFIGURED;
562 tdb 1.16 try {
563 tdb 1.30.2.1 rejectMessage = cp.getProperty(_name, "Alerter.IRC.rejectMessage");
564 tdb 1.16 } catch(PropertyNotFoundException e) {
565     _logger.write(this.toString(), Logger.ERROR, "Configuration error: "+e);
566     }
567 tdb 1.30.2.2 sendMessage(source, rejectMessage);
568 tdb 1.9 }
569     }
570    
571 tdb 1.30.2.3 /**
572     * Quick method to check if the message appears
573     * to be directed at us. We simply check to see
574     * if it starts with our nick in some fashion.
575     *
576     * @param message the message to check
577     * @return if the message is for us
578     */
579 tdb 1.30.2.1 private boolean isForMe(String message) {
580     String nick = _nickname.toLowerCase();
581     String msg = message.toLowerCase();
582     if(msg.startsWith(nick + ", ") ||
583     msg.startsWith(nick + ": ") ||
584     msg.startsWith(nick + " ")) {
585     return true;
586     }
587     else {
588     return false;
589 tdb 1.9 }
590     }
591    
592 tdb 1.30.2.3 /**
593     * Sleep for a configurable amount of time and
594     * then return. This is used when reconnecting
595     * to the server or a channel.
596     */
597 tdb 1.30.2.1 private void reconnectSleep() {
598     int delayTime = 0;
599     try {
600     delayTime = Integer.parseInt(ConfigurationProxy.getInstance().getProperty(_name, "Alerter.IRC.reconnectDelay"));
601     } catch (NumberFormatException e) {
602     delayTime = DEFAULT_RECONNECT_DELAY;
603     _logger.write(this.toString(), Logger.WARNING, "Erronous Alerter.IRC.reconnectDelay value in configuration using default of " + delayTime + " seconds");
604     } catch (PropertyNotFoundException e) {
605     delayTime = DEFAULT_RECONNECT_DELAY;
606     _logger.write(this.toString(), Logger.WARNING, "Alerter.IRC.reconnectDelay value unavailable using default of " + delayTime + " seconds");
607 tdb 1.9 }
608 tdb 1.30.2.1 _logger.write(this.toString(), Logger.ERROR, "Waiting "+delayTime+" seconds for reconnect...");
609     try {
610     Thread.sleep(delayTime * 1000);
611     } catch (InterruptedException e) {}
612 tdb 1.9 }
613    
614     /**
615 tdb 1.30.2.1 * Overrides the {@link java.lang.Object#toString() Object.toString()}
616     * method to provide clean logging (every class should have this).
617     *
618     * This uses the uk.org.iscream.cms.server.util.NameFormat class
619     * to format the toString()
620     *
621     * @return the name of this class and its CVS revision
622 tdb 1.1 */
623 tdb 1.30.2.1 public String toString() {
624     return FormatName.getName(
625     _name,
626     getClass().getName(),
627     REVISION);
628     }
629 tdb 1.1
630 tdb 1.7 /**
631     * Just a reminder to what channel we're on...
632     * this can't be dynamic :)
633     */
634     private String _channel;
635 tdb 1.9
636     /**
637     * A reminder of our current nickname...
638     */
639     private String _nickname;
640    
641 tdb 1.1 }
642    
643     }