sisimai 4.25.17 → 5.0.0

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 (178) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -3
  3. data/ANALYTICAL-PRECISION +2 -2
  4. data/Benchmarks.mk +3 -3
  5. data/CONTRIBUTING +1 -1
  6. data/ChangeLog.md +406 -407
  7. data/Developers.mk +5 -6
  8. data/Gemfile +1 -1
  9. data/Makefile +12 -12
  10. data/README-JA.md +142 -94
  11. data/README.md +282 -150
  12. data/Rakefile +9 -3
  13. data/Repository.mk +2 -3
  14. data/lib/sisimai/address.rb +118 -74
  15. data/lib/sisimai/arf.rb +84 -82
  16. data/lib/sisimai/datetime.rb +5 -52
  17. data/lib/sisimai/{data → fact}/json.rb +7 -9
  18. data/lib/sisimai/fact/yaml.rb +31 -0
  19. data/lib/sisimai/fact.rb +468 -0
  20. data/lib/sisimai/lhost/activehunter.rb +12 -14
  21. data/lib/sisimai/lhost/amavis.rb +11 -14
  22. data/lib/sisimai/lhost/amazonses.rb +37 -41
  23. data/lib/sisimai/lhost/amazonworkmail.rb +15 -18
  24. data/lib/sisimai/lhost/aol.rb +12 -14
  25. data/lib/sisimai/lhost/apachejames.rb +19 -21
  26. data/lib/sisimai/lhost/barracuda.rb +10 -12
  27. data/lib/sisimai/lhost/bigfoot.rb +21 -21
  28. data/lib/sisimai/lhost/biglobe.rb +15 -16
  29. data/lib/sisimai/lhost/courier.rb +20 -20
  30. data/lib/sisimai/lhost/domino.rb +23 -19
  31. data/lib/sisimai/lhost/einsundeins.rb +20 -16
  32. data/lib/sisimai/lhost/exchange2003.rb +30 -29
  33. data/lib/sisimai/lhost/exchange2007.rb +70 -58
  34. data/lib/sisimai/lhost/exim.rb +175 -161
  35. data/lib/sisimai/lhost/ezweb.rb +31 -56
  36. data/lib/sisimai/lhost/facebook.rb +21 -33
  37. data/lib/sisimai/lhost/fml.rb +43 -48
  38. data/lib/sisimai/lhost/gmail.rb +29 -29
  39. data/lib/sisimai/lhost/gmx.rb +18 -17
  40. data/lib/sisimai/lhost/googlegroups.rb +9 -10
  41. data/lib/sisimai/lhost/gsuite.rb +21 -27
  42. data/lib/sisimai/lhost/imailserver.rb +25 -39
  43. data/lib/sisimai/lhost/interscanmss.rb +28 -31
  44. data/lib/sisimai/lhost/kddi.rb +22 -28
  45. data/lib/sisimai/lhost/mailfoundry.rb +11 -12
  46. data/lib/sisimai/lhost/mailmarshalsmtp.rb +25 -29
  47. data/lib/sisimai/lhost/mailru.rb +33 -27
  48. data/lib/sisimai/lhost/mcafee.rb +21 -31
  49. data/lib/sisimai/lhost/messagelabs.rb +17 -20
  50. data/lib/sisimai/lhost/messagingserver.rb +40 -37
  51. data/lib/sisimai/lhost/mfilter.rb +15 -16
  52. data/lib/sisimai/lhost/mxlogic.rb +24 -23
  53. data/lib/sisimai/lhost/notes.rb +17 -17
  54. data/lib/sisimai/lhost/office365.rb +63 -27
  55. data/lib/sisimai/lhost/opensmtpd.rb +12 -13
  56. data/lib/sisimai/lhost/outlook.rb +12 -15
  57. data/lib/sisimai/lhost/postfix.rb +179 -129
  58. data/lib/sisimai/lhost/powermta.rb +12 -14
  59. data/lib/sisimai/lhost/qmail.rb +44 -47
  60. data/lib/sisimai/lhost/receivingses.rb +15 -20
  61. data/lib/sisimai/lhost/sendgrid.rb +34 -32
  62. data/lib/sisimai/lhost/sendmail.rb +66 -53
  63. data/lib/sisimai/lhost/surfcontrol.rb +19 -19
  64. data/lib/sisimai/lhost/v5sendmail.rb +45 -39
  65. data/lib/sisimai/lhost/verizon.rb +35 -39
  66. data/lib/sisimai/lhost/x1.rb +18 -17
  67. data/lib/sisimai/lhost/x2.rb +17 -14
  68. data/lib/sisimai/lhost/x3.rb +19 -19
  69. data/lib/sisimai/lhost/x4.rb +72 -57
  70. data/lib/sisimai/lhost/x5.rb +17 -19
  71. data/lib/sisimai/lhost/x6.rb +41 -17
  72. data/lib/sisimai/lhost/yahoo.rb +17 -16
  73. data/lib/sisimai/lhost/yandex.rb +16 -20
  74. data/lib/sisimai/lhost/zoho.rb +16 -15
  75. data/lib/sisimai/lhost.rb +8 -10
  76. data/lib/sisimai/mail/maildir.rb +1 -3
  77. data/lib/sisimai/mail/mbox.rb +3 -4
  78. data/lib/sisimai/mail/memory.rb +0 -1
  79. data/lib/sisimai/mail/stdin.rb +1 -3
  80. data/lib/sisimai/mail.rb +3 -7
  81. data/lib/sisimai/mda.rb +28 -42
  82. data/lib/sisimai/message.rb +435 -325
  83. data/lib/sisimai/order.rb +5 -5
  84. data/lib/sisimai/reason/authfailure.rb +64 -0
  85. data/lib/sisimai/reason/badreputation.rb +53 -0
  86. data/lib/sisimai/reason/blocked.rb +94 -160
  87. data/lib/sisimai/reason/contenterror.rb +8 -9
  88. data/lib/sisimai/reason/delivered.rb +4 -6
  89. data/lib/sisimai/reason/exceedlimit.rb +10 -12
  90. data/lib/sisimai/reason/expired.rb +6 -8
  91. data/lib/sisimai/reason/feedback.rb +2 -3
  92. data/lib/sisimai/reason/filtered.rb +17 -19
  93. data/lib/sisimai/reason/hasmoved.rb +9 -10
  94. data/lib/sisimai/reason/hostunknown.rb +15 -15
  95. data/lib/sisimai/reason/mailboxfull.rb +10 -12
  96. data/lib/sisimai/reason/mailererror.rb +18 -20
  97. data/lib/sisimai/reason/mesgtoobig.rb +9 -11
  98. data/lib/sisimai/reason/networkerror.rb +5 -8
  99. data/lib/sisimai/reason/norelaying.rb +8 -11
  100. data/lib/sisimai/reason/notaccept.rb +13 -14
  101. data/lib/sisimai/reason/notcompliantrfc.rb +43 -0
  102. data/lib/sisimai/reason/onhold.rb +6 -9
  103. data/lib/sisimai/reason/policyviolation.rb +14 -12
  104. data/lib/sisimai/reason/rejected.rb +26 -24
  105. data/lib/sisimai/reason/requireptr.rb +69 -0
  106. data/lib/sisimai/reason/securityerror.rb +33 -36
  107. data/lib/sisimai/reason/spamdetected.rb +114 -147
  108. data/lib/sisimai/reason/speeding.rb +49 -0
  109. data/lib/sisimai/reason/suspend.rb +11 -11
  110. data/lib/sisimai/reason/syntaxerror.rb +11 -10
  111. data/lib/sisimai/reason/systemerror.rb +7 -9
  112. data/lib/sisimai/reason/systemfull.rb +7 -8
  113. data/lib/sisimai/reason/toomanyconn.rb +9 -11
  114. data/lib/sisimai/reason/undefined.rb +2 -3
  115. data/lib/sisimai/reason/userunknown.rb +129 -146
  116. data/lib/sisimai/reason/vacation.rb +3 -4
  117. data/lib/sisimai/reason/virusdetected.rb +10 -11
  118. data/lib/sisimai/reason.rb +59 -64
  119. data/lib/sisimai/rfc1894.rb +55 -28
  120. data/lib/sisimai/rfc2045.rb +373 -0
  121. data/lib/sisimai/rfc3464.rb +250 -308
  122. data/lib/sisimai/rfc3834.rb +42 -45
  123. data/lib/sisimai/rfc5322.rb +75 -100
  124. data/lib/sisimai/rfc5965.rb +31 -0
  125. data/lib/sisimai/rhost/cox.rb +5 -6
  126. data/lib/sisimai/rhost/franceptt.rb +6 -8
  127. data/lib/sisimai/rhost/godaddy.rb +12 -12
  128. data/lib/sisimai/rhost/{googleapps.rb → google.rb} +80 -72
  129. data/lib/sisimai/rhost/iua.rb +9 -10
  130. data/lib/sisimai/rhost/kddi.rb +6 -8
  131. data/lib/sisimai/rhost/{exchangeonline.rb → microsoft.rb} +115 -114
  132. data/lib/sisimai/rhost/mimecast.rb +42 -40
  133. data/lib/sisimai/rhost/nttdocomo.rb +13 -18
  134. data/lib/sisimai/rhost/spectrum.rb +10 -12
  135. data/lib/sisimai/rhost/{tencentqq.rb → tencent.rb} +7 -8
  136. data/lib/sisimai/rhost.rb +23 -31
  137. data/lib/sisimai/smtp/command.rb +59 -0
  138. data/lib/sisimai/smtp/error.rb +4 -7
  139. data/lib/sisimai/smtp/reply.rb +161 -74
  140. data/lib/sisimai/smtp/status.rb +504 -393
  141. data/lib/sisimai/smtp/transcript.rb +124 -0
  142. data/lib/sisimai/smtp.rb +0 -1
  143. data/lib/sisimai/string.rb +74 -5
  144. data/lib/sisimai/time.rb +1 -2
  145. data/lib/sisimai/version.rb +1 -1
  146. data/lib/sisimai.rb +35 -21
  147. data/set-of-emails/maildir/bsd/lhost-domino-02.eml +6 -3
  148. data/set-of-emails/maildir/bsd/lhost-googlegroups-15.eml +174 -0
  149. data/set-of-emails/maildir/bsd/lhost-gsuite-15.eml +229 -0
  150. data/set-of-emails/maildir/bsd/lhost-postfix-75.eml +51 -0
  151. data/set-of-emails/maildir/bsd/lhost-postfix-76.eml +101 -0
  152. data/set-of-emails/maildir/bsd/lhost-postfix-77.eml +74 -0
  153. data/set-of-emails/maildir/bsd/lhost-postfix-78.eml +91 -0
  154. data/set-of-emails/maildir/bsd/lhost-receivingses-08.eml +88 -0
  155. data/set-of-emails/maildir/bsd/rfc3464-43.eml +88 -0
  156. data/set-of-emails/maildir/bsd/rhost-google-03.eml +101 -0
  157. data/set-of-emails/maildir/bsd/rhost-google-04.eml +102 -0
  158. data/set-of-emails/maildir/bsd/rhost-google-05.eml +82 -0
  159. data/set-of-emails/maildir/bsd/rhost-google-06.eml +102 -0
  160. data/set-of-emails/maildir/bsd/rhost-google-07.eml +69 -0
  161. data/set-of-emails/maildir/bsd/rhost-google-08.eml +99 -0
  162. data/sisimai-java.gemspec +1 -1
  163. data/sisimai.gemspec +1 -1
  164. metadata +41 -21
  165. data/.rspec +0 -2
  166. data/lib/sisimai/data/yaml.rb +0 -33
  167. data/lib/sisimai/data.rb +0 -411
  168. data/lib/sisimai/mime.rb +0 -456
  169. data/set-of-emails/maildir/mac/reported-from-nick4tech-san-01.eml +0 -6
  170. /data/set-of-emails/maildir/bsd/{rfc3464-41.eml → rfc3834-05.eml} +0 -0
  171. /data/set-of-emails/maildir/bsd/{rhost-googleapps-01.eml → rhost-google-01.eml} +0 -0
  172. /data/set-of-emails/maildir/bsd/{rhost-googleapps-02.eml → rhost-google-02.eml} +0 -0
  173. /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-01.eml → rhost-microsoft-01.eml} +0 -0
  174. /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-02.eml → rhost-microsoft-02.eml} +0 -0
  175. /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-03.eml → rhost-microsoft-03.eml} +0 -0
  176. /data/set-of-emails/maildir/bsd/{rhost-tencentqq-01.eml → rhost-tencent-01.eml} +0 -0
  177. /data/set-of-emails/maildir/bsd/{rhost-tencentqq-02.eml → rhost-tencent-02.eml} +0 -0
  178. /data/set-of-emails/maildir/bsd/{rhost-tencentqq-03.eml → rhost-tencent-03.eml} +0 -0
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sisimai
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.25.17
4
+ version: 5.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - azumakuniyuki
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-03-11 00:00:00.000000000 Z
11
+ date: 2024-02-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -75,7 +75,6 @@ extensions: []
75
75
  extra_rdoc_files: []
76
76
  files:
77
77
  - ".gitignore"
78
- - ".rspec"
79
78
  - ".rubocop.yml"
80
79
  - ".travis.yml"
81
80
  - ANALYTICAL-PRECISION
@@ -96,10 +95,10 @@ files:
96
95
  - lib/sisimai.rb
97
96
  - lib/sisimai/address.rb
98
97
  - lib/sisimai/arf.rb
99
- - lib/sisimai/data.rb
100
- - lib/sisimai/data/json.rb
101
- - lib/sisimai/data/yaml.rb
102
98
  - lib/sisimai/datetime.rb
99
+ - lib/sisimai/fact.rb
100
+ - lib/sisimai/fact/json.rb
101
+ - lib/sisimai/fact/yaml.rb
103
102
  - lib/sisimai/lhost.rb
104
103
  - lib/sisimai/lhost/activehunter.rb
105
104
  - lib/sisimai/lhost/amavis.rb
@@ -163,9 +162,10 @@ files:
163
162
  - lib/sisimai/mail/stdin.rb
164
163
  - lib/sisimai/mda.rb
165
164
  - lib/sisimai/message.rb
166
- - lib/sisimai/mime.rb
167
165
  - lib/sisimai/order.rb
168
166
  - lib/sisimai/reason.rb
167
+ - lib/sisimai/reason/authfailure.rb
168
+ - lib/sisimai/reason/badreputation.rb
169
169
  - lib/sisimai/reason/blocked.rb
170
170
  - lib/sisimai/reason/contenterror.rb
171
171
  - lib/sisimai/reason/delivered.rb
@@ -181,11 +181,14 @@ files:
181
181
  - lib/sisimai/reason/networkerror.rb
182
182
  - lib/sisimai/reason/norelaying.rb
183
183
  - lib/sisimai/reason/notaccept.rb
184
+ - lib/sisimai/reason/notcompliantrfc.rb
184
185
  - lib/sisimai/reason/onhold.rb
185
186
  - lib/sisimai/reason/policyviolation.rb
186
187
  - lib/sisimai/reason/rejected.rb
188
+ - lib/sisimai/reason/requireptr.rb
187
189
  - lib/sisimai/reason/securityerror.rb
188
190
  - lib/sisimai/reason/spamdetected.rb
191
+ - lib/sisimai/reason/speeding.rb
189
192
  - lib/sisimai/reason/suspend.rb
190
193
  - lib/sisimai/reason/syntaxerror.rb
191
194
  - lib/sisimai/reason/systemerror.rb
@@ -196,25 +199,29 @@ files:
196
199
  - lib/sisimai/reason/vacation.rb
197
200
  - lib/sisimai/reason/virusdetected.rb
198
201
  - lib/sisimai/rfc1894.rb
202
+ - lib/sisimai/rfc2045.rb
199
203
  - lib/sisimai/rfc3464.rb
200
204
  - lib/sisimai/rfc3834.rb
201
205
  - lib/sisimai/rfc5322.rb
206
+ - lib/sisimai/rfc5965.rb
202
207
  - lib/sisimai/rhost.rb
203
208
  - lib/sisimai/rhost/cox.rb
204
- - lib/sisimai/rhost/exchangeonline.rb
205
209
  - lib/sisimai/rhost/franceptt.rb
206
210
  - lib/sisimai/rhost/godaddy.rb
207
- - lib/sisimai/rhost/googleapps.rb
211
+ - lib/sisimai/rhost/google.rb
208
212
  - lib/sisimai/rhost/iua.rb
209
213
  - lib/sisimai/rhost/kddi.rb
214
+ - lib/sisimai/rhost/microsoft.rb
210
215
  - lib/sisimai/rhost/mimecast.rb
211
216
  - lib/sisimai/rhost/nttdocomo.rb
212
217
  - lib/sisimai/rhost/spectrum.rb
213
- - lib/sisimai/rhost/tencentqq.rb
218
+ - lib/sisimai/rhost/tencent.rb
214
219
  - lib/sisimai/smtp.rb
220
+ - lib/sisimai/smtp/command.rb
215
221
  - lib/sisimai/smtp/error.rb
216
222
  - lib/sisimai/smtp/reply.rb
217
223
  - lib/sisimai/smtp/status.rb
224
+ - lib/sisimai/smtp/transcript.rb
218
225
  - lib/sisimai/string.rb
219
226
  - lib/sisimai/time.rb
220
227
  - lib/sisimai/version.rb
@@ -387,6 +394,7 @@ files:
387
394
  - set-of-emails/maildir/bsd/lhost-googlegroups-12.eml
388
395
  - set-of-emails/maildir/bsd/lhost-googlegroups-13.eml
389
396
  - set-of-emails/maildir/bsd/lhost-googlegroups-14.eml
397
+ - set-of-emails/maildir/bsd/lhost-googlegroups-15.eml
390
398
  - set-of-emails/maildir/bsd/lhost-gsuite-01.eml
391
399
  - set-of-emails/maildir/bsd/lhost-gsuite-02.eml
392
400
  - set-of-emails/maildir/bsd/lhost-gsuite-03.eml
@@ -401,6 +409,7 @@ files:
401
409
  - set-of-emails/maildir/bsd/lhost-gsuite-12.eml
402
410
  - set-of-emails/maildir/bsd/lhost-gsuite-13.eml
403
411
  - set-of-emails/maildir/bsd/lhost-gsuite-14.eml
412
+ - set-of-emails/maildir/bsd/lhost-gsuite-15.eml
404
413
  - set-of-emails/maildir/bsd/lhost-imailserver-01.eml
405
414
  - set-of-emails/maildir/bsd/lhost-imailserver-02.eml
406
415
  - set-of-emails/maildir/bsd/lhost-imailserver-03.eml
@@ -545,6 +554,10 @@ files:
545
554
  - set-of-emails/maildir/bsd/lhost-postfix-72.eml
546
555
  - set-of-emails/maildir/bsd/lhost-postfix-73.eml
547
556
  - set-of-emails/maildir/bsd/lhost-postfix-74.eml
557
+ - set-of-emails/maildir/bsd/lhost-postfix-75.eml
558
+ - set-of-emails/maildir/bsd/lhost-postfix-76.eml
559
+ - set-of-emails/maildir/bsd/lhost-postfix-77.eml
560
+ - set-of-emails/maildir/bsd/lhost-postfix-78.eml
548
561
  - set-of-emails/maildir/bsd/lhost-powermta-01.eml
549
562
  - set-of-emails/maildir/bsd/lhost-powermta-02.eml
550
563
  - set-of-emails/maildir/bsd/lhost-powermta-03.eml
@@ -565,6 +578,7 @@ files:
565
578
  - set-of-emails/maildir/bsd/lhost-receivingses-05.eml
566
579
  - set-of-emails/maildir/bsd/lhost-receivingses-06.eml
567
580
  - set-of-emails/maildir/bsd/lhost-receivingses-07.eml
581
+ - set-of-emails/maildir/bsd/lhost-receivingses-08.eml
568
582
  - set-of-emails/maildir/bsd/lhost-sendgrid-01.eml
569
583
  - set-of-emails/maildir/bsd/lhost-sendgrid-02.eml
570
584
  - set-of-emails/maildir/bsd/lhost-sendgrid-03.eml
@@ -695,16 +709,14 @@ files:
695
709
  - set-of-emails/maildir/bsd/rfc3464-38.eml
696
710
  - set-of-emails/maildir/bsd/rfc3464-39.eml
697
711
  - set-of-emails/maildir/bsd/rfc3464-40.eml
698
- - set-of-emails/maildir/bsd/rfc3464-41.eml
699
712
  - set-of-emails/maildir/bsd/rfc3464-42.eml
713
+ - set-of-emails/maildir/bsd/rfc3464-43.eml
700
714
  - set-of-emails/maildir/bsd/rfc3834-01.eml
701
715
  - set-of-emails/maildir/bsd/rfc3834-02.eml
702
716
  - set-of-emails/maildir/bsd/rfc3834-03.eml
703
717
  - set-of-emails/maildir/bsd/rfc3834-04.eml
718
+ - set-of-emails/maildir/bsd/rfc3834-05.eml
704
719
  - set-of-emails/maildir/bsd/rhost-cox-01.eml
705
- - set-of-emails/maildir/bsd/rhost-exchangeonline-01.eml
706
- - set-of-emails/maildir/bsd/rhost-exchangeonline-02.eml
707
- - set-of-emails/maildir/bsd/rhost-exchangeonline-03.eml
708
720
  - set-of-emails/maildir/bsd/rhost-franceptt-01.eml
709
721
  - set-of-emails/maildir/bsd/rhost-franceptt-02.eml
710
722
  - set-of-emails/maildir/bsd/rhost-franceptt-03.eml
@@ -718,20 +730,29 @@ files:
718
730
  - set-of-emails/maildir/bsd/rhost-franceptt-12.eml
719
731
  - set-of-emails/maildir/bsd/rhost-godaddy-02.eml
720
732
  - set-of-emails/maildir/bsd/rhost-godaddy-03.eml
721
- - set-of-emails/maildir/bsd/rhost-googleapps-01.eml
722
- - set-of-emails/maildir/bsd/rhost-googleapps-02.eml
733
+ - set-of-emails/maildir/bsd/rhost-google-01.eml
734
+ - set-of-emails/maildir/bsd/rhost-google-02.eml
735
+ - set-of-emails/maildir/bsd/rhost-google-03.eml
736
+ - set-of-emails/maildir/bsd/rhost-google-04.eml
737
+ - set-of-emails/maildir/bsd/rhost-google-05.eml
738
+ - set-of-emails/maildir/bsd/rhost-google-06.eml
739
+ - set-of-emails/maildir/bsd/rhost-google-07.eml
740
+ - set-of-emails/maildir/bsd/rhost-google-08.eml
723
741
  - set-of-emails/maildir/bsd/rhost-iua-01.eml
724
742
  - set-of-emails/maildir/bsd/rhost-kddi-01.eml
725
743
  - set-of-emails/maildir/bsd/rhost-kddi-02.eml
744
+ - set-of-emails/maildir/bsd/rhost-microsoft-01.eml
745
+ - set-of-emails/maildir/bsd/rhost-microsoft-02.eml
746
+ - set-of-emails/maildir/bsd/rhost-microsoft-03.eml
726
747
  - set-of-emails/maildir/bsd/rhost-mimecast-01.eml
727
748
  - set-of-emails/maildir/bsd/rhost-mimecast-02.eml
728
749
  - set-of-emails/maildir/bsd/rhost-nttdocomo-01.eml
729
750
  - set-of-emails/maildir/bsd/rhost-nttdocomo-02.eml
730
751
  - set-of-emails/maildir/bsd/rhost-nttdocomo-03.eml
731
752
  - set-of-emails/maildir/bsd/rhost-spectrum-01.eml
732
- - set-of-emails/maildir/bsd/rhost-tencentqq-01.eml
733
- - set-of-emails/maildir/bsd/rhost-tencentqq-02.eml
734
- - set-of-emails/maildir/bsd/rhost-tencentqq-03.eml
753
+ - set-of-emails/maildir/bsd/rhost-tencent-01.eml
754
+ - set-of-emails/maildir/bsd/rhost-tencent-02.eml
755
+ - set-of-emails/maildir/bsd/rhost-tencent-03.eml
735
756
  - set-of-emails/maildir/dos/arf-01.eml
736
757
  - set-of-emails/maildir/dos/lhost-activehunter-01.eml
737
758
  - set-of-emails/maildir/dos/lhost-amavis-01.eml
@@ -889,7 +910,6 @@ files:
889
910
  - set-of-emails/maildir/mac/lhost-yahoo-01.eml
890
911
  - set-of-emails/maildir/mac/lhost-yandex-01.eml
891
912
  - set-of-emails/maildir/mac/lhost-zoho-01.eml
892
- - set-of-emails/maildir/mac/reported-from-nick4tech-san-01.eml
893
913
  - set-of-emails/maildir/mac/rfc3464-01.eml
894
914
  - set-of-emails/maildir/mac/rfc3834-01.eml
895
915
  - set-of-emails/maildir/mac/rhost-exchangeonline-01.eml
@@ -918,7 +938,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
918
938
  requirements:
919
939
  - - ">="
920
940
  - !ruby/object:Gem::Version
921
- version: 2.1.0
941
+ version: 2.4.0
922
942
  required_rubygems_version: !ruby/object:Gem::Requirement
923
943
  requirements:
924
944
  - - ">="
data/.rspec DELETED
@@ -1,2 +0,0 @@
1
- --format progress
2
- --color
@@ -1,33 +0,0 @@
1
- module Sisimai
2
- class Data
3
- # Sisimai::Data::YAML dumps parsed data object as a YAML format. This class
4
- # and method should be called from the parent object "Sisimai::Data".
5
- module YAML
6
- # Imported from p5-Sisimail/lib/Sisimai/Data/YAML.pm
7
- class << self
8
- require 'yaml'
9
-
10
- # Data dumper(YAML)
11
- # @param [Sisimai::Data] argvs Object
12
- # @return [String, Nil] Dumped data or nil if the argument
13
- # is missing
14
- def dump(argvs)
15
- return nil unless argvs
16
- return nil unless argvs.is_a? Sisimai::Data
17
-
18
- damneddata = argvs.damn
19
- yamlstring = nil
20
-
21
- begin
22
- yamlstring = ::YAML.dump(damneddata)
23
- rescue StandardError => ce
24
- warn '***warning: Failed to YAML.dump: ' << ce.to_s
25
- end
26
-
27
- return yamlstring
28
- end
29
-
30
- end
31
- end
32
- end
33
- end
data/lib/sisimai/data.rb DELETED
@@ -1,411 +0,0 @@
1
- module Sisimai
2
- # Sisimai::Data generate parsed data from Sisimai::Message object.
3
- class Data
4
- # Imported from p5-Sisimail/lib/Sisimai/Data.pm
5
- require 'sisimai/address'
6
- require 'sisimai/reason'
7
- require 'sisimai/string'
8
- require 'sisimai/rhost'
9
- require 'sisimai/time'
10
- require 'sisimai/datetime'
11
- require 'sisimai/smtp/error'
12
-
13
- @@rwaccessors = [
14
- :catch, # [?] Results generated by hook method
15
- :token, # [String] Message token/MD5 Hex digest value
16
- :lhost, # [String] local host name/Local MTA
17
- :rhost, # [String] Remote host name/Remote MTA
18
- :alias, # [String] Alias of the recipient address
19
- :listid, # [String] List-Id header of each ML
20
- :reason, # [String] Bounce reason
21
- :action, # [String] The value of Action: header
22
- :origin, # [String] Email path as a data source
23
- :subject, # [String] UTF-8 Subject text
24
- :timestamp, # [Sisimai::Time] Date: header in the original message
25
- :addresser, # [Sisimai::Address] From address
26
- :recipient, # [Sisimai::Address] Recipient address which bounced
27
- :messageid, # [String] Message-Id: header
28
- :replycode, # [String] SMTP Reply Code
29
- :smtpagent, # [String] Module(Engine) name
30
- :softbounce, # [Integer] 1 = Soft bounce, 0 = Hard bounce, -1 = ?
31
- :smtpcommand, # [String] The last SMTP command
32
- :destination, # [String] The domain part of the "recipinet"
33
- :senderdomain, # [String] The domain part of the "addresser"
34
- :feedbacktype, # [String] Feedback Type
35
- :diagnosticcode, # [String] Diagnostic-Code: Header
36
- :diagnostictype, # [String] The 1st part of Diagnostic-Code: Header
37
- :deliverystatus, # [String] Delivery Status(DSN)
38
- :timezoneoffset, # [Integer] Time zone offset(seconds)
39
- ]
40
- attr_accessor(*@@rwaccessors)
41
-
42
- RetryIndex = Sisimai::Reason.retry
43
- RFC822Head = Sisimai::RFC5322.HEADERFIELDS(:all)
44
-
45
- # Constructor of Sisimai::Data
46
- # @param [Hash] argvs Data
47
- # @return [Sisimai::Data] Structured email data
48
- def initialize(argvs)
49
- # Create email address object
50
- as = Sisimai::Address.make(argvs['addresser'])
51
- ar = Sisimai::Address.make(address: argvs['recipient'])
52
-
53
- return nil unless as.is_a? Sisimai::Address
54
- return nil unless ar.is_a? Sisimai::Address
55
- return nil if as.void
56
- return nil if ar.void
57
-
58
- @addresser = as
59
- @recipient = ar
60
- @senderdomain = as.host
61
- @destination = ar.host
62
- @alias = argvs['alias'] || ''
63
- @token = Sisimai::String.token(as.address, ar.address, argvs['timestamp'])
64
- @timestamp = Sisimai::Time.parse(::Time.at(argvs['timestamp']).to_s)
65
- @timezoneoffset = argvs['timezoneoffset'] || '+0000'
66
- @lhost = argvs['lhost'] || ''
67
- @rhost = argvs['rhost'] || ''
68
- @catch = argvs['catch'] || nil
69
- @reason = argvs['reason'] || ''
70
- @listid = argvs['listid'] || ''
71
- @subject = argvs['subject'] || ''
72
- @messageid = argvs['messageid'] || ''
73
- @smtpagent = argvs['smtpagent'] || ''
74
- @diagnosticcode = argvs['diagnosticcode'] || ''
75
- @diagnostictype = argvs['diagnostictype'] || ''
76
- @deliverystatus = argvs['deliverystatus'] || ''
77
- @smtpcommand = argvs['smtpcommand'] || ''
78
- @feedbacktype = argvs['feedbacktype'] || ''
79
- @action = argvs['action'] || ''
80
- @origin = argvs['origin'] || ''
81
- @replycode = argvs['replycode'] || ''
82
- @replycode = Sisimai::SMTP::Reply.find(argvs['diagnosticcode']).to_s if @replycode.empty?
83
- @softbounce = argvs['softbounce'] || ''
84
- end
85
-
86
- # Another constructor of Sisimai::Data
87
- # @param [Sisimai::Message] data Data Object
88
- # @param [Hash] argvs Parser options
89
- # @options argvs [Boolean] delivered true: Including "delivered" reason
90
- # @return [Array, Nil] List of Sisimai::Data or Nil if the
91
- # argument is not Sisimai::Message object
92
- def self.make(data: nil, **argvs)
93
- return nil unless data
94
- return nil unless data.is_a? Sisimai::Message
95
-
96
- messageobj = data
97
- rfc822data = messageobj.rfc822
98
- objectlist = []
99
- delivered1 = argvs[:delivered] || false
100
-
101
- return nil unless messageobj.ds
102
- return nil unless messageobj.rfc822
103
-
104
- eachobject = messageobj.ds.dup
105
- while e = eachobject.shift do
106
- # Create parameters for new() constructor.
107
- p = {
108
- 'catch' => messageobj.catch || nil,
109
- 'lhost' => e['lhost'] || '',
110
- 'rhost' => e['rhost'] || '',
111
- 'alias' => e['alias'] || '',
112
- 'action' => e['action'] || '',
113
- 'reason' => e['reason'] || '',
114
- 'replycode' => e['replycode'] || '',
115
- 'smtpagent' => e['agent'] || '',
116
- 'recipient' => e['recipient'] || '',
117
- 'softbounce' => e['softbounce'] || '',
118
- 'smtpcommand' => e['command'] || '',
119
- 'feedbacktype' => e['feedbacktype'] || '',
120
- 'diagnosticcode' => e['diagnosis'] || '',
121
- 'diagnostictype' => e['spec'] || '',
122
- 'deliverystatus' => e['status'] || '',
123
- }
124
- unless delivered1
125
- # Skip if the value of "deliverystatus" begins with "2." such as 2.1.5
126
- next if p['deliverystatus'].start_with?('2.')
127
- end
128
-
129
- # EMAIL_ADDRESS:
130
- # Detect email address from message/rfc822 part
131
- RFC822Head[:addresser].each do |f|
132
- # Check each header in message/rfc822 part
133
- next unless rfc822data[f]
134
- next if rfc822data[f].empty?
135
-
136
- j = Sisimai::Address.find(rfc822data[f]) || []
137
- next if j.empty?
138
- p['addresser'] = j[0]
139
- break
140
- end
141
-
142
- unless p['addresser']
143
- # Fallback: Get the sender address from the header of the bounced
144
- # email if the address is not set at loop above.
145
- j = Sisimai::Address.find(messageobj.header['to']) || []
146
- p['addresser'] = j[0] unless j.empty?
147
- end
148
- next unless p['addresser']
149
- next unless p['recipient']
150
-
151
- # TIMESTAMP:
152
- # Convert from a time stamp or a date string to a machine time.
153
- datestring = nil
154
- zoneoffset = 0
155
- datevalues = []
156
- datevalues << e['date'] unless e['date'].to_s.empty?
157
-
158
- # Date information did not exist in message/delivery-status part,...
159
- RFC822Head[:date].each do |f|
160
- # Get the value of Date header or other date related header.
161
- next unless rfc822data[f]
162
- datevalues << rfc822data[f]
163
- end
164
-
165
- # Set "date" getting from the value of "Date" in the bounce message
166
- datevalues << messageobj.header['date'] if datevalues.size < 2
167
-
168
- while v = datevalues.shift do
169
- # Parse each date value in the array
170
- datestring = Sisimai::DateTime.parse(v)
171
- break if datestring
172
- end
173
-
174
- if datestring && cv = datestring.match(/\A(.+)[ ]+([-+]\d{4})\z/)
175
- # Get the value of timezone offset from datestring
176
- # Wed, 26 Feb 2014 06:05:48 -0500
177
- datestring = cv[1]
178
- zoneoffset = Sisimai::DateTime.tz2second(cv[2])
179
- p['timezoneoffset'] = cv[2]
180
- end
181
-
182
- begin
183
- # Convert from the date string to an object then calculate time
184
- # zone offset.
185
- t = Sisimai::Time.strptime(datestring, '%a, %d %b %Y %T')
186
- p['timestamp'] = (t.to_time.to_i - zoneoffset) || nil
187
- rescue
188
- warn ' ***warning: Failed to strptime ' << datestring.to_s
189
- end
190
- next unless p['timestamp']
191
-
192
- # OTHER_TEXT_HEADERS:
193
- recvheader = data.header['received'] || []
194
- unless recvheader.empty?
195
- # Get localhost and remote host name from Received header.
196
- %w[lhost rhost].each { |a| e[a] ||= '' }
197
- e['lhost'] = Sisimai::RFC5322.received(recvheader[0]).shift if e['lhost'].empty?
198
- e['rhost'] = Sisimai::RFC5322.received(recvheader[-1]).pop if e['rhost'].empty?
199
- end
200
-
201
- # Remove square brackets and curly brackets from the host variable
202
- %w[rhost lhost].each do |v|
203
- p[v].delete!('[]()') # Remove square brackets and curly brackets from the host variable
204
- p[v].sub!(/\A.+=/, '') # Remove string before "="
205
- p[v].chomp!("\r") if p[v].end_with?("\r") # Remove CR at the end of the value
206
-
207
- # Check space character in each value and get the first element
208
- p[v] = p[v].split(' ', 2).shift if p[v].include?(' ')
209
- p[v].chomp!('.') if p[v].end_with?('.') # Remove "." at the end of the value
210
- end
211
-
212
- # Subject: header of the original message
213
- p['subject'] = rfc822data['subject'] || ''
214
- p['subject'].scrub!('?')
215
- p['subject'].chomp!("\r") if p['subject'].end_with?("\r")
216
-
217
- # The value of "List-Id" header
218
- p['listid'] = rfc822data['list-id'] || ''
219
- unless p['listid'].empty?
220
- # Get the value of List-Id header like "List name <list-id@example.org>"
221
- if cv = p['listid'].match(/\A.*([<].+[>]).*\z/) then p['listid'] = cv[1] end
222
- p['listid'].delete!('<>')
223
- p['listid'].chomp!("\r") if p['listid'].end_with?("\r")
224
- p['listid'] = '' if p['listid'].include?(' ')
225
- end
226
-
227
- # The value of "Message-Id" header
228
- p['messageid'] = rfc822data['message-id'] || ''
229
- unless p['messageid'].empty?
230
- # Leave only string inside of angle brackets(<>)
231
- if cv = p['messageid'].match(/\A([^ ]+)[ ].*/) then p['messageid'] = cv[1] end
232
- if cv = p['messageid'].match(/[<]([^ ]+?)[>]/) then p['messageid'] = cv[1] end
233
- end
234
-
235
- # CHECK_DELIVERY_STATUS_VALUE:
236
- # Cleanup the value of "Diagnostic-Code:" header
237
- unless p['diagnosticcode'].empty?
238
- # Count the number of D.S.N. and SMTP Reply Code
239
- vs = Sisimai::SMTP::Status.find(p['diagnosticcode'])
240
- vr = Sisimai::SMTP::Reply.find(p['diagnosticcode'])
241
- vm = 0
242
- re = nil
243
-
244
- if vs
245
- # How many times does the D.S.N. appeared
246
- vm += p['diagnosticcode'].scan(/\b#{vs}\b/).size
247
- p['deliverystatus'] = vs if vs =~ /\A[45][.][1-9][.][1-9]\z/
248
- end
249
-
250
- if vr
251
- # How many times does the SMTP reply code appeared
252
- vm += p['diagnosticcode'].scan(/\b#{vr}\b/).size
253
- p['replycode'] ||= vr
254
- end
255
-
256
- if vm > 2
257
- # Build regular expression for removing string like '550-5.1.1'
258
- # from the value of "diagnosticcode"
259
- re0 = %r/;?[ ]#{vr}[- ](?:#{vs})?/
260
- re1 = %r/;?[ ][45]\d\d[- ](?:#{vs})?/
261
- re2 = %r/;?[ ]#{vr}[- ](?:[45][.]\d[.]\d+)?/
262
-
263
- # 550-5.7.1 [192.0.2.222] Our system has detected that this message is
264
- # 550-5.7.1 likely unsolicited mail. To reduce the amount of spam sent to Gmail,
265
- # 550-5.7.1 this message has been blocked. Please visit
266
- # 550 5.7.1 https://support.google.com/mail/answer/188131 for more information.
267
- p['diagnosticcode'] = p['diagnosticcode'].gsub(re0, ' ')
268
- p['diagnosticcode'] = p['diagnosticcode'].gsub(re1, ' ')
269
- p['diagnosticcode'] = p['diagnosticcode'].gsub(re2, ' ')
270
- p['diagnosticcode'] = Sisimai::String.sweep(p['diagnosticcode'].sub(%r|<html>.+</html>|i, ''))
271
- end
272
- end
273
-
274
- if Sisimai::String.is_8bit(p['diagnosticcode'])
275
- # To avoid incompatible character encodings: ASCII-8BIT and UTF-8 (Encoding::CompatibilityError
276
- p['diagnosticcode'] = p['diagnosticcode'].force_encoding('UTF-8').scrub('?')
277
- end
278
-
279
- p['diagnostictype'] ||= 'X-UNIX' if p['reason'] == 'mailererror'
280
- p['diagnostictype'] ||= 'SMTP' unless %w[feedback vacation].include?(p['reason'])
281
-
282
- # Check the value of SMTP command
283
- p['smtpcommand'] = '' unless %w[EHLO HELO MAIL RCPT DATA QUIT].include?(p['smtpcommand'])
284
- p['origin'] = argvs[:origin] # Set the path to the original email
285
-
286
- if p['action'].empty?
287
- # Check the value of "action"
288
- if p['reason'] == 'expired'
289
- # Action: delayed
290
- p['action'] = 'delayed'
291
- elsif p['deliverystatus'].start_with?('5', '4')
292
- # Action: failed
293
- p['action'] = 'failed'
294
- end
295
- end
296
-
297
- o = Sisimai::Data.new(p)
298
- next unless o.recipient
299
-
300
- if o.reason.empty? || RetryIndex[o.reason]
301
- # Decide the reason of email bounce
302
- r = ''; r = Sisimai::Rhost.get(o) if Sisimai::Rhost.match(o.rhost)
303
- if r.empty?
304
- # Failed to detect a bounce reason by the value of "rhost"
305
- r = Sisimai::Rhost.get(o, o.destination) if Sisimai::Rhost.match(o.destination)
306
- r = Sisimai::Reason.get(o) if r.nil? || r.empty?
307
- r = 'undefined' if r.empty?
308
- end
309
- o.reason = r
310
- end
311
-
312
- if %w[delivered feedback vacation].include?(o.reason)
313
- # The value of reason is "vacation" or "feedback"
314
- o.softbounce = -1
315
- o.replycode = '' unless o.reason == 'delivered'
316
- else
317
- # Bounce message which reason is "feedback" or "vacation" does
318
- # not have the value of "deliverystatus".
319
- softorhard = nil
320
-
321
- if o.softbounce.to_s.empty?
322
- # The value is not set yet
323
- textasargv = (p['deliverystatus'] + ' ' + p['diagnosticcode']).lstrip
324
- softorhard = Sisimai::SMTP::Error.soft_or_hard(o.reason, textasargv) || ''
325
- o.softbounce = if softorhard.size > 0
326
- # Returned value is "soft" or "hard"
327
- (softorhard == 'soft') ? 1 : 0
328
- else
329
- # Returned value is an empty string
330
- -1
331
- end
332
- end
333
-
334
- if o.deliverystatus.empty?
335
- # Set pseudo status code
336
- textasargv = (o.replycode + ' ' + p['diagnosticcode']).lstrip
337
- getchecked = Sisimai::SMTP::Error.is_permanent(textasargv)
338
- tmpfailure = getchecked.nil? ? false : (getchecked ? false : true)
339
-
340
- if pseudocode = Sisimai::SMTP::Status.code(o.reason, tmpfailure)
341
- # Set the value of "deliverystatus" and "softbounce"
342
- o.deliverystatus = pseudocode
343
-
344
- if o.softbounce < 0
345
- # set the value of "softbounce" again when the value is -1
346
- softorhard = Sisimai::SMTP::Error.soft_or_hard(o.reason, pseudocode)
347
-
348
- o.softbounce = if softorhard.size > 0
349
- # Returned value is "soft" or "hard"
350
- softorhard == 'soft' ? 1 : 0
351
- else
352
- # Returned value is an empty string
353
- -1
354
- end
355
- end
356
- end
357
- end
358
-
359
- unless o.replycode.empty?
360
- # Check both of the first digit of "deliverystatus" and "replycode"
361
- o.replycode = '' unless o.replycode[0, 1] == o.deliverystatus[0, 1]
362
- end
363
-
364
- end
365
- objectlist << o
366
-
367
- end
368
- return objectlist
369
- end
370
-
371
- # Convert from object to hash reference
372
- # @return [Hash] Data in Hash reference
373
- def damn
374
- data = {}
375
- @@rwaccessors.each do |e|
376
- next if %w[addresser recipient timestamp].include?(e.to_s)
377
- data[e.to_s] = self.send(e) || ''
378
- end
379
- data['addresser'] = self.addresser.address
380
- data['recipient'] = self.recipient.address
381
- data['timestamp'] = self.timestamp.to_time.to_i
382
- return data
383
- end
384
- alias :to_hash :damn
385
-
386
- # Data dumper
387
- # @param [String] type Data format: json, yaml
388
- # @return [String, Nil] Dumped data or nil if the value of the first
389
- # argument is neither "json" nor "yaml"
390
- def dump(type = 'json')
391
- return nil unless %w[json yaml].include?(type)
392
- referclass = 'Sisimai::Data::' << type.upcase
393
-
394
- begin
395
- require referclass.downcase.gsub('::', '/')
396
- rescue
397
- warn '***warning: Failed to load' << referclass
398
- end
399
-
400
- dumpeddata = Module.const_get(referclass).dump(self)
401
- return dumpeddata
402
- end
403
-
404
- # JSON handler
405
- # @return [String] JSON string converted from Sisimai::Data
406
- def to_json(*)
407
- return self.dump('json')
408
- end
409
-
410
- end
411
- end