<commit_before>module MultiMail
  module Receiver
    # Cloudmailin's incoming email receiver.
    class Cloudmailin < MultiMail::Service
      include MultiMail::Receiver::Base

      requires :format

      # Initializes a Cloudmailin incoming email receiver.
      #
      # @param [Hash] options required and optional arguments
      # @option opts [String] :format one of "multipart", "json", "raw" or
      #   "original"
      def initialize(options = {})
        super
        @format = options[:format]
      end

      # @param [Hash] params the content of Cloudmailin's webhook
      # @return [Boolean] whether the request originates from Cloudmailin
      # @see http://docs.cloudmailin.com/receiving_email/securing_your_email_url_target/
      def valid?(params)
        true # @todo
      end

      # @param [Hash] params the content of Cloudmailin's webhook
      # @return [Array<Mail::Message>] messages
      # @see http://docs.cloudmailin.com/http_post_formats/multipart/
      # @see http://docs.cloudmailin.com/http_post_formats/json/
      # @see http://docs.cloudmailin.com/http_post_formats/raw/
      # @see http://docs.cloudmailin.com/http_post_formats/original/
      # @todo Handle cases where the attachment store is in-use.
      def transform(params)
        case @format
        when 'multipart', 'json'
          headers = Multimap.new
          params['headers'].each do |key,value|
            if Array === value
              value.each do |v|
                headers[key] = v
              end
            else
              headers[key] = value
            end
          end

          message = Mail.new do
            headers headers

            text_part do
              body params['plain']
            end

            if params.key?('html')
              html_part do
                content_type 'text/html; charset=UTF-8'
                body params['html']
              end
            end

            if params.key?('attachments')
              params['attachments'].each do |attachment|
                if @format == 'multipart'
                  add_file(:filename => attachment[:filename], :content => attachment[:tempfile].read)
                else
                  add_file(:filename => attachment['file_name'], :content => Base64.decode64(attachment['content']))
                end
              end
            end
          end

          # Extra Cloudmailin parameters.
          message['reply_plain'] = params['reply_plain']

          # Re-use Mailgun headers.
          message['X-Mailgun-Spf'] = params['envelope']['spf']['result']

          # Discard rest of `envelope`: `from`, `to`, `recipients`,
          # `helo_domain` and `remote_ip`.
          [message]
        when 'raw'
          message = Mail.new(params['message'])
          message['X-Mailgun-Spf'] = params['envelope']['spf']['result']
          [message]
        when 'original'
          raise ArgumentError, "Can't handle Cloudmailin original format"
        end<commit_msg>remove a todo<commit_after>module MultiMail
  module Receiver
    # Cloudmailin's incoming email receiver.
    class Cloudmailin < MultiMail::Service
      include MultiMail::Receiver::Base

      requires :format

      # Initializes a Cloudmailin incoming email receiver.
      #
      # @param [Hash] options required and optional arguments
      # @option opts [String] :format one of "multipart", "json", "raw" or
      #   "original"
      def initialize(options = {})
        super
        @format = options[:format]
      end

      # @param [Hash] params the content of Cloudmailin's webhook
      # @return [Boolean] whether the request originates from Cloudmailin
      # @see http://docs.cloudmailin.com/receiving_email/securing_your_email_url_target/
      def valid?(params)
        true
      end

      # @param [Hash] params the content of Cloudmailin's webhook
      # @return [Array<Mail::Message>] messages
      # @see http://docs.cloudmailin.com/http_post_formats/multipart/
      # @see http://docs.cloudmailin.com/http_post_formats/json/
      # @see http://docs.cloudmailin.com/http_post_formats/raw/
      # @see http://docs.cloudmailin.com/http_post_formats/original/
      # @todo Handle cases where the attachment store is in-use.
      def transform(params)
        case @format
        when 'multipart', 'json'
          headers = Multimap.new
          params['headers'].each do |key,value|
            if Array === value
              value.each do |v|
                headers[key] = v
              end
            else
              headers[key] = value
            end
          end

          message = Mail.new do
            headers headers

            text_part do
              body params['plain']
            end

            if params.key?('html')
              html_part do
                content_type 'text/html; charset=UTF-8'
                body params['html']
              end
            end

            if params.key?('attachments')
              params['attachments'].each do |attachment|
                if @format == 'multipart'
                  add_file(:filename => attachment[:filename], :content => attachment[:tempfile].read)
                else
                  add_file(:filename => attachment['file_name'], :content => Base64.decode64(attachment['content']))
                end
              end
            end
          end

          # Extra Cloudmailin parameters.
          message['reply_plain'] = params['reply_plain']

          # Re-use Mailgun headers.
          message['X-Mailgun-Spf'] = params['envelope']['spf']['result']

          # Discard rest of `envelope`: `from`, `to`, `recipients`,
          # `helo_domain` and `remote_ip`.
          [message]
        when 'raw'
          message = Mail.new(params['message'])
          message['X-Mailgun-Spf'] = params['envelope']['spf']['result']
          [message]
        when 'original'
          raise ArgumentError, "Can't handle Cloudmailin original format" # @todo
        end
{'fraction_non_alphanumeric': 0.10775862068965517, 'fraction_numerical': 0.0016578249336870027, 'mean_word_length': 1.89075227599425, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 13, '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': '4425575', 'n_tokens_mistral': 1643, 'n_tokens_neox': 1582, 'n_words': 405}