sisimai 4.25.16 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (177) 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 +412 -393
  7. data/Developers.mk +5 -6
  8. data/Gemfile +1 -1
  9. data/Makefile +15 -15
  10. data/README-JA.md +140 -78
  11. data/README.md +290 -143
  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 +23 -18
  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 -326
  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 +12 -12
  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 -20
  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/bsd/{rfc3464-41.eml → rfc3834-05.eml} +0 -0
  170. /data/set-of-emails/maildir/bsd/{rhost-googleapps-01.eml → rhost-google-01.eml} +0 -0
  171. /data/set-of-emails/maildir/bsd/{rhost-googleapps-02.eml → rhost-google-02.eml} +0 -0
  172. /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-01.eml → rhost-microsoft-01.eml} +0 -0
  173. /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-02.eml → rhost-microsoft-02.eml} +0 -0
  174. /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-03.eml → rhost-microsoft-03.eml} +0 -0
  175. /data/set-of-emails/maildir/bsd/{rhost-tencentqq-01.eml → rhost-tencent-01.eml} +0 -0
  176. /data/set-of-emails/maildir/bsd/{rhost-tencentqq-02.eml → rhost-tencent-02.eml} +0 -0
  177. /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.16
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: 2023-05-16 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
@@ -917,7 +938,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
917
938
  requirements:
918
939
  - - ">="
919
940
  - !ruby/object:Gem::Version
920
- version: 2.1.0
941
+ version: 2.4.0
921
942
  required_rubygems_version: !ruby/object:Gem::Requirement
922
943
  requirements:
923
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