sisimai 4.22.7 → 4.23.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sisimai might be problematic. Click here for more details.

Files changed (118) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog.md +15 -0
  3. data/README-JA.md +13 -8
  4. data/README.md +14 -9
  5. data/lib/sisimai.rb +11 -12
  6. data/lib/sisimai/address.rb +13 -23
  7. data/lib/sisimai/arf.rb +10 -12
  8. data/lib/sisimai/bite/email/activehunter.rb +5 -9
  9. data/lib/sisimai/bite/email/amazonses.rb +12 -18
  10. data/lib/sisimai/bite/email/amazonworkmail.rb +7 -12
  11. data/lib/sisimai/bite/email/aol.rb +10 -16
  12. data/lib/sisimai/bite/email/apachejames.rb +8 -12
  13. data/lib/sisimai/bite/email/bigfoot.rb +10 -15
  14. data/lib/sisimai/bite/email/biglobe.rb +7 -11
  15. data/lib/sisimai/bite/email/courier.rb +11 -15
  16. data/lib/sisimai/bite/email/domino.rb +8 -13
  17. data/lib/sisimai/bite/email/einsundeins.rb +7 -11
  18. data/lib/sisimai/bite/email/exchange2003.rb +11 -15
  19. data/lib/sisimai/bite/email/exchange2007.rb +7 -11
  20. data/lib/sisimai/bite/email/exim.rb +20 -27
  21. data/lib/sisimai/bite/email/ezweb.rb +13 -22
  22. data/lib/sisimai/bite/email/facebook.rb +7 -10
  23. data/lib/sisimai/bite/email/fml.rb +4 -7
  24. data/lib/sisimai/bite/email/gmx.rb +7 -12
  25. data/lib/sisimai/bite/email/google.rb +6 -12
  26. data/lib/sisimai/bite/email/gsuite.rb +11 -18
  27. data/lib/sisimai/bite/email/imailserver.rb +6 -10
  28. data/lib/sisimai/bite/email/interscanmss.rb +7 -11
  29. data/lib/sisimai/bite/email/kddi.rb +10 -16
  30. data/lib/sisimai/bite/email/mailfoundry.rb +6 -9
  31. data/lib/sisimai/bite/email/mailmarshalsmtp.rb +6 -10
  32. data/lib/sisimai/bite/email/mailru.rb +12 -16
  33. data/lib/sisimai/bite/email/mcafee.rb +5 -9
  34. data/lib/sisimai/bite/email/messagelabs.rb +7 -10
  35. data/lib/sisimai/bite/email/messagingserver.rb +8 -14
  36. data/lib/sisimai/bite/email/mfilter.rb +6 -10
  37. data/lib/sisimai/bite/email/mxlogic.rb +11 -17
  38. data/lib/sisimai/bite/email/notes.rb +9 -13
  39. data/lib/sisimai/bite/email/office365.rb +8 -13
  40. data/lib/sisimai/bite/email/opensmtpd.rb +7 -11
  41. data/lib/sisimai/bite/email/outlook.rb +9 -13
  42. data/lib/sisimai/bite/email/postfix.rb +12 -18
  43. data/lib/sisimai/bite/email/qmail.rb +10 -15
  44. data/lib/sisimai/bite/email/receivingses.rb +10 -17
  45. data/lib/sisimai/bite/email/sendgrid.rb +8 -14
  46. data/lib/sisimai/bite/email/sendmail.rb +8 -12
  47. data/lib/sisimai/bite/email/surfcontrol.rb +5 -9
  48. data/lib/sisimai/bite/email/userdefined.rb +5 -8
  49. data/lib/sisimai/bite/email/v5sendmail.rb +7 -11
  50. data/lib/sisimai/bite/email/verizon.rb +14 -28
  51. data/lib/sisimai/bite/email/x1.rb +5 -8
  52. data/lib/sisimai/bite/email/x2.rb +5 -8
  53. data/lib/sisimai/bite/email/x3.rb +5 -9
  54. data/lib/sisimai/bite/email/x4.rb +10 -14
  55. data/lib/sisimai/bite/email/x5.rb +6 -11
  56. data/lib/sisimai/bite/email/yahoo.rb +6 -11
  57. data/lib/sisimai/bite/email/yandex.rb +8 -12
  58. data/lib/sisimai/bite/email/zoho.rb +7 -12
  59. data/lib/sisimai/bite/json/amazonses.rb +6 -12
  60. data/lib/sisimai/bite/json/sendgrid.rb +1 -7
  61. data/lib/sisimai/data.rb +26 -34
  62. data/lib/sisimai/datetime.rb +5 -5
  63. data/lib/sisimai/mail.rb +9 -3
  64. data/lib/sisimai/mail/maildir.rb +1 -3
  65. data/lib/sisimai/mail/mbox.rb +1 -1
  66. data/lib/sisimai/mail/memory.rb +47 -0
  67. data/lib/sisimai/mail/stdin.rb +1 -1
  68. data/lib/sisimai/mda.rb +7 -10
  69. data/lib/sisimai/message.rb +4 -6
  70. data/lib/sisimai/message/email.rb +16 -24
  71. data/lib/sisimai/message/json.rb +3 -5
  72. data/lib/sisimai/mime.rb +13 -18
  73. data/lib/sisimai/order/email.rb +5 -8
  74. data/lib/sisimai/order/json.rb +2 -2
  75. data/lib/sisimai/reason.rb +3 -7
  76. data/lib/sisimai/reason/blocked.rb +0 -4
  77. data/lib/sisimai/reason/contenterror.rb +1 -1
  78. data/lib/sisimai/reason/exceedlimit.rb +2 -5
  79. data/lib/sisimai/reason/expired.rb +1 -1
  80. data/lib/sisimai/reason/filtered.rb +1 -4
  81. data/lib/sisimai/reason/hasmoved.rb +1 -4
  82. data/lib/sisimai/reason/hostunknown.rb +1 -4
  83. data/lib/sisimai/reason/mailboxfull.rb +2 -5
  84. data/lib/sisimai/reason/mesgtoobig.rb +1 -4
  85. data/lib/sisimai/reason/networkerror.rb +1 -1
  86. data/lib/sisimai/reason/norelaying.rb +1 -4
  87. data/lib/sisimai/reason/notaccept.rb +1 -3
  88. data/lib/sisimai/reason/onhold.rb +1 -5
  89. data/lib/sisimai/reason/policyviolation.rb +1 -1
  90. data/lib/sisimai/reason/rejected.rb +2 -6
  91. data/lib/sisimai/reason/spamdetected.rb +1 -5
  92. data/lib/sisimai/reason/suspend.rb +2 -5
  93. data/lib/sisimai/reason/syntaxerror.rb +0 -3
  94. data/lib/sisimai/reason/systemerror.rb +1 -1
  95. data/lib/sisimai/reason/systemfull.rb +1 -1
  96. data/lib/sisimai/reason/toomanyconn.rb +1 -5
  97. data/lib/sisimai/reason/userunknown.rb +1 -4
  98. data/lib/sisimai/reason/vacation.rb +1 -1
  99. data/lib/sisimai/reason/virusdetected.rb +1 -1
  100. data/lib/sisimai/rfc2606.rb +3 -3
  101. data/lib/sisimai/rfc3464.rb +12 -20
  102. data/lib/sisimai/rfc3834.rb +1 -10
  103. data/lib/sisimai/rfc5322.rb +4 -6
  104. data/lib/sisimai/rhost.rb +0 -4
  105. data/lib/sisimai/rhost/exchangeonline.rb +5 -7
  106. data/lib/sisimai/rhost/franceptt.rb +1 -3
  107. data/lib/sisimai/rhost/godaddy.rb +2 -4
  108. data/lib/sisimai/rhost/googleapps.rb +2 -4
  109. data/lib/sisimai/rhost/kddi.rb +0 -3
  110. data/lib/sisimai/smtp/error.rb +0 -3
  111. data/lib/sisimai/smtp/reply.rb +5 -8
  112. data/lib/sisimai/smtp/status.rb +3 -4
  113. data/lib/sisimai/string.rb +13 -20
  114. data/lib/sisimai/version.rb +1 -1
  115. data/set-of-emails/maildir/bsd/email-office365-09.eml +596 -0
  116. data/set-of-emails/maildir/bsd/email-office365-10.eml +594 -0
  117. data/set-of-emails/maildir/bsd/email-postfix-45.eml +76 -0
  118. metadata +6 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1e01dd134b0c8f9d55656ad506db438535c823b3
4
- data.tar.gz: c0128b71dbe0e35ede76cbb36a05d2d361ea92fe
3
+ metadata.gz: 124512b04d19c1929badc41c4554e3b84d3ffd5d
4
+ data.tar.gz: 24cdb80d3079432a26ef72ef022e2eaba31dfb5a
5
5
  SHA512:
6
- metadata.gz: a04b755a4f2bba636f2032f2f2f1c8b1f05a29e788a97b4497f62344e77019228f67bead30b01146642b064564f8cf60d060d0ebca04da1980ea266678e04707
7
- data.tar.gz: 771e73f4af59f9e64cc8a2b44605092dfe611819ad7559cabf583fa048c928fea545be6f9a942952fc10f38927aabd62ab4c706067e85f6e8164556336b5fd7d
6
+ metadata.gz: 6365ec7dfc91737be04c9e61b8e735ef59f9c384cfe6e67cca83a864cbbd36e6fbde05772d1088bf0432f5f756f7596636da2ccba8561e5014d1752b6584b751
7
+ data.tar.gz: 9a62227d405f0c0f15a3a8a7d3ad3c5bfc95b7cc1af24be2fb8b5bdd8a6ad966cd5981554f912987d211642e9877f0351f5a74ed754ec3336a9dc17ca1b551bf
data/ChangeLog.md CHANGED
@@ -3,6 +3,21 @@ RELEASE NOTES for Ruby version of Sisimai
3
3
  - releases: "https://github.com/sisimai/rb-Sisimai/releases"
4
4
  - download: "https://rubygems.org/gems/sisimai"
5
5
 
6
+ v4.23.0
7
+ --------------------------------------------------------------------------------
8
+ - release: ""
9
+ - version: "4.23.0"
10
+ - changes:
11
+ - #124 Implement Sisimai::Mail::Memory class for reading bounce messages from
12
+ memory(variable).
13
+ - Update regular expression in Sisimai::Bite::Email::Office365 for detecting
14
+ failure on SMTP RCPT.
15
+ - #126 Fix awful bugs(NoMethodError) in Sisimai::Bite::Email::Biglobe, EZweb,
16
+ and KDDI. Thanks to @rinmu.
17
+ - #128 Less method calls: use method chain, bang method.
18
+ - Import commit sisimai/p5-Sisimai@cccb4ef Some test code have been loosened
19
+ for UTC+13(Pacific/Tongatapu), UTC+14(Pacific/Kiritimati).
20
+
6
21
  v4.22.7
7
22
  --------------------------------------------------------------------------------
8
23
  - release: "Mon, 16 Jul 2018 13:02:54 +0900 (JST)"
data/README-JA.md CHANGED
@@ -80,10 +80,10 @@ Install
80
80
 
81
81
  ```shell
82
82
  $ sudo gem install sisimai
83
- Fetching: sisimai-4.22.2.gem (100%)
84
- Successfully installed sisimai-4.22.2
85
- Parsing documentation for sisimai-4.22.2
86
- Installing ri documentation for sisimai-4.22.2
83
+ Fetching: sisimai-4.23.0.gem (100%)
84
+ Successfully installed sisimai-4.23.0
85
+ Parsing documentation for sisimai-4.23.0
86
+ Installing ri documentation for sisimai-4.23.0
87
87
  Done installing documentation for sisimai after 6 seconds
88
88
  1 gem installed
89
89
  ```
@@ -99,8 +99,8 @@ gem install bundle rake rspec coveralls
99
99
  ...
100
100
  4 gems installed
101
101
  bundle exec rake install
102
- sisimai 4.22.2 built to pkg/sisimai-4.22.2.gem.
103
- sisimai (4.22.2) installed.
102
+ sisimai 4.23.0 built to pkg/sisimai-4.23.0.gem.
103
+ sisimai (4.23.0) installed.
104
104
  ```
105
105
 
106
106
  Usage
@@ -116,6 +116,11 @@ Basic usage
116
116
  require 'sisimai'
117
117
  v = Sisimai.make('/path/to/mbox') # or path to Maildir/
118
118
 
119
+ # Beginning with v4.23.0, both make() and dump() method of Sisimai class can
120
+ # read bounce messages from variable instead of a path to mailbox
121
+ f = File.open('/path/to/mbox', 'r'); # or path to Maildir/
122
+ v = Sisimai.make(f.read)
123
+
119
124
  # If you want to get bounce records which reason is "delivered", set "delivered"
120
125
  # option to make() method like the following:
121
126
  v = Sisimai.make('/path/to/mbox', delivered: true)
@@ -239,8 +244,8 @@ Differences between Ruby version and Perl version
239
244
  | メール解析速度(1000通のメール) | 3.75秒[2] | 1.70秒 |
240
245
  | インストール方法 | gem install | cpanm, cpm |
241
246
  | 依存モジュール数(コアモジュールを除く) | 1モジュール | 2モジュール |
242
- | LOC:ソースコードの行数 | 12000行 | 8600行 |
243
- | テスト件数(spec/,t/,xt/ディレクトリ) | 217000件 | 235000件 |
247
+ | LOC:ソースコードの行数 | 11700行 | 8500行 |
248
+ | テスト件数(spec/,t/,xt/ディレクトリ) | 218000件 | 236000件 |
244
249
  | ライセンス | 二条項BSD | 二条項BSD |
245
250
  | 開発会社によるサポート契約 | 準備中 | 提供中 |
246
251
 
data/README.md CHANGED
@@ -85,10 +85,10 @@ Install
85
85
 
86
86
  ```shell
87
87
  $ sudo gem install sisimai
88
- Fetching: sisimai-4.22.2.gem (100%)
89
- Successfully installed sisimai-4.22.2
90
- Parsing documentation for sisimai-4.22.2
91
- Installing ri documentation for sisimai-4.22.2
88
+ Fetching: sisimai-4.23.0.gem (100%)
89
+ Successfully installed sisimai-4.23.0
90
+ Parsing documentation for sisimai-4.23.0
91
+ Installing ri documentation for sisimai-4.23.0
92
92
  Done installing documentation for sisimai after 6 seconds
93
93
  1 gem installed
94
94
  ```
@@ -104,8 +104,8 @@ gem install bundle rake rspec coveralls
104
104
  ...
105
105
  4 gems installed
106
106
  bundle exec rake install
107
- sisimai 4.22.2 built to pkg/sisimai-4.22.2.gem.
108
- sisimai (4.22.2) installed.
107
+ sisimai 4.23.0 built to pkg/sisimai-4.23.0.gem.
108
+ sisimai (4.23.0) installed.
109
109
  ```
110
110
 
111
111
  Usage
@@ -121,6 +121,11 @@ messages like following.
121
121
  require 'sisimai'
122
122
  v = Sisimai.make('/path/to/mbox') # or path to Maildir/
123
123
 
124
+ # Beginning with v4.23.0, both make() and dump() method of Sisimai class can
125
+ # read bounce messages from variable instead of a path to mailbox
126
+ f = File.open('/path/to/mbox', 'r'); # or path to Maildir/
127
+ v = Sisimai.make(f.read)
128
+
124
129
  # If you want to get bounce records which reason is "delivered", set "delivered"
125
130
  # option to make() method like the following:
126
131
  v = Sisimai.make('/path/to/mbox', delivered: true)
@@ -222,7 +227,7 @@ Output example
222
227
  ![](https://libsisimai.org/static/images/demo/sisimai-dump-02.gif)
223
228
 
224
229
  ```json
225
- [{"recipient": "kijitora@example.jp", "addresser": "shironeko@1jo.example.org", "feedbacktype": "", "action": "failed", "subject": "Nyaaaaan", "smtpcommand": "DATA", "diagnosticcode": "550 Unknown user kijitora@example.jp", "listid": "", "destination": "example.jp", "smtpagent": "Email::Courier", "lhost": "1jo.example.org", "deliverystatus": "5.0.0", "timestamp": 1291954879, "messageid": "201012100421.oBA4LJFU042012@1jo.example.org", "diagnostictype": "SMTP", "timezoneoffset": "+0900", "reason": "filtered", "token": "ce999a4c869e3f5e4d8a77b2e310b23960fb32ab", "alias": "", "senderdomain": "1jo.example.org", "rhost": "mfsmax.example.jp"}, {"diagnostictype": "SMTP", "timezoneoffset": "+0900", "reason": "userunknown", "timestamp": 1381900535, "messageid": "E1C50F1B-1C83-4820-BC36-AC6FBFBE8568@example.org", "token": "9fe754876e9133aae5d20f0fd8dd7f05b4e9d9f0", "alias": "", "senderdomain": "example.org", "rhost": "mx.bouncehammer.jp", "action": "failed", "addresser": "kijitora@example.org", "recipient": "userunknown@bouncehammer.jp", "feedbacktype": "", "smtpcommand": "DATA", "subject": "バウンスメールのテスト(日本語)", "destination": "bouncehammer.jp", "listid": "", "diagnosticcode": "550 5.1.1 <userunknown@bouncehammer.jp>... User Unknown", "deliverystatus": "5.1.1", "lhost": "p0000-ipbfpfx00kyoto.kyoto.example.co.jp", "smtpagent": "Email::Sendmail"}]
230
+ [{"action": "failed", "subject": "Nyaan", "catch": null, "token": "08acf78323edc7923a783c04749dd547ab45c433", "alias": "", "messageid": "201806090556.w595u8GZ093276@neko.example.jp", "listid": "", "smtpcommand": "MAIL", "smtpagent": "Email::Sendmail", "lhost": "localhost", "timezoneoffset": "+0900", "feedbacktype": "", "senderdomain": "neko.example.jp", "diagnostictype": "SMTP", "softbounce": 1, "deliverystatus": "5.0.0", "addresser": "kijitora@neko.example.jp", "diagnosticcode": "550 Unauthenticated senders not allowed", "timestamp": 1528523769, "destination": "example.com", "recipient": "sironeko@example.com", "reason": "securityerror", "replycode": "550", "rhost": "neko.example.jp"}]
226
231
  ```
227
232
 
228
233
  Sisimai Specification
@@ -243,8 +248,8 @@ and bounceHammer are available at
243
248
  | The speed of parsing email(1000 emails) | 3.75s[2] | 1.70s |
244
249
  | How to install | gem install | cpanm, cpm |
245
250
  | Dependencies (Except core modules) | 1 module | 2 modules |
246
- | LOC:Source lines of code | 12000 lines | 8600 lines |
247
- | The number of tests(spec/,t/,xt/) directory | 217000 tests | 235000 tests |
251
+ | LOC:Source lines of code | 11700 lines | 8500 lines |
252
+ | The number of tests(spec/,t/,xt/) directory | 218000 tests | 236000 tests |
248
253
  | License | BSD 2-Clause | BSD 2-Clause |
249
254
  | Support Contract provided by Developer | Coming soon | Available |
250
255
 
data/lib/sisimai.rb CHANGED
@@ -26,20 +26,17 @@ module Sisimai
26
26
  def make(argv0, **argv1)
27
27
  return nil unless argv0
28
28
 
29
- require 'sisimai/data'
30
- require 'sisimai/message'
31
-
32
29
  input = argv1[:input] || nil
33
30
  field = argv1[:field] || []
34
31
  raise ' ***error: "field" accepts an array only' unless field.is_a? Array
35
32
 
36
33
  unless input
34
+ klass = argv0.class
37
35
  # "input" did not specified, try to detect automatically.
38
- if argv0.is_a?(::String) || argv0.is_a?(IO)
39
- # The argument may be a path to email
36
+ if klass == ::String || klass == IO
37
+ # The argument may be a path to email OR an email text
40
38
  input = 'email'
41
-
42
- elsif argv0.is_a?(Array) || argv0.is_a?(Hash)
39
+ elsif klass == Array || klass == Hash
43
40
  # The argument may be a decoded JSON object
44
41
  input = 'json'
45
42
  end
@@ -49,6 +46,8 @@ module Sisimai
49
46
  hookmethod = argv1[:hook] || nil
50
47
  bouncedata = []
51
48
 
49
+ require 'sisimai/data'
50
+ require 'sisimai/message'
52
51
  if input == 'email'
53
52
  # Path to mailbox or Maildir/, or STDIN: 'input' => 'email'
54
53
  require 'sisimai/mail'
@@ -64,7 +63,7 @@ module Sisimai
64
63
  methodargv = { data: mesg, hook: hookmethod, input: 'email', delivered: delivered1 }
65
64
  data = Sisimai::Data.make(methodargv)
66
65
  next unless data
67
- bouncedata.concat(data) if data.size > 0
66
+ bouncedata += data unless data.empty?
68
67
  end
69
68
 
70
69
  elsif input == 'json'
@@ -90,14 +89,14 @@ module Sisimai
90
89
  data = Sisimai::Data.make(methodargv)
91
90
 
92
91
  next unless data
93
- bouncedata.concat(data) if data.size > 0
92
+ bouncedata += data unless data.empty?
94
93
  end
95
94
  else
96
95
  # The value of "input" neither "email" nor "json"
97
96
  raise ' ***error: invalid value of "input"'
98
97
  end
99
98
 
100
- return nil if bouncedata.size.zero?
99
+ return nil if bouncedata.empty?
101
100
  return bouncedata
102
101
  end
103
102
 
@@ -159,8 +158,8 @@ module Sisimai
159
158
  names = Sisimai::Reason.index
160
159
 
161
160
  # These reasons are not included in the results of Sisimai::Reason.index
162
- names.concat(%w[Delivered Feedback Undefined Vacation])
163
- names.each do |e|
161
+ names += %w[Delivered Feedback Undefined Vacation]
162
+ while e = names.shift do
164
163
  # Call .description() method of Sisimai::Reason::*
165
164
  r = 'Sisimai::Reason::' << e
166
165
  require r.gsub('::', '/').downcase
@@ -8,7 +8,6 @@ module Sisimai
8
8
  :'quoted-string' => (1 << 1), # "Neko, Nyaan"
9
9
  :'comment-block' => (1 << 2), # (neko)
10
10
  }
11
-
12
11
  @@undisclosed = 'libsisimai.org.invalid'
13
12
 
14
13
  # Return pseudo recipient or sender address
@@ -67,7 +66,7 @@ module Sisimai
67
66
 
68
67
  while e = characters.shift do
69
68
  # Check each characters
70
- if %w[< > ( ) " ,].detect { |r| r == e }
69
+ if %w[< > ( ) " ,].any? { |r| r == e }
71
70
  # The character is a delimiter character
72
71
  if e == ','
73
72
  # Separator of email addresses or not
@@ -88,7 +87,7 @@ module Sisimai
88
87
  end
89
88
  else
90
89
  # "Neko, Nyaan" <neko@nyaan.example.org> OR <"neko,nyaan"@example.org>
91
- p.size > 0 ? (v[p] << e) : (v[:name] << e)
90
+ p.empty? ? (v[:name] << e) : (v[p] << e)
92
91
  end
93
92
  next
94
93
  end # End of if(',')
@@ -96,7 +95,7 @@ module Sisimai
96
95
  if e == '<'
97
96
  # <: The beginning of an email address or not
98
97
  if v[:address].size > 0
99
- p.size > 0 ? (v[p] << e) : (v[:name] << e)
98
+ p.empty? ? (v[:name] << e) : (v[p] << e)
100
99
  else
101
100
  # <neko@nyaan.example.org>
102
101
  readcursor |= Indicators[:'email-address']
@@ -116,7 +115,7 @@ module Sisimai
116
115
  p = ''
117
116
  else
118
117
  # a comment block or a display name
119
- p.size > 0 ? (v[:comment] << e) : (v[:name] << e)
118
+ p.empty? ? (v[:name] << e) : (v[:comment] << e)
120
119
  end
121
120
  next
122
121
  end # End of if('>')
@@ -201,7 +200,7 @@ module Sisimai
201
200
  end # End of if('"')
202
201
  else
203
202
  # The character is not a delimiter
204
- p.size > 0 ? (v[p] << e) : (v[:name] << e)
203
+ p.empty? ? (v[:name] << e) : (v[p] << e)
205
204
  next
206
205
  end
207
206
  end
@@ -220,7 +219,7 @@ module Sisimai
220
219
  v[:address] = v[:name]
221
220
  end
222
221
 
223
- if v[:address].size > 0
222
+ unless v[:address].empty?
224
223
  # Remove the comment from the address
225
224
  if cv = v[:address].match(/(.*)([(].+[)])(.*)/)
226
225
  # (nyaan)nekochan@example.org, nekochan(nyaan)cat@example.org or
@@ -243,15 +242,9 @@ module Sisimai
243
242
 
244
243
  # Remove angle brackets, other brackets, and quotations: []<>{}'`
245
244
  # except a domain part is an IP address like neko@[192.0.2.222]
246
- e[:address] = e[:address].sub(/\A[\[<{('`]/, '')
247
- e[:address] = e[:address].sub(/['`>})]\z/, '')
248
- e[:address] = e[:address].chomp(']') unless e[:address] =~ /[@]\[[0-9A-Za-z:\.]+\]\z/
249
-
250
- unless e[:address] =~ /\A["].+["][@]/
251
- # Remove double-quotations
252
- e[:address] = e[:address].sub(/\A["]/, '')
253
- e[:address] = e[:address].chomp('"')
254
- end
245
+ e[:address] = e[:address].sub(/\A[\[<{('`]/, '').sub(/['`>})]\z/, '')
246
+ e[:address].chomp!(']') unless e[:address] =~ /[@]\[[0-9A-Za-z:\.]+\]\z/
247
+ e[:address] = e[:address].sub(/\A["]/, '').chomp('"') unless e[:address] =~ /\A["].+["][@]/
255
248
 
256
249
  if addrs
257
250
  # Almost compatible with parse() method, returns email address only
@@ -259,14 +252,11 @@ module Sisimai
259
252
  e.delete(:comment)
260
253
  else
261
254
  # Remove double-quotations, trailing spaces.
262
- [:name, :comment].each do |f|
263
- e[f] = e[f].strip
264
- end
255
+ [:name, :comment].each { |f| e[f].strip! }
265
256
  e[:comment] = '' unless e[:comment] =~ /\A[(].+[)]/
266
-
267
- e[:name] = e[:name].squeeze(' ') unless e[:name] =~ /\A["].+["]\z/
268
- e[:name] = e[:name].sub(/\A["]/, '') unless e[:name] =~ /\A["].+["][@]/
269
- e[:name] = e[:name].chomp('"')
257
+ e[:name].squeeze!(' ') unless e[:name] =~ /\A["].+["]\z/
258
+ e[:name].sub!(/\A["]/, '') unless e[:name] =~ /\A["].+["][@]/
259
+ e[:name].chomp!('"')
270
260
  end
271
261
  addrtables << e
272
262
  end
data/lib/sisimai/arf.rb CHANGED
@@ -4,7 +4,6 @@ module Sisimai
4
4
  # Imported from p5-Sisimail/lib/Sisimai/ARF.pm
5
5
  class << self
6
6
  require 'sisimai/bite/email'
7
- require 'sisimai/rfc5322'
8
7
 
9
8
  # http://tools.ietf.org/html/rfc5965
10
9
  # http://en.wikipedia.org/wiki/Feedback_loop_(email)
@@ -50,9 +49,9 @@ module Sisimai
50
49
  # Microsoft (Hotmail, MSN, Live, Outlook) uses its own report format.
51
50
  # Amazon SES Complaints bounces
52
51
  mfrom = %r{(?:
53
- staff[@]hotmail[.]com\z
54
- |complaints[@]email-abuse[.]amazonses[.]com\z
55
- )
52
+ staff[@]hotmail[.]com
53
+ |complaints[@]email-abuse[.]amazonses[.]com
54
+ )\z
56
55
  }x
57
56
  if heads['from'] =~ mfrom && heads['subject'].include?('complaint about message from ')
58
57
  # From: staff@hotmail.com
@@ -78,7 +77,6 @@ module Sisimai
78
77
  def scan(mhead, mbody)
79
78
  return nil unless self.is_arf(mhead)
80
79
 
81
- require 'sisimai/address'
82
80
  dscontents = [Sisimai::Bite.DELIVERYSTATUS]
83
81
  hasdivided = mbody.split("\n")
84
82
  rfc822part = '' # (String) message/rfc822-headers part
@@ -121,7 +119,7 @@ module Sisimai
121
119
  # this specification is set to "1".
122
120
  #
123
121
  while e = hasdivided.shift do
124
- if readcursor.zero?
122
+ if readcursor == 0
125
123
  # Beginning of the bounce message or delivery status part
126
124
  if e =~ MarkingsOf[:message]
127
125
  readcursor |= Indicators[:deliverystatus]
@@ -129,7 +127,7 @@ module Sisimai
129
127
  end
130
128
  end
131
129
 
132
- if (readcursor & Indicators[:'message-rfc822']).zero?
130
+ if (readcursor & Indicators[:'message-rfc822']) == 0
133
131
  # Beginning of the original message part
134
132
  if e.start_with?(StartingOf[:rfc822][0], StartingOf[:rfc822][1])
135
133
  readcursor |= Indicators[:'message-rfc822']
@@ -169,13 +167,13 @@ module Sisimai
169
167
  elsif e.start_with?(' ', "\t")
170
168
  # Continued line from the previous line
171
169
  rfc822part << e + "\n" if LongFields.key?(previousfn)
172
- next if e.size > 0
170
+ next unless e.empty?
173
171
  rcptintext << e if previousfn == 'to'
174
172
  end
175
173
  else
176
174
  # Before "message/rfc822"
177
175
  next unless readcursor & Indicators[:deliverystatus] > 0
178
- next unless e.size > 0
176
+ next if e.empty?
179
177
 
180
178
  # Feedback-Type: abuse
181
179
  # User-Agent: SomeGenerator/1.0
@@ -255,7 +253,7 @@ module Sisimai
255
253
  commondata[:diagnosis] << ' ' << arfheaders[:authres]
256
254
  end
257
255
 
258
- if recipients.zero?
256
+ unless recipients > 0
259
257
  # Insert pseudo recipient address when there is no valid recipient
260
258
  # address in the message.
261
259
  dscontents[-1]['recipient'] = Sisimai::Address.undisclosed(:r)
@@ -265,7 +263,7 @@ module Sisimai
265
263
  unless rfc822part =~ /\bFrom: [^ ]+[@][^ ]+\b/
266
264
  # There is no "From:" header in the original message
267
265
  # Append the value of "Original-Mail-From" value as a sender address.
268
- rfc822part << 'From: ' << commondata[:from] + "\n" if commondata[:from].size > 0
266
+ rfc822part << 'From: ' << commondata[:from] + "\n" unless commondata[:from].empty?
269
267
  end
270
268
 
271
269
  if cv = mhead['subject'].match(/complaint about message from (\d{1,3}[.]\d{1,3}[.]\d{1,3}[.]\d{1,3})/)
@@ -275,7 +273,7 @@ module Sisimai
275
273
  'This is a Microsoft email abuse report for an email message received from IP' << arfheaders[:rhost] + ' on ' << mhead['date']
276
274
  end
277
275
 
278
- dscontents.map do |e|
276
+ dscontents.each do |e|
279
277
  if e['recipient'] =~ /\A[^ ]+[@]\z/
280
278
  # AOL = http://forums.cpanel.net/f43/aol-brutal-work-71473.html
281
279
  e['recipient'] = Sisimai::Address.s3s4(rcptintext)
@@ -29,9 +29,6 @@ module Sisimai::Bite::Email
29
29
  # part or nil if it failed to parse or
30
30
  # the arguments are missing
31
31
  def scan(mhead, mbody)
32
- return nil unless mhead
33
- return nil unless mbody
34
-
35
32
  # :from => %r/\A"MAILER-DAEMON"/,
36
33
  # :subject => %r/FAILURE NOTICE :/,
37
34
  return nil unless mhead['x-ahmailid']
@@ -45,7 +42,7 @@ module Sisimai::Bite::Email
45
42
  v = nil
46
43
 
47
44
  while e = hasdivided.shift do
48
- if readcursor.zero?
45
+ if readcursor == 0
49
46
  # Beginning of the bounce message or delivery status part
50
47
  if e == StartingOf[:message][0]
51
48
  readcursor |= Indicators[:deliverystatus]
@@ -53,7 +50,7 @@ module Sisimai::Bite::Email
53
50
  end
54
51
  end
55
52
 
56
- if (readcursor & Indicators[:'message-rfc822']).zero?
53
+ if (readcursor & Indicators[:'message-rfc822']) == 0
57
54
  # Beginning of the original message part
58
55
  if e == StartingOf[:rfc822][0]
59
56
  readcursor |= Indicators[:'message-rfc822']
@@ -71,7 +68,7 @@ module Sisimai::Bite::Email
71
68
  rfc822list << e
72
69
  else
73
70
  # Before "message/rfc822"
74
- next if (readcursor & Indicators[:deliverystatus]).zero?
71
+ next if (readcursor & Indicators[:deliverystatus]) == 0
75
72
  next if e.empty?
76
73
 
77
74
  # ----- The following addresses had permanent fatal errors -----
@@ -100,10 +97,9 @@ module Sisimai::Bite::Email
100
97
  end
101
98
  end
102
99
  end
103
- return nil if recipients.zero?
100
+ return nil unless recipients > 0
104
101
 
105
- require 'sisimai/string'
106
- dscontents.map do |e|
102
+ dscontents.each do |e|
107
103
  e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
108
104
  e['agent'] = self.smtpagent
109
105
  e.each_key { |a| e[a] ||= '' }
@@ -36,9 +36,6 @@ module Sisimai::Bite::Email
36
36
  # part or nil if it failed to parse or
37
37
  # the arguments are missing
38
38
  def scan(mhead, mbody)
39
- return nil unless mhead
40
- return nil unless mbody
41
-
42
39
  # :from => %r/\AMAILER-DAEMON[@]email[-]bounces[.]amazonses[.]com\z/,
43
40
  # :subject => %r/\ADelivery Status Notification [(]Failure[)]\z/,
44
41
  return nil if mhead['x-mailer'].to_s.start_with?('Amazon WorkMail')
@@ -46,7 +43,7 @@ module Sisimai::Bite::Email
46
43
  match = 0
47
44
  match += 1 if mhead['x-aws-outgoing']
48
45
  match += 1 if mhead['x-ses-outgoing']
49
- return nil if match.zero?
46
+ return nil unless match > 0
50
47
 
51
48
  dscontents = [Sisimai::Bite.DELIVERYSTATUS]
52
49
  hasdivided = mbody.split("\n")
@@ -66,7 +63,7 @@ module Sisimai::Bite::Email
66
63
  havepassed << e
67
64
  p = havepassed[-2]
68
65
 
69
- if readcursor.zero?
66
+ if readcursor == 0
70
67
  # Beginning of the bounce message or delivery status part
71
68
  if e.start_with?(StartingOf[:message][0], StartingOf[:message][1])
72
69
  readcursor |= Indicators[:deliverystatus]
@@ -74,7 +71,7 @@ module Sisimai::Bite::Email
74
71
  end
75
72
  end
76
73
 
77
- if (readcursor & Indicators[:'message-rfc822']).zero?
74
+ if (readcursor & Indicators[:'message-rfc822']) == 0
78
75
  # Beginning of the original message part
79
76
  if e == StartingOf[:rfc822][0]
80
77
  readcursor |= Indicators[:'message-rfc822']
@@ -93,7 +90,7 @@ module Sisimai::Bite::Email
93
90
  rfc822list << e
94
91
  else
95
92
  # Before "message/rfc822"
96
- next if (readcursor & Indicators[:deliverystatus]).zero?
93
+ next if (readcursor & Indicators[:deliverystatus]) == 0
97
94
  next if e.empty?
98
95
 
99
96
  if connvalues == connheader.keys.size
@@ -165,7 +162,7 @@ module Sisimai::Bite::Email
165
162
  #
166
163
  if cv = e.match(/\AReporting-MTA:[ ]*[DNSdns]+;[ ]*(.+)\z/)
167
164
  # Reporting-MTA: dns; mx.example.jp
168
- next if connheader['lhost'].size > 0
165
+ next unless connheader['lhost'].empty?
169
166
  connheader['lhost'] = cv[1].downcase
170
167
  connvalues += 1
171
168
  end
@@ -174,7 +171,7 @@ module Sisimai::Bite::Email
174
171
  end
175
172
  end
176
173
 
177
- if recipients.zero? && mbody =~ /notificationType/
174
+ if recipients == 0 && mbody =~ /notificationType/
178
175
  # Try to parse with Sisimai::Bite::JSON::AmazonSES module
179
176
  require 'sisimai/bite/json/amazonses'
180
177
  j = Sisimai::Bite::JSON::AmazonSES.scan(mhead, mbody)
@@ -185,17 +182,14 @@ module Sisimai::Bite::Email
185
182
  recipients = j['ds'].size
186
183
  end
187
184
  end
188
- return nil if recipients.zero?
185
+ return nil unless recipients > 0
189
186
 
190
- require 'sisimai/string'
191
- require 'sisimai/smtp/status'
192
- dscontents.map do |e|
187
+ dscontents.each do |e|
193
188
  # Set default values if each value is empty.
194
189
  connheader.each_key { |a| e[a] ||= connheader[a] || '' }
195
190
 
196
- e['agent'] = self.smtpagent
197
- e['diagnosis'] = e['diagnosis'].to_s.gsub(/\\n/, ' ')
198
- e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
191
+ e['agent'] = self.smtpagent
192
+ e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'].to_s.gsub(/\\n/, ' '))
199
193
 
200
194
  if e['status'].to_s.start_with?('5.0.0', '5.1.0', '4.0.0', '4.1.0')
201
195
  # Get other D.S.N. value from the error message
@@ -206,12 +200,12 @@ module Sisimai::Bite::Email
206
200
  errormessage = cv[1]
207
201
  end
208
202
  pseudostatus = Sisimai::SMTP::Status.find(errormessage)
209
- e['status'] = pseudostatus if pseudostatus.size > 0
203
+ e['status'] = pseudostatus unless pseudostatus.empty?
210
204
  end
211
205
 
212
206
  MessagesOf.each_key do |r|
213
207
  # Verify each regular expression of session errors
214
- next unless MessagesOf[r].find { |a| e['diagnosis'].include?(a) }
208
+ next unless MessagesOf[r].any? { |a| e['diagnosis'].include?(a) }
215
209
  e['reason'] = r.to_s
216
210
  break
217
211
  end