<commit_before>require 'net/pop'
require 'net/imap'
require 'net/http'
require_dependency 'emailer'
require_dependency 'user'
require_dependency 'person'
require_dependency 'project'
require_dependency 'conversation'
require_dependency 'task'
require_dependency 'task_list'
require_dependency 'comment'
require_dependency 'activity'
require_dependency 'upload'
require_dependency 'email'

# Receives an email and performs the adequate action
#
# Emails can be sent to <EMAIL> or <EMAIL>
# Cases:
#
# <EMAIL>                  Will post a new comment on the project's activity wall
# <EMAIL>     Will create a new conversation with Subject as a title and Body as a comment
# <EMAIL>   Will post a new comment in the conversation whose id is 5
# <EMAIL>          Will post a new comment in the task whose id is 12
#
# Invalid or malformed emails will be ignored
#
# TODO: Enhance mime and plain messages treatment
#       Parse HTML to Markdown
#       Strip the quoted text from email replies
#
module Emailer::Incoming

  def self.fetch(settings)
    type = settings[:type].to_s.downcase
    send("fetch_#{type}", settings)
  rescue SocketError
    settings_out = settings.merge(:password => '*' * settings[:password].to_s.length)
    logger.error "Error connecting to mail server with settings:\n  #{settings_out.inspect}"
    raise
  end

  def self.fetch_pop(settings)
    Net::POP3.start(settings[:address], settings[:port], settings[:user_name], settings[:password]) do |pop|
      pop.mails.each do |email|
        begin
          Emailer.receive(email.pop)
          email.delete
        rescue Exception
          logger.error "Error receiving email at #{Time.now}: #{$!}"
        end
      end
    end
  end
  
  def self.fetch_imap(settings)
    imap = Net::IMAP.new(settings[:address], settings[:port], true)
    imap.login(settings[:user_name], settings[:password])
    imap.select('Inbox')

    imap.uid_search(["NOT", "DELETED"]).each do |uid|
      source = imap.uid_fetch(uid, ['RFC822']).first.attr['RFC822']

      begin
        Emailer.receive(source)
      rescue Exception
        logger.error "Error receiving email at #{Time.now}: #{$!}"
      end

      imap.uid_copy(uid, "[Gmail]/All Mail")
      imap.uid_store(uid, "+FLAGS", [:Deleted])
    end

    imap.expunge
    imap.logout
    imap.disconnect
  end

  REPLY_REGEX = /(Re:|RE:|Fwd:|FWD:)/

  def receive(email)
    process email
    get_target
    get_action if @target.is_a?(Task)

    case @type
    when :project then post_to(@target)
    when :conversation then @target ? post_to(@target) : create_conversation
    when :task then post_to(@target) if @target
    else raise "Invalid target type"
    end
  end
<commit_msg>New regex for incoming email subject<commit_after>require 'net/pop'
require 'net/imap'
require 'net/http'
require_dependency 'emailer'
require_dependency 'user'
require_dependency 'person'
require_dependency 'project'
require_dependency 'conversation'
require_dependency 'task'
require_dependency 'task_list'
require_dependency 'comment'
require_dependency 'activity'
require_dependency 'upload'
require_dependency 'email'

# Receives an email and performs the adequate action
#
# Emails can be sent to <EMAIL> or <EMAIL>
# Cases:
#
# <EMAIL>                  Will post a new comment on the project's activity wall
# <EMAIL>     Will create a new conversation with Subject as a title and Body as a comment
# <EMAIL>   Will post a new comment in the conversation whose id is 5
# <EMAIL>          Will post a new comment in the task whose id is 12
#
# Invalid or malformed emails will be ignored
#
# TODO: Enhance mime and plain messages treatment
#       Parse HTML to Markdown
#       Strip the quoted text from email replies
#
module Emailer::Incoming

  def self.fetch(settings)
    type = settings[:type].to_s.downcase
    send("fetch_#{type}", settings)
  rescue SocketError
    settings_out = settings.merge(:password => '*' * settings[:password].to_s.length)
    logger.error "Error connecting to mail server with settings:\n  #{settings_out.inspect}"
    raise
  end

  def self.fetch_pop(settings)
    Net::POP3.start(settings[:address], settings[:port], settings[:user_name], settings[:password]) do |pop|
      pop.mails.each do |email|
        begin
          Emailer.receive(email.pop)
          email.delete
        rescue Exception
          logger.error "Error receiving email at #{Time.now}: #{$!}"
        end
      end
    end
  end
  
  def self.fetch_imap(settings)
    imap = Net::IMAP.new(settings[:address], settings[:port], true)
    imap.login(settings[:user_name], settings[:password])
    imap.select('Inbox')

    imap.uid_search(["NOT", "DELETED"]).each do |uid|
      source = imap.uid_fetch(uid, ['RFC822']).first.attr['RFC822']

      begin
        Emailer.receive(source)
      rescue Exception
        logger.error "Error receiving email at #{Time.now}: #{$!}"
      end

      imap.uid_copy(uid, "[Gmail]/All Mail")
      imap.uid_store(uid, "+FLAGS", [:Deleted])
    end

    imap.expunge
    imap.logout
    imap.disconnect
  end

  REPLY_REGEX = /(re|fwd):/i

  def receive(email)
    process email
    get_target
    get_action if @target.is_a?(Task)

    case @type
    when :project then post_to(@target)
    when :conversation then @target ? post_to(@target) : create_conversation
    when :task then post_to(@target) if @target
    else raise "Invalid target type"
    end
  end

{'fraction_non_alphanumeric': 0.10699815837937385, 'fraction_numerical': 0.003683241252302026, 'mean_word_length': 3.444353518821604, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 17, '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': '3842061', 'n_tokens_mistral': 1713, 'n_tokens_neox': 1660, 'n_words': 497}