1 /*
2   SPDX-FileCopyrightText: 2015-2021 Laurent Montel <montel@kde.org>
3 
4   SPDX-License-Identifier: LGPL-2.0-or-later
5 
6 */
7 
8 #include "removeduplicatemessageinfolderandsubfolderjob.h"
9 #include "kmail_debug.h"
10 #include <Akonadi/CollectionFetchJob>
11 #include <Akonadi/CollectionFetchScope>
12 #include <Akonadi/KMime/RemoveDuplicatesJob>
13 #include <KLocalizedString>
14 #include <KMessageBox>
15 #include <Libkdepim/ProgressManager>
16 
RemoveDuplicateMessageInFolderAndSubFolderJob(QObject * parent,QWidget * parentWidget)17 RemoveDuplicateMessageInFolderAndSubFolderJob::RemoveDuplicateMessageInFolderAndSubFolderJob(QObject *parent, QWidget *parentWidget)
18     : QObject(parent)
19     , mParentWidget(parentWidget)
20 {
21 }
22 
23 RemoveDuplicateMessageInFolderAndSubFolderJob::~RemoveDuplicateMessageInFolderAndSubFolderJob() = default;
24 
start()25 void RemoveDuplicateMessageInFolderAndSubFolderJob::start()
26 {
27     if (mTopLevelCollection.isValid()) {
28         auto fetchJob = new Akonadi::CollectionFetchJob(mTopLevelCollection, Akonadi::CollectionFetchJob::Recursive, this);
29         fetchJob->fetchScope().setAncestorRetrieval(Akonadi::CollectionFetchScope::All);
30         connect(fetchJob, &Akonadi::CollectionFetchJob::result, this, [this](KJob *job) {
31             if (job->error()) {
32                 qCWarning(KMAIL_LOG) << job->errorString();
33                 slotFetchCollectionFailed();
34             } else {
35                 auto fetch = static_cast<Akonadi::CollectionFetchJob *>(job);
36                 slotFetchCollectionDone(fetch->collections());
37             }
38         });
39     } else {
40         qCDebug(KMAIL_LOG()) << "Invalid toplevel collection";
41         deleteLater();
42     }
43 }
44 
setTopLevelCollection(const Akonadi::Collection & topLevelCollection)45 void RemoveDuplicateMessageInFolderAndSubFolderJob::setTopLevelCollection(const Akonadi::Collection &topLevelCollection)
46 {
47     mTopLevelCollection = topLevelCollection;
48 }
49 
slotFetchCollectionFailed()50 void RemoveDuplicateMessageInFolderAndSubFolderJob::slotFetchCollectionFailed()
51 {
52     qCDebug(KMAIL_LOG()) << "Fetch toplevel collection failed";
53     deleteLater();
54 }
55 
slotFetchCollectionDone(const Akonadi::Collection::List & list)56 void RemoveDuplicateMessageInFolderAndSubFolderJob::slotFetchCollectionDone(const Akonadi::Collection::List &list)
57 {
58     Akonadi::Collection::List lst;
59     for (const Akonadi::Collection &collection : list) {
60         if (collection.isValid()) {
61             if (collection.rights() & Akonadi::Collection::CanDeleteItem) {
62                 lst.append(collection);
63             }
64         }
65     }
66     if (lst.isEmpty()) {
67         deleteLater();
68     } else {
69         KPIM::ProgressItem *item = KPIM::ProgressManager::createProgressItem(i18n("Removing duplicates"));
70         item->setUsesBusyIndicator(true);
71         item->setCryptoStatus(KPIM::ProgressItem::Unknown);
72 
73         auto job = new Akonadi::RemoveDuplicatesJob(lst, this);
74         job->setProperty("ProgressItem", QVariant::fromValue(item));
75         item->setProperty("RemoveDuplicatesJob", QVariant::fromValue(qobject_cast<Akonadi::Job *>(job)));
76         connect(job, &Akonadi::RemoveDuplicatesJob::finished, this, &RemoveDuplicateMessageInFolderAndSubFolderJob::slotFinished);
77         connect(job, &Akonadi::RemoveDuplicatesJob::description, this, &RemoveDuplicateMessageInFolderAndSubFolderJob::slotRemoveDuplicatesUpdate);
78         connect(item, &KPIM::ProgressItem::progressItemCanceled, this, &RemoveDuplicateMessageInFolderAndSubFolderJob::slotRemoveDuplicatesCanceled);
79     }
80 }
81 
slotFinished(KJob * job)82 void RemoveDuplicateMessageInFolderAndSubFolderJob::slotFinished(KJob *job)
83 {
84     auto *item = job->property("ProgressItem").value<KPIM::ProgressItem *>();
85     if (item) {
86         item->setComplete();
87         item->setStatus(i18n("Done"));
88         item = nullptr;
89     }
90     if (job->error()) {
91         qCDebug(KMAIL_LOG()) << " Error during remove duplicates " << job->errorString();
92         KMessageBox::error(mParentWidget,
93                            i18n("Error occurred during removing duplicate emails: \'%1\'", job->errorText()),
94                            i18n("Error while removing duplicates"));
95     }
96 
97     deleteLater();
98 }
99 
slotRemoveDuplicatesUpdate(KJob * job,const QString & description)100 void RemoveDuplicateMessageInFolderAndSubFolderJob::slotRemoveDuplicatesUpdate(KJob *job, const QString &description)
101 {
102     auto *item = job->property("ProgressItem").value<KPIM::ProgressItem *>();
103     if (item) {
104         item->setStatus(description);
105     }
106 }
107 
slotRemoveDuplicatesCanceled(KPIM::ProgressItem * item)108 void RemoveDuplicateMessageInFolderAndSubFolderJob::slotRemoveDuplicatesCanceled(KPIM::ProgressItem *item)
109 {
110     auto *job = item->property("RemoveDuplicatesJob").value<Akonadi::Job *>();
111     if (job) {
112         job->kill(KJob::Quietly);
113     }
114 
115     item->setComplete();
116     item = nullptr;
117     deleteLater();
118 }
119