1
0
mirror of https://github.com/axllent/mailpit.git synced 2025-06-08 23:46:21 +02:00

Chore: Code cleanup

This commit is contained in:
Ralph Slooten 2024-10-12 15:20:11 +13:00
parent 073ddd33d5
commit a56fd1f53d
17 changed files with 78 additions and 54 deletions

View File

@ -78,5 +78,6 @@ func clean(text string) string {
}, text) }, text)
text = re.ReplaceAllString(text, " ") text = re.ReplaceAllString(text, " ")
return strings.TrimSpace(text) return strings.TrimSpace(text)
} }

View File

@ -30,14 +30,17 @@ type Conn struct {
// Opt represents the client configuration. // Opt represents the client configuration.
type Opt struct { type Opt struct {
// Host name
Host string `json:"host"` Host string `json:"host"`
// Port number
Port int `json:"port"` Port int `json:"port"`
// DialTimeout default is 3 seconds.
// Default is 3 seconds.
DialTimeout time.Duration `json:"dial_timeout"` DialTimeout time.Duration `json:"dial_timeout"`
// Dialer
Dialer Dialer `json:"-"` Dialer Dialer `json:"-"`
// TLSEnabled sets whether SLS is enabled
TLSEnabled bool `json:"tls_enabled"` TLSEnabled bool `json:"tls_enabled"`
// TLSSkipVerify skips TLS verification (ie: self-signed)
TLSSkipVerify bool `json:"tls_skip_verify"` TLSSkipVerify bool `json:"tls_skip_verify"`
} }
@ -50,15 +53,14 @@ type Dialer interface {
type MessageID struct { type MessageID struct {
// ID is the numerical index (non-unique) of the message. // ID is the numerical index (non-unique) of the message.
ID int ID int
// Size in bytes
Size int Size int
// UID is only present if the response is to the UIDL command. // UID is only present if the response is to the UIDL command.
UID string UID string
} }
var ( var (
lineBreak = []byte("\r\n") lineBreak = []byte("\r\n")
respOK = []byte("+OK") // `+OK` without additional info respOK = []byte("+OK") // `+OK` without additional info
respOKInfo = []byte("+OK ") // `+OK <info>` respOKInfo = []byte("+OK ") // `+OK <info>`
respErr = []byte("-ERR") // `-ERR` without additional info respErr = []byte("-ERR") // `-ERR` without additional info
@ -126,6 +128,7 @@ func (c *Conn) Send(b string) error {
if _, err := c.w.WriteString(b + "\r\n"); err != nil { if _, err := c.w.WriteString(b + "\r\n"); err != nil {
return err return err
} }
return c.w.Flush() return c.w.Flush()
} }
@ -223,12 +226,14 @@ func (c *Conn) Auth(user, password string) error {
// User sends the username to the server. // User sends the username to the server.
func (c *Conn) User(s string) error { func (c *Conn) User(s string) error {
_, err := c.Cmd("USER", false, s) _, err := c.Cmd("USER", false, s)
return err return err
} }
// Pass sends the password to the server. // Pass sends the password to the server.
func (c *Conn) Pass(s string) error { func (c *Conn) Pass(s string) error {
_, err := c.Cmd("PASS", false, s) _, err := c.Cmd("PASS", false, s)
return err return err
} }

View File

@ -13,6 +13,8 @@ import (
"strconv" "strconv"
"strings" "strings"
"time" "time"
"github.com/axllent/mailpit/internal/tools"
) )
// ProtoVersion is the protocol version // ProtoVersion is the protocol version
@ -81,6 +83,7 @@ func (c *Client) dial() (connection, error) {
} }
return net.DialUnix("unix", nil, unixAddr) return net.DialUnix("unix", nil, unixAddr)
} }
panic("Client.net must be either \"tcp\" or \"unix\"") panic("Client.net must be either \"tcp\" or \"unix\"")
} }
@ -107,26 +110,25 @@ func (c *Client) report(email []byte) ([]string, error) {
} }
bw := bufio.NewWriter(conn) bw := bufio.NewWriter(conn)
_, err = bw.WriteString("REPORT SPAMC/" + ProtoVersion + "\r\n") if _, err := bw.WriteString("REPORT SPAMC/" + ProtoVersion + "\r\n"); err != nil {
if err != nil {
return nil, err return nil, err
} }
_, err = bw.WriteString("Content-length: " + strconv.Itoa(len(email)) + "\r\n\r\n")
if err != nil { if _, err := bw.WriteString("Content-length: " + strconv.Itoa(len(email)) + "\r\n\r\n"); err != nil {
return nil, err return nil, err
} }
_, err = bw.Write(email)
if err != nil { if _, err := bw.Write(email); err != nil {
return nil, err return nil, err
} }
err = bw.Flush()
if err != nil { if err := bw.Flush(); err != nil {
return nil, err return nil, err
} }
// Client is supposed to close its writing side of the connection // Client is supposed to close its writing side of the connection
// after sending its request. // after sending its request.
err = conn.CloseWrite() if err := conn.CloseWrite(); err != nil {
if err != nil {
return nil, err return nil, err
} }
@ -134,6 +136,7 @@ func (c *Client) report(email []byte) ([]string, error) {
lines []string lines []string
br = bufio.NewReader(conn) br = bufio.NewReader(conn)
) )
for { for {
line, err := br.ReadString('\n') line, err := br.ReadString('\n')
if err == io.EOF { if err == io.EOF {
@ -171,11 +174,12 @@ func (c *Client) parseOutput(output []string) Result {
continue continue
} }
} }
// summary // summary
if spamMainRe.MatchString(row) { if spamMainRe.MatchString(row) {
res := spamMainRe.FindStringSubmatch(row) res := spamMainRe.FindStringSubmatch(row)
if len(res) == 4 { if len(res) == 4 {
if strings.ToLower(res[1]) == "true" || strings.ToLower(res[1]) == "yes" { if tools.InArray(res[1], []string{"true", "yes"}) {
result.Spam = true result.Spam = true
} else { } else {
result.Spam = false result.Spam = false
@ -197,8 +201,8 @@ func (c *Client) parseOutput(output []string) Result {
reachedRules = true reachedRules = true
continue continue
} }
// details // details
// row = strings.Trim(row, " \t\r\n")
if reachedRules && spamDetailsRe.MatchString(row) { if reachedRules && spamDetailsRe.MatchString(row) {
res := spamDetailsRe.FindStringSubmatch(row) res := spamDetailsRe.FindStringSubmatch(row)
if len(res) == 5 { if len(res) == 5 {
@ -207,6 +211,7 @@ func (c *Client) parseOutput(output []string) Result {
} }
} }
} }
return result return result
} }
@ -222,12 +227,11 @@ func (c *Client) Ping() error {
return err return err
} }
_, err = io.WriteString(conn, fmt.Sprintf("PING SPAMC/%s\r\n\r\n", ProtoVersion)) if _, err := io.WriteString(conn, fmt.Sprintf("PING SPAMC/%s\r\n\r\n", ProtoVersion)); err != nil {
if err != nil {
return err return err
} }
err = conn.CloseWrite()
if err != nil { if err := conn.CloseWrite(); err != nil {
return err return err
} }
@ -241,5 +245,6 @@ func (c *Client) Ping() error {
return err return err
} }
} }
return nil return nil
} }

View File

@ -39,8 +39,12 @@ var (
// InitDB will initialise the database // InitDB will initialise the database
func InitDB() error { func InitDB() error {
var (
dsn string
err error
)
p := config.Database p := config.Database
var dsn string
if p == "" { if p == "" {
// when no path is provided then we create a temporary file // when no path is provided then we create a temporary file
@ -74,8 +78,6 @@ func InitDB() error {
} }
} }
var err error
db, err = sql.Open(sqlDriver, dsn) db, err = sql.Open(sqlDriver, dsn)
if err != nil { if err != nil {
return err return err

View File

@ -430,6 +430,21 @@ func GetAttachmentPart(id, partID string) (*enmime.Part, error) {
return nil, errors.New("attachment not found") return nil, errors.New("attachment not found")
} }
// AttachmentSummary returns a summary of the attachment without any binary data
func AttachmentSummary(a *enmime.Part) Attachment {
o := Attachment{}
o.PartID = a.PartID
o.FileName = a.FileName
if o.FileName == "" {
o.FileName = a.ContentID
}
o.ContentType = a.ContentType
o.ContentID = a.ContentID
o.Size = float64(len(a.Content))
return o
}
// LatestID returns the latest message ID // LatestID returns the latest message ID
// //
// If a query argument is set in the request the function will return the // If a query argument is set in the request the function will return the

View File

@ -43,9 +43,13 @@ func ReindexAll() {
logger.Log().Infof("reindexing %d messages", total) logger.Log().Infof("reindexing %d messages", total)
type updateStruct struct { type updateStruct struct {
// ID in database
ID string ID string
// SearchText for searching
SearchText string SearchText string
// Snippet for UI
Snippet string Snippet string
// Metadata info
Metadata string Metadata string
} }
@ -137,5 +141,6 @@ func chunkBy[T any](items []T, chunkSize int) (chunks [][]T) {
for chunkSize < len(items) { for chunkSize < len(items) {
items, chunks = items[chunkSize:], append(chunks, items[0:chunkSize:chunkSize]) items, chunks = items[chunkSize:], append(chunks, items[0:chunkSize:chunkSize])
} }
return append(chunks, items) return append(chunks, items)
} }

View File

@ -198,6 +198,7 @@ func DeleteSearch(search, timezone string) error {
} }
dbLastAction = time.Now() dbLastAction = time.Now()
addDeletedSize(int64(deleteSize)) addDeletedSize(int64(deleteSize))
logMessagesDeleted(total) logMessagesDeleted(total)

View File

@ -3,8 +3,6 @@ package storage
import ( import (
"net/mail" "net/mail"
"time" "time"
"github.com/jhillyerd/enmime"
) )
// Message data excluding physical attachments // Message data excluding physical attachments
@ -114,21 +112,6 @@ type DBMailSummary struct {
ReplyTo []*mail.Address ReplyTo []*mail.Address
} }
// AttachmentSummary returns a summary of the attachment without any binary data
func AttachmentSummary(a *enmime.Part) Attachment {
o := Attachment{}
o.PartID = a.PartID
o.FileName = a.FileName
if o.FileName == "" {
o.FileName = a.ContentID
}
o.ContentType = a.ContentType
o.ContentID = a.ContentID
o.Size = float64(len(a.Content))
return o
}
// ListUnsubscribe contains a summary of List-Unsubscribe & List-Unsubscribe-Post headers // ListUnsubscribe contains a summary of List-Unsubscribe & List-Unsubscribe-Post headers
// including validation of the link structure // including validation of the link structure
type ListUnsubscribe struct { type ListUnsubscribe struct {

View File

@ -13,8 +13,11 @@ import (
// TagFilter struct // TagFilter struct
type TagFilter struct { type TagFilter struct {
// Match is the user-defined match
Match string Match string
// SQL represents the SQL equivalent of Match
SQL *sqlf.Stmt SQL *sqlf.Stmt
// Tags to add on match
Tags []string Tags []string
} }

View File

@ -108,6 +108,7 @@ func addMessageTag(id, name string) (string, error) {
Set("ID", id). Set("ID", id).
Set("TagID", tagID). Set("TagID", tagID).
ExecAndClose(context.TODO(), db) ExecAndClose(context.TODO(), db)
return foundName.String, err return foundName.String, err
} }

View File

@ -11,14 +11,14 @@ func Plural(total int, singular, plural string) string {
if total == 1 { if total == 1 {
return fmt.Sprintf("%d %s", total, singular) return fmt.Sprintf("%d %s", total, singular)
} }
return fmt.Sprintf("%d %s", total, plural) return fmt.Sprintf("%d %s", total, plural)
} }
// InArray tests if a string is within an array. It is not case sensitive. // InArray tests if a string is within an array. It is not case sensitive.
func InArray(k string, arr []string) bool { func InArray(k string, arr []string) bool {
k = strings.ToLower(k)
for _, v := range arr { for _, v := range arr {
if strings.ToLower(v) == k { if strings.EqualFold(v, k) {
return true return true
} }
} }

View File

@ -71,5 +71,6 @@ func Unzip(src string, dest string) ([]string, error) {
return filenames, err return filenames, err
} }
} }
return filenames, nil return filenames, nil
} }

View File

@ -23,6 +23,7 @@ var (
// AllowPrereleases defines whether pre-releases may be included // AllowPrereleases defines whether pre-releases may be included
AllowPrereleases = false AllowPrereleases = false
// temporary directory
tempDir string tempDir string
) )

View File

@ -35,7 +35,6 @@ var (
SMTPAddr = "localhost:1025" SMTPAddr = "localhost:1025"
// FromAddr email address // FromAddr email address
FromAddr string FromAddr string
// UseB - used to set from `-bs` // UseB - used to set from `-bs`
UseB bool UseB bool
// UseS - used to set from `-bs` // UseS - used to set from `-bs`

View File

@ -79,5 +79,6 @@ func getSafeArg(args []string, nr int) (string, error) {
if nr < len(args) { if nr < len(args) {
return args[nr], nil return args[nr], nil
} }
return "", errors.New("-ERR out of range") return "", errors.New("-ERR out of range")
} }

View File

@ -220,6 +220,7 @@ func middleWareFunc(fn http.HandlerFunc) http.HandlerFunc {
fn(w, r) fn(w, r)
return return
} }
w.Header().Set("Content-Encoding", "gzip") w.Header().Set("Content-Encoding", "gzip")
gz := gzip.NewWriter(w) gz := gzip.NewWriter(w)
defer gz.Close() defer gz.Close()