diff options
author | Julian Pidancet <julian.pidancet@oracle.com> | 2022-10-26 22:29:02 +0200 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2022-10-27 21:39:41 +0200 |
commit | f021bfd1c7b7885919cb71884727fd8dfdf8eba7 (patch) | |
tree | 0fe6ce6d038630d0d244b878d2eaf276ee90d0b4 /worker/maildir/container.go | |
parent | 19d16420de3748cdcae2dc9d1a123a1f6fb2425b (diff) | |
download | aerc-f021bfd1c7b7885919cb71884727fd8dfdf8eba7.tar.gz |
maildir: move common maildir code out of worker
This change moves code that could be common to both notmuch and maildir
workers in worker/lib.
Signed-off-by: Julian Pidancet <julian.pidancet@oracle.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
Diffstat (limited to 'worker/maildir/container.go')
-rw-r--r-- | worker/maildir/container.go | 100 |
1 files changed, 7 insertions, 93 deletions
diff --git a/worker/maildir/container.go b/worker/maildir/container.go index 4181648b..f9fb507b 100644 --- a/worker/maildir/container.go +++ b/worker/maildir/container.go @@ -4,108 +4,34 @@ import ( "fmt" "os" "path/filepath" - "regexp" "sort" - "strings" "github.com/emersion/go-maildir" "git.sr.ht/~rjarry/aerc/lib/uidstore" + "git.sr.ht/~rjarry/aerc/worker/lib" ) -// uidReg matches filename encoded UIDs in maildirs synched with mbsync or -// OfflineIMAP -var uidReg = regexp.MustCompile(`,U=\d+`) - // A Container is a directory which contains other directories which adhere to // the Maildir spec type Container struct { - dir string + Store *lib.MaildirStore uids *uidstore.Store recentUIDS map[uint32]struct{} // used to set the recent flag - maildirpp bool // whether to use Maildir++ directory layout } // NewContainer creates a new container at the specified directory func NewContainer(dir string, maildirpp bool) (*Container, error) { - f, err := os.Open(dir) - if err != nil { - return nil, err - } - defer f.Close() - s, err := f.Stat() + store, err := lib.NewMaildirStore(dir, maildirpp) if err != nil { return nil, err } - if !s.IsDir() { - return nil, fmt.Errorf("Given maildir '%s' not a directory", dir) - } return &Container{ - dir: dir, uids: uidstore.NewStore(), - recentUIDS: make(map[uint32]struct{}), maildirpp: maildirpp, + Store: store, uids: uidstore.NewStore(), + recentUIDS: make(map[uint32]struct{}), }, nil } -// ListFolders returns a list of maildir folders in the container -func (c *Container) ListFolders() ([]string, error) { - folders := []string{} - if c.maildirpp { - // In Maildir++ layout, INBOX is the root folder - folders = append(folders, "INBOX") - } - err := filepath.Walk(c.dir, func(path string, info os.FileInfo, err error) error { - if err != nil { - return fmt.Errorf("Invalid path '%s': error: %w", path, err) - } - if !info.IsDir() { - return nil - } - - // Skip maildir's default directories - n := info.Name() - if n == "new" || n == "tmp" || n == "cur" { - return filepath.SkipDir - } - - // Get the relative path from the parent directory - dirPath, err := filepath.Rel(c.dir, path) - if err != nil { - return err - } - - // Skip the parent directory - if dirPath == "." { - return nil - } - - // Drop dirs that lack {new,tmp,cur} subdirs - for _, sub := range []string{"new", "tmp", "cur"} { - if _, err := os.Stat(filepath.Join(path, sub)); os.IsNotExist(err) { - return nil - } - } - - if c.maildirpp { - // In Maildir++ layout, mailboxes are stored in a single directory - // and prefixed with a dot, and subfolders are separated by dots. - if !strings.HasPrefix(dirPath, ".") { - return filepath.SkipDir - } - dirPath = strings.TrimPrefix(dirPath, ".") - dirPath = strings.ReplaceAll(dirPath, ".", "/") - folders = append(folders, dirPath) - - // Since all mailboxes are stored in a single directory, don't - // recurse into subdirectories - return filepath.SkipDir - } - - folders = append(folders, dirPath) - return nil - }) - return folders, err -} - // SyncNewMail adds emails from new to cur, tracking them func (c *Container) SyncNewMail(dir maildir.Dir) error { keys, err := dir.Unseen() @@ -122,25 +48,13 @@ func (c *Container) SyncNewMail(dir maildir.Dir) error { // OpenDirectory opens an existing maildir in the container by name, moves new // messages into cur, and registers the new keys in the UIDStore. func (c *Container) OpenDirectory(name string) (maildir.Dir, error) { - dir := c.Dir(name) + dir := c.Store.Dir(name) if err := c.SyncNewMail(dir); err != nil { return dir, err } return dir, nil } -// Dir returns a maildir.Dir with the specified name inside the container -func (c *Container) Dir(name string) maildir.Dir { - if c.maildirpp { - // Use Maildir++ layout - if name == "INBOX" { - return maildir.Dir(c.dir) - } - return maildir.Dir(filepath.Join(c.dir, "."+strings.ReplaceAll(name, "/", "."))) - } - return maildir.Dir(filepath.Join(c.dir, name)) -} - // IsRecent returns if a uid has the Recent flag set func (c *Container) IsRecent(uid uint32) bool { _, ok := c.recentUIDS[uid] @@ -239,7 +153,7 @@ func (c *Container) moveMessage(dest maildir.Dir, src maildir.Dir, uid uint32) e return fmt.Errorf("could not find path for message id %d", uid) } // Remove encoded UID information from the key to prevent sync issues - name := uidReg.ReplaceAllString(filepath.Base(path), "") + name := lib.StripUIDFromMessageFilename(filepath.Base(path)) destPath := filepath.Join(string(dest), "cur", name) return os.Rename(path, destPath) } |