deleting a message

This commit is contained in:
Erik Winter 2021-01-28 09:40:08 +01:00
parent 13ef0f903d
commit 020e4dde84
4 changed files with 100 additions and 54 deletions

View File

@ -8,7 +8,6 @@ import (
"strings" "strings"
"git.sr.ht/~ewintr/gte/pkg/mstore" "git.sr.ht/~ewintr/gte/pkg/mstore"
"github.com/emersion/go-imap"
) )
type Body struct { type Body struct {
@ -32,7 +31,7 @@ func (b *Body) Len() int {
} }
func main() { func main() {
config := &mstore.EMailStoreConfiguration{ config := &mstore.EmailConfiguration{
IMAPURL: os.Getenv("IMAP_URL"), IMAPURL: os.Getenv("IMAP_URL"),
IMAPUsername: os.Getenv("IMAP_USERNAME"), IMAPUsername: os.Getenv("IMAP_USERNAME"),
IMAPPassword: os.Getenv("IMAP_PASSWORD"), IMAPPassword: os.Getenv("IMAP_PASSWORD"),
@ -43,36 +42,50 @@ func main() {
} }
//fmt.Printf("conf: %+v\n", config) //fmt.Printf("conf: %+v\n", config)
mailStore, err := mstore.EMailConnect(config) mailStore, err := mstore.EmailConnect(config)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
defer mailStore.Disconnect() defer mailStore.Disconnect()
folders, err := mailStore.Folders()
if err != nil {
log.Fatal(err)
}
for _, f := range folders {
fmt.Println(f.Name)
}
/* /*
messages, err := mailStore.Inbox() folders, err := mailStore.FolderNames()
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
for _, m := range messages { for _, f := range folders {
fmt.Println(m.Subject) fmt.Println(f)
} }
*/ */
body := NewBody(`From: todo <process@erikwinter.nl> if err := mailStore.Select("Today"); err != nil {
Subject: the subject
And here comes the body`)
if err := mailStore.Append("INBOX", imap.Literal(body)); err != nil {
log.Fatal(err) log.Fatal(err)
} }
messages, err := mailStore.Messages()
if err != nil {
log.Fatal(err)
}
for _, m := range messages {
fmt.Printf("%d: %s\n", m.ID, m.Subject)
}
if len(messages) == 0 {
log.Fatal("no messages")
return
}
if err := mailStore.Remove(messages[0].ID); err != nil {
log.Fatal(err)
}
/*
body := NewBody(`From: todo <process@erikwinter.nl>
Subject: the subject
And here comes the body`)
if err := mailStore.Append("INBOX", imap.Literal(body)); err != nil {
log.Fatal(err)
}
*/
} }

View File

@ -8,13 +8,13 @@ import (
"github.com/emersion/go-imap/client" "github.com/emersion/go-imap/client"
) )
type EMailStoreConfiguration struct { type EmailConfiguration struct {
IMAPURL string IMAPURL string
IMAPUsername string IMAPUsername string
IMAPPassword string IMAPPassword string
} }
func (esc *EMailStoreConfiguration) Valid() bool { func (esc *EmailConfiguration) Valid() bool {
if esc.IMAPURL == "" { if esc.IMAPURL == "" {
return false return false
} }
@ -25,73 +25,77 @@ func (esc *EMailStoreConfiguration) Valid() bool {
return true return true
} }
type smtpConf struct { type Email struct {
url string imap *client.Client
to string mboxStatus *imap.MailboxStatus
} }
type EMailStore struct { func EmailConnect(conf *EmailConfiguration) (*Email, error) {
imap *client.Client
}
func EMailConnect(conf *EMailStoreConfiguration) (*EMailStore, error) {
imap, err := client.DialTLS(conf.IMAPURL, nil) imap, err := client.DialTLS(conf.IMAPURL, nil)
if err != nil { if err != nil {
return &EMailStore{}, err return &Email{}, err
} }
if err := imap.Login(conf.IMAPUsername, conf.IMAPPassword); err != nil { if err := imap.Login(conf.IMAPUsername, conf.IMAPPassword); err != nil {
return &EMailStore{}, err return &Email{}, err
} }
return &EMailStore{ return &Email{
imap: imap, imap: imap,
}, nil }, nil
} }
func (es *EMailStore) Disconnect() { func (es *Email) Disconnect() {
es.imap.Logout() es.imap.Logout()
} }
func (es *EMailStore) Folders() ([]*Folder, error) { func (es *Email) FolderNames() ([]string, error) {
boxes, done := make(chan *imap.MailboxInfo), make(chan error) boxes, done := make(chan *imap.MailboxInfo), make(chan error)
go func() { go func() {
done <- es.imap.List("", "*", boxes) done <- es.imap.List("", "*", boxes)
}() }()
folders := []*Folder{} folders := []string{}
for b := range boxes { for b := range boxes {
folders = append(folders, &Folder{ folders = append(folders, b.Name)
Name: b.Name,
})
} }
if err := <-done; err != nil { if err := <-done; err != nil {
return []*Folder{}, err return []string{}, err
} }
return folders, nil return folders, nil
} }
func (es *EMailStore) Inbox() ([]*Message, error) { func (es *Email) Select(folder string) error {
mbox, err := es.imap.Select("INBOX", false) status, err := es.imap.Select(folder, false)
if err != nil { if err != nil {
return []*Message{}, err return err
} }
fmt.Println("Flags for INBOX:", mbox.Flags) fmt.Printf("status: %+v\n", status)
fmt.Println("Messages: ", mbox.Messages) es.mboxStatus = status
return nil
}
func (es *Email) Messages() ([]*Message, error) {
if es.mboxStatus == nil {
return []*Message{}, fmt.Errorf("no mailbox selected")
}
seqset := new(imap.SeqSet) seqset := new(imap.SeqSet)
seqset.AddRange(uint32(1), mbox.Messages) seqset.AddRange(uint32(1), es.mboxStatus.Messages)
imsg, done := make(chan *imap.Message), make(chan error) imsg, done := make(chan *imap.Message), make(chan error)
go func() { go func() {
done <- es.imap.Fetch(seqset, []imap.FetchItem{imap.FetchEnvelope}, imsg) done <- es.imap.Fetch(seqset, []imap.FetchItem{imap.FetchEnvelope, imap.FetchUid}, imsg)
}() }()
messages := []*Message{} messages := []*Message{}
for m := range imsg { for m := range imsg {
//fmt.Printf("%+v\n", m)
messages = append(messages, &Message{ messages = append(messages, &Message{
ID: m.Uid,
Subject: m.Envelope.Subject, Subject: m.Envelope.Subject,
}) })
} }
@ -103,6 +107,28 @@ func (es *EMailStore) Inbox() ([]*Message, error) {
return messages, nil return messages, nil
} }
func (es *EMailStore) Append(mbox string, msg imap.Literal) error { func (es *Email) Append(mbox string, msg imap.Literal) error {
return es.imap.Append(mbox, nil, time.Time{}, msg) return es.imap.Append(mbox, nil, time.Time{}, msg)
} }
func (es *Email) Remove(id uint32) error {
if es.mboxStatus == nil {
return fmt.Errorf("no mailbox selected")
}
// set deleted flag
seqset := new(imap.SeqSet)
seqset.AddRange(id, id)
storeItem := imap.FormatFlagsOp(imap.SetFlags, true)
err := es.imap.UidStore(seqset, storeItem, imap.FormatStringList([]string{imap.DeletedFlag}), nil)
if err != nil {
return err
}
// expunge box
if err := es.imap.Expunge(nil); err != nil {
return err
}
return nil
}

5
pkg/mstore/memory.go Normal file
View File

@ -0,0 +1,5 @@
package mstore
type Memory struct {
messages map[*Folder][]*Message
}

View File

@ -1,18 +1,20 @@
package mstore package mstore
type Folder struct { type Folder struct {
Name string Name string
Version uint32
} }
type Message struct { type Message struct {
ID uint32
Subject string Subject string
Body string Body string
} }
type MStorer interface { type MStorer interface {
Folders() ([]*Folder, error) Folders() ([]string, error)
Messages(folder Folder) ([]Message, error) Select(folder string) error
Move(message Message, folder Folder) error Messages() ([]*Message, error)
Update(message Message) error Add(message *Message) error
Add(message Message) error Remove(id string) error
} }