<commit_before>require "rubygems"
require "cgi"
require "sinatra/base"
require "thread"

class CEPMon
  class Web < Sinatra::Base
    @@event_listener = nil

    set :root, File.join(File.dirname(__FILE__), "..", "..")
    set :public_folder, Proc.new { File.join(root, "static") }
    enable :static

    def self.event_listener=(event_listener)
      @@event_listener = event_listener
    end

    def self.run!(*args, &block)
      started = false
      super(*args) do |server|
        Thread.current[:sinatra] = self
        started = true
        yield(server) if block_given?
      end
      raise "error starting sinatra" unless started
    end

    def initialize(*args)
      if @@event_listener.nil?
        raise "must set CEPMon::Web.event_listener first"
      end

      super(*args)
    end

    helpers do
      def h(obj)
        CGI::escapeHTML(obj.to_s)
      end
    end

    get "/history" do
      @alerts = @@event_listener.history
      erb :history
    end

    get "/alerts" do
      @alerts = @@event_listener.alerts
      erb :alerts
    end
  end # class Web
end # class CEPMon
<commit_msg>add alert filtering by url param, and rule link handlers/helpers<commit_after>require "rubygems"
require "cgi"
require "sinatra/base"
require "thread"
require "uri"

class CEPMon
  class Web < Sinatra::Base
    @@event_listener = nil

    set :root, File.join(File.dirname(__FILE__), "..", "..")
    set :public_folder, Proc.new { File.join(root, "static") }
    enable :static

    def self.event_listener=(event_listener)
      @@event_listener = event_listener
    end

    def self.run!(*args, &block)
      started = false
      super(*args) do |server|
        Thread.current[:sinatra] = self
        started = true
        yield(server) if block_given?
      end
      raise "error starting sinatra" unless started
    end

    def initialize(*args)
      if @@event_listener.nil?
        raise "must set CEPMon::Web.event_listener first"
      end

      super(*args)
    end

    helpers do
      def h(obj)
        CGI::escapeHTML(obj.to_s)
      end

      def rule_link(name, text)
        "<a href=\"/rules/#{name}\">#{h(text)}</a>"
      end

      def filter_alerts(alerts, params)
        res = alerts
        if params[:statement]
          res.delete_if { |a| a.statement != params[:statement] }
        end
        if params[:cluster]
          res.delete_if { |a| a.cluster != params[:cluster] }
        end
        if params[:host]
          res.delete_if { |a| a.host != params[:host] }
        end
        return res
      end
    end

    get "/rules" do
      @rules = @@event_listener.engine.statements
      erb :rules
    end

    get "/rules/:rule" do
      @rule = @@event_listener.engine.statements.select { |r| r[:statement] == params[:rule] }.first
      raise "can't find rule #{params[:rule]}" unless @rule
      erb :rule_detail
    end

    get "/history" do
      @alerts = filter_alerts(@@event_listener.history, params)
      erb :history
    end

    get "/alerts" do
      @alerts = filter_alerts(@@event_listener.alerts, params)
      erb :alerts
    end
  end # class Web
end # class CEPMon

{'fraction_non_alphanumeric': 0.11695721077654517, 'fraction_numerical': 0.0, 'mean_word_length': 2.3467656415694593, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, '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': '1729392', 'n_tokens_mistral': 1031, 'n_tokens_neox': 988, 'n_words': 263}