<commit_before>module Sisimai
  module MTA
    # Sisimai::MTA::X5 parses a bounce email which created by Unknown MTA #5.
    # Methods in the module are called from only Sisimai::Message.
    module X5
      # Imported from p5-Sisimail/lib/Sisimai/MTA/X5.pm
      class << self
        require 'sisimai/mta'
        require 'sisimai/rfc5322'

        Re0 = {
          :from => %r/\bTWFpbCBEZWxpdmVyeSBTdWJzeXN0ZW0\b/,
          :to   => %r/\bNotificationRecipients\b/,
        }
        Re1 = {
          :begin  => %r|\AContent-Type: message/delivery-status|,
          :rfc822 => %r|\AContent-Type: message/rfc822|,
          :endof  => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
        }
        Indicators = Sisimai::MTA.INDICATORS
        LongFields = Sisimai::RFC5322.LONGFIELDS
        RFC822Head = Sisimai::RFC5322.HEADERFIELDS

        def description; return 'Unknown MTA #5'; end
        def smtpagent;   return 'X5'; end
        def headerlist;  return []; end
        def pattern;     return Re0; end

        # Parse bounce messages from Unknown MTA #5
        # @param         [Hash] mhead       Message header of a bounce email
        # @options mhead [String] from      From header
        # @options mhead [String] date      Date header
        # @options mhead [String] subject   Subject header
        # @options mhead [Array]  received  Received headers
        # @options mhead [String] others    Other required headers
        # @param         [String] mbody     Message body of a bounce email
        # @return        [Hash, Nil]        Bounce data list and message/rfc822
        #                                   part or nil if it failed to parse or
        #                                   the arguments are missing
        def scan(mhead, mbody)
          return nil unless mhead
          return nil unless mbody

          match = 0
          plain = ''

          # To: "NotificationRecipients" <...>
          match += 1 if mhead['to'] && mhead['to'] =~ Re0[:to]

          require 'sisimai/mime'
          if mhead['from'] =~ Re0[:from]
            # From: "=?iso-2022-jp?B?TWFpbCBEZWxpdmVyeSBTdWJzeXN0ZW0=?=" <...>
            #       Mail Delivery Subsystem
            mhead['from'].split(' ').each do |f|
              # Check each element of From: header
              next unless Sisimai::MIME.is_mimeencoded(f)
              match += 1 if Sisimai::MIME.mimedecode([f]) =~ /Mail Delivery Subsystem/
              break
            end
          end

          if Sisimai::MIME.is_mimeencoded(mhead['subject'])
            # Subject: =?iso-2022-jp?B?UmV0dXJuZWQgbWFpbDogVXNlciB1bmtub3du?=<commit_msg>Fix code for Lint/UselessAssignment: Useless assignment to variable<commit_after>module Sisimai
  module MTA
    # Sisimai::MTA::X5 parses a bounce email which created by Unknown MTA #5.
    # Methods in the module are called from only Sisimai::Message.
    module X5
      # Imported from p5-Sisimail/lib/Sisimai/MTA/X5.pm
      class << self
        require 'sisimai/mta'
        require 'sisimai/rfc5322'

        Re0 = {
          :from => %r/\bTWFpbCBEZWxpdmVyeSBTdWJzeXN0ZW0\b/,
          :to   => %r/\bNotificationRecipients\b/,
        }
        Re1 = {
          :begin  => %r|\AContent-Type: message/delivery-status|,
          :rfc822 => %r|\AContent-Type: message/rfc822|,
          :endof  => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
        }
        Indicators = Sisimai::MTA.INDICATORS
        LongFields = Sisimai::RFC5322.LONGFIELDS
        RFC822Head = Sisimai::RFC5322.HEADERFIELDS

        def description; return 'Unknown MTA #5'; end
        def smtpagent;   return 'X5'; end
        def headerlist;  return []; end
        def pattern;     return Re0; end

        # Parse bounce messages from Unknown MTA #5
        # @param         [Hash] mhead       Message header of a bounce email
        # @options mhead [String] from      From header
        # @options mhead [String] date      Date header
        # @options mhead [String] subject   Subject header
        # @options mhead [Array]  received  Received headers
        # @options mhead [String] others    Other required headers
        # @param         [String] mbody     Message body of a bounce email
        # @return        [Hash, Nil]        Bounce data list and message/rfc822
        #                                   part or nil if it failed to parse or
        #                                   the arguments are missing
        def scan(mhead, mbody)
          return nil unless mhead
          return nil unless mbody
          match = 0

          # To: "NotificationRecipients" <...>
          match += 1 if mhead['to'] && mhead['to'] =~ Re0[:to]

          require 'sisimai/mime'
          if mhead['from'] =~ Re0[:from]
            # From: "=?iso-2022-jp?B?TWFpbCBEZWxpdmVyeSBTdWJzeXN0ZW0=?=" <...>
            #       Mail Delivery Subsystem
            mhead['from'].split(' ').each do |f|
              # Check each element of From: header
              next unless Sisimai::MIME.is_mimeencoded(f)
              match += 1 if Sisimai::MIME.mimedecode([f]) =~ /Mail Delivery Subsystem/
              break
            end
          end

          if Sisimai::MIME.is_mimeencoded(mhead['subject'])
            # Subject: =?iso-2022-jp?B?UmV0dXJuZWQgbWFpbDogVXNlciB1bmtub3du?=
{'fraction_non_alphanumeric': 0.09969845457972107, 'fraction_numerical': 0.020731247644176404, 'mean_word_length': 1.803486529318542, 'pattern_counts': {'":': 0, '<': 11, '<?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': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1837708', 'n_tokens_mistral': 1783, 'n_tokens_neox': 1692, 'n_words': 429}