<commit_before>require 'net/imap'

module Basil
  module Email
    # This class represents a parsed email. Headers are accessed like
    # array indices and body is provided as a method. The parsing is
    # naive, but it works for our purpose.
    class Mail
      attr_reader :body

      def initialize(headers, body)
        @headers, @body = headers, body
      end

      def [](arg)
        @headers[arg]
      end

      def self.parse(content)
        header_lines = []
        headers      = {}

        lines = content.split(/\r\n/)

        while !(line = lines.shift).empty?
          if line =~ /^\s+(.*)/ # continuation
            last = header_lines.pop
            line = "#{last} #{$1}" if last
          end

          header_lines << line
        end

        body = lines.join("\n")

        header_lines.each do |hl|
          if hl =~ /^([^:]+):(.*)$/
            headers[$1] = $2.strip
          end
        end

        new(headers, body)
      end
    end

    class << self
      # Check for email on the configured interval, if a mail is found
      # it is run through each of the email checker plugins. Any replies
      # returned will be handed to the server's broadcast_mail method.
      def check
        # if the server doesn't support us, we just do nothing.
        if Config.server.respond_to?(:broadcast_message)
          logger.debug "Server supports broadcasting"
        else
          logger.debug "Server does not support broadcasting" and return
        end

        Thread.new do
          logger.debug "Email polling spawned"

          loop do
            poll_email

            break unless poll_email?

            sleep(Config.email['interval'] || 30)
          end
        end
      end

      private

      def poll_email
        with_imap do |imap|
          imap.search(['NOT', 'DELETED']).each do |message_id|
            handle_message_id(imap, message_id)
          end
        end

      rescue Exception => ex
        logger.error ex<commit_msg>add Mail#inspect, fix bug in log-broadcasting<commit_after>require 'net/imap'

module Basil
  module Email
    # This class represents a parsed email. Headers are accessed like
    # array indices and body is provided as a method. The parsing is
    # naive, but it works for our purpose.
    class Mail
      attr_reader :body

      def initialize(headers, body)
        @headers, @body = headers, body
      end

      def [](arg)
        @headers[arg]
      end

      def inspect
        "#<Mail from: #{self['From']}, subject: #{self['Subject']}>"
      end

      def self.parse(content)
        header_lines = []
        headers      = {}

        lines = content.split(/\r\n/)

        while !(line = lines.shift).empty?
          if line =~ /^\s+(.*)/ # continuation
            last = header_lines.pop
            line = "#{last} #{$1}" if last
          end

          header_lines << line
        end

        body = lines.join("\n")

        header_lines.each do |hl|
          if hl =~ /^([^:]+):(.*)$/
            headers[$1] = $2.strip
          end
        end

        new(headers, body)
      end
    end

    class << self
      # Check for email on the configured interval, if a mail is found
      # it is run through each of the email checker plugins. Any replies
      # returned will be handed to the server's broadcast_mail method.
      def check
        # if the server doesn't support us, we just do nothing.
        if Config.server.respond_to?(:broadcast_message)
          logger.debug "Server supports broadcasting"
        else
          logger.debug "Server does not support broadcasting"; return
        end

        Thread.new do
          logger.debug "Email polling spawned"

          loop do
            poll_email

            break unless poll_email?

            sleep(Config.email['interval'] || 30)
          end
        end
      end

      private

      def poll_email
        with_imap do |imap|
          imap.search(['NOT', 'DELETED']).each do |message_id|
            handle_message_id(imap, message_id)
          end
        end

      rescue Exception => ex
        logger.error ex
{'fraction_non_alphanumeric': 0.09115022908126356, 'fraction_numerical': 0.0024113817217265494, 'mean_word_length': 1.6882696046662347, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 6, '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': '3053700', 'n_tokens_mistral': 1175, 'n_tokens_neox': 1115, 'n_words': 389}