diff options
Diffstat (limited to 'src/org/jogamp/jabot')
-rw-r--r-- | src/org/jogamp/jabot/irc/CatOut.java | 173 | ||||
-rw-r--r-- | src/org/jogamp/jabot/irc/LogBot.java | 219 | ||||
-rw-r--r-- | src/org/jogamp/jabot/util/TimeTool.java | 32 |
3 files changed, 373 insertions, 51 deletions
diff --git a/src/org/jogamp/jabot/irc/CatOut.java b/src/org/jogamp/jabot/irc/CatOut.java index af2f04d..c7888b3 100644 --- a/src/org/jogamp/jabot/irc/CatOut.java +++ b/src/org/jogamp/jabot/irc/CatOut.java @@ -1,59 +1,53 @@ +/** + * Copyright 2013 JogAmp Community. All rights reserved. + * + * This software is licensed under the GNU General Public License (GPL) Version 3. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ package org.jogamp.jabot.irc; +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; import java.util.Calendar; -import java.util.GregorianCalendar; -import java.util.Locale; -import java.util.TimeZone; import org.jibble.pircbot.PircBot; import org.jogamp.jabot.util.TimeTool; public class CatOut extends PircBot { - private final TimeZone timeZone; - private final Locale locale; - private final Calendar calendar; + private static final String HASH = "#"; - public CatOut() { - this(TimeTool.getNearZuluTimeZone(), Locale.getDefault()); - } - - public CatOut(TimeZone timeZone, Locale locale) { - this.timeZone = timeZone; - this.locale = locale; - calendar = new GregorianCalendar(timeZone, locale); - } - - public final TimeZone getTimeZone() { return timeZone; } - public final Locale getLocale() { return locale; } - - /** Returns timestamp of internal Calendar: YYYYMMDD HH:MM:SS (TMZ) */ - public final String getTimeStamp() { - return TimeTool.getTimeStamp(calendar); - } - - public final void setLoginAndName(String login, String nick) { - super.setLogin(login); - super.setName(nick); - } - - /** Updates internal Calendar w/ current time */ - public final void tick() { - calendar.setTimeInMillis(System.currentTimeMillis()); - } - - public void onMessage(String channel, String sender, - String login, String hostname, String message) { - tick(); - System.out.println(getTimeStamp()+" <"+sender+"/"+login+">: "+message); + private static long atol(String str, long def) { + try { + return Long.parseLong(str); + } catch (Exception ex) { + ex.printStackTrace(); + } + return def; } public static void main(String[] args) throws Exception { - final String login, name, server, channel; + final String joinMessage = "This channel is logged"; + final String login, name, server, channelNoHash; final boolean verbose; + final long logrotate; + final String logprefix; + final boolean htmlOut; + final File htmlHeader, htmlFooter; { - String _login=null, _name=null, _server=null, _channel=null; + String _login=null, _name=null, _server=null, _channelNoHash=null; boolean _verbose=false; + long _logrotate = 0; + String _logprefix=""; + boolean _htmlOut = false; + String _htmlHeader = null, _htmlFooter=null; for(int i=0; i<args.length; i++) { if(args[i].equals("-login")) { i++; @@ -66,27 +60,112 @@ public class CatOut extends PircBot { _server = args[i]; } else if(args[i].equals("-channel")) { i++; - _channel= args[i]; + _channelNoHash= args[i]; + if( _channelNoHash.startsWith(HASH) ) { + _channelNoHash = _channelNoHash.substring(1); + } } else if(args[i].equals("-verbose")) { _verbose=true; + } else if(args[i].equals("-htmlHeader")) { + i++; + _htmlOut=true; + _htmlHeader=args[i]; + } else if(args[i].equals("-htmlFooter")) { + i++; + _htmlOut=true; + _htmlFooter=args[i]; + } else if(args[i].equals("-logrotate")) { + i++; + _logrotate= atol(args[i], _logrotate); + } else if(args[i].equals("-logprefix")) { + i++; + _logprefix = args[i]; } } if( null == _login || null == _name || null == _server || - null == _channel ) { - System.err.println("Incomplete commandline, use "+CatOut.class.getName()+" -login VAL -name VAL -server VAL -channel VAL [-verbose]"); + null == _channelNoHash || + ( _htmlOut && null == _htmlHeader || null == _htmlFooter ) ) { + System.err.println("Incomplete commandline, use "+CatOut.class.getName()+" -login VAL -name VAL -server VAL -channel VAL [-verbose] [-htmlHeader VAL -htmlFooter VAL] [-logrotate millis [-logprefix VAL]]"); return; } login=_login; name=_name; - server=_server; channel=_channel; + server=_server; channelNoHash=_channelNoHash; verbose=_verbose; + logrotate = _logrotate; + logprefix = _logprefix; + htmlOut = _htmlOut; + htmlHeader = new File(_htmlHeader); + htmlFooter= new File(_htmlFooter); } - final CatOut bot = new CatOut(); + final LogBot bot = new LogBot(joinMessage, htmlOut); bot.setVerbose(verbose); - bot.setLoginAndName(login, name); + bot.setLoginAndName(login, name); bot.connect(server); - bot.joinChannel(channel); + bot.joinChannel(HASH+channelNoHash); + if( 0 >= logrotate ) { + // bot.sendRawLine("NAMES "+HASH+channelNoHash); // FIXME ? + } else { + PrintStream fout = null; + long t0 = System.currentTimeMillis(); + int sendNamesCount = 0; + while(true) { // forever ! + // Swap Logfiles: Open and set new logfile, then close old one. + { + final Calendar calendar = bot.tick(); + final String suffix = htmlOut ? ".html" : ".txt" ; + final String logfilename = logprefix+channelNoHash+"_"+name+"_"+TimeTool.getTimeStamp(calendar, true, false)+suffix; + final File _file = new File(logfilename); + final PrintStream _fout = new PrintStream(new FileOutputStream(_file)); + if(htmlOut) { + cat(htmlHeader, _fout); + htmlHead(HASH+channelNoHash+" @ "+server+" - "+bot.getTimeStamp()+" ("+calendar.getTimeZone().getID()+")", + _fout); + } + bot.setOut(_fout); + // bot.sendRawLine("NAMES "+HASH+channelNoHash); // FIXME ? + if(null != fout) { + if(htmlOut) { + cat(htmlFooter, fout); + } + fout.close(); // implies flush + } + fout = _fout; + } + final long t1 = System.currentTimeMillis(); + long td = 0; + while ( td < logrotate ) { + try { + Thread.sleep(FLUSH_INTERVAL); + } catch (Exception e) { } + fout.flush(); + final long t2 = System.currentTimeMillis(); + td = t2 - t1; + if ( sendNamesCount < ( t2 - t0 ) / SEND_NAMES ) { + // bot.sendRawLine("NAMES "+HASH+channelNoHash); // FIXME ? + sendNamesCount++; + } + } + } + } } + public static final long FLUSH_INTERVAL = 60*1000; // every minute + public static final long SEND_NAMES = 10*60*1000; // every 10 minutes + + public static void cat(File source, PrintStream out) throws IOException { + final BufferedInputStream input = new BufferedInputStream(new FileInputStream(source)); + int bytesRead = 0; + byte[] buffer = new byte[1024]; + while ((bytesRead = input.read(buffer, 0, buffer.length)) != -1) { + out.write(buffer, 0, bytesRead); + } + out.flush(); + input.close(); + } + public static void htmlHead(String head, PrintStream out) { + out.println("<h2>"+head+"</h2>"); + out.println("<br/>"); + } } diff --git a/src/org/jogamp/jabot/irc/LogBot.java b/src/org/jogamp/jabot/irc/LogBot.java new file mode 100644 index 0000000..4afee5d --- /dev/null +++ b/src/org/jogamp/jabot/irc/LogBot.java @@ -0,0 +1,219 @@ +/**
+ * Copyright Paul James Mutton, 2001-2009, http://www.jibble.org/
+ *
+ * Copyright 2013 JogAmp Community. All rights reserved.
+ *
+ * This software is licensed under the GNU General Public License (GPL) Version 3.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package org.jogamp.jabot.irc;
+
+import java.io.PrintStream;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.TimeZone;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.jibble.pircbot.Colors;
+import org.jibble.pircbot.PircBot;
+import org.jogamp.jabot.util.TimeTool;
+
+public class LogBot extends PircBot {
+
+ private static final Pattern urlPattern = Pattern.compile("(?i:\\b((http|https|ftp|irc)://[^\\s]+))");
+
+ public static final String GREEN = "irc-green";
+ public static final String BLACK = "irc-black";
+ public static final String BROWN = "irc-brown";
+ public static final String NAVY = "irc-navy";
+ public static final String BRICK = "irc-brick";
+ public static final String RED = "irc-red";
+
+ private final Calendar calendar;
+ private final Object timeSync = new Object();
+
+ private final boolean xmlOut;
+ private final Object outSync = new Object();
+ private PrintStream out;
+
+ private String joinMessage;
+
+ public LogBot(String joinMessage, boolean xmlOut) {
+ this(joinMessage, TimeTool.getNearZuluTimeZone(), Locale.getDefault(), System.out, xmlOut);
+ }
+
+ public LogBot(String joinMessage, TimeZone timeZone, Locale locale, PrintStream out, boolean xmlOut) {
+ calendar = new GregorianCalendar(timeZone, locale);
+ this.xmlOut = xmlOut;
+ this.out = out;
+ this.joinMessage = joinMessage;
+ }
+
+ public final void setLoginAndName(String login, String nick) {
+ super.setLogin(login);
+ super.setName(nick);
+ }
+
+ public final Calendar getCalendar() {
+ return calendar;
+ }
+
+ /** Returns timestamp of internal Calendar: YYYYMMDD HH:MM:SS (TMZ) */
+ public final String getTimeStamp() {
+ return TimeTool.getTimeStamp(calendar, true, true);
+ }
+
+ public final String getTimeStamp(long millis) {
+ final String ts;
+ synchronized(timeSync) {
+ calendar.setTimeInMillis(millis);
+ ts = TimeTool.getTimeStamp(calendar, true, true);
+ calendar.setTimeInMillis(System.currentTimeMillis());
+ }
+ return ts;
+ }
+
+ /** Updates internal Calendar w/ current time and returns it.*/
+ public final Calendar tick() {
+ synchronized(timeSync) {
+ calendar.setTimeInMillis(System.currentTimeMillis());
+ return calendar;
+ }
+ }
+
+ public PrintStream getOut() {
+ synchronized(outSync) {
+ return out;
+ }
+ }
+ public PrintStream setOut(PrintStream newOut) {
+ synchronized(outSync) {
+ final PrintStream old = out;
+ out = newOut;
+ return old;
+ }
+ }
+
+ public void append(String color, String line) {
+ tick();
+
+ if(xmlOut) {
+ line = Colors.removeFormattingAndColors(line);
+
+ line = line.replaceAll("&", "&");
+ line = line.replaceAll("<", "<");
+ line = line.replaceAll(">", ">");
+
+ Matcher matcher = urlPattern.matcher(line);
+ line = matcher.replaceAll("<a href=\"$1\">$1</a>");
+ }
+
+ synchronized(outSync) {
+ if(xmlOut) {
+ out.println("<span class=\"irc-date\">[" + getTimeStamp() + "]</span> <span class=\"" + color + "\">" + line + "</span><br />");
+ } else {
+ out.println(getTimeStamp()+" "+line);
+ }
+ out.flush();
+ }
+
+ }
+
+ public void onAction(String sender, String login, String hostname, String target, String action) {
+ append(BRICK, "* " + sender + " " + action);
+ }
+
+ public void onJoin(String channel, String sender, String login, String hostname) {
+ append(GREEN, "* " + sender + " (" + login + "@" + hostname + ") has joined " + channel);
+ if (sender.equals(getNick())) {
+ sendNotice(channel, joinMessage);
+ }
+ else {
+ sendNotice(sender, joinMessage);
+ }
+ }
+
+ public void onMessage(String channel, String sender, String login, String hostname, String message) {
+ append(BLACK, "<" + sender + "> " + message);
+
+ message = message.toLowerCase();
+ if (message.startsWith(getNick().toLowerCase()) && message.indexOf("help") > 0) {
+ sendMessage(channel, joinMessage);
+ }
+ }
+
+ public void onMode(String channel, String sourceNick, String sourceLogin, String sourceHostname, String mode) {
+ append(GREEN, "* " + sourceNick + " sets mode " + mode);
+ }
+
+ public void onNickChange(String oldNick, String login, String hostname, String newNick) {
+ append(GREEN, "* " + oldNick + " is now known as " + newNick);
+ }
+
+ public void onNotice(String sourceNick, String sourceLogin, String sourceHostname, String target, String notice) {
+ append(BROWN, "-" + sourceNick + "- " + notice);
+ }
+
+ public void onPart(String channel, String sender, String login, String hostname) {
+ append(GREEN, "* " + sender + " (" + login + "@" + hostname + ") has left " + channel);
+ }
+
+ public void onPing(String sourceNick, String sourceLogin, String sourceHostname, String target, String pingValue) {
+ append(RED, "[" + sourceNick + " PING]");
+ }
+
+ public void onPrivateMessage(String sender, String login, String hostname, String message) {
+ append(BLACK, "<- *" + sender + "* " + message);
+ }
+
+ public void onQuit(String sourceNick, String sourceLogin, String sourceHostname, String reason) {
+ append(NAVY, "* " + sourceNick + " (" + sourceLogin + "@" + sourceHostname + ") Quit (" + reason + ")");
+ }
+
+ public void onTime(String sourceNick, String sourceLogin, String sourceHostname, String target) {
+ append(RED, "[" + sourceNick + " TIME]");
+ }
+
+ public void onTopic(String channel, String topic, String setBy, long date, boolean changed) {
+ if (changed) {
+ append(GREEN, "* " + setBy + " changes topic to '" + topic + "'");
+ }
+ else {
+ append(GREEN, "* Topic is '" + topic + "'");
+ append(GREEN, "* Set by " + setBy + " on " + getTimeStamp(date));
+ }
+ }
+
+ public void onVersion(String sourceNick, String sourceLogin, String sourceHostname, String target) {
+ append(RED, "[" + sourceNick + " VERSION]");
+ }
+
+ public void onKick(String channel, String kickerNick, String kickerLogin, String kickerHostname, String recipientNick, String reason) {
+ append(GREEN, "* " + recipientNick + " was kicked from " + channel + " by " + kickerNick);
+ if (recipientNick.equalsIgnoreCase(getNick())) {
+ joinChannel(channel);
+ }
+ }
+
+ public void onDisconnect() {
+ append(NAVY, "* Disconnected.");
+ while (!isConnected()) {
+ try {
+ reconnect();
+ }
+ catch (Exception e) {
+ try {
+ Thread.sleep(10000);
+ }
+ catch (Exception anye) {
+ // Do nothing.
+ }
+ }
+ }
+ }
+}
diff --git a/src/org/jogamp/jabot/util/TimeTool.java b/src/org/jogamp/jabot/util/TimeTool.java index de90361..23f527a 100644 --- a/src/org/jogamp/jabot/util/TimeTool.java +++ b/src/org/jogamp/jabot/util/TimeTool.java @@ -1,3 +1,12 @@ +/** + * Copyright 2013 JogAmp Community. All rights reserved. + * + * This software is licensed under the GNU General Public License (GPL) Version 3. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ package org.jogamp.jabot.util; import java.util.Calendar; @@ -37,8 +46,15 @@ public class TimeTool { return tz; } - /** Returns timestamp of internal Calendar: YYYYMMDD HH:MM:SS (TMZ) */ - public static String getTimeStamp(final Calendar calendar) { + /** + * Returns timestamp of internal Calendar: YYYYMMDD HH:MM:SS + * + * @param calendar Calendar providing current time + * @param withHour if true includes daytime w/ or w/o spacing, otherwise just YYYYMMDD + * @param withSpacing if true provides spacing, otherwise just YYYYMMDDHHMMSS + * @return + */ + public static String getTimeStamp(final Calendar calendar, boolean withHour, boolean withSpacing) { final int year, month, day, hour, minute, seconds; { year = calendar.get(Calendar.YEAR); @@ -48,8 +64,16 @@ public class TimeTool { minute = calendar.get(Calendar.MINUTE); seconds = calendar.get(Calendar.SECOND); } - return String.format("%04d%02d%02d %02d:%02d:%02d (%s)", - year, month, day, hour, minute, seconds, calendar.getTimeZone().getID()); + if( !withHour ) { + return String.format("%04d%02d%02d", year, month, day); + } else { + if( !withSpacing ) { + return String.format("%04d%02d%02d%02d%02d%02d", + year, month, day, hour, minute, seconds); + } else { + return String.format("%04d%02d%02d %02d:%02d:%02d", year, month, day, hour, minute, seconds); + } + } } } |