File indexing completed on 2025-03-09 04:54:32

0001 /*
0002  * SPDX-FileCopyrightText: 2012-2024 Laurent Montel <montel@kde.org>
0003  *
0004  * SPDX-License-Identifier: LGPL-2.0-or-later
0005  */
0006 
0007 #include "contactdisplaymessagememento.h"
0008 #include "messageviewer_debug.h"
0009 #include <Akonadi/ContactSearchJob>
0010 #include <Gravatar/GravatarResolvUrlJob>
0011 #include <KIO/TransferJob>
0012 #include <gravatar/gravatarsettings.h>
0013 
0014 using namespace MessageViewer;
0015 
0016 ContactDisplayMessageMemento::ContactDisplayMessageMemento(const QString &emailAddress)
0017     : QObject(nullptr)
0018     , mEmailAddress(emailAddress)
0019 {
0020     if (!emailAddress.isEmpty()) {
0021         mSearchJob = new Akonadi::ContactSearchJob();
0022         mSearchJob->setQuery(Akonadi::ContactSearchJob::Email, emailAddress.toLower(), Akonadi::ContactSearchJob::ExactMatch);
0023         connect(mSearchJob.data(), &Akonadi::ContactSearchJob::result, this, &ContactDisplayMessageMemento::slotSearchJobFinished);
0024     } else {
0025         mFinished = true;
0026     }
0027 }
0028 
0029 ContactDisplayMessageMemento::~ContactDisplayMessageMemento()
0030 {
0031     if (mSearchJob) {
0032         disconnect(mSearchJob.data(), &Akonadi::ContactSearchJob::result, this, &ContactDisplayMessageMemento::slotSearchJobFinished);
0033         mSearchJob->kill();
0034     }
0035 }
0036 
0037 void ContactDisplayMessageMemento::slotSearchJobFinished(KJob *job)
0038 {
0039     mFinished = true;
0040     auto searchJob = static_cast<Akonadi::ContactSearchJob *>(job);
0041     if (searchJob->error()) {
0042         qCWarning(MESSAGEVIEWER_LOG) << "Unable to fetch contact:" << searchJob->errorText();
0043         Q_EMIT update(MimeTreeParser::Delayed);
0044         return;
0045     }
0046 
0047     const int contactSize(searchJob->contacts().size());
0048     if (contactSize >= 1) {
0049         if (contactSize > 1) {
0050             qCWarning(MESSAGEVIEWER_LOG) << " more than 1 contact was found we return first contact";
0051         }
0052 
0053         const KContacts::Addressee addressee = searchJob->contacts().at(0);
0054         processAddress(addressee);
0055         if (!searchPhoto(searchJob->contacts())) {
0056             // We have a data raw => we can update message
0057             if (mPhoto.isIntern()) {
0058                 Q_EMIT update(MimeTreeParser::Delayed);
0059             } else {
0060                 const QUrl url = QUrl::fromUserInput(mPhoto.url(), QString(), QUrl::AssumeLocalFile);
0061                 if (!url.isEmpty()) {
0062                     bool ok = false;
0063                     QImage image;
0064 
0065                     if (url.isLocalFile()) {
0066                         if (image.load(url.toLocalFile())) {
0067                             ok = true;
0068                         }
0069                     } else {
0070                         QByteArray imageData;
0071                         KIO::TransferJob *jobTransfert = KIO::get(url, KIO::NoReload);
0072                         QObject::connect(jobTransfert, &KIO::TransferJob::data, [&imageData](KIO::Job *, const QByteArray &data) {
0073                             imageData.append(data);
0074                         });
0075                         if (jobTransfert->exec()) {
0076                             if (image.loadFromData(imageData)) {
0077                                 ok = true;
0078                             }
0079                         }
0080                     }
0081                     if (ok) {
0082                         mImageFromUrl = image;
0083                         Q_EMIT update(MimeTreeParser::Delayed);
0084                     }
0085                 }
0086             }
0087         }
0088     }
0089     if (mPhoto.isEmpty() && mPhoto.url().isEmpty()) {
0090         // No url, no photo => search gravatar
0091         if (Gravatar::GravatarSettings::self()->gravatarSupportEnabled()) {
0092             auto resolvUrljob = new Gravatar::GravatarResolvUrlJob(this);
0093             resolvUrljob->setEmail(mEmailAddress);
0094             resolvUrljob->setUseDefaultPixmap(Gravatar::GravatarSettings::self()->gravatarUseDefaultImage());
0095             resolvUrljob->setFallbackGravatar(Gravatar::GravatarSettings::self()->fallbackToGravatar());
0096             resolvUrljob->setUseLibravatar(Gravatar::GravatarSettings::self()->libravatarSupportEnabled());
0097             if (resolvUrljob->canStart()) {
0098                 connect(resolvUrljob, &Gravatar::GravatarResolvUrlJob::finished, this, &ContactDisplayMessageMemento::slotGravatarResolvUrlFinished);
0099                 resolvUrljob->start();
0100             } else {
0101                 resolvUrljob->deleteLater();
0102             }
0103         }
0104     }
0105 }
0106 
0107 bool ContactDisplayMessageMemento::finished() const
0108 {
0109     return mFinished;
0110 }
0111 
0112 void ContactDisplayMessageMemento::detach()
0113 {
0114     disconnect(this, SIGNAL(update(MimeTreeParser::UpdateMode)), nullptr, nullptr);
0115     disconnect(this, SIGNAL(changeDisplayMail(Viewer::DisplayFormatMessage, bool)), nullptr, nullptr);
0116 }
0117 
0118 bool ContactDisplayMessageMemento::searchPhoto(const KContacts::AddresseeList &list)
0119 {
0120     bool foundPhoto = false;
0121     for (const KContacts::Addressee &addressee : list) {
0122         const KContacts::Picture photo = addressee.photo();
0123         if (!photo.isEmpty()) {
0124             mPhoto = photo;
0125             foundPhoto = true;
0126             break;
0127         }
0128     }
0129     return foundPhoto;
0130 }
0131 
0132 QImage ContactDisplayMessageMemento::imageFromUrl() const
0133 {
0134     return mImageFromUrl;
0135 }
0136 
0137 QPixmap ContactDisplayMessageMemento::gravatarPixmap() const
0138 {
0139     return mGravatarPixmap;
0140 }
0141 
0142 void ContactDisplayMessageMemento::processAddress(const KContacts::Addressee &addressee)
0143 {
0144     Viewer::DisplayFormatMessage forceDisplayTo = Viewer::UseGlobalSetting;
0145     bool mailAllowToRemoteContent = false;
0146     const QStringList customs = addressee.customs();
0147     for (const QString &custom : customs) {
0148         if (custom.contains(QLatin1StringView("MailPreferedFormatting"))) {
0149             const QString value = addressee.custom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("MailPreferedFormatting"));
0150             if (value == QLatin1StringView("TEXT")) {
0151                 forceDisplayTo = Viewer::Text;
0152             } else if (value == QLatin1StringView("HTML")) {
0153                 forceDisplayTo = Viewer::Html;
0154             } else {
0155                 forceDisplayTo = Viewer::UseGlobalSetting;
0156             }
0157         } else if (custom.contains(QLatin1StringView("MailAllowToRemoteContent"))) {
0158             const QString value = addressee.custom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("MailAllowToRemoteContent"));
0159             mailAllowToRemoteContent = (value == QLatin1StringView("TRUE"));
0160         }
0161     }
0162     Q_EMIT changeDisplayMail(forceDisplayTo, mailAllowToRemoteContent);
0163 }
0164 
0165 KContacts::Picture ContactDisplayMessageMemento::photo() const
0166 {
0167     return mPhoto;
0168 }
0169 
0170 void ContactDisplayMessageMemento::slotGravatarResolvUrlFinished(Gravatar::GravatarResolvUrlJob *job)
0171 {
0172     if (job && job->hasGravatar()) {
0173         mGravatarPixmap = job->pixmap();
0174         Q_EMIT update(MimeTreeParser::Delayed);
0175     }
0176 }
0177 
0178 #include "moc_contactdisplaymessagememento.cpp"