Messagelib

aliasesexpandjob.cpp
1/*
2 * This file is part of KMail.
3 *
4 * SPDX-FileCopyrightText: 2010 KDAB
5 * SPDX-FileContributor: Tobias Koenig <tokoe@kde.org>
6 *
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
9
10#include "aliasesexpandjob.h"
11
12#include "distributionlistexpandjob.h"
13
14#include <Akonadi/ContactGroupExpandJob>
15#include <Akonadi/ContactSearchJob>
16#include <KEmailAddress>
17
18#include <MessageCore/StringUtil>
19
20using namespace MessageComposer;
21
22AliasesExpandJob::AliasesExpandJob(const QString &recipients, const QString &defaultDomain, QObject *parent)
23 : KJob(parent)
24 , mRecipients(KEmailAddress::splitAddressList(recipients))
25 , mDefaultDomain(defaultDomain)
26{
27}
28
30
32{
33 // At first we try to expand the recipient to a distribution list
34 // or nick name and save the results in a map for later lookup
35 for (const QString &recipient : std::as_const(mRecipients)) {
36 // speedup: assume aliases and list names don't contain '@'
37 if (recipient.isEmpty() || recipient.contains(QLatin1Char('@'))) {
38 continue;
39 }
40
41 // check for distribution list
42 auto expandJob = new DistributionListExpandJob(recipient, this);
43 expandJob->setProperty("recipient", recipient);
44 connect(expandJob, &Akonadi::ContactGroupExpandJob::result, this, &AliasesExpandJob::slotDistributionListExpansionDone);
45 mDistributionListExpansionJobs++;
46 expandJob->start();
47
48 // check for nick name
49 auto searchJob = new Akonadi::ContactSearchJob(this);
50 searchJob->setProperty("recipient", recipient);
51 searchJob->setQuery(Akonadi::ContactSearchJob::NickName, recipient.toLower());
52 connect(searchJob, &Akonadi::ContactSearchJob::result, this, &AliasesExpandJob::slotNicknameExpansionDone);
53 mNicknameExpansionJobs++;
54 searchJob->start();
55 }
56
57 if (mDistributionListExpansionJobs == 0 && mNicknameExpansionJobs == 0) {
58 emitResult();
59 }
60}
61
63{
64 return mEmailAddresses;
65}
66
68{
69 return mEmptyDistributionLists;
70}
71
72void AliasesExpandJob::slotDistributionListExpansionDone(KJob *job)
73{
74 if (job->error()) {
75 setError(job->error());
76 setErrorText(job->errorText());
77 emitResult();
78 return;
79 }
80
82 const QString recipient = expandJob->property("recipient").toString();
83
84 DistributionListExpansionResult result;
85 result.addresses = expandJob->addresses();
86 result.isEmpty = expandJob->isEmpty();
87
88 mDistListExpansionResults.insert(recipient, result);
89
90 mDistributionListExpansionJobs--;
91 if (mDistributionListExpansionJobs == 0 && mNicknameExpansionJobs == 0) {
92 finishExpansion();
93 }
94}
95
96void AliasesExpandJob::slotNicknameExpansionDone(KJob *job)
97{
98 if (job->error()) {
99 setError(job->error());
100 setErrorText(job->errorText());
101 emitResult();
102 return;
103 }
104
106 const KContacts::Addressee::List contacts = searchJob->contacts();
107 const QString recipient = searchJob->property("recipient").toString();
108
109 for (const KContacts::Addressee &contact : contacts) {
110 if (contact.nickName().toLower() == recipient.toLower()) {
111 mNicknameExpansionResults.insert(recipient, contact.fullEmail());
112 break;
113 }
114 }
115
116 mNicknameExpansionJobs--;
117 if (mDistributionListExpansionJobs == 0 && mNicknameExpansionJobs == 0) {
118 finishExpansion();
119 }
120}
121
122void AliasesExpandJob::finishExpansion()
123{
124 for (const QString &recipient : std::as_const(mRecipients)) {
125 if (recipient.isEmpty()) {
126 continue;
127 }
128 if (!mEmailAddresses.isEmpty()) {
129 mEmailAddresses += QLatin1StringView(", ");
130 }
131
132 const QString receiver = recipient.trimmed();
133
134 // take prefetched expand distribution list results
135 const DistributionListExpansionResult result = mDistListExpansionResults.value(recipient);
137 QString addrSpec;
138 QString comment;
139
140 if (result.isEmpty) {
141 KEmailAddress::splitAddress(receiver, displayName, addrSpec, comment);
142 mEmailAddressOnly.append(addrSpec);
143 mEmailAddresses += receiver;
144 mEmptyDistributionLists << receiver;
145 continue;
146 }
147
148 if (!result.addresses.isEmpty()) {
149 KEmailAddress::splitAddress(result.addresses, displayName, addrSpec, comment);
150 mEmailAddressOnly.append(addrSpec);
151
152 mEmailAddresses += result.addresses;
153 continue;
154 }
155
156 // take prefetched expand nick name results
157 const QString recipientValue = mNicknameExpansionResults.value(recipient);
158 if (!recipientValue.isEmpty()) {
159 mEmailAddresses += recipientValue;
160 KEmailAddress::splitAddress(recipientValue, displayName, addrSpec, comment);
161 mEmailAddressOnly.append(addrSpec);
162
163 continue;
164 }
165
166 // check whether the address is missing the domain part
167 KEmailAddress::splitAddress(receiver, displayName, addrSpec, comment);
168 if (!addrSpec.contains(QLatin1Char('@'))) {
169 if (!mDefaultDomain.isEmpty()) {
170 mEmailAddresses += KEmailAddress::normalizedAddress(displayName, addrSpec + QLatin1Char('@') + mDefaultDomain, comment);
171 } else {
173 }
174 } else {
175 mEmailAddresses += receiver;
176 }
177 mEmailAddressOnly.append(addrSpec);
178 }
179
180 emitResult();
181}
182
183QStringList AliasesExpandJob::emailAddressOnly() const
184{
185 return mEmailAddressOnly;
186}
187
188#include "moc_aliasesexpandjob.cpp"
KContacts::Addressee::List contacts() const
AddresseeList List
void setErrorText(const QString &errorText)
void emitResult()
int error() const
void result(KJob *job)
void setError(int errorCode)
QString errorText() const
QString addresses() const
Returns the expanded email addresses.
void start() override
Starts the job.
QStringList emptyDistributionLists() const
Returns the list of distribution lists that resolved to an empty member list.
~AliasesExpandJob() override
Destroys the aliases expand job.
AliasesExpandJob(const QString &recipients, const QString &defaultDomain, QObject *parent=nullptr)
Creates a new aliases expand job.
A job to expand a distribution list to its member email addresses.
bool isEmpty() const
Returns whether the list of email addresses is empty.
QString addresses() const
Returns the email addresses of the list members.
KCODECS_EXPORT QString normalizedAddress(const QString &displayName, const QString &addrSpec, const QString &comment=QString())
KCODECS_EXPORT EmailParseResult splitAddress(const QByteArray &address, QByteArray &displayName, QByteArray &addrSpec, QByteArray &comment)
AKONADI_CALENDAR_EXPORT QString displayName(Akonadi::ETMCalendar *calendar, const Akonadi::Collection &collection)
Simple interface that both EncryptJob and SignEncryptJob implement so the composer can extract some e...
QString guessEmailAddressFromLoginName(const QString &loginName)
Uses the hostname as domain part and tries to determine the real name from the entries in the passwor...
void append(QList< T > &&value)
iterator insert(const Key &key, const T &value)
T value(const Key &key, const T &defaultValue) const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QVariant property(const char *name) const const
T qobject_cast(QObject *object)
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
QString toLower() const const
QString trimmed() const const
QString toString() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 16:59:12 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.