forked from Silverfish/proton-bridge
GODT-1993: Use more efficient filtering for message deletion
This commit is contained in:
@ -30,6 +30,7 @@ import (
|
||||
"github.com/ProtonMail/proton-bridge/v2/internal/vault"
|
||||
"github.com/ProtonMail/proton-bridge/v2/pkg/message"
|
||||
"github.com/bradenaw/juniper/stream"
|
||||
"github.com/bradenaw/juniper/xslices"
|
||||
"gitlab.protontech.ch/go/liteapi"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
@ -308,26 +309,30 @@ func (conn *imapConnector) RemoveMessagesFromMailbox(ctx context.Context, messag
|
||||
}
|
||||
|
||||
if mailboxID == liteapi.SpamLabel || mailboxID == liteapi.TrashLabel {
|
||||
// check if messages are only in Trash and AllMail before they are permanently deleted.
|
||||
var messagesToDelete []string
|
||||
var metadata []liteapi.MessageMetadata
|
||||
|
||||
// GODT-1993 - Update to more efficient method.
|
||||
for _, messageID := range messageIDs {
|
||||
m, err := conn.client.GetMessage(ctx, string(messageID))
|
||||
// There's currently no limit on how many IDs we can filter on,
|
||||
// but to be nice to API, let's chunk it by 150.
|
||||
for _, messageIDs := range xslices.Chunk(messageIDs, 150) {
|
||||
m, err := conn.client.GetMessageMetadata(ctx, liteapi.MessageFilter{
|
||||
ID: mapTo[imap.MessageID, string](messageIDs),
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get message info")
|
||||
return err
|
||||
}
|
||||
|
||||
if len(m.LabelIDs) == 1 && m.LabelIDs[0] == liteapi.AllMailLabel {
|
||||
messagesToDelete = append(messagesToDelete, m.ID)
|
||||
}
|
||||
m = xslices.Filter(m, func(m liteapi.MessageMetadata) bool {
|
||||
return len(m.LabelIDs) == 1 && m.LabelIDs[0] == liteapi.AllMailLabel
|
||||
})
|
||||
|
||||
metadata = append(metadata, m...)
|
||||
}
|
||||
|
||||
if len(messagesToDelete) == 0 {
|
||||
return nil
|
||||
if err := conn.client.DeleteMessage(ctx, xslices.Map(metadata, func(m liteapi.MessageMetadata) string {
|
||||
return m.ID
|
||||
})...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return conn.client.DeleteMessage(ctx, messagesToDelete...)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@ -22,7 +22,6 @@ import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/mail"
|
||||
"net/url"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
@ -143,15 +142,16 @@ func getParentID( //nolint:funlen
|
||||
|
||||
// Try to find a parent ID in the internal references.
|
||||
for _, internal := range internal {
|
||||
filter := url.Values{
|
||||
"ID": {internal},
|
||||
}
|
||||
var addrID string
|
||||
|
||||
if addrMode == vault.SplitMode {
|
||||
filter["AddressID"] = []string{authAddrID}
|
||||
addrID = authAddrID
|
||||
}
|
||||
|
||||
metadata, err := client.GetMessageMetadata(ctx, filter)
|
||||
metadata, err := client.GetMessageMetadata(ctx, liteapi.MessageFilter{
|
||||
ID: []string{internal},
|
||||
AddressID: addrID,
|
||||
})
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get message metadata: %w", err)
|
||||
}
|
||||
@ -168,15 +168,16 @@ func getParentID( //nolint:funlen
|
||||
// If no parent was found, try to find it in the last external reference.
|
||||
// There can be multiple messages with the same external ID; in this case, we don't pick any parent.
|
||||
if parentID == "" && len(external) > 0 {
|
||||
filter := url.Values{
|
||||
"ExternalID": {external[len(external)-1]},
|
||||
}
|
||||
var addrID string
|
||||
|
||||
if addrMode == vault.SplitMode {
|
||||
filter["AddressID"] = []string{authAddrID}
|
||||
addrID = authAddrID
|
||||
}
|
||||
|
||||
metadata, err := client.GetMessageMetadata(ctx, filter)
|
||||
metadata, err := client.GetMessageMetadata(ctx, liteapi.MessageFilter{
|
||||
ExternalID: external[len(external)-1],
|
||||
AddressID: addrID,
|
||||
})
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get message metadata: %w", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user