- Introduced new endpoints for contact discovery, including scanning, listing, and managing discovered contacts. - Implemented retry logic for handling missing DAV credentials during contact operations. - Added public share functionality for drive API, allowing users to manage public shares, including upload, delete, and rename operations. - Updated Nextcloud configuration to support public share links and improved error handling for public share permissions. - Enhanced logging and validation across contact and drive APIs for better error tracking and user feedback. - Added tests for new contact matching and ranking functionalities to ensure accuracy and reliability.
78 lines
2.4 KiB
Go
78 lines
2.4 KiB
Go
package discovery
|
|
|
|
const noReplyProfilesSQL = `
|
|
AND NOT (p.primary_email ILIKE '%noreply%' OR p.primary_email ILIKE '%no-reply%' OR p.primary_email ILIKE '%no_reply%')
|
|
AND NOT EXISTS (
|
|
SELECT 1
|
|
FROM jsonb_array_elements(COALESCE(p.all_emails, '[]'::jsonb)) AS e
|
|
WHERE COALESCE(e->>'email', '') ILIKE '%noreply%'
|
|
OR COALESCE(e->>'email', '') ILIKE '%no-reply%'
|
|
OR COALESCE(e->>'email', '') ILIKE '%no_reply%'
|
|
)`
|
|
|
|
const profileSelectColumns = `
|
|
p.id::text, p.display_name, p.primary_email, p.all_emails,
|
|
p.message_count, p.sent_count, p.received_count, p.spam_count, p.forwarded_count,
|
|
p.outbound_count, p.inbound_from_cc_count, p.copresence_cc_bcc_count,
|
|
p.is_mailing_list, p.is_disposable, p.is_spam_heavy, COALESCE(p.classification_reason, ''),
|
|
COALESCE(p.linked_contact_uid, ''), p.enrichment_status, p.enriched_data,
|
|
p.status, p.last_message_at, p.detected_in_accounts`
|
|
|
|
const profileInteractionOrderBy = `
|
|
p.outbound_count DESC,
|
|
p.inbound_from_cc_count DESC,
|
|
p.copresence_cc_bcc_count DESC,
|
|
p.message_count DESC,
|
|
p.last_message_at DESC NULLS LAST`
|
|
|
|
const groupInteractionOrderBy = `
|
|
total_outbound DESC,
|
|
total_inbound DESC,
|
|
total_copresence DESC,
|
|
total_messages DESC,
|
|
last_message_at DESC NULLS LAST`
|
|
|
|
func compareProfilesByInteraction(a, b Profile) bool {
|
|
if a.OutboundCount != b.OutboundCount {
|
|
return a.OutboundCount > b.OutboundCount
|
|
}
|
|
if a.InboundFromCCCount != b.InboundFromCCCount {
|
|
return a.InboundFromCCCount > b.InboundFromCCCount
|
|
}
|
|
if a.CopresenceCCBCCCount != b.CopresenceCCBCCCount {
|
|
return a.CopresenceCCBCCCount > b.CopresenceCCBCCCount
|
|
}
|
|
if a.MessageCount != b.MessageCount {
|
|
return a.MessageCount > b.MessageCount
|
|
}
|
|
return a.DisplayName < b.DisplayName
|
|
}
|
|
|
|
func compareProfileGroupsByInteraction(a, b ProfileGroup) bool {
|
|
ao, ai, ac, am := groupInteractionTotals(a.Profiles)
|
|
bo, bi, bc, bm := groupInteractionTotals(b.Profiles)
|
|
if ao != bo {
|
|
return ao > bo
|
|
}
|
|
if ai != bi {
|
|
return ai > bi
|
|
}
|
|
if ac != bc {
|
|
return ac > bc
|
|
}
|
|
if am != bm {
|
|
return am > bm
|
|
}
|
|
return a.DisplayName < b.DisplayName
|
|
}
|
|
|
|
func groupInteractionTotals(profiles []Profile) (outbound, inbound, copresence, messages int) {
|
|
for _, p := range profiles {
|
|
outbound += p.OutboundCount
|
|
inbound += p.InboundFromCCCount
|
|
copresence += p.CopresenceCCBCCCount
|
|
messages += p.MessageCount
|
|
}
|
|
return outbound, inbound, copresence, messages
|
|
}
|