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
data/README.md CHANGED
@@ -1,15 +1,28 @@
1
1
  ![](https://libsisimai.org/static/images/logo/sisimai-x01.png)
2
-
3
2
  [![License](https://img.shields.io/badge/license-BSD%202--Clause-orange.svg)](https://github.com/sisimai/rb-sisimai/blob/master/LICENSE)
4
3
  [![Coverage Status](https://img.shields.io/coveralls/sisimai/rb-sisimai.svg)](https://coveralls.io/r/sisimai/rb-sisimai)
5
- [![Build Status](https://travis-ci.org/sisimai/rb-sisimai.svg?branch=master)](https://travis-ci.org/sisimai/rb-sisimai)
6
- [![Codacy Badge](https://api.codacy.com/project/badge/grade/38340177e6284a65be69c0c7c3dc2b58)](https://www.codacy.com/app/azumakuniyuki/rb-sisimai)
7
- [![Ruby](https://img.shields.io/badge/ruby-v2.1.0--v2.6.0-red.svg)](https://www.ruby-lang.org/)
4
+ [![Ruby](https://img.shields.io/badge/ruby-v2.4.0--v3.3.0-red.svg)](https://www.ruby-lang.org/)
8
5
  [![Gem Version](https://badge.fury.io/rb/sisimai.svg)](https://badge.fury.io/rb/sisimai)
9
6
 
7
+ > [!IMPORTANT]
8
+ > **The default branch of this repository is [5-stable](https://github.com/sisimai/rb-sisimai/tree/5-stable)
9
+ > (Sisimai 5) since 2nd February 2024.**
10
+ > If you want to clone the old version, see the [4-stable](https://github.com/sisimai/rb-sisimai/tree/4-stable)[^1]
11
+ > branch instead. We have moved away from using both the `main` and `master` branches in our development process.
12
+ [^1]: Specify `-b 4-stable` when you clone Sisimai 4 for example, `git clone -b 4-stable https://github.com/sisimai/rb-sisimai.git`
13
+
14
+ > [!WARNING]
15
+ > Sisimai 5 requires Ruby 2.4 or later. Check the version of Ruby in your system before installing/upgrading
16
+ > by `ruby -v` command.
17
+
18
+ > [!NOTE]
19
+ > Sisimai is a Ruby Gem or Perl module, but it can be used in any environment where JSON can be read,
20
+ > such as PHP, Python, Go, and Rust. By obtaining the analysis results, it is very useful for understanding
21
+ > the bounce occurrence status.
22
+
10
23
  - [**README-JA(日本語)**](README-JA.md)
11
24
  - [What is Sisimai](#what-is-sisimai)
12
- - [Key features](#key-features)
25
+ - [The key features of sisimai](#the-key-features-of-sisimai)
13
26
  - [Command line demo](#command-line-demo)
14
27
  - [Setting Up Sisimai](#setting-up-sisimai)
15
28
  - [System requirements](#system-requirements)
@@ -22,12 +35,14 @@
22
35
  - [Callback feature](#callback-feature)
23
36
  - [One-Liner](#one-liner)
24
37
  - [Output example](#output-example)
25
- - [Sisimai Specification](#sisimai-specification)
26
- - [Differences between Ruby version and Perl version](#differences-between-ruby-version-and-perl-version)
27
- - [Other specification of Sisimai](#other-specification-of-sisimai)
38
+ - [Differences between Sisimai 4 and Sisimai 5](#differences-between-sisimai-4-and-sisimai-5)
39
+ - [Features](#features)
40
+ - [Decoding Methods](#decoding-methods)
41
+ - [MTA/ESP Module Names](#mtaesp-module-names)
42
+ - [Bounce Reasons](#bounce-reasons)
28
43
  - [Contributing](#contributing)
29
44
  - [Bug report](#bug-report)
30
- - [Emails could not be parsed](#emails-could-not-be-parsed)
45
+ - [Emails could not be decoded](#emails-could-not-be-decoded)
31
46
  - [Other Information](#other-information)
32
47
  - [Related sites](#related-sites)
33
48
  - [See also](#see-also)
@@ -36,112 +51,145 @@
36
51
  - [License](#license)
37
52
 
38
53
  What is Sisimai
39
- ===============================================================================
40
- Sisimai is a Ruby library for analyzing RFC5322 bounce emails and generating
41
- structured data from parsed results. The Ruby version of Sisimai is ported from
42
- the Perl version of Sisimai at [github.com/sisimai/p5-sisimai](https://github.com/sisimai/p5-sisimai/).
43
-
44
- ![](https://libsisimai.org/static/images/figure/sisimai-overview-1.png)
45
-
46
- Key Features
47
- -------------------------------------------------------------------------------
48
- * __Convert Bounce Mails to Structured Data__
49
- * Supported formats are Ruby(Hash, Array) and JSON(String)
50
- * __Easy to Install, Use.__
51
- * gem install
52
- * git clone & make
53
- * __High Precision of Analysis__
54
- * 2 times higher than bounceHammer
55
- * Support 68 MTAs/MDAs/ESPs
56
- * Support Feedback Loop Message(ARF)
57
- * Can detect 29 error reasons
54
+ ===================================================================================================
55
+ Sisimai is a library that decodes complex and diverse bounce emails and outputs the results of the
56
+ delivery failure, such as the reason for the bounce and the recipient email address, in structured
57
+ data. It is also possible to output in JSON format. The Ruby version of Sisimai is ported from the
58
+ Perl version of Sisimai at [github.com/sisimai/p5-sisimai](https://github.com/sisimai/p5-sisimai/).
59
+
60
+ ![](https://libsisimai.org/static/images/figure/sisimai-overview-2.png)
61
+
62
+ The key features of Sisimai
63
+ ---------------------------------------------------------------------------------------------------
64
+ * __Decode email bounces to structured data__
65
+ * Sisimai provides detailed insights into bounce emails by extracting 24 key data points.[^2]
66
+ * __Essential information__: `timestamp`, `origin`
67
+ * __Sender information__: `addresser`, `senderdomain`,
68
+ * __Recipient information__: `recipient`, `destination`, `alias`
69
+ * __Delivery information__: `action`, `replycode`,`action`, `replycode`, `deliverystatus`
70
+ * __Bounce details__: `reason`, `diagnosticcode`, `diagnostictype`, `feedbacktype`, `hardbounce`
71
+ * __Message details__: `subject`, `messageid`, `listid`,
72
+ * __Additional information__: `smtpagent`, `timezoneoffset`, `lhost`, `rhost`, `token`, `catch`
73
+ * Output formats
74
+ * Ruby (Hash, Array)
75
+ * JSON
76
+ * (by using [`oj`](https://rubygems.org/gems/oj) gem at CRuby)
77
+ * (by using [`jrjackson`](https://rubygems.org/gems/jrjackson) gem at JRuby)
78
+ * YAML ([`yaml`](https://rubygems.org/gems/yaml) gem required)
79
+ * __Easy to Install, Use.__
80
+ * `gem install`
81
+ * `git clone && make`
82
+ * __High Precision of Analysis__
83
+ * Support [70 MTAs/MDAs/ESPs](https://libsisimai.org/en/engine/)
84
+ * Support Feedback Loop Message(ARF)
85
+ * Can detect [34 bounce reasons](https://libsisimai.org/en/reason/)
86
+
87
+ [^2]: The callback function allows you to add your own data under the `catch` accessor.
58
88
 
59
89
  Command line demo
60
- -------------------------------------------------------------------------------
61
- The following screen shows a demonstration of Sisimai at the command line using
62
- Ruby(rb-sisimai) and Perl(p5-sisimai) version of Sisimai.
63
- ![](https://libsisimai.org/static/images/demo/sisimai-dump-01.gif)
90
+ ---------------------------------------------------------------------------------------------------
91
+ The following screen shows a demonstration of `dump` method of Sisimai 5 at the command line using
92
+ Ruby(rb-sisimai) and `jq` command.
93
+ ![](https://libsisimai.org/static/images/demo/sisimai-5-cli-dump-r01.gif)
64
94
 
65
95
  Setting Up Sisimai
66
- ===============================================================================
67
-
96
+ ===================================================================================================
68
97
  System requirements
69
- -------------------------------------------------------------------------------
98
+ ---------------------------------------------------------------------------------------------------
70
99
  More details about system requirements are available at
71
100
  [Sisimai | Getting Started](https://libsisimai.org/en/start/) page.
72
101
 
73
-
74
- * [Ruby 2.1.0 or later](http://www.ruby-lang.org/)
75
- * [__Oj | The fastest JSON parser and object serializer__](https://rubygems.org/gems/oj)
76
- * Also works on [JRuby 9.0.4.0 or later](http://jruby.org)
77
- * [__JrJackson | A mostly native JRuby wrapper for the java jackson json processor jar__](https://rubygems.org/gems/jrjackson)
102
+ * [Ruby 2.4.0 or later](http://www.ruby-lang.org/)
103
+ * [__oj | The fastest JSON parser and object serializer__](https://rubygems.org/gems/oj)
104
+ * Also works on [JRuby 9.2 or later](http://jruby.org)~~
105
+ * [__jrjackson | A mostly native JRuby wrapper for the java jackson json processor jar__](https://rubygems.org/gems/jrjackson)
78
106
 
79
107
  Install
80
- -------------------------------------------------------------------------------
108
+ ---------------------------------------------------------------------------------------------------
81
109
  ### From RubyGems
82
-
83
110
  ```shell
84
111
  $ sudo gem install sisimai
85
- Fetching: sisimai-4.25.5.gem (100%)
86
- Successfully installed sisimai-4.25.5
87
- Parsing documentation for sisimai-4.25.5
88
- Installing ri documentation for sisimai-4.25.5
112
+ Fetching: sisimai-5.0.2.gem (100%)
113
+ Successfully installed sisimai-5.0.2
114
+ Parsing documentation for sisimai-5.0.2
115
+ Installing ri documentation for sisimai-5.0.2
89
116
  Done installing documentation for sisimai after 6 seconds
90
117
  1 gem installed
91
118
  ```
92
119
 
93
120
  ### From GitHub
121
+ > [!WARNING]
122
+ > Sisimai 5 requires Ruby 2.4 or later. Check the version of Ruby in your system before installing/upgrading
123
+ > by `ruby -v` command.
94
124
 
95
125
  ```shell
126
+ % ruby -v
127
+ ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin21]
128
+
96
129
  $ cd /usr/local/src
97
130
  $ git clone https://github.com/sisimai/rb-sisimai.git
131
+
98
132
  $ cd ./rb-sisimai
99
133
  $ sudo make depend install-from-local
100
- gem install bundle rake rspec coveralls
134
+ gem install bundle rake minitest
135
+ ...
136
+ 3 gems installed
137
+ if [ -d "/usr/local/jr" ]; then \
138
+ PATH="/usr/local/jr/bin:$PATH" /usr/local/jr/bin/gem install bundle rake minitest; \
139
+ fi
101
140
  ...
102
- 4 gems installed
103
- bundle exec rake install
104
- sisimai 4.25.5 built to pkg/sisimai-4.25.5.gem.
105
- sisimai (4.25.5) installed.
141
+ 3 gems installed
142
+ /opt/local/bin/rake install
143
+ sisimai 5.0.2 built to pkg/sisimai-5.0.2.gem.
144
+ sisimai (5.0.2) installed.
145
+ if [ -d "/usr/local/jr" ]; then \
146
+ PATH="/usr/local/jr/bin:$PATH" /usr/local/jr/bin/rake install; \
147
+ fi
148
+ sisimai 5.0.2 built to pkg/sisimai-5.0.2-java.gem.
149
+ sisimai (5.0.2) installed.
106
150
  ```
107
151
 
108
152
  Usage
109
- ===============================================================================
110
-
153
+ ===================================================================================================
111
154
  Basic usage
112
- -------------------------------------------------------------------------------
113
- `make()` method provides feature for getting parsed data from bounced email
114
- messages like following. Beginning with v4.25.6, new accessor `origin` which
115
- keeps the path to email file as a data source is available.
116
-
155
+ ---------------------------------------------------------------------------------------------------
156
+ `Sisimai->rise()` method provides the feature for getting decoded data as Ruby Hash from bounced
157
+ email messages as the following. Beginning with v4.25.6, new accessor `origin` which keeps the path
158
+ to email file as a data source is available.
117
159
 
118
160
  ```ruby
119
161
  #! /usr/bin/env ruby
120
162
  require 'sisimai'
121
- v = Sisimai.make('/path/to/mbox') # or path to Maildir/
163
+ v = Sisimai.rise('/path/to/mbox') # or path to Maildir/
122
164
 
123
- # Beginning with v4.23.0, both make() and dump() method of Sisimai class can
124
- # read bounce messages from variable instead of a path to mailbox
165
+ # In v4.23.0, the rise() and dump() methods of the Sisimai class can now read the entire bounce
166
+ # email as a string, in addition to the PATH to the email file or mailbox.
125
167
  f = File.open('/path/to/mbox', 'r'); # or path to Maildir/
126
- v = Sisimai.make(f.read)
168
+ v = Sisimai.rise(f.read)
169
+
170
+ # If you also need analysis results that are "delivered" (successfully delivered), please specify
171
+ # the "delivered" option to the rise() method as shown below.
172
+ v = Sisimai.rise('/path/to/mbox', delivered: true)
127
173
 
128
- # If you want to get bounce records which reason is "delivered", set "delivered"
129
- # option to make() method like the following:
130
- v = Sisimai.make('/path/to/mbox', delivered: true)
174
+ # From v5.0.0, Sisimai no longer returns analysis results with a bounce reason of "vacation" by
175
+ # default. If you also need analysis results that show a "vacation" reason, please specify the
176
+ # "vacation" option to the rise() method as shown in the following code.
177
+ v = Sisimai.rise('/path/to/mbox', vacation: true );
131
178
 
132
179
  if v.is_a? Array
133
180
  v.each do |e|
134
- puts e.class # Sisimai::Data
181
+ puts e.class # Sisimai::Fact
135
182
  puts e.recipient.class # Sisimai::Address
136
183
  puts e.timestamp.class # Sisimai::Time
137
184
 
138
- puts e.addresser.address # shironeko@example.org # From
139
- puts e.recipient.address # kijitora@example.jp # To
140
- puts e.recipient.host # example.jp
141
- puts e.deliverystatus # 5.1.1
142
- puts e.replycode # 550
143
- puts e.reason # userunknown
144
- puts e.origin # /var/spool/bounce/Maildir/new/1740074341.eml
185
+ puts e.addresser.address # "michitsuna@example.org" # From
186
+ puts e.recipient.address # "kijitora@example.jp" # To
187
+ puts e.recipient.host # "example.jp"
188
+ puts e.deliverystatus # "5.1.1"
189
+ puts e.replycode # "550"
190
+ puts e.reason # "userunknown"
191
+ puts e.origin # "/var/spool/bounce/Maildir/new/1740074341.eml"
192
+ puts e.hardbounce # true
145
193
 
146
194
  h = e.damn # Convert to HASH
147
195
  j = e.dump('json') # Convert to JSON string
@@ -151,116 +199,238 @@ end
151
199
  ```
152
200
 
153
201
  Convert to JSON
154
- -------------------------------------------------------------------------------
155
- `Sisimai.dump()` method provides feature for getting parsed data as JSON string
156
- from bounced email messages like following.
202
+ ---------------------------------------------------------------------------------------------------
203
+ `Sisimai.dump()` method provides the feature for getting decoded data as JSON string from bounced
204
+ email messages like the following code:
157
205
 
158
206
  ```ruby
159
- # Get JSON string from parsed mailbox or Maildir/
207
+ # Get JSON string from path of a mailbox or a Maildir/
160
208
  puts Sisimai.dump('/path/to/mbox') # or path to Maildir/
161
209
 
162
- # dump() method also accepts "delivered" option like the following code:
163
- puts Sisimai.dump('/path/to/mbox', delivered: true)
210
+ # dump() method also accepts "delivered" and "vacation" option like the following code:
211
+ puts Sisimai.dump('/path/to/mbox', delivered: true, vacation: true)
164
212
  ```
165
213
 
166
214
  Callback feature
167
- -------------------------------------------------------------------------------
168
- Beginning with Sisimai 4.19.0, `make()` and `dump()` methods of Sisimai accept
169
- a Lambda (Proc object) in `hook` argument for setting a callback method and
170
- getting the results generated by the method via `Sisimai::Data.catch` method.
215
+ ---------------------------------------------------------------------------------------------------
216
+ `:c___` (`c` and three `_`s, looks like a fishhook) argument of `Sisimai.rise` and `Sisimai.dump`
217
+ is an Array and is a parameter to receive `Proc` objects for callback feature. The first element of
218
+ `:c___` argument is called at `Sisimai::Message.sift` for dealing email headers and entire message
219
+ body. The second element of `:c___` argument is called at the end of each email file parsing. The
220
+ result generated by the callback method is accessible via `Sisimai::Fact.catch`.
221
+
222
+ ### [0] For email headers and the body
223
+ Callback method set in the first element of `:c___` is called at `Sisimai::Message.sift()`.
171
224
 
172
225
  ```ruby
173
226
  #! /usr/bin/env ruby
174
227
  require 'sisimai'
175
- callbackto = lambda do |v|
176
- r = { 'x-mailer' => '', 'queue-id' => '' }
228
+ code = lambda do |args|
229
+ head = args['headers'] # (*Hash) Email headers
230
+ body = args['message'] # (String) Message body
231
+ adds = { 'x-mailer' => '', 'queue-id' => '' }
177
232
 
178
- if cv = v['message'].match(/^X-Postfix-Queue-ID:\s*(.+)$/)
179
- r['queue-id'] = cv[1]
233
+ if cv = body.match(/^X-Postfix-Queue-ID:\s*(.+)$/)
234
+ adds['queue-id'] = cv[1]
180
235
  end
181
- r['x-mailer'] = v['headers']['x-mailer'] || ''
182
- return r
236
+ r['x-mailer'] = head['x-mailer'] || ''
237
+ return adds
183
238
  end
184
239
 
185
- data = Sisimai.make('/path/to/mbox', hook: callbackto)
186
- json = Sisimai.dump('/path/to/mbox', hook: callbackto)
240
+ data = Sisimai.rise('/path/to/mbox', c___: [code, nil])
241
+ json = Sisimai.dump('/path/to/mbox', c___: [code, nil])
187
242
 
188
- puts data[0].catch['x-mailer'] # Apple Mail (2.1283)
243
+ puts data[0].catch['x-mailer'] # "Apple Mail (2.1283)"
244
+ puts data[0].catch['queue-id'] # "43f4KX6WR7z1xcMG"
245
+ ```
246
+
247
+ ### For each email file
248
+ Callback method set in the second element of `:c___` is called at `Sisimai.rise` method for dealing
249
+ each email file.
250
+
251
+ ```ruby
252
+ path = '/path/to/maildir'
253
+ code = lambda do |args|
254
+ kind = args['kind'] # (String) Sisimai::Mail.kind
255
+ mail = args['mail'] # (String) Entire email message
256
+ path = args['path'] # (String) Sisimai::Mail.path
257
+ fact = args['fact'] # (Array) List of Sisimai::Fact
258
+
259
+ fact.each do |e|
260
+ # Store custom information in the "catch" accessor
261
+ e.catch ||= {}
262
+ e.catch['size'] = mail.size
263
+ e.catch['kind'] = kind.capitalize
264
+
265
+ if cv = mail.match(/^Return-Path: (.+)$/)
266
+ # Return-Path: <MAILER-DAEMON>
267
+ e.catch['return-path'] = cv[1]
268
+ end
269
+ e.catch['parsedat'] = Time.new.localtime.to_s
270
+
271
+ # Save the original email with an additional "X-Sisimai-Parsed:" header to a different PATH.
272
+ a = sprintf("X-Sisimai-Parsed: %d", fact.size)
273
+ p = sprintf("/path/to/another/directory/sisimai-%s.eml", e.token)
274
+ v = mail.sub(/^(From:.+?)$/, '\1' + "\n" + a)
275
+ f = File.open(p, 'w:UTF-8')
276
+ f.write(v)
277
+ f.close
278
+
279
+ # Remove the email file in Maildir/ after decoding
280
+ File.delete(path) if kind == 'maildir'
281
+
282
+ # Need to not return a value
283
+ end
284
+ end
285
+
286
+ list = Sisimai.rise(path, c___: [nil, code])
287
+
288
+ puts list[0].catch['size'] # 2202
289
+ puts list[0].catch['kind'] # "Maildir"
290
+ puts list[0].catch['return-path'] # "<MAILER-DAEMON>"
189
291
  ```
190
292
 
191
293
  More information about the callback feature is available at
192
- [Sisimai | How To Parse - Callback](https://libsisimai.org/en/usage/#callback)
193
- Page.
294
+ [Sisimai | How To Parse - Callback](https://libsisimai.org/en/usage/#callback) Page.
194
295
 
195
296
  One-Liner
196
- -------------------------------------------------------------------------------
197
-
297
+ ---------------------------------------------------------------------------------------------------
198
298
  ```shell
199
299
  % ruby -rsisimai -e 'puts Sisimai.dump($*.shift)' /path/to/mbox
200
300
  ```
201
301
 
202
302
  Output example
203
- -------------------------------------------------------------------------------
204
- ![](https://libsisimai.org/static/images/demo/sisimai-dump-02.gif)
303
+ ---------------------------------------------------------------------------------------------------
304
+ ![](https://libsisimai.org/static/images/demo/sisimai-5-cli-dump-p01.gif)
205
305
 
206
306
  ```json
207
- [{"catch":{"x-mailer":"","return-path":"<shironeko@mx.example.co.jp>"},"token":"cf17945938502bd876603a375f0e9517c921bbab","lhost":"localhost","rhost":"mx-s.neko.example.jp","alias":"","listid":"","reason":"hasmoved","action":"failed","origin":"set-of-emails/maildir/bsd/lhost-sendmail-22.eml","subject":"Nyaaaan","messageid":"0000000011111.fff0000000003@mx.example.co.jp","replycode":"","smtpagent":"Sendmail","softbounce":0,"smtpcommand":"DATA","destination":"example.net","senderdomain":"example.co.jp","feedbacktype":"","diagnosticcode":"450 busy - please try later 551 not our customer 503 need RCPT command [data]","diagnostictype":"SMTP","deliverystatus":"5.1.6","timezoneoffset":"+0900","addresser":"shironeko@example.co.jp","recipient":"kijitora@example.net","timestamp":1397054085}]
307
+ [
308
+ {
309
+ "destination": "google.example.com",
310
+ "lhost": "gmail-smtp-in.l.google.com",
311
+ "hardbounce": 0,
312
+ "reason": "authfailure",
313
+ "catch": null,
314
+ "addresser": "michitsuna@example.jp",
315
+ "alias": "nekochan@example.co.jp",
316
+ "smtpagent": "Postfix",
317
+ "smtpcommand": "DATA",
318
+ "senderdomain": "example.jp",
319
+ "listid": "",
320
+ "action": "failed",
321
+ "feedbacktype": "",
322
+ "messageid": "hwK7pzjzJtz0RF9Y@relay3.example.com",
323
+ "origin": "./gmail-5.7.26.eml",
324
+ "recipient": "kijitora@google.example.com",
325
+ "rhost": "gmail-smtp-in.l.google.com",
326
+ "subject": "Nyaan",
327
+ "timezoneoffset": "+0900",
328
+ "replycode": 550,
329
+ "token": "84656774898baa90660be3e12fe0526e108d4473",
330
+ "diagnostictype": "SMTP",
331
+ "timestamp": 1650119685,
332
+ "diagnosticcode": "host gmail-smtp-in.l.google.com[64.233.187.27] said: This mail has been blocked because the sender is unauthenticated. Gmail requires all senders to authenticate with either SPF or DKIM. Authentication results: DKIM = did not pass SPF [relay3.example.com] with ip: [192.0.2.22] = did not pass For instructions on setting up authentication, go to https://support.google.com/mail/answer/81126#authentication c2-202200202020202020222222cat.127 - gsmtp (in reply to end of DATA command)",
333
+ "deliverystatus": "5.7.26"
334
+ }
335
+ ]
208
336
  ```
209
337
 
210
- Sisimai Specification
211
- ===============================================================================
212
-
213
- Differences between Ruby version and Perl version
214
- -------------------------------------------------------------------------------
215
- The following table show the differences between Ruby version of Sisimai
216
- and Perl version of Sisimai. Information about differences between Sisimai
217
- and bounceHammer are available at
218
- [Sisimai | Differences](https://libsisimai.org/en/diff/) page.
219
-
220
- | Features | Ruby version | Perl version |
221
- |---------------------------------------------|----------------|---------------|
222
- | System requirements | Ruby 2.1 - 2.6 | Perl 5.10 - |
223
- | | JRuby 9.0.4.0- | |
224
- | Analytical precision ratio(2000 emails)[1] | 1.00 | 1.00 |
225
- | The speed of parsing email(1000 emails) | 2.22s[2] | 1.35s |
226
- | How to install | gem install | cpanm, cpm |
227
- | Dependencies (Except core modules) | 1 module | 2 modules |
228
- | LOC:Source lines of code | 10600 lines | 10800 lines |
229
- | The number of tests(spec/,t/,xt/) directory | 241000 tests | 270000 tests |
230
- | License | BSD 2-Clause | BSD 2-Clause |
231
- | Support Contract provided by Developer | Available | Available |
232
-
233
- 1. See [./ANALYTICAL-PRECISION](https://github.com/sisimai/rb-sisimai/blob/master/ANALYTICAL-PRECISION)
234
- 2. Xeon E5-2640 2.5GHz x 2 cores | 5000 bogomips | 1GB RAM | Ruby 2.3.4p301
235
-
236
- Other specification of Sisimai
237
- -------------------------------------------------------------------------------
238
- - [**Parser Engines**](https://libsisimai.org/en/engine/)
239
- - [**Bounce Reason List**](https://libsisimai.org/en/reason/)
240
- - [**Data Structure of Sisimai::Data**](https://libsisimai.org/en/data/)
338
+ Differences between Sisimai 4 and Sisimai 5
339
+ ===================================================================================================
340
+ The following table show the differences between [Sisimai 4.25.16p1](https://github.com/sisimai/rb-sisimai/releases/tag/v4.25.16p1)
341
+ and [Sisimai 5](https://github.com/sisimai/rb-sisimai/releases/tag/v5.0.0). More information about
342
+ differences are available at [Sisimai | Differences](https://libsisimai.org/en/diff/) page.
343
+
344
+ Features
345
+ ---------------------------------------------------------------------------------------------------
346
+ Beginning with v5.0.0, Sisimai requires **Ruby 2.4.0 or later.**
347
+
348
+ | Features | Sisimai 4 | Sisimai 5 |
349
+ |------------------------------------------------------|--------------------|---------------------|
350
+ | System requirements (CRuby) | 2.1 - 3.3.0 | **2.4** or later |
351
+ | System requirements (JRuby) | 9.0.4.0 - 9.1.17.0 | **9.2** or later |
352
+ | Callback feature for the original email file | N/A | Available[^3] |
353
+ | The number of MTA/ESP modules | 68 | 70 |
354
+ | The number of detectable bounce reasons | 29 | 34 |
355
+ | Dependencies (Except Ruby Standard Gems) | 1 gem | 1 gem |
356
+ | Source lines of code | 10,300 lines | 11,370 lines |
357
+ | Test frameworks | rspec | minitest |
358
+ | The number of tests in spec/ or test/ directory | 311,000 tests | 338,000 tests |
359
+ | The number of bounce emails decoded/sec (CRuby)[^4] | 231 emails | 305 emails |
360
+ | License | 2 Clause BSD | 2 Caluse BSD |
361
+ | Commercial support | Available | Available |
362
+
363
+ [^3]: The 2nd argument of `:c___` parameter at `Sisimai.rise` method
364
+ [^4]: macOS Monterey/1.6GHz Dual-Core Intel Core i5/16GB-RAM/Ruby 3.3.0
365
+
366
+
367
+ Decoding Method
368
+ ---------------------------------------------------------------------------------------------------
369
+ Some decoding method names, class names, parameter names have been changed at Sisimai 5.
370
+ The details of the decoded data are available at [LIBSISIMAI.ORG/EN/DATA](https://libsisimai.org/en/data/)
371
+
372
+ | Decoding Method | Sisimai 4 | Sisimai 5 |
373
+ |------------------------------------------------------|--------------------|---------------------|
374
+ | Decoding method name | `Sisimai.make` | `Sisimai.rise` |
375
+ | Dumping method name | `Sisimai.dump` | `Sisimai.dump` |
376
+ | Class name of decoded object | `Sisimai::Data` | `Sisimai::Fact` |
377
+ | Parameter name of the callback | `hook` | `:c___`[^5] |
378
+ | Method name for checking the hard/soft bounce | `softbounce` | `hardbounce` |
379
+ | Decode a vacation message by default | Yes | No |
380
+ | Sisimai::Message returns an object | Yes | No |
381
+ | MIME decoding class | `Sisimai::MIME` | `Sisimai::RFC2045` |
382
+ | Decoding transcript of SMTP session | No | Yes[^6] |
383
+
384
+ [^5]: `:c___` looks like a fishhook
385
+ [^6]: `Sisimai::SMTP::Transcript.rise` Method provides the feature
386
+
387
+
388
+ MTA/ESP Module Names
389
+ ---------------------------------------------------------------------------------------------------
390
+ Three ESP module names have been changed at Sisimai 5. The list of the all MTA/ESP modules is
391
+ available at [LIBSISIMAI.ORG/EN/ENGINE](https://libsisimai.org/en/engine/)
392
+
393
+ | `Sisimai::Rhost::` | Sisimai 4 | Sisimai 5 |
394
+ |------------------------------------------------------|--------------------|---------------------|
395
+ | Microsoft Exchange Online | `ExchangeOnline` | `Microsoft` |
396
+ | Google Workspace | `GoogleApps` | `Google` |
397
+ | Tencent | `TencentQQ` | `Tencent` |
398
+
399
+ Bounce Reasons
400
+ ---------------------------------------------------------------------------------------------------
401
+ Five bounce reasons have been added at Sisimai 5. The list of the all bounce reasons sisimai can
402
+ detect is available at [LIBSISIMAI.ORG/EN/REASON](https://libsisimai.org/en/reason/)
403
+
404
+ | Rejected due to | Sisimai 4 | Sisimai 5 |
405
+ |------------------------------------------------------|--------------------|---------------------|
406
+ | sender domain authentication(SPF,DKIM,DMARC) | `SecurityError` | `AuthFailure` |
407
+ | low/bad reputation of the sender hostname/IP addr. | `Blocked` | `BadReputation` |
408
+ | missing PTR/having invalid PTR | `Blocked` | `RequirePTR` |
409
+ | non-compliance with RFC[^7] | `SecurityError` | `NotCompliantRFC` |
410
+ | exceeding a rate limit or sending too fast | `SecurityError` | `Speeding` |
411
+
412
+ [^7]: RFC5322 and related RFCs
241
413
 
242
- Contributing
243
- ===============================================================================
244
414
 
415
+ Contributing
416
+ ===================================================================================================
245
417
  Bug report
246
- -------------------------------------------------------------------------------
247
- Please use the [issue tracker](https://github.com/sisimai/rb-sisimai/issues)
248
- to report any bugs.
418
+ ---------------------------------------------------------------------------------------------------
419
+ Please use the [issue tracker](https://github.com/sisimai/rb-sisimai/issues) to report any bugs.
249
420
 
250
- Emails could not be parsed
251
- -------------------------------------------------------------------------------
252
- Bounce mails which could not be parsed by Sisimai are saved in the repository
421
+ Emails could not be decoded
422
+ ---------------------------------------------------------------------------------------------------
423
+ Bounce mails which could not be decoded by Sisimai are saved in the repository
253
424
  [set-of-emails/to-be-debugged-because/sisimai-cannot-parse-yet](https://github.com/sisimai/set-of-emails/tree/master/to-be-debugged-because/sisimai-cannot-parse-yet).
254
- If you have found any bounce email cannot be parsed using Sisimai, please add
255
- the email into the directory and send Pull-Request to this repository.
425
+ If you have found any bounce email cannot be decoded using Sisimai, please add the email into the
426
+ directory and send Pull-Request to this repository.
256
427
 
257
428
  Other Information
258
- ===============================================================================
259
-
429
+ ===================================================================================================
260
430
  Related Sites
261
- -------------------------------------------------------------------------------
431
+ ---------------------------------------------------------------------------------------------------
262
432
  * __@libsisimai__ | [Sisimai on Twitter (@libsisimai)](https://twitter.com/libsisimai)
263
- * __libSISIMAI.ORG__ | [Sisimai | The successor to bounceHammer, Library to parse bounce mails](https://libsisimai.org/)
433
+ * __LIBSISIMAI.ORG__ | [SISIMAI | MAIL ANALYZING INTERFACE | DECODING BOUNCES, BETTER AND FASTER.](https://libsisimai.org/)
264
434
  * __Sisimai Blog__ | [blog.libsisimai.org](http://blog.libsisimai.org/)
265
435
  * __Facebook Page__ | [facebook.com/libsisimai](https://www.facebook.com/libsisimai/)
266
436
  * __GitHub__ | [github.com/sisimai/rb-sisimai](https://github.com/sisimai/rb-sisimai)
@@ -269,7 +439,7 @@ Related Sites
269
439
  * __Fixtures__ | [set-of-emails - Sample emails for "make test"](https://github.com/sisimai/set-of-emails)
270
440
 
271
441
  See also
272
- -------------------------------------------------------------------------------
442
+ ---------------------------------------------------------------------------------------------------
273
443
  * [README-JA.md - README.md in Japanese(日本語)](https://github.com/sisimai/rb-sisimai/blob/master/README-JA.md)
274
444
  * [RFC3463 - Enhanced Mail System Status Codes](https://tools.ietf.org/html/rfc3463)
275
445
  * [RFC3464 - An Extensible Message Format for Delivery Status Notifications](https://tools.ietf.org/html/rfc3464)
@@ -278,14 +448,14 @@ See also
278
448
  * [RFC5322 - Internet Message Format](https://tools.ietf.org/html/rfc5322)
279
449
 
280
450
  Author
281
- ===============================================================================
451
+ ===================================================================================================
282
452
  [@azumakuniyuki](https://twitter.com/azumakuniyuki)
283
453
 
284
454
  Copyright
285
- ===============================================================================
286
- Copyright (C) 2015-2022 azumakuniyuki, All Rights Reserved.
455
+ ===================================================================================================
456
+ Copyright (C) 2015-2024 azumakuniyuki, All Rights Reserved.
287
457
 
288
458
  License
289
- ===============================================================================
459
+ ===================================================================================================
290
460
  This software is distributed under The BSD 2-Clause License.
291
461
 
data/Rakefile CHANGED
@@ -1,12 +1,18 @@
1
- require 'rspec/core/rake_task'
2
1
  require 'bundler/gem_helper'
2
+
3
3
  if RUBY_PLATFORM =~ /java/
4
4
  filename = 'sisimai-java'
5
5
  else
6
6
  filename = 'sisimai'
7
7
  end
8
8
  Bundler::GemHelper.install_tasks :name => filename
9
- RSpec::Core::RakeTask.new(:spec)
10
9
 
11
- task :default => :spec
10
+ task :default => :test
11
+ task :test => [:publictest, :privatetest]
12
+ task :publictest do
13
+ Dir.glob('./test/public/*-test.rb').each { |cf| require cf }
14
+ end
15
+ task :privatetest do
16
+ Dir.glob('./test/private/*-test.rb').each { |cf| require cf }
17
+ end
12
18