96 lines
2.3 KiB
Go
96 lines
2.3 KiB
Go
|
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()
|
||
|
}
|