Use UID-stable target dedup scan

This commit is contained in:
DonVoo 2026-07-14 21:17:45 +02:00
parent b16deffa25
commit 8e8c651eaa
3 changed files with 64 additions and 17 deletions

View file

@ -7,6 +7,7 @@ import (
"fmt"
"net"
"net/mail"
"sort"
"strconv"
"strings"
"time"
@ -259,6 +260,44 @@ func (m *imapClientMailbox) fetchHeaders(folder string, limit, offset int) ([]Me
return out, nil
}
func (m *imapClientMailbox) fetchAllHeadersByUID(folder string) ([]MessageHeader, error) {
selected, err := m.c.Select(folder, &imap.SelectOptions{ReadOnly: true}).Wait()
if err != nil {
return nil, err
}
if selected.NumMessages == 0 {
return nil, nil
}
uidSet := imap.UIDSet{}
uidSet.AddRange(1, 0)
cmd := m.c.Fetch(uidSet, &imap.FetchOptions{
Envelope: true,
Flags: true,
InternalDate: true,
RFC822Size: true,
UID: true,
})
defer cmd.Close()
var out []MessageHeader
for {
data := cmd.Next()
if data == nil {
break
}
buf, err := data.Collect()
if err != nil {
return out, err
}
out = append(out, messageHeaderFromFetch(buf))
}
if err := cmd.Close(); err != nil {
return out, err
}
sortMessageHeadersByUID(out)
return out, nil
}
func (m *imapClientMailbox) fetchOne(folder string, uid uint32) (RawMessage, error) {
if uid == 0 {
return RawMessage{}, fmt.Errorf("Nachricht ohne UID")
@ -418,6 +457,12 @@ func reverseHeaders(headers []MessageHeader) {
}
}
func sortMessageHeadersByUID(headers []MessageHeader) {
sort.SliceStable(headers, func(i, j int) bool {
return headers[i].UID < headers[j].UID
})
}
func messageIDFromFetch(buf *imapclient.FetchMessageBuffer, body []byte) string {
if buf != nil && buf.Envelope != nil && strings.TrimSpace(buf.Envelope.MessageID) != "" {
return normalizeMessageID(buf.Envelope.MessageID)