21 #include "removeduplicatesjob.h" 23 #include <QAbstractItemModel> 25 #include <akonadi/itemfetchjob.h> 26 #include <akonadi/itemdeletejob.h> 27 #include <akonadi/itemfetchscope.h> 28 #include <kmime/kmime_message.h> 30 #include <KLocalizedString> 32 class Akonadi::RemoveDuplicatesJob::Private {
46 kDebug() <<
"Processing collection" << collection.
name() <<
"(" << collection.
id() <<
")";
51 mParent->connect(job, SIGNAL(result(KJob*)), mParent, SLOT(slotFetchDone(KJob*)));
54 emit mParent->description(mParent, i18n(
"Retrieving items..."));
57 void slotFetchDone(KJob *job)
61 mParent->setError(job->error());
62 mParent->setErrorText(job->errorText());
63 mParent->emitResult();
68 mParent->emitResult();
72 emit mParent->description(mParent, i18n(
"Searching for duplicates..."));
75 Akonadi::Item::List items = fjob->
items();
79 QMap<QByteArray, uint> messageIds;
80 QMap<uint, QList<uint> > duplicates;
81 QMap<uint, uint> bodyHashes;
82 const int numberOfItems(items.size());
83 for (
int i = 0; i < numberOfItems; ++i) {
84 Akonadi::Item item = items.at(i);
85 if (item.hasPayload<KMime::Message::Ptr>()) {
86 KMime::Message::Ptr message = item.payload<KMime::Message::Ptr>();
87 QByteArray idStr = message->messageID()->as7BitString(
false);
93 if (messageIds.contains(idStr)) {
94 uint mainId = messageIds.value(idStr);
95 if (!bodyHashes.contains(mainId)) {
96 bodyHashes.insert(mainId, qHash(items.value(mainId).payload<KMime::Message::Ptr>()->encodedContent()));
98 uint hash = qHash(message->encodedContent());
99 kDebug() << idStr << bodyHashes.value(mainId) << hash;
100 if (bodyHashes.value(mainId) == hash) {
101 duplicates[mainId].append(i);
104 messageIds.insert(idStr, i);
110 QMap<uint, QList<uint> >::ConstIterator end(duplicates.constEnd());
111 for (QMap<uint, QList<uint> >::ConstIterator it = duplicates.constBegin(); it != end; ++it) {
112 QList<uint>::ConstIterator dupEnd(it.value().constEnd());
113 for (QList<uint>::ConstIterator dupIt = it.value().constBegin(); dupIt != dupEnd; ++dupIt) {
114 mDuplicateItems.append(items.value(*dupIt));
119 mParent->emitResult();
126 if (mDuplicateItems.isEmpty()) {
127 kDebug() <<
"No duplicates, I'm done here";
128 mParent->emitResult();
131 emit mParent->description(mParent, i18n(
"Removing duplicates..."));
133 mParent->connect(delCmd, SIGNAL(result(KJob*)), mParent, SLOT(slotDeleteDone(KJob*)));
138 void slotDeleteDone(KJob *job)
140 kDebug() <<
"Job done";
142 mParent->setError(job->error());
143 mParent->setErrorText(job->errorText());
144 mParent->emitResult();
149 Akonadi::Item::List mDuplicateItems;
162 , d(new Private(this))
165 d->mFolders << folder;
170 , d(new Private(this))
172 d->mFolders = folders;
173 d->mJobCount = d->mFolders.length();
185 if (d->mFolders.isEmpty()) {
186 kWarning() <<
"No collections to process";
196 kDebug() <<
"Killed!";
199 if (d->mCurrentJob) {
200 d->mCurrentJob->kill(EmitResult);
206 #include "moc_removeduplicatesjob.cpp" RemoveDuplicatesJob(const Akonadi::Collection &folder, QObject *parent=0)
Creates a new job that will remove duplicates in folder.
QString name() const
Returns the i18n'ed name of the collection.
virtual void doStart()
This method must be reimplemented in the concrete jobs.
Represents a collection of PIM items.
Base class for all actions in the Akonadi storage.
void fetchFullPayload(bool fetch=true)
Sets whether the full payload shall be fetched.
Item::List items() const
Returns the fetched items.
Job that deletes items from the Akonadi storage.
ItemFetchScope & fetchScope()
Returns the item fetch scope.
Only retrieve the immediate parent collection.
virtual bool doKill()
Kills the execution of the job.
Id id() const
Returns the unique identifier of the entity.
void setAncestorRetrieval(AncestorRetrieval ancestorDepth)
Sets how many levels of ancestor collections should be included in the retrieval. ...
virtual ~RemoveDuplicatesJob()
Destroys the job.
FreeBusyManager::Singleton.
Job that finds and removes duplicate messages in given collection.
Job that fetches items from the Akonadi storage.
QList< Collection > List
Describes a list of collections.