Package com.uwyn.drone.webui.elements.pub

Source Code of com.uwyn.drone.webui.elements.pub.ChannelLog

/*
* Copyright 2002-2005 Uwyn bvba/sprl <info[remove] at uwyn dot com>
* Distributed under the terms of the GNU Lesser General Public
* License, v2.1 or later
*
* $Id: ChannelLog.java 1769 2005-04-17 15:30:44Z gbevin $
*/
package com.uwyn.drone.webui.elements.pub;

import java.util.*;

import com.uwyn.drone.DroneConfig;
import com.uwyn.drone.core.Bot;
import com.uwyn.drone.core.BotsRunner;
import com.uwyn.drone.core.Channel;
import com.uwyn.drone.modules.exceptions.LogManagerException;
import com.uwyn.drone.modules.logmanagement.DatabaseLogsFactory;
import com.uwyn.drone.modules.logmanagement.LogResultProcessor;
import com.uwyn.drone.protocol.ServerMessage;
import com.uwyn.drone.tools.LocaleProvider;
import com.uwyn.drone.tools.LocaleProviderConfig;
import com.uwyn.rife.config.Config;
import com.uwyn.rife.engine.Element;
import com.uwyn.rife.engine.exceptions.EngineException;
import com.uwyn.rife.site.FormBuilder;
import com.uwyn.rife.site.ValidationBuilder;
import com.uwyn.rife.site.ValidationError;
import com.uwyn.rife.template.Template;
import com.uwyn.rife.tools.ExceptionUtils;
import com.uwyn.rife.tools.Localization;
import com.uwyn.rife.tools.StringUtils;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;

public class ChannelLog extends Element
{
  public static final String        IRC_ACTION = "\u0001ACTION";

  public static final String[]       NICK_COLORS = new String[] {"eeeeee", "eeeecc", "cceeee", "eeccee", "ccccee", "eecccc", "cceecc"};
  public static final Pattern        URL_HIGHLIGHT = Pattern.compile("((?:http|ftp)s?://(?:%[\\p{Digit}A-Fa-f][\\p{Digit}A-Fa-f]|[\\-_\\.!~*';\\|/?:@#&=\\+$,\\p{Alnum}])+)");
  public static final Pattern        EMAIL_HIGHLIGHT = Pattern.compile("([a-zA-Z0-9][_\\-\\.\\w]*@[\\w\\.\\-]+\\.[a-zA-Z]{2,4})");

    public SimpleDateFormat    mDateFormat;
  public SimpleDateFormat    mOutputTimeFormat;
    public SimpleDateFormat    mOutputDateFormat;
 
  public LocaleProvider    mLocaleProvider = LocaleProviderConfig.SINGLETON;

  private Highlighter     mHighlighter = null;
  private Search.SearchBean   mSearchBean = null;

  private Template  mTemplate = null;

  static Channel validateChannel(ArrayList errors, Bot bot, String channelName)
  {
    if (null == channelName)
    {
      errors.add(new ValidationError.MANDATORY("channelname"));
    }
    else
    {
      Channel channel = bot.getJoinedChannel(channelName);
      if (null == channel)
      {
        errors.add(new ValidationError.INVALID("channelname"));
      }
      else
      {
        return channel;
      }
    }

    return null;
  }
 
  public void setLocaleProvider(LocaleProvider localeProvider)
  {
    mLocaleProvider = localeProvider;
  }
 
  public void initialize()
  {
    mTemplate = getHtmlTemplate("drone.pub.channel_log");

    Locale locale = mLocaleProvider.retrieveLocale(this, mTemplate);
    mDateFormat = new SimpleDateFormat("yyyyMMdd", locale);
    mOutputTimeFormat = new SimpleDateFormat("HH:mm", locale);
    mOutputDateFormat = new SimpleDateFormat("dd-MMMM-yyyy", locale);
   
    mDateFormat.setTimeZone(TimeZone.getTimeZone(DroneConfig.getTimezone()));
    mOutputTimeFormat.setTimeZone(TimeZone.getTimeZone(DroneConfig.getTimezone()));
    mOutputDateFormat.setTimeZone(TimeZone.getTimeZone(DroneConfig.getTimezone()));
  }

  public final void processElement()
  {
    ArrayList errors = new ArrayList();

    Bot      bot = null;
    Channel    channel = null;
    Calendar  day = null;

    String botname = null;
    String channelname = null;
    String daystring = null;

    botname = getInput("botname");
    channelname = getInput("channelname");
    daystring = getInput("day");

    String[] parts = StringUtils.splitToArray(getPathInfo(), "/");
    try
    {
      if (null == botname &&
        parts.length > 1)
      {
        botname = URLDecoder.decode(parts[1], "ISO-8859-1");
      }
      if (null == channelname &&
        parts.length > 2)
      {
        channelname = "#"+URLDecoder.decode(parts[2], "ISO-8859-1");
      }
      if (null == daystring &&
        parts.length > 3)
      {
        daystring = URLDecoder.decode(parts[3], "ISO-8859-1");
      }
    }
    catch (UnsupportedEncodingException e)
    {
      Logger.getLogger("com.uwyn.drone").severe(ExceptionUtils.getExceptionStackTrace(e));
    }

    if (null == botname ||
      null == channelname)
    {
      exit("back_to_list");
    }

    if (!channelname.startsWith("#"))
    {
      channelname = "#"+channelname;
    }

    bot = BotList.validateBotName(errors, botname);
    if (bot != null)
    {
      channel = validateChannel(errors, bot, channelname);
    }
   
    if (null == bot ||
      null == channel)
    {
      exit("back_to_list");
    }
   
    day = Calendar.getInstance(TimeZone.getTimeZone(DroneConfig.getTimezone()));
    if (daystring != null)
    {
      try
      {
        day.setTime(mDateFormat.parse(daystring));
      }
      catch (ParseException e)
      {
        errors.add(new ValidationError.INVALID("DAY"));
      }
    }

    processChannelLog(errors, bot, channel, day);
  }

  protected void processChannelLog(ArrayList errors, Bot bot, Channel channel, Calendar day)
  {
    initializeHighlighting();

    FormBuilder form_builder = mTemplate.getBeanHandler().getFormBuilder();
    form_builder.generateField(mTemplate, "q", new String[] {mSearchBean.getKeyword()}, null);
    if (!hasInputValue("botname") ||
      !hasInputValue("channelname"))
    {
      setSubmissionForm(mTemplate, "search", new String[] {"qbot", bot.getName(), "qchannel", channel.getName()});
    }

    if (errors.size() > 0)
    {
      mTemplate
        .getBeanHandler()
        .getFormBuilder()
        .getValidationBuilder()
        .generateValidationErrors(mTemplate, errors, null, null);
    }
    else
    {
      Calendar previous = Calendar.getInstance(TimeZone.getTimeZone(DroneConfig.getTimezone()));
      Calendar next = Calendar.getInstance(TimeZone.getTimeZone(DroneConfig.getTimezone()));
      previous.set(day.get(Calendar.YEAR), day.get(Calendar.MONTH), day.get(Calendar.DAY_OF_MONTH));
      previous.add(Calendar.DAY_OF_MONTH, -1);
      next.set(day.get(Calendar.YEAR), day.get(Calendar.MONTH), day.get(Calendar.DAY_OF_MONTH));
      next.add(Calendar.DAY_OF_MONTH, 1);
      setExitQuery(mTemplate, "show_previous", "/"+StringUtils.encodeUrl(bot.getName())+"/"+StringUtils.encodeUrl(channel.getName().substring(1))+"/"+mDateFormat.format(previous.getTime()));
      setExitQuery(mTemplate, "show_next", "/"+StringUtils.encodeUrl(bot.getName())+"/"+StringUtils.encodeUrl(channel.getName().substring(1))+"/"+mDateFormat.format(next.getTime()));

      mTemplate.setValue("botname", encodeHtml(bot.getName()));
      mTemplate.setValue("channelname", encodeHtml(channel.getName()));
      mTemplate.setValue("servername", encodeHtml(channel.getServer().getServerName()));
      mTemplate.setValue("day", encodeHtml(mOutputDateFormat.format(day.getTime())));

      GetLogMessages log_messages = new GetLogMessages();
      try
      {
        if (DatabaseLogsFactory.get().getLogMessages(log_messages, bot, channel, day))
        {
          setOutput("botname", bot.getName());
          setOutput("channelname", channel.getName());
          setOutput("day", mDateFormat.format(day.getTime()));
          setExitQuery(mTemplate, "download");
        }
        else
        {
          mTemplate.setValue("download", "");
        }
      }
      catch (LogManagerException e)
      {
        throw new EngineException(e);
      }
    }

    print(mTemplate);
  }

  private void initializeHighlighting() throws EngineException
  {
    Query query = null;

    mSearchBean = (Search.SearchBean)getNamedInputBean("SearchBean");
    if (mSearchBean != null &&
      mSearchBean.getKeyword() != null &&
      !mSearchBean.getKeyword().equals(""))
    {
      try
      {
        query = QueryParser.parse(mSearchBean.getKeyword(), "message", new StandardAnalyzer());
      }
      catch (org.apache.lucene.queryParser.ParseException e)
      {
        // just ignore it, nothing I can do
      }
    }

    if (query != null)
    {
      try
      {
        Collection   bots = BotsRunner.getRepInstance().getBots();
        Iterator   iter = bots.iterator();

        String readerDir = null;
        while (iter.hasNext())
        {
          Bot bot = (Bot)iter.next();

          if (bot.getName().equals(getInput("botname")))
          {
            StringBuffer key = new StringBuffer();
            key
              .append(Config.getRepInstance().getString("LUCENE_DIR"))
              .append(File.separator)
              .append(bot.getName())
              .append("-")
              .append(bot.getServer().getServerName())
              .append("-")
              .append(getInput("channelname").substring(1));

            readerDir = key.toString();
          }
        }

        if (readerDir != null)
        {
          IndexReader     reader = IndexReader.open(readerDir);
          SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("<span class=\"highlighted\">", "</span>");

          mHighlighter = new Highlighter(formatter, new QueryScorer(query.rewrite(reader)));
        }
        else
        {
          throw new IOException("Couldn't find the correct index directory for this bot, channel, and server combination");
        }
      }
      catch (IOException e)
      {
        // nothing I can do, non-essential feature
        Logger
          .getLogger("com.uwyn.drone.webui.elements.pub")
          .severe(ExceptionUtils.getExceptionStackTrace(e));
      }
    }
  }

  public void doSearch()
  {
    String query = getParameter("q");

    if (query != null && !query.equals(""))
    {
      Search.SearchBean bean = new Search.SearchBean();
      bean.setKeyword(query);
      //bean.setDate(Search.INPUT_DATE_FORMAT_SHORT.format(DATE_FORMAT.parse(getInput("day"))));
      bean.setChannel(getInput("botname", getParameter("qbot"))+" - "+getInput("channelname", getParameter("qchannel")));
 
      setNamedOutputBean("SearchBean", bean);
 
      exit("search");
    }
    else
    {
      ValidationBuilder   validationBuilder = mTemplate.getBeanHandler().getFormBuilder().getValidationBuilder();
      List         validationErrors = new ArrayList();
     
      validationErrors.add(new ValidationError.INVALID("q"));
     
      validationBuilder.generateErrorMarkings(mTemplate, validationErrors, null, null);
      validationBuilder.generateValidationErrors(mTemplate, validationErrors, null, null);
    }
   
    processElement();
  }

  private class GetLogMessages extends LogResultProcessor
  {
    private HashMap  mNickColors = new HashMap();

    private int mColorCounter = 0;

    public boolean gotMessage(Timestamp moment, ServerMessage serverMessage)
    {
      String nickname = serverMessage.getPrefix().getNickName();

      String nickcolor = (String)mNickColors.get(nickname);
      if (null == nickcolor)
      {
        nickcolor = NICK_COLORS[mColorCounter++%NICK_COLORS.length];
        mNickColors.put(nickname, nickcolor);
      }
      mTemplate.setValue("bgcolor", nickcolor);

      mTemplate.setValue("time", mOutputTimeFormat.format(moment));
      mTemplate.setValue("nickname", encodeHtml(nickname));

      // translate the \u0001ACTION command which corresponds to
      // /me so that the user's nickname is used instead
      StringBuffer message = new StringBuffer();
      if (serverMessage.getPrefix() != null &&
        serverMessage.getTrailing().startsWith(IRC_ACTION))
      {
        message.append(serverMessage.getPrefix().getNickName());
        message.append(serverMessage.getTrailing().substring(IRC_ACTION.length()));
      }
      else
      {
        message.append(serverMessage.getTrailing());
      }

      String encoded_message = encodeHtml(message.toString());

      if (mHighlighter != null)
      {
        try
        {
          TokenStream tokenStream = new StandardAnalyzer().tokenStream("message", new StringReader(encoded_message));
          String highlighted = mHighlighter.getBestFragments(tokenStream, encoded_message, 25, "...");

          if (!highlighted.equals(""))
          {
            encoded_message = highlighted;
          }
        }
        catch (IOException e)
        {
          Logger
            .getLogger("com.uwyn.drone.webui.elements.pub")
            .severe(ExceptionUtils.getExceptionStackTrace(e));
        }
      }
     
      encoded_message = convertUrl(encoded_message, URL_HIGHLIGHT);

      Matcher email_matcher = EMAIL_HIGHLIGHT.matcher(encoded_message);
      encoded_message = email_matcher.replaceAll("<a href=\"mailto:$1\">$1</a>");

      mTemplate.setValue("message", encoded_message);

      mTemplate.appendBlock("messages", "message");

      return true;
    }
  }

  public static String convertUrl(String source, Pattern pattern)
  {
    String result = source;

    Matcher  url_matcher = pattern.matcher(source);
    boolean found = url_matcher.find();
        if (found)
    {
      String visual_url = null;
      String actual_url = null;
      int last = 0;
            StringBuffer sb = new StringBuffer();
      synchronized (sb)
      {
        do
        {
          actual_url = url_matcher.group(1);
          if (url_matcher.groupCount() > 1)
          {
            visual_url = url_matcher.group(2);
          }
          else
          {
            visual_url = actual_url;
          }

          sb.append(source.substring(last, url_matcher.start(0)));
          sb.append("<a href=\"");
          if (actual_url.startsWith("www."))
          {
            actual_url = "http://"+actual_url;
          }
          sb.append(actual_url);
          sb.append("\"");
          sb.append(">");
          if (visual_url.length() <= 80)
          {
            sb.append(visual_url);
          }
          else
          {
            String ellipsis = "...";
            int last_slash = visual_url.lastIndexOf("/");
            int trailing_length = visual_url.length() - last_slash + ellipsis.length();
            int start_slash = visual_url.indexOf("/", visual_url.indexOf("://")+3);
            int previous_start_slash = start_slash;
            while (start_slash+trailing_length < 80)
            {
              previous_start_slash = start_slash;
              start_slash = visual_url.indexOf("/", previous_start_slash+1);
            }

            sb.append(visual_url.substring(0, previous_start_slash+1));
            sb.append(ellipsis);
            sb.append(visual_url.substring(last_slash));
          }
          sb.append("</a>");

          last = url_matcher.end(0);

          found = url_matcher.find();
        }
        while (found);

        sb.append(source.substring(last));
        result = sb.toString();
      }
        }

    return result;
  }
}
TOP

Related Classes of com.uwyn.drone.webui.elements.pub.ChannelLog

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.