From a88e5e90dcef84dfb445dba18059ea222f629c33 Mon Sep 17 00:00:00 2001 From: Guilherme Rugai Freire Date: Thu, 18 Jul 2024 22:07:53 -0300 Subject: [PATCH] parse mail subject when receiving and saving to db this way, when the inbox route is called, there is no need to parse all mails neither request them from db just so it can have their subject --- README.md | 1 - migration.sql | 1 + pkg/mail_server/main.go | 11 +++++++++-- pkg/web_server/main.go | 27 ++++++++++++++------------- 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 90361b8..1dc614f 100644 --- a/README.md +++ b/README.md @@ -41,5 +41,4 @@ Available env variables: - Restart when either mail or web server dies - Handle attachments - Do not store the raw mail data in the DB, maybe use block storage (the provider can be a disk provider at first) - - Cache subject parsed from email. Then when listing the email it is not necessary to parse all mails and retrieve them. - Cache in general? diff --git a/migration.sql b/migration.sql index 433b787..0a71e60 100644 --- a/migration.sql +++ b/migration.sql @@ -5,5 +5,6 @@ CREATE TABLE mails ( arrived_at integer not null, rcpt_addr text not null, from_addr text not null, + subject text, data blob not null ); diff --git a/pkg/mail_server/main.go b/pkg/mail_server/main.go index 3d03cb6..4139273 100644 --- a/pkg/mail_server/main.go +++ b/pkg/mail_server/main.go @@ -10,6 +10,7 @@ import ( "strconv" "time" + "github.com/GRFreire/nthmail/pkg/mail_utils" "github.com/emersion/go-smtp" _ "github.com/mattn/go-sqlite3" ) @@ -58,13 +59,19 @@ func (session *Session) Data(reader io.Reader) error { return err } else { - stmt, err := session.tx.Prepare("INSERT INTO mails (arrived_at, rcpt_addr, from_addr, data) VALUES (?, ?, ?, ?)") + stmt, err := session.tx.Prepare("INSERT INTO mails (arrived_at, rcpt_addr, from_addr, subject, data) VALUES (?, ?, ?, ?, ?)") if err != nil { + println(err) return err } defer stmt.Close() - _, err = stmt.Exec(session.arrived_at, session.rcpt, session.from, bytes) + mail_obj, err := mail_utils.Parse_mail(bytes, true) + if err != nil { + return err + } + + _, err = stmt.Exec(session.arrived_at, session.rcpt, session.from, mail_obj.Subject, bytes) if err != nil { return err } diff --git a/pkg/web_server/main.go b/pkg/web_server/main.go index b39b069..41c2396 100644 --- a/pkg/web_server/main.go +++ b/pkg/web_server/main.go @@ -59,6 +59,12 @@ type ServerResouces struct { domain string } +type db_mail_header struct { + Id int + Arrived_at int64 + Rcpt_addr, From_addr string + Subject string +} type db_mail struct { Id int Arrived_at int64 @@ -105,7 +111,7 @@ func (sr ServerResouces) handleInbox(res http.ResponseWriter, req *http.Request) } defer tx.Commit() - stmt, err := tx.Prepare("SELECT mails.id, mails.arrived_at, mails.rcpt_addr, mails.from_addr, mails.data FROM mails WHERE mails.rcpt_addr = ?") + stmt, err := tx.Prepare("SELECT mails.id, mails.arrived_at, mails.rcpt_addr, mails.from_addr, mails.subject FROM mails WHERE mails.rcpt_addr = ?") if err != nil { res.WriteHeader(500) res.Write([]byte("internal server error")) @@ -127,8 +133,8 @@ func (sr ServerResouces) handleInbox(res http.ResponseWriter, req *http.Request) var mails []mail_utils.Mail_obj for rows.Next() { - var m db_mail - err = rows.Scan(&m.Id, &m.Arrived_at, &m.Rcpt_addr, &m.From_addr, &m.Data) + var m db_mail_header + err = rows.Scan(&m.Id, &m.Arrived_at, &m.Rcpt_addr, &m.From_addr, &m.Subject) if err != nil { res.WriteHeader(500) res.Write([]byte("internal server error")) @@ -137,17 +143,12 @@ func (sr ServerResouces) handleInbox(res http.ResponseWriter, req *http.Request) return } - mail_obj, err := mail_utils.Parse_mail(m.Data, true) - mail_obj.Date = time.Unix(m.Arrived_at, 0) + var mail_obj mail_utils.Mail_obj mail_obj.Id = m.Id - if err != nil { - res.WriteHeader(500) - res.Write([]byte("internal server error")) - - log.Println("could not parse mail") - log.Println(err) - return - } + mail_obj.Date = time.Unix(m.Arrived_at, 0) + mail_obj.To = m.Rcpt_addr + mail_obj.From = m.From_addr + mail_obj.Subject = m.Subject mails = append(mails, mail_obj) }