sisimai 4.25.17-java → 5.0.0-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.
- checksums.yaml +5 -5
- data/.travis.yml +3 -3
- data/ANALYTICAL-PRECISION +2 -2
- data/Benchmarks.mk +3 -3
- data/CONTRIBUTING +1 -1
- data/ChangeLog.md +406 -407
- data/Developers.mk +5 -6
- data/Gemfile +1 -1
- data/Makefile +12 -12
- data/README-JA.md +142 -94
- data/README.md +282 -150
- data/Rakefile +9 -3
- data/Repository.mk +2 -3
- data/lib/sisimai/address.rb +118 -74
- data/lib/sisimai/arf.rb +84 -82
- data/lib/sisimai/datetime.rb +5 -52
- data/lib/sisimai/{data → fact}/json.rb +7 -9
- data/lib/sisimai/fact/yaml.rb +31 -0
- data/lib/sisimai/fact.rb +468 -0
- data/lib/sisimai/lhost/activehunter.rb +12 -14
- data/lib/sisimai/lhost/amavis.rb +11 -14
- data/lib/sisimai/lhost/amazonses.rb +37 -41
- data/lib/sisimai/lhost/amazonworkmail.rb +15 -18
- data/lib/sisimai/lhost/aol.rb +12 -14
- data/lib/sisimai/lhost/apachejames.rb +19 -21
- data/lib/sisimai/lhost/barracuda.rb +10 -12
- data/lib/sisimai/lhost/bigfoot.rb +21 -21
- data/lib/sisimai/lhost/biglobe.rb +15 -16
- data/lib/sisimai/lhost/courier.rb +20 -20
- data/lib/sisimai/lhost/domino.rb +23 -19
- data/lib/sisimai/lhost/einsundeins.rb +20 -16
- data/lib/sisimai/lhost/exchange2003.rb +30 -29
- data/lib/sisimai/lhost/exchange2007.rb +70 -58
- data/lib/sisimai/lhost/exim.rb +175 -161
- data/lib/sisimai/lhost/ezweb.rb +31 -56
- data/lib/sisimai/lhost/facebook.rb +21 -33
- data/lib/sisimai/lhost/fml.rb +43 -48
- data/lib/sisimai/lhost/gmail.rb +29 -29
- data/lib/sisimai/lhost/gmx.rb +18 -17
- data/lib/sisimai/lhost/googlegroups.rb +9 -10
- data/lib/sisimai/lhost/gsuite.rb +21 -27
- data/lib/sisimai/lhost/imailserver.rb +25 -39
- data/lib/sisimai/lhost/interscanmss.rb +28 -31
- data/lib/sisimai/lhost/kddi.rb +22 -28
- data/lib/sisimai/lhost/mailfoundry.rb +11 -12
- data/lib/sisimai/lhost/mailmarshalsmtp.rb +25 -29
- data/lib/sisimai/lhost/mailru.rb +33 -27
- data/lib/sisimai/lhost/mcafee.rb +21 -31
- data/lib/sisimai/lhost/messagelabs.rb +17 -20
- data/lib/sisimai/lhost/messagingserver.rb +40 -37
- data/lib/sisimai/lhost/mfilter.rb +15 -16
- data/lib/sisimai/lhost/mxlogic.rb +24 -23
- data/lib/sisimai/lhost/notes.rb +17 -17
- data/lib/sisimai/lhost/office365.rb +63 -27
- data/lib/sisimai/lhost/opensmtpd.rb +12 -13
- data/lib/sisimai/lhost/outlook.rb +12 -15
- data/lib/sisimai/lhost/postfix.rb +179 -129
- data/lib/sisimai/lhost/powermta.rb +12 -14
- data/lib/sisimai/lhost/qmail.rb +44 -47
- data/lib/sisimai/lhost/receivingses.rb +15 -20
- data/lib/sisimai/lhost/sendgrid.rb +34 -32
- data/lib/sisimai/lhost/sendmail.rb +66 -53
- data/lib/sisimai/lhost/surfcontrol.rb +19 -19
- data/lib/sisimai/lhost/v5sendmail.rb +45 -39
- data/lib/sisimai/lhost/verizon.rb +35 -39
- data/lib/sisimai/lhost/x1.rb +18 -17
- data/lib/sisimai/lhost/x2.rb +17 -14
- data/lib/sisimai/lhost/x3.rb +19 -19
- data/lib/sisimai/lhost/x4.rb +72 -57
- data/lib/sisimai/lhost/x5.rb +17 -19
- data/lib/sisimai/lhost/x6.rb +41 -17
- data/lib/sisimai/lhost/yahoo.rb +17 -16
- data/lib/sisimai/lhost/yandex.rb +16 -20
- data/lib/sisimai/lhost/zoho.rb +16 -15
- data/lib/sisimai/lhost.rb +8 -10
- data/lib/sisimai/mail/maildir.rb +1 -3
- data/lib/sisimai/mail/mbox.rb +3 -4
- data/lib/sisimai/mail/memory.rb +0 -1
- data/lib/sisimai/mail/stdin.rb +1 -3
- data/lib/sisimai/mail.rb +3 -7
- data/lib/sisimai/mda.rb +28 -42
- data/lib/sisimai/message.rb +435 -325
- data/lib/sisimai/order.rb +5 -5
- data/lib/sisimai/reason/authfailure.rb +64 -0
- data/lib/sisimai/reason/badreputation.rb +53 -0
- data/lib/sisimai/reason/blocked.rb +94 -160
- data/lib/sisimai/reason/contenterror.rb +8 -9
- data/lib/sisimai/reason/delivered.rb +4 -6
- data/lib/sisimai/reason/exceedlimit.rb +10 -12
- data/lib/sisimai/reason/expired.rb +6 -8
- data/lib/sisimai/reason/feedback.rb +2 -3
- data/lib/sisimai/reason/filtered.rb +17 -19
- data/lib/sisimai/reason/hasmoved.rb +9 -10
- data/lib/sisimai/reason/hostunknown.rb +15 -15
- data/lib/sisimai/reason/mailboxfull.rb +10 -12
- data/lib/sisimai/reason/mailererror.rb +18 -20
- data/lib/sisimai/reason/mesgtoobig.rb +9 -11
- data/lib/sisimai/reason/networkerror.rb +5 -8
- data/lib/sisimai/reason/norelaying.rb +8 -11
- data/lib/sisimai/reason/notaccept.rb +13 -14
- data/lib/sisimai/reason/notcompliantrfc.rb +43 -0
- data/lib/sisimai/reason/onhold.rb +6 -9
- data/lib/sisimai/reason/policyviolation.rb +14 -12
- data/lib/sisimai/reason/rejected.rb +26 -24
- data/lib/sisimai/reason/requireptr.rb +69 -0
- data/lib/sisimai/reason/securityerror.rb +33 -36
- data/lib/sisimai/reason/spamdetected.rb +114 -147
- data/lib/sisimai/reason/speeding.rb +49 -0
- data/lib/sisimai/reason/suspend.rb +11 -11
- data/lib/sisimai/reason/syntaxerror.rb +11 -10
- data/lib/sisimai/reason/systemerror.rb +7 -9
- data/lib/sisimai/reason/systemfull.rb +7 -8
- data/lib/sisimai/reason/toomanyconn.rb +9 -11
- data/lib/sisimai/reason/undefined.rb +2 -3
- data/lib/sisimai/reason/userunknown.rb +129 -146
- data/lib/sisimai/reason/vacation.rb +3 -4
- data/lib/sisimai/reason/virusdetected.rb +10 -11
- data/lib/sisimai/reason.rb +59 -64
- data/lib/sisimai/rfc1894.rb +55 -28
- data/lib/sisimai/rfc2045.rb +373 -0
- data/lib/sisimai/rfc3464.rb +250 -308
- data/lib/sisimai/rfc3834.rb +42 -45
- data/lib/sisimai/rfc5322.rb +75 -100
- data/lib/sisimai/rfc5965.rb +31 -0
- data/lib/sisimai/rhost/cox.rb +5 -6
- data/lib/sisimai/rhost/franceptt.rb +6 -8
- data/lib/sisimai/rhost/godaddy.rb +12 -12
- data/lib/sisimai/rhost/{googleapps.rb → google.rb} +80 -72
- data/lib/sisimai/rhost/iua.rb +9 -10
- data/lib/sisimai/rhost/kddi.rb +6 -8
- data/lib/sisimai/rhost/{exchangeonline.rb → microsoft.rb} +115 -114
- data/lib/sisimai/rhost/mimecast.rb +42 -40
- data/lib/sisimai/rhost/nttdocomo.rb +13 -18
- data/lib/sisimai/rhost/spectrum.rb +10 -12
- data/lib/sisimai/rhost/{tencentqq.rb → tencent.rb} +7 -8
- data/lib/sisimai/rhost.rb +23 -31
- data/lib/sisimai/smtp/command.rb +59 -0
- data/lib/sisimai/smtp/error.rb +4 -7
- data/lib/sisimai/smtp/reply.rb +161 -74
- data/lib/sisimai/smtp/status.rb +504 -393
- data/lib/sisimai/smtp/transcript.rb +124 -0
- data/lib/sisimai/smtp.rb +0 -1
- data/lib/sisimai/string.rb +74 -5
- data/lib/sisimai/time.rb +1 -2
- data/lib/sisimai/version.rb +1 -1
- data/lib/sisimai.rb +35 -21
- data/set-of-emails/maildir/bsd/lhost-domino-02.eml +6 -3
- data/set-of-emails/maildir/bsd/lhost-googlegroups-15.eml +174 -0
- data/set-of-emails/maildir/bsd/lhost-gsuite-15.eml +229 -0
- data/set-of-emails/maildir/bsd/lhost-postfix-75.eml +51 -0
- data/set-of-emails/maildir/bsd/lhost-postfix-76.eml +101 -0
- data/set-of-emails/maildir/bsd/lhost-postfix-77.eml +74 -0
- data/set-of-emails/maildir/bsd/lhost-postfix-78.eml +91 -0
- data/set-of-emails/maildir/bsd/lhost-receivingses-08.eml +88 -0
- data/set-of-emails/maildir/bsd/rfc3464-43.eml +88 -0
- data/set-of-emails/maildir/bsd/rhost-google-03.eml +101 -0
- data/set-of-emails/maildir/bsd/rhost-google-04.eml +102 -0
- data/set-of-emails/maildir/bsd/rhost-google-05.eml +82 -0
- data/set-of-emails/maildir/bsd/rhost-google-06.eml +102 -0
- data/set-of-emails/maildir/bsd/rhost-google-07.eml +69 -0
- data/set-of-emails/maildir/bsd/rhost-google-08.eml +99 -0
- data/sisimai-java.gemspec +1 -1
- data/sisimai.gemspec +1 -1
- metadata +42 -23
- data/.rspec +0 -2
- data/lib/sisimai/data/yaml.rb +0 -33
- data/lib/sisimai/data.rb +0 -411
- data/lib/sisimai/mime.rb +0 -456
- data/set-of-emails/maildir/mac/reported-from-nick4tech-san-01.eml +0 -6
- /data/set-of-emails/maildir/bsd/{rfc3464-41.eml → rfc3834-05.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-googleapps-01.eml → rhost-google-01.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-googleapps-02.eml → rhost-google-02.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-01.eml → rhost-microsoft-01.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-02.eml → rhost-microsoft-02.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-03.eml → rhost-microsoft-03.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-tencentqq-01.eml → rhost-tencent-01.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-tencentqq-02.eml → rhost-tencent-02.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-tencentqq-03.eml → rhost-tencent-03.eml} +0 -0
@@ -0,0 +1,124 @@
|
|
1
|
+
module Sisimai
|
2
|
+
module SMTP
|
3
|
+
# Sisimai::SMTP::Transcript is a parser for transcript logs of SMTP session
|
4
|
+
module Transcript
|
5
|
+
class << self
|
6
|
+
require 'sisimai/smtp/reply'
|
7
|
+
require 'sisimai/smtp/status'
|
8
|
+
|
9
|
+
# Parse a transcript of an SMTP session and makes structured data
|
10
|
+
# @param [String] argv0 A transcript text MTA returned
|
11
|
+
# @param [String] argv1 A label string of a SMTP client
|
12
|
+
# @apram [String] argv2 A label string of a SMTP server
|
13
|
+
# @return [Array] Structured data
|
14
|
+
# [Nil] Failed to parse or the 1st argument is missing
|
15
|
+
# @since v5.0.0
|
16
|
+
def rise(argv0 = '', argv1 = '>>>', argv2 = '<<<')
|
17
|
+
return nil if argv0.size == 0
|
18
|
+
|
19
|
+
# 1. Replace label strings of SMTP client/server at the each line
|
20
|
+
argv0.gsub!(/^[ ]+#{argv1}\s+/m, '>>> '); return nil unless argv0.include?('>>> ')
|
21
|
+
argv0.gsub!(/^[ ]+#{argv2}\s+/m, '<<< '); return nil unless argv0.include?('<<< ')
|
22
|
+
|
23
|
+
# 2. Remove strings until the first '<<<' or '>>>'
|
24
|
+
esmtp = []
|
25
|
+
table = lambda do
|
26
|
+
return {
|
27
|
+
'command' => nil, # SMTP command
|
28
|
+
'argument' => '', # An argument of each SMTP command sent from a client
|
29
|
+
'parameter' => {}, # Parameter pairs of the SMTP command
|
30
|
+
'response' => { # A Response from an SMTP server
|
31
|
+
'reply' => '', # - SMTP reply code such as 550
|
32
|
+
'status' => '', # - SMTP status such as 5.1.1
|
33
|
+
'text' => [], # - Response text lines
|
34
|
+
}
|
35
|
+
}
|
36
|
+
end
|
37
|
+
parameters = '' # Command parameters of MAIL, RCPT
|
38
|
+
cursession = nil # Current session for $esmtp
|
39
|
+
|
40
|
+
cv = ''
|
41
|
+
p0 = argv0.index('<<<') || -1 # Server response
|
42
|
+
p1 = argv0.index('>>>') || -1 # Sent command
|
43
|
+
if p0 < p1
|
44
|
+
# An SMTP server response starting with '<<<' is the first
|
45
|
+
esmtp << table.call
|
46
|
+
cursession = esmtp[-1]
|
47
|
+
cursession['command'] = 'CONN'
|
48
|
+
argv0 = argv0[p0, argv0.size] if p0 > -1
|
49
|
+
else
|
50
|
+
# An SMTP command starting with '>>>' is the first
|
51
|
+
argv0 = argv0[p1, argv0.size] if p1 > -1
|
52
|
+
end
|
53
|
+
|
54
|
+
# 3. Remove unused lines, concatenate folded lines
|
55
|
+
argv0 = argv0[0, argv0.index("\n\n") - 1] # Remove strings from the first blank line to the tail
|
56
|
+
argv0.gsub!(/\n[ ]+/m, ' ') # Concatenate folded lines to each previous line
|
57
|
+
|
58
|
+
argv0.split("\n").each do |e|
|
59
|
+
# 4. Read each SMTP command and server response
|
60
|
+
if e.start_with?('>>> ')
|
61
|
+
# SMTP client sent a command ">>> SMTP-command arguments"
|
62
|
+
if cv = e.match(/\A>>>[ ]([A-Z]+)[ ]?(.*)\z/)
|
63
|
+
# >>> SMTP Command
|
64
|
+
thecommand = cv[1]
|
65
|
+
commandarg = cv[2]
|
66
|
+
|
67
|
+
esmtp << table.call
|
68
|
+
cursession = esmtp[-1]
|
69
|
+
cursession['command'] = thecommand.upcase
|
70
|
+
|
71
|
+
if thecommand =~ /\A(?:MAIL|RCPT|XFORWARD)/
|
72
|
+
# MAIL or RCPT
|
73
|
+
if cv = commandarg.match(/\A(?:FROM|TO):[ ]*<(.+[@].+)>[ ]*(.*)\z/)
|
74
|
+
# >>> MAIL FROM: <neko@example.com> SIZE=65535
|
75
|
+
# >>> RCPT TO: <kijitora@example.org>
|
76
|
+
cursession['argument'] = cv[1]
|
77
|
+
parameters = cv[2]
|
78
|
+
|
79
|
+
else
|
80
|
+
# >>> XFORWARD NAME=neko2-nyaan3.y.example.co.jp ADDR=230.0.113.2 PORT=53672
|
81
|
+
# <<< 250 2.0.0 Ok
|
82
|
+
# >>> XFORWARD PROTO=SMTP HELO=neko2-nyaan3.y.example.co.jp IDENT=2LYC6642BLzFK3MM SOURCE=REMOTE
|
83
|
+
# <<< 250 2.0.0 Ok
|
84
|
+
parameters = commandarg
|
85
|
+
commandarg = ''
|
86
|
+
end
|
87
|
+
|
88
|
+
parameters.split(" ").each do |p|
|
89
|
+
# SIZE=22022, PROTO=SMTP, and so on
|
90
|
+
if cv = p.match(/\A([^ =]+)=([^ =]+)\z/) then cursession['parameter'][cv[1].downcase] = cv[2] end
|
91
|
+
end
|
92
|
+
else
|
93
|
+
# HELO, EHLO, AUTH, DATA, QUIT or Other SMTP command
|
94
|
+
cursession['argument'] = commandarg
|
95
|
+
end
|
96
|
+
end
|
97
|
+
else
|
98
|
+
# SMTP server sent a response "<<< response text"
|
99
|
+
p = e.index('<<< '); next unless p == 0
|
100
|
+
|
101
|
+
e = e[4, e.size]
|
102
|
+
|
103
|
+
e.sub!(/\A<<<[ ]/, '')
|
104
|
+
if cv = e.match(/\A([2-5]\d\d)[ ]/) then cursession['response']['reply'] = cv[1] end
|
105
|
+
if cv = e.match(/\A[245]\d\d[ ]([245][.]\d{1,3}[.]\d{1,3})[ ]/) then cursession['response']['status'] = cv[1] end
|
106
|
+
cursession['response']['text'] << e
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
return nil if esmtp.size == 0
|
111
|
+
return esmtp
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
|
116
|
+
|
117
|
+
|
118
|
+
|
119
|
+
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
data/lib/sisimai/smtp.rb
CHANGED
data/lib/sisimai/string.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
module Sisimai
|
2
2
|
# Sisimai::String provide utilities for dealing string
|
3
3
|
module String
|
4
|
-
# Imported from p5-Sisimail/lib/Sisimai/String.pm
|
5
4
|
class << self
|
6
5
|
Match = {
|
7
6
|
html: %r|<html[ >].+?</html>|im,
|
@@ -47,11 +46,81 @@ module Sisimai
|
|
47
46
|
# sweep(' neko ') #=> 'neko'
|
48
47
|
def sweep(argv1)
|
49
48
|
return argv1 unless argv1.is_a?(::String)
|
50
|
-
argv1 = argv1.chomp.squeeze(' ').
|
51
|
-
argv1 = argv1.sub(/ [-]{2,}[^
|
49
|
+
argv1 = argv1.chomp.squeeze(' ').strip
|
50
|
+
argv1 = argv1.sub(/ [-]{2,}[^ ].+\z/, '')
|
52
51
|
return argv1
|
53
52
|
end
|
54
53
|
|
54
|
+
# Check if each element of the 2nd argument is aligned in the 1st argument or not
|
55
|
+
# @param [String] argv1 String to be checked
|
56
|
+
# @param [Array] argv2 List including the ordered strings
|
57
|
+
# @return [Bool] 0, 1
|
58
|
+
# @since v5.0.0
|
59
|
+
def aligned(argv1, argv2)
|
60
|
+
return nil if argv1.to_s.empty?
|
61
|
+
return nil unless argv2.is_a? Array
|
62
|
+
return nil unless argv2.size > 1
|
63
|
+
|
64
|
+
align = -1
|
65
|
+
right = 0
|
66
|
+
argv2.each do |e|
|
67
|
+
# Get the position of each element in the 1st argument using index()
|
68
|
+
p = argv1.index(e, align + 1)
|
69
|
+
break unless p # Break this loop when there is no string in the 1st argument
|
70
|
+
align = e.length + p - 1 # There is an aligned string in the 1st argument
|
71
|
+
right += 1
|
72
|
+
end
|
73
|
+
|
74
|
+
return true if right == argv2.size
|
75
|
+
return false
|
76
|
+
end
|
77
|
+
|
78
|
+
# Find an IPv4 address from the given string
|
79
|
+
# @param [String] argv1 String including an IPv4 address
|
80
|
+
# @return [Array] List of IPv4 addresses
|
81
|
+
# @since v5.0.0
|
82
|
+
def ipv4(argv0)
|
83
|
+
return nil if argv0.to_s.empty?
|
84
|
+
return [] if argv0.size < 7
|
85
|
+
|
86
|
+
ipv4a = []
|
87
|
+
%w|( ) [ ]|.each do |e|
|
88
|
+
# Rewrite: "mx.example.jp[192.0.2.1]" => "mx.example.jp 192.0.2.1"
|
89
|
+
p0 = argv0.index(e); next unless p0
|
90
|
+
argv0[p0, 1] = ' '
|
91
|
+
end
|
92
|
+
|
93
|
+
argv0.split(' ').each do |e|
|
94
|
+
# Find string including an IPv4 address
|
95
|
+
next unless e.index('.') # IPv4 address must include "." character
|
96
|
+
|
97
|
+
lx = e.size; next if lx < 7 || lx > 17 # 0.0.0.0 = 7, [255.255.255.255] = 17
|
98
|
+
cu = 0 # Cursor for seeking each octet of an IPv4 address
|
99
|
+
as = '' # ASCII Code of each character
|
100
|
+
eo = '' # Buffer of each octet of IPv4 Address
|
101
|
+
|
102
|
+
while cu < lx
|
103
|
+
# Check whether each character is a number or "." or not
|
104
|
+
as = e[cu, 1].ord
|
105
|
+
cu += 1
|
106
|
+
|
107
|
+
if as < 48 || as > 57
|
108
|
+
# The character is not a number(0-9)
|
109
|
+
break if as != 46 # The character is not "."
|
110
|
+
next if eo == '' # The current buffer is empty
|
111
|
+
break if eo.to_i > 255 # The current buffer is greater than 255
|
112
|
+
eo = ''
|
113
|
+
next
|
114
|
+
end
|
115
|
+
eo << as.chr
|
116
|
+
break if eo.to_i > 255
|
117
|
+
end
|
118
|
+
ipv4a << e if eo.size > 0 && eo.to_i < 256
|
119
|
+
end
|
120
|
+
|
121
|
+
return ipv4a
|
122
|
+
end
|
123
|
+
|
55
124
|
# Convert given HTML text to plain text
|
56
125
|
# @param [String] argv1 HTML text
|
57
126
|
# @param [Boolean] loose Loose check flag
|
@@ -66,8 +135,8 @@ module Sisimai
|
|
66
135
|
# 3. <a href = 'http://...'>...</a> to " http://... "
|
67
136
|
# 4. <a href = 'mailto:...'>...</a> to " Value <mailto:...> "
|
68
137
|
plain.scrub!('?')
|
69
|
-
plain.gsub!(%r|<head
|
70
|
-
plain.gsub!(%r|<style
|
138
|
+
plain.gsub!(%r|<head>.+</head>|im, '')
|
139
|
+
plain.gsub!(%r|<style.+?>.+</style>|im, '')
|
71
140
|
plain.gsub!(%r|<a\s+href\s*=\s*['"](https?://.+?)['"].*?>(.*?)</a>|i, '[\2](\1)')
|
72
141
|
plain.gsub!(%r|<a\s+href\s*=\s*["']mailto:([^\s]+?)["']>(.*?)</a>|i, '[\2](mailto:\1)')
|
73
142
|
|
data/lib/sisimai/time.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
require 'date'
|
2
2
|
module Sisimai
|
3
|
-
# Sisimai::Time is a child class of Date for Sisimai::
|
3
|
+
# Sisimai::Time is a child class of Date for Sisimai::Fact
|
4
4
|
class Time < ::DateTime
|
5
|
-
# Imported from p5-Sisimail/lib/Sisimai/Time.pm
|
6
5
|
def to_json(*)
|
7
6
|
return self.to_time.to_i
|
8
7
|
end
|
data/lib/sisimai/version.rb
CHANGED
data/lib/sisimai.rb
CHANGED
@@ -1,46 +1,59 @@
|
|
1
|
-
# Sisimai is
|
2
|
-
#
|
3
|
-
# also available if "YAML" module is installed on your system) from parsed bounce
|
4
|
-
# messages. Sisimai is a coined word: Sisi (the number 4 is pronounced "Si" in
|
5
|
-
# Japanese) and MAI (acronym of "Mail Analyzing Interface").
|
1
|
+
# Sisimai is a Ruby module for analyzing RFC5322 bounce emails and generating structured data from
|
2
|
+
# parsed results.
|
6
3
|
require 'sisimai/version'
|
7
4
|
module Sisimai
|
8
|
-
# Imported from p5-Sisimail/lib/Sisimai.pm
|
9
5
|
class << self
|
10
6
|
def version(); return Sisimai::VERSION; end
|
11
|
-
def sysname(); return 'bouncehammer'; end
|
12
7
|
def libname(); return 'Sisimai'; end
|
13
8
|
|
9
|
+
# Emulate "rise" method for the backward compatible
|
10
|
+
def make(argv0, **argv1)
|
11
|
+
warn ' ***warning: Sisimai.make will be removed at v5.1.0. Use Sisimai.rise instead';
|
12
|
+
return Sisimai.rise(argv0, **argv1)
|
13
|
+
end
|
14
|
+
|
14
15
|
# Wrapper method for parsing mailbox/maidir
|
15
16
|
# @param [String] argv0 Path to mbox or Maildir/
|
16
17
|
# @param [Hash] argv0 or Hash (decoded JSON)
|
17
18
|
# @param [IO] argv0 or STDIN object
|
18
19
|
# @param [Hash] argv1 Parser options(delivered=false)
|
19
20
|
# @options argv1 [Boolean] delivered true: Include "delivered" reason
|
20
|
-
# @options argv1 [
|
21
|
+
# @options argv1 [Boolean] vacation true: Include "vacation" reason
|
22
|
+
# @options argv1 [Array] c___ Proc object to a callback method for the message and each file
|
21
23
|
# @return [Array] Parsed objects
|
22
24
|
# @return [nil] nil if the argument was wrong or an empty array
|
23
|
-
def
|
25
|
+
def rise(argv0, **argv1)
|
24
26
|
return nil unless argv0
|
25
|
-
require 'sisimai/data'
|
26
|
-
require 'sisimai/message'
|
27
27
|
require 'sisimai/mail'
|
28
|
+
require 'sisimai/fact'
|
28
29
|
|
29
|
-
list = []
|
30
30
|
return nil unless mail = Sisimai::Mail.new(argv0)
|
31
|
+
kind = mail.kind
|
32
|
+
c___ = argv1[:c___].is_a?(Array) ? argv1[:c___] : [nil, nil]
|
33
|
+
sisi = []
|
34
|
+
|
31
35
|
while r = mail.data.read do
|
32
36
|
# Read and parse each email file
|
33
|
-
|
34
|
-
|
35
|
-
|
37
|
+
path = mail.data.path
|
38
|
+
args = { data: r, hook: c___[0], origin: path, delivered: argv1[:delivered], vacation: argv1[:vacation] }
|
39
|
+
fact = Sisimai::Fact.rise(**args) || []
|
40
|
+
|
41
|
+
if c___[1]
|
42
|
+
# Run the callback function specified with "c___" parameter of Sisimai.rise after reading
|
43
|
+
# each email file in Maildir/ every time
|
44
|
+
args = { 'kind' => kind, 'mail' => r, 'path' => path, 'fact' => fact }
|
45
|
+
begin
|
46
|
+
c___[1].call(args) if c___[1].is_a?(Proc)
|
47
|
+
rescue StandardError => ce
|
48
|
+
warn ' ***warning: Something is wrong in the second element of the ":c___":' << ce.to_s
|
49
|
+
end
|
50
|
+
end
|
36
51
|
|
37
|
-
|
38
|
-
next unless data = Sisimai::Data.make(**methodargv)
|
39
|
-
list += data unless data.empty?
|
52
|
+
sisi += fact unless fact.empty?
|
40
53
|
end
|
41
54
|
|
42
|
-
return nil if
|
43
|
-
return
|
55
|
+
return nil if sisi.empty?
|
56
|
+
return sisi
|
44
57
|
end
|
45
58
|
|
46
59
|
# Wrapper method to parse mailbox/Maildir and dump as JSON
|
@@ -49,12 +62,13 @@ module Sisimai
|
|
49
62
|
# @param [IO] argv0 or STDIN object
|
50
63
|
# @param [Hash] argv1 Parser options
|
51
64
|
# @options argv1 [Integer] delivered true: Include "delivered" reason
|
65
|
+
# @options argv1 [Integer] vacation true: Include "vacation" reason
|
52
66
|
# @options argv1 [Lambda] hook Lambda object to be called back
|
53
67
|
# @return [String] Parsed data as JSON text
|
54
68
|
def dump(argv0, **argv1)
|
55
69
|
return nil unless argv0
|
70
|
+
nyaan = Sisimai.rise(argv0, **argv1) || []
|
56
71
|
|
57
|
-
nyaan = Sisimai.make(argv0, **argv1) || []
|
58
72
|
if RUBY_PLATFORM.start_with?('java')
|
59
73
|
# java-based ruby environment like JRuby.
|
60
74
|
require 'jrjackson'
|
@@ -16,7 +16,10 @@ Received: from mailgw.example.co.jp (mx [192.0.2.98])
|
|
16
16
|
From: Postmaster@example.co.jp
|
17
17
|
To: "Neko" <kijitora@example.org>
|
18
18
|
Subject: DELIVERY FAILURE:
|
19
|
-
|
19
|
+
=?ISO-2022-JP?B?GyRCJWYhPCU2ITwbKEI=?= Neko (kijitora@example.co.jp)
|
20
|
+
=?US-ASCII?Q??=
|
21
|
+
=?ISO-2022-JP?B?GyRCJE8bKEI=?= Domino =?ISO-2022-JP?B?GyRCJUclIyVsGyhC?=
|
22
|
+
=?ISO-2022-JP?B?GyRCJS8lSCVqJEskTzgrJEQkKyRqJF4kOyRzISMbKEI=?=
|
20
23
|
Date: Thu, 08 Jul 2012 00:03:54 +0800
|
21
24
|
MIME-Version: 1.0
|
22
25
|
X-Priority: 3 (Normal)
|
@@ -40,7 +43,7 @@ was not delivered to:
|
|
40
43
|
|
41
44
|
because:
|
42
45
|
|
43
|
-
|
46
|
+
$B%f!<%6!<(B Neko (kijitora@example.co.jp) $B$O(B Domino $B%G%#%l%/%H%j$K$O8+$D$+$j$^$;$s!#(B
|
44
47
|
|
45
48
|
|
46
49
|
--==0000000000000000000000
|
@@ -51,7 +54,7 @@ Reporting-MTA: dns;mx.example.co.jp
|
|
51
54
|
Final-Recipient: rfc822;kijitora@example.co.jp
|
52
55
|
Action: failed
|
53
56
|
Status: 5.0.0
|
54
|
-
Diagnostic-Code: X-Notes;
|
57
|
+
Diagnostic-Code: X-Notes; $B%f!<%6!<(BNeko (kijitora@example.co.jp) $B$O(B Domino $B%G%#%l%/%H%j$K$O8+$D$+$j$^$;$s!#(B
|
55
58
|
|
56
59
|
--==0000000000000000000000
|
57
60
|
Content-Type: message/rfc822
|
@@ -0,0 +1,174 @@
|
|
1
|
+
Delivered-To: kijitora-cat-neko-nyaan@google.example.com
|
2
|
+
Received: by 2002:ab2:1785:0:b0:19a:50ce:a944 with SMTP id x5csp577194lqe;
|
3
|
+
Thu, 26 Feb 2023 18:30:56 -0800 (PST)
|
4
|
+
X-Received: by 2002:a05:651c:2228:b0:295:9c2e:7324 with SMTP id y40-20020a05651c222800b002959c2e7324mr6911855ljq.4.1677465056139;
|
5
|
+
Thu, 26 Feb 2023 18:30:56 -0800 (PST)
|
6
|
+
ARC-Seal: i=1; a=rsa-sha256; t=1677465056; cv=none;
|
7
|
+
d=google.com; s=arc-20160816;
|
8
|
+
b=OP8D/87B1NpWlJIFLb1Ryp9sBLMQEn0UmitQx/lhOphS5Y7h5VMQdue/m03cyueBqh
|
9
|
+
zWoeGi5vFkSzfqkopcggWfv26ZjF7ECHEWTULvw1Ddf1XqErTWOR9zjoxI5U71Kjg3CA
|
10
|
+
2JtSCWTN2JG81XAnspYKc2qX7UUPISnl6mP5NjKzuDyHQKE3AtCHaAvy+/zUIXNfGZC5
|
11
|
+
VQVXi8C0cYMPMkFfh6qBlU64K9D5H+m4XB12tkRYzhejyAVz1z0UkgPcazLiqvCIPf5d
|
12
|
+
5AajrntYaTvOar/K8+F1X3TYucNmWfGyXzPcBfCy6OjsdF4WUJ+P4WyPkcC4ZMnQuzTF
|
13
|
+
eemA==
|
14
|
+
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816;
|
15
|
+
h=in-reply-to:references:subject:from:date:message-id:auto-submitted
|
16
|
+
:to:dkim-signature;
|
17
|
+
bh=o7cpmqx+tgCx5m+g8oZRWsGCIo8X32S8zBkahP2egx0=;
|
18
|
+
b=qp3ixYdgDwSmM9zTspitM3aUqmuQqGf52SlCuvGRrjksgHbHoSY6jRljQpWPDkwUlR
|
19
|
+
LdN/dyIBBmx2HqnVEjcwaajj52M+wJdQAdGj7gu2g+SP06VpmW+szmuMtqC13cJqlNhd
|
20
|
+
VJ67sS7oBJVRm4Jy5RmE2lfpnPMduLKo4MKQc6Uj7yxkeQlP4iNCVPfp1McXyhxtFHns
|
21
|
+
KogLbkS8NFpA04RaC4tabvp4vDup1/bFS/JRPBE4IQiYyUqVrG8s7o/0U5DznTy3Zsgf
|
22
|
+
zpxCIWd9zYzzmWFeKdyJNmAaH6e7/s+5rQVGe/ryc2q4lPNadxPcsMjOoJ2d29RCyFMy
|
23
|
+
/q0A==
|
24
|
+
ARC-Authentication-Results: i=1; mx.google.com;
|
25
|
+
dkim=pass header.i=@googlemail.com header.s=20210112 header.b=PqBP51+l;
|
26
|
+
spf=none (google.com: mail-sor-f69.google.com does not designate permitted sender hosts) smtp.helo=mail-sor-f69.google.com;
|
27
|
+
dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=googlemail.com
|
28
|
+
Return-Path: <>
|
29
|
+
Received: from mail-sor-f69.google.com (mail-sor-f69.google.com. [209.85.220.69])
|
30
|
+
by mx.google.com with SMTPS id q4-20020a2e9144000000b002946a078ae0sor1225584ljg.16.2023.02.26.18.30.56
|
31
|
+
for <kijitora-cat-neko-nyaan@google.example.com>
|
32
|
+
(Google Transport Security);
|
33
|
+
Thu, 26 Feb 2023 18:30:56 -0800 (PST)
|
34
|
+
Received-SPF: none (google.com: mail-sor-f69.google.com does not designate permitted sender hosts) client-ip=209.85.220.69;
|
35
|
+
Authentication-Results: mx.google.com;
|
36
|
+
dkim=pass header.i=@googlemail.com header.s=20210112 header.b=PqBP51+l;
|
37
|
+
spf=none (google.com: mail-sor-f69.google.com does not designate permitted sender hosts) smtp.helo=mail-sor-f69.google.com;
|
38
|
+
dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=googlemail.com
|
39
|
+
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
|
40
|
+
d=googlemail.com; s=20210112;
|
41
|
+
h=in-reply-to:references:subject:from:date:message-id:auto-submitted
|
42
|
+
:to:from:to:cc:subject:date:message-id:reply-to;
|
43
|
+
bh=o7cpmqx+tgCx5m+g8oZRWsGCIo8X32S8zBkahP2egx0=;
|
44
|
+
b=PqBP51+lcin2uB1zGXsK534CFC9hpjVMDQRkzfbcTLcn9dQoqN2Mqs+6yHelWNr4eX
|
45
|
+
iZ0EVsWqfkU10OngaL9ThubvJqbYhZbc2Gcn0LdiqGrhMxPNSQ34rh/nlEODsbbJf2VW
|
46
|
+
693Q+Z2ZhhZEapenSlVZjt8yz4CRi0qTdXkUPMEAnBEMpNviY2RidqALyeGgZBO5bNCm
|
47
|
+
FJd6AqwcHWW39mkM/iogaQjVVuxS68j8RApvY45meW+2JU718KqwmjVbP2KZ/ITCjOtf
|
48
|
+
TvNrRnHviC5vlUQKpmgpA2O/IzohR+nLnZctyT0KmRFNT/64gIm0fXNtrBnO8H2h5guG
|
49
|
+
9KEg==
|
50
|
+
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
|
51
|
+
d=1e100.net; s=20210112;
|
52
|
+
h=in-reply-to:references:subject:from:date:message-id:auto-submitted
|
53
|
+
:to:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;
|
54
|
+
bh=o7cpmqx+tgCx5m+g8oZRWsGCIo8X32S8zBkahP2egx0=;
|
55
|
+
b=A5Pr4scyEyeQ8hEk1X/11Ny4vP9lDOgOFCbADSW8su0Rq9MpPOp9qzYd85NcptzYaJ
|
56
|
+
ppKYZKCmzxoyQ3ZpPjo2EE/hXov0uG8I2uyWRuLrZETzVfIrtuWcri7E4xevduA9kdhu
|
57
|
+
nNrB9v2oFGRP5+Qz250EP2JHQLr02yLBjk7Bjz4cQDWsxGoyKLXNmLIeef84O6CgwiSp
|
58
|
+
z47l7B0D6LeL3DsUn15BVi2dPE4WNy6WayLXectHuguPV0e0MAipvveS81atFaRlgn0M
|
59
|
+
ri1GaOyX1O482y53Dzp0CxpMn4ncGjy16fiIbCYWhM1zFXWlwE0gh0KUUvIi5Ufbu8Vw
|
60
|
+
qDPQ==
|
61
|
+
X-Gm-Message-State: AO0yUKUJaTXy+S83h8MMnRXh7sfSuZ7HejgVWHxgkbSYtw+QqlbGU2lF 7AXe9LaunF0Hpx5yxJZoRdluHO2zI0nVlH5Xf5XAZw==
|
62
|
+
X-Google-Smtp-Source: AK7set/UsC/BGtW9CgmWT8fuRPR2fZ9bqAPkWp9ktaIpWH7ZEk6t6+2qHXF6VAriVlypEme5zhNO1UrtaRrYckjLRErmeFA6MB/l9as=
|
63
|
+
X-Received: by 2002:a05:651c:1614:b0:293:27a9:ef34 with SMTP id f20-20020a05651c161400b0029327a9ef34mr2807111ljq.0.1677465056065;
|
64
|
+
Thu, 26 Feb 2023 18:30:56 -0800 (PST)
|
65
|
+
Content-Type: multipart/report; boundary="000000000000ca2d9205f5a5444d"; report-type=delivery-status
|
66
|
+
To: kijitora-cat-neko-nyaan@google.example.com
|
67
|
+
Received: by 2002:a05:651c:1614:b0:293:27a9:ef34 with SMTP id f20-20020a05651c161400b0029327a9ef34mr2834317ljq.0; Thu, 26 Feb 2023 18:30:56 -0800 (PST)
|
68
|
+
Return-Path: <>
|
69
|
+
Auto-Submitted: auto-replied
|
70
|
+
Message-ID: <63fc15e0.050a0220.58de0.183e.GMR@mx.google.com>
|
71
|
+
Date: Thu, 26 Feb 2023 18:30:56 -0800 (PST)
|
72
|
+
From: Mail Delivery Subsystem <mailer-daemon@googlemail.com>
|
73
|
+
Subject: Delivery Status Notification (Failure)
|
74
|
+
X-Failed-Recipients: neko-nyaan-cat-meeting@google-groups.example.com
|
75
|
+
|
76
|
+
--000000000000ca2d9205f5a5444d
|
77
|
+
Content-Type: multipart/related; boundary="000000000000ca332c05f5a5444e"
|
78
|
+
|
79
|
+
--000000000000ca332c05f5a5444e
|
80
|
+
Content-Type: multipart/alternative; boundary="000000000000ca333105f5a5444f"
|
81
|
+
|
82
|
+
--000000000000ca333105f5a5444f
|
83
|
+
Content-Type: text/plain; charset="UTF-8"
|
84
|
+
|
85
|
+
|
86
|
+
** Message not delivered **
|
87
|
+
|
88
|
+
You're sending this from a different address or alias using the 'Send mail as' feature. The settings for your 'Send mail as' account are misconfigured or out of date. Check those settings and try resending.
|
89
|
+
|
90
|
+
Learn more here: https://support.google.com/mail/?p=CustomFromDenied
|
91
|
+
|
92
|
+
The response was:
|
93
|
+
|
94
|
+
Unspecified Error (SENT_SECOND_EHLO): Smtp server does not advertise AUTH capability
|
95
|
+
|
96
|
+
--000000000000ca333105f5a5444f
|
97
|
+
Content-Type: text/html; charset="UTF-8"
|
98
|
+
|
99
|
+
|
100
|
+
<html>
|
101
|
+
<head>
|
102
|
+
<style>
|
103
|
+
* {
|
104
|
+
font-family:Roboto, "Helvetica Neue", Helvetica, Arial, sans-serif;
|
105
|
+
}
|
106
|
+
</style>
|
107
|
+
</head>
|
108
|
+
<body>
|
109
|
+
<table cellpadding="0" cellspacing="0" class="email-wrapper" style="padding-top:32px;background-color:#ffffff;"><tbody>
|
110
|
+
<tr><td>
|
111
|
+
<table cellpadding=0 cellspacing=0><tbody>
|
112
|
+
<tr><td style="max-width:560px;padding:24px 24px 32px;background-color:#fafafa;border:1px solid #e0e0e0;border-radius:2px">
|
113
|
+
<img style="padding:0 24px 16px 0;float:left" width=72 height=72 alt="Error Icon" src="cid:icon.png">
|
114
|
+
<table style="min-width:272px;padding-top:8px"><tbody>
|
115
|
+
<tr><td><h2 style="font-size:20px;color:#212121;font-weight:bold;margin:0">
|
116
|
+
Message not delivered
|
117
|
+
</h2></td></tr>
|
118
|
+
<tr><td style="padding-top:20px;color:#757575;font-size:16px;font-weight:normal;text-align:left">
|
119
|
+
You're sending this from a different address or alias using the 'Send mail as' feature. The settings for your 'Send mail as' account are misconfigured or out of date. Check those settings and try resending.
|
120
|
+
</td></tr>
|
121
|
+
<tr><td style="padding-top:24px;color:#4285F4;font-size:14px;font-weight:bold;text-align:left">
|
122
|
+
<a style="text-decoration:none" href="https://support.google.com/mail/?p=CustomFromDenied">LEARN MORE</a>
|
123
|
+
</td></tr>
|
124
|
+
</tbody></table>
|
125
|
+
</td></tr>
|
126
|
+
</tbody></table>
|
127
|
+
</td></tr>
|
128
|
+
<tr style="border:none;background-color:#fff;font-size:12.8px;width:90%">
|
129
|
+
<td align="left" style="padding:48px 10px">
|
130
|
+
The response was:<br/>
|
131
|
+
<p style="font-family:monospace">
|
132
|
+
Unspecified Error (SENT_SECOND_EHLO): Smtp server does not advertise AUTH capability
|
133
|
+
</p>
|
134
|
+
</td>
|
135
|
+
</tr>
|
136
|
+
</tbody></table>
|
137
|
+
</body>
|
138
|
+
</html>
|
139
|
+
|
140
|
+
--000000000000ca333105f5a5444f--
|
141
|
+
--000000000000ca332c05f5a5444e
|
142
|
+
Content-Type: image/png; name="icon.png"
|
143
|
+
Content-Disposition: attachment; filename="icon.png"
|
144
|
+
Content-Transfer-Encoding: base64
|
145
|
+
Content-ID: <icon.png>
|
146
|
+
|
147
|
+
|
148
|
+
--000000000000ca332c05f5a5444e--
|
149
|
+
--000000000000ca2d9205f5a5444d
|
150
|
+
Content-Type: message/delivery-status
|
151
|
+
|
152
|
+
|
153
|
+
--000000000000ca2d9205f5a5444d
|
154
|
+
Content-Type: message/rfc822
|
155
|
+
|
156
|
+
X-Gm-Message-State: AO0yUKVhi7hlxZPb1quoNAHFXZJYgxvbTGotZqnNumozCBfX0y128Dd7 ntdOGQFAIqeTt2XVskzfywmr4dxrTq5ZkcUjJd8=
|
157
|
+
X-Google-Smtp-Source: AK7set9BQ/++KfZD1JUmMUMiZsssix2NWMbSdwZ9fNTVQYWVFsuwS0n2iAfCxXwTBPTRWmYP524J/ncm2F65UJI4xAk=
|
158
|
+
X-Received: by 2002:a05:651c:1614:b0:293:27a9:ef34 with SMTP id f20-20020a05651c161400b0029327a9ef34mr2807080ljq.0.1677465053122; Thu, 26 Feb 2023 18:30:53 -0800 (PST)
|
159
|
+
MIME-Version: 1.0
|
160
|
+
In-Reply-To: <CAByYQsEaO0O4GgfWivReAX=r_OECkcwQgkgSbXJy7LeCm5vvNg@mail.gmail.com>
|
161
|
+
From: <michitsuna@example.jp>
|
162
|
+
Date: Mon, 27 Feb 2023 11:30:40 +0900
|
163
|
+
X-Gmail-Original-Message-ID: <CAByYQsF5qdTf_h-1AAVPW0RgR1YN+LE=+0Uv9LpQ4aA_myPtCw@mail.gmail.com>
|
164
|
+
Message-ID: <CAByYQsF5qdTf_h-1AAVPW0RgR1YN+LE=+0Uv9LpQ4aA_myPtCw@mail.gmail.com>
|
165
|
+
Subject: Nyaan
|
166
|
+
To: <nekochan@example.co.jp>
|
167
|
+
Content-Type: multipart/mixed; boundary="0000000000009d969b05f5a54484"
|
168
|
+
|
169
|
+
--0000000000009d969b05f5a54484
|
170
|
+
|
171
|
+
----- Message truncated -----
|
172
|
+
--0000000000009d969b05f5a54484--
|
173
|
+
|
174
|
+
--000000000000ca2d9205f5a5444d--
|