<commit_before>package ru.org.linux.site;

import java.io.IOException;
import java.net.URLEncoder;
import java.sql.*;
import java.util.Date;

import ru.org.linux.util.HTMLFormatter;
import ru.org.linux.util.ProfileHashtable;
import ru.org.linux.util.UtilException;

public class SearchViewer implements Viewer {
  public static final int SEARCH_TOPICS = 1;
  public static final int SEARCH_ALL = 0;

  public static final int SEARCH_3MONTH = 1;
  public static final int SEARCH_YEAR = 2;

  public static final int SORT_R = 1;
  public static final int SORT_DATE = 2;

  private final String query;
  private int include = SEARCH_ALL;
  private int date = SEARCH_ALL;
  private int section = 0;
  private int sort = SORT_R;

  public SearchViewer(String query) {
    this.query = query;
  }

  public String show(Connection db) throws IOException, SQLException, UtilException {
    StringBuilder select = new StringBuilder("SELECT msgs.id, title, postdate, section, topic, nick, score, max_score, rank(idxFTI, q) as rank, headline(message, q, 'HighlightAll=True') as headline");

    if (include==SEARCH_ALL) {
      select.append(" FROM msgs_and_cmts as msgs, msgbase, plainto_tsquery(?) as q");
    } else {
      select.append(" FROM msgs, msgbase, plainto_tsquery(?) as q");
    }

    select.append(" WHERE msgs.id = msgbase.id AND idxFTI @@ q");

    if (date==SEARCH_3MONTH) {
      select.append(" AND postdate>CURRENT_TIMESTAMP-'3 month'::interval");
    } else if (date == SEARCH_YEAR) {
      select.append(" AND postdate>CURRENT_TIMESTAMP-'1 year'::interval");
    }

    if (section!=0) {
      select.append(" AND section=").append(section);
    }

    if (sort==SORT_DATE) {
      select.append(" ORDER BY postdate DESC");
    } else {
      select.append(" ORDER BY rank DESC");
    }

    select.append(" LIMIT 100");

    PreparedStatement pst = null;
    try {
      pst = db.prepareStatement(select.toString());

      pst.setString(1, query);

      ResultSet rs = pst.executeQuery();

      return printResults(rs);
    } finally {
      if (pst!=null) {
        pst.close();
      }
    }
  }

  private String printResults(ResultSet rs) throws SQLException {
    StringBuilder out = new StringBuilder("<h1> </h1>");

    out.append("<div class=\"messages\"><div class=\"comment\"");

    while (rs.next()) {
      String title = rs.getString("title");
      int topic = rs.getInt("topic");
      int id = rs.getInt("id");
      String headline = rs.getString("headline");
      Timestamp postdate = rs.getTimestamp("postdate");
      String nick = rs.getString("nick");
      int userScore = rs.getInt("score");
      int userMaxScore = rs.getInt("max_score");

      String url;

      if (topic==0) {
        url = "jump-message.jsp?msgid="+id;
      } else {
        url = "jump-message.jsp?msgid="+topic+"&cid="+id;
      }

      out.append("<table width=\"100%\" cellspacing=0 cellpadding=0 border=0>");
      out.append("<tr class=body><td>");
      out.append("<div class=msg>");

      out.append("<h2><a href=\"").append(url).append("\">").append(HTMLFormatter.htmlSpecialChars(title)).append("</a></h2>");

      out.append("<p>").append(headline).append("</p>");

      out.append("<p><i>").append(nick).append(' ');

      if (!"anonymous".equals(nick)) {
        out.append(User.getStars(userScore, userMaxScore)).append(' ');
      }

      out.append("(<a href=\"whois.jsp?nick=").append(URLEncoder.encode(nick)).append("\">*</a>) (").append(Template.dateFormat.format(postdate)).append(")</i>");

      out.append("</div></td></tr></table><p>");
    }

    out.append("</div></div>");

    return out.toString();
  }

  public String getVariantID(ProfileHashtable prof) throws UtilException {
    return "search?q="+ URLEncoder.encode(query)+"&include="+include+"&date="+date+"&section="+section+"&sort="+sort;
  }

  public Date getExpire() {
    return new java.util.Date(new java.util.Date().getTime() + 15*60*1000);
  }

  public static int parseInclude(String include) {
    if (include==null) {
      return SEARCH_ALL;
    }

    if (include.equals("topics")) {
      return SEARCH_TOPICS;
    }

    return SEARCH_ALL;
  }

  public static int parseDate(String date) {
    if (date==null) {
      return SEARCH_YEAR;
    }

    if (date.equals("3month")) {
      return SEARCH_3MONTH;
    }

    if (date.equals("all")) {
      return SEARCH_ALL;
    }

    return SEARCH_YEAR;
  }

  public void setInclude(int include) {
    this.include = include;
  }

  public void setDate(int date) {
    this.date = date;
  }

  public void setSection(int section) {
    this.section = section;
  }

  public void setSort(int sort) {
    this.sort = sort;
  }
}
<commit_msg>валидация HTML результатов поиска<commit_after>package ru.org.linux.site;

import java.io.IOException;
import java.net.URLEncoder;
import java.sql.*;
import java.util.Date;

import ru.org.linux.util.HTMLFormatter;
import ru.org.linux.util.ProfileHashtable;
import ru.org.linux.util.UtilException;

public class SearchViewer implements Viewer {
  public static final int SEARCH_TOPICS = 1;
  public static final int SEARCH_ALL = 0;

  public static final int SEARCH_3MONTH = 1;
  public static final int SEARCH_YEAR = 2;

  public static final int SORT_R = 1;
  public static final int SORT_DATE = 2;

  private final String query;
  private int include = SEARCH_ALL;
  private int date = SEARCH_ALL;
  private int section = 0;
  private int sort = SORT_R;

  public SearchViewer(String query) {
    this.query = query;
  }

  public String show(Connection db) throws IOException, SQLException, UtilException {
    StringBuilder select = new StringBuilder("SELECT msgs.id, title, postdate, section, topic, nick, score, max_score, rank(idxFTI, q) as rank, headline(message, q, 'HighlightAll=True') as headline");

    if (include==SEARCH_ALL) {
      select.append(" FROM msgs_and_cmts as msgs, msgbase, plainto_tsquery(?) as q");
    } else {
      select.append(" FROM msgs, msgbase, plainto_tsquery(?) as q");
    }

    select.append(" WHERE msgs.id = msgbase.id AND idxFTI @@ q");

    if (date==SEARCH_3MONTH) {
      select.append(" AND postdate>CURRENT_TIMESTAMP-'3 month'::interval");
    } else if (date == SEARCH_YEAR) {
      select.append(" AND postdate>CURRENT_TIMESTAMP-'1 year'::interval");
    }

    if (section!=0) {
      select.append(" AND section=").append(section);
    }

    if (sort==SORT_DATE) {
      select.append(" ORDER BY postdate DESC");
    } else {
      select.append(" ORDER BY rank DESC");
    }

    select.append(" LIMIT 100");

    PreparedStatement pst = null;
    try {
      pst = db.prepareStatement(select.toString());

      pst.setString(1, query);

      ResultSet rs = pst.executeQuery();

      return printResults(rs);
    } finally {
      if (pst!=null) {
        pst.close();
      }
    }
  }

  private String printResults(ResultSet rs) throws SQLException {
    StringBuilder out = new StringBuilder("<h1> </h1>");

    out.append("<div class=\"messages\"><div class=\"comment\"");

    while (rs.next()) {
      String title = rs.getString("title");
      int topic = rs.getInt("topic");
      int id = rs.getInt("id");
      String headline = rs.getString("headline");
      Timestamp postdate = rs.getTimestamp("postdate");
      String nick = rs.getString("nick");
      int userScore = rs.getInt("score");
      int userMaxScore = rs.getInt("max_score");

      String url;

      if (topic==0) {
        url = "jump-message.jsp?msgid="+id;
      } else {
        url = "jump-message.jsp?msgid="+topic+"&amp;cid="+id;
      }

      out.append("<table width=\"100%\" cellspacing=0 cellpadding=0 border=0>");
      out.append("<tr class=body><td>");
      out.append("<div class=msg>");

      out.append("<h2><a href=\"").append(url).append("\">").append(HTMLFormatter.htmlSpecialChars(title)).append("</a></h2>");

      out.append("<p>").append(headline).append("</p>");

      out.append("<p><i>").append(nick).append(' ');

      if (!"anonymous".equals(nick)) {
        out.append(User.getStars(userScore, userMaxScore)).append(' ');
      }

      out.append("(<a href=\"whois.jsp?nick=").append(URLEncoder.encode(nick)).append("\">*</a>) (").append(Template.dateFormat.format(postdate)).append(")</i>");

      out.append("</div></td></tr></table><p>");
    }

    out.append("</div></div>");

    return out.toString();
  }

  public String getVariantID(ProfileHashtable prof) throws UtilException {
    return "search?q="+ URLEncoder.encode(query)+"&include="+include+"&date="+date+"&section="+section+"&sort="+sort;
  }

  public Date getExpire() {
    return new java.util.Date(new java.util.Date().getTime() + 15*60*1000);
  }

  public static int parseInclude(String include) {
    if (include==null) {
      return SEARCH_ALL;
    }

    if (include.equals("topics")) {
      return SEARCH_TOPICS;
    }

    return SEARCH_ALL;
  }

  public static int parseDate(String date) {
    if (date==null) {
      return SEARCH_YEAR;
    }

    if (date.equals("3month")) {
      return SEARCH_3MONTH;
    }

    if (date.equals("all")) {
      return SEARCH_ALL;
    }

    return SEARCH_YEAR;
  }

  public void setInclude(int include) {
    this.include = include;
  }

  public void setDate(int date) {
    this.date = date;
  }

  public void setSection(int section) {
    this.section = section;
  }

  public void setSort(int sort) {
    this.sort = sort;
  }
}

{'fraction_non_alphanumeric': 0.15756613756613758, 'fraction_numerical': 0.00783068783068783, 'mean_word_length': 3.234318996415771, 'pattern_counts': {'":': 0, '<': 55, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4635297', 'n_tokens_mistral': 3171, 'n_tokens_neox': 3058, 'n_words': 677}