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,25 +1,44 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::Office365 parses a bounce email which created by
3
- # Microsoft Office 365.
4
- # Methods in the module are called from only Sisimai::Message.
2
+ # Sisimai::Lhost::Office365 parses a bounce email which created by Microsoft Office 365. Methods in
3
+ # the module are called from only Sisimai::Message.
5
4
  module Office365
6
5
  class << self
7
- # Imported from p5-Sisimail/lib/Sisimai/Lhost/Office365.pm
8
6
  require 'sisimai/lhost'
9
7
 
10
8
  Indicators = Sisimai::Lhost.INDICATORS
11
- ReBackbone = %r|^Content-Type:[ ]message/rfc822|.freeze
9
+ Boundaries = ['Content-Type: message/rfc822', 'Original message headers:'].freeze
12
10
  StartingOf = {
13
11
  error: ['Diagnostic information for administrators:'],
14
12
  eoerr: ['Original message headers:'],
15
13
  }.freeze
16
14
  MarkingsOf = {
17
- eoe: %r/\A(?:Original[ ][Mm]essage[ ][Hh]eaders:?|Message[ ]Hops)/,
18
- error: %r/\A(?:Diagnostic[ ]information[ ]for[ ]administrators:|Error[ ]Details)/,
15
+ eoe: %r{\A(?:
16
+ Original[ ][Mm]essage[ ][Hh]eaders:?
17
+ |Message[ ]Hops
18
+ |Cabe.+alhos[ ]originais[ ]da[ ]mensagem:
19
+ |Oorspronkelijke[ ]berichtkoppen:
20
+ )
21
+ }x,
22
+ rfc3464: %r|\AContent-Type:[ ]message/delivery-status|,
23
+ lhost: %r{\A(?:
24
+ Generating[ ]server
25
+ |Bronserver
26
+ |Servidor[ ]de[ ]origem
27
+ ):[ ](.+)\z
28
+ }x,
29
+ error: %r{\A(?:
30
+ Diagnostic[ ]information[ ]for[ ]administrators:
31
+ |Error[ ]Details
32
+ |Diagnostische[ ]gegevens[ ]voor[ ]beheerders:
33
+ |Informa.+es[ ]de[ ]diagn.+stico[ ]para[ ]administradores:
34
+ )
35
+ }x,
19
36
  message: %r{\A(?:
20
37
  Delivery[ ]has[ ]failed[ ]to[ ]these[ ]recipients[ ]or[ ]groups:
21
38
  |Original[ ]Message[ ]Details
22
39
  |.+[ ]rejected[ ]your[ ]message[ ]to[ ]the[ ]following[ ]e[-]?mail[ ]addresses:
40
+ |Falha[ ]na[ ]entrega[ ]a[ ]estes[ ]destinat.+rios[ ]ou[ ]grupos:
41
+ |Uw[ ]bericht[ ]kan[ ]niet[ ]worden[ ]bezorgd[ ]bij[ ]de[ ]volgende[ ]geadresseerden[ ]of[ ]groepen:
23
42
  )
24
43
  }x,
25
44
  }.freeze
@@ -37,7 +56,7 @@ module Sisimai::Lhost
37
56
  %r/\A4[.]4[.]7\z/ => 'expired',
38
57
  %r/\A4[.]4[.]312\z/ => 'networkerror',
39
58
  %r/\A4[.]4[.]316\z/ => 'expired',
40
- %r/\A4[.]7[.]26\z/ => 'securityerror',
59
+ %r/\A4[.]7[.]26\z/ => 'authfailure',
41
60
  %r/\A4[.]7[.][56]\d\d\z/ => 'blocked',
42
61
  %r/\A4[.]7[.]8[5-9]\d\z/ => 'blocked',
43
62
  %r/\A5[.]0[.]350\z/ => 'contenterror',
@@ -51,16 +70,16 @@ module Sisimai::Lhost
51
70
  %r/\A5[.]7[.]1[23]\z/ => 'rejected',
52
71
  %r/\A5[.]7[.]124\z/ => 'rejected',
53
72
  %r/\A5[.]7[.]13[3-6]\z/ => 'rejected',
54
- %r/\A5[.]7[.]23\z/ => 'blocked',
73
+ %r/\A5[.]7[.]23\z/ => 'authfailure',
55
74
  %r/\A5[.]7[.]25\z/ => 'networkerror',
56
75
  %r/\A5[.]7[.]50[1-3]\z/ => 'spamdetected',
57
76
  %r/\A5[.]7[.]50[4-5]\z/ => 'filtered',
58
77
  %r/\A5[.]7[.]50[6-7]\z/ => 'blocked',
59
78
  %r/\A5[.]7[.]508\z/ => 'toomanyconn',
60
- %r/\A5[.]7[.]509\z/ => 'securityerror',
79
+ %r/\A5[.]7[.]509\z/ => 'authfailure',
61
80
  %r/\A5[.]7[.]510\z/ => 'notaccept',
62
81
  %r/\A5[.]7[.]511\z/ => 'rejected',
63
- %r/\A5[.]7[.]512\z/ => 'securityerror',
82
+ %r/\A5[.]7[.]512\z/ => 'authfailure',
64
83
  %r/\A5[.]7[.]57\z/ => 'securityerror',
65
84
  %r/\A5[.]7[.]60[6-9]\z/ => 'blocked',
66
85
  %r/\A5[.]7[.]6[1-4]\d\z/ => 'blocked',
@@ -75,7 +94,7 @@ module Sisimai::Lhost
75
94
  # @param [String] mbody Message body of a bounce email
76
95
  # @return [Hash] Bounce data list and message/rfc822 part
77
96
  # @return [Nil] it failed to parse or the arguments are missing
78
- def make(mhead, mbody)
97
+ def inquire(mhead, mbody)
79
98
  # X-MS-Exchange-Message-Is-Ndr:
80
99
  # X-Microsoft-Antispam-PRVS: <....@...outlook.com>
81
100
  # X-Exchange-Antispam-Report-Test: UriScan:;
@@ -86,6 +105,9 @@ module Sisimai::Lhost
86
105
  tryto = %r/.+[.](?:outbound[.]protection|prod)[.]outlook[.]com\b/
87
106
  match = 0
88
107
  match += 1 if mhead['subject'].include?('Undeliverable:')
108
+ match += 1 if mhead['subject'].include?('Onbestelbaar:')
109
+ match += 1 if mhead['subject'].include?('Não_entregue:')
110
+
89
111
  Headers365.each do |e|
90
112
  next if mhead[e].nil?
91
113
  next if mhead[e].empty?
@@ -102,8 +124,8 @@ module Sisimai::Lhost
102
124
  fieldtable = Sisimai::RFC1894.FIELDTABLE
103
125
  permessage = {} # (Hash) Store values of each Per-Message field
104
126
  dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
105
- emailsteak = Sisimai::RFC5322.fillet(mbody, ReBackbone)
106
- bodyslices = emailsteak[0].split("\n")
127
+ emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
128
+ bodyslices = emailparts[0].split("\n")
107
129
  readcursor = 0 # (Integer) Points the current cursor position
108
130
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
109
131
  connheader = {}
@@ -112,8 +134,8 @@ module Sisimai::Lhost
112
134
  v = nil
113
135
 
114
136
  while e = bodyslices.shift do
115
- # Read error messages and delivery status lines from the head of the email
116
- # to the previous line of the beginning of the original message.
137
+ # Read error messages and delivery status lines from the head of the email to the previous
138
+ # line of the beginning of the original message.
117
139
  if readcursor == 0
118
140
  # Beginning of the bounce message or delivery status part
119
141
  readcursor |= Indicators[:deliverystatus] if e =~ MarkingsOf[:message]
@@ -145,7 +167,7 @@ module Sisimai::Lhost
145
167
  v['recipient'] = cv[1]
146
168
  recipients += 1
147
169
 
148
- elsif cv = e.match(/\AGenerating server: (.+)\z/)
170
+ elsif cv = e.match(MarkingsOf[:lhost])
149
171
  # Generating server: FFFFFFFFFFFF.e0.prod.outlook.com
150
172
  connheader['lhost'] = cv[1].downcase
151
173
  else
@@ -154,11 +176,20 @@ module Sisimai::Lhost
154
176
  next unless f = Sisimai::RFC1894.match(e)
155
177
  next unless o = Sisimai::RFC1894.field(e)
156
178
  next unless fieldtable[o[0]]
157
- next if o[0] =~ /\A(?:diagnostic-code|final-recipient)\z/
158
- v[fieldtable[o[0]]] = o[2]
159
179
 
160
- next unless f == 1
161
- permessage[fieldtable[o[0]]] = o[2]
180
+ if v['diagnosis']
181
+ # Do not capture "Diagnostic-Code:" field because error message have already
182
+ # been captured
183
+ next if o[0] =~ /\A(?:diagnostic-code|final-recipient)\z/
184
+ v[fieldtable[o[0]]] = o[2]
185
+
186
+ next unless f
187
+ permessage[fieldtable[o[0]]] = o[2]
188
+ else
189
+ # Capture "Diagnostic-Code:" field because no error messages have been captured
190
+ v[fieldtable[o[0]]] = o[2]
191
+ permessage[fieldtable[o[0]]] = o[2]
192
+ end
162
193
  else
163
194
  if e =~ MarkingsOf[:error]
164
195
  # Diagnostic information for administrators:
@@ -167,13 +198,18 @@ module Sisimai::Lhost
167
198
  # kijitora@example.com
168
199
  # Remote Server returned '550 5.1.10 RESOLVER.ADR.RecipientNotFound; Recipien=
169
200
  # t not found by SMTP address lookup'
170
- next unless v['diagnosis']
171
- if e =~ MarkingsOf[:eoe]
172
- # Original message headers:
173
- endoferror = true
174
- next
201
+ if v['diagnosis']
202
+ # The error message text have already captured
203
+ if e =~ MarkingsOf[:eoe]
204
+ # Original message headers:
205
+ endoferror = true
206
+ next
207
+ end
208
+ v['diagnosis'] << ' ' << e
209
+ else
210
+ # The error message text has not been captured yet
211
+ endoferror = true if e =~ MarkingsOf[:rfc3464]
175
212
  end
176
- v['diagnosis'] << ' ' << e
177
213
  end
178
214
  end
179
215
  end
@@ -207,7 +243,7 @@ module Sisimai::Lhost
207
243
  end
208
244
  end
209
245
 
210
- return { 'ds' => dscontents, 'rfc822' => emailsteak[1] }
246
+ return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
211
247
  end
212
248
  def description; return 'Microsoft Office 365: https://office.microsoft.com/'; end
213
249
  end
@@ -1,13 +1,12 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::OpenSMTPD parses a bounce email which created by
3
- # OpenSMTPD. Methods in the module are called from only Sisimai::Message.
2
+ # Sisimai::Lhost::OpenSMTPD parses a bounce email which created by OpenSMTPD. Methods in the module
3
+ # are called from only Sisimai::Message.
4
4
  module OpenSMTPD
5
5
  class << self
6
- # Imported from p5-Sisimail/lib/Sisimai/Lhost/OpenSMTPD.pm
7
6
  require 'sisimai/lhost'
8
7
 
9
8
  Indicators = Sisimai::Lhost.INDICATORS
10
- ReBackbone = %r|^[ ]+Below is a copy of the original message:|.freeze
9
+ Boundaries = [' Below is a copy of the original message:'].freeze
11
10
  StartingOf = {
12
11
  # http://www.openbsd.org/cgi-bin/man.cgi?query=smtpd&sektion=8
13
12
  # opensmtpd-5.4.2p1/smtpd/
@@ -70,21 +69,21 @@ module Sisimai::Lhost
70
69
  # @param [String] mbody Message body of a bounce email
71
70
  # @return [Hash] Bounce data list and message/rfc822 part
72
71
  # @return [Nil] it failed to parse or the arguments are missing
73
- def make(mhead, mbody)
72
+ def inquire(mhead, mbody)
74
73
  return nil unless mhead['subject'].start_with?('Delivery status notification')
75
74
  return nil unless mhead['from'].start_with?('Mailer Daemon <')
76
75
  return nil unless mhead['received'].any? { |a| a.include?(' (OpenSMTPD) with ') }
77
76
 
78
77
  dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
79
- emailsteak = Sisimai::RFC5322.fillet(mbody, ReBackbone)
80
- bodyslices = emailsteak[0].split("\n")
78
+ emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
79
+ bodyslices = emailparts[0].split("\n")
81
80
  readcursor = 0 # (Integer) Points the current cursor position
82
81
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
83
82
  v = nil
84
83
 
85
84
  while e = bodyslices.shift do
86
- # Read error messages and delivery status lines from the head of the email
87
- # to the previous line of the beginning of the original message.
85
+ # Read error messages and delivery status lines from the head of the email to the previous
86
+ # line of the beginning of the original message.
88
87
  if readcursor == 0
89
88
  # Beginning of the bounce message or delivery status part
90
89
  readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
@@ -105,15 +104,15 @@ module Sisimai::Lhost
105
104
  # Below is a copy of the original message:
106
105
  v = dscontents[-1]
107
106
 
108
- if cv = e.match(/\A([^ ]+?[@][^ ]+?):?[ ](.+)\z/)
107
+ if e.include?('@') && Sisimai::String.aligned(e, ['@', ' '])
109
108
  # kijitora@example.jp: 550 5.2.2 <kijitora@example>... Mailbox Full
110
109
  if v['recipient']
111
110
  # There are multiple recipient addresses in the message body.
112
111
  dscontents << Sisimai::Lhost.DELIVERYSTATUS
113
112
  v = dscontents[-1]
114
113
  end
115
- v['recipient'] = cv[1]
116
- v['diagnosis'] = cv[2]
114
+ v['recipient'] = e[0, e.index(':')]
115
+ v['diagnosis'] = e[e.index(':') + 1, e.size]
117
116
  recipients += 1
118
117
  end
119
118
  end
@@ -128,7 +127,7 @@ module Sisimai::Lhost
128
127
  break
129
128
  end
130
129
  end
131
- return { 'ds' => dscontents, 'rfc822' => emailsteak[1] }
130
+ return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
132
131
  end
133
132
  def description; return 'OpenSMTPD'; end
134
133
  end
@@ -1,14 +1,12 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::Outlook parses a bounce email which created by
3
- # Microsoft Outlook.com.
4
- # Methods in the module are called from only Sisimai::Message.
2
+ # Sisimai::Lhost::Outlook parses a bounce email which created by Microsoft Outlook.com. Methods in
3
+ # the module are called from only Sisimai::Message.
5
4
  module Outlook
6
5
  class << self
7
- # Imported from p5-Sisimail/lib/Sisimai/Lhost/US/Outlook.pm
8
6
  require 'sisimai/lhost'
9
7
 
10
8
  Indicators = Sisimai::Lhost.INDICATORS
11
- ReBackbone = %r|^Content-Type: message/rfc822|.freeze
9
+ Boundaries = ['Content-Type: message/rfc822'].freeze
12
10
  StartingOf = { message: ['This is an automatically generated Delivery Status Notification'] }.freeze
13
11
  MessagesOf = {
14
12
  'hostunknown' => ['The mail could not be delivered to the recipient because the domain is not reachable'],
@@ -20,7 +18,7 @@ module Sisimai::Lhost
20
18
  # @param [String] mbody Message body of a bounce email
21
19
  # @return [Hash] Bounce data list and message/rfc822 part
22
20
  # @return [Nil] it failed to parse or the arguments are missing
23
- def make(mhead, mbody)
21
+ def inquire(mhead, mbody)
24
22
  # X-Message-Delivery: Vj0xLjE7RD0wO0dEPTA7U0NMPTk7bD0xO3VzPTE=
25
23
  # X-Message-Info: AuEzbeVr9u5fkDpn2vR5iCu5wb6HBeY4iruBjnutBzpStnUabbM...
26
24
  match = 0
@@ -30,21 +28,20 @@ module Sisimai::Lhost
30
28
  match += 1 if mhead['received'].any? { |a| a.include?('.hotmail.com') }
31
29
  return nil if match < 2
32
30
 
33
- require 'sisimai/rfc1894'
34
31
  fieldtable = Sisimai::RFC1894.FIELDTABLE
35
32
  permessage = {} # (Hash) Store values of each Per-Message field
36
33
 
37
34
  dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
38
- emailsteak = Sisimai::RFC5322.fillet(mbody, ReBackbone)
39
- bodyslices = emailsteak[0].split("\n")
35
+ emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
36
+ bodyslices = emailparts[0].split("\n")
40
37
  readslices = ['']
41
38
  readcursor = 0 # (Integer) Points the current cursor position
42
39
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
43
40
  v = nil
44
41
 
45
42
  while e = bodyslices.shift do
46
- # Read error messages and delivery status lines from the head of the email
47
- # to the previous line of the beginning of the original message.
43
+ # Read error messages and delivery status lines from the head of the email to the previous
44
+ # line of the beginning of the original message.
48
45
  readslices << e # Save the current line for the next loop
49
46
 
50
47
  if readcursor == 0
@@ -85,14 +82,14 @@ module Sisimai::Lhost
85
82
  next unless fieldtable[o[0]]
86
83
  v[fieldtable[o[0]]] = o[2]
87
84
 
88
- next unless f == 1
85
+ next unless f
89
86
  permessage[fieldtable[o[0]]] = o[2]
90
87
  end
91
88
  else
92
89
  # Continued line of the value of Diagnostic-Code field
93
90
  next unless readslices[-2].start_with?('Diagnostic-Code:')
94
- next unless cv = e.match(/\A[ \t]+(.+)\z/)
95
- v['diagnosis'] << ' ' << cv[1]
91
+ next unless e.start_with?(' ')
92
+ v['diagnosis'] << ' ' << Sisimai::String.sweep(e)
96
93
  readslices[-1] = 'Diagnostic-Code: ' << e
97
94
  end
98
95
  end
@@ -100,7 +97,6 @@ module Sisimai::Lhost
100
97
 
101
98
  dscontents.each do |e|
102
99
  # Set default values if each value is empty.
103
- e['lhost'] ||= permessage['rhost']
104
100
  permessage.each_key { |a| e[a] ||= permessage[a] || '' }
105
101
 
106
102
  e['diagnosis'] = Sisimai::String.sweep(e['diagnosis']) || ''
@@ -124,7 +120,7 @@ module Sisimai::Lhost
124
120
  end
125
121
  end
126
122
 
127
- return { 'ds' => dscontents, 'rfc822' => emailsteak[1] }
123
+ return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
128
124
  end
129
125
  def description; return 'Microsoft Outlook.com: https://www.outlook.com/'; end
130
126
  end