notmuch: make maildir store path configurable
Add the "maildir-store" account configuration option to select the maildir store to associate with the notmuch database. This also allows the previous changes to be backward compatible since not specifying this option will make the backend behave the same as if there were no changes. Fixes: https://todo.sr.ht/~rjarry/aerc/73 Signed-off-by: Julian Pidancet <julian.pidancet@oracle.com> Acked-by: Robin Jarry <robin@jarry.cc> Acked-by: Tim Culverhouse <tim@timculverhouse.com>
This commit is contained in:
parent
c7bfe4e490
commit
fbff8cf0ac
3 changed files with 78 additions and 34 deletions
|
@ -66,12 +66,18 @@ This can for example be useful if you use an archive or spam tag.
|
||||||
|
|
||||||
Default: none
|
Default: none
|
||||||
|
|
||||||
|
*maildir-store*
|
||||||
|
Path to the maildir store containing the message files backing the
|
||||||
|
notmuch database. This is often the same as the notmuch database path.
|
||||||
|
This is optional. If specified, it will be used by aerc to list
|
||||||
|
available folders and enable commands such as :delete and :archive.
|
||||||
|
|
||||||
|
Default: none
|
||||||
|
|
||||||
# USAGE
|
# USAGE
|
||||||
|
|
||||||
Notmuch shows slightly different behavior than for example imap.++
|
Notmuch shows slightly different behavior than for example imap.++
|
||||||
Some commands are simply unsupported because they have no proper counterpart
|
Some commands are slightly different in semantics and mentioned below:
|
||||||
in notmuch, like :delete and :archive.++
|
|
||||||
Others are slightly different in semantics and mentioned below:
|
|
||||||
|
|
||||||
*cf* <notmuch query>
|
*cf* <notmuch query>
|
||||||
The change folder command allows for arbitrary notmuch queries. Performing a
|
The change folder command allows for arbitrary notmuch queries. Performing a
|
||||||
|
|
|
@ -20,19 +20,21 @@ func (w *worker) handleNotmuchEvent(et eventType) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *worker) handleUpdateDirCounts(ev eventType) error {
|
func (w *worker) handleUpdateDirCounts(ev eventType) error {
|
||||||
folders, err := w.store.FolderMap()
|
if w.store != nil {
|
||||||
if err != nil {
|
folders, err := w.store.FolderMap()
|
||||||
logging.Errorf("failed listing directories: %v", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for name := range folders {
|
|
||||||
query := fmt.Sprintf("folder:%s", strconv.Quote(name))
|
|
||||||
info, err := w.buildDirInfo(name, query, true)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logging.Errorf("could not gather DirectoryInfo: %v", err)
|
logging.Errorf("failed listing directories: %v", err)
|
||||||
continue
|
return err
|
||||||
|
}
|
||||||
|
for name := range folders {
|
||||||
|
query := fmt.Sprintf("folder:%s", strconv.Quote(name))
|
||||||
|
info, err := w.buildDirInfo(name, query, true)
|
||||||
|
if err != nil {
|
||||||
|
logging.Errorf("could not gather DirectoryInfo: %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
w.w.PostMessage(info, nil)
|
||||||
}
|
}
|
||||||
w.w.PostMessage(info, nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for name, query := range w.nameQueryMap {
|
for name, query := range w.nameQueryMap {
|
||||||
|
|
|
@ -179,11 +179,19 @@ func (w *worker) handleConfigure(msg *types.Configure) error {
|
||||||
}
|
}
|
||||||
excludedTags := w.loadExcludeTags(msg.Config)
|
excludedTags := w.loadExcludeTags(msg.Config)
|
||||||
w.db = notmuch.NewDB(pathToDB, excludedTags)
|
w.db = notmuch.NewDB(pathToDB, excludedTags)
|
||||||
store, err := lib.NewMaildirStore(pathToDB, false)
|
|
||||||
if err != nil {
|
val, ok := msg.Config.Params["maildir-store"]
|
||||||
return fmt.Errorf("Cannot initialize maildir store: %w", err)
|
if ok {
|
||||||
|
path, err := homedir.Expand(val)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
store, err := lib.NewMaildirStore(path, false)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Cannot initialize maildir store: %w", err)
|
||||||
|
}
|
||||||
|
w.store = store
|
||||||
}
|
}
|
||||||
w.store = store
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -207,19 +215,21 @@ func (w *worker) handleConnect(msg *types.Connect) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *worker) handleListDirectories(msg *types.ListDirectories) error {
|
func (w *worker) handleListDirectories(msg *types.ListDirectories) error {
|
||||||
folders, err := w.store.FolderMap()
|
if w.store != nil {
|
||||||
if err != nil {
|
folders, err := w.store.FolderMap()
|
||||||
logging.Errorf("failed listing directories: %v", err)
|
if err != nil {
|
||||||
return err
|
logging.Errorf("failed listing directories: %v", err)
|
||||||
}
|
return err
|
||||||
for name := range folders {
|
}
|
||||||
w.w.PostMessage(&types.Directory{
|
for name := range folders {
|
||||||
Message: types.RespondTo(msg),
|
w.w.PostMessage(&types.Directory{
|
||||||
Dir: &models.Directory{
|
Message: types.RespondTo(msg),
|
||||||
Name: name,
|
Dir: &models.Directory{
|
||||||
Attributes: []string{},
|
Name: name,
|
||||||
},
|
Attributes: []string{},
|
||||||
}, nil)
|
},
|
||||||
|
}, nil)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, name := range w.queryMapOrder {
|
for _, name := range w.queryMapOrder {
|
||||||
|
@ -287,9 +297,11 @@ func (w *worker) queryFromName(name string) (string, bool) {
|
||||||
// try the friendly name first, if that fails assume it's a query
|
// try the friendly name first, if that fails assume it's a query
|
||||||
q, ok := w.nameQueryMap[name]
|
q, ok := w.nameQueryMap[name]
|
||||||
if !ok {
|
if !ok {
|
||||||
folders, _ := w.store.FolderMap()
|
if w.store != nil {
|
||||||
if _, ok := folders[name]; ok {
|
folders, _ := w.store.FolderMap()
|
||||||
return fmt.Sprintf("folder:%s", strconv.Quote(name)), true
|
if _, ok := folders[name]; ok {
|
||||||
|
return fmt.Sprintf("folder:%s", strconv.Quote(name)), true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return name, true
|
return name, true
|
||||||
}
|
}
|
||||||
|
@ -713,6 +725,10 @@ func (w *worker) handleCheckMail(msg *types.CheckMail) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *worker) handleDeleteMessages(msg *types.DeleteMessages) error {
|
func (w *worker) handleDeleteMessages(msg *types.DeleteMessages) error {
|
||||||
|
if w.store == nil {
|
||||||
|
return errUnsupported
|
||||||
|
}
|
||||||
|
|
||||||
var deleted []uint32
|
var deleted []uint32
|
||||||
|
|
||||||
// With notmuch, two identical files can be referenced under
|
// With notmuch, two identical files can be referenced under
|
||||||
|
@ -753,6 +769,10 @@ func (w *worker) handleDeleteMessages(msg *types.DeleteMessages) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *worker) handleCopyMessages(msg *types.CopyMessages) error {
|
func (w *worker) handleCopyMessages(msg *types.CopyMessages) error {
|
||||||
|
if w.store == nil {
|
||||||
|
return errUnsupported
|
||||||
|
}
|
||||||
|
|
||||||
// Only allow file to be copied to a maildir folder
|
// Only allow file to be copied to a maildir folder
|
||||||
folders, _ := w.store.FolderMap()
|
folders, _ := w.store.FolderMap()
|
||||||
dest, ok := folders[msg.Destination]
|
dest, ok := folders[msg.Destination]
|
||||||
|
@ -781,6 +801,10 @@ func (w *worker) handleCopyMessages(msg *types.CopyMessages) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *worker) handleMoveMessages(msg *types.MoveMessages) error {
|
func (w *worker) handleMoveMessages(msg *types.MoveMessages) error {
|
||||||
|
if w.store == nil {
|
||||||
|
return errUnsupported
|
||||||
|
}
|
||||||
|
|
||||||
var moved []uint32
|
var moved []uint32
|
||||||
|
|
||||||
// With notmuch, two identical files can be referenced under
|
// With notmuch, two identical files can be referenced under
|
||||||
|
@ -824,6 +848,10 @@ func (w *worker) handleMoveMessages(msg *types.MoveMessages) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *worker) handleAppendMessage(msg *types.AppendMessage) error {
|
func (w *worker) handleAppendMessage(msg *types.AppendMessage) error {
|
||||||
|
if w.store == nil {
|
||||||
|
return errUnsupported
|
||||||
|
}
|
||||||
|
|
||||||
// Only allow file to be created in a maildir folder
|
// Only allow file to be created in a maildir folder
|
||||||
// since we are the "master" maildir process, we can modify the maildir directly
|
// since we are the "master" maildir process, we can modify the maildir directly
|
||||||
folders, _ := w.store.FolderMap()
|
folders, _ := w.store.FolderMap()
|
||||||
|
@ -859,6 +887,10 @@ func (w *worker) handleAppendMessage(msg *types.AppendMessage) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *worker) handleCreateDirectory(msg *types.CreateDirectory) error {
|
func (w *worker) handleCreateDirectory(msg *types.CreateDirectory) error {
|
||||||
|
if w.store == nil {
|
||||||
|
return errUnsupported
|
||||||
|
}
|
||||||
|
|
||||||
dir := w.store.Dir(msg.Directory)
|
dir := w.store.Dir(msg.Directory)
|
||||||
if err := dir.Init(); err != nil {
|
if err := dir.Init(); err != nil {
|
||||||
logging.Errorf("could not create directory %s: %v",
|
logging.Errorf("could not create directory %s: %v",
|
||||||
|
@ -870,6 +902,10 @@ func (w *worker) handleCreateDirectory(msg *types.CreateDirectory) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *worker) handleRemoveDirectory(msg *types.RemoveDirectory) error {
|
func (w *worker) handleRemoveDirectory(msg *types.RemoveDirectory) error {
|
||||||
|
if w.store == nil {
|
||||||
|
return errUnsupported
|
||||||
|
}
|
||||||
|
|
||||||
dir := w.store.Dir(msg.Directory)
|
dir := w.store.Dir(msg.Directory)
|
||||||
if err := os.RemoveAll(string(dir)); err != nil {
|
if err := os.RemoveAll(string(dir)); err != nil {
|
||||||
logging.Errorf("could not remove directory %s: %v",
|
logging.Errorf("could not remove directory %s: %v",
|
||||||
|
|
Loading…
Reference in a new issue