sisimai 4.25.16-java → 5.0.2-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/rake-test.yml +55 -0
  3. data/.travis.yml +3 -3
  4. data/ANALYTICAL-PRECISION +2 -2
  5. data/Benchmarks.mk +3 -3
  6. data/CONTRIBUTING +1 -1
  7. data/ChangeLog.md +451 -393
  8. data/Developers.mk +5 -6
  9. data/Gemfile +1 -1
  10. data/Makefile +15 -15
  11. data/README-JA.md +323 -149
  12. data/README.md +319 -149
  13. data/Rakefile +9 -3
  14. data/Repository.mk +2 -3
  15. data/lib/sisimai/address.rb +118 -74
  16. data/lib/sisimai/arf.rb +84 -82
  17. data/lib/sisimai/datetime.rb +5 -52
  18. data/lib/sisimai/{data → fact}/json.rb +7 -9
  19. data/lib/sisimai/fact/yaml.rb +31 -0
  20. data/lib/sisimai/fact.rb +506 -0
  21. data/lib/sisimai/lhost/activehunter.rb +12 -14
  22. data/lib/sisimai/lhost/amavis.rb +11 -14
  23. data/lib/sisimai/lhost/amazonses.rb +37 -42
  24. data/lib/sisimai/lhost/amazonworkmail.rb +15 -19
  25. data/lib/sisimai/lhost/aol.rb +12 -15
  26. data/lib/sisimai/lhost/apachejames.rb +19 -21
  27. data/lib/sisimai/lhost/barracuda.rb +10 -12
  28. data/lib/sisimai/lhost/bigfoot.rb +21 -22
  29. data/lib/sisimai/lhost/biglobe.rb +15 -16
  30. data/lib/sisimai/lhost/courier.rb +20 -20
  31. data/lib/sisimai/lhost/domino.rb +23 -20
  32. data/lib/sisimai/lhost/einsundeins.rb +23 -18
  33. data/lib/sisimai/lhost/exchange2003.rb +30 -29
  34. data/lib/sisimai/lhost/exchange2007.rb +70 -58
  35. data/lib/sisimai/lhost/exim.rb +179 -174
  36. data/lib/sisimai/lhost/ezweb.rb +31 -56
  37. data/lib/sisimai/lhost/facebook.rb +21 -34
  38. data/lib/sisimai/lhost/fml.rb +43 -48
  39. data/lib/sisimai/lhost/gmail.rb +29 -29
  40. data/lib/sisimai/lhost/gmx.rb +18 -17
  41. data/lib/sisimai/lhost/googlegroups.rb +11 -11
  42. data/lib/sisimai/lhost/gsuite.rb +21 -28
  43. data/lib/sisimai/lhost/imailserver.rb +25 -39
  44. data/lib/sisimai/lhost/interscanmss.rb +28 -31
  45. data/lib/sisimai/lhost/kddi.rb +22 -28
  46. data/lib/sisimai/lhost/mailfoundry.rb +11 -12
  47. data/lib/sisimai/lhost/mailmarshalsmtp.rb +25 -29
  48. data/lib/sisimai/lhost/mailru.rb +37 -40
  49. data/lib/sisimai/lhost/mcafee.rb +21 -31
  50. data/lib/sisimai/lhost/messagelabs.rb +17 -21
  51. data/lib/sisimai/lhost/messagingserver.rb +40 -37
  52. data/lib/sisimai/lhost/mfilter.rb +16 -17
  53. data/lib/sisimai/lhost/mxlogic.rb +24 -33
  54. data/lib/sisimai/lhost/notes.rb +17 -17
  55. data/lib/sisimai/lhost/office365.rb +64 -28
  56. data/lib/sisimai/lhost/opensmtpd.rb +12 -13
  57. data/lib/sisimai/lhost/outlook.rb +12 -16
  58. data/lib/sisimai/lhost/postfix.rb +179 -130
  59. data/lib/sisimai/lhost/powermta.rb +12 -14
  60. data/lib/sisimai/lhost/qmail.rb +44 -47
  61. data/lib/sisimai/lhost/receivingses.rb +15 -21
  62. data/lib/sisimai/lhost/sendgrid.rb +34 -34
  63. data/lib/sisimai/lhost/sendmail.rb +65 -53
  64. data/lib/sisimai/lhost/surfcontrol.rb +19 -19
  65. data/lib/sisimai/lhost/v5sendmail.rb +45 -39
  66. data/lib/sisimai/lhost/verizon.rb +35 -39
  67. data/lib/sisimai/lhost/x1.rb +18 -17
  68. data/lib/sisimai/lhost/x2.rb +17 -14
  69. data/lib/sisimai/lhost/x3.rb +19 -19
  70. data/lib/sisimai/lhost/x4.rb +72 -57
  71. data/lib/sisimai/lhost/x5.rb +17 -19
  72. data/lib/sisimai/lhost/x6.rb +41 -17
  73. data/lib/sisimai/lhost/yahoo.rb +17 -16
  74. data/lib/sisimai/lhost/yandex.rb +16 -21
  75. data/lib/sisimai/lhost/zoho.rb +16 -15
  76. data/lib/sisimai/lhost.rb +8 -10
  77. data/lib/sisimai/mail/maildir.rb +1 -3
  78. data/lib/sisimai/mail/mbox.rb +3 -4
  79. data/lib/sisimai/mail/memory.rb +0 -1
  80. data/lib/sisimai/mail/stdin.rb +1 -3
  81. data/lib/sisimai/mail.rb +3 -7
  82. data/lib/sisimai/mda.rb +28 -42
  83. data/lib/sisimai/message.rb +444 -326
  84. data/lib/sisimai/order.rb +5 -5
  85. data/lib/sisimai/reason/authfailure.rb +65 -0
  86. data/lib/sisimai/reason/badreputation.rb +53 -0
  87. data/lib/sisimai/reason/blocked.rb +96 -160
  88. data/lib/sisimai/reason/contenterror.rb +8 -9
  89. data/lib/sisimai/reason/delivered.rb +4 -6
  90. data/lib/sisimai/reason/exceedlimit.rb +10 -12
  91. data/lib/sisimai/reason/expired.rb +7 -8
  92. data/lib/sisimai/reason/feedback.rb +2 -3
  93. data/lib/sisimai/reason/filtered.rb +17 -19
  94. data/lib/sisimai/reason/hasmoved.rb +9 -10
  95. data/lib/sisimai/reason/hostunknown.rb +15 -15
  96. data/lib/sisimai/reason/mailboxfull.rb +11 -12
  97. data/lib/sisimai/reason/mailererror.rb +18 -20
  98. data/lib/sisimai/reason/mesgtoobig.rb +9 -11
  99. data/lib/sisimai/reason/networkerror.rb +5 -8
  100. data/lib/sisimai/reason/norelaying.rb +8 -11
  101. data/lib/sisimai/reason/notaccept.rb +13 -14
  102. data/lib/sisimai/reason/notcompliantrfc.rb +43 -0
  103. data/lib/sisimai/reason/onhold.rb +6 -9
  104. data/lib/sisimai/reason/policyviolation.rb +14 -12
  105. data/lib/sisimai/reason/rejected.rb +26 -24
  106. data/lib/sisimai/reason/requireptr.rb +69 -0
  107. data/lib/sisimai/reason/securityerror.rb +34 -36
  108. data/lib/sisimai/reason/spamdetected.rb +115 -147
  109. data/lib/sisimai/reason/speeding.rb +49 -0
  110. data/lib/sisimai/reason/suspend.rb +12 -11
  111. data/lib/sisimai/reason/syntaxerror.rb +11 -10
  112. data/lib/sisimai/reason/systemerror.rb +7 -9
  113. data/lib/sisimai/reason/systemfull.rb +7 -8
  114. data/lib/sisimai/reason/toomanyconn.rb +9 -11
  115. data/lib/sisimai/reason/undefined.rb +2 -3
  116. data/lib/sisimai/reason/userunknown.rb +129 -146
  117. data/lib/sisimai/reason/vacation.rb +3 -4
  118. data/lib/sisimai/reason/virusdetected.rb +10 -11
  119. data/lib/sisimai/reason.rb +59 -64
  120. data/lib/sisimai/rfc1894.rb +55 -28
  121. data/lib/sisimai/rfc2045.rb +373 -0
  122. data/lib/sisimai/rfc3464.rb +250 -308
  123. data/lib/sisimai/rfc3834.rb +42 -45
  124. data/lib/sisimai/rfc5322.rb +177 -146
  125. data/lib/sisimai/rfc5965.rb +31 -0
  126. data/lib/sisimai/rhost/cox.rb +5 -6
  127. data/lib/sisimai/rhost/franceptt.rb +6 -8
  128. data/lib/sisimai/rhost/godaddy.rb +12 -12
  129. data/lib/sisimai/rhost/google.rb +530 -0
  130. data/lib/sisimai/rhost/iua.rb +9 -10
  131. data/lib/sisimai/rhost/kddi.rb +6 -8
  132. data/lib/sisimai/rhost/{exchangeonline.rb → microsoft.rb} +115 -114
  133. data/lib/sisimai/rhost/mimecast.rb +51 -42
  134. data/lib/sisimai/rhost/nttdocomo.rb +12 -12
  135. data/lib/sisimai/rhost/spectrum.rb +10 -12
  136. data/lib/sisimai/rhost/{tencentqq.rb → tencent.rb} +7 -8
  137. data/lib/sisimai/rhost.rb +23 -31
  138. data/lib/sisimai/smtp/command.rb +59 -0
  139. data/lib/sisimai/smtp/error.rb +4 -7
  140. data/lib/sisimai/smtp/reply.rb +161 -74
  141. data/lib/sisimai/smtp/status.rb +507 -393
  142. data/lib/sisimai/smtp/transcript.rb +124 -0
  143. data/lib/sisimai/smtp.rb +0 -1
  144. data/lib/sisimai/string.rb +74 -5
  145. data/lib/sisimai/time.rb +1 -2
  146. data/lib/sisimai/version.rb +1 -1
  147. data/lib/sisimai.rb +46 -31
  148. data/set-of-emails/maildir/bsd/lhost-domino-02.eml +6 -3
  149. data/set-of-emails/maildir/bsd/lhost-googlegroups-15.eml +174 -0
  150. data/set-of-emails/maildir/bsd/lhost-gsuite-15.eml +229 -0
  151. data/set-of-emails/maildir/bsd/lhost-postfix-75.eml +51 -0
  152. data/set-of-emails/maildir/bsd/lhost-postfix-76.eml +101 -0
  153. data/set-of-emails/maildir/bsd/lhost-postfix-77.eml +74 -0
  154. data/set-of-emails/maildir/bsd/lhost-postfix-78.eml +91 -0
  155. data/set-of-emails/maildir/bsd/lhost-receivingses-08.eml +88 -0
  156. data/set-of-emails/maildir/bsd/lhost-sendmail-60.eml +85 -0
  157. data/set-of-emails/maildir/bsd/rfc3464-43.eml +88 -0
  158. data/set-of-emails/maildir/bsd/rhost-google-03.eml +101 -0
  159. data/set-of-emails/maildir/bsd/rhost-google-04.eml +102 -0
  160. data/set-of-emails/maildir/bsd/rhost-google-05.eml +82 -0
  161. data/set-of-emails/maildir/bsd/rhost-google-06.eml +102 -0
  162. data/set-of-emails/maildir/bsd/rhost-google-07.eml +69 -0
  163. data/set-of-emails/maildir/bsd/rhost-google-08.eml +99 -0
  164. data/sisimai-java.gemspec +1 -1
  165. data/sisimai.gemspec +1 -1
  166. metadata +48 -26
  167. data/.rspec +0 -2
  168. data/lib/sisimai/data/yaml.rb +0 -33
  169. data/lib/sisimai/data.rb +0 -411
  170. data/lib/sisimai/mime.rb +0 -456
  171. data/lib/sisimai/rhost/googleapps.rb +0 -261
  172. /data/set-of-emails/maildir/bsd/{rfc3464-41.eml → rfc3834-05.eml} +0 -0
  173. /data/set-of-emails/maildir/bsd/{rhost-googleapps-01.eml → rhost-google-01.eml} +0 -0
  174. /data/set-of-emails/maildir/bsd/{rhost-googleapps-02.eml → rhost-google-02.eml} +0 -0
  175. /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-01.eml → rhost-microsoft-01.eml} +0 -0
  176. /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-02.eml → rhost-microsoft-02.eml} +0 -0
  177. /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-03.eml → rhost-microsoft-03.eml} +0 -0
  178. /data/set-of-emails/maildir/bsd/{rhost-tencentqq-01.eml → rhost-tencent-01.eml} +0 -0
  179. /data/set-of-emails/maildir/bsd/{rhost-tencentqq-02.eml → rhost-tencent-02.eml} +0 -0
  180. /data/set-of-emails/maildir/bsd/{rhost-tencentqq-03.eml → rhost-tencent-03.eml} +0 -0
@@ -1,10 +1,8 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::Verizon parses a bounce email which created by
3
- # Verizon Wireless.
4
- # Methods in the module are called from only Sisimai::Message.
2
+ # Sisimai::Lhost::Verizon parses a bounce email which created by Verizon Wireless. Methods in the
3
+ # module are called from only Sisimai::Message.
5
4
  module Verizon
6
5
  class << self
7
- # Imported from p5-Sisimail/lib/Sisimai/Lhost/Verizon.pm
8
6
  require 'sisimai/lhost'
9
7
  Indicators = Sisimai::Lhost.INDICATORS
10
8
 
@@ -13,25 +11,25 @@ module Sisimai::Lhost
13
11
  # @param [String] mbody Message body of a bounce email
14
12
  # @return [Hash] Bounce data list and message/rfc822 part
15
13
  # @return [Nil] it failed to parse or the arguments are missing
16
- def make(mhead, mbody)
14
+ def inquire(mhead, mbody)
17
15
  match = -1
18
16
  while true
19
17
  # Check the value of "From" header
20
18
  # :'subject' => %r/Undeliverable Message/,
21
19
  break unless mhead['received'].any? { |a| a.include?('.vtext.com (') }
22
20
  match = 1 if mhead['from'] == 'post_master@vtext.com'
23
- match = 0 if mhead['from'] =~ /[<]?sysadmin[@].+[.]vzwpix[.]com[>]?\z/
21
+ match = 0 if Sisimai::String.aligned(mhead['from'], ['sysadmin@', '.vzwpix.com'])
24
22
  break
25
23
  end
26
24
  return nil if match < 0
27
25
 
26
+ boundaries = []
28
27
  dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
29
- rebackbone = /^__BOUNDARY_STRING_HERE__/
28
+ emailparts = []
30
29
  readcursor = 0 # (Integer) Points the current cursor position
31
30
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
32
31
  senderaddr = '' # (String) Sender address in the message body
33
32
  subjecttxt = '' # (String) Subject of the original message
34
-
35
33
  markingsof = {} # (Hash) Delimiter patterns
36
34
  startingof = {} # (Hash) Delimiter strings
37
35
  messagesof = {} # (Hash) Error message patterns
@@ -39,22 +37,21 @@ module Sisimai::Lhost
39
37
 
40
38
  if match == 1
41
39
  # vtext.com
42
- markingsof = { message: %r/\AError:[ \t]/ }
40
+ markingsof = { message: ['Error: '] }
43
41
  messagesof = {
44
42
  # The attempted recipient address does not exist.
45
43
  'userunknown' => ['550 - Requested action not taken: no such user here'],
46
44
  }
47
- boundary00 = Sisimai::MIME.boundary(mhead['content-type'], 1) || ''
48
- rebackbone = Regexp.new('^' << Regexp.escape(boundary00)) unless boundary00.empty?
49
- emailsteak = Sisimai::RFC5322.fillet(mbody, rebackbone)
50
- bodyslices = emailsteak[0].split("\n")
45
+ boundaries = [Sisimai::RFC2045.boundary(mhead['content-type'], 1)]
46
+ emailparts = Sisimai::RFC5322.part(mbody, boundaries)
47
+ bodyslices = emailparts[0].split("\n")
51
48
 
52
49
  while e = bodyslices.shift do
53
- # Read error messages and delivery status lines from the head of the email
54
- # to the previous line of the beginning of the original message.
50
+ # Read error messages and delivery status lines from the head of the email to the previous
51
+ # line of the beginning of the original message.
55
52
  if readcursor == 0
56
53
  # Beginning of the bounce message or delivery status part
57
- readcursor |= Indicators[:deliverystatus] if e =~ markingsof[:message]
54
+ readcursor |= Indicators[:deliverystatus] if e.start_with?(markingsof[:message][0])
58
55
  next
59
56
  end
60
57
  next if (readcursor & Indicators[:deliverystatus]) == 0
@@ -66,41 +63,40 @@ module Sisimai::Lhost
66
63
  # MAIL FROM: *******@hg.example.com
67
64
  # RCPT TO: *****@vtext.com
68
65
  v = dscontents[-1]
69
- if cv = e.match(/\A[ \t]+RCPT TO: (.*)\z/)
66
+ if e.start_with?(' RCPT TO: ')
70
67
  if v['recipient']
71
68
  # There are multiple recipient addresses in the message body.
72
69
  dscontents << Sisimai::Lhost.DELIVERYSTATUS
73
70
  v = dscontents[-1]
74
71
  end
75
72
 
76
- v['recipient'] = cv[1]
73
+ v['recipient'] = e[11, e.size]
77
74
  recipients += 1
78
75
  next
79
76
 
80
- elsif cv = e.match(/\A[ \t]+MAIL FROM:[ \t](.+)\z/)
77
+ elsif e.start_with?(' MAIL FROM: ')
81
78
  # MAIL FROM: *******@hg.example.com
82
- senderaddr = cv[1] if senderaddr.empty?
79
+ senderaddr = e[13, e.size] if senderaddr.empty?
83
80
 
84
- elsif cv = e.match(/\A[ \t]+Subject:[ \t](.+)\z/)
81
+ elsif e.start_with?(' Subject: ')
85
82
  # Subject:
86
- subjecttxt = cv[1] if subjecttxt.empty?
83
+ subjecttxt = e[11, e.size] if subjecttxt.empty?
87
84
  else
88
85
  # 550 - Requested action not taken: no such user here
89
- v['diagnosis'] = e if e =~ /\A(\d{3})[ \t][-][ \t](.*)\z/
86
+ v['diagnosis'] = e if e.include?(' - ')
90
87
  end
91
88
  end
92
89
  else
93
90
  # vzwpix.com
94
91
  startingof = { message: ['Message could not be delivered to mobile'] }
95
92
  messagesof = { 'userunknown' => ['No valid recipients for this MM'] }
96
- boundary00 = Sisimai::MIME.boundary(mhead['content-type'], 1)
97
- rebackbone = Regexp.new('^' << Regexp.escape(boundary00)) unless boundary00.empty?
98
- emailsteak = Sisimai::RFC5322.fillet(mbody, rebackbone)
99
- bodyslices = emailsteak[0].split("\n")
93
+ boundaries = [Sisimai::RFC2045.boundary(mhead['content-type'], 1)]
94
+ emailparts = Sisimai::RFC5322.part(mbody, boundaries)
95
+ bodyslices = emailparts[0].split("\n")
100
96
 
101
97
  while e = bodyslices.shift do
102
- # Read error messages and delivery status lines from the head of the email
103
- # to the previous line of the beginning of the original message.
98
+ # Read error messages and delivery status lines from the head of the email to the previous
99
+ # line of the beginning of the original message.
104
100
  if readcursor == 0
105
101
  # Beginning of the bounce message or delivery status part
106
102
  readcursor |= Indicators[:deliverystatus] if e.start_with?(startingof[:message][0])
@@ -115,35 +111,35 @@ module Sisimai::Lhost
115
111
  # Subject: test for bounce
116
112
  # Date: Wed, 20 Jun 2013 10:29:52 +0000
117
113
  v = dscontents[-1]
118
- if cv = e.match(/\ATo:[ \t]+(.*)\z/)
114
+ if e.start_with?('To: ')
119
115
  if v['recipient']
120
116
  # There are multiple recipient addresses in the message body.
121
117
  dscontents << Sisimai::Lhost.DELIVERYSTATUS
122
118
  v = dscontents[-1]
123
119
  end
124
- v['recipient'] = Sisimai::Address.s3s4(cv[1])
120
+ v['recipient'] = Sisimai::Address.s3s4(e[4, e.size])
125
121
  recipients += 1
126
122
  next
127
123
 
128
- elsif cv = e.match(/\AFrom:[ \t](.+)\z/)
124
+ elsif e.start_with?('From: ')
129
125
  # From: kijitora <kijitora@example.jp>
130
- senderaddr = Sisimai::Address.s3s4(cv[1]) if senderaddr.empty?
126
+ senderaddr = Sisimai::Address.s3s4(e[4, e.size]) if senderaddr.empty?
131
127
 
132
- elsif cv = e.match(/\ASubject:[ \t](.+)\z/)
128
+ elsif e.start_with?('Subject: ')
133
129
  # Subject:
134
- subjecttxt = cv[1] if subjecttxt.empty?
130
+ subjecttxt = e[9, e.size] if subjecttxt.empty?
135
131
  else
136
132
  # Message could not be delivered to mobile.
137
133
  # Error: No valid recipients for this MM
138
- v['diagnosis'] = e if e =~ /\AError:[ \t]+(.+)\z/
134
+ v['diagnosis'] = Sisimai::String.sweep(e[7, e.size]) if e.start_with?('Error: ')
139
135
  end
140
136
  end
141
137
  end
142
138
  return nil unless recipients > 0
143
139
 
144
140
  # Set the value of "MAIL FROM:" and "From:"
145
- emailsteak[1] << ('From: ' << senderaddr << "\n") unless emailsteak[1] =~ /^From: /
146
- emailsteak[1] << ('Subject: ' << subjecttxt << "\n") unless emailsteak[1] =~ /^Subject: /
141
+ emailparts[1] << ('From: ' << senderaddr << "\n") if emailparts[1].include?("\nFrom: ") == false
142
+ emailparts[1] << ('Subject: ' << subjecttxt << "\n") if emailparts[1].include?("\nSubject: ") == false
147
143
 
148
144
  dscontents.each do |e|
149
145
  e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
@@ -155,7 +151,7 @@ module Sisimai::Lhost
155
151
  end
156
152
  end
157
153
 
158
- return { 'ds' => dscontents, 'rfc822' => emailsteak[1] }
154
+ return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
159
155
  end
160
156
  def description; return 'Verizon Wireless: https://www.verizonwireless.com'; end
161
157
  end
@@ -1,38 +1,37 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::X1 parses a bounce email which created by Unknown MTA #1.
3
- # Methods in the module are called from only Sisimai::Message.
2
+ # Sisimai::Lhost::X1 parses a bounce email which created by Unknown MTA #1. Methods in the module
3
+ # are called from only Sisimai::Message.
4
4
  module X1
5
5
  class << self
6
- # Imported from p5-Sisimail/lib/Sisimai/Lhost/X1.pm
7
6
  require 'sisimai/lhost'
8
7
 
9
8
  Indicators = Sisimai::Lhost.INDICATORS
10
- ReBackbone = %r|^Received: from \d+[.]\d+[.]\d+[.]\d|.freeze
11
- MarkingsOf = { message: %r/\AThe original message was received at (.+)\z/ }.freeze
9
+ Boundaries = ['Received: from '].freeze
10
+ MarkingsOf = { message: ['The original message was received at '] }.freeze
12
11
 
13
12
  # Parse bounce messages from Unknown MTA #1
14
13
  # @param [Hash] mhead Message headers of a bounce email
15
14
  # @param [String] mbody Message body of a bounce email
16
15
  # @return [Hash] Bounce data list and message/rfc822 part
17
16
  # @return [Nil] it failed to parse or the arguments are missing
18
- def make(mhead, mbody)
17
+ def inquire(mhead, mbody)
19
18
  return nil unless mhead['subject'].start_with?('Returned Mail: ')
20
19
  return nil unless mhead['from'].start_with?('"Mail Deliver System" ')
21
20
 
22
21
  dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
23
- emailsteak = Sisimai::RFC5322.fillet(mbody, ReBackbone)
24
- bodyslices = emailsteak[0].split("\n")
22
+ emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
23
+ bodyslices = emailparts[0].split("\n")
25
24
  readcursor = 0 # (Integer) Points the current cursor position
26
25
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
27
26
  datestring = '' # (String) Date string
28
27
  v = nil
29
28
 
30
29
  while e = bodyslices.shift do
31
- # Read error messages and delivery status lines from the head of the email
32
- # to the previous line of the beginning of the original message.
30
+ # Read error messages and delivery status lines from the head of the email to the previous
31
+ # line of the beginning of the original message.
33
32
  if readcursor == 0
34
33
  # Beginning of the bounce message or delivery status part
35
- readcursor |= Indicators[:deliverystatus] if e =~ MarkingsOf[:message]
34
+ readcursor |= Indicators[:deliverystatus] if e.start_with?(MarkingsOf[:message][0])
36
35
  next
37
36
  end
38
37
  next if (readcursor & Indicators[:deliverystatus]) == 0
@@ -46,20 +45,22 @@ module Sisimai::Lhost
46
45
  # kijitora@example.co.jp [User unknown]
47
46
  v = dscontents[-1]
48
47
 
49
- if cv = e.match(/\A([^ ]+?[@][^ ]+?)[ ]+\[(.+)\]\z/)
48
+ if Sisimai::String.aligned(e, ['@', ' [', ']'])
50
49
  # kijitora@example.co.jp [User unknown]
51
50
  if v['recipient']
52
51
  # There are multiple recipient addresses in the message body.
53
52
  dscontents << Sisimai::Lhost.DELIVERYSTATUS
54
53
  v = dscontents[-1]
55
54
  end
56
- v['recipient'] = cv[1]
57
- v['diagnosis'] = cv[2]
55
+ p1 = e.index(' ')
56
+ p2 = e.index(']')
57
+ v['recipient'] = e[0, p1]
58
+ v['diagnosis'] = e[p1 + 2, p2 - p1 - 2]
58
59
  recipients += 1
59
60
 
60
- elsif cv = e.match(MarkingsOf[:message])
61
+ elsif e.start_with?(MarkingsOf[:message][0])
61
62
  # The original message was received at Thu, 29 Apr 2010 23:34:45 +0900 (JST)
62
- datestring = cv[1]
63
+ datestring = e[MarkingsOf[:message][0].size, e.size]
63
64
  end
64
65
  end
65
66
  return nil unless recipients > 0
@@ -69,7 +70,7 @@ module Sisimai::Lhost
69
70
  e['date'] = datestring || ''
70
71
  end
71
72
 
72
- return { 'ds' => dscontents, 'rfc822' => emailsteak[1] }
73
+ return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
73
74
  end
74
75
  def description; return 'Unknown MTA #1'; end
75
76
  end
@@ -1,13 +1,12 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::X2 parses a bounce email which created by Unknown MTA #2.
3
- # Methods in the module are called from only Sisimai::Message.
2
+ # Sisimai::Lhost::X2 parses a bounce email which created by Unknown MTA #2. Methods in the module
3
+ # are called from only Sisimai::Message.
4
4
  module X2
5
5
  class << self
6
- # Imported from p5-Sisimail/lib/Sisimai/Lhost/X2.pm
7
6
  require 'sisimai/lhost'
8
7
 
9
8
  Indicators = Sisimai::Lhost.INDICATORS
10
- ReBackbone = %r|^--- Original message follows[.]|.freeze
9
+ Boundaries = ['--- Original message follows.'].freeze
11
10
  StartingOf = { message: ['Unable to deliver message to the following address'] }.freeze
12
11
 
13
12
  # Parse bounce messages from Unknown MTA #2
@@ -15,20 +14,24 @@ module Sisimai::Lhost
15
14
  # @param [String] mbody Message body of a bounce email
16
15
  # @return [Hash] Bounce data list and message/rfc822 part
17
16
  # @return [Nil] it failed to parse or the arguments are missing
18
- def make(mhead, mbody)
19
- return nil unless mhead['from'].include?('MAILER-DAEMON@')
20
- return nil unless mhead['subject'] =~ %r/\A(?>Delivery failure|fail(?:ure|ed) delivery)/
17
+ def inquire(mhead, mbody)
18
+ match = nil
19
+ match ||= 1 if mhead['from'].include?('MAILER-DAEMON@')
20
+ match ||= 1 if mhead['subject'].start_with?('Delivery failure')
21
+ match ||= 1 if mhead['subject'].start_with?('failure delivery')
22
+ match ||= 1 if mhead['subject'].start_with?('failed delivery')
23
+ return nil unless match
21
24
 
22
25
  dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
23
- emailsteak = Sisimai::RFC5322.fillet(mbody, ReBackbone)
24
- bodyslices = emailsteak[0].split("\n")
26
+ emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
27
+ bodyslices = emailparts[0].split("\n")
25
28
  readcursor = 0 # (Integer) Points the current cursor position
26
29
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
27
30
  v = nil
28
31
 
29
32
  while e = bodyslices.shift do
30
- # Read error messages and delivery status lines from the head of the email
31
- # to the previous line of the beginning of the original message.
33
+ # Read error messages and delivery status lines from the head of the email to the previous
34
+ # line of the beginning of the original message.
32
35
  if readcursor == 0
33
36
  # Beginning of the bounce message or delivery status part
34
37
  readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
@@ -44,14 +47,14 @@ module Sisimai::Lhost
44
47
  # This user doesn't have a example.com account (kijitora@example.com) [0]
45
48
  v = dscontents[-1]
46
49
 
47
- if cv = e.match(/\A[<]([^ ]+[@][^ ]+)[>]:\z/)
50
+ if e.start_with?('<') && Sisimai::String.aligned(e, ['<', '@', '>', ':'])
48
51
  # <kijitora@example.com>:
49
52
  if v['recipient']
50
53
  # There are multiple recipient addresses in the message body.
51
54
  dscontents << Sisimai::Lhost.DELIVERYSTATUS
52
55
  v = dscontents[-1]
53
56
  end
54
- v['recipient'] = cv[1]
57
+ v['recipient'] = e[1, e.size - 3]
55
58
  recipients += 1
56
59
  else
57
60
  # This user doesn't have a example.com account (kijitora@example.com) [0]
@@ -62,7 +65,7 @@ module Sisimai::Lhost
62
65
  return nil unless recipients > 0
63
66
 
64
67
  dscontents.each { |e| e['diagnosis'] = Sisimai::String.sweep(e['diagnosis']) }
65
- return { 'ds' => dscontents, 'rfc822' => emailsteak[1] }
68
+ return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
66
69
  end
67
70
  def description; return 'Unknown MTA #2'; end
68
71
  end
@@ -1,13 +1,12 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::X3 parses a bounce email which created by Unknown MTA #3.
3
- # Methods in the module are called from only Sisimai::Message.
2
+ # Sisimai::Lhost::X3 parses a bounce email which created by Unknown MTA #3. Methods in the module
3
+ # are called from only Sisimai::Message.
4
4
  module X3
5
5
  class << self
6
- # Imported from p5-Sisimail/lib/Sisimai/Lhost/X3.pm
7
6
  require 'sisimai/lhost'
8
7
 
9
8
  Indicators = Sisimai::Lhost.INDICATORS
10
- ReBackbone = %r|^Content-Type:[ ]message/rfc822|.freeze
9
+ Boundaries = ['Content-Type: message/rfc822'].freeze
11
10
  StartingOf = { message: [' This is an automatically generated Delivery Status Notification.'] }.freeze
12
11
 
13
12
  # Parse bounce messages from Unknown MTA #3
@@ -15,20 +14,21 @@ module Sisimai::Lhost
15
14
  # @param [String] mbody Message body of a bounce email
16
15
  # @return [Hash] Bounce data list and message/rfc822 part
17
16
  # @return [Nil] it failed to parse or the arguments are missing
18
- def make(mhead, mbody)
17
+ def inquire(mhead, mbody)
19
18
  return nil unless mhead['subject'].start_with?('Delivery status notification')
20
19
  return nil unless mhead['from'].start_with?('Mail Delivery System')
21
20
 
21
+ require 'sisimai/smtp/command'
22
22
  dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
23
- emailsteak = Sisimai::RFC5322.fillet(mbody, ReBackbone)
24
- bodyslices = emailsteak[0].split("\n")
23
+ emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
24
+ bodyslices = emailparts[0].split("\n")
25
25
  readcursor = 0 # (Integer) Points the current cursor position
26
26
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
27
27
  v = nil
28
28
 
29
29
  while e = bodyslices.shift do
30
- # Read error messages and delivery status lines from the head of the email
31
- # to the previous line of the beginning of the original message.
30
+ # Read error messages and delivery status lines from the head of the email to the previous
31
+ # line of the beginning of the original message.
32
32
  if readcursor == 0
33
33
  # Beginning of the bounce message or delivery status part
34
34
  readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
@@ -54,29 +54,29 @@ module Sisimai::Lhost
54
54
  # ============================================================================
55
55
  v = dscontents[-1]
56
56
 
57
- if cv = e.match(/\A[ \t]+[*][ ]([^ ]+[@][^ ]+)\z/)
57
+ if e.include?(' * ') && e.include?('@')
58
58
  # * kijitora@example.com
59
59
  if v['recipient']
60
60
  # There are multiple recipient addresses in the message body.
61
61
  dscontents << Sisimai::Lhost.DELIVERYSTATUS
62
62
  v = dscontents[-1]
63
63
  end
64
- v['recipient'] = cv[1]
64
+ v['recipient'] = e[e.index(' * ') + 3, e.size]
65
65
  recipients += 1
66
66
  else
67
67
  # Detect error message
68
- if cv = e.match(/\ASMTP:([^ ]+)[ ](.+)\z/)
68
+ if e.start_with?('SMTP:')
69
69
  # SMTP:RCPT host 192.0.2.8: 553 5.3.0 <kijitora@example.com>... No such user here
70
- v['command'] = cv[1].upcase
71
- v['diagnosis'] = cv[2]
70
+ v['command'] = Sisimai::SMTP::Command.find(e)
71
+ v['diagnosis'] = e
72
72
 
73
- elsif cv = e.match(/\ARouting: (.+)/)
73
+ elsif e.start_with?('Routing: ')
74
74
  # Routing: Could not find a gateway for kijitora@example.co.jp
75
- v['diagnosis'] = cv[1]
75
+ v['diagnosis'] = e[9, e.size]
76
76
 
77
- elsif cv = e.match(/\ADiagnostic-Code: smtp; (.+)/)
77
+ elsif e.start_with?('Diagnostic-Code: smtp; ')
78
78
  # Diagnostic-Code: smtp; 552 5.2.2 Over quota
79
- v['diagnosis'] = cv[1]
79
+ v['diagnosis'] = e[e.index(';') + 2, e.size]
80
80
  end
81
81
  end
82
82
  end
@@ -87,7 +87,7 @@ module Sisimai::Lhost
87
87
  e['status'] = Sisimai::SMTP::Status.find(e['diagnosis']) || ''
88
88
  end
89
89
 
90
- return { 'ds' => dscontents, 'rfc822' => emailsteak[1] }
90
+ return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
91
91
  end
92
92
  def description; return 'Unknown MTA #3'; end
93
93
  end