Messagelib

aliasesexpandjob.cpp
1 /*
2  * This file is part of KMail.
3  *
4  * SPDX-FileCopyrightText: 2010 KDAB
5  * SPDX-FileContributor: Tobias Koenig <[email protected]>
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/Contact/ContactGroupExpandJob>
15 #include <Akonadi/Contact/ContactSearchJob>
16 #include <KEmailAddress>
17 
18 #include <MessageCore/StringUtil>
19 
20 using namespace MessageComposer;
21 
22 AliasesExpandJob::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 
72 void 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 
96 void 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 
122 void 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 += QLatin1String(", ");
130  }
131 
132  const QString receiver = recipient.trimmed();
133 
134  // take prefetched expand distribution list results
135  const DistributionListExpansionResult result = mDistListExpansionResults.value(recipient);
136  QString displayName;
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 {
172  mEmailAddresses += MessageCore::StringUtil::guessEmailAddressFromLoginName(addrSpec);
173  }
174  } else {
175  mEmailAddresses += receiver;
176  }
177  mEmailAddressOnly.append(addrSpec);
178  }
179 
180  emitResult();
181 }
182 
183 QStringList AliasesExpandJob::emailAddressOnly() const
184 {
185  return mEmailAddressOnly;
186 }
void start() override
Starts the job.
QString addresses() const
Returns the email addresses of the list members.
QStringList emptyDistributionLists() const
Returns the list of distribution lists that resolved to an empty member list.
void emitResult()
KCODECS_EXPORT EmailParseResult splitAddress(const QByteArray &address, QByteArray &displayName, QByteArray &addrSpec, QByteArray &comment)
void setError(int errorCode)
bool isEmpty() const
Returns whether the list of email addresses is empty.
QString addresses() const
Returns the expanded email addresses.
void setErrorText(const QString &errorText)
void append(const T &value)
QVariant property(const char *name) const const
bool isEmpty() const const
QString trimmed() const const
QString guessEmailAddressFromLoginName(const QString &loginName)
Uses the hostname as domain part and tries to determine the real name from the entries in the passwor...
Definition: stringutil.cpp:509
QString toLower() const const
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
~AliasesExpandJob() override
Destroys the aliases expand job.
KCODECS_EXPORT QStringList splitAddressList(const QString &aStr)
Simple interface that both EncryptJob and SignEncryptJob implement so the composer can extract some e...
KContacts::Addressee::List contacts() const
AddresseeList List
KCODECS_EXPORT QString normalizedAddress(const QString &displayName, const QString &addrSpec, const QString &comment=QString())
AliasesExpandJob(const QString &recipients, const QString &defaultDomain, QObject *parent=nullptr)
Creates a new aliases expand job.
QMap::iterator insert(const Key &key, const T &value)
void result(KJob *job)
A job to expand a distribution list to its member email addresses.
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
T qobject_cast(QObject *object)
QString toString() const const
QString errorText() const
int error() const
const T value(const Key &key, const T &defaultValue) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sat Dec 4 2021 23:12:52 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.