mirror of https://git.sr.ht/~rjarry/aerc
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
261 lines
6.0 KiB
Go
261 lines
6.0 KiB
Go
//go:build notmuch
|
|
// +build notmuch
|
|
|
|
package notmuch
|
|
|
|
/*
|
|
#cgo LDFLAGS: -lnotmuch
|
|
|
|
#include <stdlib.h>
|
|
#include <notmuch.h>
|
|
|
|
*/
|
|
import "C"
|
|
|
|
import (
|
|
"time"
|
|
"unsafe"
|
|
)
|
|
|
|
type Message struct {
|
|
message *C.notmuch_message_t
|
|
}
|
|
|
|
// Close frees resources associated with the message
|
|
func (m *Message) Close() {
|
|
C.notmuch_message_destroy(m.message)
|
|
}
|
|
|
|
// ID returns the message ID
|
|
func (m *Message) ID() string {
|
|
cID := C.notmuch_message_get_message_id(m.message)
|
|
return C.GoString(cID)
|
|
}
|
|
|
|
// ThreadID returns the thread ID of the message
|
|
func (m *Message) ThreadID() string {
|
|
cID := C.notmuch_message_get_thread_id(m.message)
|
|
return C.GoString(cID)
|
|
}
|
|
|
|
func (m *Message) Replies() Messages {
|
|
cMessages := C.notmuch_message_get_replies(m.message)
|
|
return Messages{
|
|
messages: cMessages,
|
|
}
|
|
}
|
|
|
|
func (m *Message) TotalFiles() int {
|
|
return int(C.notmuch_message_count_files(m.message))
|
|
}
|
|
|
|
// Filename returns a single filename associated with the message. If the
|
|
// message has multiple filenames, the return value will be arbitrarily chosen
|
|
func (m *Message) Filename() string {
|
|
cFilename := C.notmuch_message_get_filename(m.message)
|
|
return C.GoString(cFilename)
|
|
}
|
|
|
|
func (m *Message) Filenames() []string {
|
|
cFilenames := C.notmuch_message_get_filenames(m.message)
|
|
defer C.notmuch_filenames_destroy(cFilenames)
|
|
|
|
filenames := []string{}
|
|
for C.notmuch_filenames_valid(cFilenames) > 0 {
|
|
filename := C.notmuch_filenames_get(cFilenames)
|
|
filenames = append(filenames, C.GoString(filename))
|
|
C.notmuch_filenames_move_to_next(cFilenames)
|
|
}
|
|
return filenames
|
|
}
|
|
|
|
// TODO is this needed?
|
|
// func (m *Message) Reindex() error {
|
|
//
|
|
// }
|
|
|
|
type Flag int
|
|
|
|
const (
|
|
MESSAGE_FLAG_MATCH Flag = iota
|
|
MESSAGE_FLAG_EXCLUDED
|
|
MESSAGE_FLAG_GHOST
|
|
)
|
|
|
|
func (m *Message) Flag(flag Flag) (bool, error) {
|
|
var ok C.notmuch_bool_t
|
|
cFlag := C.notmuch_message_flag_t(flag)
|
|
err := errorWrap(C.notmuch_message_get_flag_st(m.message, cFlag, &ok))
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
if ok == 0 {
|
|
return false, nil
|
|
}
|
|
return true, nil
|
|
}
|
|
|
|
// TODO why does this exist??
|
|
// func (m *Message) SetFlag(flag Flag) {
|
|
//
|
|
// }
|
|
|
|
func (m *Message) Date() time.Time {
|
|
cTime := C.notmuch_message_get_date(m.message)
|
|
return time.Unix(int64(cTime), 0)
|
|
}
|
|
|
|
func (m *Message) Header(field string) string {
|
|
cField := C.CString(field)
|
|
defer C.free(unsafe.Pointer(cField))
|
|
cHeader := C.notmuch_message_get_header(m.message, cField)
|
|
return C.GoString(cHeader)
|
|
}
|
|
|
|
func (m *Message) Tags() []string {
|
|
cTags := C.notmuch_message_get_tags(m.message)
|
|
defer C.notmuch_tags_destroy(cTags)
|
|
|
|
tags := []string{}
|
|
for C.notmuch_tags_valid(cTags) > 0 {
|
|
tag := C.notmuch_tags_get(cTags)
|
|
tags = append(tags, C.GoString(tag))
|
|
C.notmuch_tags_move_to_next(cTags)
|
|
}
|
|
return tags
|
|
}
|
|
|
|
func (m *Message) AddTag(tag string) error {
|
|
cTag := C.CString(tag)
|
|
defer C.free(unsafe.Pointer(cTag))
|
|
|
|
return errorWrap(C.notmuch_message_add_tag(m.message, cTag))
|
|
}
|
|
|
|
func (m *Message) RemoveTag(tag string) error {
|
|
cTag := C.CString(tag)
|
|
defer C.free(unsafe.Pointer(cTag))
|
|
|
|
return errorWrap(C.notmuch_message_remove_tag(m.message, cTag))
|
|
}
|
|
|
|
func (m *Message) RemoveAllTags() error {
|
|
return errorWrap(C.notmuch_message_remove_all_tags(m.message))
|
|
}
|
|
|
|
// SyncTagsToMaildirFlags adds/removes the appropriate tags to the maildir
|
|
// filename
|
|
func (m *Message) SyncTagsToMaildirFlags() error {
|
|
return errorWrap(C.notmuch_message_tags_to_maildir_flags(m.message))
|
|
}
|
|
|
|
// SyncMaildirFlagsToTags syncs the current maildir flags to the notmuch tags
|
|
func (m *Message) SyncMaildirFlagsToTags() error {
|
|
return errorWrap(C.notmuch_message_maildir_flags_to_tags(m.message))
|
|
}
|
|
|
|
func (m *Message) HasMaildirFlag(flag rune) (bool, error) {
|
|
var ok C.notmuch_bool_t
|
|
err := errorWrap(C.notmuch_message_has_maildir_flag_st(m.message, C.char(flag), &ok))
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
if ok == 0 {
|
|
return false, nil
|
|
}
|
|
return true, nil
|
|
}
|
|
|
|
func (m *Message) Freeze() error {
|
|
return errorWrap(C.notmuch_message_freeze(m.message))
|
|
}
|
|
|
|
func (m *Message) Thaw() error {
|
|
return errorWrap(C.notmuch_message_thaw(m.message))
|
|
}
|
|
|
|
func (m *Message) Property(key string) (string, error) {
|
|
var (
|
|
cKey *C.char
|
|
cValue *C.char
|
|
)
|
|
defer C.free(unsafe.Pointer(cKey))
|
|
defer C.free(unsafe.Pointer(cValue))
|
|
cKey = C.CString(key)
|
|
err := errorWrap(C.notmuch_message_get_property(m.message, cKey, &cValue)) //nolint:gocritic // see note in notmuch.go
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return C.GoString(cValue), nil
|
|
}
|
|
|
|
func (m *Message) AddProperty(key string, value string) error {
|
|
var (
|
|
cKey *C.char
|
|
cValue *C.char
|
|
)
|
|
defer C.free(unsafe.Pointer(cKey))
|
|
defer C.free(unsafe.Pointer(cValue))
|
|
cKey = C.CString(key)
|
|
cValue = C.CString(value)
|
|
return errorWrap(C.notmuch_message_add_property(m.message, cKey, cValue))
|
|
}
|
|
|
|
func (m *Message) RemoveProperty(key string, value string) error {
|
|
var (
|
|
cKey *C.char
|
|
cValue *C.char
|
|
)
|
|
defer C.free(unsafe.Pointer(cKey))
|
|
defer C.free(unsafe.Pointer(cValue))
|
|
cKey = C.CString(key)
|
|
cValue = C.CString(value)
|
|
return errorWrap(C.notmuch_message_remove_property(m.message, cKey, cValue))
|
|
}
|
|
|
|
func (m *Message) RemoveAllProperties(key string) error {
|
|
var cKey *C.char
|
|
defer C.free(unsafe.Pointer(cKey))
|
|
cKey = C.CString(key)
|
|
return errorWrap(C.notmuch_message_remove_all_properties(m.message, cKey))
|
|
}
|
|
|
|
func (m *Message) RemoveAllPropertiesWithPrefix(prefix string) error {
|
|
var cPrefix *C.char
|
|
defer C.free(unsafe.Pointer(cPrefix))
|
|
cPrefix = C.CString(prefix)
|
|
return errorWrap(C.notmuch_message_remove_all_properties_with_prefix(m.message, cPrefix))
|
|
}
|
|
|
|
func (m *Message) Properties(key string, exact bool) *Properties {
|
|
var (
|
|
cKey *C.char
|
|
cExact C.int
|
|
)
|
|
defer C.free(unsafe.Pointer(cKey))
|
|
if exact {
|
|
cExact = 1
|
|
}
|
|
|
|
cKey = C.CString(key)
|
|
props := C.notmuch_message_get_properties(m.message, cKey, cExact)
|
|
|
|
return &Properties{
|
|
properties: props,
|
|
}
|
|
}
|
|
|
|
func (m *Message) CountProperties(key string) (int, error) {
|
|
var (
|
|
cKey *C.char
|
|
cCount C.uint
|
|
)
|
|
defer C.free(unsafe.Pointer(cKey))
|
|
cKey = C.CString(key)
|
|
err := errorWrap(C.notmuch_message_count_properties(m.message, cKey, &cCount))
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return int(cCount), nil
|
|
}
|