-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlibsisimai.go
118 lines (107 loc) · 4.5 KB
/
libsisimai.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// Copyright (C) 2020-2025 azumakuniyuki and sisimai development team, All rights reserved.
// This software is distributed under The BSD 2-Clause License.
package sisimai
// _ _ _ _ _ _
// | (_) |__ ___(_)___(_)_ __ ___ __ _(_) ___ _ __ __ _
// | | | '_ \/ __| / __| | '_ ` _ \ / _` | | / _ \| '__/ _` |
// | | | |_) \__ \ \__ \ | | | | | | (_| | || (_) | | | (_| |
// |_|_|_.__/|___/_|___/_|_| |_| |_|\__,_|_(_)___/|_| \__, |
// https://libsisimai.org/ |___/
//
// sisimai is a library that decodes complex and diverse bounce emails and outputs the results of the
// delivery failure, such as the reason for the bounce and the recipient email address, in structured
// data. It is also possible to output in JSON format.
import "io"
import "fmt"
import "errors"
import "libsisimai.org/sisimai/sis"
import sisimbox "libsisimai.org/sisimai/mail"
import sisifact "libsisimai.org/sisimai/fact"
import sisimoji "libsisimai.org/sisimai/string"
const libname string = "sisimai"
const version string = "5.2.0"
const patchlv uint8 = 0
type CallbackArgs = sis.CallbackArgs
type CfParameter1 = sis.CfParameter1
type CfParameter2 = sis.CfParameter2
// Version() returns the version number of sisimai
func Version() string {
// @param NONE
// @return string version number like "v5.2.0p22"
v := "v" + version; if patchlv > 0 { v += "p" + string(patchlv) }
return v
}
// Args() returns the pointer to sis.DecodingArgs{}
func Args() *sis.DecodingArgs {
// @param NONE
// @return *sis.DecodingArgs
return &sis.DecodingArgs{
Delivered: false, // Include sis.Fact{}.Action = "delivered" records in the decoded data
Vacation: false, // Include sis.Fact{}.Reason = "vacation" records in the decoded data
Callback1: nil, // The 1st callback function
Callback2: nil, // The 2nd callback function
}
}
// sisimai.Rise() is a function for decoding bounce mails in a mailbox or a Maildir/
//func Rise(path string, args map[string]bool, c___ []interface{}) (*[]sis.Fact, *[]sis.NotDecoded) {
func Rise(path string, args *sis.DecodingArgs) (*[]sis.Fact, *[]sis.NotDecoded) {
// @param string path Path to mbox or Maildir/ or "STDIN"
// @param *sis.DecodingArgs args Arguments for decoding
// @return []sis.Fact
sisidigest := []sis.Fact{} // Decoded bounce message structures
notdecoded := []sis.NotDecoded{} // List of occurred errors and warnings
emailthing, nyaan := sisimbox.Rise(path); if nyaan != nil {
// The file does not exist, or is not a regular file.
ce := *sis.MakeNotDecoded(fmt.Sprintf("%s", nyaan), true); ce.Email(emailthing.Path)
notdecoded = append(notdecoded, ce)
return &sisidigest, ¬decoded
}
for {
// Read the email specified with the first argument until io.EOF
if mesg, nyaan := emailthing.Read(); nyaan != nil {
// Failed to read the email
if errors.Is(nyaan, io.EOF) {
// sisimai has reached to the end of email/directory
break
} else {
// Something wrong, sisimai failed to read the email as a text
ce := *sis.MakeNotDecoded(fmt.Sprintf("%s", nyaan), true); ce.Email(emailthing.Path)
notdecoded = append(notdecoded, ce)
continue
}
} else {
// Read and decode each email file as a string
if emailthing.Size == 0 {
// The email file was empty
ce := *sis.MakeNotDecoded("the email file is empty", true); ce.Email(emailthing.Path)
notdecoded = append(notdecoded, ce)
continue
}
mesg = sisimoji.ToLF(mesg)
fact, nyaan := sisifact.Rise(mesg, emailthing.Path, args)
if len(fact) > 0 { sisidigest = append(sisidigest, fact...) }
if len(nyaan) > 0 { notdecoded = append(notdecoded, nyaan...) }
if args.Callback2 != nil {
// Run the 2nd callback function specified with the 3rd argument of Sisimai.Rise() after
// reading each email file in Maildir/ every time
carg := &sis.CallbackArgs{
Headers: map[string][]string{
"path": []string{emailthing.Path},
"dir": []string{emailthing.Dir},
"file": []string{emailthing.File},
"kind": []string{emailthing.Kind},
},
Payload: mesg,
}
//args.Callback2.(func(*sis.CallbackArgs))(carg)
if _, nyaan := args.Callback2(carg); nyaan != nil {
ce := *sis.MakeNotDecoded(fmt.Sprintf("%s", nyaan), true); ce.Email(emailthing.Path)
notdecoded = append(notdecoded, ce)
}
}
}
}
// TODO: Add warning information of the decoding results into notdecoded as sis.NotDecoded{}
// when the reason is "onhold" or "undefined"
return &sisidigest, ¬decoded
}