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 {
 
   47       kDebug() << 
"Processing collection" << collection.
name() << 
"(" << collection.
id() << 
")";
 
   52       mParent->connect( job, SIGNAL(result(KJob*)), mParent, SLOT(slotFetchDone(KJob*)) );
 
   55       emit mParent->description( mParent, i18n( 
"Retrieving items..." ) );
 
   58     void slotFetchDone( KJob *job )
 
   62         mParent->setError( job->error() );
 
   63         mParent->setErrorText( job->errorText() );
 
   64         mParent->emitResult();
 
   69         mParent->emitResult();
 
   73       emit mParent->description( mParent, i18n( 
"Searching for duplicates..." ) );
 
   76       Akonadi::Item::List items = fjob->
items();
 
   80       QMap<QByteArray, uint> messageIds;
 
   81       QMap<uint, QList<uint> > duplicates;
 
   82       QMap<uint, uint> bodyHashes;
 
   83       const int numberOfItems( items.size() );
 
   84       for ( 
int i = 0; i < numberOfItems; ++i ) {
 
   85         Akonadi::Item item = items.at( i );
 
   86         if ( item.hasPayload<KMime::Message::Ptr>() ) {
 
   87           KMime::Message::Ptr message = item.payload<KMime::Message::Ptr>();
 
   88           QByteArray idStr = message->messageID()->as7BitString( 
false );
 
   94             if ( messageIds.contains( idStr ) ) {
 
   95               uint mainId = messageIds.value( idStr );
 
   96               if ( !bodyHashes.contains( mainId ) ) {
 
   97                 bodyHashes.insert( mainId, qHash( items.value( mainId ).payload<KMime::Message::Ptr>()->encodedContent() ) );
 
   99               uint hash = qHash( message->encodedContent() );
 
  100               kDebug() << idStr << bodyHashes.value( mainId ) << hash;
 
  101               if ( bodyHashes.value( mainId ) == hash ) {
 
  102                 duplicates[ mainId ].append( i );
 
  105               messageIds.insert( idStr, i );
 
  111       QMap<uint, QList<uint> >::ConstIterator end( duplicates.constEnd() );
 
  112       for ( QMap<uint, QList<uint> >::ConstIterator it = duplicates.constBegin(); it != end; ++it ) {
 
  113         QList<uint>::ConstIterator dupEnd( it.value().constEnd() );
 
  114         for ( QList<uint>::ConstIterator dupIt = it.value().constBegin(); dupIt != dupEnd; ++dupIt ) {
 
  115           mDuplicateItems.append( items.value( *dupIt ) );
 
  120         mParent->emitResult();
 
  124       if ( mJobCount > 0 ) {
 
  127         if ( mDuplicateItems.isEmpty() ) {
 
  128           kDebug() << 
"No duplicates, I'm done here";
 
  129           mParent->emitResult();
 
  132           emit mParent->description( mParent, i18n( 
"Removing duplicates..." ) );
 
  134           mParent->connect( delCmd, SIGNAL(result(KJob*)), mParent, SLOT(slotDeleteDone(KJob*)) );
 
  139     void slotDeleteDone( KJob *job )
 
  141       kDebug() << 
"Job done";
 
  143       mParent->setError( job->error() );
 
  144       mParent->setErrorText( job->errorText() );
 
  145       mParent->emitResult();
 
  150     Akonadi::Item::List mDuplicateItems;
 
  159 using namespace Akonadi;
 
  163   , 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. 
 
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.