zangtumb/vendor/github.com/amalfra/maildir/maildir.go

96 lines
2.3 KiB
Go
Raw Normal View History

2020-10-08 15:36:17 -05:00
package maildir
import (
"errors"
"os"
"path/filepath"
"sort"
"strings"
"github.com/amalfra/maildir/lib"
)
// Maildir implements maildir format and it's operations
type Maildir struct {
path string
}
// NewMaildir will create new maildir at specified path
func NewMaildir(path string) *Maildir {
maildir := new(Maildir)
maildir.path = path
_, dCur := os.Stat(path + "/cur")
_, dTmp := os.Stat(path + "/tmp")
_, dNew := os.Stat(path + "/new")
if os.IsNotExist(dCur) || os.IsNotExist(dTmp) || os.IsNotExist(dNew) {
maildir.createDirectories()
}
return maildir
}
// createDirectories will the sub directories required by maildir
func (m *Maildir) createDirectories() {
for _, subDir := range lib.Subdirs {
os.MkdirAll(filepath.Join(m.path, subDir), os.ModePerm)
}
}
// Add writes data out as a new message. Returns Message instance
func (m *Maildir) Add(data string) (*lib.Message, error) {
msg, err := lib.NewMessage(m.path)
if err != nil {
return nil, errors.New("failed to create message")
}
err = msg.Write(data)
if err != nil {
return nil, errors.New("failed to write message")
}
return msg, nil
}
// Get returns a message object for key
func (m *Maildir) Get(key string) *lib.Message {
return lib.LoadMessage(m.path, key)
}
// List returns an array of messages from new or cur directory, sorted by key
func (m *Maildir) List(dir string) (map[string]*lib.Message, error) {
if !lib.StringInSlice(dir, lib.Subdirs) {
return nil, errors.New("dir must be :new, :cur, or :tmp")
}
keys, err := m.getDirListing(dir)
if err != nil {
return nil, errors.New("failed to get directory listing")
}
sort.Sort(sort.StringSlice(keys))
// map keys to message objects
keyMap := make(map[string]*lib.Message)
for _, key := range keys {
keyMap[key] = m.Get(key)
}
return keyMap, nil
}
// getDirListing returns an array of keys in dir
func (m *Maildir) getDirListing(dir string) ([]string, error) {
filter := "*"
searchPath := filepath.Join(m.path, dir, filter)
filePaths, err := filepath.Glob(searchPath)
// remove maildir path so that only key remains
for i, filePath := range filePaths {
filePaths[i] = strings.TrimPrefix(filePath, m.path)
}
return filePaths, err
}
// Delete a message by key
func (m *Maildir) Delete(key string) error {
return m.Get(key).Destroy()
}