<commit_before>require 'stockboy/provider'
require 'stockboy/providers/imap/search_options'
require 'net/imap'
require 'mail'

module Stockboy::Providers

  # Read data from a file attachment in IMAP email
  #
  # == Job template DSL
  #
  #   provider :imap do
  #     host "imap.example.com"
  #     username "<EMAIL>"
  #     password "<PASSWORD>"
  #     mailbox "INBOX"
  #     subject "Daily Report"
  #     since Date.today
  #     file_name /report-[0-9]+\.csv/
  #   end
  #
  class IMAP < Stockboy::Provider

    # @!group Options

    # Host name or IP address for IMAP server connection
    #
    # @!attribute [rw] host
    # @return [String]
    # @example
    #   host "imap.example.com"
    #
    dsl_attr :host

    # User name for connection credentials
    #
    # @!attribute [rw] username
    # @return [String]
    # @example
    #   username "<EMAIL>"
    #
    dsl_attr :username

    # Password for connection credentials
    #
    # @!attribute [rw] password
    # @return [String]
    # @example
    #   password "<PASSWORD>"
    #
    dsl_attr :password

    # Where to look for email on the server (usually "INBOX")
    #
    # @!attribute [rw] mailbox
    # @return [String]
    # @example
    #   mailbox "INBOX"
    #
    dsl_attr :mailbox

    # Substring to find contained in matching email subject
    #
    # @!attribute [rw] subject
    # @return [String]
    # @example
    #   subject "Daily Report"
    #
    dsl_attr :subject

    # Email address of the sender
    #
    # @!attribute [rw] from
    # @return [String]
    # @example
    #   from "<EMAIL>"
    #
    dsl_attr :from

    # Minimum time sent for matching email
    #
    # @!attribute [rw] since
    # @return [String]
    # @example
    #   since Date.today
    #
    dsl_attr :since, alias: :newer_than

    # Key-value tokens for IMAP search options
    #
    # @!attribute [rw] search
    # @return [String]
    # @example
    #   search ['FLAGGED', 'BODY', 'Report attached']
    #
    dsl_attr :search

    # Name or pattern for matching attachment files. First matching attachment
    # is picked, or the first attachment if not specified.
    #
    # @!attribute [rw] attachment
    # @return [String, Regexp]
    # @example
    #   attachment "daily-report.csv"
    #   attachment /daily-report-[0-9]+.csv/
    #
    dsl_attr :attachment, alias: :file_name

    # @macro file_size_options
    dsl_attr :file_smaller, alias: :smaller_than
    dsl_attr :file_larger,  alias: :larger_than

    # Method for choosing which email message to process from potential
    # matches. Default is last by date sent.
    #
    # @!attribute [rw] pick
    # @return [Symbol, Proc]
    # @example
    #   pick :last
    #   pick :first
    #   pick ->(list) {
    #     list.max_by { |msgid| client.fetch(msgid, 'SENTON').to_i }
    #   }
    #
    dsl_attr :pick

    # @!endgroup

    # Initialize a new IMAP reader
    #
    def initialize(opts={}, &block)
      super(opts, &block)
      @host         = opts[:host]
      @username     = opts[:username]
      @password     = opts[:password]
      @mailbox      = opts[:mailbox]
      @subject      = opts[:subject]
      @from         = opts[:from]
      @since        = opts[:since]
      @search       = opts[:search]
      @attachment   = opts[:attachment]
      @file_smaller = opts[:file_smaller]
      @file_larger  = opts[:file_larger]
      @pick         = opts[:pick] || :last
      DSL.new(self).instance_eval(&block) if block_given?
    end

    # Direct access to the configured +Net::IMAP+ connection
    #
    # @example
    #   provider.client do |imap|<commit_msg>Fix requiring of nested module<commit_after>require 'stockboy/provider'
require 'net/imap'
require 'mail'

module Stockboy::Providers

  # Read data from a file attachment in IMAP email
  #
  # == Job template DSL
  #
  #   provider :imap do
  #     host "imap.example.com"
  #     username "<EMAIL>"
  #     password "<PASSWORD>"
  #     mailbox "INBOX"
  #     subject "Daily Report"
  #     since Date.today
  #     file_name /report-[0-9]+\.csv/
  #   end
  #
  class IMAP < Stockboy::Provider

    # @!group Options

    # Host name or IP address for IMAP server connection
    #
    # @!attribute [rw] host
    # @return [String]
    # @example
    #   host "imap.example.com"
    #
    dsl_attr :host

    # User name for connection credentials
    #
    # @!attribute [rw] username
    # @return [String]
    # @example
    #   username "<EMAIL>"
    #
    dsl_attr :username

    # Password for connection credentials
    #
    # @!attribute [rw] password
    # @return [String]
    # @example
    #   password "<PASSWORD>"
    #
    dsl_attr :password

    # Where to look for email on the server (usually "INBOX")
    #
    # @!attribute [rw] mailbox
    # @return [String]
    # @example
    #   mailbox "INBOX"
    #
    dsl_attr :mailbox

    # Substring to find contained in matching email subject
    #
    # @!attribute [rw] subject
    # @return [String]
    # @example
    #   subject "Daily Report"
    #
    dsl_attr :subject

    # Email address of the sender
    #
    # @!attribute [rw] from
    # @return [String]
    # @example
    #   from "<EMAIL>"
    #
    dsl_attr :from

    # Minimum time sent for matching email
    #
    # @!attribute [rw] since
    # @return [String]
    # @example
    #   since Date.today
    #
    dsl_attr :since, alias: :newer_than

    # Key-value tokens for IMAP search options
    #
    # @!attribute [rw] search
    # @return [String]
    # @example
    #   search ['FLAGGED', 'BODY', 'Report attached']
    #
    dsl_attr :search

    # Name or pattern for matching attachment files. First matching attachment
    # is picked, or the first attachment if not specified.
    #
    # @!attribute [rw] attachment
    # @return [String, Regexp]
    # @example
    #   attachment "daily-report.csv"
    #   attachment /daily-report-[0-9]+.csv/
    #
    dsl_attr :attachment, alias: :file_name

    # @macro file_size_options
    dsl_attr :file_smaller, alias: :smaller_than
    dsl_attr :file_larger,  alias: :larger_than

    # Method for choosing which email message to process from potential
    # matches. Default is last by date sent.
    #
    # @!attribute [rw] pick
    # @return [Symbol, Proc]
    # @example
    #   pick :last
    #   pick :first
    #   pick ->(list) {
    #     list.max_by { |msgid| client.fetch(msgid, 'SENTON').to_i }
    #   }
    #
    dsl_attr :pick

    # @!endgroup

    # Initialize a new IMAP reader
    #
    def initialize(opts={}, &block)
      require 'stockboy/providers/imap/search_options'
      super(opts, &block)
      @host         = opts[:host]
      @username     = opts[:username]
      @password     = opts[:password]
      @mailbox      = opts[:mailbox]
      @subject      = opts[:subject]
      @from         = opts[:from]
      @since        = opts[:since]
      @search       = opts[:search]
      @attachment   = opts[:attachment]
      @file_smaller = opts[:file_smaller]
      @file_larger  = opts[:file_larger]
      @pick         = opts[:pick] || :last
      DSL.new(self).instance_eval(&block) if block_given?
    end

    # Direct access to the configured +Net::IMAP+ connection
    #
    # @example
    #   provider.client do |imap|
{'fraction_non_alphanumeric': 0.11658208750514333, 'fraction_numerical': 0.001097243176518996, 'mean_word_length': 2.2194260485651216, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '337733', 'n_tokens_mistral': 2420, 'n_tokens_neox': 2350, 'n_words': 635}